diff --git a/.cocos-project.json b/.cocos-project.json
new file mode 100644
index 0000000..18b6879
--- /dev/null
+++ b/.cocos-project.json
@@ -0,0 +1,5 @@
+{
+ "engine_version": "cocos2d-x-3.17.2",
+ "has_native": true,
+ "project_type": "js"
+}
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..70e19e6
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,154 @@
+#/****************************************************************************
+# Copyright (c) 2013 cocos2d-x.org
+# Copyright (c) 2014 martell malone
+# Copyright (c) 2015-2017 Chukong Technologies Inc.
+#
+# http://www.cocos2d-x.org
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+# ****************************************************************************/
+
+cmake_minimum_required(VERSION 3.6)
+
+set(APP_NAME Fbird)
+
+project(${APP_NAME})
+
+set(RUNTIME_SRC_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/frameworks/runtime-src)
+set(COCOS2DX_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/frameworks/cocos2d-x)
+set(CMAKE_MODULE_PATH ${COCOS2DX_ROOT_PATH}/cmake/Modules/)
+
+include(CocosBuildSet)
+set(BUILD_JS_LIBS ON)
+add_subdirectory(${COCOS2DX_ROOT_PATH}/cocos ${ENGINE_BINARY_PATH}/cocos/core)
+
+# script and source files info, not need to compile
+set(res_main_files
+ "${CMAKE_CURRENT_SOURCE_DIR}/main.js"
+ "${CMAKE_CURRENT_SOURCE_DIR}/project.json"
+ )
+set(res_res_folders
+ "${CMAKE_CURRENT_SOURCE_DIR}/res"
+ )
+set(res_src_folders
+ "${CMAKE_CURRENT_SOURCE_DIR}/src"
+ )
+set(res_script_folders
+ "${COCOS2DX_ROOT_PATH}/cocos/scripting/js-bindings/script"
+ )
+if(APPLE OR VS)
+ cocos_mark_multi_resources(res_main RES_TO "Resources" FILES ${res_main_files})
+ cocos_mark_multi_resources(res_res RES_TO "Resources/res" FOLDERS ${res_res_folders})
+ cocos_mark_multi_resources(res_src RES_TO "Resources/src" FOLDERS ${res_src_folders})
+ cocos_mark_multi_resources(res_script RES_TO "Resources/script" FOLDERS ${res_script_folders})
+ set(cc_common_res ${res_main} ${res_res} ${res_src} ${res_script})
+endif()
+
+# record sources, headers
+set(GAME_SOURCE ${RUNTIME_SRC_ROOT}/Classes/AppDelegate.cpp)
+set(GAME_HEADER ${RUNTIME_SRC_ROOT}/Classes/AppDelegate.h)
+
+if(ANDROID)
+ # change APP_NAME to the share library name for Android, it's value depend on AndroidManifest.xml
+ set(APP_NAME cocos2djs)
+ list(APPEND GAME_SOURCE ${RUNTIME_SRC_ROOT}/proj.android/app/jni/hellojavascript/main.cpp)
+elseif(LINUX)
+ list(APPEND GAME_SOURCE ${RUNTIME_SRC_ROOT}/proj.linux/main.cpp)
+elseif(WINDOWS)
+ set(WINDOWS_SRC ${RUNTIME_SRC_ROOT}/proj.win32/main.cpp)
+ list(APPEND WINDOWS_SRC ${RUNTIME_SRC_ROOT}/proj.win32/game.rc)
+ list(APPEND GAME_HEADER
+ ${RUNTIME_SRC_ROOT}/proj.win32/main.h
+ ${RUNTIME_SRC_ROOT}/proj.win32/resource.h
+ )
+ list(APPEND GAME_SOURCE ${WINDOWS_SRC} ${cc_common_res})
+elseif(APPLE)
+ if(IOS)
+ list(APPEND GAME_HEADER
+ ${RUNTIME_SRC_ROOT}/proj.ios_mac/ios/AppController.h
+ ${RUNTIME_SRC_ROOT}/proj.ios_mac/ios/RootViewController.h
+ )
+ set(APP_UI_RES
+ ${RUNTIME_SRC_ROOT}/proj.ios_mac/ios/LaunchScreen.storyboard
+ ${RUNTIME_SRC_ROOT}/proj.ios_mac/ios/LaunchScreenBackground.png
+ ${RUNTIME_SRC_ROOT}/proj.ios_mac/ios/Images.xcassets
+ )
+ list(APPEND GAME_SOURCE
+ ${RUNTIME_SRC_ROOT}/proj.ios_mac/ios/main.m
+ ${RUNTIME_SRC_ROOT}/proj.ios_mac/ios/AppController.mm
+ ${RUNTIME_SRC_ROOT}/proj.ios_mac/ios/RootViewController.mm
+ ${RUNTIME_SRC_ROOT}/proj.ios_mac/ios/Prefix.pch
+ ${APP_UI_RES}
+ )
+ elseif(MACOSX)
+ set(APP_UI_RES
+ ${RUNTIME_SRC_ROOT}/proj.ios_mac/mac/Icon.icns
+ ${RUNTIME_SRC_ROOT}/proj.ios_mac/mac/Info.plist
+ )
+ list(APPEND GAME_SOURCE
+ ${RUNTIME_SRC_ROOT}/proj.ios_mac/mac/main.cpp
+ ${RUNTIME_SRC_ROOT}/proj.ios_mac/mac/Prefix.pch
+ ${APP_UI_RES}
+ )
+ endif()
+ list(APPEND GAME_SOURCE ${cc_common_res})
+endif()
+
+set(APP_SRC ${GAME_HEADER} ${GAME_SOURCE})
+
+# mark app complie info and libs info
+if(NOT ANDROID)
+ add_executable(${APP_NAME} ${APP_SRC})
+else()
+ add_library(${APP_NAME} SHARED ${APP_SRC})
+ add_subdirectory(${COCOS2DX_ROOT_PATH}/cocos/platform/android ${ENGINE_BINARY_PATH}/cocos/platform)
+ target_link_libraries(${APP_NAME} -Wl,--whole-archive cpp_android_spec -Wl,--no-whole-archive)
+ add_subdirectory(${COCOS2DX_ROOT_PATH}/cocos/scripting/js-bindings/proj.android ${ENGINE_BINARY_PATH}/cocos/js-android)
+ target_link_libraries(${APP_NAME} -Wl,--whole-archive js_android_spec -Wl,--no-whole-archive)
+endif()
+
+target_link_libraries(${APP_NAME} jscocos2d)
+target_include_directories(${APP_NAME} PRIVATE ${RUNTIME_SRC_ROOT}/Classes)
+
+# mark app resources, resource will be copy auto after mark
+setup_cocos_app_config(${APP_NAME})
+if(APPLE)
+ set_target_properties(${APP_NAME} PROPERTIES RESOURCE "${APP_UI_RES}")
+ if(MACOSX)
+ set_target_properties(${APP_NAME} PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST "${RUNTIME_SRC_ROOT}/proj.ios_mac/mac/Info.plist"
+ )
+ elseif(IOS)
+ cocos_pak_xcode(${APP_NAME} INFO_PLIST "iOSBundleInfo.plist.in")
+ set_xcode_property(${APP_NAME} ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon")
+ set_xcode_property(${APP_NAME} DEVELOPMENT_TEAM "")
+ set_xcode_property(${APP_NAME} CODE_SIGN_IDENTITY "iPhone Developer")
+ endif()
+elseif(WINDOWS)
+ cocos_copy_target_dll(${APP_NAME})
+endif()
+# copy resource on linux or WINDOWS
+if(LINUX OR WINDOWS)
+ set(APP_RES_DIR "$/Resources")
+ cocos_copy_target_res(${APP_NAME} COPY_TO ${APP_RES_DIR} FILES ${res_main_files})
+ cocos_copy_target_res(${APP_NAME} COPY_TO ${APP_RES_DIR}/res FOLDERS ${res_res_folders})
+ cocos_copy_target_res(${APP_NAME} COPY_TO ${APP_RES_DIR}/src FOLDERS ${res_src_folders})
+ cocos_copy_target_res(${APP_NAME} COPY_TO ${APP_RES_DIR}/script FOLDERS ${res_script_folders})
+endif()
+
diff --git a/frameworks/cocos2d-html5/.gitignore b/frameworks/cocos2d-html5/.gitignore
new file mode 100644
index 0000000..73b9c1a
--- /dev/null
+++ b/frameworks/cocos2d-html5/.gitignore
@@ -0,0 +1,10 @@
+lib
+/web.config
+.idea
+build
+aspnet_client
+node_modules
+/tools/jsdoc_toolkit-2.4.0
+/package
+/tools/jsdoc_toolkit/jsdoc_toolkit-2.4.0
+/.project
diff --git a/frameworks/cocos2d-html5/Base64Images.js b/frameworks/cocos2d-html5/Base64Images.js
new file mode 100644
index 0000000..0d98350
--- /dev/null
+++ b/frameworks/cocos2d-html5/Base64Images.js
@@ -0,0 +1,32 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+var cc = cc || {};
+
+cc._loadingImage = "data:image/gif;base64,R0lGODlhEAAQALMNAD8/P7+/vyoqKlVVVX9/fxUVFUBAQGBgYMDAwC8vL5CQkP///wAAAP///wAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFAAANACwAAAAAEAAQAAAEO5DJSau9OOvNex0IMnDIsiCkiW6g6BmKYlBFkhSUEgQKlQCARG6nEBwOgl+QApMdCIRD7YZ5RjlGpCUCACH5BAUAAA0ALAAAAgAOAA4AAAQ6kLGB0JA4M7QW0hrngRllkYyhKAYqKUGguAws0ypLS8JxCLQDgXAIDg+FRKIA6v0SAECCBpXSkstMBAAh+QQFAAANACwAAAAACgAQAAAEOJDJORAac6K1kDSKYmydpASBUl0mqmRfaGTCcQgwcxDEke+9XO2WkxQSiUIuAQAkls0n7JgsWq8RACH5BAUAAA0ALAAAAAAOAA4AAAQ6kMlplDIzTxWC0oxwHALnDQgySAdBHNWFLAvCukc215JIZihVIZEogDIJACBxnCSXTcmwGK1ar1hrBAAh+QQFAAANACwAAAAAEAAKAAAEN5DJKc4RM+tDyNFTkSQF5xmKYmQJACTVpQSBwrpJNteZSGYoFWjIGCAQA2IGsVgglBOmEyoxIiMAIfkEBQAADQAsAgAAAA4ADgAABDmQSVZSKjPPBEDSGucJxyGA1XUQxAFma/tOpDlnhqIYN6MEAUXvF+zldrMBAjHoIRYLhBMqvSmZkggAIfkEBQAADQAsBgAAAAoAEAAABDeQyUmrnSWlYhMASfeFVbZdjHAcgnUQxOHCcqWylKEohqUEAYVkgEAMfkEJYrFA6HhKJsJCNFoiACH5BAUAAA0ALAIAAgAOAA4AAAQ3kMlJq704611SKloCAEk4lln3DQgyUMJxCBKyLAh1EMRR3wiDQmHY9SQslyIQUMRmlmVTIyRaIgA7";
+
+cc._fpsImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAAgCAYAAAD9qabkAAAKQ2lDQ1BJQ0MgcHJvZmlsZQAAeNqdU3dYk/cWPt/3ZQ9WQtjwsZdsgQAiI6wIyBBZohCSAGGEEBJAxYWIClYUFRGcSFXEgtUKSJ2I4qAouGdBiohai1VcOO4f3Ke1fXrv7e371/u855zn/M55zw+AERImkeaiagA5UoU8Otgfj09IxMm9gAIVSOAEIBDmy8JnBcUAAPADeXh+dLA//AGvbwACAHDVLiQSx+H/g7pQJlcAIJEA4CIS5wsBkFIAyC5UyBQAyBgAsFOzZAoAlAAAbHl8QiIAqg0A7PRJPgUA2KmT3BcA2KIcqQgAjQEAmShHJAJAuwBgVYFSLALAwgCgrEAiLgTArgGAWbYyRwKAvQUAdo5YkA9AYACAmUIszAAgOAIAQx4TzQMgTAOgMNK/4KlfcIW4SAEAwMuVzZdL0jMUuJXQGnfy8ODiIeLCbLFCYRcpEGYJ5CKcl5sjE0jnA0zODAAAGvnRwf44P5Dn5uTh5mbnbO/0xaL+a/BvIj4h8d/+vIwCBAAQTs/v2l/l5dYDcMcBsHW/a6lbANpWAGjf+V0z2wmgWgrQevmLeTj8QB6eoVDIPB0cCgsL7SViob0w44s+/zPhb+CLfvb8QB7+23rwAHGaQJmtwKOD/XFhbnauUo7nywRCMW735yP+x4V//Y4p0eI0sVwsFYrxWIm4UCJNx3m5UpFEIcmV4hLpfzLxH5b9CZN3DQCshk/ATrYHtctswH7uAQKLDljSdgBAfvMtjBoLkQAQZzQyefcAAJO/+Y9AKwEAzZek4wAAvOgYXKiUF0zGCAAARKCBKrBBBwzBFKzADpzBHbzAFwJhBkRADCTAPBBCBuSAHAqhGJZBGVTAOtgEtbADGqARmuEQtMExOA3n4BJcgetwFwZgGJ7CGLyGCQRByAgTYSE6iBFijtgizggXmY4EImFINJKApCDpiBRRIsXIcqQCqUJqkV1II/ItchQ5jVxA+pDbyCAyivyKvEcxlIGyUQPUAnVAuagfGorGoHPRdDQPXYCWomvRGrQePYC2oqfRS+h1dAB9io5jgNExDmaM2WFcjIdFYIlYGibHFmPlWDVWjzVjHVg3dhUbwJ5h7wgkAouAE+wIXoQQwmyCkJBHWExYQ6gl7CO0EroIVwmDhDHCJyKTqE+0JXoS+cR4YjqxkFhGrCbuIR4hniVeJw4TX5NIJA7JkuROCiElkDJJC0lrSNtILaRTpD7SEGmcTCbrkG3J3uQIsoCsIJeRt5APkE+S+8nD5LcUOsWI4kwJoiRSpJQSSjVlP+UEpZ8yQpmgqlHNqZ7UCKqIOp9aSW2gdlAvU4epEzR1miXNmxZDy6Qto9XQmmlnafdoL+l0ugndgx5Fl9CX0mvoB+nn6YP0dwwNhg2Dx0hiKBlrGXsZpxi3GS+ZTKYF05eZyFQw1zIbmWeYD5hvVVgq9ip8FZHKEpU6lVaVfpXnqlRVc1U/1XmqC1SrVQ+rXlZ9pkZVs1DjqQnUFqvVqR1Vu6k2rs5Sd1KPUM9RX6O+X/2C+mMNsoaFRqCGSKNUY7fGGY0hFsYyZfFYQtZyVgPrLGuYTWJbsvnsTHYF+xt2L3tMU0NzqmasZpFmneZxzQEOxrHg8DnZnErOIc4NznstAy0/LbHWaq1mrX6tN9p62r7aYu1y7Rbt69rvdXCdQJ0snfU6bTr3dQm6NrpRuoW623XP6j7TY+t56Qn1yvUO6d3RR/Vt9KP1F+rv1u/RHzcwNAg2kBlsMThj8MyQY+hrmGm40fCE4agRy2i6kcRoo9FJoye4Ju6HZ+M1eBc+ZqxvHGKsNN5l3Gs8YWJpMtukxKTF5L4pzZRrmma60bTTdMzMyCzcrNisyeyOOdWca55hvtm82/yNhaVFnMVKizaLx5balnzLBZZNlvesmFY+VnlW9VbXrEnWXOss623WV2xQG1ebDJs6m8u2qK2brcR2m23fFOIUjynSKfVTbtox7PzsCuya7AbtOfZh9iX2bfbPHcwcEh3WO3Q7fHJ0dcx2bHC866ThNMOpxKnD6VdnG2ehc53zNRemS5DLEpd2lxdTbaeKp26fesuV5RruutK10/Wjm7ub3K3ZbdTdzD3Ffav7TS6bG8ldwz3vQfTw91jicczjnaebp8LzkOcvXnZeWV77vR5Ps5wmntYwbcjbxFvgvct7YDo+PWX6zukDPsY+Ap96n4e+pr4i3z2+I37Wfpl+B/ye+zv6y/2P+L/hefIW8U4FYAHBAeUBvYEagbMDawMfBJkEpQc1BY0FuwYvDD4VQgwJDVkfcpNvwBfyG/ljM9xnLJrRFcoInRVaG/owzCZMHtYRjobPCN8Qfm+m+UzpzLYIiOBHbIi4H2kZmRf5fRQpKjKqLupRtFN0cXT3LNas5Fn7Z72O8Y+pjLk722q2cnZnrGpsUmxj7Ju4gLiquIF4h/hF8ZcSdBMkCe2J5MTYxD2J43MC52yaM5zkmlSWdGOu5dyiuRfm6c7Lnnc8WTVZkHw4hZgSl7I/5YMgQlAvGE/lp25NHRPyhJuFT0W+oo2iUbG3uEo8kuadVpX2ON07fUP6aIZPRnXGMwlPUit5kRmSuSPzTVZE1t6sz9lx2S05lJyUnKNSDWmWtCvXMLcot09mKyuTDeR55m3KG5OHyvfkI/lz89sVbIVM0aO0Uq5QDhZML6greFsYW3i4SL1IWtQz32b+6vkjC4IWfL2QsFC4sLPYuHhZ8eAiv0W7FiOLUxd3LjFdUrpkeGnw0n3LaMuylv1Q4lhSVfJqedzyjlKD0qWlQyuCVzSVqZTJy26u9Fq5YxVhlWRV72qX1VtWfyoXlV+scKyorviwRrjm4ldOX9V89Xlt2treSrfK7etI66Trbqz3Wb+vSr1qQdXQhvANrRvxjeUbX21K3nShemr1js20zcrNAzVhNe1bzLas2/KhNqP2ep1/XctW/a2rt77ZJtrWv913e/MOgx0VO97vlOy8tSt4V2u9RX31btLugt2PGmIbur/mft24R3dPxZ6Pe6V7B/ZF7+tqdG9s3K+/v7IJbVI2jR5IOnDlm4Bv2pvtmne1cFoqDsJB5cEn36Z8e+NQ6KHOw9zDzd+Zf7f1COtIeSvSOr91rC2jbaA9ob3v6IyjnR1eHUe+t/9+7zHjY3XHNY9XnqCdKD3x+eSCk+OnZKeenU4/PdSZ3Hn3TPyZa11RXb1nQ8+ePxd07ky3X/fJ897nj13wvHD0Ivdi2yW3S609rj1HfnD94UivW2/rZffL7Vc8rnT0Tes70e/Tf/pqwNVz1/jXLl2feb3vxuwbt24m3Ry4Jbr1+Hb27Rd3Cu5M3F16j3iv/L7a/eoH+g/qf7T+sWXAbeD4YMBgz8NZD+8OCYee/pT/04fh0kfMR9UjRiONj50fHxsNGr3yZM6T4aeypxPPyn5W/3nrc6vn3/3i+0vPWPzY8Av5i8+/rnmp83Lvq6mvOscjxx+8znk98ab8rc7bfe+477rfx70fmSj8QP5Q89H6Y8en0E/3Pud8/vwv94Tz+4A5JREAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfcAgcQLxxUBNp/AAAQZ0lEQVR42u2be3QVVZbGv1N17829eRLyIKAEOiISEtPhJTJAYuyBDmhWjAEx4iAGBhxA4wABbVAMWUAeykMCM+HRTcBRWkNH2l5moS0LCCrQTkYeQWBQSCAIgYRXEpKbW/XNH5zS4noR7faPEeu31l0h4dSpvc+t/Z199jkFWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhY/H9D/MR9qfKnLj/00U71aqfJn9+HCkCR/Wk36ddsgyJ/1wF4fkDfqqm9/gPsUeTnVr6a2xlQfnxdI7zs0W7irzD17Ytb2WT7EeNv/r4ox1O3Quf2QP2pgt9utwfout4FQE8AVBSlnaRmfvAURQkg2RlAbwB9AThlW5L0GaiKojhJhgOIBqDa7XaPrusdPtr5kQwF0BVAAoBIABRCKDd5aFUhRDAAw57eAOwAhKIoupft3zoqhB1AqLwuHIBut9uFt02qqvqRDJR2dAEQJj/BAOjn56dqmma+xiaECAEQAWAggLsB6A6HQ2iaZggBhBAqgEAAnQB0kzaEmT4hAITT6VQ8Ho/HJAKKECJQtr8LwD1y/A1/vcdfEUIEyfZ9AcQbYvZ942Px88L2UwlJR0dH0EMPPbRj5syZPUeNGrXR7Xb/641xIwJ1XY9NSUlZm52dfW+XLl1w8uRJzJ8//+OGhoYJqqqe1TSt1Wsm9NN1PSIqKmr12rVrR5WUlHy1bdu2AQCumWc3IYRD1/UwVVXnFRQUTIuNjUVzczN2797dWFJSkq8oymZd15sAGAEnFEUJ1nX9nzIzM1dnZmZGh4SE4OTJk5g5c+Zf29vbp9pstrMej6fVOyhIhgAYU1hY+B+hoaGoqKg4XVlZea+XTULTNFdCQsLGiRMnPuR2u3UhBOV9eeDAAWXTpk095DUe6WsoyRE5OTlr0tLSAux2O/bs2cO5c+e+pijKUpIXSHaQVAGkvPLKK++6XK4OksJLCFlXV2cvKSlJBFAjhU+x2WwhHo9nUHp6+urMzMy7wsLCUF9fjxdffPHjxsbGiTab7WuPx9NiEutOuq4PyMjI+M+srKyYqKgoHD58GDNmzNjq8XhyVFU9b/q+LH7hBAEYu3PnTlZVVRFAGgCX6f/tAHoOHDjwa0p27txp/JO9e/f+QM7cipw9nfL3kQBKt2zZQpJ87rnn6mQmoHilw2EACs+cOUOSrK+vZ1NTE0nyo48+IoBpxswoBcMJ4Ndjx471kOTFixe5d+9ekqTH42H//v13A4jyzpAURfEH0H/OnDnthu1z5sw558MmFUCPWbNmnaMP3nrrLZoyDmP8Hl68eDFJ8siRI9/Yc+zYMQKYKdtAztrTrl27xptRXV1NAKMAOAyBBBA/Y8aMdpLs6Ojgxx9//E37+++//29yvFXppwvAwMcee8xjtDHsuXLlCqOjo//ia3wsfpkoALqFhoZuIckJEyackimm3dQmEMDUmpoakmRISMhhAHOHDx/eQJIbN24kgKEyMAHAFRMTs2XXrl1saWkhSZ0kp0+ffhrAr3wEW/S8efOukORLL72kA1gKYMPWrVtJkk899dRJAHeYrgsEsIQkjx8/TgDvAPjd448/3kaSb7zxBmUa7vC6z53BwcFbSHL9+vU6Sc6aNes8gF5ewWAH0PfVV18lSQL4DMBGIcQ6AKtcLleBFC2jXtFt8ODBe0iyoqKCAJYByC8qKmJDQwOzsrK+MAmqo1OnTveHhoa+GRkZ+XZkZOSWiIiIvzgcjk9mzpypkWRmZuZpmbYbGV4AgPnNzc1sa2sjgN0A5iQmJtaSZHl5OQHcb/K3s81mW0uSTU1NBFAFYFbfvn1Pk+Tbb79NAA8IIVzW42/hByA+Pz/fLR/2ZXIda05NI/z9/TeR5J49ewhgqlxTrtI0jY2NjQQw3zTLuWJiYjaUlJToS5Ys6fjkk080kwDEeAmADcA9GzZsIElGRUW9CyAWwLApU6Y0kOSKFSsog9QICGdERMTGsrIyZmVlEcC9AB4IDw/fTpLbtm0jgN94CUAnAJmVlZVcs2aNZ/LkyRdJcvbs2b4EwAkgZfPmzTxw4AABFAN4BkC6vFeUSewcAO5duXIlSTIhIaEawGMAxgKYAmAGgCS73e5vrKVk/yGythANYEhCQsIhkly+fDkBpKqqGmL6DgIALDKN/3yZpVWQZGVlJQE8aPI3KiMjo5okV61aRQAjAPQBMPfIkSN0u90EUCBtsPiFEwpgbn19PdetW2fM5N4zQ9ekpKQqkty0aRMBpMjiWM6JEydIkoqirJUFJ6iq6pAPVy8A6cZMehMBUACEuVyuFwG8HBwcPEIWx367ZMkSjSQXLVrUJouTRorrkAHdA8BdQogsAOsKCwtJkmPGjDkvMw2bDDo/ADEjRoz4XylyFbm5uY0mAbjLyyZ/AOOrq6tZVlbWsWDBgo69e/eyoqKCgwcPPg4gSQaoIRbp27dvN7KF+tLSUr28vJwFBQXtMpvpYRIM7+wrAkDeqVOnePbsWQIoNKfzpiXPg8uXLydJJicnNwF4f+nSpW6STEtLq5fjYwhk1wkTJtSQ5Ouvv04AqTKj+N2xY8dIkgEBAW/Ie1v8wncRegwZMmQvSfbr12+3Ua33WqPfOWbMmP0kWVpaSgCDZAqcfejQIWNZsEGKgvnh9gfQb9myZd8nAEJVVZtMkUNk8CcNHTq0liR1XWdYWNhmH1mJIme80OnTp18x1rp5eXkEsNJms92Fb7e/IgEsvHz5Mp999tkmAI/l5uZeMC0B7vEqqAYAyL106RJJsra2lpWVld+sucePH38ZQG+5NncBeOrgwYMkqbe3t/Po0aOsra011wAWyl0H7x0JJ4DE+fPnu0kyPT29DsDdUrBuyNKEEAkAdpw/f/6GeoEM8GUmfwEgPCIiopwkGxsbabPZPgOw6L777vvm4p49e26VGYjFLxUhhD+ApLKyMp44ccIoVnXybgbgzkcfffRzklyzZg0BDJYCMMmoCwQFBXkLgLGWvvcWAgBToSsKwNPTp09vMR7UuLi4rwH0lgU8c/Db5ezbeeTIkRWzZ8++aMxu+fn5BPCADBwHgP4LFy701NXVEUAJgAnPP/98kyxMNgHo53A4zH77BQQETMvPz7+Um5vbBuAlAFMSExPPmdbVL0qh8Acw8fDhw5SCchVAEYAVb775JknyhRdeaJYztHfxMwLAaqNwCGC2FArv8x0hAHKNLGPKlCme5OTk/Zs3bzb7O0wKiiG8KXl5ed8IxenTp0mSR48e1UmyW7duWywBuD2xyQcgFECgoih+8H1gyJgZV5Lkyy+/3CbTRIePtl2HDBmyw1QBHyGDdXZdXR1JUghRKkXBjOMHCoBdpr0L3nvvPZLkF198wejo6O0A4lVVDTb74HQ6AwD8Wq7Jh8rgGgDgQ13XjVR8qaxJuADMbmlpYXl5uV5UVNRWUFDgfv/993Vj/ZydnU1c37eHXML4S3viAcQqitJD2l104cIFY8lTKsXSBWBMVVWVcd9yed2A1NTUQ6Zl00CvLMMOoHdubm6zFIlWOf5+PsY/Kj09vdrU11QAwwGsv3jxIk21m2DZr10I0RXAuAcffPBgaWkpV69eTYfDcdiwUxY0w6xw+flX8L1xApjevXv3lREREaW6rofB93aPDUDQpEmTMgHgtddeqwBwEd/utZvpqK6uPgEAcXFxkA94NwB9unfvjrNnz4LklwDcf08iIqv66Zs2bXrl4YcfxooVKxAbG7uqrq5uAYA2TdOEqqpGYIi2tjbl6aeffu/YsWPv5uTk7JaC1wHg4Pnz542MwoVvTx+21dbWYvjw4WLixIl+2dnZ9lGjRgmSTE1NRUpKCkwFTGiaxtTU1OXTpk3707Bhw/6g67pDipnT4biuj7qut+Lbk3Vf1tTUXI9qu91Pjq1QFEUBgJaWFgBo8yGOQ8eNGxcAAOvXr/8QwBUfYygAKL169eoCABcuXACAWtn2hOGv0+kMNO1KiPDw8F4A4rZv3/7R1KlTR0+bNu1ht9u9r1+/fqitrQXJgwDarRC6/QjPzs4+QJIffPCB9/aQmSAA43ft2mW0e1QGoi8CAPyLsZccExNTC2BlRkbGRdOyYJCP2csBIN6UAZzCd7cBbQCijYp/dXU1ExMTz6SmptaMHj36f9LS0vYlJCRsl6mxIWSdu3fv/g5J7t+/nwC2AShMTk6+SJKff/45AWRLYbD7+fndAeDf5BJnLoCCyZMnt5JkdnZ2C4B/F0KEm1Pu+Pj4rST55ZdfEsBWAK+mpaVdMo3raDn7KwDuSEpK+m+S3LBhAwG8DuCtHTt2UBbpjgC408vvcFVV15HkuXPnjMp+p5uMf0RcXNyHJNnQ0EBVVfcCWBQXF3fG+Jv0yxABPwB5LS0tRmFxN4BlTzzxxGWSXLx4sS5F3GGFy+1Hp5SUlJq6ujoWFxdTpsZ2H+0iIyMj/0iSWVlZX5mr5jfJFroPGzasxlhTnjp1iiTZ3NxMl8tlrCd9pfa9SkpKSJI5OTmnZOageLUZZqxvfVFWVkZcPwdgNwnSCKPqb17jkmR8fPzfZMDZ5CRsFBmNI7h95s2b1yhT7/MAYmStwCx4vy0uLqa3v5qmEcCfvSr1QQAeXb16NY3Cm3HQ55133iGAp+SxZTNhKSkpfzUddkrFjYevzAQCeGjp0qXfsYckY2NjTwD4leGDLCL2HTdunNtoY+zWSHFcIHdsFCtcfuZ1vO9Eqs3m7/F47sb1k2qX/f3997W2tl7BjWfpBYDOzzzzzIVJkyZh0KBBCwEsB3AJvl9AETabLcDj8dwRFRW1ctasWb8JCgpSzp07d62wsPC/Wltb8xRFadR1/ZqPXYbgAQMGbI2Pjw/+6quv9ldVVT0r01ezuPRJSUn5Y9euXXVd11WzDaqq6kePHm3+7LPPRgO4KlNuxWazhXo8nuTk5OSXMjIyEl0uFxoaGtqKior+dPXq1VdUVT0jj7r68ieoT58+vx8yZMjdx48fP1JVVTVF9m20VW02WyfZf97YsWPjXS4X6urqWvPy8jYCWCyEuEDS8FdVFKWzruv//OSTTy5OTk7uqWkaPv3007qysrJ8RVH+LI8ym8/rB3Tu3HnRI488knLo0KG2ffv2ZQI4C98vP6mqqoZqmpaclpa2cOTIkX39/f3R0NDQUVxc/G5TU9PLqqrWa5rWLH1QVFUN0TStX1JSUvH48eP7BwYG4uDBg1cKCgpeBbBe2u+2Qug2EwD5N5sMPuNtMe8XP4TT6Qxoa2sbIGeXvUKIK7d4IISiKC5d1wPljOfA9bPwzYqiXNV13dd6Uqiq6qdpml2mpe02m63d4/G4vcTF5fF47LJf71nJA6BZVVW3pmntuPHlmAD5wk6Q9NnbHp9vHaqq6tA0zU/64PZhk1FfCZB9G/23ALiqKEqzD39tpvbGUqoFwFUhRLP3yzpCCDtJpxyXDulfG27+pqRR3DXsUWVd4Yq0x/taVQjhIhksC8L+ABpM9ljBf5sKwI8pIBr75L5E4vvu+UNeG/a+hv+AL7yFH8qPtOfHjtOP6V/Bja8D6z/B2Nys/1u9Xv33tLf4GfF/LC4GCJwByWIAAAAASUVORK5CYII=";
+
+cc._loaderImage = "data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAAlAAD/4QMpaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjAtYzA2MCA2MS4xMzQ3NzcsIDIwMTAvMDIvMTItMTc6MzI6MDAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjM4MDBEMDY2QTU1MjExRTFBQTAzQjEzMUNFNzMxRkQwIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjM4MDBEMDY1QTU1MjExRTFBQTAzQjEzMUNFNzMxRkQwIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzUgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkU2RTk0OEM4OERCNDExRTE5NEUyRkE3M0M3QkE1NTlEIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkU2RTk0OEM5OERCNDExRTE5NEUyRkE3M0M3QkE1NTlEIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+/+4ADkFkb2JlAGTAAAAAAf/bAIQADQkJCQoJDQoKDRMMCwwTFhENDREWGhUVFhUVGhkUFhUVFhQZGR0fIB8dGScnKionJzk4ODg5QEBAQEBAQEBAQAEODAwOEA4RDw8RFA4RDhQVERISERUfFRUXFRUfKB0ZGRkZHSgjJiAgICYjLCwoKCwsNzc1NzdAQEBAQEBAQEBA/8AAEQgAyACgAwEiAAIRAQMRAf/EALAAAAEFAQEAAAAAAAAAAAAAAAQAAgMFBgcBAQEAAwEBAAAAAAAAAAAAAAAAAQMEAgUQAAIBAgIEBwoLBgQGAwAAAAECAwAEEQUhMRIGQVFxsTITFGGBwdEiQlKSMzWRoeFicqKyI1NzFYJjJDQWB9KjVCbxwkNkJWXik3QRAAIBAgMFBQcDBQEAAAAAAAABAhEDIRIEMUFRcTJhwVIUBZGhsSJyEzOB0ULhYpIjUxX/2gAMAwEAAhEDEQA/AMJSpUqAVKlXuFAeUq9wpUB5XuFe4V6ooDzZHDox0CnGMinzwl7Z8NajaHeoO3vmTBZBtp9YUIqTEV5ROxHKnWRnaU8VRMhFBUjpV7hSoSeUq9pUB5Sr2lhQHlKvcK8oBV7hSFSRrtaKAZs07YNPM1pG2xJIAw1jSeandry/8X4m8VCKkWwaWwam7Xl/4v1W8VLtmX/i/VbxUoKkWwakSM407tmX/i/VbxUmzGwjQsjdY41IARie/U0IbZO0kNtCXnOCkEBeFu4KI3Bs7DNb27ya+jDx3kJeEnpJJEcQVbWDsk17u5urd591ucZkWhym2Vnd9RkCDEpFxDRpbw0bunu5mlp2De2FMLYXOD2wB2xbOeraUcYGJ72mlSUiqzzdzMd3Z3mixltA2yzcK/NlHM1DQyRXce1HocdNOEfJXZ88y9ZojOqhiBszIRiHQ8Y4cK5TvHuzLljHNMqxNoDjLFraHHnjPxcNCGVbxEUzYNTx5jZSxhpW6qTzlwJ+DCvO2Zf+L9VvFSgqyHYNLYNTdssPxfibxUu15f8Ai/VPiqCakOwa82DU/a8v/F+JvFTDdWPBL8R8VKCvYRYV5UzoMAy6QdIIqI0B4KJtxiRQwou16QoGUkntH5Tz0RbZbmF2hktraSVBo2lUkY8tDye0flPPXTslVUyiyVRsjqUOA4yMT8dW2ram2m6UVTNq9S7EIyUVJydMTn/6DnP+im9Wl+g5z/opvVrpteEhQWY4AaSTwAVf5WPiZh/9S5/zj7zltzlmYWkfWXNvJDGTgGcYDHirR7i7mSbwXParsFMrgb7w6jKw/wCmnc9I14kF3vpvCljbMyWMOJL4aEiB8qU/ObUK7HYWVrl1pFZWiCOCBQqKOLjPGTrNZZqKbUXVHq2nNwTuJRk1VpbgXN8s7Rk5ym0UQQzhIG2NAjhxHWbI+gCBVjBBFbwxwQqEiiUJGg1BVGAFe7dV28WYLYZFmF2Th1UD7JGjymGyn1iK5OyzIBGB1HgrLZhamzumQAGJwSqnSCh1q3GOCodxt4cxurdcpzuN4cyhiWaF5Bg09udUmnWw1H/jV9nFuJ7Quo+8h8peThFA+047vduyMtk7fYqTl07YFdfUufMPzT5p71UdtlmYXaGS2t3mQHAsgxANdadYJopLe4QS2867EsZ4QfCNYrCFbjdDPmgkYyWFxgVf04ifJf6ScNdRUW1XBb6FU5TjF5EpSSrGu/s5lN+g5z/opvVpfoOc/wCim9WtdHnatvObJXDW7xLGhB8nrPaY9/HCr+tEdPCVaSeDoYLnqF63lzW4/PFSW3ecxbI84VSzWUwUaSdg0DXXK5nvAipnd6qgKvWnQO7pri9ZUEmm3Vl2j1kr8pRlFRyquBNZjGxQ/S56Y1S2fu9OVueon11Szahoou06QoQUXadIVCD2FJJ7R+U89dMydv8Axdn+TH9muZye0flPPXQstlK5Tbka1gUjlC1q0vVLkeb6r+O3Tx9xcY1nt8c0NrZCyiOE1108NYjGv1joo7Js1jzKyScYLIvkzL6LDwHXVJksH9Sb49dKNq0tj1jA6uriOCL+02FWX7iVtZX1/AzaHTyeoauKn2MX9W79zebiZCuR5MjSrhfXuEtwTrUeZH+yNfdrRNcxI6IzhXlJEak6WIGJ2Rw4ChWnChndtlVBLMdQA0k1gbXNMzzDfDLs6mjaPKppJbWwJ1bOwwxw43OnHh71YT3DpfWUJmFlb5jHHDdeXBHIsrRea5TSqvxqG04cNN62vetoCS4tre5mgnkGE9q+3DKOkuI2WX6LDQRRHWDh1UCtwj7QRg2wdl8Djgw1qe7XvW0BQ3kfZ7mSLgU+T9E6RVbnuVrnWVSWqj+Lt8ZbRuHEdKPkYVcZ2MJY5fSGyeVar45+rkWQHAqccalPE5km1htWK5nK4Wnt5FuUBUwOMG4nGkA/BXUrW4S6torlOjMgcd/xVn7rLo7zKs0uEjCNeSvdwoBhgsZxX1l2j36k3Lu+uyprdj5Vs5A+i/lD48a0aaVJOPi7jB6lbzWozpjB48pf1NDXNN4vfl7+Z4BXS65pvF78vfzPAK71XTHmZ/S/yT+jvJ7L3fHytz1E+upbL+Qj5W56jfXWRnsIYKLtekKEFGWvSFQgyjk9o/Keet3YthlMP/5x9msJJ7R+U89biyb/AMXEv7gD6tadL1T+kwepRrC39ZkLDMbiwMvUHRPG0bjlGg8ore/23sxBldxfMPLupNhT8yL/AORNZbdzJ484scytxgLqJY5LZj6Q2sV5G1Vud1mjjyG0ij0NEGSZToKyhjtqw4waztuiXA3qKTbSxltfGhbZlE95ZtZqxVbgiOZhrER9ph3Svk9+pJILZ4Y4DGBFCUMKjRsGPobPFhUfW0NJmljE2xJcIrcI2vFUEln1lRXd6lrazXT9GCNpD+yNqoI7mOVduNw6nzlOIoPOUa6yye1XXcbMR5GdQ3xY0BSbj31/FcTQZirJ+q431q7anbHCTZ72Bw7lbPrKBMcBWNNgbMBBh+bsjBdni0VJ1lARZs6yWiupxCuMDy6KpS2IwOo6DTr3Mre3e5tZZVUM4ZBjqOOJoWO4jkXajcOOMHGgDISvWIrdAkKR80+TzVl908bPPL3LzxOuHdifxVfiTAg92qI/w+/8gGgSyN/mR7XPVlp0lF/3L3mbVKtu5Hjbk/8AHE2Fc03i9+Xv5ngFdKNc13i9+Xv5ngFaNV0x5nn+l/kn9HeEWXu+PlbnqJ9dS2Xu9OVueon11kZ7CGCjLXpCgxRlr0hUIPYUcntH5Tz1s8vb+Bt1/dqPirGSe0flPPWusG/g4Py15q06XqlyMWvVYQ+ruI9xJOqzO9hOto/sP8tbGOFIrmWeM7IuMDMnAXXQJOUjQeOsJk0nY96ip0CYunrjaHx1t+srPJUbXBm2LrFPikwTOb+T+VhbZxGMrDXp83x1QSy2tucJpUjPETp+Cn5/ftaRvKvtp3Kx48HG3erHMzOxZiWZtLMdJNQSbbL71Vk6yynViOkqnEEfOWtPbXi3EQkGg6mXiNckjeSJxJGxR10qw0GtxuxmvbImD4CZMFlA4fRfv0BqesqqzTMZNMEDbIHtHH2QeCiZJSqMQdOGiue53mz3czQwsRbIcNHnkec3c4qAMuriz68gTIToxwOOnlp0MjxMJYW741Gs3RVldtbygE/dMcHX/moDaxTiWNZB53B3arb8/wC+4SOF4sf/AKxU9kcBsfOGHfoUHtG/RbzY5Die5HHhXdvavqiZ9Q8Jdlq4/gbKua7xe/L38zwCuhpf2Uk/Zo50kmwJKIdogDjw1VzzeL35e/meAVp1LTgqY4nn+mRauzqmqwrjzCLL3fHytz1E+upLL+Qj5W56jfXWRnroYKLtekKEFF2vSFQg9hSSe0flPPWosm/hIfoLzVl5PaPynnrRWb/w0X0F5q06XqlyM2sVYx5gmbFre/t71NY2T+0h8VbSO5SWNJUOKSAMp7jDGspmMPaLRlXS6eWve1/FRO7WYdbZm1Y/eW/R7qHxHRXGojlm3ulid6aVbaW+OALvgCLq2Hm9WxHKWqjhj6xsK1e8dm15l4niG1LZkswGsxtrPeOmsvayBJA1VItlWjptLuTdPMo7LtjRDq9naK4+WF9IrUW7BaHOljGqVHB7w2hzVoZt87d8vaNYSLl02CcRsDEbJbj71Uu7UBkvJ7/D7q2QoDxySaAO8MTXdxRVMpRp5XZOWdF/ms7R5XdyKfKWJsO/5PhrG5XlNxmEywW6bTnTxAAcJNbGSMXkM1pjgbiNo1PziPJ+Os7u7m/6ReM00ZOgxSpqYYHT3wRXMKN4ll9zUG4bQfNshu8sZVuEA2hirA4qe/VOwwrVbzbww5mI44UKRRYkbWG0S3JWctbd7u5WFfOOLHiUdJqmaipfLsIsObhWe001lMkMVvJNjhghIALMcBxCs7fxXQmkupx1bXDswGPlaTidVaEyKNXkoo4eBV+Sq7L7Vs9zcBgeyQ4GQ/MB1crmoim2orezqcowTuSeEY48jQ7oZX2PLzdyLhNd6RjrEY6I7+uspvH78vfzPAK6UAAAFGAGgAcArmu8Xvy9/M8ArTfio24RW5nnaG67uou3H/KPuqT2X8hHytz1G+upLL3enK3PUb66ys9RDBRdr0hQgou06QqEGUkntH5Tz1e238vF9BeaqKT2j8p56vbb+Xi+gvNWjTdUuRn1XTHmTh8KrJTJlt8t1CPIY44cGnpJVjTJYkmjaN9Ib4u7V923njTethRauZJV3PaW1rfLIiXEDYg6R4VYc9CXW7thfOZbKdbGZtLW8uPVY/u3GrkNUkM9zlcxUjbhfWOA90cRq4gv4LhdqN+VToNYWmnRm9NNVWNTyHc6VWBv8wt4YeHqm6xyPmroq1Z7WGFLSxTq7WLSuPSdjrkfumq5yHXDUeA92oO2SKpVumNAaoJLMXH3myp0rpJ4uKhc3tbDM5BMri1zAj79j7KTiY8TcdBpcsith0286o+sPCagEX9Pzg4zXUCp6QYse8oouCG3tk6m1BYv05W6T+IdyolxbHDAAa2OgDlNCz3ryN2WxBd5PJMg1t81eId2ukqnLlTBbfcuY+9uJLiRcvtPvHdsHK+cfRHcHDWsyawjyy0WBcDI3lTP6TeIcFV+S5OmXx9bJg1048o8Cj0V8Jq2DVu09nL80up7OxHi+oal3P8AXB/IsZS8T/YOV65zvCcc7vfzPAK3ivWCz445zeH954BXOr6I8yfSfyz+jvCLP3fHytz1G+upLP3fHytz1E+usbPaQ0UXadIUIKLtekKhB7Ckk9o/Keer22/l4/oLzVRSe0flPPV7b/y8X0F5q0abqlyM+q6Y8yQsBTDMor1o8aiaE1pbluMqS3sbLLHIhSRQyngqukhaJ9uBjo+H5aOa3ao2t34qouRlLajTalGP8v0IY8ylXQ+PKPFU/bYXOLPge6CKia0LaxTOxHu1Q7cuBd9yPEJ7TbjXKO8CajbMIF6CNIeNvJHjqIWJ7tSpYkalqVblwIdyG+RGXur0hXYJFxal+Dhq5y3slkv3Y2pD0pTr+QUClpJRUdo9XW4OLrTHtM16cZLLWkeC7y4jvlNEpcRtw1Ux27Ci448NZrTFy3nn3IQWxlgGrDZ3pza7/M8ArZo+ArF5171uvp+CqdV0R5l/psUrs2vB3hdl7vTlbnqJ9dS2Xu+PlbnqJ9dY2eshooq16QoQUXa9IVCD2FLJ7RuU89WNtmUSQqkgYMgw0accKrpPaPynnrZWG4Vi+VWmY5tnMWXG+XrIYnA0rhj0mdcTgdNdwnKDqjmduM1SRR/qlr8/4KX6pa8T/BVzDuLZXudRZblmbxXcPUNPc3KqCIwrbOzgrHEnHjoyD+3eSXkht7DeKG4umDGOJVUklfouThXfmbnZ7Cvy1vt9pmv1W1+d8FL9VteJvgq5yrcOGfLmzHN80iyyETPbptAEFo2ZG8pmUa1OFNn3Ky6W/sbDKM5hv5bx2WTZA+7RF2y52WOPJTzE+z2Dy1vt9pT/AKpacTerS/U7Tib1a04/t7kDXPY03jhN0W6sQ7K7W3q2dnrMccaDy/8At80kuZfqWYxWNtlcvUPPhiGYhWDeUy7IwYU8xPs9g8tb7faUn6pacTerTxm9oOBvVq3v9z927aynuId44LiWKNnjhAXF2UYhRg516qpsryjLr21665zFLSTaK9U2GOA87SwqY37knRU+BzOzags0s1Oyr+BKM6sxwP6tSDPLMen6vy0rvdm3Sxlu7K/S7WDDrFUDUTxgnTU826eXW7KlxmqQuwDBXUKcD+1Xee/wXuKX5XDGWLapSVcOyhEM/seJ/V+WnjeGx4pPV+Wkm6kKZlFay3Jlt7iFpYZY8ASVK6DjtDDA0f8A0Tl340/1f8Ndx8xJVWXB0KbktFFpNzdVXAC/qOwA0CQni2flrO3Vwbm5lnI2TKxbDirX/wBE5d+NcfV/wVR7xZPa5U9utvI8nWhmbbw0YEAYYAVxfhfy5rlKR4Fulu6X7mW1mzT8S4Yis/5CPlbnqJ9dSWfu9OVueon11mZvQ2i7XpChKKtekKhBlNJ7R+U89bDfGTb3a3ZX0Lcj6kdY+T2j8p560288m1kWQr6MJ+ylSAr+2cnV5renjs3H1loX+3j9XvbbtxLN9lqW4UnV5jdnjtXHxihtyZNjeSBu5J9k1BJe7xy7W5CJ/wCzuD/mTVTf2+fq97LJuLrPsNRueS7W6aJ/38x+vLVXuY+xvHaNxbf2GoCezf8A36j/APsSf8w1sLnqczTefJluYoLm5uo5F61sBshItP1cNFYe1f8A3ir/APfE/wCZUe9bB94r5jwuPsrQFhmG4l/Z2M17HdW90tuu3IkTHaCjWdIw0VVZdks9/C06yJFEp2dp+E1bbqybGTZ8vpQD7L1XRv8A7blT96Oda7tpNuuNE37Cq9KSisjyuUoxrStKllHbLlWTXsMs8chuSuwEPDqwoLe5y+YRE/gLzmqRekvKKtd4327yM/ulHxmrHJStySWVRyrjxKI2XC/CTlnlPPKTpTdFbP0L1bgrf5Lp0G3dPhQHwV0S1lzBsns3sESR8Crh9WAJGjSOKuU3E+zdZQ3oJh8IArdZXFDmOTpHa3i2+YrI2KtKy4ricBsBuHHgFXSo440+Wa2qqxjvM9uMoy+WvzWpLCWWWE28HxL6e43ojgkeSCBY1Ri5BGIUDT51cl3vm276BBqSEH4WbxV0tlkyXJcxTMb+OW6uY9mGHrCzDQwwAbTp2uKuTZ9N1uYsfRRR8WPhrm419mSSjRyiqxVK7y23B/ftuTm2oSdJyzNVw3BFn7vTlbnqF9dS2fu9OVueon11lZuQ2iLdsGFD05H2dNQGV0ntG5Tz1dWm9N1b2kVq8EVwsI2UaQaQOKhmitZGLOmk68DhSFvY+gfWNSAg7z3Qvo7yKCKIohiaNR5LKxx8qpxvjcqS0VpbxvwOAcRQPZ7D0G9Y0uz2HoH1jUCpLY7zXlpbm3eKO5QuzjrBqZji3x17PvNcyT288VvDBJbMWUovS2hslW7mFQ9nsPQPrGl2ew9A+saCod/WNxtbYsrfb17WBxx5ddD2281xC88klvDcSXEnWuzrqOGGC9zRUPZ7D0G9Y0uzWHoH1jQVCLreq6ntZbaO3it1mGy7RjTs1X2mYy20ZiCq8ZOODcdEdmsPQb1jS7PYegfWNdJuLqnQiSUlRqpFLmryxtH1Ma7Qw2gNNPOdSt0oI27p007s9h6B9Y0uz2HoH1jXX3Z+I4+1b8IJdX89xLHKQFMXQUahpxoiPN5P+onfU+A0/s9h6DesaXZ7D0D6xpG7OLbUtu0StW5JJx2bBsmbtiSiEk+cxoCWWSaVpZOk2vDVo0VYdnsPQb1jSNvZcCH1jSd2c+p1XAmFqEOmOPEfaH+BQd1ueo211IzrgFUYKNAAqI1WztCpUqVCRUqVKgFSpUqAVKlSoBUqVKgFSpUqAVKlSoBUqVKgFSpUqAVKlSoD/9k=";
diff --git a/frameworks/cocos2d-html5/CCBoot.js b/frameworks/cocos2d-html5/CCBoot.js
new file mode 100644
index 0000000..22c5049
--- /dev/null
+++ b/frameworks/cocos2d-html5/CCBoot.js
@@ -0,0 +1,2899 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2015 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The main namespace of Cocos2d-JS, all engine core classes, functions, properties and constants are defined in this namespace
+ * @namespace
+ * @name cc
+ */
+var cc = cc || {};
+cc._tmp = cc._tmp || {};
+cc._LogInfos = {};
+
+var _p = window;
+/** @expose */
+_p.gl;
+/** @expose */
+_p.WebGLRenderingContext;
+/** @expose */
+_p.DeviceOrientationEvent;
+/** @expose */
+_p.DeviceMotionEvent;
+/** @expose */
+_p.AudioContext;
+if (!_p.AudioContext) {
+ /** @expose */
+ _p.webkitAudioContext;
+}
+/** @expose */
+_p.mozAudioContext;
+_p = Object.prototype;
+/** @expose */
+_p._super;
+/** @expose */
+_p.ctor;
+_p = null;
+
+/**
+ * drawing primitive of game engine
+ * @type {cc.DrawingPrimitive}
+ */
+cc._drawingUtil = null;
+
+/**
+ * main Canvas 2D/3D Context of game engine
+ * @type {CanvasRenderingContext2D|WebGLRenderingContext}
+ */
+cc._renderContext = null;
+cc._supportRender = false;
+
+/**
+ * Main canvas of game engine
+ * @type {HTMLCanvasElement}
+ */
+cc._canvas = null;
+
+/**
+ * The element contains the game canvas
+ * @type {HTMLDivElement}
+ */
+cc.container = null;
+cc._gameDiv = null;
+
+window.ENABLE_IMAEG_POOL = true;
+
+/**
+ * Iterate over an object or an array, executing a function for each matched element.
+ * @param {object|array} obj
+ * @param {function} iterator
+ * @param {object} [context]
+ */
+cc.each = function (obj, iterator, context) {
+ if (!obj)
+ return;
+ if (obj instanceof Array) {
+ for (var i = 0, li = obj.length; i < li; i++) {
+ if (iterator.call(context, obj[i], i) === false)
+ return;
+ }
+ } else {
+ for (var key in obj) {
+ if (iterator.call(context, obj[key], key) === false)
+ return;
+ }
+ }
+};
+
+/**
+ * Copy all of the properties in source objects to target object and return the target object.
+ * @param {object} target
+ * @param {object} *sources
+ * @returns {object}
+ */
+cc.extend = function (target) {
+ var sources = arguments.length >= 2 ? Array.prototype.slice.call(arguments, 1) : [];
+
+ cc.each(sources, function (src) {
+ for (var key in src) {
+ if (src.hasOwnProperty(key)) {
+ target[key] = src[key];
+ }
+ }
+ });
+ return target;
+};
+
+/**
+ * Another way to subclass: Using Google Closure.
+ * The following code was copied + pasted from goog.base / goog.inherits
+ * @function
+ * @param {Function} childCtor
+ * @param {Function} parentCtor
+ */
+cc.inherits = function (childCtor, parentCtor) {
+ function tempCtor() {}
+ tempCtor.prototype = parentCtor.prototype;
+ childCtor.superClass_ = parentCtor.prototype;
+ childCtor.prototype = new tempCtor();
+ childCtor.prototype.constructor = childCtor;
+
+ // Copy "static" method, but doesn't generate subclasses.
+ // for( var i in parentCtor ) {
+ // childCtor[ i ] = parentCtor[ i ];
+ // }
+};
+
+/**
+ * Check the obj whether is function or not
+ * @param {*} obj
+ * @returns {boolean}
+ */
+cc.isFunction = function (obj) {
+ return typeof obj === 'function';
+};
+
+/**
+ * Check the obj whether is number or not
+ * @param {*} obj
+ * @returns {boolean}
+ */
+cc.isNumber = function (obj) {
+ return typeof obj === 'number' || Object.prototype.toString.call(obj) === '[object Number]';
+};
+
+/**
+ * Check the obj whether is string or not
+ * @param {*} obj
+ * @returns {boolean}
+ */
+cc.isString = function (obj) {
+ return typeof obj === 'string' || Object.prototype.toString.call(obj) === '[object String]';
+};
+
+/**
+ * Check the obj whether is array or not
+ * @param {*} obj
+ * @returns {boolean}
+ */
+cc.isArray = function (obj) {
+ return Array.isArray(obj) ||
+ (typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object Array]');
+};
+
+/**
+ * Check the obj whether is undefined or not
+ * @param {*} obj
+ * @returns {boolean}
+ */
+cc.isUndefined = function (obj) {
+ return typeof obj === 'undefined';
+};
+
+/**
+ * Check the obj whether is object or not
+ * @param {*} obj
+ * @returns {boolean}
+ */
+cc.isObject = function (obj) {
+ return typeof obj === "object" && Object.prototype.toString.call(obj) === '[object Object]';
+};
+
+/**
+ * Check the url whether cross origin
+ * @param {String} url
+ * @returns {boolean}
+ */
+cc.isCrossOrigin = function (url) {
+ if (!url) {
+ cc.log("invalid URL");
+ return false;
+ }
+ var startIndex = url.indexOf("://");
+ if (startIndex === -1)
+ return false;
+
+ var endIndex = url.indexOf("/", startIndex + 3);
+ var urlOrigin = (endIndex === -1) ? url : url.substring(0, endIndex);
+ return urlOrigin !== location.origin;
+};
+
+//+++++++++++++++++++++++++something about async begin+++++++++++++++++++++++++++++++
+/**
+ * Async Pool class, a helper of cc.async
+ * @param {Object|Array} srcObj
+ * @param {Number} limit the limit of parallel number
+ * @param {function} iterator
+ * @param {function} onEnd
+ * @param {object} target
+ * @constructor
+ */
+cc.AsyncPool = function (srcObj, limit, iterator, onEnd, target) {
+ var self = this;
+ self._finished = false;
+ self._srcObj = srcObj;
+ self._limit = limit;
+ self._pool = [];
+ self._iterator = iterator;
+ self._iteratorTarget = target;
+ self._onEnd = onEnd;
+ self._onEndTarget = target;
+ self._results = srcObj instanceof Array ? [] : {};
+ self._errors = srcObj instanceof Array ? [] : {};
+
+ cc.each(srcObj, function (value, index) {
+ self._pool.push({index: index, value: value});
+ });
+
+ self.size = self._pool.length;
+ self.finishedSize = 0;
+ self._workingSize = 0;
+
+ self._limit = self._limit || self.size;
+
+ self.onIterator = function (iterator, target) {
+ self._iterator = iterator;
+ self._iteratorTarget = target;
+ };
+
+ self.onEnd = function (endCb, endCbTarget) {
+ self._onEnd = endCb;
+ self._onEndTarget = endCbTarget;
+ };
+
+ self._handleItem = function () {
+ var self = this;
+ if (self._pool.length === 0 || self._workingSize >= self._limit)
+ return; //return directly if the array's length = 0 or the working size great equal limit number
+
+ var item = self._pool.shift();
+ var value = item.value, index = item.index;
+ self._workingSize++;
+ self._iterator.call(self._iteratorTarget, value, index,
+ function (err, result) {
+ if (self._finished) {
+ return;
+ }
+
+ if (err) {
+ self._errors[this.index] = err;
+ }
+ else {
+ self._results[this.index] = result;
+ }
+
+ self.finishedSize++;
+ self._workingSize--;
+ if (self.finishedSize === self.size) {
+ var errors = self._errors.length === 0 ? null : self._errors;
+ self.onEnd(errors, self._results);
+ return;
+ }
+ self._handleItem();
+ }.bind(item),
+ self);
+ };
+
+ self.flow = function () {
+ var self = this;
+ if (self._pool.length === 0) {
+ if (self._onEnd)
+ self._onEnd.call(self._onEndTarget, null, []);
+ return;
+ }
+ for (var i = 0; i < self._limit; i++)
+ self._handleItem();
+ };
+
+ self.onEnd = function(errors, results) {
+ self._finished = true;
+ if (self._onEnd) {
+ var selector = self._onEnd;
+ var target = self._onEndTarget;
+ self._onEnd = null;
+ self._onEndTarget = null;
+ selector.call(target, errors, results);
+ }
+ };
+};
+
+/**
+ * @class
+ */
+cc.async = /** @lends cc.async# */{
+ /**
+ * Do tasks series.
+ * @param {Array|Object} tasks
+ * @param {function} [cb] callback
+ * @param {Object} [target]
+ * @return {cc.AsyncPool}
+ */
+ series: function (tasks, cb, target) {
+ var asyncPool = new cc.AsyncPool(tasks, 1, function (func, index, cb1) {
+ func.call(target, cb1);
+ }, cb, target);
+ asyncPool.flow();
+ return asyncPool;
+ },
+
+ /**
+ * Do tasks parallel.
+ * @param {Array|Object} tasks
+ * @param {function} cb callback
+ * @param {Object} [target]
+ * @return {cc.AsyncPool}
+ */
+ parallel: function (tasks, cb, target) {
+ var asyncPool = new cc.AsyncPool(tasks, 0, function (func, index, cb1) {
+ func.call(target, cb1);
+ }, cb, target);
+ asyncPool.flow();
+ return asyncPool;
+ },
+
+ /**
+ * Do tasks waterfall.
+ * @param {Array|Object} tasks
+ * @param {function} cb callback
+ * @param {Object} [target]
+ * @return {cc.AsyncPool}
+ */
+ waterfall: function (tasks, cb, target) {
+ var args = [];
+ var lastResults = [null];//the array to store the last results
+ var asyncPool = new cc.AsyncPool(tasks, 1,
+ function (func, index, cb1) {
+ args.push(function (err) {
+ args = Array.prototype.slice.call(arguments, 1);
+ if (tasks.length - 1 === index) lastResults = lastResults.concat(args);//while the last task
+ cb1.apply(null, arguments);
+ });
+ func.apply(target, args);
+ }, function (err) {
+ if (!cb)
+ return;
+ if (err)
+ return cb.call(target, err);
+ cb.apply(target, lastResults);
+ });
+ asyncPool.flow();
+ return asyncPool;
+ },
+
+ /**
+ * Do tasks by iterator.
+ * @param {Array|Object} tasks
+ * @param {function|Object} iterator
+ * @param {function} [callback]
+ * @param {Object} [target]
+ * @return {cc.AsyncPool}
+ */
+ map: function (tasks, iterator, callback, target) {
+ var locIterator = iterator;
+ if (typeof(iterator) === "object") {
+ callback = iterator.cb;
+ target = iterator.iteratorTarget;
+ locIterator = iterator.iterator;
+ }
+ var asyncPool = new cc.AsyncPool(tasks, 0, locIterator, callback, target);
+ asyncPool.flow();
+ return asyncPool;
+ },
+
+ /**
+ * Do tasks by iterator limit.
+ * @param {Array|Object} tasks
+ * @param {Number} limit
+ * @param {function} iterator
+ * @param {function} cb callback
+ * @param {Object} [target]
+ */
+ mapLimit: function (tasks, limit, iterator, cb, target) {
+ var asyncPool = new cc.AsyncPool(tasks, limit, iterator, cb, target);
+ asyncPool.flow();
+ return asyncPool;
+ }
+};
+//+++++++++++++++++++++++++something about async end+++++++++++++++++++++++++++++++++
+
+//+++++++++++++++++++++++++something about path begin++++++++++++++++++++++++++++++++
+/**
+ * @class
+ */
+cc.path = /** @lends cc.path# */{
+ normalizeRE: /[^\.\/]+\/\.\.\//,
+
+ /**
+ * Join strings to be a path.
+ * @example
+ cc.path.join("a", "b.png");//-->"a/b.png"
+ cc.path.join("a", "b", "c.png");//-->"a/b/c.png"
+ cc.path.join("a", "b");//-->"a/b"
+ cc.path.join("a", "b", "/");//-->"a/b/"
+ cc.path.join("a", "b/", "/");//-->"a/b/"
+ * @returns {string}
+ */
+ join: function () {
+ var l = arguments.length;
+ var result = "";
+ for (var i = 0; i < l; i++) {
+ result = (result + (result === "" ? "" : "/") + arguments[i]).replace(/(\/|\\\\)$/, "");
+ }
+ return result;
+ },
+
+ /**
+ * Get the ext name of a path.
+ * @example
+ cc.path.extname("a/b.png");//-->".png"
+ cc.path.extname("a/b.png?a=1&b=2");//-->".png"
+ cc.path.extname("a/b");//-->null
+ cc.path.extname("a/b?a=1&b=2");//-->null
+ * @param {string} pathStr
+ * @returns {*}
+ */
+ extname: function (pathStr) {
+ var temp = /(\.[^\.\/\?\\]*)(\?.*)?$/.exec(pathStr);
+ return temp ? temp[1] : null;
+ },
+
+ /**
+ * Get the main name of a file name
+ * @param {string} fileName
+ * @returns {string}
+ */
+ mainFileName: function (fileName) {
+ if (fileName) {
+ var idx = fileName.lastIndexOf(".");
+ if (idx !== -1)
+ return fileName.substring(0, idx);
+ }
+ return fileName;
+ },
+
+ /**
+ * Get the file name of a file path.
+ * @example
+ cc.path.basename("a/b.png");//-->"b.png"
+ cc.path.basename("a/b.png?a=1&b=2");//-->"b.png"
+ cc.path.basename("a/b.png", ".png");//-->"b"
+ cc.path.basename("a/b.png?a=1&b=2", ".png");//-->"b"
+ cc.path.basename("a/b.png", ".txt");//-->"b.png"
+ * @param {string} pathStr
+ * @param {string} [extname]
+ * @returns {*}
+ */
+ basename: function (pathStr, extname) {
+ var index = pathStr.indexOf("?");
+ if (index > 0) pathStr = pathStr.substring(0, index);
+ var reg = /(\/|\\\\)([^(\/|\\\\)]+)$/g;
+ var result = reg.exec(pathStr.replace(/(\/|\\\\)$/, ""));
+ if (!result) return null;
+ var baseName = result[2];
+ if (extname && pathStr.substring(pathStr.length - extname.length).toLowerCase() === extname.toLowerCase())
+ return baseName.substring(0, baseName.length - extname.length);
+ return baseName;
+ },
+
+ /**
+ * Get dirname of a file path.
+ * @example
+ * unix
+ cc.path.driname("a/b/c.png");//-->"a/b"
+ cc.path.driname("a/b/c.png?a=1&b=2");//-->"a/b"
+ cc.path.dirname("a/b/");//-->"a/b"
+ cc.path.dirname("c.png");//-->""
+ * windows
+ cc.path.driname("a\\b\\c.png");//-->"a\b"
+ cc.path.driname("a\\b\\c.png?a=1&b=2");//-->"a\b"
+ * @param {string} pathStr
+ * @returns {*}
+ */
+ dirname: function (pathStr) {
+ return pathStr.replace(/((.*)(\/|\\|\\\\))?(.*?\..*$)?/, '$2');
+ },
+
+ /**
+ * Change extname of a file path.
+ * @example
+ cc.path.changeExtname("a/b.png", ".plist");//-->"a/b.plist"
+ cc.path.changeExtname("a/b.png?a=1&b=2", ".plist");//-->"a/b.plist?a=1&b=2"
+ * @param {string} pathStr
+ * @param {string} [extname]
+ * @returns {string}
+ */
+ changeExtname: function (pathStr, extname) {
+ extname = extname || "";
+ var index = pathStr.indexOf("?");
+ var tempStr = "";
+ if (index > 0) {
+ tempStr = pathStr.substring(index);
+ pathStr = pathStr.substring(0, index);
+ }
+ index = pathStr.lastIndexOf(".");
+ if (index < 0) return pathStr + extname + tempStr;
+ return pathStr.substring(0, index) + extname + tempStr;
+ },
+ /**
+ * Change file name of a file path.
+ * @example
+ cc.path.changeBasename("a/b/c.plist", "b.plist");//-->"a/b/b.plist"
+ cc.path.changeBasename("a/b/c.plist?a=1&b=2", "b.plist");//-->"a/b/b.plist?a=1&b=2"
+ cc.path.changeBasename("a/b/c.plist", ".png");//-->"a/b/c.png"
+ cc.path.changeBasename("a/b/c.plist", "b");//-->"a/b/b"
+ cc.path.changeBasename("a/b/c.plist", "b", true);//-->"a/b/b.plist"
+ * @param {String} pathStr
+ * @param {String} basename
+ * @param {Boolean} [isSameExt]
+ * @returns {string}
+ */
+ changeBasename: function (pathStr, basename, isSameExt) {
+ if (basename.indexOf(".") === 0) return this.changeExtname(pathStr, basename);
+ var index = pathStr.indexOf("?");
+ var tempStr = "";
+ var ext = isSameExt ? this.extname(pathStr) : "";
+ if (index > 0) {
+ tempStr = pathStr.substring(index);
+ pathStr = pathStr.substring(0, index);
+ }
+ index = pathStr.lastIndexOf("/");
+ index = index <= 0 ? 0 : index + 1;
+ return pathStr.substring(0, index) + basename + ext + tempStr;
+ },
+ //todo make public after verification
+ _normalize: function (url) {
+ var oldUrl = url = String(url);
+
+ //removing all ../
+ do {
+ oldUrl = url;
+ url = url.replace(this.normalizeRE, "");
+ } while (oldUrl.length !== url.length);
+ return url;
+ }
+};
+//+++++++++++++++++++++++++something about path end++++++++++++++++++++++++++++++++
+
+//+++++++++++++++++++++++++something about loader start+++++++++++++++++++++++++++
+/**
+ * Resource loading management. Created by in CCBoot.js as a singleton
+ * cc.loader.
+ * @name cc.Loader
+ * @class
+ * @memberof cc
+ * @see cc.loader
+ */
+
+var imagePool = {
+ _pool: new Array(10),
+ _MAX: 10,
+ _smallImg: "data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA=",
+
+ count: 0,
+ get: function () {
+ if (this.count > 0) {
+ this.count--;
+ var result = this._pool[this.count];
+ this._pool[this.count] = null;
+ return result;
+ }
+ else {
+ return new Image();
+ }
+ },
+ put: function (img) {
+ var pool = this._pool;
+ if (img instanceof HTMLImageElement && this.count < this._MAX) {
+ img.src = this._smallImg;
+ pool[this.count] = img;
+ this.count++;
+ }
+ }
+};
+
+/**
+ * Singleton instance of cc.Loader.
+ * @name cc.loader
+ * @member {cc.Loader}
+ * @memberof cc
+ */
+cc.loader = (function () {
+ var _jsCache = {}, //cache for js
+ _register = {}, //register of loaders
+ _langPathCache = {}, //cache for lang path
+ _aliases = {}, //aliases for res url
+ _queue = {}, // Callback queue for resources already loading
+ _urlRegExp = new RegExp("^(?:https?|ftp)://\\S*$", "i");
+
+ return /** @lends cc.Loader# */{
+ /**
+ * Root path of resources.
+ * @type {String}
+ */
+ resPath: "",
+
+ /**
+ * Root path of audio resources
+ * @type {String}
+ */
+ audioPath: "",
+
+ /**
+ * Cache for data loaded.
+ * @type {Object}
+ */
+ cache: {},
+
+ /**
+ * Get XMLHttpRequest.
+ * @returns {XMLHttpRequest}
+ */
+ getXMLHttpRequest: function () {
+ var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP");
+ xhr.timeout = 10000;
+ if (xhr.ontimeout === undefined) {
+ xhr._timeoutId = -1;
+ }
+ return xhr;
+ },
+
+ //@MODE_BEGIN DEV
+
+ _getArgs4Js: function (args) {
+ var a0 = args[0], a1 = args[1], a2 = args[2], results = ["", null, null];
+
+ if (args.length === 1) {
+ results[1] = a0 instanceof Array ? a0 : [a0];
+ } else if (args.length === 2) {
+ if (typeof a1 === "function") {
+ results[1] = a0 instanceof Array ? a0 : [a0];
+ results[2] = a1;
+ } else {
+ results[0] = a0 || "";
+ results[1] = a1 instanceof Array ? a1 : [a1];
+ }
+ } else if (args.length === 3) {
+ results[0] = a0 || "";
+ results[1] = a1 instanceof Array ? a1 : [a1];
+ results[2] = a2;
+ } else throw new Error("arguments error to load js!");
+ return results;
+ },
+
+ isLoading: function (url) {
+ return (_queue[url] !== undefined);
+ },
+
+ /**
+ * Load js files.
+ * If the third parameter doesn't exist, then the baseDir turns to be "".
+ *
+ * @param {string} [baseDir] The pre path for jsList or the list of js path.
+ * @param {array} jsList List of js path.
+ * @param {function} [cb] Callback function
+ * @returns {*}
+ */
+ loadJs: function (baseDir, jsList, cb) {
+ var self = this,
+ args = self._getArgs4Js(arguments);
+
+ var preDir = args[0], list = args[1], callback = args[2];
+ if (navigator.userAgent.indexOf("Trident/5") > -1) {
+ self._loadJs4Dependency(preDir, list, 0, callback);
+ } else {
+ cc.async.map(list, function (item, index, cb1) {
+ var jsPath = cc.path.join(preDir, item);
+ if (_jsCache[jsPath]) return cb1(null);
+ self._createScript(jsPath, false, cb1);
+ }, callback);
+ }
+ },
+ /**
+ * Load js width loading image.
+ *
+ * @param {string} [baseDir]
+ * @param {array} jsList
+ * @param {function} [cb]
+ */
+ loadJsWithImg: function (baseDir, jsList, cb) {
+ var self = this, jsLoadingImg = self._loadJsImg(),
+ args = self._getArgs4Js(arguments);
+ this.loadJs(args[0], args[1], function (err) {
+ if (err) throw new Error(err);
+ jsLoadingImg.parentNode.removeChild(jsLoadingImg);//remove loading gif
+ if (args[2]) args[2]();
+ });
+ },
+ _createScript: function (jsPath, isAsync, cb) {
+ var d = document, self = this, s = document.createElement('script');
+ s.async = isAsync;
+ _jsCache[jsPath] = true;
+ if (cc.game.config["noCache"] && typeof jsPath === "string") {
+ if (self._noCacheRex.test(jsPath))
+ s.src = jsPath + "&_t=" + (new Date() - 0);
+ else
+ s.src = jsPath + "?_t=" + (new Date() - 0);
+ } else {
+ s.src = jsPath;
+ }
+ s.addEventListener('load', function () {
+ s.parentNode.removeChild(s);
+ this.removeEventListener('load', arguments.callee, false);
+ cb();
+ }, false);
+ s.addEventListener('error', function () {
+ s.parentNode.removeChild(s);
+ cb("Load " + jsPath + " failed!");
+ }, false);
+ d.body.appendChild(s);
+ },
+ _loadJs4Dependency: function (baseDir, jsList, index, cb) {
+ if (index >= jsList.length) {
+ if (cb) cb();
+ return;
+ }
+ var self = this;
+ self._createScript(cc.path.join(baseDir, jsList[index]), false, function (err) {
+ if (err) return cb(err);
+ self._loadJs4Dependency(baseDir, jsList, index + 1, cb);
+ });
+ },
+ _loadJsImg: function () {
+ var d = document, jsLoadingImg = d.getElementById("cocos2d_loadJsImg");
+ if (!jsLoadingImg) {
+ jsLoadingImg = document.createElement('img');
+
+ if (cc._loadingImage)
+ jsLoadingImg.src = cc._loadingImage;
+
+ var canvasNode = d.getElementById(cc.game.config["id"]);
+ canvasNode.style.backgroundColor = "transparent";
+ canvasNode.parentNode.appendChild(jsLoadingImg);
+
+ var canvasStyle = getComputedStyle ? getComputedStyle(canvasNode) : canvasNode.currentStyle;
+ if (!canvasStyle)
+ canvasStyle = {width: canvasNode.width, height: canvasNode.height};
+ jsLoadingImg.style.left = canvasNode.offsetLeft + (parseFloat(canvasStyle.width) - jsLoadingImg.width) / 2 + "px";
+ jsLoadingImg.style.top = canvasNode.offsetTop + (parseFloat(canvasStyle.height) - jsLoadingImg.height) / 2 + "px";
+ jsLoadingImg.style.position = "absolute";
+ }
+ return jsLoadingImg;
+ },
+ //@MODE_END DEV
+
+ /**
+ * Load a single resource as txt.
+ * @param {string} url
+ * @param {function} [cb] arguments are : err, txt
+ */
+ loadTxt: function (url, cb) {
+ if (!cc._isNodeJs) {
+ var xhr = this.getXMLHttpRequest(),
+ errInfo = "load " + url + " failed!";
+ xhr.open("GET", url, true);
+ if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
+ // IE-specific logic here
+ xhr.setRequestHeader("Accept-Charset", "utf-8");
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState === 4)
+ (xhr.status === 200||xhr.status === 0) ? cb(null, xhr.responseText) : cb({status:xhr.status, errorMessage:errInfo}, null);
+ };
+ } else {
+ if (xhr.overrideMimeType) xhr.overrideMimeType("text\/plain; charset=utf-8");
+ var loadCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ if (xhr.readyState === 4) {
+ (xhr.status === 200||xhr.status === 0) ? cb(null, xhr.responseText) : cb({status:xhr.status, errorMessage:errInfo}, null);
+ }
+ };
+ var errorCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ cb({status: xhr.status, errorMessage: errInfo}, null);
+ };
+ var timeoutCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ cb({status: xhr.status, errorMessage: "Request timeout: " + errInfo}, null);
+ };
+ xhr.addEventListener('load', loadCallback);
+ xhr.addEventListener('error', errorCallback);
+ if (xhr.ontimeout === undefined) {
+ xhr._timeoutId = setTimeout(function () {
+ timeoutCallback();
+ }, xhr.timeout);
+ }
+ else {
+ xhr.addEventListener('timeout', timeoutCallback);
+ }
+ }
+ xhr.send(null);
+ } else {
+ var fs = require("fs");
+ fs.readFile(url, function (err, data) {
+ err ? cb(err) : cb(null, data.toString());
+ });
+ }
+ },
+
+ loadCsb: function(url, cb){
+ var xhr = cc.loader.getXMLHttpRequest(),
+ errInfo = "load " + url + " failed!";
+ xhr.open("GET", url, true);
+ xhr.responseType = "arraybuffer";
+
+ var loadCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ var arrayBuffer = xhr.response; // Note: not oReq.responseText
+ if (arrayBuffer) {
+ window.msg = arrayBuffer;
+ }
+ if (xhr.readyState === 4) {
+ (xhr.status === 200||xhr.status === 0) ? cb(null, xhr.response) : cb({status:xhr.status, errorMessage:errInfo}, null);
+ }
+ };
+ var errorCallback = function(){
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ cb({status:xhr.status, errorMessage:errInfo}, null);
+ };
+ var timeoutCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ cb({status: xhr.status, errorMessage: "Request timeout: " + errInfo}, null);
+ };
+ xhr.addEventListener('load', loadCallback);
+ xhr.addEventListener('error', errorCallback);
+ if (xhr.ontimeout === undefined) {
+ xhr._timeoutId = setTimeout(function () {
+ timeoutCallback();
+ }, xhr.timeout);
+ }
+ else {
+ xhr.addEventListener('timeout', timeoutCallback);
+ }
+ xhr.send(null);
+ },
+
+ /**
+ * Load a single resource as json.
+ * @param {string} url
+ * @param {function} [cb] arguments are : err, json
+ */
+ loadJson: function (url, cb) {
+ this.loadTxt(url, function (err, txt) {
+ if (err) {
+ cb(err);
+ }
+ else {
+ try {
+ var result = JSON.parse(txt);
+ }
+ catch (e) {
+ throw new Error("parse json [" + url + "] failed : " + e);
+ return;
+ }
+ cb(null, result);
+ }
+ });
+ },
+
+ _checkIsImageURL: function (url) {
+ var ext = /(\.png)|(\.jpg)|(\.bmp)|(\.jpeg)|(\.gif)/.exec(url);
+ return (ext != null);
+ },
+ /**
+ * Load a single image.
+ * @param {!string} url
+ * @param {object} [option]
+ * @param {function} callback
+ * @returns {Image}
+ */
+ loadImg: function (url, option, callback, img) {
+ var opt = {
+ isCrossOrigin: true
+ };
+ if (callback !== undefined)
+ opt.isCrossOrigin = option.isCrossOrigin === undefined ? opt.isCrossOrigin : option.isCrossOrigin;
+ else if (option !== undefined)
+ callback = option;
+
+ var texture = this.getRes(url);
+ if (texture) {
+ callback && callback(null, texture);
+ return null;
+ }
+
+ var queue = _queue[url];
+ if (queue) {
+ queue.callbacks.push(callback);
+ return queue.img;
+ }
+
+ img = img || imagePool.get();
+ if (opt.isCrossOrigin && location.origin !== "file://")
+ img.crossOrigin = "Anonymous";
+ else
+ img.crossOrigin = null;
+
+ var loadCallback = function () {
+ this.removeEventListener('load', loadCallback, false);
+ this.removeEventListener('error', errorCallback, false);
+
+ var queue = _queue[url];
+ if (queue) {
+ var callbacks = queue.callbacks;
+ for (var i = 0; i < callbacks.length; ++i) {
+ var cb = callbacks[i];
+ if (cb) {
+ cb(null, img);
+ }
+ }
+ queue.img = null;
+ delete _queue[url];
+ }
+
+ if (window.ENABLE_IMAEG_POOL && cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ imagePool.put(img);
+ }
+ };
+
+ var self = this;
+ var errorCallback = function () {
+ this.removeEventListener('load', loadCallback, false);
+ this.removeEventListener('error', errorCallback, false);
+
+ if (window.location.protocol !== 'https:' && img.crossOrigin && img.crossOrigin.toLowerCase() === "anonymous") {
+ opt.isCrossOrigin = false;
+ self.release(url);
+ cc.loader.loadImg(url, opt, callback, img);
+ } else {
+ var queue = _queue[url];
+ if (queue) {
+ var callbacks = queue.callbacks;
+ for (var i = 0; i < callbacks.length; ++i) {
+ var cb = callbacks[i];
+ if (cb) {
+ cb("load image failed");
+ }
+ }
+ queue.img = null;
+ delete _queue[url];
+ }
+
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ imagePool.put(img);
+ }
+ }
+ };
+
+ _queue[url] = {
+ img: img,
+ callbacks: callback ? [callback] : []
+ };
+
+ img.addEventListener("load", loadCallback);
+ img.addEventListener("error", errorCallback);
+ img.src = url;
+ return img;
+ },
+
+ /**
+ * Iterator function to load res
+ * @param {object} item
+ * @param {number} index
+ * @param {function} [cb]
+ * @returns {*}
+ * @private
+ */
+ _loadResIterator: function (item, index, cb) {
+ var self = this, url = null;
+ var type = item.type;
+ if (type) {
+ type = "." + type.toLowerCase();
+ url = item.src ? item.src : item.name + type;
+ } else {
+ url = item;
+ type = cc.path.extname(url);
+ }
+
+ var obj = self.getRes(url);
+ if (obj)
+ return cb(null, obj);
+ var loader = null;
+ if (type) {
+ loader = _register[type.toLowerCase()];
+ }
+ if (!loader) {
+ cc.error("loader for [" + type + "] doesn't exist!");
+ return cb();
+ }
+ var realUrl = url;
+ if (!_urlRegExp.test(url)) {
+ var basePath = loader.getBasePath ? loader.getBasePath() : self.resPath;
+ realUrl = self.getUrl(basePath, url);
+ }
+
+ if (cc.game.config["noCache"] && typeof realUrl === "string") {
+ if (self._noCacheRex.test(realUrl))
+ realUrl += "&_t=" + (new Date() - 0);
+ else
+ realUrl += "?_t=" + (new Date() - 0);
+ }
+ loader.load(realUrl, url, item, function (err, data) {
+ if (err) {
+ cc.log(err);
+ self.cache[url] = null;
+ delete self.cache[url];
+ cb({status: 520, errorMessage: err}, null);
+ } else {
+ self.cache[url] = data;
+ cb(null, data);
+ }
+ });
+ },
+ _noCacheRex: /\?/,
+
+ /**
+ * Get url with basePath.
+ * @param {string} basePath
+ * @param {string} [url]
+ * @returns {*}
+ */
+ getUrl: function (basePath, url) {
+ var self = this, path = cc.path;
+ if (basePath !== undefined && url === undefined) {
+ url = basePath;
+ var type = path.extname(url);
+ type = type ? type.toLowerCase() : "";
+ var loader = _register[type];
+ if (!loader)
+ basePath = self.resPath;
+ else
+ basePath = loader.getBasePath ? loader.getBasePath() : self.resPath;
+ }
+ url = cc.path.join(basePath || "", url);
+ if (url.match(/[\/(\\\\)]lang[\/(\\\\)]/i)) {
+ if (_langPathCache[url])
+ return _langPathCache[url];
+ var extname = path.extname(url) || "";
+ url = _langPathCache[url] = url.substring(0, url.length - extname.length) + "_" + cc.sys.language + extname;
+ }
+ return url;
+ },
+
+ /**
+ * Load resources then call the callback.
+ * @param {string} resources
+ * @param {function} [option] callback or trigger
+ * @param {function|Object} [loadCallback]
+ * @return {cc.AsyncPool}
+ */
+ load: function (resources, option, loadCallback) {
+ var self = this;
+ var len = arguments.length;
+ if (len === 0)
+ throw new Error("arguments error!");
+
+ if (len === 3) {
+ if (typeof option === "function") {
+ if (typeof loadCallback === "function")
+ option = {trigger: option, cb: loadCallback};
+ else
+ option = {cb: option, cbTarget: loadCallback};
+ }
+ } else if (len === 2) {
+ if (typeof option === "function")
+ option = {cb: option};
+ } else if (len === 1) {
+ option = {};
+ }
+
+ if (!(resources instanceof Array))
+ resources = [resources];
+ var asyncPool = new cc.AsyncPool(
+ resources, cc.CONCURRENCY_HTTP_REQUEST_COUNT,
+ function (value, index, AsyncPoolCallback, aPool) {
+ self._loadResIterator(value, index, function (err) {
+ var arr = Array.prototype.slice.call(arguments, 1);
+ if (option.trigger)
+ option.trigger.call(option.triggerTarget, arr[0], aPool.size, aPool.finishedSize); //call trigger
+ AsyncPoolCallback(err, arr[0]);
+ });
+ },
+ option.cb, option.cbTarget);
+ asyncPool.flow();
+ return asyncPool;
+ },
+
+ _handleAliases: function (fileNames, cb) {
+ var self = this;
+ var resList = [];
+ for (var key in fileNames) {
+ var value = fileNames[key];
+ _aliases[key] = value;
+ resList.push(value);
+ }
+ this.load(resList, cb);
+ },
+
+ /**
+ *
+ * Loads alias map from the contents of a filename.
+ *
+ * @note The plist file name should follow the format below:
+ *
+ *
+ *
+ *
+ * filenames
+ *
+ * sounds/click.wav
+ * sounds/click.caf
+ * sounds/endgame.wav
+ * sounds/endgame.caf
+ * sounds/gem-0.wav
+ * sounds/gem-0.caf
+ *
+ * metadata
+ *
+ * version
+ * 1
+ *
+ *
+ *
+ *
+ * @param {String} url The plist file name.
+ * @param {Function} [callback]
+ */
+ loadAliases: function (url, callback) {
+ var self = this, dict = self.getRes(url);
+ if (!dict) {
+ self.load(url, function (err, results) {
+ self._handleAliases(results[0]["filenames"], callback);
+ });
+ } else
+ self._handleAliases(dict["filenames"], callback);
+ },
+
+ /**
+ * Register a resource loader into loader.
+ * @param {string} extNames
+ * @param {function} loader
+ */
+ register: function (extNames, loader) {
+ if (!extNames || !loader) return;
+ var self = this;
+ if (typeof extNames === "string")
+ return _register[extNames.trim().toLowerCase()] = loader;
+ for (var i = 0, li = extNames.length; i < li; i++) {
+ _register["." + extNames[i].trim().toLowerCase()] = loader;
+ }
+ },
+
+ /**
+ * Get resource data by url.
+ * @param url
+ * @returns {*}
+ */
+ getRes: function (url) {
+ return this.cache[url] || this.cache[_aliases[url]];
+ },
+
+ /**
+ * Get aliase by url.
+ * @param url
+ * @returns {*}
+ */
+ _getAliase: function (url) {
+ return _aliases[url];
+ },
+
+ /**
+ * Release the cache of resource by url.
+ * @param url
+ */
+ release: function (url) {
+ var cache = this.cache;
+ var queue = _queue[url];
+ if (queue) {
+ queue.img = null;
+ delete _queue[url];
+ }
+ delete cache[url];
+ delete cache[_aliases[url]];
+ delete _aliases[url];
+ },
+
+ /**
+ * Resource cache of all resources.
+ */
+ releaseAll: function () {
+ var locCache = this.cache;
+ for (var key in locCache)
+ delete locCache[key];
+ for (var key in _aliases)
+ delete _aliases[key];
+ }
+ };
+})();
+//+++++++++++++++++++++++++something about loader end+++++++++++++++++++++++++++++
+
+/**
+ * A string tool to construct a string with format string.
+ * for example:
+ * cc.formatStr("a: %d, b: %b", a, b);
+ * cc.formatStr(a, b, c);
+ * @returns {String}
+ */
+cc.formatStr = function () {
+ var args = arguments;
+ var l = args.length;
+ if (l < 1)
+ return "";
+
+ var str = args[0];
+ var needToFormat = true;
+ if (typeof str === "object") {
+ needToFormat = false;
+ }
+ for (var i = 1; i < l; ++i) {
+ var arg = args[i];
+ if (needToFormat) {
+ while (true) {
+ var result = null;
+ if (typeof arg === "number") {
+ result = str.match(/(%d)|(%s)/);
+ if (result) {
+ str = str.replace(/(%d)|(%s)/, arg);
+ break;
+ }
+ }
+ result = str.match(/%s/);
+ if (result)
+ str = str.replace(/%s/, arg);
+ else
+ str += " " + arg;
+ break;
+ }
+ } else
+ str += " " + arg;
+ }
+ return str;
+};
+
+
+//+++++++++++++++++++++++++Engine initialization function begin+++++++++++++++++++++++++++
+(function () {
+
+var _tmpCanvas1 = document.createElement("canvas"),
+ _tmpCanvas2 = document.createElement("canvas");
+
+cc.create3DContext = function (canvas, opt_attribs) {
+ var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
+ var context = null;
+ for (var ii = 0; ii < names.length; ++ii) {
+ try {
+ context = canvas.getContext(names[ii], opt_attribs);
+ } catch (e) {
+ }
+ if (context) {
+ break;
+ }
+ }
+ return context;
+};
+
+var _initSys = function () {
+ /**
+ * System variables
+ * @namespace
+ * @name cc.sys
+ */
+ cc.sys = {};
+ var sys = cc.sys;
+
+ /**
+ * English language code
+ * @memberof cc.sys
+ * @name LANGUAGE_ENGLISH
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_ENGLISH = "en";
+
+ /**
+ * Chinese language code
+ * @memberof cc.sys
+ * @name LANGUAGE_CHINESE
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_CHINESE = "zh";
+
+ /**
+ * French language code
+ * @memberof cc.sys
+ * @name LANGUAGE_FRENCH
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_FRENCH = "fr";
+
+ /**
+ * Italian language code
+ * @memberof cc.sys
+ * @name LANGUAGE_ITALIAN
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_ITALIAN = "it";
+
+ /**
+ * German language code
+ * @memberof cc.sys
+ * @name LANGUAGE_GERMAN
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_GERMAN = "de";
+
+ /**
+ * Spanish language code
+ * @memberof cc.sys
+ * @name LANGUAGE_SPANISH
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_SPANISH = "es";
+
+ /**
+ * Spanish language code
+ * @memberof cc.sys
+ * @name LANGUAGE_DUTCH
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_DUTCH = "du";
+
+ /**
+ * Russian language code
+ * @memberof cc.sys
+ * @name LANGUAGE_RUSSIAN
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_RUSSIAN = "ru";
+
+ /**
+ * Korean language code
+ * @memberof cc.sys
+ * @name LANGUAGE_KOREAN
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_KOREAN = "ko";
+
+ /**
+ * Japanese language code
+ * @memberof cc.sys
+ * @name LANGUAGE_JAPANESE
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_JAPANESE = "ja";
+
+ /**
+ * Hungarian language code
+ * @memberof cc.sys
+ * @name LANGUAGE_HUNGARIAN
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_HUNGARIAN = "hu";
+
+ /**
+ * Portuguese language code
+ * @memberof cc.sys
+ * @name LANGUAGE_PORTUGUESE
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_PORTUGUESE = "pt";
+
+ /**
+ * Arabic language code
+ * @memberof cc.sys
+ * @name LANGUAGE_ARABIC
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_ARABIC = "ar";
+
+ /**
+ * Norwegian language code
+ * @memberof cc.sys
+ * @name LANGUAGE_NORWEGIAN
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_NORWEGIAN = "no";
+
+ /**
+ * Polish language code
+ * @memberof cc.sys
+ * @name LANGUAGE_POLISH
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_POLISH = "pl";
+
+ /**
+ * Unknown language code
+ * @memberof cc.sys
+ * @name LANGUAGE_UNKNOWN
+ * @constant
+ * @type {Number}
+ */
+ sys.LANGUAGE_UNKNOWN = "unkonwn";
+
+ /**
+ * @memberof cc.sys
+ * @name OS_IOS
+ * @constant
+ * @type {string}
+ */
+ sys.OS_IOS = "iOS";
+ /**
+ * @memberof cc.sys
+ * @name OS_ANDROID
+ * @constant
+ * @type {string}
+ */
+ sys.OS_ANDROID = "Android";
+ /**
+ * @memberof cc.sys
+ * @name OS_WINDOWS
+ * @constant
+ * @type {string}
+ */
+ sys.OS_WINDOWS = "Windows";
+ /**
+ * @memberof cc.sys
+ * @name OS_MARMALADE
+ * @constant
+ * @type {string}
+ */
+ sys.OS_MARMALADE = "Marmalade";
+ /**
+ * @memberof cc.sys
+ * @name OS_LINUX
+ * @constant
+ * @type {string}
+ */
+ sys.OS_LINUX = "Linux";
+ /**
+ * @memberof cc.sys
+ * @name OS_BADA
+ * @constant
+ * @type {string}
+ */
+ sys.OS_BADA = "Bada";
+ /**
+ * @memberof cc.sys
+ * @name OS_BLACKBERRY
+ * @constant
+ * @type {string}
+ */
+ sys.OS_BLACKBERRY = "Blackberry";
+ /**
+ * @memberof cc.sys
+ * @name OS_OSX
+ * @constant
+ * @type {string}
+ */
+ sys.OS_OSX = "OS X";
+ /**
+ * @memberof cc.sys
+ * @name OS_WP8
+ * @constant
+ * @type {string}
+ */
+ sys.OS_WP8 = "WP8";
+ /**
+ * @memberof cc.sys
+ * @name OS_WINRT
+ * @constant
+ * @type {string}
+ */
+ sys.OS_WINRT = "WINRT";
+ /**
+ * @memberof cc.sys
+ * @name OS_UNKNOWN
+ * @constant
+ * @type {string}
+ */
+ sys.OS_UNKNOWN = "Unknown";
+
+ /**
+ * @memberof cc.sys
+ * @name UNKNOWN
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.UNKNOWN = -1;
+ /**
+ * @memberof cc.sys
+ * @name WIN32
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.WIN32 = 0;
+ /**
+ * @memberof cc.sys
+ * @name LINUX
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.LINUX = 1;
+ /**
+ * @memberof cc.sys
+ * @name MACOS
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.MACOS = 2;
+ /**
+ * @memberof cc.sys
+ * @name ANDROID
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.ANDROID = 3;
+ /**
+ * @memberof cc.sys
+ * @name IOS
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.IPHONE = 4;
+ /**
+ * @memberof cc.sys
+ * @name IOS
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.IPAD = 5;
+ /**
+ * @memberof cc.sys
+ * @name BLACKBERRY
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.BLACKBERRY = 6;
+ /**
+ * @memberof cc.sys
+ * @name NACL
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.NACL = 7;
+ /**
+ * @memberof cc.sys
+ * @name EMSCRIPTEN
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.EMSCRIPTEN = 8;
+ /**
+ * @memberof cc.sys
+ * @name TIZEN
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.TIZEN = 9;
+ /**
+ * @memberof cc.sys
+ * @name WINRT
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.WINRT = 10;
+ /**
+ * @memberof cc.sys
+ * @name WP8
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.WP8 = 11;
+ /**
+ * @memberof cc.sys
+ * @name MOBILE_BROWSER
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.MOBILE_BROWSER = 100;
+ /**
+ * @memberof cc.sys
+ * @name DESKTOP_BROWSER
+ * @constant
+ * @default
+ * @type {Number}
+ */
+ sys.DESKTOP_BROWSER = 101;
+
+ sys.BROWSER_TYPE_WECHAT = "wechat";
+ sys.BROWSER_TYPE_ANDROID = "androidbrowser";
+ sys.BROWSER_TYPE_IE = "ie";
+ sys.BROWSER_TYPE_QQ_APP = "qq"; // QQ App
+ sys.BROWSER_TYPE_QQ = "qqbrowser";
+ sys.BROWSER_TYPE_MOBILE_QQ = "mqqbrowser";
+ sys.BROWSER_TYPE_UC = "ucbrowser";
+ sys.BROWSER_TYPE_360 = "360browser";
+ sys.BROWSER_TYPE_BAIDU_APP = "baiduboxapp";
+ sys.BROWSER_TYPE_BAIDU = "baidubrowser";
+ sys.BROWSER_TYPE_MAXTHON = "maxthon";
+ sys.BROWSER_TYPE_OPERA = "opera";
+ sys.BROWSER_TYPE_OUPENG = "oupeng";
+ sys.BROWSER_TYPE_MIUI = "miuibrowser";
+ sys.BROWSER_TYPE_FIREFOX = "firefox";
+ sys.BROWSER_TYPE_SAFARI = "safari";
+ sys.BROWSER_TYPE_CHROME = "chrome";
+ sys.BROWSER_TYPE_LIEBAO = "liebao";
+ sys.BROWSER_TYPE_QZONE = "qzone";
+ sys.BROWSER_TYPE_SOUGOU = "sogou";
+ sys.BROWSER_TYPE_UNKNOWN = "unknown";
+
+ /**
+ * Is native ? This is set to be true in jsb auto.
+ * @memberof cc.sys
+ * @name isNative
+ * @type {Boolean}
+ */
+ sys.isNative = false;
+
+ var win = window, nav = win.navigator, doc = document, docEle = doc.documentElement;
+ var ua = nav.userAgent.toLowerCase();
+
+ /**
+ * Indicate whether system is mobile system
+ * @memberof cc.sys
+ * @name isMobile
+ * @type {Boolean}
+ */
+ sys.isMobile = /mobile|android|iphone|ipad/.test(ua);
+
+ /**
+ * Indicate the running platform
+ * @memberof cc.sys
+ * @name platform
+ * @type {Number}
+ */
+ sys.platform = sys.isMobile ? sys.MOBILE_BROWSER : sys.DESKTOP_BROWSER;
+
+ var currLanguage = nav.language;
+ currLanguage = currLanguage ? currLanguage : nav.browserLanguage;
+ currLanguage = currLanguage ? currLanguage.split("-")[0] : sys.LANGUAGE_ENGLISH;
+
+ /**
+ * Indicate the current language of the running system
+ * @memberof cc.sys
+ * @name language
+ * @type {String}
+ */
+ sys.language = currLanguage;
+
+ // Get the os of system
+ var isAndroid = false, iOS = false, osVersion = '', osMainVersion = 0;
+ var uaResult = /android (\d+(?:\.\d+)+)/i.exec(ua) || /android (\d+(?:\.\d+)+)/i.exec(nav.platform);
+ if (uaResult) {
+ isAndroid = true;
+ osVersion = uaResult[1] || '';
+ osMainVersion = parseInt(osVersion) || 0;
+ }
+ uaResult = /(iPad|iPhone|iPod).*OS ((\d+_?){2,3})/i.exec(ua);
+ if (uaResult) {
+ iOS = true;
+ osVersion = uaResult[2] || '';
+ osMainVersion = parseInt(osVersion) || 0;
+ }
+ else if (/(iPhone|iPad|iPod)/.exec(nav.platform)) {
+ iOS = true;
+ osVersion = '';
+ osMainVersion = 0;
+ }
+
+ var osName = sys.OS_UNKNOWN;
+ if (nav.appVersion.indexOf("Win") !== -1) osName = sys.OS_WINDOWS;
+ else if (iOS) osName = sys.OS_IOS;
+ else if (nav.appVersion.indexOf("Mac") !== -1) osName = sys.OS_OSX;
+ else if (nav.appVersion.indexOf("X11") !== -1 && nav.appVersion.indexOf("Linux") === -1) osName = sys.OS_UNIX;
+ else if (isAndroid) osName = sys.OS_ANDROID;
+ else if (nav.appVersion.indexOf("Linux") !== -1) osName = sys.OS_LINUX;
+
+ /**
+ * Indicate the running os name
+ * @memberof cc.sys
+ * @name os
+ * @type {String}
+ */
+ sys.os = osName;
+ /**
+ * Indicate the running os version string
+ * @memberof cc.sys
+ * @name osVersion
+ * @type {String}
+ */
+ sys.osVersion = osVersion;
+ /**
+ * Indicate the running os main version number
+ * @memberof cc.sys
+ * @name osMainVersion
+ * @type {Number}
+ */
+ sys.osMainVersion = osMainVersion;
+
+ /**
+ * Indicate the running browser type
+ * @memberof cc.sys
+ * @name browserType
+ * @type {String}
+ */
+ sys.browserType = sys.BROWSER_TYPE_UNKNOWN;
+ /* Determine the browser type */
+ (function(){
+ var typeReg1 = /micromessenger|mqqbrowser|sogou|qzone|liebao|ucbrowser|360 aphone|360browser|baiduboxapp|baidubrowser|maxthon|mxbrowser|trident|miuibrowser/i;
+ var typeReg2 = /qqbrowser|qq|chrome|safari|firefox|opr|oupeng|opera/i;
+ var browserTypes = typeReg1.exec(ua);
+ if(!browserTypes) browserTypes = typeReg2.exec(ua);
+ var browserType = browserTypes ? browserTypes[0] : sys.BROWSER_TYPE_UNKNOWN;
+ if (browserType === 'micromessenger')
+ browserType = sys.BROWSER_TYPE_WECHAT;
+ else if (browserType === "safari" && isAndroid)
+ browserType = sys.BROWSER_TYPE_ANDROID;
+ else if (browserType === "trident")
+ browserType = sys.BROWSER_TYPE_IE;
+ else if (browserType === "360 aphone")
+ browserType = sys.BROWSER_TYPE_360;
+ else if (browserType === "mxbrowser")
+ browserType = sys.BROWSER_TYPE_MAXTHON;
+ else if (browserType === "opr")
+ browserType = sys.BROWSER_TYPE_OPERA;
+
+ sys.browserType = browserType;
+ })();
+
+ /**
+ * Indicate the running browser version
+ * @memberof cc.sys
+ * @name browserVersion
+ * @type {String}
+ */
+ sys.browserVersion = "";
+ /* Determine the browser version number */
+ (function(){
+ var versionReg1 = /(mqqbrowser|micromessenger|sogou|qzone|liebao|maxthon|mxbrowser|baidu)(mobile)?(browser)?\/?([\d.]+)/i;
+ var versionReg2 = /(msie |rv:|firefox|chrome|ucbrowser|qq|oupeng|opera|opr|safari|miui)(mobile)?(browser)?\/?([\d.]+)/i;
+ var tmp = ua.match(versionReg1);
+ if(!tmp) tmp = ua.match(versionReg2);
+ sys.browserVersion = tmp ? tmp[4] : "";
+ })();
+
+ var w = window.innerWidth || document.documentElement.clientWidth;
+ var h = window.innerHeight || document.documentElement.clientHeight;
+ var ratio = window.devicePixelRatio || 1;
+
+ /**
+ * Indicate the real pixel resolution of the whole game window
+ * @memberof cc.sys
+ * @name windowPixelResolution
+ * @type {Size}
+ */
+ sys.windowPixelResolution = {
+ width: ratio * w,
+ height: ratio * h
+ };
+
+ sys._checkWebGLRenderMode = function () {
+ if (cc._renderType !== cc.game.RENDER_TYPE_WEBGL)
+ throw new Error("This feature supports WebGL render mode only.");
+ };
+
+ //Whether or not the Canvas BlendModes are supported.
+ sys._supportCanvasNewBlendModes = (function(){
+ var canvas = _tmpCanvas1;
+ canvas.width = 1;
+ canvas.height = 1;
+ var context = canvas.getContext('2d');
+ context.fillStyle = '#000';
+ context.fillRect(0, 0, 1, 1);
+ context.globalCompositeOperation = 'multiply';
+
+ var canvas2 = _tmpCanvas2;
+ canvas2.width = 1;
+ canvas2.height = 1;
+ var context2 = canvas2.getContext('2d');
+ context2.fillStyle = '#fff';
+ context2.fillRect(0, 0, 1, 1);
+ context.drawImage(canvas2, 0, 0, 1, 1);
+
+ return context.getImageData(0, 0, 1, 1).data[0] === 0;
+ })();
+
+ // Adjust mobile css settings
+ if (cc.sys.isMobile) {
+ var fontStyle = document.createElement("style");
+ fontStyle.type = "text/css";
+ document.body.appendChild(fontStyle);
+
+ fontStyle.textContent = "body,canvas,div{ -moz-user-select: none;-webkit-user-select: none;-ms-user-select: none;-khtml-user-select: none;"
+ + "-webkit-tap-highlight-color:rgba(0,0,0,0);}";
+ }
+
+ /**
+ * cc.sys.localStorage is a local storage component.
+ * @memberof cc.sys
+ * @name localStorage
+ * @type {Object}
+ */
+ try {
+ var localStorage = sys.localStorage = win.localStorage;
+ localStorage.setItem("storage", "");
+ localStorage.removeItem("storage");
+ localStorage = null;
+ } catch (e) {
+ var warn = function () {
+ cc.warn("Warning: localStorage isn't enabled. Please confirm browser cookie or privacy option");
+ };
+ sys.localStorage = {
+ getItem : warn,
+ setItem : warn,
+ removeItem : warn,
+ clear : warn
+ };
+ }
+
+ var _supportCanvas = !!_tmpCanvas1.getContext("2d");
+ var _supportWebGL = false;
+ if (win.WebGLRenderingContext) {
+ var tmpCanvas = document.createElement("CANVAS");
+ try{
+ var context = cc.create3DContext(tmpCanvas);
+ if (context) {
+ _supportWebGL = true;
+ }
+
+ if (_supportWebGL && sys.os === sys.OS_IOS && sys.osMainVersion === 9) {
+ // Not activating WebGL in iOS 9 UIWebView because it may crash when entering background
+ if (!window.indexedDB) {
+ _supportWebGL = false;
+ }
+ }
+
+ if (_supportWebGL && sys.os === sys.OS_ANDROID) {
+ var browserVer = parseFloat(sys.browserVersion);
+ switch (sys.browserType) {
+ case sys.BROWSER_TYPE_MOBILE_QQ:
+ case sys.BROWSER_TYPE_BAIDU:
+ case sys.BROWSER_TYPE_BAIDU_APP:
+ // QQ & Baidu Brwoser 6.2+ (using blink kernel)
+ if (browserVer >= 6.2) {
+ _supportWebGL = true;
+ }
+ else {
+ _supportWebGL = false;
+ }
+ break;
+ case sys.BROWSER_TYPE_CHROME:
+ // Chrome on android supports WebGL from v.30
+ if(browserVer >= 30.0) {
+ _supportWebGL = true;
+ } else {
+ _supportWebGL = false;
+ }
+ break;
+ case sys.BROWSER_TYPE_ANDROID:
+ // Android 5+ default browser
+ if (sys.osMainVersion && sys.osMainVersion >= 5) {
+ _supportWebGL = true;
+ }
+ break;
+ case sys.BROWSER_TYPE_UNKNOWN:
+ case sys.BROWSER_TYPE_360:
+ case sys.BROWSER_TYPE_MIUI:
+ case sys.BROWSER_TYPE_UC:
+ _supportWebGL = false;
+ }
+ }
+ }
+ catch (e) {}
+ tmpCanvas = null;
+ }
+
+ /**
+ * The capabilities of the current platform
+ * @memberof cc.sys
+ * @name capabilities
+ * @type {Object}
+ */
+ var capabilities = sys.capabilities = {
+ "canvas": _supportCanvas,
+ "opengl": _supportWebGL
+ };
+ if (docEle['ontouchstart'] !== undefined || doc['ontouchstart'] !== undefined || nav.msPointerEnabled)
+ capabilities["touches"] = true;
+ if (docEle['onmouseup'] !== undefined)
+ capabilities["mouse"] = true;
+ if (docEle['onkeyup'] !== undefined)
+ capabilities["keyboard"] = true;
+ if (win.DeviceMotionEvent || win.DeviceOrientationEvent)
+ capabilities["accelerometer"] = true;
+
+ /**
+ * Forces the garbage collection, only available in JSB
+ * @memberof cc.sys
+ * @name garbageCollect
+ * @function
+ */
+ sys.garbageCollect = function () {
+ // N/A in cocos2d-html5
+ };
+
+ /**
+ * Dumps rooted objects, only available in JSB
+ * @memberof cc.sys
+ * @name dumpRoot
+ * @function
+ */
+ sys.dumpRoot = function () {
+ // N/A in cocos2d-html5
+ };
+
+ /**
+ * Restart the JS VM, only available in JSB
+ * @memberof cc.sys
+ * @name restartVM
+ * @function
+ */
+ sys.restartVM = function () {
+ // N/A in cocos2d-html5
+ };
+
+ /**
+ * Clean a script in the JS VM, only available in JSB
+ * @memberof cc.sys
+ * @name cleanScript
+ * @param {String} jsfile
+ * @function
+ */
+ sys.cleanScript = function (jsfile) {
+ // N/A in cocos2d-html5
+ };
+
+ /**
+ * Check whether an object is valid,
+ * In web engine, it will return true if the object exist
+ * In native engine, it will return true if the JS object and the correspond native object are both valid
+ * @memberof cc.sys
+ * @name isObjectValid
+ * @param {Object} obj
+ * @return {boolean} Validity of the object
+ * @function
+ */
+ sys.isObjectValid = function (obj) {
+ if (obj) return true;
+ else return false;
+ };
+
+ /**
+ * Dump system informations
+ * @memberof cc.sys
+ * @name dump
+ * @function
+ */
+ sys.dump = function () {
+ var self = this;
+ var str = "";
+ str += "isMobile : " + self.isMobile + "\r\n";
+ str += "language : " + self.language + "\r\n";
+ str += "browserType : " + self.browserType + "\r\n";
+ str += "browserVersion : " + self.browserVersion + "\r\n";
+ str += "capabilities : " + JSON.stringify(self.capabilities) + "\r\n";
+ str += "os : " + self.os + "\r\n";
+ str += "osVersion : " + self.osVersion + "\r\n";
+ str += "platform : " + self.platform + "\r\n";
+ str += "Using " + (cc._renderType === cc.game.RENDER_TYPE_WEBGL ? "WEBGL" : "CANVAS") + " renderer." + "\r\n";
+ cc.log(str);
+ };
+
+ /**
+ * Open a url in browser
+ * @memberof cc.sys
+ * @name openURL
+ * @param {String} url
+ */
+ sys.openURL = function(url){
+ window.open(url);
+ };
+
+ /**
+ * Get the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.
+ * @memberof cc.sys
+ * @name now
+ * @return {Number}
+ */
+ sys.now = function () {
+ if (Date.now) {
+ return Date.now();
+ }
+ else {
+ return +(new Date);
+ }
+ };
+};
+_initSys();
+
+_tmpCanvas1 = null;
+_tmpCanvas2 = null;
+
+//to make sure the cc.log, cc.warn, cc.error and cc.assert would not throw error before init by debugger mode.
+cc.log = cc.warn = cc.error = cc.assert = function () {
+};
+
+var _config = null,
+ //cache for js and module that has added into jsList to be loaded.
+ _jsAddedCache = {},
+ _engineInitCalled = false,
+ _engineLoadedCallback = null;
+
+cc._engineLoaded = false;
+
+function _determineRenderType(config) {
+ var CONFIG_KEY = cc.game.CONFIG_KEY,
+ userRenderMode = parseInt(config[CONFIG_KEY.renderMode]) || 0;
+
+ // Adjust RenderType
+ if (isNaN(userRenderMode) || userRenderMode > 2 || userRenderMode < 0)
+ config[CONFIG_KEY.renderMode] = 0;
+
+ // Determine RenderType
+ cc._renderType = cc.game.RENDER_TYPE_CANVAS;
+ cc._supportRender = false;
+
+ if (userRenderMode === 0) {
+ if (cc.sys.capabilities["opengl"]) {
+ cc._renderType = cc.game.RENDER_TYPE_WEBGL;
+ cc._supportRender = true;
+ }
+ else if (cc.sys.capabilities["canvas"]) {
+ cc._renderType = cc.game.RENDER_TYPE_CANVAS;
+ cc._supportRender = true;
+ }
+ }
+ else if (userRenderMode === 1 && cc.sys.capabilities["canvas"]) {
+ cc._renderType = cc.game.RENDER_TYPE_CANVAS;
+ cc._supportRender = true;
+ }
+ else if (userRenderMode === 2 && cc.sys.capabilities["opengl"]) {
+ cc._renderType = cc.game.RENDER_TYPE_WEBGL;
+ cc._supportRender = true;
+ }
+}
+
+function _getJsListOfModule(moduleMap, moduleName, dir) {
+ if (_jsAddedCache[moduleName]) return null;
+ dir = dir || "";
+ var jsList = [];
+ var tempList = moduleMap[moduleName];
+ if (!tempList) throw new Error("can not find module [" + moduleName + "]");
+ var ccPath = cc.path;
+ for (var i = 0, li = tempList.length; i < li; i++) {
+ var item = tempList[i];
+ if (_jsAddedCache[item]) continue;
+ var extname = ccPath.extname(item);
+ if (!extname) {
+ var arr = _getJsListOfModule(moduleMap, item, dir);
+ if (arr) jsList = jsList.concat(arr);
+ } else if (extname.toLowerCase() === ".js") jsList.push(ccPath.join(dir, item));
+ _jsAddedCache[item] = 1;
+ }
+ return jsList;
+}
+
+function _afterEngineLoaded(config) {
+ if (cc._initDebugSetting)
+ cc._initDebugSetting(config[cc.game.CONFIG_KEY.debugMode]);
+ cc._engineLoaded = true;
+ console.log(cc.ENGINE_VERSION);
+ if (_engineLoadedCallback) _engineLoadedCallback();
+}
+
+function _load(config) {
+ var self = this;
+ var CONFIG_KEY = cc.game.CONFIG_KEY, engineDir = config[CONFIG_KEY.engineDir], loader = cc.loader;
+
+ if (cc.Class) {
+ // Single file loaded
+ _afterEngineLoaded(config);
+ } else {
+ // Load cocos modules
+ var ccModulesPath = cc.path.join(engineDir, "moduleConfig.json");
+ loader.loadJson(ccModulesPath, function (err, modulesJson) {
+ if (err) throw new Error(err);
+ var modules = config["modules"] || [];
+ var moduleMap = modulesJson["module"];
+ var jsList = [];
+ if (cc.sys.capabilities["opengl"] && modules.indexOf("base4webgl") < 0) modules.splice(0, 0, "base4webgl");
+ else if (modules.indexOf("core") < 0) modules.splice(0, 0, "core");
+ for (var i = 0, li = modules.length; i < li; i++) {
+ var arr = _getJsListOfModule(moduleMap, modules[i], engineDir);
+ if (arr) jsList = jsList.concat(arr);
+ }
+ cc.loader.loadJsWithImg(jsList, function (err) {
+ if (err) throw err;
+ _afterEngineLoaded(config);
+ });
+ });
+ }
+}
+
+function _windowLoaded() {
+ this.removeEventListener('load', _windowLoaded, false);
+ _load(cc.game.config);
+}
+
+cc.initEngine = function (config, cb) {
+ if (_engineInitCalled) {
+ var previousCallback = _engineLoadedCallback;
+ _engineLoadedCallback = function () {
+ previousCallback && previousCallback();
+ cb && cb();
+ }
+ return;
+ }
+
+ _engineLoadedCallback = cb;
+
+ // Config uninitialized and given, initialize with it
+ if (!cc.game.config && config) {
+ cc.game.config = config;
+ }
+ // No config given and no config set before, load it
+ else if (!cc.game.config) {
+ cc.game._loadConfig();
+ }
+ config = cc.game.config;
+
+ _determineRenderType(config);
+
+ document.body ? _load(config) : cc._addEventListener(window, 'load', _windowLoaded, false);
+ _engineInitCalled = true;
+};
+
+})();
+//+++++++++++++++++++++++++Engine initialization function end+++++++++++++++++++++++++++++
+
+//+++++++++++++++++++++++++something about CCGame begin+++++++++++++++++++++++++++
+/**
+ * An object to boot the game.
+ * @class
+ * @name cc.game
+ *
+ */
+cc.game = /** @lends cc.game# */{
+ /**
+ * Debug mode: No debugging. {@static}
+ * @const {Number}
+ * @static
+ */
+ DEBUG_MODE_NONE: 0,
+ /**
+ * Debug mode: Info, warning, error to console.
+ * @const {Number}
+ * @static
+ */
+ DEBUG_MODE_INFO: 1,
+ /**
+ * Debug mode: Warning, error to console.
+ * @const {Number}
+ * @static
+ */
+ DEBUG_MODE_WARN: 2,
+ /**
+ * Debug mode: Error to console.
+ * @const {Number}
+ * @static
+ */
+ DEBUG_MODE_ERROR: 3,
+ /**
+ * Debug mode: Info, warning, error to web page.
+ * @const {Number}
+ * @static
+ */
+ DEBUG_MODE_INFO_FOR_WEB_PAGE: 4,
+ /**
+ * Debug mode: Warning, error to web page.
+ * @const {Number}
+ * @static
+ */
+ DEBUG_MODE_WARN_FOR_WEB_PAGE: 5,
+ /**
+ * Debug mode: Error to web page.
+ * @const {Number}
+ * @static
+ */
+ DEBUG_MODE_ERROR_FOR_WEB_PAGE: 6,
+
+ /**
+ * Event that is fired when the game is hidden.
+ * @constant {String}
+ */
+ EVENT_HIDE: "game_on_hide",
+ /**
+ * Event that is fired when the game is shown.
+ * @constant {String}
+ */
+ EVENT_SHOW: "game_on_show",
+ /**
+ * Event that is fired when the game is resized.
+ * @constant {String}
+ */
+ EVENT_RESIZE: "game_on_resize",
+ /**
+ * Event that is fired when the renderer is done being initialized.
+ * @constant {String}
+ */
+ EVENT_RENDERER_INITED: "renderer_inited",
+
+ /** @constant {Number} */
+ RENDER_TYPE_CANVAS: 0,
+ /** @constant {Number} */
+ RENDER_TYPE_WEBGL: 1,
+ /** @constant {Number} */
+ RENDER_TYPE_OPENGL: 2,
+
+ _eventHide: null,
+ _eventShow: null,
+
+ /**
+ * Keys found in project.json.
+ *
+ * @constant
+ * @type {Object}
+ *
+ * @prop {String} engineDir - In debug mode, if you use the whole engine to develop your game, you should specify its relative path with "engineDir".
+ * @prop {String} modules - Defines which modules you will need in your game, it's useful only on web
+ * @prop {String} debugMode - Debug mode, see DEBUG_MODE_XXX constant definitions.
+ * @prop {String} exposeClassName - Expose class name to chrome debug tools
+ * @prop {String} showFPS - Left bottom corner fps information will show when "showFPS" equals true, otherwise it will be hide.
+ * @prop {String} frameRate - Sets the wanted frame rate for your game, but the real fps depends on your game implementation and the running environment.
+ * @prop {String} id - Sets the id of your canvas element on the web page, it's useful only on web.
+ * @prop {String} renderMode - Sets the renderer type, only useful on web, 0: Automatic, 1: Canvas, 2: WebGL
+ * @prop {String} jsList - Sets the list of js files in your game.
+ */
+ CONFIG_KEY: {
+ width: "width",
+ height: "height",
+ engineDir: "engineDir",
+ modules: "modules",
+ debugMode: "debugMode",
+ exposeClassName: "exposeClassName",
+ showFPS: "showFPS",
+ frameRate: "frameRate",
+ id: "id",
+ renderMode: "renderMode",
+ jsList: "jsList"
+ },
+
+ // states
+ _paused: true,//whether the game is paused
+ _configLoaded: false,//whether config loaded
+ _prepareCalled: false,//whether the prepare function has been called
+ _prepared: false,//whether the engine has prepared
+ _rendererInitialized: false,
+
+ _renderContext: null,
+
+ _intervalId: null,//interval target of main
+
+ _lastTime: null,
+ _frameTime: null,
+
+ /**
+ * The outer frame of the game canvas, parent of cc.container
+ * @type {Object}
+ */
+ frame: null,
+ /**
+ * The container of game canvas, equals to cc.container
+ * @type {Object}
+ */
+ container: null,
+ /**
+ * The canvas of the game, equals to cc._canvas
+ * @type {Object}
+ */
+ canvas: null,
+
+ /**
+ * Config of game
+ * @type {Object}
+ */
+ config: null,
+
+ /**
+ * Callback when the scripts of engine have been load.
+ * @type {Function|null}
+ */
+ onStart: null,
+
+ /**
+ * Callback when game exits.
+ * @type {Function|null}
+ */
+ onStop: null,
+
+//@Public Methods
+
+// @Game play control
+ /**
+ * Set frameRate of game.
+ * @param frameRate
+ */
+ setFrameRate: function (frameRate) {
+ var self = this, config = self.config, CONFIG_KEY = self.CONFIG_KEY;
+ config[CONFIG_KEY.frameRate] = frameRate;
+ if (self._intervalId)
+ window.cancelAnimationFrame(self._intervalId);
+ self._intervalId = 0;
+ self._paused = true;
+ self._setAnimFrame();
+ self._runMainLoop();
+ },
+
+ /**
+ * Run the game frame by frame.
+ */
+ step: function () {
+ cc.director.mainLoop();
+ },
+
+ /**
+ * Pause the game.
+ */
+ pause: function () {
+ if (this._paused) return;
+ this._paused = true;
+ // Pause audio engine
+ if (cc.audioEngine) {
+ cc.audioEngine._pausePlaying();
+ }
+ // Pause main loop
+ if (this._intervalId)
+ window.cancelAnimationFrame(this._intervalId);
+ this._intervalId = 0;
+ },
+
+ /**
+ * Resume the game from pause.
+ */
+ resume: function () {
+ if (!this._paused) return;
+ this._paused = false;
+ // Resume audio engine
+ if (cc.audioEngine) {
+ cc.audioEngine._resumePlaying();
+ }
+ // Resume main loop
+ this._runMainLoop();
+ },
+
+ /**
+ * Check whether the game is paused.
+ */
+ isPaused: function () {
+ return this._paused;
+ },
+
+ /**
+ * Restart game.
+ */
+ restart: function () {
+ cc.director.popToSceneStackLevel(0);
+ // Clean up audio
+ cc.audioEngine && cc.audioEngine.end();
+
+ cc.game.onStart();
+ },
+
+ /**
+ * End game, it will close the game window
+ */
+ end: function () {
+ close();
+ },
+
+// @Game loading
+ /**
+ * Prepare game.
+ * @param cb
+ */
+ prepare: function (cb) {
+ var self = this,
+ config = self.config,
+ CONFIG_KEY = self.CONFIG_KEY;
+
+ // Config loaded
+ if (!this._configLoaded) {
+ this._loadConfig(function () {
+ self.prepare(cb);
+ });
+ return;
+ }
+
+ // Already prepared
+ if (this._prepared) {
+ if (cb) cb();
+ return;
+ }
+ // Prepare called, but not done yet
+ if (this._prepareCalled) {
+ return;
+ }
+ // Prepare never called and engine ready
+ if (cc._engineLoaded) {
+ this._prepareCalled = true;
+
+ this._initRenderer(config[CONFIG_KEY.width], config[CONFIG_KEY.height]);
+
+ /**
+ * cc.view is the shared view object.
+ * @type {cc.EGLView}
+ * @name cc.view
+ * @memberof cc
+ */
+ cc.view = cc.EGLView._getInstance();
+
+ /**
+ * @type {cc.Director}
+ * @name cc.director
+ * @memberof cc
+ */
+ cc.director = cc.Director._getInstance();
+ if (cc.director.setOpenGLView)
+ cc.director.setOpenGLView(cc.view);
+ /**
+ * cc.winSize is the alias object for the size of the current game window.
+ * @type {cc.Size}
+ * @name cc.winSize
+ * @memberof cc
+ */
+ cc.winSize = cc.director.getWinSize();
+
+ this._initEvents();
+
+ this._setAnimFrame();
+ this._runMainLoop();
+
+ // Load game scripts
+ var jsList = config[CONFIG_KEY.jsList];
+ if (jsList) {
+ cc.loader.loadJsWithImg(jsList, function (err) {
+ if (err) throw new Error(err);
+ self._prepared = true;
+ if (cb) cb();
+ });
+ }
+ else {
+ if (cb) cb();
+ }
+
+ return;
+ }
+
+ // Engine not loaded yet
+ cc.initEngine(this.config, function () {
+ self.prepare(cb);
+ });
+ },
+
+ /**
+ * Run game with configuration object and onStart function.
+ * @param {Object|Function} [config] Pass configuration object or onStart function
+ * @param {onStart} [onStart] onStart function to be executed after game initialized
+ */
+ run: function (config, onStart) {
+ if (typeof config === 'function') {
+ cc.game.onStart = config;
+ }
+ else {
+ if (config) {
+ if (typeof config === 'string') {
+ if (!cc.game.config) this._loadConfig();
+ cc.game.config[cc.game.CONFIG_KEY.id] = config;
+ } else {
+ cc.game.config = config;
+ }
+ }
+ if (typeof onStart === 'function') {
+ cc.game.onStart = onStart;
+ }
+ }
+
+ this.prepare(cc.game.onStart && cc.game.onStart.bind(cc.game));
+ },
+
+//@Private Methods
+
+// @Time ticker section
+ _setAnimFrame: function () {
+ this._lastTime = new Date();
+ var frameRate = cc.game.config[cc.game.CONFIG_KEY.frameRate];
+ this._frameTime = 1000 / frameRate;
+ if (frameRate !== 60 && frameRate !== 30) {
+ window.requestAnimFrame = this._stTime;
+ window.cancelAnimationFrame = this._ctTime;
+ }
+ else {
+ window.requestAnimFrame = window.requestAnimationFrame ||
+ window.webkitRequestAnimationFrame ||
+ window.mozRequestAnimationFrame ||
+ window.oRequestAnimationFrame ||
+ window.msRequestAnimationFrame ||
+ this._stTime;
+ window.cancelAnimationFrame = window.cancelAnimationFrame ||
+ window.cancelRequestAnimationFrame ||
+ window.msCancelRequestAnimationFrame ||
+ window.mozCancelRequestAnimationFrame ||
+ window.oCancelRequestAnimationFrame ||
+ window.webkitCancelRequestAnimationFrame ||
+ window.msCancelAnimationFrame ||
+ window.mozCancelAnimationFrame ||
+ window.webkitCancelAnimationFrame ||
+ window.oCancelAnimationFrame ||
+ this._ctTime;
+ }
+ },
+ _stTime: function (callback) {
+ var currTime = new Date().getTime();
+ var timeToCall = Math.max(0, cc.game._frameTime - (currTime - cc.game._lastTime));
+ var id = window.setTimeout(function() { callback(); },
+ timeToCall);
+ cc.game._lastTime = currTime + timeToCall;
+ return id;
+ },
+ _ctTime: function (id) {
+ window.clearTimeout(id);
+ },
+ //Run game.
+ _runMainLoop: function () {
+ var self = this, callback, config = self.config, CONFIG_KEY = self.CONFIG_KEY,
+ director = cc.director,
+ skip = true, frameRate = config[CONFIG_KEY.frameRate];
+
+ director.setDisplayStats(config[CONFIG_KEY.showFPS]);
+
+ callback = function () {
+ if (!self._paused) {
+ if (frameRate === 30) {
+ if (skip = !skip) {
+ self._intervalId = window.requestAnimFrame(callback);
+ return;
+ }
+ }
+
+ director.mainLoop();
+ self._intervalId = window.requestAnimFrame(callback);
+ }
+ };
+
+ self._intervalId = window.requestAnimFrame(callback);
+ self._paused = false;
+ },
+
+// @Game loading section
+ _loadConfig: function (cb) {
+ // Load config
+ var config = this.config || document["ccConfig"];
+ // Already loaded or Load from document.ccConfig
+ if (config) {
+ this._initConfig(config);
+ cb && cb();
+ }
+ // Load from project.json
+ else {
+ var cocos_script = document.getElementsByTagName('script');
+ for (var i = 0; i < cocos_script.length; i++) {
+ var _t = cocos_script[i].getAttribute('cocos');
+ if (_t === '' || _t) {
+ break;
+ }
+ }
+ var self = this;
+ var loaded = function (err, txt) {
+ var data = JSON.parse(txt);
+ self._initConfig(data);
+ cb && cb();
+ };
+ var _src, txt, _resPath;
+ if (i < cocos_script.length) {
+ _src = cocos_script[i].src;
+ if (_src) {
+ _resPath = /(.*)\//.exec(_src)[0];
+ cc.loader.resPath = _resPath;
+ _src = cc.path.join(_resPath, 'project.json');
+ }
+ cc.loader.loadTxt(_src, loaded);
+ }
+ if (!txt) {
+ cc.loader.loadTxt("project.json", loaded);
+ }
+ }
+ },
+
+ _initConfig: function (config) {
+ var CONFIG_KEY = this.CONFIG_KEY,
+ modules = config[CONFIG_KEY.modules];
+
+ // Configs adjustment
+ config[CONFIG_KEY.showFPS] = typeof config[CONFIG_KEY.showFPS] === 'undefined' ? true : config[CONFIG_KEY.showFPS];
+ config[CONFIG_KEY.engineDir] = config[CONFIG_KEY.engineDir] || "frameworks/cocos2d-html5";
+ if (config[CONFIG_KEY.debugMode] == null)
+ config[CONFIG_KEY.debugMode] = 0;
+ config[CONFIG_KEY.exposeClassName] = !!config[CONFIG_KEY.exposeClassName];
+ config[CONFIG_KEY.frameRate] = config[CONFIG_KEY.frameRate] || 60;
+ if (config[CONFIG_KEY.renderMode] == null)
+ config[CONFIG_KEY.renderMode] = 0;
+ if (config[CONFIG_KEY.registerSystemEvent] == null)
+ config[CONFIG_KEY.registerSystemEvent] = true;
+
+ // Modules adjustment
+ if (modules && modules.indexOf("core") < 0) modules.splice(0, 0, "core");
+ modules && (config[CONFIG_KEY.modules] = modules);
+ this.config = config;
+ this._configLoaded = true;
+ },
+
+ _initRenderer: function (width, height) {
+ // Avoid setup to be called twice.
+ if (this._rendererInitialized) return;
+
+ if (!cc._supportRender) {
+ throw new Error("The renderer doesn't support the renderMode " + this.config[this.CONFIG_KEY.renderMode]);
+ }
+
+ var el = this.config[cc.game.CONFIG_KEY.id],
+ win = window,
+ element = cc.$(el) || cc.$('#' + el),
+ localCanvas, localContainer, localConStyle;
+
+ if (element.tagName === "CANVAS") {
+ width = width || element.width;
+ height = height || element.height;
+
+ //it is already a canvas, we wrap it around with a div
+ this.canvas = cc._canvas = localCanvas = element;
+ this.container = cc.container = localContainer = document.createElement("DIV");
+ if (localCanvas.parentNode)
+ localCanvas.parentNode.insertBefore(localContainer, localCanvas);
+ } else {
+ //we must make a new canvas and place into this element
+ if (element.tagName !== "DIV") {
+ cc.log("Warning: target element is not a DIV or CANVAS");
+ }
+ width = width || element.clientWidth;
+ height = height || element.clientHeight;
+ this.canvas = cc._canvas = localCanvas = cc.$(document.createElement("CANVAS"));
+ this.container = cc.container = localContainer = document.createElement("DIV");
+ element.appendChild(localContainer);
+ }
+ localContainer.setAttribute('id', 'Cocos2dGameContainer');
+ localContainer.appendChild(localCanvas);
+ this.frame = (localContainer.parentNode === document.body) ? document.documentElement : localContainer.parentNode;
+
+ localCanvas.addClass("gameCanvas");
+ localCanvas.setAttribute("width", width || 480);
+ localCanvas.setAttribute("height", height || 320);
+ localCanvas.setAttribute("tabindex", 99);
+
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ this._renderContext = cc._renderContext = cc.webglContext
+ = cc.create3DContext(localCanvas, {
+ 'stencil': true,
+ 'alpha': false
+ });
+ }
+ // WebGL context created successfully
+ if (this._renderContext) {
+ cc.renderer = cc.rendererWebGL;
+ win.gl = this._renderContext; // global variable declared in CCMacro.js
+ cc.renderer.init();
+ cc._drawingUtil = new cc.DrawingPrimitiveWebGL(this._renderContext);
+ cc.textureCache._initializingRenderer();
+ cc.glExt = {};
+ cc.glExt.instanced_arrays = win.gl.getExtension("ANGLE_instanced_arrays");
+ cc.glExt.element_uint = win.gl.getExtension("OES_element_index_uint");
+ } else {
+ cc._renderType = cc.game.RENDER_TYPE_CANVAS;
+ cc.renderer = cc.rendererCanvas;
+ this._renderContext = cc._renderContext = new cc.CanvasContextWrapper(localCanvas.getContext("2d"));
+ cc._drawingUtil = cc.DrawingPrimitiveCanvas ? new cc.DrawingPrimitiveCanvas(this._renderContext) : null;
+ }
+
+ cc._gameDiv = localContainer;
+ cc.game.canvas.oncontextmenu = function () {
+ if (!cc._isContextMenuEnable) return false;
+ };
+
+ this.dispatchEvent(this.EVENT_RENDERER_INITED, true);
+
+ this._rendererInitialized = true;
+ },
+
+ _initEvents: function () {
+ var win = window, hidden;
+
+ this._eventHide = this._eventHide || new cc.EventCustom(this.EVENT_HIDE);
+ this._eventHide.setUserData(this);
+ this._eventShow = this._eventShow || new cc.EventCustom(this.EVENT_SHOW);
+ this._eventShow.setUserData(this);
+
+ // register system events
+ if (this.config[this.CONFIG_KEY.registerSystemEvent])
+ cc.inputManager.registerSystemEvent(this.canvas);
+
+ if (!cc.isUndefined(document.hidden)) {
+ hidden = "hidden";
+ } else if (!cc.isUndefined(document.mozHidden)) {
+ hidden = "mozHidden";
+ } else if (!cc.isUndefined(document.msHidden)) {
+ hidden = "msHidden";
+ } else if (!cc.isUndefined(document.webkitHidden)) {
+ hidden = "webkitHidden";
+ }
+
+ var changeList = [
+ "visibilitychange",
+ "mozvisibilitychange",
+ "msvisibilitychange",
+ "webkitvisibilitychange",
+ "qbrowserVisibilityChange"
+ ];
+ var onHidden = function () {
+ if (cc.eventManager && cc.game._eventHide)
+ cc.eventManager.dispatchEvent(cc.game._eventHide);
+ };
+ var onShow = function () {
+ if (cc.eventManager && cc.game._eventShow)
+ cc.eventManager.dispatchEvent(cc.game._eventShow);
+ };
+
+ if (hidden) {
+ for (var i=0; i -1) {
+ win.onfocus = function(){ onShow() };
+ }
+
+ if ("onpageshow" in window && "onpagehide" in window) {
+ win.addEventListener("pagehide", onHidden, false);
+ win.addEventListener("pageshow", onShow, false);
+ }
+
+ cc.eventManager.addCustomListener(cc.game.EVENT_HIDE, function () {
+ cc.game.pause();
+ });
+ cc.eventManager.addCustomListener(cc.game.EVENT_SHOW, function () {
+ cc.game.resume();
+ });
+ }
+};
+//+++++++++++++++++++++++++something about CCGame end+++++++++++++++++++++++++++++
+
+Function.prototype.bind = Function.prototype.bind || function (oThis) {
+ if (!cc.isFunction(this)) {
+ // closest thing possible to the ECMAScript 5
+ // internal IsCallable function
+ throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
+ }
+
+ var aArgs = Array.prototype.slice.call(arguments, 1),
+ fToBind = this,
+ fNOP = function () {},
+ fBound = function () {
+ return fToBind.apply(this instanceof fNOP && oThis
+ ? this
+ : oThis,
+ aArgs.concat(Array.prototype.slice.call(arguments)));
+ };
+
+ fNOP.prototype = this.prototype;
+ fBound.prototype = new fNOP();
+
+ return fBound;
+};
diff --git a/frameworks/cocos2d-html5/CCDebugger.js b/frameworks/cocos2d-html5/CCDebugger.js
new file mode 100644
index 0000000..7acfc1c
--- /dev/null
+++ b/frameworks/cocos2d-html5/CCDebugger.js
@@ -0,0 +1,333 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc._LogInfos = {
+ ActionManager_addAction: "cc.ActionManager.addAction(): action must be non-null",
+ ActionManager_removeAction: "cocos2d: removeAction: Target not found",
+ ActionManager_removeActionByTag: "cc.ActionManager.removeActionByTag(): an invalid tag",
+ ActionManager_removeActionByTag_2: "cc.ActionManager.removeActionByTag(): target must be non-null",
+ ActionManager_getActionByTag: "cc.ActionManager.getActionByTag(): an invalid tag",
+ ActionManager_getActionByTag_2: "cocos2d : getActionByTag(tag = %s): Action not found",
+
+ configuration_dumpInfo: "cocos2d: **** WARNING **** CC_ENABLE_PROFILERS is defined. Disable it when you finish profiling (from ccConfig.js)",
+ configuration_loadConfigFile: "Expected 'data' dict, but not found. Config file: %s",
+ configuration_loadConfigFile_2: "Please load the resource first : %s",
+
+ Director_resume: "cocos2d: Director: Error in gettimeofday",
+ Director_setProjection: "cocos2d: Director: unrecognized projection",
+ Director_popToSceneStackLevel: "cocos2d: Director: unrecognized projection",
+ Director_popToSceneStackLevel_2: "cocos2d: Director: Error in gettimeofday",
+ Director_popScene: "running scene should not null",
+ Director_pushScene: "the scene should not null",
+
+ arrayVerifyType: "element type is wrong!",
+
+ Scheduler_scheduleCallbackForTarget: "CCSheduler#scheduleCallback. Callback already scheduled. Updating interval from:%s to %s",
+ Scheduler_scheduleCallbackForTarget_2: "cc.scheduler.scheduleCallbackForTarget(): callback_fn should be non-null.",
+ Scheduler_scheduleCallbackForTarget_3: "cc.scheduler.scheduleCallbackForTarget(): target should be non-null.",
+ Scheduler_pauseTarget: "cc.Scheduler.pauseTarget():target should be non-null",
+ Scheduler_resumeTarget: "cc.Scheduler.resumeTarget():target should be non-null",
+ Scheduler_isTargetPaused: "cc.Scheduler.isTargetPaused():target should be non-null",
+
+ Node_getZOrder: "getZOrder is deprecated. Please use getLocalZOrder instead.",
+ Node_setZOrder: "setZOrder is deprecated. Please use setLocalZOrder instead.",
+ Node_getRotation: "RotationX != RotationY. Don't know which one to return",
+ Node_getScale: "ScaleX != ScaleY. Don't know which one to return",
+ Node_addChild: "An Node can't be added as a child of itself.",
+ Node_addChild_2: "child already added. It can't be added again",
+ Node_addChild_3: "child must be non-null",
+ Node_removeFromParentAndCleanup: "removeFromParentAndCleanup is deprecated. Use removeFromParent instead",
+ Node_boundingBox: "boundingBox is deprecated. Use getBoundingBox instead",
+ Node_removeChildByTag: "argument tag is an invalid tag",
+ Node_removeChildByTag_2: "cocos2d: removeChildByTag(tag = %s): child not found!",
+ Node_removeAllChildrenWithCleanup: "removeAllChildrenWithCleanup is deprecated. Use removeAllChildren instead",
+ Node_stopActionByTag: "cc.Node.stopActionBy(): argument tag an invalid tag",
+ Node_getActionByTag: "cc.Node.getActionByTag(): argument tag is an invalid tag",
+ Node_resumeSchedulerAndActions: "resumeSchedulerAndActions is deprecated, please use resume instead.",
+ Node_pauseSchedulerAndActions: "pauseSchedulerAndActions is deprecated, please use pause instead.",
+ Node__arrayMakeObjectsPerformSelector: "Unknown callback function",
+ Node_reorderChild: "cc.Node.reorderChild(): child must be non-null",
+ Node_reorderChild_2: "cc.Node.reorderChild(): this child is not in children list",
+ Node_runAction: "cc.Node.runAction(): action must be non-null",
+ Node_schedule: "callback function must be non-null",
+ Node_schedule_2: "interval must be positive",
+ Node_initWithTexture: "cocos2d: Could not initialize cc.AtlasNode. Invalid Texture.",
+
+ AtlasNode_updateAtlasValues: "cc.AtlasNode.updateAtlasValues(): Shall be overridden in subclasses",
+ AtlasNode_initWithTileFile: "",
+ AtlasNode__initWithTexture: "cocos2d: Could not initialize cc.AtlasNode. Invalid Texture.",
+
+ _EventListenerKeyboard_checkAvailable: "cc._EventListenerKeyboard.checkAvailable(): Invalid EventListenerKeyboard!",
+ _EventListenerTouchOneByOne_checkAvailable: "cc._EventListenerTouchOneByOne.checkAvailable(): Invalid EventListenerTouchOneByOne!",
+ _EventListenerTouchAllAtOnce_checkAvailable: "cc._EventListenerTouchAllAtOnce.checkAvailable(): Invalid EventListenerTouchAllAtOnce!",
+ _EventListenerAcceleration_checkAvailable: "cc._EventListenerAcceleration.checkAvailable(): _onAccelerationEvent must be non-nil",
+
+ EventListener_create: "Invalid parameter.",
+
+ __getListenerID: "Don't call this method if the event is for touch.",
+
+ eventManager__forceAddEventListener: "Invalid scene graph priority!",
+ eventManager_addListener: "0 priority is forbidden for fixed priority since it's used for scene graph based priority.",
+ eventManager_removeListeners: "Invalid listener type!",
+ eventManager_setPriority: "Can't set fixed priority with scene graph based listener.",
+ eventManager_addListener_2: "Invalid parameters.",
+ eventManager_addListener_3: "listener must be a cc.EventListener object when adding a fixed priority listener",
+ eventManager_addListener_4: "The listener has been registered, please don't register it again.",
+
+ LayerMultiplex_initWithLayers: "parameters should not be ending with null in Javascript",
+ LayerMultiplex_switchTo: "Invalid index in MultiplexLayer switchTo message",
+ LayerMultiplex_switchToAndReleaseMe: "Invalid index in MultiplexLayer switchTo message",
+ LayerMultiplex_addLayer: "cc.Layer.addLayer(): layer should be non-null",
+
+ EGLView_setDesignResolutionSize: "Resolution not valid",
+ EGLView_setDesignResolutionSize_2: "should set resolutionPolicy",
+
+ inputManager_handleTouchesBegin: "The touches is more than MAX_TOUCHES, nUnusedIndex = %s",
+
+ swap: "cc.swap is being modified from original macro, please check usage",
+ checkGLErrorDebug: "WebGL error %s",
+
+ animationCache__addAnimationsWithDictionary: "cocos2d: cc.AnimationCache: No animations were found in provided dictionary.",
+ animationCache__addAnimationsWithDictionary_2: "cc.AnimationCache. Invalid animation format",
+ animationCache_addAnimations: "cc.AnimationCache.addAnimations(): File could not be found",
+ animationCache__parseVersion1: "cocos2d: cc.AnimationCache: Animation '%s' found in dictionary without any frames - cannot add to animation cache.",
+ animationCache__parseVersion1_2: "cocos2d: cc.AnimationCache: Animation '%s' refers to frame '%s' which is not currently in the cc.SpriteFrameCache. This frame will not be added to the animation.",
+ animationCache__parseVersion1_3: "cocos2d: cc.AnimationCache: None of the frames for animation '%s' were found in the cc.SpriteFrameCache. Animation is not being added to the Animation Cache.",
+ animationCache__parseVersion1_4: "cocos2d: cc.AnimationCache: An animation in your dictionary refers to a frame which is not in the cc.SpriteFrameCache. Some or all of the frames for the animation '%s' may be missing.",
+ animationCache__parseVersion2: "cocos2d: CCAnimationCache: Animation '%s' found in dictionary without any frames - cannot add to animation cache.",
+ animationCache__parseVersion2_2: "cocos2d: cc.AnimationCache: Animation '%s' refers to frame '%s' which is not currently in the cc.SpriteFrameCache. This frame will not be added to the animation.",
+ animationCache_addAnimations_2: "cc.AnimationCache.addAnimations(): Invalid texture file name",
+
+ Sprite_ignoreAnchorPointForPosition: "cc.Sprite.ignoreAnchorPointForPosition(): it is invalid in cc.Sprite when using SpriteBatchNode",
+ Sprite_setDisplayFrameWithAnimationName: "cc.Sprite.setDisplayFrameWithAnimationName(): Frame not found",
+ Sprite_setDisplayFrameWithAnimationName_2: "cc.Sprite.setDisplayFrameWithAnimationName(): Invalid frame index",
+ Sprite_setDisplayFrame: "setDisplayFrame is deprecated, please use setSpriteFrame instead.",
+ Sprite__updateBlendFunc: "cc.Sprite._updateBlendFunc(): _updateBlendFunc doesn't work when the sprite is rendered using a cc.CCSpriteBatchNode",
+ Sprite_initWithSpriteFrame: "cc.Sprite.initWithSpriteFrame(): spriteFrame should be non-null",
+ Sprite_initWithSpriteFrameName: "cc.Sprite.initWithSpriteFrameName(): spriteFrameName should be non-null",
+ Sprite_initWithSpriteFrameName1: " is null, please check.",
+ Sprite_initWithFile: "cc.Sprite.initWithFile(): filename should be non-null",
+ Sprite_setDisplayFrameWithAnimationName_3: "cc.Sprite.setDisplayFrameWithAnimationName(): animationName must be non-null",
+ Sprite_addChild: "cc.Sprite.addChild(): cc.Sprite only supports cc.Sprites as children when using cc.SpriteBatchNode",
+ Sprite_addChild_2: "cc.Sprite.addChild(): cc.Sprite only supports a sprite using same texture as children when using cc.SpriteBatchNode",
+ Sprite_addChild_3: "cc.Sprite.addChild(): child should be non-null",
+ Sprite_setTexture: "cc.Sprite.texture setter: Batched sprites should use the same texture as the batchnode",
+ Sprite_updateQuadFromSprite: "cc.SpriteBatchNode.updateQuadFromSprite(): cc.SpriteBatchNode only supports cc.Sprites as children",
+ Sprite_insertQuadFromSprite: "cc.SpriteBatchNode.insertQuadFromSprite(): cc.SpriteBatchNode only supports cc.Sprites as children",
+ Sprite_addChild_4: "cc.SpriteBatchNode.addChild(): cc.SpriteBatchNode only supports cc.Sprites as children",
+ Sprite_addChild_5: "cc.SpriteBatchNode.addChild(): cc.Sprite is not using the same texture",
+ Sprite_initWithTexture: "Sprite.initWithTexture(): Argument must be non-nil ",
+ Sprite_setSpriteFrame: "Invalid spriteFrameName",
+ Sprite_setTexture_2: "Invalid argument: cc.Sprite.texture setter expects a CCTexture2D.",
+ Sprite_updateQuadFromSprite_2: "cc.SpriteBatchNode.updateQuadFromSprite(): sprite should be non-null",
+ Sprite_insertQuadFromSprite_2: "cc.SpriteBatchNode.insertQuadFromSprite(): sprite should be non-null",
+
+ SpriteBatchNode_addSpriteWithoutQuad: "cc.SpriteBatchNode.addQuadFromSprite(): SpriteBatchNode only supports cc.Sprites as children",
+ SpriteBatchNode_increaseAtlasCapacity: "cocos2d: CCSpriteBatchNode: resizing TextureAtlas capacity from %s to %s.",
+ SpriteBatchNode_increaseAtlasCapacity_2: "cocos2d: WARNING: Not enough memory to resize the atlas",
+ SpriteBatchNode_reorderChild: "cc.SpriteBatchNode.addChild(): Child doesn't belong to Sprite",
+ SpriteBatchNode_removeChild: "cc.SpriteBatchNode.addChild(): sprite batch node should contain the child",
+ SpriteBatchNode_addSpriteWithoutQuad_2: "cc.SpriteBatchNode.addQuadFromSprite(): child should be non-null",
+ SpriteBatchNode_reorderChild_2: "cc.SpriteBatchNode.addChild(): child should be non-null",
+
+ spriteFrameCache__getFrameConfig: "cocos2d: WARNING: originalWidth/Height not found on the cc.SpriteFrame. AnchorPoint won't work as expected. Regenrate the .plist",
+ spriteFrameCache_addSpriteFrames: "cocos2d: WARNING: an alias with name %s already exists",
+ spriteFrameCache__checkConflict: "cocos2d: WARNING: Sprite frame: %s has already been added by another source, please fix name conflit",
+ spriteFrameCache_getSpriteFrame: "cocos2d: cc.SpriteFrameCahce: Frame %s not found",
+ spriteFrameCache__getFrameConfig_2: "Please load the resource first : %s",
+ spriteFrameCache_addSpriteFrames_2: "cc.SpriteFrameCache.addSpriteFrames(): plist should be non-null",
+ spriteFrameCache_addSpriteFrames_3: "Argument must be non-nil",
+
+ CCSpriteBatchNode_updateQuadFromSprite: "cc.SpriteBatchNode.updateQuadFromSprite(): cc.SpriteBatchNode only supports cc.Sprites as children",
+ CCSpriteBatchNode_insertQuadFromSprite: "cc.SpriteBatchNode.insertQuadFromSprite(): cc.SpriteBatchNode only supports cc.Sprites as children",
+ CCSpriteBatchNode_addChild: "cc.SpriteBatchNode.addChild(): cc.SpriteBatchNode only supports cc.Sprites as children",
+ CCSpriteBatchNode_initWithTexture: "Sprite.initWithTexture(): Argument must be non-nil ",
+ CCSpriteBatchNode_addChild_2: "cc.Sprite.addChild(): child should be non-null",
+ CCSpriteBatchNode_setSpriteFrame: "Invalid spriteFrameName",
+ CCSpriteBatchNode_setTexture: "Invalid argument: cc.Sprite texture setter expects a CCTexture2D.",
+ CCSpriteBatchNode_updateQuadFromSprite_2: "cc.SpriteBatchNode.updateQuadFromSprite(): sprite should be non-null",
+ CCSpriteBatchNode_insertQuadFromSprite_2: "cc.SpriteBatchNode.insertQuadFromSprite(): sprite should be non-null",
+ CCSpriteBatchNode_addChild_3: "cc.SpriteBatchNode.addChild(): child should be non-null",
+
+ TextureAtlas_initWithFile: "cocos2d: Could not open file: %s",
+ TextureAtlas_insertQuad: "cc.TextureAtlas.insertQuad(): invalid totalQuads",
+ TextureAtlas_initWithTexture: "cc.TextureAtlas.initWithTexture():texture should be non-null",
+ TextureAtlas_updateQuad: "cc.TextureAtlas.updateQuad(): quad should be non-null",
+ TextureAtlas_updateQuad_2: "cc.TextureAtlas.updateQuad(): Invalid index",
+ TextureAtlas_insertQuad_2: "cc.TextureAtlas.insertQuad(): Invalid index",
+ TextureAtlas_insertQuads: "cc.TextureAtlas.insertQuad(): Invalid index + amount",
+ TextureAtlas_insertQuadFromIndex: "cc.TextureAtlas.insertQuadFromIndex(): Invalid newIndex",
+ TextureAtlas_insertQuadFromIndex_2: "cc.TextureAtlas.insertQuadFromIndex(): Invalid fromIndex",
+ TextureAtlas_removeQuadAtIndex: "cc.TextureAtlas.removeQuadAtIndex(): Invalid index",
+ TextureAtlas_removeQuadsAtIndex: "cc.TextureAtlas.removeQuadsAtIndex(): index + amount out of bounds",
+ TextureAtlas_moveQuadsFromIndex: "cc.TextureAtlas.moveQuadsFromIndex(): move is out of bounds",
+ TextureAtlas_moveQuadsFromIndex_2: "cc.TextureAtlas.moveQuadsFromIndex(): Invalid newIndex",
+ TextureAtlas_moveQuadsFromIndex_3: "cc.TextureAtlas.moveQuadsFromIndex(): Invalid oldIndex",
+
+ textureCache_addPVRTCImage: "TextureCache:addPVRTCImage does not support on HTML5",
+ textureCache_addETCImage: "TextureCache:addPVRTCImage does not support on HTML5",
+ textureCache_textureForKey: "textureForKey is deprecated. Please use getTextureForKey instead.",
+ textureCache_addPVRImage: "addPVRImage does not support on HTML5",
+ textureCache_addUIImage: "cocos2d: Couldn't add UIImage in TextureCache",
+ textureCache_dumpCachedTextureInfo: "cocos2d: '%s' id=%s %s x %s",
+ textureCache_dumpCachedTextureInfo_2: "cocos2d: '%s' id= HTMLCanvasElement %s x %s",
+ textureCache_dumpCachedTextureInfo_3: "cocos2d: TextureCache dumpDebugInfo: %s textures, HTMLCanvasElement for %s KB (%s MB)",
+ textureCache_addUIImage_2: "cc.Texture.addUIImage(): image should be non-null",
+
+ Texture2D_initWithETCFile: "initWithETCFile does not support on HTML5",
+ Texture2D_initWithPVRFile: "initWithPVRFile does not support on HTML5",
+ Texture2D_initWithPVRTCData: "initWithPVRTCData does not support on HTML5",
+ Texture2D_addImage: "cc.Texture.addImage(): path should be non-null",
+ Texture2D_initWithImage: "cocos2d: cc.Texture2D. Can't create Texture. UIImage is nil",
+ Texture2D_initWithImage_2: "cocos2d: WARNING: Image (%s x %s) is bigger than the supported %s x %s",
+ Texture2D_initWithString: "initWithString isn't supported on cocos2d-html5",
+ Texture2D_initWithETCFile_2: "initWithETCFile does not support on HTML5",
+ Texture2D_initWithPVRFile_2: "initWithPVRFile does not support on HTML5",
+ Texture2D_initWithPVRTCData_2: "initWithPVRTCData does not support on HTML5",
+ Texture2D_bitsPerPixelForFormat: "bitsPerPixelForFormat: %s, cannot give useful result, it's a illegal pixel format",
+ Texture2D__initPremultipliedATextureWithImage: "cocos2d: cc.Texture2D: Using RGB565 texture since image has no alpha",
+ Texture2D_addImage_2: "cc.Texture.addImage(): path should be non-null",
+ Texture2D_initWithData: "NSInternalInconsistencyException",
+
+ MissingFile: "Missing file: %s",
+ radiansToDegress: "cc.radiansToDegress() should be called cc.radiansToDegrees()",
+ RectWidth: "Rect width exceeds maximum margin: %s",
+ RectHeight: "Rect height exceeds maximum margin: %s",
+
+ EventManager__updateListeners: "If program goes here, there should be event in dispatch.",
+ EventManager__updateListeners_2: "_inDispatch should be 1 here."
+};
+
+//+++++++++++++++++++++++++something about log start++++++++++++++++++++++++++++
+cc._logToWebPage = function (msg) {
+ if (!cc._canvas)
+ return;
+
+ var logList = cc._logList;
+ var doc = document;
+ if (!logList) {
+ var logDiv = doc.createElement("Div");
+ var logDivStyle = logDiv.style;
+
+ logDiv.setAttribute("id", "logInfoDiv");
+ cc._canvas.parentNode.appendChild(logDiv);
+ logDiv.setAttribute("width", "200");
+ logDiv.setAttribute("height", cc._canvas.height);
+ logDivStyle.zIndex = "99999";
+ logDivStyle.position = "absolute";
+ logDivStyle.top = "0";
+ logDivStyle.left = "0";
+
+ logList = cc._logList = doc.createElement("textarea");
+ var logListStyle = logList.style;
+
+ logList.setAttribute("rows", "20");
+ logList.setAttribute("cols", "30");
+ logList.setAttribute("disabled", true);
+ logDiv.appendChild(logList);
+ logListStyle.backgroundColor = "transparent";
+ logListStyle.borderBottom = "1px solid #cccccc";
+ logListStyle.borderRightWidth = "0px";
+ logListStyle.borderLeftWidth = "0px";
+ logListStyle.borderTopWidth = "0px";
+ logListStyle.borderTopStyle = "none";
+ logListStyle.borderRightStyle = "none";
+ logListStyle.borderLeftStyle = "none";
+ logListStyle.padding = "0px";
+ logListStyle.margin = 0;
+
+ }
+ logList.value = logList.value + msg + "\r\n";
+ logList.scrollTop = logList.scrollHeight;
+};
+
+//to make sure the cc.log, cc.warn, cc.error and cc.assert would not throw error before init by debugger mode.
+cc._formatString = function (arg) {
+ if (cc.isObject(arg)) {
+ try {
+ return JSON.stringify(arg);
+ } catch (err) {
+ return "";
+ }
+ } else
+ return arg;
+};
+/**
+ * Init Debug setting.
+ * @function
+ * @param {Number} mode
+ */
+cc._initDebugSetting = function (mode) {
+ var ccGame = cc.game;
+ if(mode === ccGame.DEBUG_MODE_NONE)
+ return;
+
+ var locLog;
+ if(mode > ccGame.DEBUG_MODE_ERROR){
+ //log to web page
+ locLog = cc._logToWebPage.bind(cc);
+ cc.error = function(){
+ locLog("ERROR : " + cc.formatStr.apply(cc, arguments));
+ };
+ cc.assert = function(cond, msg) {
+ if (!cond && msg) {
+ for (var i = 2; i < arguments.length; i++)
+ msg = msg.replace(/(%s)|(%d)/, cc._formatString(arguments[i]));
+ locLog("Assert: " + msg);
+ }
+ };
+ if(mode !== ccGame.DEBUG_MODE_ERROR_FOR_WEB_PAGE){
+ cc.warn = function(){
+ locLog("WARN : " + cc.formatStr.apply(cc, arguments));
+ };
+ }
+ if(mode === ccGame.DEBUG_MODE_INFO_FOR_WEB_PAGE){
+ cc.log = function(){
+ locLog(cc.formatStr.apply(cc, arguments));
+ };
+ }
+ } else if(console && console.log.apply){//console is null when user doesn't open dev tool on IE9
+ //log to console
+
+ cc.error = Function.prototype.bind.call(console.error, console);
+ //If console.assert is not support user throw Error msg on wrong condition
+ if (console.assert) {
+ cc.assert = Function.prototype.bind.call(console.assert, console);
+ } else {
+ cc.assert = function (cond, msg) {
+ if (!cond && msg) {
+ for (var i = 2; i < arguments.length; i++)
+ msg = msg.replace(/(%s)|(%d)/, cc._formatString(arguments[i]));
+ throw new Error(msg);
+ }
+ };
+ }
+ if (mode !== ccGame.DEBUG_MODE_ERROR)
+ cc.warn = Function.prototype.bind.call(console.warn, console);
+ if (mode === ccGame.DEBUG_MODE_INFO)
+ cc.log = Function.prototype.bind.call(console.log, console);
+ }
+};
+//+++++++++++++++++++++++++something about log end+++++++++++++++++++++++++++++
diff --git a/frameworks/cocos2d-html5/bower.json b/frameworks/cocos2d-html5/bower.json
new file mode 100644
index 0000000..e97d56b
--- /dev/null
+++ b/frameworks/cocos2d-html5/bower.json
@@ -0,0 +1,36 @@
+{
+ "name": "cocos2d-html5",
+ "homepage": "http://www.cocos2d-x.org",
+ "authors": [
+ "AUTHORS.txt"
+ ],
+ "description": "Cocos2d-html5 is a cross-platform 2D game engine written in Javascript, based on Cocos2d-X and licensed under MIT. It incorporates the same high level api as “Cocos2d JS-binding engine” and compatible with Cocos2d-X. It currently supports canvas and WebGL renderering.",
+ "main": "README.mdown",
+ "keywords": [
+ "cocos2d-x",
+ "cocos2d",
+ "game",
+ "engine",
+ "opengl",
+ "cross",
+ "multi",
+ "platform",
+ "iphone",
+ "ipad",
+ "android",
+ "windows",
+ "metro",
+ "bada",
+ "marmalade",
+ "playbook"
+ ],
+ "license": "MIT",
+ "private": false,
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ]
+}
diff --git a/frameworks/cocos2d-html5/cocos2d/actions/CCAction.js b/frameworks/cocos2d-html5/cocos2d/actions/CCAction.js
new file mode 100644
index 0000000..e548782
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/actions/CCAction.js
@@ -0,0 +1,694 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/** Default Action tag
+ * @constant
+ * @type {Number}
+ * @default
+ */
+cc.ACTION_TAG_INVALID = -1;
+
+/**
+ * Base class for cc.Action objects.
+ * @class
+ *
+ * @extends cc.Class
+ *
+ * @property {cc.Node} target - The target will be set with the 'startWithTarget' method. When the 'stop' method is called, target will be set to nil.
+ * @property {cc.Node} originalTarget - The original target of the action.
+ * @property {Number} tag - The tag of the action, can be used to find the action.
+ */
+cc.Action = cc.Class.extend(/** @lends cc.Action# */{
+ //***********variables*************
+ originalTarget: null,
+ target: null,
+ tag: cc.ACTION_TAG_INVALID,
+
+ //**************Public Functions***********
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor: function () {
+ this.originalTarget = null;
+ this.target = null;
+ this.tag = cc.ACTION_TAG_INVALID;
+ },
+
+ /**
+ * to copy object with deep copy.
+ *
+ * @deprecated since v3.0 please use .clone
+ *
+ * @return {cc.Action}
+ */
+ copy: function () {
+ cc.log("copy is deprecated. Please use clone instead.");
+ return this.clone();
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.Action}
+ */
+ clone: function () {
+ var action = new cc.Action();
+ action.originalTarget = null;
+ action.target = null;
+ action.tag = this.tag;
+ return action;
+ },
+
+ /**
+ * return true if the action has finished.
+ *
+ * @return {Boolean}
+ */
+ isDone: function () {
+ return true;
+ },
+
+ /**
+ * called before the action start. It will also set the target.
+ *
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ this.originalTarget = target;
+ this.target = target;
+ },
+
+ /**
+ * called after the action has finished. It will set the 'target' to nil.
+ * IMPORTANT: You should never call "action stop" manually. Instead, use: "target.stopAction(action);"
+ */
+ stop: function () {
+ this.target = null;
+ },
+
+ /**
+ * called every frame with it's delta time.
+ * DON'T override unless you know what you are doing.
+ *
+ * @param {Number} dt
+ */
+ step: function (dt) {
+ cc.log("[Action step]. override me");
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ cc.log("[Action update]. override me");
+ },
+
+ /**
+ * get the target.
+ *
+ * @return {cc.Node}
+ */
+ getTarget: function () {
+ return this.target;
+ },
+
+ /**
+ * The action will modify the target properties.
+ *
+ * @param {cc.Node} target
+ */
+ setTarget: function (target) {
+ this.target = target;
+ },
+
+ /**
+ * get the original target.
+ *
+ * @return {cc.Node}
+ */
+ getOriginalTarget: function () {
+ return this.originalTarget;
+ },
+
+ /**
+ * Set the original target, since target can be nil.
+ * Is the target that were used to run the action.
+ * Unless you are doing something complex, like cc.ActionManager, you should NOT call this method.
+ * The target is 'assigned', it is not 'retained'.
+ * @param {cc.Node} originalTarget
+ */
+ setOriginalTarget: function (originalTarget) {
+ this.originalTarget = originalTarget;
+ },
+
+ /**
+ * get tag number.
+ * @return {Number}
+ */
+ getTag: function () {
+ return this.tag;
+ },
+
+ /**
+ * set tag number.
+ * @param {Number} tag
+ */
+ setTag: function (tag) {
+ this.tag = tag;
+ },
+
+ /**
+ * Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
+ * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
+ * This is a hack, and should be removed once JSB fixes the retain/release bug.
+ */
+ retain: function () {
+ },
+
+ /**
+ * Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
+ * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
+ * This is a hack, and should be removed once JSB fixes the retain/release bug.
+ */
+ release: function () {
+ }
+});
+
+/**
+ * Allocates and initializes the action.
+ *
+ * @function cc.action
+ * @static
+ * @return {cc.Action}
+ *
+ * @example
+ * // return {cc.Action}
+ * var action = cc.action();
+ */
+cc.action = function () {
+ return new cc.Action();
+};
+
+/**
+ * Please use cc.action instead.
+ * Allocates and initializes the action.
+ *
+ * @deprecated since v3.0 please use cc.action() instead.
+ * @static
+ * @returns {cc.Action}
+ */
+cc.Action.create = cc.action;
+
+
+/**
+ * Base class actions that do have a finite time duration.
+ * Possible actions:
+ * - An action with a duration of 0 seconds.
+ * - An action with a duration of 35.5 seconds.
+ *
+ * Infinite time actions are valid
+ * @class
+ * @extends cc.Action
+ */
+cc.FiniteTimeAction = cc.Action.extend(/** @lends cc.FiniteTimeAction# */{
+ // duration in seconds
+ _duration: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor: function () {
+ cc.Action.prototype.ctor.call(this);
+ this._duration = 0;
+ },
+
+ /**
+ * get duration of the action. (seconds)
+ *
+ * @return {Number}
+ */
+ getDuration: function () {
+ return this._duration * (this._timesForRepeat || 1);
+ },
+
+ /**
+ * set duration of the action. (seconds)
+ *
+ * @param {Number} duration
+ */
+ setDuration: function (duration) {
+ this._duration = duration;
+ },
+
+ /**
+ * Returns a reversed action.
+ * For example:
+ * - The action will be x coordinates of 0 move to 100.
+ * - The reversed action will be x of 100 move to 0.
+ * - Will be rewritten
+ *
+ * @return {?cc.Action}
+ */
+ reverse: function () {
+ cc.log("cocos2d: FiniteTimeAction#reverse: Implement me");
+ return null;
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.FiniteTimeAction}
+ */
+ clone: function () {
+ return new cc.FiniteTimeAction();
+ }
+});
+
+/**
+ * Changes the speed of an action, making it take longer (speed > 1)
+ * or less (speed < 1) time.
+ * Useful to simulate 'slow motion' or 'fast forward' effect.
+ *
+ * @warning This action can't be Sequenceable because it is not an cc.IntervalAction
+ * @class
+ * @extends cc.Action
+ * @param {cc.ActionInterval} action
+ * @param {Number} speed
+ */
+cc.Speed = cc.Action.extend(/** @lends cc.Speed# */{
+ _speed: 0.0,
+ _innerAction: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {cc.ActionInterval} action
+ * @param {Number} speed
+ */
+ ctor: function (action, speed) {
+ cc.Action.prototype.ctor.call(this);
+ this._speed = 0;
+ this._innerAction = null;
+
+ action && this.initWithAction(action, speed);
+ },
+
+ /**
+ * Gets the current running speed.
+ * Will get a percentage number, compared to the original speed.
+ *
+ * @return {Number}
+ */
+ getSpeed: function () {
+ return this._speed;
+ },
+
+ /**
+ * alter the speed of the inner function in runtime.
+ *
+ * @param {Number} speed
+ */
+ setSpeed: function (speed) {
+ this._speed = speed;
+ },
+
+ /**
+ * initializes the action.
+ *
+ * @param {cc.ActionInterval} action
+ * @param {Number} speed
+ * @return {Boolean}
+ */
+ initWithAction: function (action, speed) {
+ if (!action)
+ throw new Error("cc.Speed.initWithAction(): action must be non nil");
+
+ this._innerAction = action;
+ this._speed = speed;
+ return true;
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.Speed}
+ */
+ clone: function () {
+ var action = new cc.Speed();
+ action.initWithAction(this._innerAction.clone(), this._speed);
+ return action;
+ },
+
+ /**
+ * called before the action start. It will also set the target.
+ *
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.Action.prototype.startWithTarget.call(this, target);
+ this._innerAction.startWithTarget(target);
+ },
+
+ /**
+ * Stop the action.
+ */
+ stop: function () {
+ this._innerAction.stop();
+ cc.Action.prototype.stop.call(this);
+ },
+
+ /**
+ * called every frame with it's delta time.
+ * DON'T override unless you know what you are doing.
+ *
+ * @param {Number} dt
+ */
+ step: function (dt) {
+ this._innerAction.step(dt * this._speed);
+ },
+
+ /**
+ * return true if the action has finished.
+ *
+ * @return {Boolean}
+ */
+ isDone: function () {
+ return this._innerAction.isDone();
+ },
+
+ /**
+ * returns a reversed action.
+ * For example:
+ * - The action will be x coordinates of 0 move to 100.
+ * - The reversed action will be x of 100 move to 0.
+ * - Will be rewritten
+ *
+ * @return {cc.Speed}
+ */
+ reverse: function () {
+ return new cc.Speed(this._innerAction.reverse(), this._speed);
+ },
+
+ /**
+ * Set inner Action.
+ * @param {cc.ActionInterval} action
+ */
+ setInnerAction: function (action) {
+ if (this._innerAction !== action) {
+ this._innerAction = action;
+ }
+ },
+
+ /**
+ * Get inner Action.
+ *
+ * @return {cc.ActionInterval}
+ */
+ getInnerAction: function () {
+ return this._innerAction;
+ }
+});
+
+/**
+ * creates the speed action.
+ *
+ * @function cc.speed
+ * @param {cc.ActionInterval} action
+ * @param {Number} speed
+ * @return {cc.Speed}
+ */
+cc.speed = function (action, speed) {
+ return new cc.Speed(action, speed);
+};
+
+/**
+ * Please use cc.speed instead.
+ * creates the action.
+ *
+ * @param {cc.ActionInterval} action
+ * @param {Number} speed
+ * @return {cc.Speed}
+ * @static
+ * @deprecated since v3.0 please use cc.speed() instead.
+ */
+cc.Speed.create = cc.speed;
+
+/**
+ * cc.Follow is an action that "follows" a node.
+ *
+ * @example
+ * //example
+ * //Instead of using cc.Camera as a "follower", use this action instead.
+ * layer.runAction(cc.follow(hero));
+ *
+ * @property {Number} leftBoundary - world leftBoundary.
+ * @property {Number} rightBoundary - world rightBoundary.
+ * @property {Number} topBoundary - world topBoundary.
+ * @property {Number} bottomBoundary - world bottomBoundary.
+ *
+ * @param {cc.Node} followedNode
+ * @param {cc.Rect} rect
+ * @example
+ * // creates the action with a set boundary
+ * var sprite = new cc.Sprite("spriteFileName");
+ * var followAction = new cc.Follow(sprite, cc.rect(0, 0, s.width * 2 - 100, s.height));
+ * this.runAction(followAction);
+ *
+ * // creates the action with no boundary set
+ * var sprite = new cc.Sprite("spriteFileName");
+ * var followAction = new cc.Follow(sprite);
+ * this.runAction(followAction);
+ *
+ * @class
+ * @extends cc.Action
+ */
+cc.Follow = cc.Action.extend(/** @lends cc.Follow# */{
+ // node to follow
+ _followedNode: null,
+ // whether camera should be limited to certain area
+ _boundarySet: false,
+ // if screen size is bigger than the boundary - update not needed
+ _boundaryFullyCovered: false,
+ // fast access to the screen dimensions
+ _halfScreenSize: null,
+ _fullScreenSize: null,
+ _worldRect: null,
+
+ leftBoundary: 0.0,
+ rightBoundary: 0.0,
+ topBoundary: 0.0,
+ bottomBoundary: 0.0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * creates the action with a set boundary.
+ * creates the action with no boundary set.
+ * @param {cc.Node} followedNode
+ * @param {cc.Rect} rect
+ */
+ ctor: function (followedNode, rect) {
+ cc.Action.prototype.ctor.call(this);
+ this._followedNode = null;
+ this._boundarySet = false;
+
+ this._boundaryFullyCovered = false;
+ this._halfScreenSize = null;
+ this._fullScreenSize = null;
+
+ this.leftBoundary = 0.0;
+ this.rightBoundary = 0.0;
+ this.topBoundary = 0.0;
+ this.bottomBoundary = 0.0;
+ this._worldRect = cc.rect(0, 0, 0, 0);
+
+ if (followedNode)
+ rect ? this.initWithTarget(followedNode, rect)
+ : this.initWithTarget(followedNode);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.Follow}
+ */
+ clone: function () {
+ var action = new cc.Follow();
+ var locRect = this._worldRect;
+ var rect = new cc.Rect(locRect.x, locRect.y, locRect.width, locRect.height);
+ action.initWithTarget(this._followedNode, rect);
+ return action;
+ },
+
+ /**
+ * Get whether camera should be limited to certain area.
+ *
+ * @return {Boolean}
+ */
+ isBoundarySet: function () {
+ return this._boundarySet;
+ },
+
+ /**
+ * alter behavior - turn on/off boundary.
+ *
+ * @param {Boolean} value
+ */
+ setBoudarySet: function (value) {
+ this._boundarySet = value;
+ },
+
+ /**
+ * initializes the action with a set boundary.
+ *
+ * @param {cc.Node} followedNode
+ * @param {cc.Rect} [rect=]
+ * @return {Boolean}
+ */
+ initWithTarget: function (followedNode, rect) {
+ if (!followedNode)
+ throw new Error("cc.Follow.initWithAction(): followedNode must be non nil");
+
+ var _this = this;
+ rect = rect || cc.rect(0, 0, 0, 0);
+ _this._followedNode = followedNode;
+ _this._worldRect = rect;
+
+ _this._boundarySet = !cc._rectEqualToZero(rect);
+
+ _this._boundaryFullyCovered = false;
+
+ var winSize = cc.director.getWinSize();
+ _this._fullScreenSize = cc.p(winSize.width, winSize.height);
+ _this._halfScreenSize = cc.pMult(_this._fullScreenSize, 0.5);
+
+ if (_this._boundarySet) {
+ _this.leftBoundary = -((rect.x + rect.width) - _this._fullScreenSize.x);
+ _this.rightBoundary = -rect.x;
+ _this.topBoundary = -rect.y;
+ _this.bottomBoundary = -((rect.y + rect.height) - _this._fullScreenSize.y);
+
+ if (_this.rightBoundary < _this.leftBoundary) {
+ // screen width is larger than world's boundary width
+ //set both in the middle of the world
+ _this.rightBoundary = _this.leftBoundary = (_this.leftBoundary + _this.rightBoundary) / 2;
+ }
+ if (_this.topBoundary < _this.bottomBoundary) {
+ // screen width is larger than world's boundary width
+ //set both in the middle of the world
+ _this.topBoundary = _this.bottomBoundary = (_this.topBoundary + _this.bottomBoundary) / 2;
+ }
+
+ if ((_this.topBoundary === _this.bottomBoundary) && (_this.leftBoundary === _this.rightBoundary))
+ _this._boundaryFullyCovered = true;
+ }
+ return true;
+ },
+
+ /**
+ * called every frame with it's delta time.
+ * DON'T override unless you know what you are doing.
+ *
+ * @param {Number} dt
+ */
+ step: function (dt) {
+ var tempPosX = this._followedNode.x;
+ var tempPosY = this._followedNode.y;
+ tempPosX = this._halfScreenSize.x - tempPosX;
+ tempPosY = this._halfScreenSize.y - tempPosY;
+
+ //TODO Temporary treatment - The dirtyFlag symbol error
+ this.target._renderCmd._dirtyFlag = 0;
+
+ if (this._boundarySet) {
+ // whole map fits inside a single screen, no need to modify the position - unless map boundaries are increased
+ if (this._boundaryFullyCovered)
+ return;
+
+ this.target.setPosition(cc.clampf(tempPosX, this.leftBoundary, this.rightBoundary), cc.clampf(tempPosY, this.bottomBoundary, this.topBoundary));
+ } else {
+ this.target.setPosition(tempPosX, tempPosY);
+ }
+ },
+
+ /**
+ * Return true if the action has finished.
+ *
+ * @return {Boolean}
+ */
+ isDone: function () {
+ return ( !this._followedNode.running );
+ },
+
+ /**
+ * Stop the action.
+ */
+ stop: function () {
+ this.target = null;
+ cc.Action.prototype.stop.call(this);
+ }
+});
+
+/**
+ * creates the action with a set boundary.
+ * creates the action with no boundary set.
+ *
+ * @function
+ * @param {cc.Node} followedNode
+ * @param {cc.Rect} rect
+ * @return {cc.Follow|Null} returns the cc.Follow object on success
+ * @example
+ * // example
+ * // creates the action with a set boundary
+ * var sprite = new cc.Sprite("spriteFileName");
+ * var followAction = cc.follow(sprite, cc.rect(0, 0, s.width * 2 - 100, s.height));
+ * this.runAction(followAction);
+ *
+ * // creates the action with no boundary set
+ * var sprite = new cc.Sprite("spriteFileName");
+ * var followAction = cc.follow(sprite);
+ * this.runAction(followAction);
+ */
+cc.follow = function (followedNode, rect) {
+ return new cc.Follow(followedNode, rect);
+};
+
+/**
+ * Please use cc.follow instead.
+ * creates the action with a set boundary.
+ * creates the action with no boundary set.
+ * @param {cc.Node} followedNode
+ * @param {cc.Rect} rect
+ * @return {cc.Follow|Null} returns the cc.Follow object on success
+ * @static
+ * @deprecated since v3.0 please cc.follow() instead.
+ */
+cc.Follow.create = cc.follow;
diff --git a/frameworks/cocos2d-html5/cocos2d/actions/CCActionCatmullRom.js b/frameworks/cocos2d-html5/cocos2d/actions/CCActionCatmullRom.js
new file mode 100644
index 0000000..a17dca4
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/actions/CCActionCatmullRom.js
@@ -0,0 +1,612 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008 Radu Gruian
+ Copyright (c) 2011 Vit Valentin
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+ Orignal code by Radu Gruian: http://www.codeproject.com/Articles/30838/Overhauser-Catmull-Rom-Splines-for-Camera-Animatio.So
+
+ Adapted to cocos2d-x by Vit Valentin
+
+ Adapted from cocos2d-x to cocos2d-iphone by Ricardo Quesada
+ ****************************************************************************/
+
+/**
+ * Returns the Cardinal Spline position for a given set of control points, tension and time.
+ * CatmullRom Spline formula.
+ * s(-ttt + 2tt - t)P1 + s(-ttt + tt)P2 + (2ttt - 3tt + 1)P2 + s(ttt - 2tt + t)P3 + (-2ttt + 3tt)P3 + s(ttt - tt)P4
+ *
+ * @function
+ * @param {cc.Point} p0
+ * @param {cc.Point} p1
+ * @param {cc.Point} p2
+ * @param {cc.Point} p3
+ * @param {Number} tension
+ * @param {Number} t
+ * @param {cc.Point} [out]
+ * @return {cc.Point}
+ */
+cc.cardinalSplineAt = function (p0, p1, p2, p3, tension, t, out) {
+ var t2 = t * t;
+ var t3 = t2 * t;
+
+ /*
+ * Formula: s(-ttt + 2tt - t)P1 + s(-ttt + tt)P2 + (2ttt - 3tt + 1)P2 + s(ttt - 2tt + t)P3 + (-2ttt + 3tt)P3 + s(ttt - tt)P4
+ */
+ var s = (1 - tension) / 2;
+
+ var b1 = s * ((-t3 + (2 * t2)) - t); // s(-t3 + 2 t2 - t)P1
+ var b2 = s * (-t3 + t2) + (2 * t3 - 3 * t2 + 1); // s(-t3 + t2)P2 + (2 t3 - 3 t2 + 1)P2
+ var b3 = s * (t3 - 2 * t2 + t) + (-2 * t3 + 3 * t2); // s(t3 - 2 t2 + t)P3 + (-2 t3 + 3 t2)P3
+ var b4 = s * (t3 - t2); // s(t3 - t2)P4
+
+ var x = (p0.x * b1 + p1.x * b2 + p2.x * b3 + p3.x * b4);
+ var y = (p0.y * b1 + p1.y * b2 + p2.y * b3 + p3.y * b4);
+ if (out !== undefined) {
+ out.x = x;
+ out.y = y;
+ }
+ else {
+ return cc.p(x, y);
+ }
+};
+
+/**
+ * returns a new copy of the array reversed.
+ *
+ * @return {Array}
+ */
+cc.reverseControlPoints = function (controlPoints) {
+ var newArray = [];
+ for (var i = controlPoints.length - 1; i >= 0; i--) {
+ newArray.push(cc.p(controlPoints[i].x, controlPoints[i].y));
+ }
+ return newArray;
+};
+
+
+/**
+ * returns a new clone of the controlPoints
+ *
+ * @param controlPoints
+ * @returns {Array}
+ */
+cc.cloneControlPoints = function (controlPoints) {
+ var newArray = [];
+ for (var i = 0; i < controlPoints.length; i++)
+ newArray.push(cc.p(controlPoints[i].x, controlPoints[i].y));
+ return newArray;
+};
+
+/**
+ * returns a new clone of the controlPoints
+ * @deprecated since v3.0 please use cc.cloneControlPoints() instead.
+ * @param controlPoints
+ * @returns {Array}
+ */
+cc.copyControlPoints = cc.cloneControlPoints;
+
+/**
+ * returns a point from the array
+ *
+ * @param {Array} controlPoints
+ * @param {Number} pos
+ * @return {Array}
+ */
+cc.getControlPointAt = function (controlPoints, pos) {
+ var p = Math.min(controlPoints.length - 1, Math.max(pos, 0));
+ return controlPoints[p];
+};
+
+/**
+ * reverse the current control point array inline, without generating a new one
+ *
+ * @param controlPoints
+ */
+cc.reverseControlPointsInline = function (controlPoints) {
+ var len = controlPoints.length;
+ var mid = 0 | (len / 2);
+ for (var i = 0; i < mid; ++i) {
+ var temp = controlPoints[i];
+ controlPoints[i] = controlPoints[len - i - 1];
+ controlPoints[len - i - 1] = temp;
+ }
+};
+
+
+/**
+ * Cardinal Spline path. {@link http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Cardinal_spline}
+ * Absolute coordinates.
+ *
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} duration
+ * @param {Array} points array of control points
+ * @param {Number} tension
+ *
+ * @example
+ * //create a cc.CardinalSplineTo
+ * var action1 = cc.cardinalSplineTo(3, array, 0);
+ */
+cc.CardinalSplineTo = cc.ActionInterval.extend(/** @lends cc.CardinalSplineTo# */{
+ /** Array of control points */
+ _points:null,
+ _deltaT:0,
+ _tension:0,
+ _previousPosition:null,
+ _accumulatedDiff:null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Creates an action with a Cardinal Spline array of points and tension.
+ * @param {Number} duration
+ * @param {Array} points array of control points
+ * @param {Number} tension
+ */
+ ctor: function (duration, points, tension) {
+ cc.ActionInterval.prototype.ctor.call(this);
+
+ this._points = [];
+ tension !== undefined && this.initWithDuration(duration, points, tension);
+ },
+
+ /**
+ * initializes the action with a duration and an array of points
+ *
+ * @param {Number} duration
+ * @param {Array} points array of control points
+ * @param {Number} tension
+ *
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, points, tension) {
+ if(!points || points.length === 0)
+ throw new Error("Invalid configuration. It must at least have one control point");
+
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ this.setPoints(points);
+ this._tension = tension;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ *
+ * @returns {cc.CardinalSplineTo}
+ */
+ clone:function () {
+ var action = new cc.CardinalSplineTo();
+ action.initWithDuration(this._duration, cc.copyControlPoints(this._points), this._tension);
+ return action;
+ },
+
+ /**
+ * called before the action start. It will also set the target.
+ *
+ * @param {cc.Node} target
+ */
+ startWithTarget:function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ // Issue #1441 from cocos2d-iphone
+ this._deltaT = 1 / (this._points.length - 1);
+ this._previousPosition = cc.p(this.target.getPositionX(), this.target.getPositionY());
+ this._accumulatedDiff = cc.p(0, 0);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ dt = this._computeEaseTime(dt);
+ var p, lt;
+ var ps = this._points;
+ // eg.
+ // p..p..p..p..p..p..p
+ // 1..2..3..4..5..6..7
+ // want p to be 1, 2, 3, 4, 5, 6
+ if (dt === 1) {
+ p = ps.length - 1;
+ lt = 1;
+ } else {
+ var locDT = this._deltaT;
+ p = 0 | (dt / locDT);
+ lt = (dt - locDT * p) / locDT;
+ }
+
+ var newPos = cc.cardinalSplineAt(
+ cc.getControlPointAt(ps, p - 1),
+ cc.getControlPointAt(ps, p - 0),
+ cc.getControlPointAt(ps, p + 1),
+ cc.getControlPointAt(ps, p + 2),
+ this._tension, lt);
+
+ if (cc.ENABLE_STACKABLE_ACTIONS) {
+ var tempX, tempY;
+ tempX = this.target.getPositionX() - this._previousPosition.x;
+ tempY = this.target.getPositionY() - this._previousPosition.y;
+ if (tempX !== 0 || tempY !== 0) {
+ var locAccDiff = this._accumulatedDiff;
+ tempX = locAccDiff.x + tempX;
+ tempY = locAccDiff.y + tempY;
+ locAccDiff.x = tempX;
+ locAccDiff.y = tempY;
+ newPos.x += tempX;
+ newPos.y += tempY;
+ }
+ }
+ this.updatePosition(newPos);
+ },
+
+ /**
+ * reverse a new cc.CardinalSplineTo.
+ * Along the track of movement in the opposite.
+ *
+ * @return {cc.CardinalSplineTo}
+ */
+ reverse:function () {
+ var reversePoints = cc.reverseControlPoints(this._points);
+ return cc.cardinalSplineTo(this._duration, reversePoints, this._tension);
+ },
+
+ /**
+ * update position of target
+ *
+ * @param {cc.Point} newPos
+ */
+ updatePosition:function (newPos) {
+ this.target.setPosition(newPos);
+ this._previousPosition = newPos;
+ },
+
+ /**
+ * Points getter
+ *
+ * @return {Array}
+ */
+ getPoints:function () {
+ return this._points;
+ },
+
+ /**
+ * Points setter
+ *
+ * @param {Array} points
+ */
+ setPoints:function (points) {
+ this._points = points;
+ }
+});
+
+/**
+ * creates an action with a Cardinal Spline array of points and tension.
+ *
+ * @function
+ * @param {Number} duration
+ * @param {Array} points array of control points
+ * @param {Number} tension
+ * @return {cc.CardinalSplineTo}
+ *
+ * @example
+ * //create a cc.CardinalSplineTo
+ * var action1 = cc.cardinalSplineTo(3, array, 0);
+ */
+cc.cardinalSplineTo = function (duration, points, tension) {
+ return new cc.CardinalSplineTo(duration, points, tension);
+};
+
+/**
+ * Please use cc.cardinalSplineTo instead.
+ * creates an action with a Cardinal Spline array of points and tension
+ *
+ * @function
+ * @param {Number} duration
+ * @param {Array} points array of control points
+ * @param {Number} tension
+ * @return {cc.CardinalSplineTo}
+ * @static
+ * @deprecated since v3.0 please use cc.cardinalSplineTo(duration, points, tension) instead.
+ */
+cc.CardinalSplineTo.create = cc.cardinalSplineTo;
+
+/**
+ * Cardinal Spline path. {@link http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Cardinal_spline}
+ * Relative coordinates.
+ *
+ * @class
+ * @extends cc.CardinalSplineTo
+ * @param {Number} duration
+ * @param {Array} points
+ * @param {Number} tension
+ *
+ * @example
+ * //create a cc.CardinalSplineBy
+ * var action1 = cc.cardinalSplineBy(3, array, 0);
+ */
+cc.CardinalSplineBy = cc.CardinalSplineTo.extend(/** @lends cc.CardinalSplineBy# */{
+ _startPosition:null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * creates an action with a Cardinal Spline array of points and tension.
+ * @param {Number} duration
+ * @param {Array} points
+ * @param {Number} tension
+ */
+ ctor:function (duration, points, tension) {
+ cc.CardinalSplineTo.prototype.ctor.call(this);
+ this._startPosition = cc.p(0, 0);
+
+ tension !== undefined && this.initWithDuration(duration, points, tension);
+ },
+
+ /**
+ * called before the action start. It will also set the target.
+ *
+ * @param {cc.Node} target
+ */
+ startWithTarget:function (target) {
+ cc.CardinalSplineTo.prototype.startWithTarget.call(this, target);
+ this._startPosition.x = target.getPositionX();
+ this._startPosition.y = target.getPositionY();
+ },
+
+ /**
+ * reverse a new cc.CardinalSplineBy
+ *
+ * @return {cc.CardinalSplineBy}
+ */
+ reverse:function () {
+ var copyConfig = this._points.slice();
+ var current;
+ //
+ // convert "absolutes" to "diffs"
+ //
+ var p = copyConfig[0];
+ for (var i = 1; i < copyConfig.length; ++i) {
+ current = copyConfig[i];
+ copyConfig[i] = cc.pSub(current, p);
+ p = current;
+ }
+
+ // convert to "diffs" to "reverse absolute"
+ var reverseArray = cc.reverseControlPoints(copyConfig);
+
+ // 1st element (which should be 0,0) should be here too
+ p = reverseArray[ reverseArray.length - 1 ];
+ reverseArray.pop();
+
+ p.x = -p.x;
+ p.y = -p.y;
+
+ reverseArray.unshift(p);
+ for (var i = 1; i < reverseArray.length; ++i) {
+ current = reverseArray[i];
+ current.x = -current.x;
+ current.y = -current.y;
+ current.x += p.x;
+ current.y += p.y;
+ reverseArray[i] = current;
+ p = current;
+ }
+ return cc.cardinalSplineBy(this._duration, reverseArray, this._tension);
+ },
+
+ /**
+ * update position of target
+ *
+ * @param {cc.Point} newPos
+ */
+ updatePosition:function (newPos) {
+ var pos = this._startPosition;
+ var posX = newPos.x + pos.x;
+ var posY = newPos.y + pos.y;
+ this._previousPosition.x = posX;
+ this._previousPosition.y = posY;
+ this.target.setPosition(posX, posY);
+ },
+
+ /**
+ * returns a new clone of the action
+ *
+ * @returns {cc.CardinalSplineBy}
+ */
+ clone:function () {
+ var a = new cc.CardinalSplineBy();
+ a.initWithDuration(this._duration, cc.copyControlPoints(this._points), this._tension);
+ return a;
+ }
+});
+
+/**
+ * creates an action with a Cardinal Spline array of points and tension.
+ *
+ * @function
+ * @param {Number} duration
+ * @param {Array} points
+ * @param {Number} tension
+ *
+ * @return {cc.CardinalSplineBy}
+ */
+cc.cardinalSplineBy = function (duration, points, tension) {
+ return new cc.CardinalSplineBy(duration, points, tension);
+};
+
+/**
+ * Please use cc.cardinalSplineBy instead.
+ * creates an action with a Cardinal Spline array of points and tension.
+ * @function
+ * @param {Number} duration
+ * @param {Array} points
+ * @param {Number} tension
+ * @return {cc.CardinalSplineBy}
+ * @static
+ * @deprecated since v3.0 please use cc.cardinalSplineBy(duration, points, tension);
+ */
+cc.CardinalSplineBy.create = cc.cardinalSplineBy;
+
+/**
+ * An action that moves the target with a CatmullRom curve to a destination point.
+ * A Catmull Rom is a Cardinal Spline with a tension of 0.5.
+ * {@link http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Catmull.E2.80.93Rom_spline}
+ * Absolute coordinates.
+ *
+ * @class
+ * @extends cc.CardinalSplineTo
+ * @param {Number} dt
+ * @param {Array} points
+ *
+ * @example
+ * var action1 = cc.catmullRomTo(3, array);
+ */
+cc.CatmullRomTo = cc.CardinalSplineTo.extend(/** @lends cc.CatmullRomTo# */{
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * creates an action with a Cardinal Spline array of points and tension.
+ * @param {Number} dt
+ * @param {Array} points
+ */
+ ctor: function(dt, points) {
+ points && this.initWithDuration(dt, points);
+ },
+
+ /**
+ * Initializes the action with a duration and an array of points
+ *
+ * @param {Number} dt
+ * @param {Array} points
+ */
+ initWithDuration:function (dt, points) {
+ return cc.CardinalSplineTo.prototype.initWithDuration.call(this, dt, points, 0.5);
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.CatmullRomTo}
+ */
+ clone:function () {
+ var action = new cc.CatmullRomTo();
+ action.initWithDuration(this._duration, cc.copyControlPoints(this._points));
+ return action;
+ }
+});
+
+/**
+ * creates an action with a Cardinal Spline array of points and tension.
+ *
+ * @function
+ * @param {Number} dt
+ * @param {Array} points
+ * @return {cc.CatmullRomTo}
+ *
+ * @example
+ * var action1 = cc.catmullRomTo(3, array);
+ */
+cc.catmullRomTo = function (dt, points) {
+ return new cc.CatmullRomTo(dt, points);
+};
+/**
+ * Please use cc.catmullRomTo instead.
+ * creates an action with a Cardinal Spline array of points and tension.
+ *
+ * @param {Number} dt
+ * @param {Array} points
+ * @return {cc.CatmullRomTo}
+ * @static
+ * @deprecated since v3.0 please use cc.catmullRomTo(dt, points) instead.
+ */
+cc.CatmullRomTo.create = cc.catmullRomTo;
+
+/**
+ * An action that moves the target with a CatmullRom curve by a certain distance.
+ * A Catmull Rom is a Cardinal Spline with a tension of 0.5.
+ * http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Catmull.E2.80.93Rom_spline
+ * Relative coordinates.
+ *
+ * @class
+ * @extends cc.CardinalSplineBy
+ * @param {Number} dt
+ * @param {Array} points
+ *
+ * @example
+ * var action1 = cc.catmullRomBy(3, array);
+ */
+cc.CatmullRomBy = cc.CardinalSplineBy.extend({
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Creates an action with a Cardinal Spline array of points and tension.
+ * @param {Number} dt
+ * @param {Array} points
+ */
+ ctor: function(dt, points) {
+ cc.CardinalSplineBy.prototype.ctor.call(this);
+ points && this.initWithDuration(dt, points);
+ },
+
+ /**
+ * initializes the action with a duration and an array of points
+ *
+ * @function
+ * @param {Number} dt
+ * @param {Array} points
+ */
+ initWithDuration:function (dt, points) {
+ return cc.CardinalSplineTo.prototype.initWithDuration.call(this, dt, points, 0.5);
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.CatmullRomBy}
+ */
+ clone:function () {
+ var action = new cc.CatmullRomBy();
+ action.initWithDuration(this._duration, cc.copyControlPoints(this._points));
+ return action;
+ }
+});
+
+/**
+ * Creates an action with a Cardinal Spline array of points and tension
+ * @function
+ * @param {Number} dt
+ * @param {Array} points
+ * @return {cc.CatmullRomBy}
+ * @example
+ * var action1 = cc.catmullRomBy(3, array);
+ */
+cc.catmullRomBy = function (dt, points) {
+ return new cc.CatmullRomBy(dt, points);
+};
+/**
+ * Please use cc.catmullRomBy instead
+ * Creates an action with a Cardinal Spline array of points and tension
+ * @static
+ * @deprecated since v3.0 please cc.catmullRomBy(dt, points) instead.
+ */
+cc.CatmullRomBy.create = cc.catmullRomBy;
diff --git a/frameworks/cocos2d-html5/cocos2d/actions/CCActionEase.js b/frameworks/cocos2d-html5/cocos2d/actions/CCActionEase.js
new file mode 100644
index 0000000..f6ddef0
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/actions/CCActionEase.js
@@ -0,0 +1,3680 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Base class for Easing actions
+ * @class
+ * @extends cc.ActionInterval
+ * @param {cc.ActionInterval} action
+ *
+ * @deprecated since v3.0 Does not recommend the use of the base object.
+ *
+ * @example
+ * var moveEase = new cc.ActionEase(action);
+ */
+cc.ActionEase = cc.ActionInterval.extend(/** @lends cc.ActionEase# */{
+ _inner:null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * creates the action of ActionEase.
+ * @param {cc.ActionInterval} action
+ */
+ ctor: function (action) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ action && this.initWithAction(action);
+ },
+
+ /**
+ * initializes the action
+ *
+ * @param {cc.ActionInterval} action
+ * @return {Boolean}
+ */
+ initWithAction:function (action) {
+ if(!action)
+ throw new Error("cc.ActionEase.initWithAction(): action must be non nil");
+
+ if (this.initWithDuration(action.getDuration())) {
+ this._inner = action;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.ActionEase}
+ */
+ clone:function(){
+ var action = new cc.ActionEase();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * called before the action start. It will also set the target.
+ *
+ * @param {cc.Node} target
+ */
+ startWithTarget:function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ this._inner.startWithTarget(this.target);
+ },
+
+ /**
+ * Stop the action.
+ */
+ stop:function () {
+ this._inner.stop();
+ cc.ActionInterval.prototype.stop.call(this);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ this._inner.update(dt);
+ },
+
+ /**
+ * Create new action to original operation effect opposite.
+ * For example:
+ * - The action will be x coordinates of 0 move to 100.
+ * - The reversed action will be x of 100 move to 0.
+ * - Will be rewritten
+ * @return {cc.ActionEase}
+ */
+ reverse:function () {
+ return new cc.ActionEase(this._inner.reverse());
+ },
+
+ /**
+ * Get inner Action.
+ *
+ * @return {cc.ActionInterval}
+ */
+ getInnerAction:function(){
+ return this._inner;
+ }
+});
+
+/**
+ * creates the action of ActionEase
+ *
+ * @param {cc.ActionInterval} action
+ * @return {cc.ActionEase}
+ * @example
+ * // example
+ * var moveEase = cc.actionEase(action);
+ */
+cc.actionEase = function (action) {
+ return new cc.ActionEase(action);
+};
+
+/**
+ * Please use cc.actionEase instead
+ * creates the action of ActionEase
+ *
+ * @param {cc.ActionInterval} action
+ * @return {cc.ActionEase}
+ * @static
+ * @deprecated since v3.0 please use cc.actionEase(action) instead.
+ */
+cc.ActionEase.create = cc.actionEase;
+
+/**
+ * Base class for Easing actions with rate parameters
+ *
+ * @class
+ * @extends cc.ActionEase
+ * @param {cc.ActionInterval} action
+ * @param {Number} rate
+ *
+ * @deprecated since v3.0 please cc.easeRateAction(action, 3.0);
+ *
+ * @example
+ * //The old usage
+ * cc.EaseRateAction.create(action, 3.0);
+ * //The new usage
+ * var moveEaseRateAction = cc.easeRateAction(action, 3.0);
+ */
+cc.EaseRateAction = cc.ActionEase.extend(/** @lends cc.EaseRateAction# */{
+ _rate:0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Creates the action with the inner action and the rate parameter.
+ * @param {cc.ActionInterval} action
+ * @param {Number} rate
+ */
+ ctor: function(action, rate){
+ cc.ActionEase.prototype.ctor.call(this);
+
+ rate !== undefined && this.initWithAction(action, rate);
+ },
+
+ /**
+ * set rate value for the actions
+ * @param {Number} rate
+ */
+ setRate:function (rate) {
+ this._rate = rate;
+ },
+
+ /** get rate value for the actions
+ * @return {Number}
+ */
+ getRate:function () {
+ return this._rate;
+ },
+
+ /**
+ * Initializes the action with the inner action and the rate parameter
+ * @param {cc.ActionInterval} action
+ * @param {Number} rate
+ * @return {Boolean}
+ */
+ initWithAction:function (action, rate) {
+ if (cc.ActionEase.prototype.initWithAction.call(this, action)) {
+ this._rate = rate;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseRateAction}
+ */
+ clone:function(){
+ var action = new cc.EaseRateAction();
+ action.initWithAction(this._inner.clone(), this._rate);
+ return action;
+ },
+
+ /**
+ * Create new action to original operation effect opposite.
+ * For example:
+ * - The action will be x coordinates of 0 move to 100.
+ * - The reversed action will be x of 100 move to 0.
+ * - Will be rewritten
+ * @return {cc.EaseRateAction}
+ */
+ reverse:function () {
+ return new cc.EaseRateAction(this._inner.reverse(), 1 / this._rate);
+ }
+});
+
+/**
+ * Creates the action with the inner action and the rate parameter.
+ *
+ * @param {cc.ActionInterval} action
+ * @param {Number} rate
+ * @return {cc.EaseRateAction}
+ * @example
+ * // example
+ * var moveEaseRateAction = cc.easeRateAction(action, 3.0);
+ */
+cc.easeRateAction = function (action, rate) {
+ return new cc.EaseRateAction(action, rate);
+};
+
+/**
+ * Please use cc.easeRateAction instead.
+ * Creates the action with the inner action and the rate parameter.
+ *
+ * @param {cc.ActionInterval} action
+ * @param {Number} rate
+ * @return {cc.EaseRateAction}
+ * @static
+ * @deprecated since v3.0 please use cc.easeRateAction(action, rate)
+ * @example
+ * //The old usage
+ * cc.EaseRateAction.create(action, 3.0);
+ * //The new usage
+ * var moveEaseRateAction = cc.easeRateAction(action, 3.0);
+ */
+cc.EaseRateAction.create = cc.easeRateAction;
+
+/**
+ * cc.EaseIn action with a rate. From slow to fast.
+ *
+ * @class
+ * @extends cc.EaseRateAction
+ *
+ * @deprecated since v3.0 please use action.easing(cc.easeIn(3));
+ *
+ * @example
+ * //The old usage
+ * cc.EaseIn.create(action, 3);
+ * //The new usage
+ * action.easing(cc.easeIn(3.0));
+ */
+cc.EaseIn = cc.EaseRateAction.extend(/** @lends cc.EaseIn# */{
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ this._inner.update(Math.pow(dt, this._rate));
+ },
+
+ /**
+ * Create a cc.easeIn action. Opposite with the original motion trajectory.
+ * @return {cc.EaseIn}
+ */
+ reverse:function () {
+ return new cc.EaseIn(this._inner.reverse(), 1 / this._rate);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseIn}
+ */
+ clone:function(){
+ var action = new cc.EaseIn();
+ action.initWithAction(this._inner.clone(), this._rate);
+ return action;
+ }
+});
+
+/**
+ * Creates the action with the inner action and the rate parameter.
+ * From slow to fast.
+ *
+ * @static
+ * @deprecated since v3.0 Please use action.easing(cc.easeIn(3))
+ *
+ * @example
+ * //The old usage
+ * cc.EaseIn.create(action, 3);
+ * //The new usage
+ * action.easing(cc.easeIn(3.0));
+ *
+ * @param {cc.ActionInterval} action
+ * @param {Number} rate
+ * @return {cc.EaseIn}
+ */
+cc.EaseIn.create = function (action, rate) {
+ return new cc.EaseIn(action, rate);
+};
+
+/**
+ * Creates the action easing object with the rate parameter.
+ * From slow to fast.
+ *
+ * @function
+ * @param {Number} rate
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeIn(3.0));
+ */
+cc.easeIn = function (rate) {
+ return {
+ _rate: rate,
+ easing: function (dt) {
+ return Math.pow(dt, this._rate);
+ },
+ reverse: function(){
+ return cc.easeIn(1 / this._rate);
+ }
+ };
+};
+
+/**
+ * cc.EaseOut action with a rate. From fast to slow.
+ *
+ * @class
+ * @extends cc.EaseRateAction
+ *
+ * @deprecated since v3.0 please use action.easing(cc.easeOut(3))
+ *
+ * @example
+ * //The old usage
+ * cc.EaseOut.create(action, 3);
+ * //The new usage
+ * action.easing(cc.easeOut(3.0));
+ */
+cc.EaseOut = cc.EaseRateAction.extend(/** @lends cc.EaseOut# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ this._inner.update(Math.pow(dt, 1 / this._rate));
+ },
+
+ /**
+ * Create a cc.easeIn action. Opposite with the original motion trajectory.
+ * @return {cc.EaseOut}
+ */
+ reverse:function () {
+ return new cc.EaseOut(this._inner.reverse(), 1 / this._rate);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseOut}
+ */
+ clone:function(){
+ var action = new cc.EaseOut();
+ action.initWithAction(this._inner.clone(),this._rate);
+ return action;
+ }
+});
+
+/**
+ * Creates the action with the inner action and the rate parameter.
+ * From fast to slow.
+ *
+ * @static
+ * @deprecated since v3.0 Please use cc.easeOut instead.
+ *
+ * @example
+ * //The old usage
+ * cc.EaseOut.create(action, 3);
+ * //The new usage
+ * action.easing(cc.easeOut(3.0));
+ *
+ * @param {cc.ActionInterval} action
+ * @param {Number} rate
+ * @return {cc.EaseOut}
+ */
+cc.EaseOut.create = function (action, rate) {
+ return new cc.EaseOut(action, rate);
+};
+
+/**
+ * Creates the action easing object with the rate parameter.
+ * From fast to slow.
+ *
+ * @function
+ * @param {Number} rate
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeOut(3.0));
+ */
+cc.easeOut = function (rate) {
+ return {
+ _rate: rate,
+ easing: function (dt) {
+ return Math.pow(dt, 1 / this._rate);
+ },
+ reverse: function(){
+ return cc.easeOut(1 / this._rate)
+ }
+ };
+};
+
+/**
+ * cc.EaseInOut action with a rate.
+ * Slow to fast then to slow.
+ * @class
+ * @extends cc.EaseRateAction
+ *
+ * @deprecated since v3.0 please use action.easing(cc.easeInOut(3.0))
+ *
+ * @example
+ * //The old usage
+ * cc.EaseInOut.create(action, 3);
+ * //The new usage
+ * action.easing(cc.easeInOut(3.0));
+ */
+cc.EaseInOut = cc.EaseRateAction.extend(/** @lends cc.EaseInOut# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ dt *= 2;
+ if (dt < 1)
+ this._inner.update(0.5 * Math.pow(dt, this._rate));
+ else
+ this._inner.update(1.0 - 0.5 * Math.pow(2 - dt, this._rate));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseInOut}
+ */
+ clone:function(){
+ var action = new cc.EaseInOut();
+ action.initWithAction(this._inner.clone(), this._rate);
+ return action;
+ },
+
+ /**
+ * Create a cc.EaseInOut action. Opposite with the original motion trajectory.
+ * @return {cc.EaseInOut}
+ */
+ reverse:function () {
+ return new cc.EaseInOut(this._inner.reverse(), this._rate);
+ }
+});
+
+/**
+ * Creates the action with the inner action and the rate parameter.
+ * Slow to fast then to slow.
+ * @static
+ * @deprecated since v3.0 Please use action.easing(cc.easeInOut(3.0))
+ *
+ * @example
+ * //The old usage
+ * cc.EaseInOut.create(action, 3);
+ * //The new usage
+ * action.easing(cc.easeInOut(3.0));
+ *
+ * @param {cc.ActionInterval} action
+ * @param {Number} rate
+ * @return {cc.EaseInOut}
+ */
+cc.EaseInOut.create = function (action, rate) {
+ return new cc.EaseInOut(action, rate);
+};
+
+/**
+ * Creates the action easing object with the rate parameter.
+ * Slow to fast then to slow.
+ * @function
+ * @param {Number} rate
+ * @return {Object}
+ *
+ * @example
+ * //The new usage
+ * action.easing(cc.easeInOut(3.0));
+ */
+cc.easeInOut = function (rate) {
+ return {
+ _rate: rate,
+ easing: function (dt) {
+ dt *= 2;
+ if (dt < 1)
+ return 0.5 * Math.pow(dt, this._rate);
+ else
+ return 1.0 - 0.5 * Math.pow(2 - dt, this._rate);
+ },
+ reverse: function(){
+ return cc.easeInOut(this._rate);
+ }
+ };
+};
+
+/**
+ * cc.Ease Exponential In. Slow to Fast.
+ * Reference easeInExpo:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 please action.easing(cc.easeExponentialIn())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseExponentialIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeExponentialIn());
+ */
+cc.EaseExponentialIn = cc.ActionEase.extend(/** @lends cc.EaseExponentialIn# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ this._inner.update(dt === 0 ? 0 : Math.pow(2, 10 * (dt - 1)));
+ },
+
+ /**
+ * Create a cc.EaseExponentialOut action. Opposite with the original motion trajectory.
+ * @return {cc.EaseExponentialOut}
+ */
+ reverse:function () {
+ return new cc.EaseExponentialOut(this._inner.reverse());
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseExponentialIn}
+ */
+ clone:function(){
+ var action = new cc.EaseExponentialIn();
+ action.initWithAction(this._inner.clone());
+ return action;
+ }
+});
+
+/**
+ * Creates the action easing object with the rate parameter.
+ * Reference easeInExpo:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ * @deprecated since v3.0 Please use action.easing(cc.easeExponentialIn())
+ * @param {cc.ActionInterval} action
+ * @return {cc.EaseExponentialIn}
+ *
+ * @example
+ * //The old usage
+ * cc.EaseExponentialIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeExponentialIn());
+ */
+cc.EaseExponentialIn.create = function (action) {
+ return new cc.EaseExponentialIn(action);
+};
+
+cc._easeExponentialInObj = {
+ easing: function(dt){
+ return dt === 0 ? 0 : Math.pow(2, 10 * (dt - 1));
+ },
+ reverse: function(){
+ return cc._easeExponentialOutObj;
+ }
+};
+
+/**
+ * Creates the action easing object with the rate parameter.
+ * Reference easeInExpo:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeExponentialIn());
+ */
+cc.easeExponentialIn = function(){
+ return cc._easeExponentialInObj;
+};
+
+/**
+ * Ease Exponential Out.
+ * Reference easeOutExpo:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 please use action.easing(cc.easeExponentialOut())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseExponentialOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeExponentialOut());
+ */
+cc.EaseExponentialOut = cc.ActionEase.extend(/** @lends cc.EaseExponentialOut# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ this._inner.update(dt === 1 ? 1 : (-(Math.pow(2, -10 * dt)) + 1));
+ },
+
+ /**
+ * Create a cc.EaseExponentialIn action. Opposite with the original motion trajectory.
+ * @return {cc.EaseExponentialIn}
+ */
+ reverse:function () {
+ return new cc.EaseExponentialIn(this._inner.reverse());
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseExponentialOut}
+ */
+ clone:function(){
+ var action = new cc.EaseExponentialOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ }
+});
+
+/**
+ * Creates the action easing object with the rate parameter.
+ * Reference easeOutExpo:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ * @deprecated since v3.0 Please use action.easing(cc.easeExponentialOut())
+ * @param {cc.ActionInterval} action
+ * @return {Object}
+ *
+ * @example
+ * //The old usage
+ * cc.EaseExponentialOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeExponentialOut());
+ */
+cc.EaseExponentialOut.create = function (action) {
+ return new cc.EaseExponentialOut(action);
+};
+
+cc._easeExponentialOutObj = {
+ easing: function(dt){
+ return dt === 1 ? 1 : (-(Math.pow(2, -10 * dt)) + 1);
+ },
+ reverse: function(){
+ return cc._easeExponentialInObj;
+ }
+};
+
+/**
+ * creates the action easing object.
+ * Reference easeOutExpo:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ *
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeExponentialOut());
+ */
+cc.easeExponentialOut = function(){
+ return cc._easeExponentialOutObj;
+};
+
+/**
+ * Ease Exponential InOut.
+ * Reference easeInOutExpo:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ *
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 please use action.easing(cc.easeExponentialInOut)
+ *
+ * @example
+ * //The old usage
+ * cc.EaseExponentialInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeExponentialInOut());
+ */
+cc.EaseExponentialInOut = cc.ActionEase.extend(/** @lends cc.EaseExponentialInOut# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ if( dt !== 1 && dt !== 0) {
+ dt *= 2;
+ if (dt < 1)
+ dt = 0.5 * Math.pow(2, 10 * (dt - 1));
+ else
+ dt = 0.5 * (-Math.pow(2, -10 * (dt - 1)) + 2);
+ }
+ this._inner.update(dt);
+ },
+
+ /**
+ * Create a cc.EaseExponentialInOut action. Opposite with the original motion trajectory.
+ * @return {cc.EaseExponentialInOut}
+ */
+ reverse:function () {
+ return new cc.EaseExponentialInOut(this._inner.reverse());
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseExponentialInOut}
+ */
+ clone:function(){
+ var action = new cc.EaseExponentialInOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ }
+});
+
+/**
+ * creates an EaseExponentialInOut action.
+ * Reference easeInOutExpo:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ * @deprecated since v3.0 Please use action.easing(cc.easeExponentialInOut)
+ * @param {cc.ActionInterval} action
+ * @return {cc.EaseExponentialInOut}
+ *
+ * @example
+ * //The old usage
+ * cc.EaseExponentialInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeExponentialInOut());
+ */
+cc.EaseExponentialInOut.create = function (action) {
+ return new cc.EaseExponentialInOut(action);
+};
+
+cc._easeExponentialInOutObj = {
+ easing: function(dt){
+ if( dt !== 1 && dt !== 0) {
+ dt *= 2;
+ if (dt < 1)
+ return 0.5 * Math.pow(2, 10 * (dt - 1));
+ else
+ return 0.5 * (-Math.pow(2, -10 * (dt - 1)) + 2);
+ }
+ return dt;
+ },
+ reverse: function(){
+ return cc._easeExponentialInOutObj;
+ }
+};
+
+/**
+ * creates an EaseExponentialInOut action easing object.
+ * Reference easeInOutExpo:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeExponentialInOut());
+ */
+cc.easeExponentialInOut = function(){
+ return cc._easeExponentialInOutObj;
+};
+
+/**
+ * Ease Sine In.
+ * Reference easeInSine:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 please use action.easing(cc.easeSineIn())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseSineIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeSineIn());
+ */
+cc.EaseSineIn = cc.ActionEase.extend(/** @lends cc.EaseSineIn# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ dt = dt===0 || dt===1 ? dt : -1 * Math.cos(dt * Math.PI / 2) + 1;
+ this._inner.update(dt);
+ },
+
+ /**
+ * Create a cc.EaseSineOut action. Opposite with the original motion trajectory.
+ * @return {cc.EaseSineOut}
+ */
+ reverse:function () {
+ return new cc.EaseSineOut(this._inner.reverse());
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseSineIn}
+ */
+ clone:function(){
+ var action = new cc.EaseSineIn();
+ action.initWithAction(this._inner.clone());
+ return action;
+ }
+});
+
+/**
+ * creates an EaseSineIn action.
+ * Reference easeInSine:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ * @deprecated since v3.0 Please use action.easing(cc.easeSineIn())
+ * @param {cc.ActionInterval} action
+ * @return {cc.EaseSineIn}
+ *
+ * @example
+ * //The old usage
+ * cc.EaseSineIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeSineIn());
+ */
+cc.EaseSineIn.create = function (action) {
+ return new cc.EaseSineIn(action);
+};
+
+cc._easeSineInObj = {
+ easing: function(dt){
+ return (dt===0 || dt===1) ? dt : -1 * Math.cos(dt * Math.PI / 2) + 1;
+ },
+ reverse: function(){
+ return cc._easeSineOutObj;
+ }
+};
+/**
+ * creates an EaseSineIn action.
+ * Reference easeInSine:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeSineIn());
+ */
+cc.easeSineIn = function(){
+ return cc._easeSineInObj;
+};
+
+/**
+ * Ease Sine Out.
+ * Reference easeOutSine:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 please use action.easing(cc.easeSineOut())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseSineOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeSineOut());
+ */
+cc.EaseSineOut = cc.ActionEase.extend(/** @lends cc.EaseSineOut# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ dt = dt===0 || dt===1 ? dt : Math.sin(dt * Math.PI / 2);
+ this._inner.update(dt);
+ },
+
+ /**
+ * Create a cc.EaseSineIn action. Opposite with the original motion trajectory.
+ * @return {cc.EaseSineIn}
+ */
+ reverse:function () {
+ return new cc.EaseSineIn(this._inner.reverse());
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseSineOut}
+ */
+ clone:function(){
+ var action = new cc.EaseSineOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ }
+});
+
+/**
+ * Creates an EaseSineOut action.
+ * Reference easeOutSine:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ * @deprecated since v3.0 Please use action.easing(cc.easeSineOut())
+ * @param {cc.ActionInterval} action
+ * @return {cc.EaseSineOut}
+ *
+ * @example
+ * //The old usage
+ * cc.EaseSineOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeSineOut());
+ */
+cc.EaseSineOut.create = function (action) {
+ return new cc.EaseSineOut(action);
+};
+
+cc._easeSineOutObj = {
+ easing: function(dt){
+ return (dt===0 || dt===1) ? dt : Math.sin(dt * Math.PI / 2);
+ },
+ reverse: function(){
+ return cc._easeSineInObj;
+ }
+};
+
+/**
+ * Creates an EaseSineOut action easing object.
+ * Reference easeOutSine:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeSineOut());
+ */
+cc.easeSineOut = function(){
+ return cc._easeSineOutObj;
+};
+
+/**
+ * Ease Sine InOut.
+ * Reference easeInOutSine:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 please use action.easing(cc.easeSineInOut())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseSineInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeSineInOut());
+ */
+cc.EaseSineInOut = cc.ActionEase.extend(/** @lends cc.EaseSineInOut# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ dt = dt===0 || dt===1 ? dt : -0.5 * (Math.cos(Math.PI * dt) - 1);
+ this._inner.update(dt);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseSineInOut}
+ */
+ clone:function(){
+ var action = new cc.EaseSineInOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a cc.EaseSineInOut action. Opposite with the original motion trajectory.
+ * @return {cc.EaseSineInOut}
+ */
+ reverse:function () {
+ return new cc.EaseSineInOut(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeInOutSine:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ * @param {cc.ActionInterval} action
+ * @return {cc.EaseSineInOut}
+ * @deprecated since v3.0 Please use action.easing(cc.easeSineInOut())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseSineInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeSineInOut());
+ */
+cc.EaseSineInOut.create = function (action) {
+ return new cc.EaseSineInOut(action);
+};
+
+cc._easeSineInOutObj = {
+ easing: function(dt){
+ return (dt === 0 || dt === 1) ? dt : -0.5 * (Math.cos(Math.PI * dt) - 1);
+ },
+ reverse: function(){
+ return cc._easeSineInOutObj;
+ }
+};
+
+/**
+ * creates the action easing object.
+ * Reference easeInOutSine:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeSineInOut());
+ */
+cc.easeSineInOut = function(){
+ return cc._easeSineInOutObj;
+};
+
+/**
+ * Ease Elastic abstract class.
+ * @class
+ * @extends cc.ActionEase
+ * @param {cc.ActionInterval} action
+ * @param {Number} [period=0.3]
+ *
+ * @deprecated since v3.0 Does not recommend the use of the base object.
+ */
+cc.EaseElastic = cc.ActionEase.extend(/** @lends cc.EaseElastic# */{
+ _period: 0.3,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Creates the action with the inner action and the period in radians (default is 0.3).
+ * @param {cc.ActionInterval} action
+ * @param {Number} [period=0.3]
+ */
+ ctor:function(action, period){
+ cc.ActionEase.prototype.ctor.call(this);
+
+ action && this.initWithAction(action, period);
+ },
+
+ /**
+ * get period of the wave in radians. default is 0.3
+ * @return {Number}
+ */
+ getPeriod:function () {
+ return this._period;
+ },
+
+ /**
+ * set period of the wave in radians.
+ * @param {Number} period
+ */
+ setPeriod:function (period) {
+ this._period = period;
+ },
+
+ /**
+ * Initializes the action with the inner action and the period in radians (default is 0.3)
+ * @param {cc.ActionInterval} action
+ * @param {Number} [period=0.3]
+ * @return {Boolean}
+ */
+ initWithAction:function (action, period) {
+ cc.ActionEase.prototype.initWithAction.call(this, action);
+ this._period = (period == null) ? 0.3 : period;
+ return true;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * Will be overwrite.
+ * @return {?cc.Action}
+ */
+ reverse:function () {
+ cc.log("cc.EaseElastic.reverse(): it should be overridden in subclass.");
+ return null;
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseElastic}
+ */
+ clone:function(){
+ var action = new cc.EaseElastic();
+ action.initWithAction(this._inner.clone(), this._period);
+ return action;
+ }
+});
+
+/**
+ * Creates the action with the inner action and the period in radians (default is 0.3).
+ * @static
+ * @deprecated since v3.0 Does not recommend the use of the base object.
+ * @param {cc.ActionInterval} action
+ * @param {Number} [period=0.3]
+ * @return {cc.EaseElastic}
+ */
+cc.EaseElastic.create = function (action, period) {
+ return new cc.EaseElastic(action, period);
+};
+
+/**
+ * Ease Elastic In action.
+ * Reference easeInElastic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @warning This action doesn't use a bijective function. Actions like Sequence might have an unexpected result when used with this action.
+ * @class
+ * @extends cc.EaseElastic
+ *
+ * @deprecated since v3.0 please use action.easing(cc.easeElasticIn())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseElasticIn.create(action, period);
+ * //The new usage
+ * action.easing(cc.easeElasticIn(period));
+ */
+cc.EaseElasticIn = cc.EaseElastic.extend(/** @lends cc.EaseElasticIn# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var newT = 0;
+ if (dt === 0 || dt === 1) {
+ newT = dt;
+ } else {
+ var s = this._period / 4;
+ dt = dt - 1;
+ newT = -Math.pow(2, 10 * dt) * Math.sin((dt - s) * Math.PI * 2 / this._period);
+ }
+ this._inner.update(newT);
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseElasticOut}
+ */
+ reverse:function () {
+ return new cc.EaseElasticOut(this._inner.reverse(), this._period);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseElasticIn}
+ */
+ clone:function(){
+ var action = new cc.EaseElasticIn();
+ action.initWithAction(this._inner.clone(), this._period);
+ return action;
+ }
+});
+
+/**
+ * Creates the action with the inner action and the period in radians (default is 0.3).
+ * Reference easeInElastic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @deprecated since v3.0 Please use action.easing(cc.easeElasticIn(period))
+ *
+ * @example
+ * //The old usage
+ * cc.EaseElasticIn.create(action, period);
+ * //The new usage
+ * action.easing(cc.easeElasticIn(period));
+ *
+ * @param {cc.ActionInterval} action
+ * @param {Number} [period=0.3]
+ * @return {cc.EaseElasticIn}
+ */
+cc.EaseElasticIn.create = function (action, period) {
+ return new cc.EaseElasticIn(action, period);
+};
+
+//default ease elastic in object (period = 0.3)
+cc._easeElasticInObj = {
+ easing:function(dt){
+ if (dt === 0 || dt === 1)
+ return dt;
+ dt = dt - 1;
+ return -Math.pow(2, 10 * dt) * Math.sin((dt - (0.3 / 4)) * Math.PI * 2 / 0.3);
+ },
+ reverse:function(){
+ return cc._easeElasticOutObj;
+ }
+};
+
+/**
+ * Creates the action easing obejct with the period in radians (default is 0.3).
+ * Reference easeInElastic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @param {Number} [period=0.3]
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeElasticIn(3.0));
+ */
+cc.easeElasticIn = function (period) {
+ if(period && period !== 0.3){
+ return {
+ _period: period,
+ easing: function (dt) {
+ if (dt === 0 || dt === 1)
+ return dt;
+ dt = dt - 1;
+ return -Math.pow(2, 10 * dt) * Math.sin((dt - (this._period / 4)) * Math.PI * 2 / this._period);
+ },
+ reverse:function () {
+ return cc.easeElasticOut(this._period);
+ }
+ };
+ }
+ return cc._easeElasticInObj;
+};
+
+/**
+ * Ease Elastic Out action.
+ * Reference easeOutElastic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @warning This action doesn't use a bijective function. Actions like Sequence might have an unexpected result when used with this action.
+ * @class
+ * @extends cc.EaseElastic
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeElasticOut(period))
+ *
+ * @example
+ * //The old usage
+ * cc.EaseElasticOut.create(action, period);
+ * //The new usage
+ * action.easing(cc.easeElasticOut(period));
+ */
+cc.EaseElasticOut = cc.EaseElastic.extend(/** @lends cc.EaseElasticOut# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var newT = 0;
+ if (dt === 0 || dt === 1) {
+ newT = dt;
+ } else {
+ var s = this._period / 4;
+ newT = Math.pow(2, -10 * dt) * Math.sin((dt - s) * Math.PI * 2 / this._period) + 1;
+ }
+
+ this._inner.update(newT);
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseElasticIn}
+ */
+ reverse:function () {
+ return new cc.EaseElasticIn(this._inner.reverse(), this._period);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseElasticOut}
+ */
+ clone:function(){
+ var action = new cc.EaseElasticOut();
+ action.initWithAction(this._inner.clone(), this._period);
+ return action;
+ }
+});
+
+/**
+ * Creates the action with the inner action and the period in radians (default is 0.3).
+ * Reference easeOutElastic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @deprecated since v3.0 Please use action.easing(cc.easeElasticOut(period))
+ * @param {cc.ActionInterval} action
+ * @param {Number} [period=0.3]
+ * @return {cc.EaseElasticOut}
+ *
+ * @example
+ * //The old usage
+ * cc.EaseElasticOut.create(action, period);
+ * //The new usage
+ * action.easing(cc.easeElasticOut(period));
+ */
+cc.EaseElasticOut.create = function (action, period) {
+ return new cc.EaseElasticOut(action, period);
+};
+
+//default ease elastic out object (period = 0.3)
+cc._easeElasticOutObj = {
+ easing: function (dt) {
+ return (dt === 0 || dt === 1) ? dt : Math.pow(2, -10 * dt) * Math.sin((dt - (0.3 / 4)) * Math.PI * 2 / 0.3) + 1;
+ },
+ reverse:function(){
+ return cc._easeElasticInObj;
+ }
+};
+/**
+ * Creates the action easing object with the period in radians (default is 0.3).
+ * Reference easeOutElastic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @param {Number} [period=0.3]
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeElasticOut(3.0));
+ */
+cc.easeElasticOut = function (period) {
+ if(period && period !== 0.3){
+ return {
+ _period: period,
+ easing: function (dt) {
+ return (dt === 0 || dt === 1) ? dt : Math.pow(2, -10 * dt) * Math.sin((dt - (this._period / 4)) * Math.PI * 2 / this._period) + 1;
+ },
+ reverse:function(){
+ return cc.easeElasticIn(this._period);
+ }
+ };
+ }
+ return cc._easeElasticOutObj;
+};
+
+/**
+ * Ease Elastic InOut action.
+ * Reference easeInOutElastic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @warning This action doesn't use a bijective function. Actions like Sequence might have an unexpected result when used with this action.
+ * @class
+ * @extends cc.EaseElastic
+ *
+ * @deprecated since v3.0 please use action.easing(cc.easeElasticInOut())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseElasticInOut.create(action, period);
+ * //The new usage
+ * action.easing(cc.easeElasticInOut(period));
+ */
+cc.EaseElasticInOut = cc.EaseElastic.extend(/** @lends cc.EaseElasticInOut# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var newT = 0;
+ var locPeriod = this._period;
+ if (dt === 0 || dt === 1) {
+ newT = dt;
+ } else {
+ dt = dt * 2;
+ if (!locPeriod)
+ locPeriod = this._period = 0.3 * 1.5;
+
+ var s = locPeriod / 4;
+ dt = dt - 1;
+ if (dt < 0)
+ newT = -0.5 * Math.pow(2, 10 * dt) * Math.sin((dt - s) * Math.PI * 2 / locPeriod);
+ else
+ newT = Math.pow(2, -10 * dt) * Math.sin((dt - s) * Math.PI * 2 / locPeriod) * 0.5 + 1;
+ }
+ this._inner.update(newT);
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseElasticInOut}
+ */
+ reverse:function () {
+ return new cc.EaseElasticInOut(this._inner.reverse(), this._period);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseElasticInOut}
+ */
+ clone:function(){
+ var action = new cc.EaseElasticInOut();
+ action.initWithAction(this._inner.clone(), this._period);
+ return action;
+ }
+});
+
+/**
+ * Creates the action with the inner action and the period in radians (default is 0.3).
+ * Reference easeInOutElastic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @deprecated since v3.0 Please use action.easing(cc.easeElasticInOut(period))
+ * @param {cc.ActionInterval} action
+ * @param {Number} [period=0.3]
+ * @return {cc.EaseElasticInOut}
+ *
+ * @example
+ * //The old usage
+ * cc.EaseElasticInOut.create(action, period);
+ * //The new usage
+ * action.easing(cc.easeElasticInOut(period));
+ */
+cc.EaseElasticInOut.create = function (action, period) {
+ return new cc.EaseElasticInOut(action, period);
+};
+
+/**
+ * Creates the action easing object with the period in radians (default is 0.3).
+ * Reference easeInOutElastic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @param {Number} [period=0.3]
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeElasticInOut(3.0));
+ */
+cc.easeElasticInOut = function (period) {
+ period = period || 0.3;
+ return {
+ _period: period,
+ easing: function (dt) {
+ var newT = 0;
+ var locPeriod = this._period;
+ if (dt === 0 || dt === 1) {
+ newT = dt;
+ } else {
+ dt = dt * 2;
+ if (!locPeriod)
+ locPeriod = this._period = 0.3 * 1.5;
+ var s = locPeriod / 4;
+ dt = dt - 1;
+ if (dt < 0)
+ newT = -0.5 * Math.pow(2, 10 * dt) * Math.sin((dt - s) * Math.PI * 2 / locPeriod);
+ else
+ newT = Math.pow(2, -10 * dt) * Math.sin((dt - s) * Math.PI * 2 / locPeriod) * 0.5 + 1;
+ }
+ return newT;
+ },
+ reverse: function(){
+ return cc.easeElasticInOut(this._period);
+ }
+ };
+};
+
+/**
+ * cc.EaseBounce abstract class.
+ *
+ * @deprecated since v3.0 Does not recommend the use of the base object.
+ *
+ * @class
+ * @extends cc.ActionEase
+ */
+cc.EaseBounce = cc.ActionEase.extend(/** @lends cc.EaseBounce# */{
+ /**
+ * @param {Number} time1
+ * @return {Number}
+ */
+ bounceTime:function (time1) {
+ if (time1 < 1 / 2.75) {
+ return 7.5625 * time1 * time1;
+ } else if (time1 < 2 / 2.75) {
+ time1 -= 1.5 / 2.75;
+ return 7.5625 * time1 * time1 + 0.75;
+ } else if (time1 < 2.5 / 2.75) {
+ time1 -= 2.25 / 2.75;
+ return 7.5625 * time1 * time1 + 0.9375;
+ }
+
+ time1 -= 2.625 / 2.75;
+ return 7.5625 * time1 * time1 + 0.984375;
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseBounce}
+ */
+ clone:function(){
+ var action = new cc.EaseBounce();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseBounce}
+ */
+ reverse:function () {
+ return new cc.EaseBounce(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates an ease bounce action.
+ * @static
+ * @deprecated since v3.0 Does not recommend the use of the base object.
+ * @param {cc.ActionInterval} action
+ * @return {cc.EaseBounce}
+ */
+cc.EaseBounce.create = function (action) {
+ return new cc.EaseBounce(action);
+};
+
+/**
+ * cc.EaseBounceIn action.
+ * Eased bounce effect at the beginning.
+ * @warning This action doesn't use a bijective function. Actions like Sequence might have an unexpected result when used with this action.
+ * @class
+ * @extends cc.EaseBounce
+ *
+ * @deprecated since v3.0 please use action.easing(cc.easeBounceIn())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseBounceIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeBounceIn());
+ */
+cc.EaseBounceIn = cc.EaseBounce.extend(/** @lends cc.EaseBounceIn# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var newT = 1 - this.bounceTime(1 - dt);
+ this._inner.update(newT);
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseBounceOut}
+ */
+ reverse:function () {
+ return new cc.EaseBounceOut(this._inner.reverse());
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseBounceIn}
+ */
+ clone:function(){
+ var action = new cc.EaseBounceIn();
+ action.initWithAction(this._inner.clone());
+ return action;
+ }
+});
+
+/**
+ * Creates the action.
+ * Eased bounce effect at the beginning.
+ * @static
+ * @deprecated since v3.0 Please use action.easing(cc.easeBounceIn())
+ * @param {cc.ActionInterval} action
+ * @return {cc.EaseBounceIn}
+ *
+ * @example
+ * //The old usage
+ * cc.EaseBounceIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeBounceIn());
+ */
+cc.EaseBounceIn.create = function (action) {
+ return new cc.EaseBounceIn(action);
+};
+
+cc._bounceTime = function (time1) {
+ if (time1 < 1 / 2.75) {
+ return 7.5625 * time1 * time1;
+ } else if (time1 < 2 / 2.75) {
+ time1 -= 1.5 / 2.75;
+ return 7.5625 * time1 * time1 + 0.75;
+ } else if (time1 < 2.5 / 2.75) {
+ time1 -= 2.25 / 2.75;
+ return 7.5625 * time1 * time1 + 0.9375;
+ }
+
+ time1 -= 2.625 / 2.75;
+ return 7.5625 * time1 * time1 + 0.984375;
+};
+
+cc._easeBounceInObj = {
+ easing: function(dt){
+ return 1 - cc._bounceTime(1 - dt);
+ },
+ reverse: function(){
+ return cc._easeBounceOutObj;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Eased bounce effect at the beginning.
+ * @function
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeBounceIn());
+ */
+cc.easeBounceIn = function(){
+ return cc._easeBounceInObj;
+};
+
+/**
+ * cc.EaseBounceOut action.
+ * Eased bounce effect at the ending.
+ * @warning This action doesn't use a bijective function. Actions like Sequence might have an unexpected result when used with this action.
+ * @class
+ * @extends cc.EaseBounce
+ *
+ * @deprecated since v3.0 please use action.easing(cc.easeBounceOut())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseBounceOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeBounceOut());
+ */
+cc.EaseBounceOut = cc.EaseBounce.extend(/** @lends cc.EaseBounceOut# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var newT = this.bounceTime(dt);
+ this._inner.update(newT);
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseBounceIn}
+ */
+ reverse:function () {
+ return new cc.EaseBounceIn(this._inner.reverse());
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseBounceOut}
+ */
+ clone:function(){
+ var action = new cc.EaseBounceOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ }
+});
+
+/**
+ * Creates the action.
+ * Eased bounce effect at the ending.
+ * @static
+ * @deprecated since v3.0 please use action.easing(cc.easeBounceOut())
+ * @param {cc.ActionInterval} action
+ * @return {cc.EaseBounceOut}
+ *
+ * @example
+ * //The old usage
+ * cc.EaseBounceOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeBounceOut());
+ */
+cc.EaseBounceOut.create = function (action) {
+ return new cc.EaseBounceOut(action);
+};
+
+cc._easeBounceOutObj = {
+ easing: function(dt){
+ return cc._bounceTime(dt);
+ },
+ reverse:function () {
+ return cc._easeBounceInObj;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Eased bounce effect at the ending.
+ * @function
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeBounceOut());
+ */
+cc.easeBounceOut = function(){
+ return cc._easeBounceOutObj;
+};
+
+/**
+ * cc.EaseBounceInOut action.
+ * Eased bounce effect at the beginning and ending.
+ * @warning This action doesn't use a bijective function. Actions like Sequence might have an unexpected result when used with this action.
+ * @class
+ * @extends cc.EaseBounce
+ *
+ * @deprecated since v3.0 Please use acton.easing(cc.easeBounceInOut())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseBounceInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeBounceInOut());
+ */
+cc.EaseBounceInOut = cc.EaseBounce.extend(/** @lends cc.EaseBounceInOut# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var newT = 0;
+ if (dt < 0.5) {
+ dt = dt * 2;
+ newT = (1 - this.bounceTime(1 - dt)) * 0.5;
+ } else {
+ newT = this.bounceTime(dt * 2 - 1) * 0.5 + 0.5;
+ }
+ this._inner.update(newT);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseBounceInOut}
+ */
+ clone:function(){
+ var action = new cc.EaseBounceInOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseBounceInOut}
+ */
+ reverse:function () {
+ return new cc.EaseBounceInOut(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Eased bounce effect at the beginning and ending.
+ * @static
+ * @deprecated since v3.0 Please use action.easing(cc.easeBounceInOut())
+ * @param {cc.ActionInterval} action
+ * @return {cc.EaseBounceInOut}
+ *
+ * @example
+ * //The old usage
+ * cc.EaseBounceInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeBounceInOut());
+ */
+cc.EaseBounceInOut.create = function (action) {
+ return new cc.EaseBounceInOut(action);
+};
+
+cc._easeBounceInOutObj = {
+ easing: function (time1) {
+ var newT;
+ if (time1 < 0.5) {
+ time1 = time1 * 2;
+ newT = (1 - cc._bounceTime(1 - time1)) * 0.5;
+ } else {
+ newT = cc._bounceTime(time1 * 2 - 1) * 0.5 + 0.5;
+ }
+ return newT;
+ },
+ reverse: function(){
+ return cc._easeBounceInOutObj;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Eased bounce effect at the beginning and ending.
+ * @function
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeBounceInOut());
+ */
+cc.easeBounceInOut = function(){
+ return cc._easeBounceInOutObj;
+};
+
+/**
+ * cc.EaseBackIn action.
+ * In the opposite direction to move slowly, and then accelerated to the right direction.
+ * @warning This action doesn't use a bijective function. Actions like Sequence might have an unexpected result when used with this action.
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 please use action.easing(cc.easeBackIn())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseBackIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeBackIn());
+ */
+cc.EaseBackIn = cc.ActionEase.extend(/** @lends cc.EaseBackIn# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var overshoot = 1.70158;
+ dt = dt===0 || dt===1 ? dt : dt * dt * ((overshoot + 1) * dt - overshoot);
+ this._inner.update(dt);
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseBackOut}
+ */
+ reverse:function () {
+ return new cc.EaseBackOut(this._inner.reverse());
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseBackIn}
+ */
+ clone:function(){
+ var action = new cc.EaseBackIn();
+ action.initWithAction(this._inner.clone());
+ return action;
+ }
+});
+
+
+/**
+ * Creates the cc.EaseBackIn.
+ * In the opposite direction to move slowly, and then accelerated to the right direction.
+ * @static
+ * @deprecated since v3.0 Please use action.easing(cc.easeBackIn())
+ * @param {cc.ActionInterval} action
+ * @return {cc.EaseBackIn}
+ *
+ * @example
+ * //The old usage
+ * cc.EaseBackIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeBackIn());
+ */
+cc.EaseBackIn.create = function (action) {
+ return new cc.EaseBackIn(action);
+};
+
+cc._easeBackInObj = {
+ easing: function (time1) {
+ var overshoot = 1.70158;
+ return (time1===0 || time1===1) ? time1 : time1 * time1 * ((overshoot + 1) * time1 - overshoot);
+ },
+ reverse: function(){
+ return cc._easeBackOutObj;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * In the opposite direction to move slowly, and then accelerated to the right direction.
+ * @function
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeBackIn());
+ */
+cc.easeBackIn = function(){
+ return cc._easeBackInObj;
+};
+
+/**
+ * cc.EaseBackOut action.
+ * Fast moving more than the finish, and then slowly back to the finish.
+ * @warning This action doesn't use a bijective function. Actions like Sequence might have an unexpected result when used with this action.
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 please use action.easing(cc.easeBackOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseBackOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeBackOut());
+ */
+cc.EaseBackOut = cc.ActionEase.extend(/** @lends cc.EaseBackOut# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var overshoot = 1.70158;
+ dt = dt - 1;
+ this._inner.update(dt * dt * ((overshoot + 1) * dt + overshoot) + 1);
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseBackIn}
+ */
+ reverse:function () {
+ return new cc.EaseBackIn(this._inner.reverse());
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseBackOut}
+ */
+ clone:function(){
+ var action = new cc.EaseBackOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ }
+});
+
+/**
+ * Creates the action.
+ * Fast moving more than the finish, and then slowly back to the finish.
+ * @static
+ * @deprecated since v3.0 Please use action.easing(cc.easeBackOut());
+ * @param {cc.ActionInterval} action
+ * @return {cc.EaseBackOut}
+ *
+ * @example
+ * //The old usage
+ * cc.EaseBackOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeBackOut());
+ */
+cc.EaseBackOut.create = function (action) {
+ return new cc.EaseBackOut(action);
+};
+
+cc._easeBackOutObj = {
+ easing: function (time1) {
+ var overshoot = 1.70158;
+ time1 = time1 - 1;
+ return time1 * time1 * ((overshoot + 1) * time1 + overshoot) + 1;
+ },
+ reverse: function(){
+ return cc._easeBackInObj;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Fast moving more than the finish, and then slowly back to the finish.
+ * @function
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeBackOut());
+ */
+cc.easeBackOut = function(){
+ return cc._easeBackOutObj;
+};
+
+/**
+ * cc.EaseBackInOut action.
+ * Beginning of cc.EaseBackIn. Ending of cc.EaseBackOut.
+ * @warning This action doesn't use a bijective function. Actions like Sequence might have an unexpected result when used with this action.
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeBackInOut())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseBackInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeBackInOut());
+ */
+cc.EaseBackInOut = cc.ActionEase.extend(/** @lends cc.EaseBackInOut# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var overshoot = 1.70158 * 1.525;
+ dt = dt * 2;
+ if (dt < 1) {
+ this._inner.update((dt * dt * ((overshoot + 1) * dt - overshoot)) / 2);
+ } else {
+ dt = dt - 2;
+ this._inner.update((dt * dt * ((overshoot + 1) * dt + overshoot)) / 2 + 1);
+ }
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseBackInOut}
+ */
+ clone:function(){
+ var action = new cc.EaseBackInOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseBackInOut}
+ */
+ reverse:function () {
+ return new cc.EaseBackInOut(this._inner.reverse());
+ }
+});
+
+
+/**
+ * Creates the action.
+ * Beginning of cc.EaseBackIn. Ending of cc.EaseBackOut.
+ * @static
+ * @param {cc.ActionInterval} action
+ * @return {cc.EaseBackInOut}
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeBackInOut())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseBackInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeBackInOut());
+ */
+cc.EaseBackInOut.create = function (action) {
+ return new cc.EaseBackInOut(action);
+};
+
+cc._easeBackInOutObj = {
+ easing: function (time1) {
+ var overshoot = 1.70158 * 1.525;
+ time1 = time1 * 2;
+ if (time1 < 1) {
+ return (time1 * time1 * ((overshoot + 1) * time1 - overshoot)) / 2;
+ } else {
+ time1 = time1 - 2;
+ return (time1 * time1 * ((overshoot + 1) * time1 + overshoot)) / 2 + 1;
+ }
+ },
+ reverse: function(){
+ return cc._easeBackInOutObj;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Beginning of cc.EaseBackIn. Ending of cc.EaseBackOut.
+ * @function
+ * @return {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeBackInOut());
+ */
+cc.easeBackInOut = function(){
+ return cc._easeBackInOutObj;
+};
+
+/**
+ * cc.EaseBezierAction action.
+ * Manually set a 4 order Bessel curve.
+ * According to the set point, calculate the trajectory.
+ * @class
+ * @extends cc.ActionEase
+ * @param {cc.Action} action
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeBezierAction())
+ *
+ * @example
+ * //The old usage
+ * var action = cc.EaseBezierAction.create(action);
+ * action.setBezierParamer(0.5, 0.5, 1.0, 1.0);
+ * //The new usage
+ * action.easing(cc.easeBezierAction(0.5, 0.5, 1.0, 1.0));
+ */
+cc.EaseBezierAction = cc.ActionEase.extend(/** @lends cc.EaseBezierAction# */{
+
+ _p0: null,
+ _p1: null,
+ _p2: null,
+ _p3: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Initialization requires the application of Bessel curve of action.
+ * @param {cc.Action} action
+ */
+ ctor: function(action){
+ cc.ActionEase.prototype.ctor.call(this, action);
+ },
+
+ _updateTime: function(a, b, c, d, t){
+ return (Math.pow(1-t,3) * a + 3*t*(Math.pow(1-t,2))*b + 3*Math.pow(t,2)*(1-t)*c + Math.pow(t,3)*d );
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ var t = this._updateTime(this._p0, this._p1, this._p2, this._p3, dt);
+ this._inner.update(t);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseBezierAction}
+ */
+ clone: function(){
+ var action = new cc.EaseBezierAction();
+ action.initWithAction(this._inner.clone());
+ action.setBezierParamer(this._p0, this._p1, this._p2, this._p3);
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseBezierAction}
+ */
+ reverse: function(){
+ var action = new cc.EaseBezierAction(this._inner.reverse());
+ action.setBezierParamer(this._p3, this._p2, this._p1, this._p0);
+ return action;
+ },
+
+ /**
+ * Set of 4 reference point
+ * @param p0
+ * @param p1
+ * @param p2
+ * @param p3
+ */
+ setBezierParamer: function(p0, p1, p2, p3){
+ this._p0 = p0 || 0;
+ this._p1 = p1 || 0;
+ this._p2 = p2 || 0;
+ this._p3 = p3 || 0;
+ }
+});
+
+/**
+ * Creates the action.
+ * After creating the cc.EaseBezierAction, also need to manually call setBezierParamer.
+ * According to the set point, calculate the trajectory.
+ * @static
+ * @param action
+ * @returns {cc.EaseBezierAction}
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeBezierAction())
+ *
+ * @example
+ * //The old usage
+ * var action = cc.EaseBezierAction.create(action);
+ * action.setBezierParamer(0.5, 0.5, 1.0, 1.0);
+ * //The new usage
+ * action.easing(cc.easeBezierAction(0.5, 0.5, 1.0, 1.0));
+ */
+cc.EaseBezierAction.create = function(action){
+ return new cc.EaseBezierAction(action);
+};
+
+/**
+ * Creates the action easing object.
+ * Into the 4 reference point.
+ * To calculate the motion curve.
+ * @param {Number} p0 The first bezier parameter
+ * @param {Number} p1 The second bezier parameter
+ * @param {Number} p2 The third bezier parameter
+ * @param {Number} p3 The fourth bezier parameter
+ * @returns {Object}
+ * @example
+ * // example
+ * action.easing(cc.easeBezierAction(0.5, 0.5, 1.0, 1.0));
+ */
+cc.easeBezierAction = function(p0, p1, p2, p3){
+ return {
+ easing: function(time){
+ return cc.EaseBezierAction.prototype._updateTime(p0, p1, p2, p3, time);
+ },
+ reverse: function(){
+ return cc.easeBezierAction(p3, p2, p1, p0);
+ }
+ };
+};
+
+/**
+ * cc.EaseQuadraticActionIn action.
+ * Reference easeInQuad:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuadraticAction())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuadraticActionIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuadraticActionIn());
+ */
+cc.EaseQuadraticActionIn = cc.ActionEase.extend(/** @lends cc.EaseQuadraticActionIn# */{
+
+ _updateTime: function(time){
+ return Math.pow(time, 2);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseQuadraticActionIn}
+ */
+ clone: function(){
+ var action = new cc.EaseQuadraticActionIn();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseQuadraticActionIn}
+ */
+ reverse: function(){
+ return new cc.EaseQuadraticActionIn(this._inner.reverse());
+ }
+
+});
+
+/**
+ * Creates the cc.EaseQuadRaticActionIn.
+ * Reference easeInQuad:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ * @param action
+ * @returns {cc.EaseQuadraticActionIn}
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuadraticAction())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuadraticActionIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuadraticActionIn());
+ */
+cc.EaseQuadraticActionIn.create = function(action){
+ return new cc.EaseQuadraticActionIn(action);
+};
+
+cc._easeQuadraticActionIn = {
+ easing: cc.EaseQuadraticActionIn.prototype._updateTime,
+ reverse: function(){
+ return cc._easeQuadraticActionIn;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Reference easeInQuad:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @returns {Object}
+ * @example
+ * //example
+ * action.easing(cc.easeQuadraticActionIn());
+ */
+cc.easeQuadraticActionIn = function(){
+ return cc._easeQuadraticActionIn;
+};
+
+/**
+ * cc.EaseQuadraticActionIn action.
+ * Reference easeOutQuad:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuadraticActionOut())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuadraticActionOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuadraticActionOut());
+ */
+cc.EaseQuadraticActionOut = cc.ActionEase.extend(/** @lends cc.EaseQuadraticActionOut# */{
+
+ _updateTime: function(time){
+ return -time*(time-2);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseQuadraticActionOut}
+ */
+ clone: function(){
+ var action = new cc.EaseQuadraticActionOut();
+ action.initWithAction();
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseQuadraticActionOut}
+ */
+ reverse: function(){
+ return new cc.EaseQuadraticActionOut(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeOutQuad:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ * @param action
+ * @returns {cc.EaseQuadraticActionOut}
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuadraticActionOut())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuadraticActionOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuadraticActionOut());
+ */
+cc.EaseQuadraticActionOut.create = function(action){
+ return new cc.EaseQuadraticActionOut(action);
+};
+
+cc._easeQuadraticActionOut = {
+ easing: cc.EaseQuadraticActionOut.prototype._updateTime,
+ reverse: function(){
+ return cc._easeQuadraticActionOut;
+ }
+};
+/**
+ * Creates the action easing object.
+ * Reference easeOutQuad:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @returns {Object}
+ * @example
+ * //example
+ * action.easing(cc.easeQuadraticActionOut());
+ */
+cc.easeQuadraticActionOut = function(){
+ return cc._easeQuadraticActionOut;
+};
+
+/**
+ * cc.EaseQuadraticActionInOut action.
+ * Reference easeInOutQuad:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuadraticActionInOut())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuadraticActionInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuadraticActionInOut());
+ */
+cc.EaseQuadraticActionInOut = cc.ActionEase.extend(/** @lends cc.EaseQuadraticActionInOut# */{
+ _updateTime: function(time){
+ var resultTime = time;
+ time *= 2;
+ if(time < 1){
+ resultTime = time * time * 0.5;
+ }else{
+ --time;
+ resultTime = -0.5 * ( time * ( time - 2 ) - 1)
+ }
+ return resultTime;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseQuadraticActionInOut}
+ */
+ clone: function(){
+ var action = new cc.EaseQuadraticActionInOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseQuadraticActionInOut}
+ */
+ reverse: function(){
+ return new cc.EaseQuadraticActionInOut(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeInOutQuad:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuadraticActionInOut())
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuadraticActionInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuadraticActionInOut());
+ *
+ * @param action
+ * @returns {cc.EaseQuadraticActionInOut}
+ */
+cc.EaseQuadraticActionInOut.create = function(action){
+ return new cc.EaseQuadraticActionInOut(action);
+};
+
+cc._easeQuadraticActionInOut = {
+ easing: cc.EaseQuadraticActionInOut.prototype._updateTime,
+ reverse: function(){
+ return cc._easeQuadraticActionInOut;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Reference easeInOutQuad:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @returns {Object}
+ * @example
+ * //example
+ * action.easing(cc.easeQuadraticActionInOut());
+ */
+cc.easeQuadraticActionInOut = function(){
+ return cc._easeQuadraticActionInOut;
+};
+
+/**
+ * cc.EaseQuarticActionIn action.
+ * Reference easeInQuart:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuarticActionIn());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuarticActionIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuarticActionIn());
+ */
+cc.EaseQuarticActionIn = cc.ActionEase.extend(/** @lends cc.EaseQuarticActionIn# */{
+ _updateTime: function(time){
+ return time * time * time * time;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseQuarticActionIn}
+ */
+ clone: function(){
+ var action = new cc.EaseQuarticActionIn();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseQuarticActionIn}
+ */
+ reverse: function(){
+ return new cc.EaseQuarticActionIn(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeInQuart:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuarticActionIn());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuarticActionIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuarticActionIn());
+ *
+ * @param action
+ * @returns {cc.EaseQuarticActionIn}
+ */
+cc.EaseQuarticActionIn.create = function(action){
+ return new cc.EaseQuarticActionIn(action);
+};
+
+cc._easeQuarticActionIn = {
+ easing: cc.EaseQuarticActionIn.prototype._updateTime,
+ reverse: function(){
+ return cc._easeQuarticActionIn;
+ }
+};
+/**
+ * Creates the action easing object.
+ * Reference easeIntQuart:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @returns {Object}
+ * @example
+ * //example
+ * action.easing(cc.easeQuarticActionIn());
+ */
+cc.easeQuarticActionIn = function(){
+ return cc._easeQuarticActionIn;
+};
+
+/**
+ * cc.EaseQuarticActionOut action.
+ * Reference easeOutQuart:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.QuarticActionOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuarticActionOut.create(action);
+ * //The new usage
+ * action.easing(cc.EaseQuarticActionOut());
+ */
+cc.EaseQuarticActionOut = cc.ActionEase.extend(/** @lends cc.EaseQuarticActionOut# */{
+ _updateTime: function(time){
+ time -= 1;
+ return -(time * time * time * time - 1);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseQuarticActionOut}
+ */
+ clone: function(){
+ var action = new cc.EaseQuarticActionOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseQuarticActionOut}
+ */
+ reverse: function(){
+ return new cc.EaseQuarticActionOut(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeOutQuart:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.QuarticActionOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuarticActionOut.create(action);
+ * //The new usage
+ * action.easing(cc.EaseQuarticActionOut());
+ *
+ * @param action
+ * @returns {cc.EaseQuarticActionOut}
+ */
+cc.EaseQuarticActionOut.create = function(action){
+ return new cc.EaseQuarticActionOut(action);
+};
+
+cc._easeQuarticActionOut = {
+ easing: cc.EaseQuarticActionOut.prototype._updateTime,
+ reverse: function(){
+ return cc._easeQuarticActionOut;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Reference easeOutQuart:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @returns {Object}
+ * @example
+ * //example
+ * action.easing(cc.QuarticActionOut());
+ */
+cc.easeQuarticActionOut = function(){
+ return cc._easeQuarticActionOut;
+};
+
+/**
+ * cc.EaseQuarticActionInOut action.
+ * Reference easeInOutQuart:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuarticActionInOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuarticActionInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuarticActionInOut());
+ */
+cc.EaseQuarticActionInOut = cc.ActionEase.extend(/** @lends cc.EaseQuarticActionInOut# */{
+ _updateTime: function(time){
+ time = time*2;
+ if (time < 1)
+ return 0.5 * time * time * time * time;
+ time -= 2;
+ return -0.5 * (time * time * time * time - 2);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseQuarticActionInOut}
+ */
+ clone: function(){
+ var action = new cc.EaseQuarticActionInOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseQuarticActionInOut}
+ */
+ reverse: function(){
+ return new cc.EaseQuarticActionInOut(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeInOutQuart:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuarticActionInOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuarticActionInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuarticActionInOut());
+ *
+ * @param action
+ * @returns {cc.EaseQuarticActionInOut}
+ */
+cc.EaseQuarticActionInOut.create = function(action){
+ return new cc.EaseQuarticActionInOut(action);
+};
+
+cc._easeQuarticActionInOut = {
+ easing: cc.EaseQuarticActionInOut.prototype._updateTime,
+ reverse: function(){
+ return cc._easeQuarticActionInOut;
+ }
+};
+/**
+ * Creates the action easing object.
+ * Reference easeInOutQuart:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @returns {Object}
+ */
+cc.easeQuarticActionInOut = function(){
+ return cc._easeQuarticActionInOut;
+};
+
+/**
+ * cc.EaseQuinticActionIn action.
+ * Reference easeInQuint:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuinticActionIn());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuinticActionIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuinticActionIn());
+ */
+cc.EaseQuinticActionIn = cc.ActionEase.extend(/** @lends cc.EaseQuinticActionIn# */{
+ _updateTime: function(time){
+ return time * time * time * time * time;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseQuinticActionIn}
+ */
+ clone: function(){
+ var action = new cc.EaseQuinticActionIn();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseQuinticActionIn}
+ */
+ reverse: function(){
+ return new cc.EaseQuinticActionIn(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeInQuint:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuinticActionIn());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuinticActionIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuinticActionIn());
+ *
+ * @param action
+ * @returns {cc.EaseQuinticActionIn}
+ */
+cc.EaseQuinticActionIn.create = function(action){
+ return new cc.EaseQuinticActionIn(action);
+};
+
+cc._easeQuinticActionIn = {
+ easing: cc.EaseQuinticActionIn.prototype._updateTime,
+ reverse: function(){
+ return cc._easeQuinticActionIn;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Reference easeInQuint:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @returns {Object}
+ * @example
+ * //example
+ * action.easing(cc.easeQuinticActionIn());
+ */
+cc.easeQuinticActionIn = function(){
+ return cc._easeQuinticActionIn;
+};
+
+/**
+ * cc.EaseQuinticActionOut action.
+ * Reference easeQuint:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuadraticActionOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuinticActionOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuadraticActionOut());
+ */
+cc.EaseQuinticActionOut = cc.ActionEase.extend(/** @lends cc.EaseQuinticActionOut# */{
+ _updateTime: function(time){
+ time -=1;
+ return (time * time * time * time * time + 1);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseQuinticActionOut}
+ */
+ clone: function(){
+ var action = new cc.EaseQuinticActionOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseQuinticActionOut}
+ */
+ reverse: function(){
+ return new cc.EaseQuinticActionOut(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeOutQuint:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuadraticActionOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuinticActionOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuadraticActionOut());
+ *
+ * @param action
+ * @returns {cc.EaseQuinticActionOut}
+ */
+cc.EaseQuinticActionOut.create = function(action){
+ return new cc.EaseQuinticActionOut(action);
+};
+
+cc._easeQuinticActionOut = {
+ easing: cc.EaseQuinticActionOut.prototype._updateTime,
+ reverse: function(){
+ return cc._easeQuinticActionOut;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Reference easeOutQuint:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @returns {Object}
+ * @example
+ * //example
+ * action.easing(cc.easeQuadraticActionOut());
+ */
+cc.easeQuinticActionOut = function(){
+ return cc._easeQuinticActionOut;
+};
+
+/**
+ * cc.EaseQuinticActionInOut action.
+ * Reference easeInOutQuint:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuinticActionInOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuinticActionInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuinticActionInOut());
+ */
+cc.EaseQuinticActionInOut = cc.ActionEase.extend(/** @lends cc.EaseQuinticActionInOut# */{
+ _updateTime: function(time){
+ time = time*2;
+ if (time < 1)
+ return 0.5 * time * time * time * time * time;
+ time -= 2;
+ return 0.5 * (time * time * time * time * time + 2);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseQuinticActionInOut}
+ */
+ clone: function(){
+ var action = new cc.EaseQuinticActionInOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseQuinticActionInOut}
+ */
+ reverse: function(){
+ return new cc.EaseQuinticActionInOut(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeInOutQuint:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeQuinticActionInOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseQuinticActionInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeQuinticActionInOut());
+ *
+ * @param action
+ * @returns {cc.EaseQuinticActionInOut}
+ */
+cc.EaseQuinticActionInOut.create = function(action){
+ return new cc.EaseQuinticActionInOut(action);
+};
+
+cc._easeQuinticActionInOut = {
+ easing: cc.EaseQuinticActionInOut.prototype._updateTime,
+ reverse: function(){
+ return cc._easeQuinticActionInOut;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Reference easeInOutQuint:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @returns {Object}
+ * @example
+ * //example
+ * action.easing(cc.easeQuinticActionInOut());
+ */
+cc.easeQuinticActionInOut = function(){
+ return cc._easeQuinticActionInOut;
+};
+
+/**
+ * cc.EaseCircleActionIn action.
+ * Reference easeInCirc:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeCircleActionIn());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseCircleActionIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeCircleActionIn());
+ */
+cc.EaseCircleActionIn = cc.ActionEase.extend(/** @lends cc.EaseCircleActionIn# */{
+ _updateTime: function(time){
+ return -1 * (Math.sqrt(1 - time * time) - 1);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseCircleActionIn}
+ */
+ clone: function(){
+ var action = new cc.EaseCircleActionIn();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseCircleActionIn}
+ */
+ reverse: function(){
+ return new cc.EaseCircleActionIn(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeInCirc:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeCircleActionIn());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseCircleActionIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeCircleActionIn());
+ *
+ * @param action
+ * @returns {cc.EaseCircleActionIn}
+ */
+cc.EaseCircleActionIn.create = function(action){
+ return new cc.EaseCircleActionIn(action);
+};
+
+cc._easeCircleActionIn = {
+ easing: cc.EaseCircleActionIn.prototype._updateTime,
+ reverse: function(){
+ return cc._easeCircleActionIn;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Reference easeInCirc:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @returns {Object}
+ * @example
+ * //example
+ * action.easing(cc.easeCircleActionIn());
+ */
+cc.easeCircleActionIn = function(){
+ return cc._easeCircleActionIn;
+};
+
+/**
+ * cc.EaseCircleActionOut action.
+ * Reference easeOutCirc:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeCircleActionOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseCircleActionOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeCircleActionOut());
+ */
+cc.EaseCircleActionOut = cc.ActionEase.extend(/** @lends cc.EaseCircleActionOut# */{
+ _updateTime: function(time){
+ time = time - 1;
+ return Math.sqrt(1 - time * time);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseCircleActionOut}
+ */
+ clone: function(){
+ var action = new cc.EaseCircleActionOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseCircleActionOut}
+ */
+ reverse: function(){
+ return new cc.EaseCircleActionOut(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeOutCirc:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeCircleActionOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseCircleActionOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeCircleActionOut());
+ *
+ * @param action
+ * @returns {cc.EaseCircleActionOut}
+ */
+cc.EaseCircleActionOut.create = function(action){
+ return new cc.EaseCircleActionOut(action);
+};
+
+cc._easeCircleActionOut = {
+ easing: cc.EaseCircleActionOut.prototype._updateTime,
+ reverse: function(){
+ return cc._easeCircleActionOut;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Reference easeOutCirc:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @returns {Object}
+ * @exampple
+ * //example
+ * actioneasing(cc.easeCircleActionOut());
+ */
+cc.easeCircleActionOut = function(){
+ return cc._easeCircleActionOut;
+};
+
+/**
+ * cc.EaseCircleActionInOut action.
+ * Reference easeInOutCirc:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeCircleActionInOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseCircleActionInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeCircleActionInOut());
+ */
+cc.EaseCircleActionInOut = cc.ActionEase.extend(/** @lends cc.EaseCircleActionInOut# */{
+ _updateTime: function(time){
+ time = time * 2;
+ if (time < 1)
+ return -0.5 * (Math.sqrt(1 - time * time) - 1);
+ time -= 2;
+ return 0.5 * (Math.sqrt(1 - time * time) + 1);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseCircleActionInOut}
+ */
+ clone: function(){
+ var action = new cc.EaseCircleActionInOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseCircleActionInOut}
+ */
+ reverse: function(){
+ return new cc.EaseCircleActionInOut(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeInOutCirc:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeCircleActionInOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseCircleActionInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeCircleActionInOut());
+ *
+ * @param action
+ * @returns {cc.EaseCircleActionInOut}
+ */
+cc.EaseCircleActionInOut.create = function(action){
+ return new cc.EaseCircleActionInOut(action);
+};
+
+cc._easeCircleActionInOut = {
+ easing: cc.EaseCircleActionInOut.prototype._updateTime,
+ reverse: function(){
+ return cc._easeCircleActionInOut;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Reference easeInOutCirc:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @returns {Object}
+ * @example
+ * //example
+ * action.easing(cc.easeCircleActionInOut());
+ */
+cc.easeCircleActionInOut = function(){
+ return cc._easeCircleActionInOut;
+};
+
+/**
+ * cc.EaseCubicActionIn action.
+ * Reference easeInCubic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 action.easing(cc.easeCubicActionIn());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseCubicActionIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeCubicActionIn());
+ */
+cc.EaseCubicActionIn = cc.ActionEase.extend(/** @lends cc.EaseCubicActionIn# */{
+ _updateTime: function(time){
+ return time * time * time;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseCubicActionIn}
+ */
+ clone: function(){
+ var action = new cc.EaseCubicActionIn();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseCubicActionIn}
+ */
+ reverse: function(){
+ return new cc.EaseCubicActionIn(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeInCubic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ *
+ * @deprecated since v3.0 action.easing(cc.easeCubicActionIn());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseCubicActionIn.create(action);
+ * //The new usage
+ * action.easing(cc.easeCubicActionIn());
+ *
+ * @param action
+ * @returns {cc.EaseCubicActionIn}
+ */
+cc.EaseCubicActionIn.create = function(action){
+ return new cc.EaseCubicActionIn(action);
+};
+
+cc._easeCubicActionIn = {
+ easing: cc.EaseCubicActionIn.prototype._updateTime,
+ reverse: function(){
+ return cc._easeCubicActionIn;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Reference easeInCubic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @returns {Object}
+ * @example
+ * //example
+ * action.easing(cc.easeCubicActionIn());
+ */
+cc.easeCubicActionIn = function(){
+ return cc._easeCubicActionIn;
+};
+
+/**
+ * cc.EaseCubicActionOut action.
+ * Reference easeOutCubic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeCubicActionOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseCubicActionOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeCubicActionOut());
+ */
+cc.EaseCubicActionOut = cc.ActionEase.extend(/** @lends cc.EaseCubicActionOut# */{
+ _updateTime: function(time){
+ time -= 1;
+ return (time * time * time + 1);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseCubicActionOut}
+ */
+ clone: function(){
+ var action = new cc.EaseCubicActionOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseCubicActionOut}
+ */
+ reverse: function(){
+ return new cc.EaseCubicActionOut(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeOutCubic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeCubicActionOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseCubicActionOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeCubicActionOut());
+ *
+ * @param action
+ * @returns {cc.EaseCubicActionOut}
+ */
+cc.EaseCubicActionOut.create = function(action){
+ return new cc.EaseCubicActionOut(action);
+};
+
+cc._easeCubicActionOut = {
+ easing: cc.EaseCubicActionOut.prototype._updateTime,
+ reverse: function(){
+ return cc._easeCubicActionOut;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Reference easeOutCubic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @returns {Object}
+ * @example
+ * //example
+ * action.easing(cc.easeCubicActionOut());
+ */
+cc.easeCubicActionOut = function(){
+ return cc._easeCubicActionOut;
+};
+
+/**
+ * cc.EaseCubicActionInOut action.
+ * Reference easeInOutCubic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @class
+ * @extends cc.ActionEase
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeCubicActionInOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseCubicActionInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeCubicActionInOut());
+ */
+cc.EaseCubicActionInOut = cc.ActionEase.extend(/** @lends cc.EaseCubicActionInOut# */{
+ _updateTime: function(time){
+ time = time*2;
+ if (time < 1)
+ return 0.5 * time * time * time;
+ time -= 2;
+ return 0.5 * (time * time * time + 2);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function(dt){
+ this._inner.update(this._updateTime(dt));
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @returns {cc.EaseCubicActionInOut}
+ */
+ clone: function(){
+ var action = new cc.EaseCubicActionInOut();
+ action.initWithAction(this._inner.clone());
+ return action;
+ },
+
+ /**
+ * Create a action. Opposite with the original motion trajectory.
+ * @return {cc.EaseCubicActionInOut}
+ */
+ reverse: function(){
+ return new cc.EaseCubicActionInOut(this._inner.reverse());
+ }
+});
+
+/**
+ * Creates the action.
+ * Reference easeInOutCubic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @static
+ *
+ * @deprecated since v3.0 Please use action.easing(cc.easeCubicActionInOut());
+ *
+ * @example
+ * //The old usage
+ * cc.EaseCubicActionInOut.create(action);
+ * //The new usage
+ * action.easing(cc.easeCubicActionInOut());
+ *
+ * @param action
+ * @returns {cc.EaseCubicActionInOut}
+ */
+cc.EaseCubicActionInOut.create = function(action){
+ return new cc.EaseCubicActionInOut(action);
+};
+
+cc._easeCubicActionInOut = {
+ easing: cc.EaseCubicActionInOut.prototype._updateTime,
+ reverse: function(){
+ return cc._easeCubicActionInOut;
+ }
+};
+
+/**
+ * Creates the action easing object.
+ * Reference easeInOutCubic:
+ * {@link http://www.zhihu.com/question/21981571/answer/19925418}
+ * @function
+ * @returns {Object}
+ */
+cc.easeCubicActionInOut = function(){
+ return cc._easeCubicActionInOut;
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/actions/CCActionInstant.js b/frameworks/cocos2d-html5/cocos2d/actions/CCActionInstant.js
new file mode 100644
index 0000000..f1e73f9
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/actions/CCActionInstant.js
@@ -0,0 +1,749 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Instant actions are immediate actions. They don't have a duration like.
+ * the CCIntervalAction actions.
+ * @class
+ * @extends cc.FiniteTimeAction
+ */
+cc.ActionInstant = cc.FiniteTimeAction.extend(/** @lends cc.ActionInstant# */{
+ /**
+ * return true if the action has finished.
+ * @return {Boolean}
+ */
+ isDone:function () {
+ return true;
+ },
+
+ /**
+ * called every frame with it's delta time.
+ * DON'T override unless you know what you are doing.
+ * @param {Number} dt
+ */
+ step:function (dt) {
+ this.update(1);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ //nothing
+ },
+
+ /**
+ * returns a reversed action.
+ * For example:
+ * - The action will be x coordinates of 0 move to 100.
+ * - The reversed action will be x of 100 move to 0.
+ * - Will be rewritten
+ * @returns {cc.Action}
+ */
+ reverse:function(){
+ return this.clone();
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.FiniteTimeAction}
+ */
+ clone:function(){
+ return new cc.ActionInstant();
+ }
+});
+
+/**
+ * Show the node.
+ * @class
+ * @extends cc.ActionInstant
+ */
+cc.Show = cc.ActionInstant.extend(/** @lends cc.Show# */{
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ this.target.visible = true;
+ },
+
+ /**
+ * returns a reversed action.
+ * For example:
+ * - The action will be x coordinates of 0 move to 100.
+ * - The reversed action will be x of 100 move to 0.
+ * - Will be rewritten
+ * @returns {cc.Hide}
+ */
+ reverse:function () {
+ return new cc.Hide();
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.FiniteTimeAction}
+ */
+ clone:function(){
+ return new cc.Show();
+ }
+});
+
+/**
+ * Show the Node.
+ * @function
+ * @return {cc.Show}
+ * @example
+ * // example
+ * var showAction = cc.show();
+ */
+cc.show = function () {
+ return new cc.Show();
+};
+
+/**
+ * Show the Node. Please use cc.show instead.
+ * @static
+ * @deprecated since v3.0 Please use cc.show instead.
+ * @return {cc.Show}
+ */
+cc.Show.create = cc.show;
+
+/**
+ * Hide the node.
+ * @class
+ * @extends cc.ActionInstant
+ */
+cc.Hide = cc.ActionInstant.extend(/** @lends cc.Hide# */{
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ this.target.visible = false;
+ },
+
+ /**
+ * returns a reversed action.
+ * For example:
+ * - The action will be x coordinates of 0 move to 100.
+ * - The reversed action will be x of 100 move to 0.
+ * - Will be rewritten
+ * @returns {cc.Show}
+ */
+ reverse:function () {
+ return new cc.Show();
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.Hide}
+ */
+ clone:function(){
+ return new cc.Hide();
+ }
+});
+
+/**
+ * Hide the node.
+ * @function
+ * @return {cc.Hide}
+ * @example
+ * // example
+ * var hideAction = cc.hide();
+ */
+cc.hide = function () {
+ return new cc.Hide();
+};
+
+/**
+ * Hide the node. Please use cc.hide instead.
+ * @static
+ * @deprecated since v3.0 Please use cc.hide instead.
+ * @return {cc.Hide}
+ * @example
+ * // example
+ * var hideAction = cc.hide();
+ */
+cc.Hide.create = cc.hide;
+
+/**
+ * Toggles the visibility of a node.
+ * @class
+ * @extends cc.ActionInstant
+ */
+cc.ToggleVisibility = cc.ActionInstant.extend(/** @lends cc.ToggleVisibility# */{
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ this.target.visible = !this.target.visible;
+ },
+
+ /**
+ * returns a reversed action.
+ * @returns {cc.ToggleVisibility}
+ */
+ reverse:function () {
+ return new cc.ToggleVisibility();
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.ToggleVisibility}
+ */
+ clone:function(){
+ return new cc.ToggleVisibility();
+ }
+});
+
+/**
+ * Toggles the visibility of a node.
+ * @function
+ * @return {cc.ToggleVisibility}
+ * @example
+ * // example
+ * var toggleVisibilityAction = cc.toggleVisibility();
+ */
+cc.toggleVisibility = function () {
+ return new cc.ToggleVisibility();
+};
+
+/**
+ * Toggles the visibility of a node. Please use cc.toggleVisibility instead.
+ * @static
+ * @deprecated since v3.0 Please use cc.toggleVisibility instead.
+ * @return {cc.ToggleVisibility}
+ */
+cc.ToggleVisibility.create = cc.toggleVisibility;
+
+/**
+ * Delete self in the next frame.
+ * @class
+ * @extends cc.ActionInstant
+ * @param {Boolean} [isNeedCleanUp=true]
+ *
+ * @example
+ * // example
+ * var removeSelfAction = new cc.RemoveSelf(false);
+ */
+cc.RemoveSelf = cc.ActionInstant.extend({
+ _isNeedCleanUp: true,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Create a RemoveSelf object with a flag indicate whether the target should be cleaned up while removing.
+ * @param {Boolean} [isNeedCleanUp=true]
+ */
+ ctor:function(isNeedCleanUp){
+ cc.FiniteTimeAction.prototype.ctor.call(this);
+
+ isNeedCleanUp !== undefined && this.init(isNeedCleanUp);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function(dt){
+ this.target.removeFromParent(this._isNeedCleanUp);
+ },
+
+ /**
+ * Initialization of the node, please do not call this function by yourself, you should pass the parameters to constructor to initialize it
.
+ * @param isNeedCleanUp
+ * @returns {boolean}
+ */
+ init:function(isNeedCleanUp){
+ this._isNeedCleanUp = isNeedCleanUp;
+ return true;
+ },
+
+ /**
+ * returns a reversed action.
+ */
+ reverse:function(){
+ return new cc.RemoveSelf(this._isNeedCleanUp);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.RemoveSelf}
+ */
+ clone:function(){
+ return new cc.RemoveSelf(this._isNeedCleanUp);
+ }
+});
+
+/**
+ * Create a RemoveSelf object with a flag indicate whether the target should be cleaned up while removing.
+ *
+ * @function
+ * @param {Boolean} [isNeedCleanUp=true]
+ * @return {cc.RemoveSelf}
+ *
+ * @example
+ * // example
+ * var removeSelfAction = cc.removeSelf();
+ */
+cc.removeSelf = function(isNeedCleanUp){
+ return new cc.RemoveSelf(isNeedCleanUp);
+};
+
+/**
+ * Please use cc.removeSelf instead.
+ * Create a RemoveSelf object with a flag indicate whether the target should be cleaned up while removing.
+ *
+ * @static
+ * @deprecated since v3.0 Please use cc.removeSelf instead.
+ * @param {Boolean} [isNeedCleanUp=true]
+ * @return {cc.RemoveSelf}
+ */
+cc.RemoveSelf.create = cc.removeSelf;
+
+/**
+ * Flips the sprite horizontally.
+ * @class
+ * @extends cc.ActionInstant
+ * @param {Boolean} flip Indicate whether the target should be flipped or not
+ *
+ * @example
+ * var flipXAction = new cc.FlipX(true);
+ */
+cc.FlipX = cc.ActionInstant.extend(/** @lends cc.FlipX# */{
+ _flippedX:false,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Create a FlipX action to flip or unflip the target.
+ * @param {Boolean} flip Indicate whether the target should be flipped or not
+ */
+ ctor:function(flip){
+ cc.FiniteTimeAction.prototype.ctor.call(this);
+ this._flippedX = false;
+ flip !== undefined && this.initWithFlipX(flip);
+ },
+
+ /**
+ * initializes the action with a set flipX.
+ * @param {Boolean} flip
+ * @return {Boolean}
+ */
+ initWithFlipX:function (flip) {
+ this._flippedX = flip;
+ return true;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ this.target.flippedX = this._flippedX;
+ },
+
+ /**
+ * returns a reversed action.
+ * @return {cc.FlipX}
+ */
+ reverse:function () {
+ return new cc.FlipX(!this._flippedX);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.FiniteTimeAction}
+ */
+ clone:function(){
+ var action = new cc.FlipX();
+ action.initWithFlipX(this._flippedX);
+ return action;
+ }
+});
+
+/**
+ * Create a FlipX action to flip or unflip the target.
+ *
+ * @function
+ * @param {Boolean} flip Indicate whether the target should be flipped or not
+ * @return {cc.FlipX}
+ * @example
+ * var flipXAction = cc.flipX(true);
+ */
+cc.flipX = function (flip) {
+ return new cc.FlipX(flip);
+};
+
+/**
+ * Plese use cc.flipX instead.
+ * Create a FlipX action to flip or unflip the target
+ *
+ * @static
+ * @deprecated since v3.0 Plese use cc.flipX instead.
+ * @param {Boolean} flip Indicate whether the target should be flipped or not
+ * @return {cc.FlipX}
+ */
+cc.FlipX.create = cc.flipX;
+
+/**
+ * Flips the sprite vertically
+ * @class
+ * @extends cc.ActionInstant
+ * @param {Boolean} flip
+ * @example
+ * var flipYAction = new cc.FlipY(true);
+ */
+cc.FlipY = cc.ActionInstant.extend(/** @lends cc.FlipY# */{
+ _flippedY:false,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Create a FlipY action to flip or unflip the target.
+ *
+ * @param {Boolean} flip
+ */
+ ctor: function(flip){
+ cc.FiniteTimeAction.prototype.ctor.call(this);
+ this._flippedY = false;
+
+ flip !== undefined && this.initWithFlipY(flip);
+ },
+
+ /**
+ * initializes the action with a set flipY.
+ * @param {Boolean} flip
+ * @return {Boolean}
+ */
+ initWithFlipY:function (flip) {
+ this._flippedY = flip;
+ return true;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ this.target.flippedY = this._flippedY;
+ },
+
+ /**
+ * returns a reversed action.
+ * @return {cc.FlipY}
+ */
+ reverse:function () {
+ return new cc.FlipY(!this._flippedY);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.FlipY}
+ */
+ clone:function(){
+ var action = new cc.FlipY();
+ action.initWithFlipY(this._flippedY);
+ return action;
+ }
+});
+
+/**
+ * Create a FlipY action to flip or unflip the target.
+ *
+ * @function
+ * @param {Boolean} flip
+ * @return {cc.FlipY}
+ * @example
+ * var flipYAction = cc.flipY(true);
+ */
+cc.flipY = function (flip) {
+ return new cc.FlipY(flip);
+};
+
+/**
+ * Please use cc.flipY instead
+ * Create a FlipY action to flip or unflip the target
+ *
+ * @static
+ * @deprecated since v3.0 Please use cc.flipY instead.
+ * @param {Boolean} flip
+ * @return {cc.FlipY}
+ */
+cc.FlipY.create = cc.flipY;
+
+/**
+ * Places the node in a certain position
+ * @class
+ * @extends cc.ActionInstant
+ * @param {cc.Point|Number} pos
+ * @param {Number} [y]
+ * @example
+ * var placeAction = new cc.Place(cc.p(200, 200));
+ * var placeAction = new cc.Place(200, 200);
+ */
+cc.Place = cc.ActionInstant.extend(/** @lends cc.Place# */{
+ _x: 0,
+ _y: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Creates a Place action with a position.
+ * @param {cc.Point|Number} pos
+ * @param {Number} [y]
+ */
+ ctor:function(pos, y){
+ cc.FiniteTimeAction.prototype.ctor.call(this);
+ this._x = 0;
+ this._y = 0;
+
+ if (pos !== undefined) {
+ if (pos.x !== undefined) {
+ y = pos.y;
+ pos = pos.x;
+ }
+ this.initWithPosition(pos, y);
+ }
+ },
+
+ /**
+ * Initializes a Place action with a position
+ * @param {number} x
+ * @param {number} y
+ * @return {Boolean}
+ */
+ initWithPosition: function (x, y) {
+ this._x = x;
+ this._y = y;
+ return true;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ this.target.setPosition(this._x, this._y);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.Place}
+ */
+ clone:function(){
+ var action = new cc.Place();
+ action.initWithPosition(this._x, this._y);
+ return action;
+ }
+});
+
+/**
+ * Creates a Place action with a position.
+ * @function
+ * @param {cc.Point|Number} pos
+ * @param {Number} [y]
+ * @return {cc.Place}
+ * @example
+ * // example
+ * var placeAction = cc.place(cc.p(200, 200));
+ * var placeAction = cc.place(200, 200);
+ */
+cc.place = function (pos, y) {
+ return new cc.Place(pos, y);
+};
+
+/**
+ * Please use cc.place instead.
+ * Creates a Place action with a position.
+ * @static
+ * @deprecated since v3.0 Please use cc.place instead.
+ * @param {cc.Point|Number} pos
+ * @param {Number} [y]
+ * @return {cc.Place}
+ */
+cc.Place.create = cc.place;
+
+
+/**
+ * Calls a 'callback'.
+ * @class
+ * @extends cc.ActionInstant
+ * @param {function} selector
+ * @param {object|null} [selectorTarget]
+ * @param {*|null} [data] data for function, it accepts all data types.
+ * @example
+ * // example
+ * // CallFunc without data
+ * var finish = new cc.CallFunc(this.removeSprite, this);
+ *
+ * // CallFunc with data
+ * var finish = new cc.CallFunc(this.removeFromParentAndCleanup, this, true);
+ */
+cc.CallFunc = cc.ActionInstant.extend(/** @lends cc.CallFunc# */{
+ _selectorTarget:null,
+ _function:null,
+ _data:null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Creates a CallFunc action with the callback.
+ * @param {function} selector
+ * @param {object|null} [selectorTarget]
+ * @param {*|null} [data] data for function, it accepts all data types.
+ */
+ ctor:function(selector, selectorTarget, data){
+ cc.FiniteTimeAction.prototype.ctor.call(this);
+
+ this.initWithFunction(selector, selectorTarget, data);
+ },
+
+ /**
+ * Initializes the action with a function or function and its target
+ * @param {function} selector
+ * @param {object|Null} selectorTarget
+ * @param {*|Null} [data] data for function, it accepts all data types.
+ * @return {Boolean}
+ */
+ initWithFunction:function (selector, selectorTarget, data) {
+ if (selector) {
+ this._function = selector;
+ }
+ if (selectorTarget) {
+ this._selectorTarget = selectorTarget;
+ }
+ if (data !== undefined) {
+ this._data = data;
+ }
+ return true;
+ },
+
+ /**
+ * execute the function.
+ */
+ execute:function () {
+ if (this._function) {
+ this._function.call(this._selectorTarget, this.target, this._data);
+ }
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ this.execute();
+ },
+
+ /**
+ * Get selectorTarget.
+ * @return {object}
+ */
+ getTargetCallback:function () {
+ return this._selectorTarget;
+ },
+
+ /**
+ * Set selectorTarget.
+ * @param {object} sel
+ */
+ setTargetCallback:function (sel) {
+ if (sel !== this._selectorTarget) {
+ if (this._selectorTarget)
+ this._selectorTarget = null;
+ this._selectorTarget = sel;
+ }
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.CallFunc}
+ */
+ clone:function(){
+ var action = new cc.CallFunc();
+ action.initWithFunction(this._function, this._selectorTarget, this._data);
+ return action;
+ }
+});
+
+/**
+ * Creates the action with the callback
+ * @function
+ * @param {function} selector
+ * @param {object|null} [selectorTarget]
+ * @param {*|null} [data] data for function, it accepts all data types.
+ * @return {cc.CallFunc}
+ * @example
+ * // example
+ * // CallFunc without data
+ * var finish = cc.callFunc(this.removeSprite, this);
+ *
+ * // CallFunc with data
+ * var finish = cc.callFunc(this.removeFromParentAndCleanup, this._grossini, true);
+ */
+cc.callFunc = function (selector, selectorTarget, data) {
+ return new cc.CallFunc(selector, selectorTarget, data);
+};
+
+/**
+ * Please use cc.callFunc instead.
+ * Creates the action with the callback.
+ * @static
+ * @deprecated since v3.0 Please use cc.callFunc instead.
+ * @param {function} selector
+ * @param {object|null} [selectorTarget]
+ * @param {*|null} [data] data for function, it accepts all data types.
+ * @return {cc.CallFunc}
+ */
+cc.CallFunc.create = cc.callFunc;
diff --git a/frameworks/cocos2d-html5/cocos2d/actions/CCActionInterval.js b/frameworks/cocos2d-html5/cocos2d/actions/CCActionInterval.js
new file mode 100644
index 0000000..905d72b
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/actions/CCActionInterval.js
@@ -0,0 +1,3578 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * An interval action is an action that takes place within a certain period of time.
+ * It has an start time, and a finish time. The finish time is the parameter
+ * duration plus the start time.
+ *
+ * These CCActionInterval actions have some interesting properties, like:
+ * - They can run normally (default)
+ * - They can run reversed with the reverse method
+ * - They can run with the time altered with the Accelerate, AccelDeccel and Speed actions.
+ *
+ * For example, you can simulate a Ping Pong effect running the action normally and
+ * then running it again in Reverse mode.
+ *
+ * @class
+ * @extends cc.FiniteTimeAction
+ * @param {Number} d duration in seconds
+ * @example
+ * var actionInterval = new cc.ActionInterval(3);
+ */
+cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
+ _elapsed: 0,
+ _firstTick: false,
+ _easeList: null,
+ _timesForRepeat: 1,
+ _repeatForever: false,
+ _repeatMethod: false,//Compatible with repeat class, Discard after can be deleted
+ _speed: 1,
+ _speedMethod: false,//Compatible with speed class, Discard after can be deleted
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} d duration in seconds
+ */
+ ctor: function (d) {
+ this._speed = 1;
+ this._timesForRepeat = 1;
+ this._repeatForever = false;
+ this.MAX_VALUE = 2;
+ this._repeatMethod = false;//Compatible with repeat class, Discard after can be deleted
+ this._speedMethod = false;//Compatible with repeat class, Discard after can be deleted
+ cc.FiniteTimeAction.prototype.ctor.call(this);
+ d !== undefined && this.initWithDuration(d);
+ },
+
+ /**
+ * How many seconds had elapsed since the actions started to run.
+ * @return {Number}
+ */
+ getElapsed: function () {
+ return this._elapsed;
+ },
+
+ /**
+ * Initializes the action.
+ * @param {Number} d duration in seconds
+ * @return {Boolean}
+ */
+ initWithDuration: function (d) {
+ this._duration = (d === 0) ? cc.FLT_EPSILON : d;
+ // prevent division by 0
+ // This comparison could be in step:, but it might decrease the performance
+ // by 3% in heavy based action games.
+ this._elapsed = 0;
+ this._firstTick = true;
+ return true;
+ },
+
+ /**
+ * Returns true if the action has finished.
+ * @return {Boolean}
+ */
+ isDone: function () {
+ return (this._elapsed >= this._duration);
+ },
+
+ /**
+ * Some additional parameters of cloning.
+ * @param {cc.Action} action
+ * @private
+ */
+ _cloneDecoration: function (action) {
+ action._repeatForever = this._repeatForever;
+ action._speed = this._speed;
+ action._timesForRepeat = this._timesForRepeat;
+ action._easeList = this._easeList;
+ action._speedMethod = this._speedMethod;
+ action._repeatMethod = this._repeatMethod;
+ },
+
+ _reverseEaseList: function (action) {
+ if (this._easeList) {
+ action._easeList = [];
+ for (var i = 0; i < this._easeList.length; i++) {
+ action._easeList.push(this._easeList[i].reverse());
+ }
+ }
+ },
+
+ /**
+ * Returns a new clone of the action.
+ * @returns {cc.ActionInterval}
+ */
+ clone: function () {
+ var action = new cc.ActionInterval(this._duration);
+ this._cloneDecoration(action);
+ return action;
+ },
+
+ /**
+ * Implementation of ease motion.
+ *
+ * @example
+ * //example
+ * action.easing(cc.easeIn(3.0));
+ * @param {Object} easeObj
+ * @returns {cc.ActionInterval}
+ */
+ easing: function (easeObj) {
+ if (this._easeList)
+ this._easeList.length = 0;
+ else
+ this._easeList = [];
+ for (var i = 0; i < arguments.length; i++)
+ this._easeList.push(arguments[i]);
+ return this;
+ },
+
+ _computeEaseTime: function (dt) {
+ var locList = this._easeList;
+ if ((!locList) || (locList.length === 0))
+ return dt;
+ for (var i = 0, n = locList.length; i < n; i++)
+ dt = locList[i].easing(dt);
+ return dt;
+ },
+
+ /**
+ * called every frame with it's delta time.
+ * DON'T override unless you know what you are doing.
+ *
+ * @param {Number} dt
+ */
+ step: function (dt) {
+ if (this._firstTick) {
+ this._firstTick = false;
+ this._elapsed = 0;
+ } else
+ this._elapsed += dt;
+
+ //this.update((1 > (this._elapsed / this._duration)) ? this._elapsed / this._duration : 1);
+ //this.update(Math.max(0, Math.min(1, this._elapsed / Math.max(this._duration, cc.FLT_EPSILON))));
+ var t = this._elapsed / (this._duration > 0.0000001192092896 ? this._duration : 0.0000001192092896);
+ t = (1 > t ? t : 1);
+ this.update(t > 0 ? t : 0);
+
+ //Compatible with repeat class, Discard after can be deleted (this._repeatMethod)
+ if (this._repeatMethod && this._timesForRepeat > 1 && this.isDone()) {
+ if (!this._repeatForever) {
+ this._timesForRepeat--;
+ }
+ //var diff = locInnerAction.getElapsed() - locInnerAction._duration;
+ this.startWithTarget(this.target);
+ // to prevent jerk. issue #390 ,1247
+ //this._innerAction.step(0);
+ //this._innerAction.step(diff);
+ this.step(this._elapsed - this._duration);
+
+ }
+ },
+
+ /**
+ * Start this action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.Action.prototype.startWithTarget.call(this, target);
+ this._elapsed = 0;
+ this._firstTick = true;
+ },
+
+ /**
+ * returns a reversed action.
+ * Will be overwrite.
+ *
+ * @return {?cc.Action}
+ */
+ reverse: function () {
+ cc.log("cc.IntervalAction: reverse not implemented.");
+ return null;
+ },
+
+ /**
+ * Set amplitude rate.
+ * @warning It should be overridden in subclass.
+ * @param {Number} amp
+ */
+ setAmplitudeRate: function (amp) {
+ // Abstract class needs implementation
+ cc.log("cc.ActionInterval.setAmplitudeRate(): it should be overridden in subclass.");
+ },
+
+ /**
+ * Get amplitude rate.
+ * @warning It should be overridden in subclass.
+ * @return {Number} 0
+ */
+ getAmplitudeRate: function () {
+ // Abstract class needs implementation
+ cc.log("cc.ActionInterval.getAmplitudeRate(): it should be overridden in subclass.");
+ return 0;
+ },
+
+ /**
+ * Changes the speed of an action, making it take longer (speed>1)
+ * or less (speed<1) time.
+ * Useful to simulate 'slow motion' or 'fast forward' effect.
+ *
+ * @param speed
+ * @returns {cc.Action}
+ */
+ speed: function (speed) {
+ if (speed <= 0) {
+ cc.log("The speed parameter error");
+ return this;
+ }
+
+ this._speedMethod = true;//Compatible with repeat class, Discard after can be deleted
+ this._speed *= speed;
+ return this;
+ },
+
+ /**
+ * Get this action speed.
+ * @return {Number}
+ */
+ getSpeed: function () {
+ return this._speed;
+ },
+
+ /**
+ * Set this action speed.
+ * @param {Number} speed
+ * @returns {cc.ActionInterval}
+ */
+ setSpeed: function (speed) {
+ this._speed = speed;
+ return this;
+ },
+
+ /**
+ * Repeats an action a number of times.
+ * To repeat an action forever use the CCRepeatForever action.
+ * @param times
+ * @returns {cc.ActionInterval}
+ */
+ repeat: function (times) {
+ times = Math.round(times);
+ if (isNaN(times) || times < 1) {
+ cc.log("The repeat parameter error");
+ return this;
+ }
+ this._repeatMethod = true;//Compatible with repeat class, Discard after can be deleted
+ this._timesForRepeat *= times;
+ return this;
+ },
+
+ /**
+ * Repeats an action for ever.
+ * To repeat the an action for a limited number of times use the Repeat action.
+ * @returns {cc.ActionInterval}
+ */
+ repeatForever: function () {
+ this._repeatMethod = true;//Compatible with repeat class, Discard after can be deleted
+ this._timesForRepeat = this.MAX_VALUE;
+ this._repeatForever = true;
+ return this;
+ }
+});
+
+/**
+ * An interval action is an action that takes place within a certain period of time.
+ * @function
+ * @param {Number} d duration in seconds
+ * @return {cc.ActionInterval}
+ * @example
+ * // example
+ * var actionInterval = cc.actionInterval(3);
+ */
+cc.actionInterval = function (d) {
+ return new cc.ActionInterval(d);
+};
+
+/**
+ * Please use cc.actionInterval instead.
+ * An interval action is an action that takes place within a certain period of time.
+ * @static
+ * @deprecated since v3.0 Please use cc.actionInterval instead.
+ * @param {Number} d duration in seconds
+ * @return {cc.ActionInterval}
+ */
+cc.ActionInterval.create = cc.actionInterval;
+
+/**
+ * Runs actions sequentially, one after another.
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Array|cc.FiniteTimeAction} tempArray
+ * @example
+ * // create sequence with actions
+ * var seq = new cc.Sequence(act1, act2);
+ *
+ * // create sequence with array
+ * var seq = new cc.Sequence(actArray);
+ */
+cc.Sequence = cc.ActionInterval.extend(/** @lends cc.Sequence# */{
+ _actions: null,
+ _split: null,
+ _last: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Create an array of sequenceable actions.
+ * @param {Array|cc.FiniteTimeAction} tempArray
+ */
+ ctor: function (tempArray) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ this._actions = [];
+
+ var paramArray = (tempArray instanceof Array) ? tempArray : arguments;
+ var last = paramArray.length - 1;
+ if ((last >= 0) && (paramArray[last] == null))
+ cc.log("parameters should not be ending with null in Javascript");
+
+ if (last >= 0) {
+ var prev = paramArray[0], action1;
+ for (var i = 1; i < last; i++) {
+ if (paramArray[i]) {
+ action1 = prev;
+ prev = cc.Sequence._actionOneTwo(action1, paramArray[i]);
+ }
+ }
+ this.initWithTwoActions(prev, paramArray[last]);
+ }
+ },
+
+ /**
+ * Initializes the action
+ * @param {cc.FiniteTimeAction} actionOne
+ * @param {cc.FiniteTimeAction} actionTwo
+ * @return {Boolean}
+ */
+ initWithTwoActions: function (actionOne, actionTwo) {
+ if (!actionOne || !actionTwo)
+ throw new Error("cc.Sequence.initWithTwoActions(): arguments must all be non nil");
+
+ var d = actionOne._duration + actionTwo._duration;
+ this.initWithDuration(d);
+
+ this._actions[0] = actionOne;
+ this._actions[1] = actionTwo;
+ return true;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.Sequence}
+ */
+ clone: function () {
+ var action = new cc.Sequence();
+ this._cloneDecoration(action);
+ action.initWithTwoActions(this._actions[0].clone(), this._actions[1].clone());
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ this._split = this._actions[0]._duration / this._duration;
+ this._last = -1;
+ },
+
+ /**
+ * stop the action.
+ */
+ stop: function () {
+ // Issue #1305
+ if (this._last !== -1)
+ this._actions[this._last].stop();
+ cc.Action.prototype.stop.call(this);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ var new_t, found = 0;
+ var locSplit = this._split, locActions = this._actions, locLast = this._last, actionFound;
+
+ dt = this._computeEaseTime(dt);
+ if (dt < locSplit) {
+ // action[0]
+ new_t = (locSplit !== 0) ? dt / locSplit : 1;
+
+ if (found === 0 && locLast === 1) {
+ // Reverse mode ?
+ // XXX: Bug. this case doesn't contemplate when _last==-1, found=0 and in "reverse mode"
+ // since it will require a hack to know if an action is on reverse mode or not.
+ // "step" should be overriden, and the "reverseMode" value propagated to inner Sequences.
+ locActions[1].update(0);
+ locActions[1].stop();
+ }
+ } else {
+ // action[1]
+ found = 1;
+ new_t = (locSplit === 1) ? 1 : (dt - locSplit) / (1 - locSplit);
+
+ if (locLast === -1) {
+ // action[0] was skipped, execute it.
+ locActions[0].startWithTarget(this.target);
+ locActions[0].update(1);
+ locActions[0].stop();
+ }
+ if (!locLast) {
+ // switching to action 1. stop action 0.
+ locActions[0].update(1);
+ locActions[0].stop();
+ }
+ }
+
+ actionFound = locActions[found];
+ // Last action found and it is done.
+ if (locLast === found && actionFound.isDone())
+ return;
+
+ // Last action found and it is done
+ if (locLast !== found)
+ actionFound.startWithTarget(this.target);
+
+ new_t = new_t * actionFound._timesForRepeat;
+ actionFound.update(new_t > 1 ? new_t % 1 : new_t);
+ this._last = found;
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.Sequence}
+ */
+ reverse: function () {
+ var action = cc.Sequence._actionOneTwo(this._actions[1].reverse(), this._actions[0].reverse());
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ }
+});
+
+/** helper constructor to create an array of sequenceable actions
+ * @function
+ * @param {Array|cc.FiniteTimeAction} tempArray
+ * @return {cc.Sequence}
+ * @example
+ * // example
+ * // create sequence with actions
+ * var seq = cc.sequence(act1, act2);
+ *
+ * // create sequence with array
+ * var seq = cc.sequence(actArray);
+ * todo: It should be use new
+ */
+cc.sequence = function (/*Multiple Arguments*/tempArray) {
+ var paramArray = (tempArray instanceof Array) ? tempArray : arguments;
+ if ((paramArray.length > 0) && (paramArray[paramArray.length - 1] == null))
+ cc.log("parameters should not be ending with null in Javascript");
+
+ var result, current, i, repeat;
+ while (paramArray && paramArray.length > 0) {
+ current = Array.prototype.shift.call(paramArray);
+ repeat = current._timesForRepeat || 1;
+ current._repeatMethod = false;
+ current._timesForRepeat = 1;
+
+ i = 0;
+ if (!result) {
+ result = current;
+ i = 1;
+ }
+
+ for (i; i < repeat; i++) {
+ result = cc.Sequence._actionOneTwo(result, current);
+ }
+ }
+
+ return result;
+};
+
+/**
+ * Please use cc.sequence instead.
+ * helper constructor to create an array of sequenceable actions
+ * @static
+ * @deprecated since v3.0 Please use cc.sequence instead.
+ * @param {Array|cc.FiniteTimeAction} tempArray
+ * @return {cc.Sequence}
+ */
+cc.Sequence.create = cc.sequence;
+
+/** creates the action
+ * @param {cc.FiniteTimeAction} actionOne
+ * @param {cc.FiniteTimeAction} actionTwo
+ * @return {cc.Sequence}
+ * @private
+ */
+cc.Sequence._actionOneTwo = function (actionOne, actionTwo) {
+ var sequence = new cc.Sequence();
+ sequence.initWithTwoActions(actionOne, actionTwo);
+ return sequence;
+};
+
+/**
+ * Repeats an action a number of times.
+ * To repeat an action forever use the CCRepeatForever action.
+ * @class
+ * @extends cc.ActionInterval
+ * @param {cc.FiniteTimeAction} action
+ * @param {Number} times
+ * @example
+ * var rep = new cc.Repeat(cc.sequence(jump2, jump1), 5);
+ */
+cc.Repeat = cc.ActionInterval.extend(/** @lends cc.Repeat# */{
+ _times: 0,
+ _total: 0,
+ _nextDt: 0,
+ _actionInstant: false,
+ _innerAction: null, //CCFiniteTimeAction
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Creates a Repeat action. Times is an unsigned integer between 1 and pow(2,30).
+ * @param {cc.FiniteTimeAction} action
+ * @param {Number} times
+ */
+ ctor: function (action, times) {
+ cc.ActionInterval.prototype.ctor.call(this);
+
+ times !== undefined && this.initWithAction(action, times);
+ },
+
+ /**
+ * @param {cc.FiniteTimeAction} action
+ * @param {Number} times
+ * @return {Boolean}
+ */
+ initWithAction: function (action, times) {
+ var duration = action._duration * times;
+
+ if (this.initWithDuration(duration)) {
+ this._times = times;
+ this._innerAction = action;
+ if (action instanceof cc.ActionInstant) {
+ this._actionInstant = true;
+ this._times -= 1;
+ }
+ this._total = 0;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.Repeat}
+ */
+ clone: function () {
+ var action = new cc.Repeat();
+ this._cloneDecoration(action);
+ action.initWithAction(this._innerAction.clone(), this._times);
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ this._total = 0;
+ this._nextDt = this._innerAction._duration / this._duration;
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ this._innerAction.startWithTarget(target);
+ },
+
+ /**
+ * stop the action
+ */
+ stop: function () {
+ this._innerAction.stop();
+ cc.Action.prototype.stop.call(this);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+ var locInnerAction = this._innerAction;
+ var locDuration = this._duration;
+ var locTimes = this._times;
+ var locNextDt = this._nextDt;
+
+ if (dt >= locNextDt) {
+ while (dt > locNextDt && this._total < locTimes) {
+ locInnerAction.update(1);
+ this._total++;
+ locInnerAction.stop();
+ locInnerAction.startWithTarget(this.target);
+ locNextDt += locInnerAction._duration / locDuration;
+ this._nextDt = locNextDt;
+ }
+
+ // fix for issue #1288, incorrect end value of repeat
+ if (dt >= 1.0 && this._total < locTimes)
+ this._total++;
+
+ // don't set a instant action back or update it, it has no use because it has no duration
+ if (!this._actionInstant) {
+ if (this._total === locTimes) {
+ locInnerAction.update(1);
+ locInnerAction.stop();
+ } else {
+ // issue #390 prevent jerk, use right update
+ locInnerAction.update(dt - (locNextDt - locInnerAction._duration / locDuration));
+ }
+ }
+ } else {
+ locInnerAction.update((dt * locTimes) % 1.0);
+ }
+ },
+
+ /**
+ * Return true if the action has finished.
+ * @return {Boolean}
+ */
+ isDone: function () {
+ return this._total === this._times;
+ },
+
+ /**
+ * returns a reversed action.
+ * @return {cc.Repeat}
+ */
+ reverse: function () {
+ var action = new cc.Repeat(this._innerAction.reverse(), this._times);
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ },
+
+ /**
+ * Set inner Action.
+ * @param {cc.FiniteTimeAction} action
+ */
+ setInnerAction: function (action) {
+ if (this._innerAction !== action) {
+ this._innerAction = action;
+ }
+ },
+
+ /**
+ * Get inner Action.
+ * @return {cc.FiniteTimeAction}
+ */
+ getInnerAction: function () {
+ return this._innerAction;
+ }
+});
+
+/**
+ * Creates a Repeat action. Times is an unsigned integer between 1 and pow(2,30)
+ * @function
+ * @param {cc.FiniteTimeAction} action
+ * @param {Number} times
+ * @return {cc.Repeat}
+ * @example
+ * // example
+ * var rep = cc.repeat(cc.sequence(jump2, jump1), 5);
+ */
+cc.repeat = function (action, times) {
+ return new cc.Repeat(action, times);
+};
+
+/**
+ * Please use cc.repeat instead
+ * Creates a Repeat action. Times is an unsigned integer between 1 and pow(2,30)
+ * @static
+ * @deprecated since v3.0 Please use cc.repeat instead.
+ * @param {cc.FiniteTimeAction} action
+ * @param {Number} times
+ * @return {cc.Repeat}
+ */
+cc.Repeat.create = cc.repeat;
+
+
+/** Repeats an action for ever.
+ * To repeat the an action for a limited number of times use the Repeat action.
+ * @warning This action can't be Sequenceable because it is not an IntervalAction
+ * @class
+ * @extends cc.ActionInterval
+ * @param {cc.FiniteTimeAction} action
+ * @example
+ * var rep = new cc.RepeatForever(cc.sequence(jump2, jump1), 5);
+ */
+cc.RepeatForever = cc.ActionInterval.extend(/** @lends cc.RepeatForever# */{
+ _innerAction: null, //CCActionInterval
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Create a acton which repeat forever.
+ * @param {cc.FiniteTimeAction} action
+ */
+ ctor: function (action) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ this._innerAction = null;
+
+ action && this.initWithAction(action);
+ },
+
+ /**
+ * @param {cc.ActionInterval} action
+ * @return {Boolean}
+ */
+ initWithAction: function (action) {
+ if (!action)
+ throw new Error("cc.RepeatForever.initWithAction(): action must be non null");
+
+ this._innerAction = action;
+ return true;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.RepeatForever}
+ */
+ clone: function () {
+ var action = new cc.RepeatForever();
+ this._cloneDecoration(action);
+ action.initWithAction(this._innerAction.clone());
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ this._innerAction.startWithTarget(target);
+ },
+
+ /**
+ * called every frame with it's delta time.
+ * DON'T override unless you know what you are doing.
+ * @param dt delta time in seconds
+ */
+ step: function (dt) {
+ var locInnerAction = this._innerAction;
+ locInnerAction.step(dt);
+ if (locInnerAction.isDone()) {
+ //var diff = locInnerAction.getElapsed() - locInnerAction._duration;
+ locInnerAction.startWithTarget(this.target);
+ // to prevent jerk. issue #390 ,1247
+ //this._innerAction.step(0);
+ //this._innerAction.step(diff);
+ locInnerAction.step(locInnerAction.getElapsed() - locInnerAction._duration);
+ }
+ },
+
+ /**
+ * Return true if the action has finished.
+ * @return {Boolean}
+ */
+ isDone: function () {
+ return false;
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.RepeatForever}
+ */
+ reverse: function () {
+ var action = new cc.RepeatForever(this._innerAction.reverse());
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ },
+
+ /**
+ * Set inner action.
+ * @param {cc.ActionInterval} action
+ */
+ setInnerAction: function (action) {
+ if (this._innerAction !== action) {
+ this._innerAction = action;
+ }
+ },
+
+ /**
+ * Get inner action.
+ * @return {cc.ActionInterval}
+ */
+ getInnerAction: function () {
+ return this._innerAction;
+ }
+});
+
+/**
+ * Create a acton which repeat forever
+ * @function
+ * @param {cc.FiniteTimeAction} action
+ * @return {cc.RepeatForever}
+ * @example
+ * // example
+ * var repeat = cc.repeatForever(cc.rotateBy(1.0, 360));
+ */
+cc.repeatForever = function (action) {
+ return new cc.RepeatForever(action);
+};
+
+/**
+ * Please use cc.repeatForever instead
+ * Create a acton which repeat forever
+ * @static
+ * @deprecated since v3.0 Please use cc.repeatForever instead.
+ * @param {cc.FiniteTimeAction} action
+ * @return {cc.RepeatForever}
+ * @param {Array|cc.FiniteTimeAction} tempArray
+ * @example
+ * var action = new cc.Spawn(cc.jumpBy(2, cc.p(300, 0), 50, 4), cc.rotateBy(2, 720));
+ */
+cc.RepeatForever.create = cc.repeatForever;
+
+
+/** Spawn a new action immediately
+ * @class
+ * @extends cc.ActionInterval
+ */
+cc.Spawn = cc.ActionInterval.extend(/** @lends cc.Spawn# */{
+ _one: null,
+ _two: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Array|cc.FiniteTimeAction} tempArray
+ */
+ ctor: function (tempArray) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ this._one = null;
+ this._two = null;
+
+ var i, paramArray, last;
+ if (tempArray instanceof Array) {
+ paramArray = tempArray;
+ }
+ else {
+ paramArray = new Array(arguments.length);
+ for (i = 0; i < arguments.length; ++i) {
+ paramArray[i] = arguments[i];
+ }
+ }
+ last = paramArray.length - 1;
+ if ((last >= 0) && (paramArray[last] == null))
+ cc.log("parameters should not be ending with null in Javascript");
+
+ if (last >= 0) {
+ var prev = paramArray[0], action1;
+ for (i = 1; i < last; i++) {
+ if (paramArray[i]) {
+ action1 = prev;
+ prev = cc.Spawn._actionOneTwo(action1, paramArray[i]);
+ }
+ }
+ this.initWithTwoActions(prev, paramArray[last]);
+ }
+ },
+
+ /** initializes the Spawn action with the 2 actions to spawn
+ * @param {cc.FiniteTimeAction} action1
+ * @param {cc.FiniteTimeAction} action2
+ * @return {Boolean}
+ */
+ initWithTwoActions: function (action1, action2) {
+ if (!action1 || !action2)
+ throw new Error("cc.Spawn.initWithTwoActions(): arguments must all be non null");
+
+ var ret = false;
+
+ var d1 = action1._duration;
+ var d2 = action2._duration;
+
+ if (this.initWithDuration(Math.max(d1, d2))) {
+ this._one = action1;
+ this._two = action2;
+
+ if (d1 > d2) {
+ this._two = cc.Sequence._actionOneTwo(action2, cc.delayTime(d1 - d2));
+ } else if (d1 < d2) {
+ this._one = cc.Sequence._actionOneTwo(action1, cc.delayTime(d2 - d1));
+ }
+
+ ret = true;
+ }
+ return ret;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.Spawn}
+ */
+ clone: function () {
+ var action = new cc.Spawn();
+ this._cloneDecoration(action);
+ action.initWithTwoActions(this._one.clone(), this._two.clone());
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ this._one.startWithTarget(target);
+ this._two.startWithTarget(target);
+ },
+
+ /**
+ * Stop the action
+ */
+ stop: function () {
+ this._one.stop();
+ this._two.stop();
+ cc.Action.prototype.stop.call(this);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+ if (this._one)
+ this._one.update(dt);
+ if (this._two)
+ this._two.update(dt);
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.Spawn}
+ */
+ reverse: function () {
+ var action = cc.Spawn._actionOneTwo(this._one.reverse(), this._two.reverse());
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ }
+});
+
+/**
+ * Create a spawn action which runs several actions in parallel.
+ * @function
+ * @param {Array|cc.FiniteTimeAction}tempArray
+ * @return {cc.Spawn}
+ * @example
+ * // example
+ * var action = cc.spawn(cc.jumpBy(2, cc.p(300, 0), 50, 4), cc.rotateBy(2, 720));
+ * todo:It should be the direct use new
+ */
+cc.spawn = function (/*Multiple Arguments*/tempArray) {
+ var paramArray = (tempArray instanceof Array) ? tempArray : arguments;
+ if ((paramArray.length > 0) && (paramArray[paramArray.length - 1] == null))
+ cc.log("parameters should not be ending with null in Javascript");
+
+ var prev = paramArray[0];
+ for (var i = 1; i < paramArray.length; i++) {
+ if (paramArray[i] != null)
+ prev = cc.Spawn._actionOneTwo(prev, paramArray[i]);
+ }
+ return prev;
+};
+
+/**
+ * Please use cc.spawn instead.
+ * Create a spawn action which runs several actions in parallel.
+ * @static
+ * @deprecated since v3.0 Please use cc.spawn instead.
+ * @param {Array|cc.FiniteTimeAction}tempArray
+ * @return {cc.Spawn}
+ */
+cc.Spawn.create = cc.spawn;
+
+/**
+ * @param {cc.FiniteTimeAction} action1
+ * @param {cc.FiniteTimeAction} action2
+ * @return {cc.Spawn}
+ * @private
+ */
+cc.Spawn._actionOneTwo = function (action1, action2) {
+ var pSpawn = new cc.Spawn();
+ pSpawn.initWithTwoActions(action1, action2);
+ return pSpawn;
+};
+
+
+/**
+ * Rotates a cc.Node object to a certain angle by modifying it's.
+ * rotation attribute.
+ * The direction will be decided by the shortest angle.
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaAngleX deltaAngleX in degrees.
+ * @param {Number} [deltaAngleY] deltaAngleY in degrees.
+ * @example
+ * var rotateTo = new cc.RotateTo(2, 61.0);
+ */
+cc.RotateTo = cc.ActionInterval.extend(/** @lends cc.RotateTo# */{
+ _dstAngleX: 0,
+ _startAngleX: 0,
+ _diffAngleX: 0,
+
+ _dstAngleY: 0,
+ _startAngleY: 0,
+ _diffAngleY: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Creates a RotateTo action with x and y rotation angles.
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaAngleX deltaAngleX in degrees.
+ * @param {Number} [deltaAngleY] deltaAngleY in degrees.
+ */
+ ctor: function (duration, deltaAngleX, deltaAngleY) {
+ cc.ActionInterval.prototype.ctor.call(this);
+
+ deltaAngleX !== undefined && this.initWithDuration(duration, deltaAngleX, deltaAngleY);
+ },
+
+ /**
+ * Initializes the action.
+ * @param {Number} duration
+ * @param {Number} deltaAngleX
+ * @param {Number} deltaAngleY
+ * @return {Boolean}
+ */
+ initWithDuration: function (duration, deltaAngleX, deltaAngleY) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ this._dstAngleX = deltaAngleX || 0;
+ this._dstAngleY = deltaAngleY !== undefined ? deltaAngleY : this._dstAngleX;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.RotateTo}
+ */
+ clone: function () {
+ var action = new cc.RotateTo();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._dstAngleX, this._dstAngleY);
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+
+ // Calculate X
+ var locStartAngleX = target.rotationX % 360.0;
+ var locDiffAngleX = this._dstAngleX - locStartAngleX;
+ if (locDiffAngleX > 180)
+ locDiffAngleX -= 360;
+ if (locDiffAngleX < -180)
+ locDiffAngleX += 360;
+ this._startAngleX = locStartAngleX;
+ this._diffAngleX = locDiffAngleX;
+
+ // Calculate Y It's duplicated from calculating X since the rotation wrap should be the same
+ this._startAngleY = target.rotationY % 360.0;
+ var locDiffAngleY = this._dstAngleY - this._startAngleY;
+ if (locDiffAngleY > 180)
+ locDiffAngleY -= 360;
+ if (locDiffAngleY < -180)
+ locDiffAngleY += 360;
+ this._diffAngleY = locDiffAngleY;
+ },
+
+ /**
+ * RotateTo reverse not implemented.
+ * Will be overridden.
+ * @returns {cc.Action}
+ */
+ reverse: function () {
+ cc.log("cc.RotateTo.reverse(): it should be overridden in subclass.");
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+ if (this.target) {
+ this.target.rotationX = this._startAngleX + this._diffAngleX * dt;
+ this.target.rotationY = this._startAngleY + this._diffAngleY * dt;
+ }
+ }
+});
+
+/**
+ * Creates a RotateTo action with separate rotation angles.
+ * To specify the angle of rotation.
+ * @function
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaAngleX deltaAngleX in degrees.
+ * @param {Number} [deltaAngleY] deltaAngleY in degrees.
+ * @return {cc.RotateTo}
+ * @example
+ * // example
+ * var rotateTo = cc.rotateTo(2, 61.0);
+ */
+cc.rotateTo = function (duration, deltaAngleX, deltaAngleY) {
+ return new cc.RotateTo(duration, deltaAngleX, deltaAngleY);
+};
+
+/**
+ * Please use cc.rotateTo instead
+ * Creates a RotateTo action with separate rotation angles.
+ * To specify the angle of rotation.
+ * @static
+ * @deprecated since v3.0 Please use cc.rotateTo instead.
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaAngleX deltaAngleX in degrees.
+ * @param {Number} [deltaAngleY] deltaAngleY in degrees.
+ * @return {cc.RotateTo}
+ */
+cc.RotateTo.create = cc.rotateTo;
+
+
+/**
+ * Rotates a cc.Node object clockwise a number of degrees by modifying it's rotation attribute.
+ * Relative to its properties to modify.
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaAngleX deltaAngleX in degrees
+ * @param {Number} [deltaAngleY] deltaAngleY in degrees
+ * @example
+ * var actionBy = new cc.RotateBy(2, 360);
+ */
+cc.RotateBy = cc.ActionInterval.extend(/** @lends cc.RotateBy# */{
+ _angleX: 0,
+ _startAngleX: 0,
+ _angleY: 0,
+ _startAngleY: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaAngleX deltaAngleX in degrees
+ * @param {Number} [deltaAngleY] deltaAngleY in degrees
+ */
+ ctor: function (duration, deltaAngleX, deltaAngleY) {
+ cc.ActionInterval.prototype.ctor.call(this);
+
+ deltaAngleX !== undefined && this.initWithDuration(duration, deltaAngleX, deltaAngleY);
+ },
+
+ /**
+ * Initializes the action.
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaAngleX deltaAngleX in degrees
+ * @param {Number} [deltaAngleY=] deltaAngleY in degrees
+ * @return {Boolean}
+ */
+ initWithDuration: function (duration, deltaAngleX, deltaAngleY) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ this._angleX = deltaAngleX || 0;
+ this._angleY = deltaAngleY || this._angleX;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.RotateBy}
+ */
+ clone: function () {
+ var action = new cc.RotateBy();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._angleX, this._angleY);
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ this._startAngleX = target.rotationX;
+ this._startAngleY = target.rotationY;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+ if (this.target) {
+ this.target.rotationX = this._startAngleX + this._angleX * dt;
+ this.target.rotationY = this._startAngleY + this._angleY * dt;
+ }
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.RotateBy}
+ */
+ reverse: function () {
+ var action = new cc.RotateBy(this._duration, -this._angleX, -this._angleY);
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ }
+});
+
+/**
+ * Rotates a cc.Node object clockwise a number of degrees by modifying it's rotation attribute.
+ * Relative to its properties to modify.
+ * @function
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaAngleX deltaAngleX in degrees
+ * @param {Number} [deltaAngleY] deltaAngleY in degrees
+ * @return {cc.RotateBy}
+ * @example
+ * // example
+ * var actionBy = cc.rotateBy(2, 360);
+ */
+cc.rotateBy = function (duration, deltaAngleX, deltaAngleY) {
+ return new cc.RotateBy(duration, deltaAngleX, deltaAngleY);
+};
+/**
+ * Please use cc.rotateBy instead.
+ * Rotates a cc.Node object clockwise a number of degrees by modifying it's rotation attribute.
+ * Relative to its properties to modify.
+ * @static
+ * @deprecated since v3.0 Please use cc.rotateBy instead.
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaAngleX deltaAngleX in degrees
+ * @param {Number} [deltaAngleY] deltaAngleY in degrees
+ * @return {cc.RotateBy}
+ */
+cc.RotateBy.create = cc.rotateBy;
+
+
+/**
+ *
+ * Moves a CCNode object x,y pixels by modifying it's position attribute.
+ * x and y are relative to the position of the object.
+ * Several CCMoveBy actions can be concurrently called, and the resulting
+ * movement will be the sum of individual movements.
+ *
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} duration duration in seconds
+ * @param {cc.Point|Number} deltaPos
+ * @param {Number} [deltaY]
+ * @example
+ * var actionBy = cc.moveBy(2, cc.p(windowSize.width - 40, windowSize.height - 40));
+ */
+cc.MoveBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{
+ _positionDelta: null,
+ _startPosition: null,
+ _previousPosition: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} duration duration in seconds
+ * @param {cc.Point|Number} deltaPos
+ * @param {Number} [deltaY]
+ */
+ ctor: function (duration, deltaPos, deltaY) {
+ cc.ActionInterval.prototype.ctor.call(this);
+
+ this._positionDelta = cc.p(0, 0);
+ this._startPosition = cc.p(0, 0);
+ this._previousPosition = cc.p(0, 0);
+
+ deltaPos !== undefined && this.initWithDuration(duration, deltaPos, deltaY);
+ },
+
+ /**
+ * Initializes the action.
+ * @param {Number} duration duration in seconds
+ * @param {cc.Point} position
+ * @param {Number} [y]
+ * @return {Boolean}
+ */
+ initWithDuration: function (duration, position, y) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ if (position.x !== undefined) {
+ y = position.y;
+ position = position.x;
+ }
+
+ this._positionDelta.x = position;
+ this._positionDelta.y = y;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.MoveBy}
+ */
+ clone: function () {
+ var action = new cc.MoveBy();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._positionDelta);
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ var locPosX = target.getPositionX();
+ var locPosY = target.getPositionY();
+ this._previousPosition.x = locPosX;
+ this._previousPosition.y = locPosY;
+ this._startPosition.x = locPosX;
+ this._startPosition.y = locPosY;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+ if (this.target) {
+ var x = this._positionDelta.x * dt;
+ var y = this._positionDelta.y * dt;
+ var locStartPosition = this._startPosition;
+ if (cc.ENABLE_STACKABLE_ACTIONS) {
+ var targetX = this.target.getPositionX();
+ var targetY = this.target.getPositionY();
+ var locPreviousPosition = this._previousPosition;
+
+ locStartPosition.x = locStartPosition.x + targetX - locPreviousPosition.x;
+ locStartPosition.y = locStartPosition.y + targetY - locPreviousPosition.y;
+ x = x + locStartPosition.x;
+ y = y + locStartPosition.y;
+ locPreviousPosition.x = x;
+ locPreviousPosition.y = y;
+ this.target.setPosition(x, y);
+ } else {
+ this.target.setPosition(locStartPosition.x + x, locStartPosition.y + y);
+ }
+ }
+ },
+
+ /**
+ * MoveTo reverse is not implemented
+ * @return {cc.MoveBy}
+ */
+ reverse: function () {
+ var action = new cc.MoveBy(this._duration, cc.p(-this._positionDelta.x, -this._positionDelta.y));
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ }
+});
+
+/**
+ * Create the action.
+ * Relative to its coordinate moves a certain distance.
+ * @function
+ * @param {Number} duration duration in seconds
+ * @param {cc.Point|Number} deltaPos
+ * @param {Number} deltaY
+ * @return {cc.MoveBy}
+ * @example
+ * // example
+ * var actionBy = cc.moveBy(2, cc.p(windowSize.width - 40, windowSize.height - 40));
+ */
+cc.moveBy = function (duration, deltaPos, deltaY) {
+ return new cc.MoveBy(duration, deltaPos, deltaY);
+};
+/**
+ * Please use cc.moveBy instead.
+ * Relative to its coordinate moves a certain distance.
+ * @static
+ * @deprecated since v3.0 please use cc.moveBy instead.
+ * @param {Number} duration duration in seconds
+ * @param {cc.Point|Number} deltaPos
+ * @param {Number} deltaY
+ * @return {cc.MoveBy}
+ */
+cc.MoveBy.create = cc.moveBy;
+
+
+/**
+ * Moves a CCNode object to the position x,y. x and y are absolute coordinates by modifying it's position attribute.
+ * Several CCMoveTo actions can be concurrently called, and the resulting
+ * movement will be the sum of individual movements.
+ * @class
+ * @extends cc.MoveBy
+ * @param {Number} duration duration in seconds
+ * @param {cc.Point|Number} position
+ * @param {Number} y
+ * @example
+ * var actionTo = new cc.MoveTo(2, cc.p(80, 80));
+ */
+cc.MoveTo = cc.MoveBy.extend(/** @lends cc.MoveTo# */{
+ _endPosition: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} duration duration in seconds
+ * @param {cc.Point|Number} position
+ * @param {Number} y
+ */
+ ctor: function (duration, position, y) {
+ cc.MoveBy.prototype.ctor.call(this);
+ this._endPosition = cc.p(0, 0);
+
+ position !== undefined && this.initWithDuration(duration, position, y);
+ },
+
+ /**
+ * Initializes the action.
+ * @param {Number} duration duration in seconds
+ * @param {cc.Point} position
+ * @param {Number} y
+ * @return {Boolean}
+ */
+ initWithDuration: function (duration, position, y) {
+ if (cc.MoveBy.prototype.initWithDuration.call(this, duration, position, y)) {
+ if (position.x !== undefined) {
+ y = position.y;
+ position = position.x;
+ }
+
+ this._endPosition.x = position;
+ this._endPosition.y = y;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.MoveTo}
+ */
+ clone: function () {
+ var action = new cc.MoveTo();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._endPosition);
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.MoveBy.prototype.startWithTarget.call(this, target);
+ this._positionDelta.x = this._endPosition.x - target.getPositionX();
+ this._positionDelta.y = this._endPosition.y - target.getPositionY();
+ }
+});
+
+/**
+ * Create new action.
+ * Moving to the specified coordinates.
+ * @function
+ * @param {Number} duration duration in seconds
+ * @param {cc.Point|Number} position
+ * @param {Number} y
+ * @return {cc.MoveTo}
+ * @example
+ * // example
+ * var actionTo = cc.moveTo(2, cc.p(80, 80));
+ */
+cc.moveTo = function (duration, position, y) {
+ return new cc.MoveTo(duration, position, y);
+};
+/**
+ * Please use cc.moveTo instead.
+ * Moving to the specified coordinates.
+ * @static
+ * @deprecated since v3.0 Please use cc.moveTo instead.
+ * @param {Number} duration duration in seconds
+ * @param {cc.Point|Number} position
+ * @param {Number} y
+ * @return {cc.MoveTo}
+ */
+cc.MoveTo.create = cc.moveTo;
+
+/**
+ * Skews a cc.Node object to given angles by modifying it's skewX and skewY attributes
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} t time in seconds
+ * @param {Number} sx
+ * @param {Number} sy
+ * @example
+ * var actionTo = new cc.SkewTo(2, 37.2, -37.2);
+ */
+cc.SkewTo = cc.ActionInterval.extend(/** @lends cc.SkewTo# */{
+ _skewX: 0,
+ _skewY: 0,
+ _startSkewX: 0,
+ _startSkewY: 0,
+ _endSkewX: 0,
+ _endSkewY: 0,
+ _deltaX: 0,
+ _deltaY: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} t time in seconds
+ * @param {Number} sx
+ * @param {Number} sy
+ */
+ ctor: function (t, sx, sy) {
+ cc.ActionInterval.prototype.ctor.call(this);
+
+ sy !== undefined && this.initWithDuration(t, sx, sy);
+ },
+
+ /**
+ * Initializes the action.
+ * @param {Number} t time in seconds
+ * @param {Number} sx
+ * @param {Number} sy
+ * @return {Boolean}
+ */
+ initWithDuration: function (t, sx, sy) {
+ var ret = false;
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, t)) {
+ this._endSkewX = sx;
+ this._endSkewY = sy;
+ ret = true;
+ }
+ return ret;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.SkewTo}
+ */
+ clone: function () {
+ var action = new cc.SkewTo();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._endSkewX, this._endSkewY);
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+
+ this._startSkewX = target.skewX % 180;
+ this._deltaX = this._endSkewX - this._startSkewX;
+ if (this._deltaX > 180)
+ this._deltaX -= 360;
+ if (this._deltaX < -180)
+ this._deltaX += 360;
+
+ this._startSkewY = target.skewY % 360;
+ this._deltaY = this._endSkewY - this._startSkewY;
+ if (this._deltaY > 180)
+ this._deltaY -= 360;
+ if (this._deltaY < -180)
+ this._deltaY += 360;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+ this.target.skewX = this._startSkewX + this._deltaX * dt;
+ this.target.skewY = this._startSkewY + this._deltaY * dt;
+ }
+});
+/**
+ * Create new action.
+ * Skews a cc.Node object to given angles by modifying it's skewX and skewY attributes.
+ * Changes to the specified value.
+ * @function
+ * @param {Number} t time in seconds
+ * @param {Number} sx
+ * @param {Number} sy
+ * @return {cc.SkewTo}
+ * @example
+ * // example
+ * var actionTo = cc.skewTo(2, 37.2, -37.2);
+ */
+cc.skewTo = function (t, sx, sy) {
+ return new cc.SkewTo(t, sx, sy);
+};
+/**
+ * Please use cc.skewTo instead.
+ * Skews a cc.Node object to given angles by modifying it's skewX and skewY attributes。
+ * Changes to the specified value.
+ * @static
+ * @deprecated since v3.0 Please use cc.skewTo instead.
+ * @param {Number} t time in seconds
+ * @param {Number} sx
+ * @param {Number} sy
+ * @return {cc.SkewTo}
+ */
+cc.SkewTo.create = cc.skewTo;
+
+/**
+ * Skews a cc.Node object by skewX and skewY degrees.
+ * Relative to its attribute modification.
+ * @class
+ * @extends cc.SkewTo
+ * @param {Number} t time in seconds
+ * @param {Number} sx skew in degrees for X axis
+ * @param {Number} sy skew in degrees for Y axis
+ */
+cc.SkewBy = cc.SkewTo.extend(/** @lends cc.SkewBy# */{
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} t time in seconds
+ * @param {Number} sx skew in degrees for X axis
+ * @param {Number} sy skew in degrees for Y axis
+ */
+ ctor: function (t, sx, sy) {
+ cc.SkewTo.prototype.ctor.call(this);
+ sy !== undefined && this.initWithDuration(t, sx, sy);
+ },
+
+ /**
+ * Initializes the action.
+ * @param {Number} t time in seconds
+ * @param {Number} deltaSkewX skew in degrees for X axis
+ * @param {Number} deltaSkewY skew in degrees for Y axis
+ * @return {Boolean}
+ */
+ initWithDuration: function (t, deltaSkewX, deltaSkewY) {
+ var ret = false;
+ if (cc.SkewTo.prototype.initWithDuration.call(this, t, deltaSkewX, deltaSkewY)) {
+ this._skewX = deltaSkewX;
+ this._skewY = deltaSkewY;
+ ret = true;
+ }
+ return ret;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.SkewBy}
+ */
+ clone: function () {
+ var action = new cc.SkewBy();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._skewX, this._skewY);
+ return action;
+ },
+
+ /**
+ * Start the action width target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.SkewTo.prototype.startWithTarget.call(this, target);
+ this._deltaX = this._skewX;
+ this._deltaY = this._skewY;
+ this._endSkewX = this._startSkewX + this._deltaX;
+ this._endSkewY = this._startSkewY + this._deltaY;
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.SkewBy}
+ */
+ reverse: function () {
+ var action = new cc.SkewBy(this._duration, -this._skewX, -this._skewY);
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ }
+});
+
+/**
+ * Skews a cc.Node object by skewX and skewY degrees.
+ * Relative to its attribute modification.
+ * @function
+ * @param {Number} t time in seconds
+ * @param {Number} sx sx skew in degrees for X axis
+ * @param {Number} sy sy skew in degrees for Y axis
+ * @return {cc.SkewBy}
+ * @example
+ * // example
+ * var actionBy = cc.skewBy(2, 0, -90);
+ */
+cc.skewBy = function (t, sx, sy) {
+ return new cc.SkewBy(t, sx, sy);
+};
+/**
+ * Please use cc.skewBy instead.
+ * Skews a cc.Node object by skewX and skewY degrees.
+ * Relative to its attribute modification.
+ * @static
+ * @deprecated since v3.0 please use cc.skewBy instead.
+ * @param {Number} t time in seconds
+ * @param {Number} sx sx skew in degrees for X axis
+ * @param {Number} sy sy skew in degrees for Y axis
+ * @return {cc.SkewBy}
+ */
+cc.SkewBy.create = cc.skewBy;
+
+
+/**
+ * Moves a cc.Node object simulating a parabolic jump movement by modifying it's position attribute.
+ * Relative to its movement.
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} duration
+ * @param {cc.Point|Number} position
+ * @param {Number} [y]
+ * @param {Number} height
+ * @param {Number} jumps
+ * @example
+ * var actionBy = new cc.JumpBy(2, cc.p(300, 0), 50, 4);
+ * var actionBy = new cc.JumpBy(2, 300, 0, 50, 4);
+ */
+cc.JumpBy = cc.ActionInterval.extend(/** @lends cc.JumpBy# */{
+ _startPosition: null,
+ _delta: null,
+ _height: 0,
+ _jumps: 0,
+ _previousPosition: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} duration
+ * @param {cc.Point|Number} position
+ * @param {Number} [y]
+ * @param {Number} height
+ * @param {Number} jumps
+ */
+ ctor: function (duration, position, y, height, jumps) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ this._startPosition = cc.p(0, 0);
+ this._previousPosition = cc.p(0, 0);
+ this._delta = cc.p(0, 0);
+
+ height !== undefined && this.initWithDuration(duration, position, y, height, jumps);
+ },
+ /**
+ * Initializes the action.
+ * @param {Number} duration
+ * @param {cc.Point|Number} position
+ * @param {Number} [y]
+ * @param {Number} height
+ * @param {Number} jumps
+ * @return {Boolean}
+ * @example
+ * actionBy.initWithDuration(2, cc.p(300, 0), 50, 4);
+ * actionBy.initWithDuration(2, 300, 0, 50, 4);
+ */
+ initWithDuration: function (duration, position, y, height, jumps) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ if (jumps === undefined) {
+ jumps = height;
+ height = y;
+ y = position.y;
+ position = position.x;
+ }
+ this._delta.x = position;
+ this._delta.y = y;
+ this._height = height;
+ this._jumps = jumps;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.JumpBy}
+ */
+ clone: function () {
+ var action = new cc.JumpBy();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._delta, this._height, this._jumps);
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ var locPosX = target.getPositionX();
+ var locPosY = target.getPositionY();
+ this._previousPosition.x = locPosX;
+ this._previousPosition.y = locPosY;
+ this._startPosition.x = locPosX;
+ this._startPosition.y = locPosY;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+ if (this.target) {
+ var frac = dt * this._jumps % 1.0;
+ var y = this._height * 4 * frac * (1 - frac);
+ y += this._delta.y * dt;
+
+ var x = this._delta.x * dt;
+ var locStartPosition = this._startPosition;
+ if (cc.ENABLE_STACKABLE_ACTIONS) {
+ var targetX = this.target.getPositionX();
+ var targetY = this.target.getPositionY();
+ var locPreviousPosition = this._previousPosition;
+
+ locStartPosition.x = locStartPosition.x + targetX - locPreviousPosition.x;
+ locStartPosition.y = locStartPosition.y + targetY - locPreviousPosition.y;
+ x = x + locStartPosition.x;
+ y = y + locStartPosition.y;
+ locPreviousPosition.x = x;
+ locPreviousPosition.y = y;
+ this.target.setPosition(x, y);
+ } else {
+ this.target.setPosition(locStartPosition.x + x, locStartPosition.y + y);
+ }
+ }
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.JumpBy}
+ */
+ reverse: function () {
+ var action = new cc.JumpBy(this._duration, cc.p(-this._delta.x, -this._delta.y), this._height, this._jumps);
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ }
+});
+
+/**
+ * Moves a cc.Node object simulating a parabolic jump movement by modifying it's position attribute.
+ * Relative to its movement.
+ * @function
+ * @param {Number} duration
+ * @param {cc.Point|Number} position
+ * @param {Number} [y]
+ * @param {Number} height
+ * @param {Number} jumps
+ * @return {cc.JumpBy}
+ * @example
+ * // example
+ * var actionBy = cc.jumpBy(2, cc.p(300, 0), 50, 4);
+ * var actionBy = cc.jumpBy(2, 300, 0, 50, 4);
+ */
+cc.jumpBy = function (duration, position, y, height, jumps) {
+ return new cc.JumpBy(duration, position, y, height, jumps);
+};
+/**
+ * Please use cc.jumpBy instead.
+ * Moves a cc.Node object simulating a parabolic jump movement by modifying it's position attribute.
+ * Relative to its movement.
+ * @static
+ * @deprecated since v3.0 please use cc.jumpBy instead.
+ * @param {Number} duration
+ * @param {cc.Point|Number} position
+ * @param {Number} [y]
+ * @param {Number} height
+ * @param {Number} jumps
+ * @return {cc.JumpBy}
+ */
+cc.JumpBy.create = cc.jumpBy;
+
+/**
+ * Moves a cc.Node object to a parabolic position simulating a jump movement by modifying it's position attribute.
+ * Jump to the specified location.
+ * @class
+ * @extends cc.JumpBy
+ * @param {Number} duration
+ * @param {cc.Point|Number} position
+ * @param {Number} [y]
+ * @param {Number} height
+ * @param {Number} jumps
+ * @example
+ * var actionTo = new cc.JumpTo(2, cc.p(300, 0), 50, 4);
+ * var actionTo = new cc.JumpTo(2, 300, 0, 50, 4);
+ */
+cc.JumpTo = cc.JumpBy.extend(/** @lends cc.JumpTo# */{
+ _endPosition: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} duration
+ * @param {cc.Point|Number} position
+ * @param {Number} [y]
+ * @param {Number} height
+ * @param {Number} jumps
+ */
+ ctor: function (duration, position, y, height, jumps) {
+ cc.JumpBy.prototype.ctor.call(this);
+ this._endPosition = cc.p(0, 0);
+
+ height !== undefined && this.initWithDuration(duration, position, y, height, jumps);
+ },
+ /**
+ * Initializes the action.
+ * @param {Number} duration
+ * @param {cc.Point|Number} position
+ * @param {Number} [y]
+ * @param {Number} height
+ * @param {Number} jumps
+ * @return {Boolean}
+ * @example
+ * actionTo.initWithDuration(2, cc.p(300, 0), 50, 4);
+ * actionTo.initWithDuration(2, 300, 0, 50, 4);
+ */
+ initWithDuration: function (duration, position, y, height, jumps) {
+ if (cc.JumpBy.prototype.initWithDuration.call(this, duration, position, y, height, jumps)) {
+ if (jumps === undefined) {
+ y = position.y;
+ position = position.x;
+ }
+ this._endPosition.x = position;
+ this._endPosition.y = y;
+ return true;
+ }
+ return false;
+ },
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.JumpBy.prototype.startWithTarget.call(this, target);
+ this._delta.x = this._endPosition.x - this._startPosition.x;
+ this._delta.y = this._endPosition.y - this._startPosition.y;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.JumpTo}
+ */
+ clone: function () {
+ var action = new cc.JumpTo();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._endPosition, this._height, this._jumps);
+ return action;
+ }
+});
+
+/**
+ * Moves a cc.Node object to a parabolic position simulating a jump movement by modifying it's position attribute.
+ * Jump to the specified location.
+ * @function
+ * @param {Number} duration
+ * @param {cc.Point|Number} position
+ * @param {Number} [y]
+ * @param {Number} height
+ * @param {Number} jumps
+ * @return {cc.JumpTo}
+ * @example
+ * // example
+ * var actionTo = cc.jumpTo(2, cc.p(300, 300), 50, 4);
+ * var actionTo = cc.jumpTo(2, 300, 300, 50, 4);
+ */
+cc.jumpTo = function (duration, position, y, height, jumps) {
+ return new cc.JumpTo(duration, position, y, height, jumps);
+};
+/**
+ * Please use cc.jumpTo instead.
+ * Moves a cc.Node object to a parabolic position simulating a jump movement by modifying it's position attribute.
+ * Jump to the specified location.
+ * @static
+ * @deprecated since v3.0 please use cc.jumpTo instead.
+ * @param {Number} duration
+ * @param {cc.Point|Number} position
+ * @param {Number} [y]
+ * @param {Number} height
+ * @param {Number} jumps
+ * @return {cc.JumpTo}
+ */
+cc.JumpTo.create = cc.jumpTo;
+
+/**
+ * @function
+ * @param {Number} a
+ * @param {Number} b
+ * @param {Number} c
+ * @param {Number} d
+ * @param {Number} t
+ * @return {Number}
+ */
+cc.bezierAt = function (a, b, c, d, t) {
+ return (Math.pow(1 - t, 3) * a +
+ 3 * t * (Math.pow(1 - t, 2)) * b +
+ 3 * Math.pow(t, 2) * (1 - t) * c +
+ Math.pow(t, 3) * d );
+};
+
+/** An action that moves the target with a cubic Bezier curve by a certain distance.
+ * Relative to its movement.
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} t time in seconds
+ * @param {Array} c Array of points
+ * @example
+ * var bezier = [cc.p(0, windowSize.height / 2), cc.p(300, -windowSize.height / 2), cc.p(300, 100)];
+ * var bezierForward = new cc.BezierBy(3, bezier);
+ */
+cc.BezierBy = cc.ActionInterval.extend(/** @lends cc.BezierBy# */{
+ _config: null,
+ _startPosition: null,
+ _previousPosition: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} t time in seconds
+ * @param {Array} c Array of points
+ */
+ ctor: function (t, c) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ this._config = [];
+ this._startPosition = cc.p(0, 0);
+ this._previousPosition = cc.p(0, 0);
+
+ c && this.initWithDuration(t, c);
+ },
+
+ /**
+ * Initializes the action.
+ * @param {Number} t time in seconds
+ * @param {Array} c Array of points
+ * @return {Boolean}
+ */
+ initWithDuration: function (t, c) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, t)) {
+ this._config = c;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.BezierBy}
+ */
+ clone: function () {
+ var action = new cc.BezierBy();
+ this._cloneDecoration(action);
+ var newConfigs = [];
+ for (var i = 0; i < this._config.length; i++) {
+ var selConf = this._config[i];
+ newConfigs.push(cc.p(selConf.x, selConf.y));
+ }
+ action.initWithDuration(this._duration, newConfigs);
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ var locPosX = target.getPositionX();
+ var locPosY = target.getPositionY();
+ this._previousPosition.x = locPosX;
+ this._previousPosition.y = locPosY;
+ this._startPosition.x = locPosX;
+ this._startPosition.y = locPosY;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+ if (this.target) {
+ var locConfig = this._config;
+ var xa = 0;
+ var xb = locConfig[0].x;
+ var xc = locConfig[1].x;
+ var xd = locConfig[2].x;
+
+ var ya = 0;
+ var yb = locConfig[0].y;
+ var yc = locConfig[1].y;
+ var yd = locConfig[2].y;
+
+ var x = cc.bezierAt(xa, xb, xc, xd, dt);
+ var y = cc.bezierAt(ya, yb, yc, yd, dt);
+
+ var locStartPosition = this._startPosition;
+ if (cc.ENABLE_STACKABLE_ACTIONS) {
+ var targetX = this.target.getPositionX();
+ var targetY = this.target.getPositionY();
+ var locPreviousPosition = this._previousPosition;
+
+ locStartPosition.x = locStartPosition.x + targetX - locPreviousPosition.x;
+ locStartPosition.y = locStartPosition.y + targetY - locPreviousPosition.y;
+ x = x + locStartPosition.x;
+ y = y + locStartPosition.y;
+ locPreviousPosition.x = x;
+ locPreviousPosition.y = y;
+ this.target.setPosition(x, y);
+ } else {
+ this.target.setPosition(locStartPosition.x + x, locStartPosition.y + y);
+ }
+ }
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.BezierBy}
+ */
+ reverse: function () {
+ var locConfig = this._config;
+ var r = [
+ cc.pAdd(locConfig[1], cc.pNeg(locConfig[2])),
+ cc.pAdd(locConfig[0], cc.pNeg(locConfig[2])),
+ cc.pNeg(locConfig[2])];
+ var action = new cc.BezierBy(this._duration, r);
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ }
+});
+
+/**
+ * An action that moves the target with a cubic Bezier curve by a certain distance.
+ * Relative to its movement.
+ * @function
+ * @param {Number} t time in seconds
+ * @param {Array} c Array of points
+ * @return {cc.BezierBy}
+ * @example
+ * // example
+ * var bezier = [cc.p(0, windowSize.height / 2), cc.p(300, -windowSize.height / 2), cc.p(300, 100)];
+ * var bezierForward = cc.bezierBy(3, bezier);
+ */
+cc.bezierBy = function (t, c) {
+ return new cc.BezierBy(t, c);
+};
+/**
+ * Please use cc.bezierBy instead.
+ * An action that moves the target with a cubic Bezier curve by a certain distance.
+ * Relative to its movement.
+ * @static
+ * @deprecated since v3.0 please use cc.bezierBy instead.
+ * @param {Number} t time in seconds
+ * @param {Array} c Array of points
+ * @return {cc.BezierBy}
+ */
+cc.BezierBy.create = cc.bezierBy;
+
+
+/** An action that moves the target with a cubic Bezier curve to a destination point.
+ * @class
+ * @extends cc.BezierBy
+ * @param {Number} t
+ * @param {Array} c array of points
+ * @example
+ * var bezier = [cc.p(0, windowSize.height / 2), cc.p(300, -windowSize.height / 2), cc.p(300, 100)];
+ * var bezierTo = new cc.BezierTo(2, bezier);
+ */
+cc.BezierTo = cc.BezierBy.extend(/** @lends cc.BezierTo# */{
+ _toConfig: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} t
+ * @param {Array} c array of points
+ * var bezierTo = new cc.BezierTo(2, bezier);
+ */
+ ctor: function (t, c) {
+ cc.BezierBy.prototype.ctor.call(this);
+ this._toConfig = [];
+ c && this.initWithDuration(t, c);
+ },
+
+ /**
+ * Initializes the action.
+ * @param {Number} t time in seconds
+ * @param {Array} c Array of points
+ * @return {Boolean}
+ */
+ initWithDuration: function (t, c) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, t)) {
+ this._toConfig = c;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.BezierTo}
+ */
+ clone: function () {
+ var action = new cc.BezierTo();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._toConfig);
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.BezierBy.prototype.startWithTarget.call(this, target);
+ var locStartPos = this._startPosition;
+ var locToConfig = this._toConfig;
+ var locConfig = this._config;
+
+ locConfig[0] = cc.pSub(locToConfig[0], locStartPos);
+ locConfig[1] = cc.pSub(locToConfig[1], locStartPos);
+ locConfig[2] = cc.pSub(locToConfig[2], locStartPos);
+ }
+});
+/**
+ * An action that moves the target with a cubic Bezier curve to a destination point.
+ * @function
+ * @param {Number} t
+ * @param {Array} c array of points
+ * @return {cc.BezierTo}
+ * @example
+ * // example
+ * var bezier = [cc.p(0, windowSize.height / 2), cc.p(300, -windowSize.height / 2), cc.p(300, 100)];
+ * var bezierTo = cc.bezierTo(2, bezier);
+ */
+cc.bezierTo = function (t, c) {
+ return new cc.BezierTo(t, c);
+};
+/**
+ * Please use cc.bezierTo instead
+ * @static
+ * @deprecated since v3.0 please use cc.bezierTo instead.
+ * @param {Number} t
+ * @param {Array} c array of points
+ * @return {cc.BezierTo}
+ */
+cc.BezierTo.create = cc.bezierTo;
+
+
+/** Scales a cc.Node object to a zoom factor by modifying it's scale attribute.
+ * @warning This action doesn't support "reverse"
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} duration
+ * @param {Number} sx scale parameter in X
+ * @param {Number} [sy] scale parameter in Y, if Null equal to sx
+ * @example
+ * // It scales to 0.5 in both X and Y.
+ * var actionTo = new cc.ScaleTo(2, 0.5);
+ *
+ * // It scales to 0.5 in x and 2 in Y
+ * var actionTo = new cc.ScaleTo(2, 0.5, 2);
+ */
+cc.ScaleTo = cc.ActionInterval.extend(/** @lends cc.ScaleTo# */{
+ _scaleX: 1,
+ _scaleY: 1,
+ _startScaleX: 1,
+ _startScaleY: 1,
+ _endScaleX: 0,
+ _endScaleY: 0,
+ _deltaX: 0,
+ _deltaY: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} duration
+ * @param {Number} sx scale parameter in X
+ * @param {Number} [sy] scale parameter in Y, if Null equal to sx
+ */
+ ctor: function (duration, sx, sy) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ sx !== undefined && this.initWithDuration(duration, sx, sy);
+ },
+
+ /**
+ * Initializes the action.
+ * @param {Number} duration
+ * @param {Number} sx
+ * @param {Number} [sy=]
+ * @return {Boolean}
+ */
+ initWithDuration: function (duration, sx, sy) { //function overload here
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ this._endScaleX = sx;
+ this._endScaleY = (sy != null) ? sy : sx;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.ScaleTo}
+ */
+ clone: function () {
+ var action = new cc.ScaleTo();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._endScaleX, this._endScaleY);
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ this._startScaleX = target.scaleX;
+ this._startScaleY = target.scaleY;
+ this._deltaX = this._endScaleX - this._startScaleX;
+ this._deltaY = this._endScaleY - this._startScaleY;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+ if (this.target) {
+ this.target.scaleX = this._startScaleX + this._deltaX * dt;
+ this.target.scaleY = this._startScaleY + this._deltaY * dt;
+ }
+ }
+});
+/**
+ * Scales a cc.Node object to a zoom factor by modifying it's scale attribute.
+ * @function
+ * @param {Number} duration
+ * @param {Number} sx scale parameter in X
+ * @param {Number} [sy] scale parameter in Y, if Null equal to sx
+ * @return {cc.ScaleTo}
+ * @example
+ * // example
+ * // It scales to 0.5 in both X and Y.
+ * var actionTo = cc.scaleTo(2, 0.5);
+ *
+ * // It scales to 0.5 in x and 2 in Y
+ * var actionTo = cc.scaleTo(2, 0.5, 2);
+ */
+cc.scaleTo = function (duration, sx, sy) { //function overload
+ return new cc.ScaleTo(duration, sx, sy);
+};
+/**
+ * Please use cc.scaleTo instead.
+ * Scales a cc.Node object to a zoom factor by modifying it's scale attribute.
+ * @static
+ * @deprecated since v3.0 please use cc.scaleTo instead.
+ * @param {Number} duration
+ * @param {Number} sx scale parameter in X
+ * @param {Number} [sy] scale parameter in Y, if Null equal to sx
+ * @return {cc.ScaleTo}
+ */
+cc.ScaleTo.create = cc.scaleTo;
+
+
+/** Scales a cc.Node object a zoom factor by modifying it's scale attribute.
+ * Relative to its changes.
+ * @class
+ * @extends cc.ScaleTo
+ */
+cc.ScaleBy = cc.ScaleTo.extend(/** @lends cc.ScaleBy# */{
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ScaleTo.prototype.startWithTarget.call(this, target);
+ this._deltaX = this._startScaleX * this._endScaleX - this._startScaleX;
+ this._deltaY = this._startScaleY * this._endScaleY - this._startScaleY;
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.ScaleBy}
+ */
+ reverse: function () {
+ var action = new cc.ScaleBy(this._duration, 1 / this._endScaleX, 1 / this._endScaleY);
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.ScaleBy}
+ */
+ clone: function () {
+ var action = new cc.ScaleBy();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._endScaleX, this._endScaleY);
+ return action;
+ }
+});
+/**
+ * Scales a cc.Node object a zoom factor by modifying it's scale attribute.
+ * Relative to its changes.
+ * @function
+ * @param {Number} duration duration in seconds
+ * @param {Number} sx sx scale parameter in X
+ * @param {Number|Null} [sy=] sy scale parameter in Y, if Null equal to sx
+ * @return {cc.ScaleBy}
+ * @example
+ * // example without sy, it scales by 2 both in X and Y
+ * var actionBy = cc.scaleBy(2, 2);
+ *
+ * //example with sy, it scales by 0.25 in X and 4.5 in Y
+ * var actionBy2 = cc.scaleBy(2, 0.25, 4.5);
+ */
+cc.scaleBy = function (duration, sx, sy) {
+ return new cc.ScaleBy(duration, sx, sy);
+};
+/**
+ * Please use cc.scaleBy instead.
+ * Scales a cc.Node object a zoom factor by modifying it's scale attribute.
+ * Relative to its changes.
+ * @static
+ * @deprecated since v3.0 please use cc.scaleBy() instead.
+ * @param {Number} duration duration in seconds
+ * @param {Number} sx sx scale parameter in X
+ * @param {Number|Null} [sy=] sy scale parameter in Y, if Null equal to sx
+ * @return {cc.ScaleBy}
+ */
+cc.ScaleBy.create = cc.scaleBy;
+
+/** Blinks a cc.Node object by modifying it's visible attribute
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} duration duration in seconds
+ * @param {Number} blinks blinks in times
+ * @example
+ * var action = new cc.Blink(2, 10);
+ */
+cc.Blink = cc.ActionInterval.extend(/** @lends cc.Blink# */{
+ _times: 0,
+ _originalState: false,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} duration duration in seconds
+ * @param {Number} blinks blinks in times
+ */
+ ctor: function (duration, blinks) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ blinks !== undefined && this.initWithDuration(duration, blinks);
+ },
+
+ /**
+ * Initializes the action.
+ * @param {Number} duration duration in seconds
+ * @param {Number} blinks blinks in times
+ * @return {Boolean}
+ */
+ initWithDuration: function (duration, blinks) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ this._times = blinks;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.Blink}
+ */
+ clone: function () {
+ var action = new cc.Blink();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._times);
+ return action;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt time in seconds
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+ if (this.target && !this.isDone()) {
+ var slice = 1.0 / this._times;
+ var m = dt % slice;
+ this.target.visible = (m > (slice / 2));
+ }
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ this._originalState = target.visible;
+ },
+
+ /**
+ * stop the action
+ */
+ stop: function () {
+ this.target.visible = this._originalState;
+ cc.ActionInterval.prototype.stop.call(this);
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.Blink}
+ */
+ reverse: function () {
+ var action = new cc.Blink(this._duration, this._times);
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ }
+});
+/**
+ * Blinks a cc.Node object by modifying it's visible attribute.
+ * @function
+ * @param {Number} duration duration in seconds
+ * @param blinks blinks in times
+ * @return {cc.Blink}
+ * @example
+ * // example
+ * var action = cc.blink(2, 10);
+ */
+cc.blink = function (duration, blinks) {
+ return new cc.Blink(duration, blinks);
+};
+/**
+ * Please use cc.blink instead.
+ * Blinks a cc.Node object by modifying it's visible attribute.
+ * @static
+ * @deprecated since v3.0 please use cc.blink instead.
+ * @param {Number} duration duration in seconds
+ * @param blinks blinks in times
+ * @return {cc.Blink}
+ */
+cc.Blink.create = cc.blink;
+
+/** Fades an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from the current value to a custom one.
+ * @warning This action doesn't support "reverse"
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} duration
+ * @param {Number} opacity 0-255, 0 is transparent
+ * @example
+ * var action = new cc.FadeTo(1.0, 0);
+ */
+cc.FadeTo = cc.ActionInterval.extend(/** @lends cc.FadeTo# */{
+ _toOpacity: 0,
+ _fromOpacity: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} duration
+ * @param {Number} opacity 0-255, 0 is transparent
+ */
+ ctor: function (duration, opacity) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ opacity !== undefined && this.initWithDuration(duration, opacity);
+ },
+
+ /**
+ * Initializes the action.
+ * @param {Number} duration duration in seconds
+ * @param {Number} opacity
+ * @return {Boolean}
+ */
+ initWithDuration: function (duration, opacity) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ this._toOpacity = opacity;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.FadeTo}
+ */
+ clone: function () {
+ var action = new cc.FadeTo();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._toOpacity);
+ return action;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} time time in seconds
+ */
+ update: function (time) {
+ time = this._computeEaseTime(time);
+ var fromOpacity = this._fromOpacity !== undefined ? this._fromOpacity : 255;
+ this.target.opacity = fromOpacity + (this._toOpacity - fromOpacity) * time;
+ },
+
+ /**
+ * Start this action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ this._fromOpacity = target.opacity;
+ }
+});
+
+/**
+ * Fades an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from the current value to a custom one.
+ * @function
+ * @param {Number} duration
+ * @param {Number} opacity 0-255, 0 is transparent
+ * @return {cc.FadeTo}
+ * @example
+ * // example
+ * var action = cc.fadeTo(1.0, 0);
+ */
+cc.fadeTo = function (duration, opacity) {
+ return new cc.FadeTo(duration, opacity);
+};
+/**
+ * Please use cc.fadeTo instead.
+ * Fades an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from the current value to a custom one.
+ * @static
+ * @deprecated since v3.0 please use cc.fadeTo instead.
+ * @param {Number} duration
+ * @param {Number} opacity 0-255, 0 is transparent
+ * @return {cc.FadeTo}
+ */
+cc.FadeTo.create = cc.fadeTo;
+
+/** Fades In an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from 0 to 255.
+ * The "reverse" of this action is FadeOut
+ * @class
+ * @extends cc.FadeTo
+ * @param {Number} duration duration in seconds
+ */
+cc.FadeIn = cc.FadeTo.extend(/** @lends cc.FadeIn# */{
+ _reverseAction: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} duration duration in seconds
+ */
+ ctor: function (duration) {
+ cc.FadeTo.prototype.ctor.call(this);
+ if (duration == null)
+ duration = 0;
+ this.initWithDuration(duration, 255);
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.FadeOut}
+ */
+ reverse: function () {
+ var action = new cc.FadeOut();
+ action.initWithDuration(this._duration, 0);
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.FadeIn}
+ */
+ clone: function () {
+ var action = new cc.FadeIn();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._toOpacity);
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ if (this._reverseAction)
+ this._toOpacity = this._reverseAction._fromOpacity;
+ cc.FadeTo.prototype.startWithTarget.call(this, target);
+ }
+});
+
+/**
+ * Fades In an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from 0 to 255.
+ * @function
+ * @param {Number} duration duration in seconds
+ * @return {cc.FadeIn}
+ * @example
+ * //example
+ * var action = cc.fadeIn(1.0);
+ */
+cc.fadeIn = function (duration) {
+ return new cc.FadeIn(duration);
+};
+/**
+ * Please use cc.fadeIn instead.
+ * Fades In an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from 0 to 255.
+ * @static
+ * @deprecated since v3.0 please use cc.fadeIn() instead.
+ * @param {Number} duration duration in seconds
+ * @return {cc.FadeIn}
+ */
+cc.FadeIn.create = cc.fadeIn;
+
+
+/** Fades Out an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from 255 to 0.
+ * The "reverse" of this action is FadeIn
+ * @class
+ * @extends cc.FadeTo
+ * @param {Number} duration duration in seconds
+ */
+cc.FadeOut = cc.FadeTo.extend(/** @lends cc.FadeOut# */{
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} duration duration in seconds
+ */
+ ctor: function (duration) {
+ cc.FadeTo.prototype.ctor.call(this);
+ if (duration == null)
+ duration = 0;
+ this.initWithDuration(duration, 0);
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.FadeIn}
+ */
+ reverse: function () {
+ var action = new cc.FadeIn();
+ action._reverseAction = this;
+ action.initWithDuration(this._duration, 255);
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.FadeOut}
+ */
+ clone: function () {
+ var action = new cc.FadeOut();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._toOpacity);
+ return action;
+ }
+});
+
+/**
+ * Fades Out an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from 255 to 0.
+ * @function
+ * @param {Number} d duration in seconds
+ * @return {cc.FadeOut}
+ * @example
+ * // example
+ * var action = cc.fadeOut(1.0);
+ */
+cc.fadeOut = function (d) {
+ return new cc.FadeOut(d);
+};
+/**
+ * Please use cc.fadeOut instead.
+ * Fades Out an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from 255 to 0.
+ * @static
+ * @deprecated since v3.0 please use cc.fadeOut instead.
+ * @param {Number} d duration in seconds
+ * @return {cc.FadeOut}
+ */
+cc.FadeOut.create = cc.fadeOut;
+
+/** Tints a cc.Node that implements the cc.NodeRGB protocol from current tint to a custom one.
+ * @warning This action doesn't support "reverse"
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} duration
+ * @param {Number} red 0-255
+ * @param {Number} green 0-255
+ * @param {Number} blue 0-255
+ * @example
+ * var action = new cc.TintTo(2, 255, 0, 255);
+ */
+cc.TintTo = cc.ActionInterval.extend(/** @lends cc.TintTo# */{
+ _to: null,
+ _from: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} duration
+ * @param {Number} red 0-255
+ * @param {Number} green 0-255
+ * @param {Number} blue 0-255
+ */
+ ctor: function (duration, red, green, blue) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ this._to = cc.color(0, 0, 0);
+ this._from = cc.color(0, 0, 0);
+
+ blue !== undefined && this.initWithDuration(duration, red, green, blue);
+ },
+
+ /**
+ * Initializes the action.
+ * @param {Number} duration
+ * @param {Number} red 0-255
+ * @param {Number} green 0-255
+ * @param {Number} blue 0-255
+ * @return {Boolean}
+ */
+ initWithDuration: function (duration, red, green, blue) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ this._to = cc.color(red, green, blue);
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.TintTo}
+ */
+ clone: function () {
+ var action = new cc.TintTo();
+ this._cloneDecoration(action);
+ var locTo = this._to;
+ action.initWithDuration(this._duration, locTo.r, locTo.g, locTo.b);
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+
+ this._from = this.target.color;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt time in seconds
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+ var locFrom = this._from, locTo = this._to;
+ if (locFrom) {
+ this.target.setColor(
+ cc.color(
+ locFrom.r + (locTo.r - locFrom.r) * dt,
+ locFrom.g + (locTo.g - locFrom.g) * dt,
+ locFrom.b + (locTo.b - locFrom.b) * dt)
+ );
+ }
+ }
+});
+
+/**
+ * Tints a cc.Node that implements the cc.NodeRGB protocol from current tint to a custom one.
+ * @function
+ * @param {Number} duration
+ * @param {Number} red 0-255
+ * @param {Number} green 0-255
+ * @param {Number} blue 0-255
+ * @return {cc.TintTo}
+ * @example
+ * // example
+ * var action = cc.tintTo(2, 255, 0, 255);
+ */
+cc.tintTo = function (duration, red, green, blue) {
+ return new cc.TintTo(duration, red, green, blue);
+};
+/**
+ * Please use cc.tintTo instead.
+ * Tints a cc.Node that implements the cc.NodeRGB protocol from current tint to a custom one.
+ * @static
+ * @deprecated since v3.0 please use cc.tintTo instead.
+ * @param {Number} duration
+ * @param {Number} red 0-255
+ * @param {Number} green 0-255
+ * @param {Number} blue 0-255
+ * @return {cc.TintTo}
+ */
+cc.TintTo.create = cc.tintTo;
+
+
+/** Tints a cc.Node that implements the cc.NodeRGB protocol from current tint to a custom one.
+ * Relative to their own color change.
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaRed
+ * @param {Number} deltaGreen
+ * @param {Number} deltaBlue
+ * @example
+ * var action = new cc.TintBy(2, -127, -255, -127);
+ */
+cc.TintBy = cc.ActionInterval.extend(/** @lends cc.TintBy# */{
+ _deltaR: 0,
+ _deltaG: 0,
+ _deltaB: 0,
+
+ _fromR: 0,
+ _fromG: 0,
+ _fromB: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaRed
+ * @param {Number} deltaGreen
+ * @param {Number} deltaBlue
+ */
+ ctor: function (duration, deltaRed, deltaGreen, deltaBlue) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ deltaBlue !== undefined && this.initWithDuration(duration, deltaRed, deltaGreen, deltaBlue);
+ },
+
+ /**
+ * Initializes the action.
+ * @param {Number} duration
+ * @param {Number} deltaRed 0-255
+ * @param {Number} deltaGreen 0-255
+ * @param {Number} deltaBlue 0-255
+ * @return {Boolean}
+ */
+ initWithDuration: function (duration, deltaRed, deltaGreen, deltaBlue) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ this._deltaR = deltaRed;
+ this._deltaG = deltaGreen;
+ this._deltaB = deltaBlue;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.TintBy}
+ */
+ clone: function () {
+ var action = new cc.TintBy();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration, this._deltaR, this._deltaG, this._deltaB);
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+
+ var color = target.color;
+ this._fromR = color.r;
+ this._fromG = color.g;
+ this._fromB = color.b;
+
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt time in seconds
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+
+ this.target.color = cc.color(this._fromR + this._deltaR * dt,
+ this._fromG + this._deltaG * dt,
+ this._fromB + this._deltaB * dt);
+
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.TintBy}
+ */
+ reverse: function () {
+ var action = new cc.TintBy(this._duration, -this._deltaR, -this._deltaG, -this._deltaB);
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ }
+});
+
+/**
+ * Tints a cc.Node that implements the cc.NodeRGB protocol from current tint to a custom one.
+ * Relative to their own color change.
+ * @function
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaRed
+ * @param {Number} deltaGreen
+ * @param {Number} deltaBlue
+ * @return {cc.TintBy}
+ * @example
+ * // example
+ * var action = cc.tintBy(2, -127, -255, -127);
+ */
+cc.tintBy = function (duration, deltaRed, deltaGreen, deltaBlue) {
+ return new cc.TintBy(duration, deltaRed, deltaGreen, deltaBlue);
+};
+/**
+ * Please use cc.tintBy instead.
+ * Tints a cc.Node that implements the cc.NodeRGB protocol from current tint to a custom one.
+ * Relative to their own color change.
+ * @static
+ * @deprecated since v3.0 please use cc.tintBy instead.
+ * @param {Number} duration duration in seconds
+ * @param {Number} deltaRed
+ * @param {Number} deltaGreen
+ * @param {Number} deltaBlue
+ * @return {cc.TintBy}
+ */
+cc.TintBy.create = cc.tintBy;
+
+/** Delays the action a certain amount of seconds
+ * @class
+ * @extends cc.ActionInterval
+ */
+cc.DelayTime = cc.ActionInterval.extend(/** @lends cc.DelayTime# */{
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * Will be overwrite.
+ * @param {Number} dt time in seconds
+ */
+ update: function (dt) {
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.DelayTime}
+ */
+ reverse: function () {
+ var action = new cc.DelayTime(this._duration);
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+ return action;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.DelayTime}
+ */
+ clone: function () {
+ var action = new cc.DelayTime();
+ this._cloneDecoration(action);
+ action.initWithDuration(this._duration);
+ return action;
+ }
+});
+
+/**
+ * Delays the action a certain amount of seconds
+ * @function
+ * @param {Number} d duration in seconds
+ * @return {cc.DelayTime}
+ * @example
+ * // example
+ * var delay = cc.delayTime(1);
+ */
+cc.delayTime = function (d) {
+ return new cc.DelayTime(d);
+};
+/**
+ * Please use cc.delayTime instead.
+ * Delays the action a certain amount of seconds
+ * @static
+ * @deprecated since v3.0 please use cc.delaTime instead.
+ * @param {Number} d duration in seconds
+ * @return {cc.DelayTime}
+ */
+cc.DelayTime.create = cc.delayTime;
+
+/**
+ *
+ * Executes an action in reverse order, from time=duration to time=0
+ * @warning Use this action carefully. This action is not sequenceable.
+ * Use it as the default "reversed" method of your own actions, but using it outside the "reversed"
+ * scope is not recommended.
+ *
+ * @class
+ * @extends cc.ActionInterval
+ * @param {cc.FiniteTimeAction} action
+ * @example
+ * var reverse = new cc.ReverseTime(this);
+ */
+cc.ReverseTime = cc.ActionInterval.extend(/** @lends cc.ReverseTime# */{
+ _other: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {cc.FiniteTimeAction} action
+ */
+ ctor: function (action) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ this._other = null;
+
+ action && this.initWithAction(action);
+ },
+
+ /**
+ * @param {cc.FiniteTimeAction} action
+ * @return {Boolean}
+ */
+ initWithAction: function (action) {
+ if (!action)
+ throw new Error("cc.ReverseTime.initWithAction(): action must be non null");
+ if (action === this._other)
+ throw new Error("cc.ReverseTime.initWithAction(): the action was already passed in.");
+
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, action._duration)) {
+ // Don't leak if action is reused
+ this._other = action;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.ReverseTime}
+ */
+ clone: function () {
+ var action = new cc.ReverseTime();
+ this._cloneDecoration(action);
+ action.initWithAction(this._other.clone());
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ this._other.startWithTarget(target);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt time in seconds
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+ if (this._other)
+ this._other.update(1 - dt);
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.ActionInterval}
+ */
+ reverse: function () {
+ return this._other.clone();
+ },
+
+ /**
+ * Stop the action
+ */
+ stop: function () {
+ this._other.stop();
+ cc.Action.prototype.stop.call(this);
+ }
+});
+
+/**
+ * Executes an action in reverse order, from time=duration to time=0.
+ * @function
+ * @param {cc.FiniteTimeAction} action
+ * @return {cc.ReverseTime}
+ * @example
+ * // example
+ * var reverse = cc.reverseTime(this);
+ */
+cc.reverseTime = function (action) {
+ return new cc.ReverseTime(action);
+};
+/**
+ * Please use cc.reverseTime instead.
+ * Executes an action in reverse order, from time=duration to time=0.
+ * @static
+ * @deprecated since v3.0 please use cc.reverseTime instead.
+ * @param {cc.FiniteTimeAction} action
+ * @return {cc.ReverseTime}
+ */
+cc.ReverseTime.create = cc.reverseTime;
+
+
+/** Animates a sprite given the name of an Animation
+ * @class
+ * @extends cc.ActionInterval
+ * @param {cc.Animation} animation
+ * @example
+ * // create the animation with animation
+ * var anim = new cc.Animate(dance_grey);
+ */
+cc.Animate = cc.ActionInterval.extend(/** @lends cc.Animate# */{
+ _animation: null,
+ _nextFrame: 0,
+ _origFrame: null,
+ _executedLoops: 0,
+ _splitTimes: null,
+ _currFrameIndex: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * create the animate with animation.
+ * @param {cc.Animation} animation
+ */
+ ctor: function (animation) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ this._splitTimes = [];
+
+ animation && this.initWithAnimation(animation);
+ },
+
+ /**
+ * @return {cc.Animation}
+ */
+ getAnimation: function () {
+ return this._animation;
+ },
+
+ /**
+ * @param {cc.Animation} animation
+ */
+ setAnimation: function (animation) {
+ this._animation = animation;
+ },
+
+ /**
+ * Gets the index of sprite frame currently displayed.
+ * @return {Number}
+ */
+ getCurrentFrameIndex: function () {
+ return this._currFrameIndex;
+ },
+
+ /**
+ * @param {cc.Animation} animation
+ * @return {Boolean}
+ */
+ initWithAnimation: function (animation) {
+ if (!animation)
+ throw new Error("cc.Animate.initWithAnimation(): animation must be non-NULL");
+ var singleDuration = animation.getDuration();
+ if (this.initWithDuration(singleDuration * animation.getLoops())) {
+ this._nextFrame = 0;
+ this.setAnimation(animation);
+
+ this._origFrame = null;
+ this._executedLoops = 0;
+ var locTimes = this._splitTimes;
+ locTimes.length = 0;
+
+ var accumUnitsOfTime = 0;
+ var newUnitOfTimeValue = singleDuration / animation.getTotalDelayUnits();
+
+ var frames = animation.getFrames();
+ cc.arrayVerifyType(frames, cc.AnimationFrame);
+
+ for (var i = 0; i < frames.length; i++) {
+ var frame = frames[i];
+ var value = (accumUnitsOfTime * newUnitOfTimeValue) / singleDuration;
+ accumUnitsOfTime += frame.getDelayUnits();
+ locTimes.push(value);
+ }
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.Animate}
+ */
+ clone: function () {
+ var action = new cc.Animate();
+ this._cloneDecoration(action);
+ action.initWithAnimation(this._animation.clone());
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Sprite} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ if (this._animation.getRestoreOriginalFrame())
+ this._origFrame = target.getSpriteFrame();
+ this._nextFrame = 0;
+ this._executedLoops = 0;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+ // if t==1, ignore. Animation should finish with t==1
+ if (dt < 1.0) {
+ dt *= this._animation.getLoops();
+
+ // new loop? If so, reset frame counter
+ var loopNumber = 0 | dt;
+ if (loopNumber > this._executedLoops) {
+ this._nextFrame = 0;
+ this._executedLoops++;
+ }
+
+ // new t for animations
+ dt = dt % 1.0;
+ }
+
+ var frames = this._animation.getFrames();
+ var numberOfFrames = frames.length, locSplitTimes = this._splitTimes;
+ for (var i = this._nextFrame; i < numberOfFrames; i++) {
+ if (locSplitTimes[i] <= dt) {
+ _currFrameIndex = i;
+ this.target.setSpriteFrame(frames[_currFrameIndex].getSpriteFrame());
+ this._nextFrame = i + 1;
+ } else {
+ // Issue 1438. Could be more than one frame per tick, due to low frame rate or frame delta < 1/FPS
+ break;
+ }
+ }
+ },
+
+ /**
+ * Returns a reversed action.
+ * @return {cc.Animate}
+ */
+ reverse: function () {
+ var locAnimation = this._animation;
+ var oldArray = locAnimation.getFrames();
+ var newArray = [];
+ cc.arrayVerifyType(oldArray, cc.AnimationFrame);
+ if (oldArray.length > 0) {
+ for (var i = oldArray.length - 1; i >= 0; i--) {
+ var element = oldArray[i];
+ if (!element)
+ break;
+ newArray.push(element.clone());
+ }
+ }
+ var newAnim = new cc.Animation(newArray, locAnimation.getDelayPerUnit(), locAnimation.getLoops());
+ newAnim.setRestoreOriginalFrame(locAnimation.getRestoreOriginalFrame());
+ var action = new cc.Animate(newAnim);
+ this._cloneDecoration(action);
+ this._reverseEaseList(action);
+
+ return action;
+ },
+
+ /**
+ * stop the action
+ */
+ stop: function () {
+ if (this._animation.getRestoreOriginalFrame() && this.target)
+ this.target.setSpriteFrame(this._origFrame);
+ cc.Action.prototype.stop.call(this);
+ }
+});
+
+/**
+ * create the animate with animation
+ * @function
+ * @param {cc.Animation} animation
+ * @return {cc.Animate}
+ * @example
+ * // example
+ * // create the animation with animation
+ * var anim = cc.animate(dance_grey);
+ */
+cc.animate = function (animation) {
+ return new cc.Animate(animation);
+};
+/**
+ * Please use cc.animate instead
+ * create the animate with animation
+ * @static
+ * @deprecated since v3.0 please use cc.animate instead.
+ * @param {cc.Animation} animation
+ * @return {cc.Animate}
+ */
+cc.Animate.create = cc.animate;
+
+/**
+ *
+ * Overrides the target of an action so that it always runs on the target
+ * specified at action creation rather than the one specified by runAction.
+ *
+ * @class
+ * @extends cc.ActionInterval
+ * @param {cc.Node} target
+ * @param {cc.FiniteTimeAction} action
+ */
+cc.TargetedAction = cc.ActionInterval.extend(/** @lends cc.TargetedAction# */{
+ _action: null,
+ _forcedTarget: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Create an action with the specified action and forced target.
+ * @param {cc.Node} target
+ * @param {cc.FiniteTimeAction} action
+ */
+ ctor: function (target, action) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ action && this.initWithTarget(target, action);
+ },
+
+ /**
+ * Init an action with the specified action and forced target
+ * @param {cc.Node} target
+ * @param {cc.FiniteTimeAction} action
+ * @return {Boolean}
+ */
+ initWithTarget: function (target, action) {
+ if (this.initWithDuration(action._duration)) {
+ this._forcedTarget = target;
+ this._action = action;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * returns a new clone of the action
+ * @returns {cc.TargetedAction}
+ */
+ clone: function () {
+ var action = new cc.TargetedAction();
+ this._cloneDecoration(action);
+ action.initWithTarget(this._forcedTarget, this._action.clone());
+ return action;
+ },
+
+ /**
+ * Start the action with target.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ this._action.startWithTarget(this._forcedTarget);
+ },
+
+ /**
+ * stop the action
+ */
+ stop: function () {
+ this._action.stop();
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ dt = this._computeEaseTime(dt);
+ this._action.update(dt);
+ },
+
+ /**
+ * return the target that the action will be forced to run with
+ * @return {cc.Node}
+ */
+ getForcedTarget: function () {
+ return this._forcedTarget;
+ },
+
+ /**
+ * set the target that the action will be forced to run with
+ * @param {cc.Node} forcedTarget
+ */
+ setForcedTarget: function (forcedTarget) {
+ if (this._forcedTarget !== forcedTarget)
+ this._forcedTarget = forcedTarget;
+ }
+});
+
+/**
+ * Create an action with the specified action and forced target
+ * @function
+ * @param {cc.Node} target
+ * @param {cc.FiniteTimeAction} action
+ * @return {cc.TargetedAction}
+ */
+cc.targetedAction = function (target, action) {
+ return new cc.TargetedAction(target, action);
+};
+/**
+ * Please use cc.targetedAction instead
+ * Create an action with the specified action and forced target
+ * @static
+ * @deprecated since v3.0 please use cc.targetedAction instead.
+ * @param {cc.Node} target
+ * @param {cc.FiniteTimeAction} action
+ * @return {cc.TargetedAction}
+ */
+cc.TargetedAction.create = cc.targetedAction;
diff --git a/frameworks/cocos2d-html5/cocos2d/actions/CCActionTween.js b/frameworks/cocos2d-html5/cocos2d/actions/CCActionTween.js
new file mode 100644
index 0000000..daa6c36
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/actions/CCActionTween.js
@@ -0,0 +1,167 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ *
+ * @class
+ * @extends cc.Class
+ */
+cc.ActionTweenDelegate = cc.Class.extend(/** @lends cc.ActionTweenDelegate */{
+
+ /**
+ * Update Tween Action.
+ * @param value
+ * @param key
+ */
+ updateTweenAction: function (value, key) {
+ }
+});
+
+/**
+ * cc.ActionTween
+ * cc.ActionTween is an action that lets you update any property of an object.
+ *
+ * @class
+ * @extends cc.ActionInterval
+ * @example
+ * //For example, if you want to modify the "width" property of a target from 200 to 300 in 2 seconds, then:
+ * var modifyWidth = cc.actionTween(2,"width",200,300)
+ * target.runAction(modifyWidth);
+ *
+ * //Another example: cc.ScaleTo action could be rewriten using cc.PropertyAction:
+ * // scaleA and scaleB are equivalents
+ * var scaleA = cc.scaleTo(2,3);
+ * var scaleB = cc.actionTween(2,"scale",1,3);
+ * @param {Number} duration
+ * @param {String} key
+ * @param {Number} from
+ * @param {Number} to
+ */
+cc.ActionTween = cc.ActionInterval.extend(/** @lends cc.ActionTween */{
+ key: "",
+ from: 0,
+ to: 0,
+ delta: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Creates an initializes the action with the property name (key), and the from and to parameters.
+ * @param {Number} duration
+ * @param {String} key
+ * @param {Number} from
+ * @param {Number} to
+ */
+ ctor: function (duration, key, from, to) {
+ cc.ActionInterval.prototype.ctor.call(this);
+ this.key = "";
+
+ to !== undefined && this.initWithDuration(duration, key, from, to);
+ },
+
+ /**
+ * initializes the action with the property name (key), and the from and to parameters.
+ * @param {Number} duration
+ * @param {String} key
+ * @param {Number} from
+ * @param {Number} to
+ * @return {Boolean}
+ */
+ initWithDuration: function (duration, key, from, to) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ this.key = key;
+ this.to = to;
+ this.from = from;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Start this tween with target.
+ * @param {cc.ActionTweenDelegate} target
+ */
+ startWithTarget: function (target) {
+ if (!target || !target.updateTweenAction)
+ throw new Error("cc.ActionTween.startWithTarget(): target must be non-null, and target must implement updateTweenAction function");
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ this.delta = this.to - this.from;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ this.target.updateTweenAction(this.to - this.delta * (1 - dt), this.key);
+ },
+
+ /**
+ * returns a reversed action.
+ * @return {cc.ActionTween}
+ */
+ reverse: function () {
+ return new cc.ActionTween(this.duration, this.key, this.to, this.from);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.ActionTween}
+ */
+ clone: function () {
+ var action = new cc.ActionTween();
+ action.initWithDuration(this._duration, this.key, this.from, this.to);
+ return action;
+ }
+});
+
+/**
+ * Creates an initializes the action with the property name (key), and the from and to parameters.
+ * @function
+ * @param {Number} duration
+ * @param {String} key
+ * @param {Number} from
+ * @param {Number} to
+ * @return {cc.ActionTween}
+ */
+cc.actionTween = function (duration, key, from, to) {
+ return new cc.ActionTween(duration, key, from, to);
+};
+
+/**
+ * Please use cc.actionTween instead.
+ * Creates an initializes the action with the property name (key), and the from and to parameters.
+ * @static
+ * @deprecated since v3.0 Please use cc.actionTween instead.
+ * @param {Number} duration
+ * @param {String} key
+ * @param {Number} from
+ * @param {Number} to
+ * @return {cc.ActionTween}
+ */
+cc.ActionTween.create = cc.actionTween;
diff --git a/frameworks/cocos2d-html5/cocos2d/actions3d/CCActionGrid.js b/frameworks/cocos2d-html5/cocos2d/actions3d/CCActionGrid.js
new file mode 100644
index 0000000..61b90a1
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/actions3d/CCActionGrid.js
@@ -0,0 +1,427 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Base class for Grid actions
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ */
+cc.GridAction = cc.ActionInterval.extend(/** @lends cc.GridAction# */{
+ _gridSize:null,
+ _gridNodeTarget:null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ */
+ ctor:function(duration, gridSize){
+ cc.sys._checkWebGLRenderMode();
+ cc.ActionInterval.prototype.ctor.call(this);
+ this._gridSize = cc.size(0,0);
+
+ gridSize && this.initWithDuration(duration, gridSize);
+ },
+
+ _cacheTargetAsGridNode:function (target) {
+ this._gridNodeTarget = target;
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.ActionInterval}
+ */
+ clone:function(){
+ var action = new cc.GridAction();
+ var locGridSize = this._gridSize;
+ action.initWithDuration(this._duration, cc.size(locGridSize.width, locGridSize.height));
+ return action;
+ },
+
+ /**
+ * called before the action start. It will also set the target.
+ *
+ * @param {cc.Node} target
+ */
+ startWithTarget:function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ cc.renderer.childrenOrderDirty = true;
+ this._cacheTargetAsGridNode(target);
+
+ var newGrid = this.getGrid();
+
+ var targetGrid = this._gridNodeTarget.getGrid();
+ if (targetGrid && targetGrid.getReuseGrid() > 0) {
+ var locGridSize = targetGrid.getGridSize();
+ if (targetGrid.isActive() && (locGridSize.width === this._gridSize.width) && (locGridSize.height === this._gridSize.height))
+ targetGrid.reuse();
+ } else {
+ if (targetGrid && targetGrid.isActive())
+ targetGrid.setActive(false);
+ this._gridNodeTarget.setGrid(newGrid);
+ this._gridNodeTarget.getGrid().setActive(true);
+ }
+ },
+
+ /**
+ * Create a cc.ReverseTime action. Opposite with the original motion trajectory.
+ * @return {cc.ReverseTime}
+ */
+ reverse:function () {
+ return new cc.ReverseTime(this);
+ },
+
+ /**
+ * Initializes the action with size and duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, gridSize) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ this._gridSize.width = gridSize.width;
+ this._gridSize.height = gridSize.height;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Returns the grid.
+ * @return {cc.GridBase}
+ */
+ getGrid:function () {
+ // Abstract class needs implementation
+ cc.log("cc.GridAction.getGrid(): it should be overridden in subclass.");
+ }
+});
+
+/**
+ * creates the action with size and duration
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @return {cc.GridAction}
+ */
+cc.gridAction = function (duration, gridSize) {
+ return new cc.GridAction(duration, gridSize);
+};
+
+/**
+ * Please use cc.gridAction instead.
+ * Creates the action with size and duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @return {cc.GridAction}
+ * @static
+ * @deprecated since v3.0 Please use cc.gridAction instead.
+ */
+cc.GridAction.create = cc.gridAction;
+
+/**
+ * Base class for cc.Grid3D actions.
+ * Grid3D actions can modify a non-tiled grid.
+ * @class
+ * @extends cc.GridAction
+ */
+cc.Grid3DAction = cc.GridAction.extend(/** @lends cc.Grid3DAction# */{
+
+ /**
+ * returns the grid
+ * @return {cc.Grid3D}
+ */
+ getGrid:function () {
+ return new cc.Grid3D(this._gridSize, undefined, undefined, this._gridNodeTarget.getGridRect());
+ },
+
+ /**
+ * get rect of the grid
+ * @return {cc.Rect} rect
+ */
+ getGridRect:function () {
+ return this._gridNodeTarget.getGridRect();
+ },
+
+ /**
+ * returns the vertex than belongs to certain position in the grid.
+ * It will be deprecated in future, please use getVertex instead.
+ * @param {cc.Point} position
+ * @return {cc.Vertex3F}
+ */
+ vertex:function (position) {
+ return this.getVertex(position);
+ },
+
+ /**
+ * returns the vertex than belongs to certain position in the grid
+ * @param {cc.Point} position
+ * @return {cc.Vertex3F}
+ */
+ getVertex: function(position){
+ return this.target.grid.getVertex(position);
+ },
+
+ /**
+ * returns the non-transformed vertex than belongs to certain position in the grid
+ * It will be deprecated in future, please use getVertex instead.
+ * @param {cc.Point} position
+ * @return {cc.Vertex3F}
+ */
+ originalVertex:function (position) {
+ return this.getOriginalVertex(position);
+ },
+
+ /**
+ * returns the non-transformed vertex that belongs to certain position in the grid
+ * @param {cc.Point} position
+ * @return {cc.Vertex3F}
+ */
+ getOriginalVertex:function (position) {
+ return this.target.grid.originalVertex(position);
+ },
+
+ /**
+ * sets a new vertex to a certain position of the grid
+ * @param {cc.Point} position
+ * @param {cc.Vertex3F} vertex
+ */
+ setVertex:function (position, vertex) {
+ this.target.grid.setVertex(position, vertex);
+ }
+});
+
+/**
+ * creates the action with size and duration
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @return {cc.Grid3DAction}
+ */
+cc.grid3DAction = function (duration, gridSize) {
+ return new cc.Grid3DAction(duration, gridSize);
+};
+/**
+ * Please use cc.grid3DAction instead.
+ * creates the action with size and duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @return {cc.Grid3DAction}
+ * @static
+ * @deprecated since v3.0 Please use cc.grid3DAction instead.
+ */
+cc.Grid3DAction.create = cc.grid3DAction;
+
+/**
+ * Base class for cc.TiledGrid3D actions.
+ * @class
+ * @extends cc.GridAction
+ */
+cc.TiledGrid3DAction = cc.GridAction.extend(/** @lends cc.TiledGrid3DAction# */{
+
+ /**
+ * returns the tile that belongs to a certain position of the grid
+ * It will be deprecated in future, please use getTile instead.
+ * @param {cc.Point} position
+ * @return {cc.Quad3}
+ */
+ tile:function (position) {
+ return this.getTile(position);
+ },
+
+ /**
+ * returns the tile that belongs to a certain position of the grid
+ * @param {cc.Point} position
+ * @return {cc.Quad3}
+ */
+ getTile:function (position) {
+ return this.target.grid.tile(position);
+ },
+
+ /**
+ * returns the non-transformed tile that belongs to a certain position of the grid
+ * It will be deprecated in future, please use getOriginalTile instead.
+ * @param {cc.Point} position
+ * @return {cc.Quad3}
+ */
+ originalTile:function (position) {
+ return this.getOriginalTile(position);
+ },
+
+ /**
+ * returns the non-transformed tile that belongs to a certain position of the grid
+ * @param {cc.Point} position
+ * @return {cc.Quad3}
+ */
+ getOriginalTile:function (position) {
+ return this.target.grid.originalTile(position);
+ },
+
+ /**
+ * sets a new tile to a certain position of the grid
+ * @param {cc.Point} position
+ * @param {cc.Quad3} coords
+ */
+ setTile:function (position, coords) {
+ this.target.grid.setTile(position, coords);
+ },
+
+ /**
+ * returns the grid
+ * @return {cc.TiledGrid3D}
+ */
+ getGrid:function () {
+ return new cc.TiledGrid3D(this._gridSize, undefined, undefined, this._gridNodeTarget.getGridRect());
+ }
+});
+
+/**
+ * Creates the action with duration and grid size
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @return {cc.TiledGrid3DAction}
+ */
+cc.tiledGrid3DAction = function (duration, gridSize) {
+ return new cc.TiledGrid3DAction(duration, gridSize);
+};
+
+/**
+ * Please use cc.tiledGrid3DAction instead
+ * Creates the action with duration and grid size
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @return {cc.TiledGrid3DAction}
+ * @static
+ * @deprecated since v3.0 Please use cc.tiledGrid3DAction instead.
+ */
+cc.TiledGrid3DAction.create = cc.tiledGrid3DAction;
+
+/**
+ *
+ * cc.StopGrid action.
+ * @warning Don't call this action if another grid action is active.
+ * Call if you want to remove the the grid effect. Example:
+ * cc.sequence(Lens.action(...), cc.stopGrid(...), null);
+ *
+ * @class
+ * @extends cc.ActionInstant
+ */
+cc.StopGrid = cc.ActionInstant.extend(/** @lends cc.StopGrid# */{
+
+ /**
+ * called before the action start. It will also set the target.
+ *
+ * @param {cc.Node} target
+ */
+ startWithTarget:function (target) {
+ cc.ActionInstant.prototype.startWithTarget.call(this, target);
+ cc.renderer.childrenOrderDirty = true;
+ var grid = this.target.grid;
+ if (grid && grid.isActive())
+ grid.setActive(false);
+ }
+});
+
+/**
+ * Allocates and initializes the action
+ * @function
+ * @return {cc.StopGrid}
+ */
+cc.stopGrid = function () {
+ return new cc.StopGrid();
+};
+/**
+ * Please use cc.stopGrid instead
+ * Allocates and initializes the action
+ * @return {cc.StopGrid}
+ * @static
+ * @deprecated since v3.0 Please use cc.stopGrid instead.
+ */
+cc.StopGrid.create = cc.stopGrid;
+
+/**
+ * cc.ReuseGrid action
+ * @class
+ * @extends cc.ActionInstant
+ * @param {Number} times
+ */
+cc.ReuseGrid = cc.ActionInstant.extend(/** @lends cc.ReuseGrid# */{
+ _times:null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} times
+ */
+ ctor: function(times) {
+ cc.ActionInstant.prototype.ctor.call(this);
+ times !== undefined && this.initWithTimes(times);
+ },
+
+ /**
+ * initializes an action with the number of times that the current grid will be reused
+ * @param {Number} times
+ * @return {Boolean}
+ */
+ initWithTimes:function (times) {
+ this._times = times;
+ return true;
+ },
+
+ /**
+ * called before the action start. It will also set the target.
+ *
+ * @param {cc.Node} target
+ */
+ startWithTarget:function (target) {
+ cc.ActionInstant.prototype.startWithTarget.call(this, target);
+ cc.renderer.childrenOrderDirty = true;
+ if (this.target.grid && this.target.grid.isActive())
+ this.target.grid.setReuseGrid(this.target.grid.getReuseGrid() + this._times);
+ }
+});
+
+/**
+ * creates an action with the number of times that the current grid will be reused
+ * @function
+ * @param {Number} times
+ * @return {cc.ReuseGrid}
+ */
+cc.reuseGrid = function (times) {
+ return new cc.ReuseGrid(times);
+};
+/**
+ * Please use cc.reuseGrid instead
+ * creates an action with the number of times that the current grid will be reused
+ * @param {Number} times
+ * @return {cc.ReuseGrid}
+ * @static
+ * @deprecated since v3.0 Please use cc.reuseGrid instead.
+ */
+cc.ReuseGrid.create = cc.reuseGrid;
diff --git a/frameworks/cocos2d-html5/cocos2d/actions3d/CCActionGrid3D.js b/frameworks/cocos2d-html5/cocos2d/actions3d/CCActionGrid3D.js
new file mode 100644
index 0000000..31be9c2
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/actions3d/CCActionGrid3D.js
@@ -0,0 +1,1257 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.Waves3D action.
+ * Reference the test cases (Effects Advanced Test)
+ * @class
+ * @extends cc.Grid3DAction
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ */
+cc.Waves3D = cc.Grid3DAction.extend(/** @lends cc.Waves3D# */{
+ _waves: 0,
+ _amplitude: 0,
+ _amplitudeRate: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Create a wave 3d action with duration, grid size, waves and amplitude.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ */
+ ctor:function (duration, gridSize, waves, amplitude) {
+ cc.GridAction.prototype.ctor.call(this);
+ amplitude !== undefined && this.initWithDuration(duration, gridSize, waves, amplitude);
+ },
+
+ /**
+ * get Amplitude
+ * @return {Number}
+ */
+ getAmplitude:function () {
+ return this._amplitude;
+ },
+
+ /**
+ * set Amplitude
+ * @param {Number} amplitude
+ */
+ setAmplitude:function (amplitude) {
+ this._amplitude = amplitude;
+ },
+
+ /**
+ * get Amplitude Rate
+ * @return {Number}
+ */
+ getAmplitudeRate:function () {
+ return this._amplitudeRate;
+ },
+
+ /**
+ * set Amplitude Rate
+ * @param {Number} amplitudeRate
+ */
+ setAmplitudeRate:function (amplitudeRate) {
+ this._amplitudeRate = amplitudeRate;
+ },
+
+ /**
+ * initializes an action with duration, grid size, waves and amplitude
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, gridSize, waves, amplitude) {
+ if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
+ this._waves = waves;
+ this._amplitude = amplitude;
+ this._amplitudeRate = 1.0;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var locGridSize = this._gridSize;
+ var locAmplitude = this._amplitude, locPos = cc.p(0, 0);
+ var locAmplitudeRate = this._amplitudeRate, locWaves = this._waves;
+ for (var i = 0; i < locGridSize.width + 1; ++i) {
+ for (var j = 0; j < locGridSize.height + 1; ++j) {
+ locPos.x = i;
+ locPos.y = j;
+ var v = this.originalVertex(locPos);
+ v.z += (Math.sin(Math.PI * dt * locWaves * 2 + (v.y + v.x) * 0.01) * locAmplitude * locAmplitudeRate);
+ //cc.log("v.z offset is" + (Math.sin(Math.PI * dt * this._waves * 2 + (v.y + v.x) * 0.01) * this._amplitude * this._amplitudeRate));
+ this.setVertex(locPos, v);
+ }
+ }
+ }
+});
+
+/**
+ * Create a wave 3d action with duration, grid size, waves and amplitude.
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ */
+cc.waves3D = function (duration, gridSize, waves, amplitude) {
+ return new cc.Waves3D(duration, gridSize, waves, amplitude);
+};
+/**
+ * Please use cc.waves3D instead.
+ * Create a wave 3d action with duration, grid size, waves and amplitude.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @static
+ * @deprecated since v3.0 Please use cc.waves3D instead.
+ */
+cc.Waves3D.create = cc.waves3D;
+
+/**
+ * cc.FlipX3D action.
+ * Flip around.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.Grid3DAction
+ * @param {Number} duration
+ */
+cc.FlipX3D = cc.Grid3DAction.extend(/** @lends cc.FlipX3D# */{
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Create a Flip X 3D action with duration.
+ * @param {Number} duration
+ */
+ ctor: function(duration) {
+ if (duration !== undefined)
+ cc.GridAction.prototype.ctor.call(this, duration, cc.size(1, 1));
+ else cc.GridAction.prototype.ctor.call(this);
+ },
+
+ /**
+ * initializes the action with duration
+ * @param {Number} duration
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration) {
+ return cc.Grid3DAction.prototype.initWithDuration.call(this, duration, cc.size(1, 1));
+ },
+
+ /**
+ * initializes the action with gridSize and duration
+ * @param {cc.Size} gridSize
+ * @param {Number} duration
+ * @return {Boolean}
+ */
+ initWithSize:function (gridSize, duration) {
+ if (gridSize.width !== 1 || gridSize.height !== 1) {
+ // Grid size must be (1,1)
+ cc.log("Grid size must be (1,1)");
+ return false;
+ }
+ return cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var angle = Math.PI * dt; // 180 degrees
+ var mz = Math.sin(angle);
+ angle = angle / 2.0; // x calculates degrees from 0 to 90
+ var mx = Math.cos(angle);
+
+ var diff = new cc.Vertex3F();
+ var tempVer = cc.p(0, 0);
+ tempVer.x = tempVer.y = 1;
+ var v0 = this.originalVertex(tempVer);
+ tempVer.x = tempVer.y = 0;
+ var v1 = this.originalVertex(tempVer);
+
+ var x0 = v0.x;
+ var x1 = v1.x;
+ var x;
+ var a, b, c, d;
+
+ if (x0 > x1) {
+ // Normal Grid
+ a = cc.p(0, 0);
+ b = cc.p(0, 1);
+ c = cc.p(1, 0);
+ d = cc.p(1, 1);
+ x = x0;
+ } else {
+ // Reversed Grid
+ c = cc.p(0, 0);
+ d = cc.p(0, 1);
+ a = cc.p(1, 0);
+ b = cc.p(1, 1);
+ x = x1;
+ }
+
+ diff.x = ( x - x * mx );
+ diff.z = Math.abs(parseFloat((x * mz) / 4.0));
+
+ // bottom-left
+ var v = this.originalVertex(a);
+ v.x = diff.x;
+ v.z += diff.z;
+ this.setVertex(a, v);
+
+ // upper-left
+ v = this.originalVertex(b);
+ v.x = diff.x;
+ v.z += diff.z;
+ this.setVertex(b, v);
+
+ // bottom-right
+ v = this.originalVertex(c);
+ v.x -= diff.x;
+ v.z -= diff.z;
+ this.setVertex(c, v);
+
+ // upper-right
+ v = this.originalVertex(d);
+ v.x -= diff.x;
+ v.z -= diff.z;
+ this.setVertex(d, v);
+ }
+});
+
+/**
+ * Create a Flip X 3D action with duration.
+ * Flip around.
+ * @function
+ * @param {Number} duration
+ * @return {cc.FlipX3D}
+ */
+cc.flipX3D = function (duration) {
+ return new cc.FlipX3D(duration);
+};
+
+/**
+ * Please use cc.flipX3D instead.
+ * Create a Flip X 3D action with duration.
+ * Flip around.
+ * @param {Number} duration
+ * @return {cc.FlipX3D}
+ * @static
+ * @deprecated since v3.0 Please use cc.flipX3D instead.
+ */
+cc.FlipX3D.create = cc.flipX3D;
+
+/**
+ * cc.FlipY3D action.
+ * Upside down.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.FlipX3D
+ * @param {Number} duration
+ */
+cc.FlipY3D = cc.FlipX3D.extend(/** @lends cc.FlipY3D# */{
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Create a flip Y 3d action with duration.
+ * @param {Number} duration
+ */
+ ctor: function(duration) {
+ if (duration !== undefined)
+ cc.GridAction.prototype.ctor.call(this, duration, cc.size(1, 1));
+ else cc.GridAction.prototype.ctor.call(this);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var angle = Math.PI * dt; // 180 degrees
+ var mz = Math.sin(angle);
+ angle = angle / 2.0; // x calculates degrees from 0 to 90
+ var my = Math.cos(angle);
+
+ var diff = new cc.Vertex3F();
+
+ var tempP = cc.p(0, 0);
+ tempP.x = tempP.y = 1;
+ var v0 = this.originalVertex(tempP);
+ tempP.x = tempP.y = 0;
+ var v1 = this.originalVertex(tempP);
+
+ var y0 = v0.y;
+ var y1 = v1.y;
+ var y;
+ var a, b, c, d;
+
+ if (y0 > y1) {
+ // Normal Grid
+ a = cc.p(0, 0);
+ b = cc.p(0, 1);
+ c = cc.p(1, 0);
+ d = cc.p(1, 1);
+ y = y0;
+ } else {
+ // Reversed Grid
+ b = cc.p(0, 0);
+ a = cc.p(0, 1);
+ d = cc.p(1, 0);
+ c = cc.p(1, 1);
+ y = y1;
+ }
+
+ diff.y = y - y * my;
+ diff.z = Math.abs(parseFloat(y * mz) / 4.0);
+
+ // bottom-left
+ var v = this.originalVertex(a);
+ v.y = diff.y;
+ v.z += diff.z;
+ this.setVertex(a, v);
+
+ // upper-left
+ v = this.originalVertex(b);
+ v.y -= diff.y;
+ v.z -= diff.z;
+ this.setVertex(b, v);
+
+ // bottom-right
+ v = this.originalVertex(c);
+ v.y = diff.y;
+ v.z += diff.z;
+ this.setVertex(c, v);
+
+ // upper-right
+ v = this.originalVertex(d);
+ v.y -= diff.y;
+ v.z -= diff.z;
+ this.setVertex(d, v);
+ }
+});
+
+/**
+ * Create a flip Y 3d action with duration.
+ * Upside down.
+ * @function
+ * @param {Number} duration
+ * @return {cc.FlipY3D}
+ */
+cc.flipY3D = function (duration) {
+ return new cc.FlipY3D(duration);
+};
+
+/**
+ * Please use cc.flipY3D instead.
+ * Create a flip Y 3d action with duration.
+ * @param {Number} duration
+ * @return {cc.FlipY3D}
+ * @static
+ * @deprecated since v3.0 Please use cc.flipY3D instead.
+ */
+cc.FlipY3D.create = cc.flipY3D;
+
+/**
+ * cc.Lens3D action.
+ * Upside down.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.Grid3DAction
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {cc.Point} position
+ * @param {Number} radius
+ */
+cc.Lens3D = cc.Grid3DAction.extend(/** @lends cc.Lens3D# */{
+ //lens center position
+ _position:null,
+ _radius:0,
+ //lens effect. Defaults to 0.7 - 0 means no effect, 1 is very strong effect
+ _lensEffect:0,
+ //lens is concave. (true = concave, false = convex) default is convex i.e. false
+ _concave:false,
+ _dirty:false,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * creates a lens 3d action with center position, radius.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {cc.Point} position
+ * @param {Number} radius
+ */
+ ctor:function (duration, gridSize, position, radius) {
+ cc.GridAction.prototype.ctor.call(this);
+
+ this._position = cc.p(0, 0);
+ radius !== undefined && this.initWithDuration(duration, gridSize, position, radius);
+ },
+
+ /**
+ * Get lens center position
+ * @return {Number}
+ */
+ getLensEffect:function () {
+ return this._lensEffect;
+ },
+
+ /**
+ * Set lens center position
+ * @param {Number} lensEffect
+ */
+ setLensEffect:function (lensEffect) {
+ this._lensEffect = lensEffect;
+ },
+
+ /**
+ * Set whether lens is concave
+ * @param {Boolean} concave
+ */
+ setConcave:function (concave) {
+ this._concave = concave;
+ },
+
+ /**
+ * get Position
+ * @return {cc.Point}
+ */
+ getPosition:function () {
+ return this._position;
+ },
+
+ /**
+ * set Position
+ * @param {cc.Point} position
+ */
+ setPosition:function (position) {
+ if (!cc.pointEqualToPoint(position, this._position)) {
+ this._position.x = position.x;
+ this._position.y = position.y;
+ this._dirty = true;
+ }
+ },
+
+ /**
+ * initializes the action with center position, radius, a grid size and duration
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {cc.Point} position
+ * @param {Number} radius
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, gridSize, position, radius) {
+ if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
+ this.setPosition(position);
+ this._radius = radius;
+ this._lensEffect = 0.7;
+ this._dirty = true;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ if (this._dirty) {
+ var locGridSizeWidth = this._gridSize.width, locGridSizeHeight = this._gridSize.height;
+ var locRadius = this._radius, locLensEffect = this._lensEffect;
+ var locPos = cc.p(0, 0);
+ var vect = cc.p(0, 0);
+ var v, r, l, new_r, pre_log;
+ for (var i = 0; i < locGridSizeWidth + 1; ++i) {
+ for (var j = 0; j < locGridSizeHeight + 1; ++j) {
+ locPos.x = i;
+ locPos.y = j;
+ v = this.originalVertex(locPos);
+ vect.x = this._position.x - v.x;
+ vect.y = this._position.y - v.y;
+ r = cc.pLength(vect);
+
+ if (r < locRadius) {
+ r = locRadius - r;
+ pre_log = r / locRadius;
+ if (pre_log === 0)
+ pre_log = 0.001;
+
+ l = Math.log(pre_log) * locLensEffect;
+ new_r = Math.exp(l) * locRadius;
+
+ r = cc.pLength(vect);
+ if (r > 0) {
+ vect.x = vect.x / r;
+ vect.y = vect.y / r;
+
+ vect.x = vect.x * new_r;
+ vect.y = vect.y * new_r;
+ v.z += cc.pLength(vect) * locLensEffect;
+ }
+ }
+ this.setVertex(locPos, v);
+ }
+ }
+ this._dirty = false;
+ }
+ }
+});
+
+/**
+ * creates a lens 3d action with center position, radius
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {cc.Point} position
+ * @param {Number} radius
+ * @return {cc.Lens3D}
+ */
+cc.lens3D = function (duration, gridSize, position, radius) {
+ return new cc.Lens3D(duration, gridSize, position, radius);
+};
+
+/**
+ * Please use cc.lens3D instead
+ * creates a lens 3d action with center position, radius
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {cc.Point} position
+ * @param {Number} radius
+ * @return {cc.Lens3D}
+ * @static
+ * @deprecated since v3.0 Please use cc.lens3D instead.
+ */
+cc.Lens3D.create = cc.lens3D;
+
+/**
+ * cc.Ripple3D action.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.Grid3DAction
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {cc.Point} position
+ * @param {Number} radius
+ * @param {Number} waves
+ * @param {Number} amplitude
+ */
+cc.Ripple3D = cc.Grid3DAction.extend(/** @lends cc.Ripple3D# */{
+ /* center position */
+ _position: null,
+ _radius: 0,
+ _waves: 0,
+ _amplitude: 0,
+ _amplitudeRate: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * creates a ripple 3d action with radius, number of waves, amplitude.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {cc.Point} position
+ * @param {Number} radius
+ * @param {Number} waves
+ * @param {Number} amplitude
+ */
+ ctor:function (duration, gridSize, position, radius, waves, amplitude) {
+ cc.GridAction.prototype.ctor.call(this);
+
+ this._position = cc.p(0, 0);
+ amplitude !== undefined && this.initWithDuration(duration, gridSize, position, radius, waves, amplitude);
+ },
+
+ /**
+ * get center position
+ * @return {cc.Point}
+ */
+ getPosition:function () {
+ return this._position;
+ },
+
+ /**
+ * set center position
+ * @param {cc.Point} position
+ */
+ setPosition:function (position) {
+ this._position.x = position.x;
+ this._position.y = position.y;
+ },
+
+ /**
+ * get Amplitude
+ * @return {Number}
+ */
+ getAmplitude:function () {
+ return this._amplitude;
+ },
+
+ /**
+ * set Amplitude
+ * @param {Number} amplitude
+ */
+ setAmplitude:function (amplitude) {
+ this._amplitude = amplitude;
+ },
+
+ /**
+ * get Amplitude rate
+ * @return {*}
+ */
+ getAmplitudeRate:function () {
+ return this._amplitudeRate;
+ },
+
+ /**
+ * get amplitude rate
+ * @param {Number} amplitudeRate
+ */
+ setAmplitudeRate:function (amplitudeRate) {
+ this._amplitudeRate = amplitudeRate;
+ },
+
+ /**
+ * initializes the action with radius, number of waves, amplitude, a grid size and duration
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {cc.Point} position
+ * @param {Number} radius
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, gridSize, position, radius, waves, amplitude) {
+ if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
+ this.setPosition(position);
+ this._radius = radius;
+ this._waves = waves;
+ this._amplitude = amplitude;
+ this._amplitudeRate = 1.0;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var locGridSizeWidth = this._gridSize.width, locGridSizeHeight = this._gridSize.height;
+ var locPos = cc.p(0, 0), locRadius = this._radius;
+ var locWaves = this._waves, locAmplitude = this._amplitude, locAmplitudeRate = this._amplitudeRate;
+ var v, r, tempPos = cc.p(0, 0);
+ for (var i = 0; i < (locGridSizeWidth + 1); ++i) {
+ for (var j = 0; j < (locGridSizeHeight + 1); ++j) {
+ locPos.x = i;
+ locPos.y = j;
+ v = this.originalVertex(locPos);
+
+ tempPos.x = this._position.x - v.x;
+ tempPos.y = this._position.y - v.y;
+ r = cc.pLength(tempPos);
+
+ if (r < locRadius) {
+ r = locRadius - r;
+ var rate = Math.pow(r / locRadius, 2);
+ v.z += (Math.sin(dt * Math.PI * locWaves * 2 + r * 0.1) * locAmplitude * locAmplitudeRate * rate);
+ }
+ this.setVertex(locPos, v);
+ }
+ }
+ }
+});
+
+/**
+ * creates a ripple 3d action with radius, number of waves, amplitude
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {cc.Point} position
+ * @param {Number} radius
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @return {cc.Ripple3D}
+ */
+cc.ripple3D = function (duration, gridSize, position, radius, waves, amplitude) {
+ return new cc.Ripple3D(duration, gridSize, position, radius, waves, amplitude);
+};
+
+/**
+ * Please use cc.ripple3D instead
+ * creates a ripple 3d action with radius, number of waves, amplitude
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {cc.Point} position
+ * @param {Number} radius
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @return {cc.Ripple3D}
+ * @static
+ * @deprecated since v3.0 Please use cc.ripple3D instead.
+ */
+cc.Ripple3D.create = cc.ripple3D;
+
+/**
+ * cc.Shaky3D action.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.Grid3DAction
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shakeZ
+ */
+cc.Shaky3D = cc.Grid3DAction.extend(/** @lends cc.Shaky3D# */{
+ _randRange: 0,
+ _shakeZ: false,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Create a shaky3d action with a range, shake Z vertices.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shakeZ
+ */
+ ctor:function (duration, gridSize, range, shakeZ) {
+ cc.GridAction.prototype.ctor.call(this);
+ shakeZ !== undefined && this.initWithDuration(duration, gridSize, range, shakeZ);
+ },
+
+ /**
+ * initializes the action with a range, shake Z vertices, a grid and duration
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shakeZ
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, gridSize, range, shakeZ) {
+ if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
+ this._randRange = range;
+ this._shakeZ = shakeZ;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var locGridSizeWidth = this._gridSize.width, locGridSizeHeight = this._gridSize.height;
+ var locRandRange = this._randRange, locShakeZ = this._shakeZ, locP = cc.p(0, 0);
+ var v;
+ for (var i = 0; i < (locGridSizeWidth + 1); ++i) {
+ for (var j = 0; j < (locGridSizeHeight + 1); ++j) {
+ locP.x = i;
+ locP.y = j;
+ v = this.originalVertex(locP);
+ v.x += (cc.rand() % (locRandRange * 2)) - locRandRange;
+ v.y += (cc.rand() % (locRandRange * 2)) - locRandRange;
+ if (locShakeZ)
+ v.z += (cc.rand() % (locRandRange * 2)) - locRandRange;
+ this.setVertex(locP, v);
+ }
+ }
+ }
+});
+
+/**
+ * creates the action with a range, shake Z vertices, a grid and duration
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shakeZ
+ * @return {cc.Shaky3D}
+ */
+cc.shaky3D = function (duration, gridSize, range, shakeZ) {
+ return new cc.Shaky3D(duration, gridSize, range, shakeZ);
+};
+
+/**
+ * Please use cc.shaky3D instead
+ * creates the action with a range, shake Z vertices, a grid and duration
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shakeZ
+ * @return {cc.Shaky3D}
+ * @static
+ * @deprecated since v3.0 Please use cc.shaky3D instead.
+ */
+cc.Shaky3D.create = cc.shaky3D;
+
+/**
+ * cc.Liquid action.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.Grid3DAction
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ */
+cc.Liquid = cc.Grid3DAction.extend(/** @lends cc.Liquid# */{
+ _waves: 0,
+ _amplitude: 0,
+ _amplitudeRate: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Create a liquid action with amplitude, a grid and duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ */
+ ctor: function (duration, gridSize, waves, amplitude) {
+ cc.GridAction.prototype.ctor.call(this);
+ amplitude !== undefined && this.initWithDuration(duration, gridSize, waves, amplitude);
+ },
+
+ /**
+ * get amplitude
+ * @return {Number}
+ */
+ getAmplitude:function () {
+ return this._amplitude;
+ },
+
+ /**
+ * set amplitude
+ * @param {Number} amplitude
+ */
+ setAmplitude:function (amplitude) {
+ this._amplitude = amplitude;
+ },
+
+ /**
+ * get amplitude rate
+ * @return {Number}
+ */
+ getAmplitudeRate:function () {
+ return this._amplitudeRate;
+ },
+
+ /**
+ * set amplitude rate
+ * @param {Number} amplitudeRate
+ */
+ setAmplitudeRate:function (amplitudeRate) {
+ this._amplitudeRate = amplitudeRate;
+ },
+
+ /**
+ * initializes the action with amplitude, a grid and duration
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, gridSize, waves, amplitude) {
+ if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
+ this._waves = waves;
+ this._amplitude = amplitude;
+ this._amplitudeRate = 1.0;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var locSizeWidth = this._gridSize.width, locSizeHeight = this._gridSize.height, locPos = cc.p(0, 0);
+ var locWaves = this._waves, locAmplitude = this._amplitude, locAmplitudeRate = this._amplitudeRate;
+ var v;
+ for (var i = 1; i < locSizeWidth; ++i) {
+ for (var j = 1; j < locSizeHeight; ++j) {
+ locPos.x = i;
+ locPos.y = j;
+ v = this.originalVertex(locPos);
+ v.x = (v.x + (Math.sin(dt * Math.PI * locWaves * 2 + v.x * .01) * locAmplitude * locAmplitudeRate));
+ v.y = (v.y + (Math.sin(dt * Math.PI * locWaves * 2 + v.y * .01) * locAmplitude * locAmplitudeRate));
+ this.setVertex(locPos, v);
+ }
+ }
+ }
+});
+
+/**
+ * creates the action with amplitude, a grid and duration
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @return {cc.Liquid}
+ */
+cc.liquid = function (duration, gridSize, waves, amplitude) {
+ return new cc.Liquid(duration, gridSize, waves, amplitude);
+};
+
+/**
+ * Please use cc.liquid instead
+ * creates the action with amplitude, a grid and duration
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @return {cc.Liquid}
+ * @static
+ * @deprecated since v3.0 Please use cc.liquid instead.
+ */
+cc.Liquid.create = cc.liquid;
+
+/**
+ * cc.Waves action.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.Grid3DAction
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @param {Boolean} horizontal
+ * @param {Boolean} vertical
+ */
+cc.Waves = cc.Grid3DAction.extend(/** @lends cc.Waves# */{
+ _waves: 0,
+ _amplitude: 0,
+ _amplitudeRate: 0,
+ _vertical: false,
+ _horizontal: false,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Create a wave action with amplitude, horizontal sin, vertical sin, a grid and duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @param {Boolean} horizontal
+ * @param {Boolean} vertical
+ */
+ ctor: function (duration, gridSize, waves, amplitude, horizontal, vertical) {
+ cc.GridAction.prototype.ctor.call(this);
+ vertical !== undefined && this.initWithDuration(duration, gridSize, waves, amplitude, horizontal, vertical);
+ },
+
+ /**
+ * get amplitude
+ * @return {Number}
+ */
+ getAmplitude:function () {
+ return this._amplitude;
+ },
+
+ /**
+ * set amplitude
+ * @param {Number} amplitude
+ */
+ setAmplitude:function (amplitude) {
+ this._amplitude = amplitude;
+ },
+
+ /**
+ * get amplitude rate
+ * @return {Number}
+ */
+ getAmplitudeRate:function () {
+ return this._amplitudeRate;
+ },
+
+ /**
+ * set amplitude rate
+ * @param {Number} amplitudeRate
+ */
+ setAmplitudeRate:function (amplitudeRate) {
+ this._amplitudeRate = amplitudeRate;
+ },
+
+ /**
+ * initializes the action with amplitude, horizontal sin, vertical sin, a grid and duration
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @param {Boolean} horizontal
+ * @param {Boolean} vertical
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, gridSize, waves, amplitude, horizontal, vertical) {
+ if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
+ this._waves = waves;
+ this._amplitude = amplitude;
+ this._amplitudeRate = 1.0;
+ this._horizontal = horizontal;
+ this._vertical = vertical;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var locSizeWidth = this._gridSize.width, locSizeHeight = this._gridSize.height, locPos = cc.p(0, 0);
+ var locVertical = this._vertical, locHorizontal = this._horizontal;
+ var locWaves = this._waves, locAmplitude = this._amplitude, locAmplitudeRate = this._amplitudeRate;
+ var v;
+ for (var i = 0; i < locSizeWidth + 1; ++i) {
+ for (var j = 0; j < locSizeHeight + 1; ++j) {
+ locPos.x = i;
+ locPos.y = j;
+ v = this.originalVertex(locPos);
+ if (locVertical)
+ v.x = (v.x + (Math.sin(dt * Math.PI * locWaves * 2 + v.y * .01) * locAmplitude * locAmplitudeRate));
+ if (locHorizontal)
+ v.y = (v.y + (Math.sin(dt * Math.PI * locWaves * 2 + v.x * .01) * locAmplitude * locAmplitudeRate));
+ this.setVertex(locPos, v);
+ }
+ }
+ }
+});
+
+/**
+ * initializes the action with amplitude, horizontal sin, vertical sin, a grid and duration
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @param {Boolean} horizontal
+ * @param {Boolean} vertical
+ * @return {cc.Waves}
+ */
+cc.waves = function (duration, gridSize, waves, amplitude, horizontal, vertical) {
+ return new cc.Waves(duration, gridSize, waves, amplitude, horizontal, vertical);
+};
+
+/**
+ * Please use cc.waves instead
+ * initializes the action with amplitude, horizontal sin, vertical sin, a grid and duration
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @param {Boolean} horizontal
+ * @param {Boolean} vertical
+ * @return {cc.Waves}
+ * @static
+ * @deprecated since v3.0 Please use cc.waves instead.
+ */
+cc.Waves.create = cc.waves;
+
+/** @brief */
+/**
+ * cc.Twirl action.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.Grid3DAction
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {cc.Point} position
+ * @param {Number} twirls
+ * @param {Number} amplitude
+ */
+cc.Twirl = cc.Grid3DAction.extend(/** @lends cc.Twirl# */{
+ /* twirl center */
+ _position: null,
+ _twirls: 0,
+ _amplitude: 0,
+ _amplitudeRate: 0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Create a grid 3d action with center position, number of twirls, amplitude, a grid size and duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {cc.Point} position
+ * @param {Number} twirls
+ * @param {Number} amplitude
+ */
+ ctor:function (duration, gridSize, position, twirls, amplitude) {
+ cc.GridAction.prototype.ctor.call(this);
+
+ this._position = cc.p(0, 0);
+ amplitude !== undefined && this.initWithDuration(duration, gridSize, position, twirls, amplitude);
+ },
+
+ /**
+ * get twirl center
+ * @return {cc.Point}
+ */
+ getPosition:function () {
+ return this._position;
+ },
+
+ /**
+ * set twirl center
+ * @param {cc.Point} position
+ */
+ setPosition:function (position) {
+ this._position.x = position.x;
+ this._position.y = position.y;
+ },
+
+ /**
+ * get amplitude
+ * @return {Number}
+ */
+ getAmplitude:function () {
+ return this._amplitude;
+ },
+
+ /**
+ * set amplitude
+ * @param {Number} amplitude
+ */
+ setAmplitude:function (amplitude) {
+ this._amplitude = amplitude;
+ },
+
+ /**
+ * get amplitude rate
+ * @return {Number}
+ */
+ getAmplitudeRate:function () {
+ return this._amplitudeRate;
+ },
+
+ /**
+ * set amplitude rate
+ * @param {Number} amplitudeRate
+ */
+ setAmplitudeRate:function (amplitudeRate) {
+ this._amplitudeRate = amplitudeRate;
+ },
+
+ /** initializes the action with center position, number of twirls, amplitude, a grid size and duration */
+ initWithDuration:function (duration, gridSize, position, twirls, amplitude) {
+ if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
+ this.setPosition(position);
+ this._twirls = twirls;
+ this._amplitude = amplitude;
+ this._amplitudeRate = 1.0;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ *
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var c = this._position;
+ var locSizeWidth = this._gridSize.width, locSizeHeight = this._gridSize.height, locPos = cc.p(0, 0);
+ var amp = 0.1 * this._amplitude * this._amplitudeRate;
+ var locTwirls = this._twirls;
+ var v, a, dX, dY, avg = cc.p(0, 0);
+ for (var i = 0; i < (locSizeWidth + 1); ++i) {
+ for (var j = 0; j < (locSizeHeight + 1); ++j) {
+ locPos.x = i;
+ locPos.y = j;
+ v = this.originalVertex(locPos);
+
+ avg.x = i - (locSizeWidth / 2.0);
+ avg.y = j - (locSizeHeight / 2.0);
+
+ a = cc.pLength(avg) * Math.cos(Math.PI / 2.0 + dt * Math.PI * locTwirls * 2) * amp;
+
+ dX = Math.sin(a) * (v.y - c.y) + Math.cos(a) * (v.x - c.x);
+ dY = Math.cos(a) * (v.y - c.y) - Math.sin(a) * (v.x - c.x);
+
+ v.x = c.x + dX;
+ v.y = c.y + dY;
+
+ this.setVertex(locPos, v);
+ }
+ }
+ }
+});
+
+/**
+ * creates the action with center position, number of twirls, amplitude, a grid size and duration
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {cc.Point} position
+ * @param {Number} twirls
+ * @param {Number} amplitude
+ * @return {cc.Twirl}
+ */
+cc.twirl = function (duration, gridSize, position, twirls, amplitude) {
+ return new cc.Twirl(duration, gridSize, position, twirls, amplitude);
+};
+
+/**
+ * Please use cc.twirl instead
+ * creates the action with center position, number of twirls, amplitude, a grid size and duration
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {cc.Point} position
+ * @param {Number} twirls
+ * @param {Number} amplitude
+ * @return {cc.Twirl}
+ * @static
+ * @deprecated since v3.0 Please use cc.twirl instead.
+ */
+cc.Twirl.create = cc.twirl;
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/actions3d/CCActionPageTurn3D.js b/frameworks/cocos2d-html5/cocos2d/actions3d/CCActionPageTurn3D.js
new file mode 100644
index 0000000..ae7313b
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/actions3d/CCActionPageTurn3D.js
@@ -0,0 +1,130 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ *
+ * This action simulates a page turn from the bottom right hand corner of the screen.
+ * It's not much use by itself but is used by the PageTurnTransition.
+ *
+ * Based on an original paper by L Hong et al.
+ * http://www.parc.com/publication/1638/turning-pages-of-3d-electronic-books.html
+ *
+ * @class
+ * @extends cc.Grid3DAction
+ */
+cc.PageTurn3D = cc.Grid3DAction.extend(/** @lends cc.PageTurn3D# */{
+ getGrid: function(){
+ var result = new cc.Grid3D(this._gridSize, undefined, undefined, this._gridNodeTarget.getGridRect());
+ result.setNeedDepthTestForBlit(true);
+ return result;
+ },
+
+ clone: function(){
+ var ret = new cc.PageTurn3D();
+ ret.initWithDuration(this._duration, this._gridSize);
+ return ret;
+ },
+
+ /**
+ * Update each tick
+ * Time is the percentage of the way through the duration
+ */
+ update:function (time) {
+ var tt = Math.max(0, time - 0.25);
+ var deltaAy = (tt * tt * 500);
+ var ay = -100 - deltaAy;
+
+ var deltaTheta = Math.sqrt(time);
+ var theta = deltaTheta>0.5?Math.PI/2 *deltaTheta : Math.PI/2*(1-deltaTheta);
+ var rotateByYAxis = (2-time)*Math.PI;
+
+ var sinTheta = Math.sin(theta);
+ var cosTheta = Math.cos(theta);
+
+ var locGridSize = this._gridSize;
+ var locVer = cc.p(0, 0);
+ for (var i = 0; i <= locGridSize.width; ++i) {
+ for (var j = 0; j <= locGridSize.height; ++j) {
+ locVer.x = i;
+ locVer.y = j;
+ // Get original vertex
+ var p = this.getOriginalVertex(locVer);
+
+ p.x -= this.getGridRect().x;
+ var R = Math.sqrt((p.x * p.x) + ((p.y - ay) * (p.y - ay)));
+ var r = R * sinTheta;
+ var alpha = Math.asin(p.x / R);
+ var beta = alpha / sinTheta;
+ var cosBeta = Math.cos(beta);
+
+ // If beta > PI then we've wrapped around the cone
+ // Reduce the radius to stop these points interfering with others
+ if (beta <= Math.PI)
+ p.x = ( r * Math.sin(beta));
+ else
+ p.x = 0; //Force X = 0 to stop wrapped points
+
+ p.y = ( R + ay - ( r * (1 - cosBeta) * sinTheta));
+
+ // We scale z here to avoid the animation being
+ // too much bigger than the screen due to perspectve transform
+ p.z = (r * ( 1 - cosBeta ) * cosTheta);// "100" didn't work for
+ p.x = p.z * Math.sin(rotateByYAxis) + p.x * Math.cos(rotateByYAxis);
+ p.z = p.z * Math.cos(rotateByYAxis) - p.x * Math.cos(rotateByYAxis);
+ p.z/= 7;
+ // Stop z coord from dropping beneath underlying page in a transition
+ // issue #751
+ if (p.z < 0.5)
+ p.z = 0.5;
+
+ // Set new coords
+ p.x+= this.getGridRect().x;
+ this.setVertex(locVer, p);
+ }
+ }
+ }
+});
+
+/**
+ * create PageTurn3D action
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @return {cc.PageTurn3D}
+ */
+cc.pageTurn3D = function (duration, gridSize) {
+ return new cc.PageTurn3D(duration, gridSize);
+};
+/**
+ * Please use cc.pageTurn3D instead
+ * create PageTurn3D action
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @return {cc.PageTurn3D}
+ * @static
+ * @deprecated since v3.0 please use cc.pageTurn3D instead.
+ */
+cc.PageTurn3D.create = cc.pageTurn3D;
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/actions3d/CCActionTiledGrid.js b/frameworks/cocos2d-html5/cocos2d/actions3d/CCActionTiledGrid.js
new file mode 100644
index 0000000..67dffc5
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/actions3d/CCActionTiledGrid.js
@@ -0,0 +1,1300 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.ShakyTiles3D action.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.TiledGrid3DAction
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shakeZ
+ */
+cc.ShakyTiles3D = cc.TiledGrid3DAction.extend(/** @lends cc.ShakyTiles3D# */{
+ _randRange:0,
+ _shakeZ:false,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Creates the action with a range, whether or not to shake Z vertices, a grid size, and duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shakeZ
+ */
+ ctor:function (duration, gridSize, range, shakeZ) {
+ cc.GridAction.prototype.ctor.call(this);
+ shakeZ !== undefined && this.initWithDuration(duration, gridSize, range, shakeZ);
+ },
+
+ /**
+ * Initializes the action with a range, whether or not to shake Z vertices, a grid size, and duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shakeZ
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, gridSize, range, shakeZ) {
+ if (cc.TiledGrid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
+ this._randRange = range;
+ this._shakeZ = shakeZ;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var locGridSize = this._gridSize, locRandRange = this._randRange;
+ var locPos = cc.p(0, 0);
+ for (var i = 0; i < locGridSize.width; ++i) {
+ for (var j = 0; j < locGridSize.height; ++j) {
+ locPos.x = i;
+ locPos.y = j;
+ var coords = this.originalTile(locPos);
+
+ // X
+ coords.bl.x += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.br.x += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.tl.x += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.tr.x += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+
+ // Y
+ coords.bl.y += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.br.y += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.tl.y += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.tr.y += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+
+ if (this._shakeZ) {
+ coords.bl.z += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.br.z += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.tl.z += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.tr.z += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ }
+
+ this.setTile(locPos, coords);
+ }
+ }
+ }
+});
+
+/**
+ * Creates the action with a range, whether or not to shake Z vertices, a grid size, and duration.
+ * Reference the test cases (Effects Test)
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shakeZ
+ * @return {cc.ShakyTiles3D}
+ */
+cc.shakyTiles3D = function (duration, gridSize, range, shakeZ) {
+ return new cc.ShakyTiles3D(duration, gridSize, range, shakeZ);
+};
+
+/**
+ * Please use cc.shakyTiles3D instead.
+ * creates the action with a range, whether or not to shake Z vertices, a grid size, and duration.
+ * Reference the test cases (Effects Test)
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shakeZ
+ * @return {cc.ShakyTiles3D}
+ * @static
+ * @deprecated since v3.0 Please use cc.shakyTiles3D instead.
+ */
+cc.ShakyTiles3D.create = cc.shakyTiles3D;
+
+/**
+ * cc.ShatteredTiles3D action.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.TiledGrid3DAction
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shatterZ
+ */
+cc.ShatteredTiles3D = cc.TiledGrid3DAction.extend(/** @lends cc.ShatteredTiles3D# */{
+ _randRange:0,
+ _once:false,
+ _shatterZ:false,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Creates the action with a range, whether of not to shatter Z vertices, a grid size and duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shatterZ
+ */
+ ctor:function (duration, gridSize, range, shatterZ) {
+ cc.GridAction.prototype.ctor.call(this);
+ shatterZ !== undefined && this.initWithDuration(duration, gridSize, range, shatterZ);
+ },
+
+ /**
+ * Initializes the action with a range, whether or not to shatter Z vertices, a grid size and duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shatterZ
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, gridSize, range, shatterZ) {
+ if (cc.TiledGrid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
+ this._once = false;
+ this._randRange = range;
+ this._shatterZ = shatterZ;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ if (this._once === false) {
+ var locGridSize = this._gridSize, locRandRange = this._randRange;
+ var coords, locPos = cc.p(0, 0);
+ for (var i = 0; i < locGridSize.width; ++i) {
+ for (var j = 0; j < locGridSize.height; ++j) {
+ locPos.x = i;
+ locPos.y = j;
+ coords = this.originalTile(locPos);
+
+ // X
+ coords.bl.x += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.br.x += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.tl.x += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.tr.x += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+
+ // Y
+ coords.bl.y += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.br.y += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.tl.y += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.tr.y += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+
+ if (this._shatterZ) {
+ coords.bl.z += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.br.z += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.tl.z += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ coords.tr.z += ( cc.rand() % (locRandRange * 2) ) - locRandRange;
+ }
+ this.setTile(locPos, coords);
+ }
+ }
+ this._once = true;
+ }
+ }
+});
+
+/**
+ * Creates the action with a range, whether of not to shatter Z vertices, a grid size and duration.
+ * Reference the test cases (Effects Test)
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shatterZ
+ * @return {cc.ShatteredTiles3D}
+ */
+cc.shatteredTiles3D = function (duration, gridSize, range, shatterZ) {
+ return new cc.ShatteredTiles3D(duration, gridSize, range, shatterZ);
+};
+
+/**
+ * Please use cc.shatteredTiles3D instead.
+ * Creates the action with a range, whether of not to shatter Z vertices, a grid size and duration.
+ * Reference the test cases (Effects Test)
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} range
+ * @param {Boolean} shatterZ
+ * @return {cc.ShatteredTiles3D}
+ * @static
+ * @deprecated since v3.0 Please use cc.shatteredTiles3D instead.
+ */
+cc.ShatteredTiles3D.create = cc.shatteredTiles3D;
+
+/**
+ * A Tile composed of position, startPosition and delta.
+ * @Class
+ * @constructor
+ * @param {cc.Point} [position=cc.p(0,0)]
+ * @param {cc.Point} [startPosition=cc.p(0,0)]
+ * @param {cc.Size} [delta=cc.p(0,0)]
+ */
+cc.Tile = function (position, startPosition, delta) {
+ this.position = position || cc.p(0,0);
+ this.startPosition = startPosition || cc.p(0,0);
+ this.delta = delta || cc.p(0,0);
+};
+
+/**
+ * cc.ShuffleTiles action, Shuffle the tiles in random order.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.TiledGrid3DAction
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} seed
+ */
+cc.ShuffleTiles = cc.TiledGrid3DAction.extend(/** @lends cc.ShuffleTiles# */{
+ _seed:0,
+ _tilesCount:0,
+ _tilesOrder:null,
+ _tiles:null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Creates the action with a random seed, the grid size and the duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} seed
+ */
+ ctor:function (duration, gridSize, seed) {
+ cc.GridAction.prototype.ctor.call(this);
+ this._tilesOrder = [];
+ this._tiles = [];
+
+ seed !== undefined && this.initWithDuration(duration, gridSize, seed);
+ },
+
+ /**
+ * Initializes the action with a random seed, the grid size and the duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} seed
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, gridSize, seed) {
+ if (cc.TiledGrid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
+ this._seed = seed;
+ this._tilesOrder.length = 0;
+ this._tiles.length = 0;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Shuffle
+ * @param {Array} array
+ * @param {Number} len
+ */
+ shuffle:function (array, len) {
+ for (var i = len - 1; i >= 0; i--) {
+ var j = 0 | (cc.rand() % (i + 1));
+ var v = array[i];
+ array[i] = array[j];
+ array[j] = v;
+ }
+ },
+
+ /**
+ * Get Delta
+ * @param {cc.Size} pos
+ */
+ getDelta:function (pos) {
+ var locGridSize = this._gridSize;
+ var idx = pos.width * locGridSize.height + pos.height;
+ return cc.size(((this._tilesOrder[idx] / locGridSize.height) - pos.width),
+ ((this._tilesOrder[idx] % locGridSize.height) - pos.height));
+ },
+
+ /**
+ * Place Tile
+ * @param {cc.Point} pos
+ * @param {cc.Tile} tile
+ */
+ placeTile:function (pos, tile) {
+ var coords = this.originalTile(pos);
+
+ var step = this.target.grid.getStep();
+ var locPosition = tile.position;
+ coords.bl.x += (locPosition.x * step.x);
+ coords.bl.y += (locPosition.y * step.y);
+
+ coords.br.x += (locPosition.x * step.x);
+ coords.br.y += (locPosition.y * step.y);
+
+ coords.tl.x += (locPosition.x * step.x);
+ coords.tl.y += (locPosition.y * step.y);
+
+ coords.tr.x += (locPosition.x * step.x);
+ coords.tr.y += (locPosition.y * step.y);
+
+ this.setTile(pos, coords);
+ },
+
+ /**
+ * Start with target
+ * @param {cc.Node} target
+ */
+ startWithTarget:function (target) {
+ cc.TiledGrid3DAction.prototype.startWithTarget.call(this, target);
+ var locGridSize = this._gridSize;
+
+ this._tilesCount = locGridSize.width * locGridSize.height;
+ var locTilesOrder = this._tilesOrder;
+ locTilesOrder.length = 0;
+
+ /**
+ * Use k to loop. Because m_nTilesCount is unsigned int,
+ * and i is used later for int.
+ */
+ for (var k = 0; k < this._tilesCount; ++k)
+ locTilesOrder[k] = k;
+ this.shuffle(locTilesOrder, this._tilesCount);
+
+ var locTiles = this._tiles ;
+ locTiles.length = 0;
+ var tileIndex = 0, tempSize = cc.size(0,0);
+ for (var i = 0; i < locGridSize.width; ++i) {
+ for (var j = 0; j < locGridSize.height; ++j) {
+ locTiles[tileIndex] = new cc.Tile();
+ locTiles[tileIndex].position = cc.p(i, j);
+ locTiles[tileIndex].startPosition = cc.p(i, j);
+ tempSize.width = i;
+ tempSize.height = j;
+ locTiles[tileIndex].delta = this.getDelta(tempSize);
+ ++tileIndex;
+ }
+ }
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var tileIndex = 0, locGridSize = this._gridSize, locTiles = this._tiles;
+ var selTile, locPos = cc.p(0, 0);
+ for (var i = 0; i < locGridSize.width; ++i) {
+ for (var j = 0; j < locGridSize.height; ++j) {
+ locPos.x = i;
+ locPos.y = j;
+ selTile = locTiles[tileIndex];
+ selTile.position.x = selTile.delta.width * dt;
+ selTile.position.y = selTile.delta.height * dt;
+ this.placeTile(locPos, selTile);
+ ++tileIndex;
+ }
+ }
+ }
+});
+
+/**
+ * Creates the action with a random seed, the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} seed
+ * @return {cc.ShuffleTiles}
+ */
+cc.shuffleTiles = function (duration, gridSize, seed) {
+ return new cc.ShuffleTiles(duration, gridSize, seed);
+};
+
+/**
+ * Please use cc.shuffleTiles instead.
+ * Creates the action with a random seed, the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} seed
+ * @return {cc.ShuffleTiles}
+ * @static
+ * @deprecated since v3.0 Please use cc.shuffleTiles instead.
+ */
+cc.ShuffleTiles.create = cc.shuffleTiles;
+
+/**
+ * cc.FadeOutTRTiles action. Fades out the tiles in a Top-Right direction.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.TiledGrid3DAction
+ */
+cc.FadeOutTRTiles = cc.TiledGrid3DAction.extend(/** @lends cc.FadeOutTRTiles# */{
+ /**
+ * Test function
+ * @param {cc.Point} pos
+ * @param {Number} time
+ */
+ testFunc:function (pos, time) {
+ var locX = this._gridSize.width * time;
+ var locY = this._gridSize.height * time;
+ if (locX === this._gridSize.width && locY === this._gridSize.height) return 0.0;
+ if ((locX + locY) === 0.0)
+ return 1.0;
+ return Math.pow((pos.x + pos.y) / (locX + locY), 6);
+ },
+
+ /**
+ * Turn on Tile
+ * @param {cc.Point} pos
+ */
+ turnOnTile:function (pos) {
+ this.setTile(pos, this.originalTile(pos));
+ },
+
+ /**
+ * Turn Off Tile
+ * @param {cc.Point} pos
+ */
+ turnOffTile:function (pos) {
+ this.setTile(pos, new cc.Quad3());
+ },
+
+ /**
+ * Transform tile
+ * @param {cc.Point} pos
+ * @param {Number} distance
+ */
+ transformTile:function (pos, distance) {
+ var coords = this.originalTile(pos);
+ var step = this.target.grid.getStep();
+
+ coords.bl.x += (step.x / 2) * (1.0 - distance);
+ coords.bl.y += (step.y / 2) * (1.0 - distance);
+
+ coords.br.x -= (step.x / 2) * (1.0 - distance);
+ coords.br.y += (step.y / 2) * (1.0 - distance);
+
+ coords.tl.x += (step.x / 2) * (1.0 - distance);
+ coords.tl.y -= (step.y / 2) * (1.0 - distance);
+
+ coords.tr.x -= (step.x / 2) * (1.0 - distance);
+ coords.tr.y -= (step.y / 2) * (1.0 - distance);
+
+ this.setTile(pos, coords);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var locGridSize = this._gridSize;
+ var locPos = cc.p(0, 0), distance;
+ for (var i = 0; i < locGridSize.width; ++i) {
+ for (var j = 0; j < locGridSize.height; ++j) {
+ locPos.x = i;
+ locPos.y = j;
+ distance = this.testFunc(locPos, dt);
+ if (distance === 0)
+ this.turnOffTile(locPos);
+ else if (distance < 1)
+ this.transformTile(locPos, distance);
+ else
+ this.turnOnTile(locPos);
+ }
+ }
+ }
+});
+
+/**
+ * Creates the action with the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @function
+ * @param duration
+ * @param gridSize
+ * @return {cc.FadeOutTRTiles}
+ */
+cc.fadeOutTRTiles = function (duration, gridSize) {
+ return new cc.FadeOutTRTiles(duration, gridSize);
+};
+
+/**
+ * Please use cc.fadeOutTRTiles instead.
+ * Creates the action with the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @param duration
+ * @param gridSize
+ * @return {cc.FadeOutTRTiles}
+ * @static
+ * @deprecated since v3.0 Please use cc.fadeOutTRTiles instead.
+ */
+cc.FadeOutTRTiles.create = cc.fadeOutTRTiles;
+
+/**
+ * cc.FadeOutBLTiles action. Fades out the tiles in a Bottom-Left direction.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.FadeOutTRTiles
+ */
+cc.FadeOutBLTiles = cc.FadeOutTRTiles.extend(/** @lends cc.FadeOutBLTiles# */{
+ /**
+ * Test function
+ * @param {cc.Point} pos
+ * @param {Number} time
+ */
+ testFunc:function (pos, time) {
+ var locX = this._gridSize.width * (1.0 - time);
+ var locY = this._gridSize.height * (1.0 - time);
+ if ((locX + locY) === 0)
+ return 0.0;
+ if ((pos.x + pos.y) === 0)
+ return 1.0;
+
+ return Math.pow((locX + locY) / (pos.x + pos.y), 6);
+ }
+});
+
+/**
+ * Creates the action with the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @function
+ * @param duration
+ * @param gridSize
+ * @return {cc.FadeOutBLTiles}
+ */
+cc.fadeOutBLTiles = function (duration, gridSize) {
+ return new cc.FadeOutBLTiles(duration, gridSize);
+};
+
+/**
+ * Please use cc.fadeOutBLTiles instead.
+ * Creates the action with the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @param duration
+ * @param gridSize
+ * @return {cc.FadeOutBLTiles}
+ * @static
+ * @deprecated since v3.0 Please use cc.fadeOutBLTiles instead.
+ */
+cc.FadeOutBLTiles.create = cc.fadeOutBLTiles;
+
+/**
+ * cc.FadeOutUpTiles action. Fades out the tiles in upwards direction.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.FadeOutTRTiles
+ */
+cc.FadeOutUpTiles = cc.FadeOutTRTiles.extend(/** @lends cc.FadeOutUpTiles# */{
+ /**
+ * Test function
+ * @param {cc.Point} pos
+ * @param {Number} time
+ */
+ testFunc:function (pos, time) {
+ var locY = this._gridSize.height * time;
+ if( locY === this._gridSize.height) return 0.0;
+ if (locY === 0.0) return 1.0;
+ return Math.pow(pos.y / locY, 6);
+ },
+
+ transformTile:function (pos, distance) {
+ var coords = this.originalTile(pos);
+ var step = this.target.grid.getStep();
+
+ coords.bl.y += (step.y / 2) * (1.0 - distance);
+ coords.br.y += (step.y / 2) * (1.0 - distance);
+ coords.tl.y -= (step.y / 2) * (1.0 - distance);
+ coords.tr.y -= (step.y / 2) * (1.0 - distance);
+
+ this.setTile(pos, coords);
+ }
+});
+
+/**
+ * Creates the action with the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @return {cc.FadeOutUpTiles}
+ */
+cc.fadeOutUpTiles = function (duration, gridSize) {
+ return new cc.FadeOutUpTiles(duration, gridSize);
+};
+
+/**
+ * Please use cc.fadeOutUpTiles instead.
+ * Creates the action with the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @return {cc.FadeOutUpTiles}
+ * @static
+ * @deprecated since v3.0 Please use cc.fadeOutUpTiles instead.
+ */
+cc.FadeOutUpTiles.create = cc.fadeOutUpTiles;
+
+/**
+ * cc.FadeOutDownTiles action. Fades out the tiles in downwards direction.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.FadeOutUpTiles
+ */
+cc.FadeOutDownTiles = cc.FadeOutUpTiles.extend(/** @lends cc.FadeOutDownTiles# */{
+ /**
+ * Test function
+ * @param {cc.Point} pos
+ * @param {Number} time
+ */
+ testFunc:function (pos, time) {
+ var locY = this._gridSize.height * (1.0 - time);
+ if( locY === 0.0 ) return 0.0;
+ if (pos.y === 0) return 1.0;
+ return Math.pow(locY / pos.y, 6);
+ }
+});
+
+/**
+ * Creates the action with the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @return {cc.FadeOutDownTiles}
+ */
+cc.fadeOutDownTiles = function (duration, gridSize) {
+ return new cc.FadeOutDownTiles(duration, gridSize);
+};
+/**
+ * Please use cc.fadeOutDownTiles instead.
+ * Creates the action with the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @return {cc.FadeOutDownTiles}
+ * @static
+ * @deprecated since v3.0 Please use cc.fadeOutDownTiles instead.
+ */
+cc.FadeOutDownTiles.create = cc.fadeOutDownTiles;
+
+/**
+ * cc.TurnOffTiles action.
+ * Turn off the files in random order.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.TiledGrid3DAction
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number|Null} [seed=0]
+ * @example
+ * // turnOffTiles without seed
+ * var toff = new cc.TurnOffTiles(this._duration, cc.size(x, y));
+ *
+ * // turnOffTiles with seed
+ * var toff = new cc.TurnOffTiles(this._duration, cc.size(x, y), 0);
+ */
+cc.TurnOffTiles = cc.TiledGrid3DAction.extend(/** @lends cc.TurnOffTiles# */{
+ _seed:null,
+ _tilesCount:0,
+ _tilesOrder:null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Creates the action with a random seed, the grid size and the duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number|Null} [seed=0]
+ */
+ ctor:function (duration, gridSize, seed) {
+ cc.GridAction.prototype.ctor.call(this);
+ this._tilesOrder = [];
+
+ gridSize !== undefined && this.initWithDuration(duration, gridSize, seed);
+ },
+
+ /**
+ * Initializes the action with a random seed, the grid size and the duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number|Null} [seed=0]
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, gridSize, seed) {
+ if (cc.TiledGrid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
+ this._seed = seed || 0;
+ this._tilesOrder.length = 0;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Shuffle
+ * @param {Array} array
+ * @param {Number} len
+ */
+ shuffle:function (array, len) {
+ for (var i = len - 1; i >= 0; i--) {
+ var j = 0 | (cc.rand() % (i + 1));
+ var v = array[i];
+ array[i] = array[j];
+ array[j] = v;
+ }
+ },
+
+ /**
+ * Turn on tile.
+ * @param {cc.Point} pos
+ */
+ turnOnTile:function (pos) {
+ this.setTile(pos, this.originalTile(pos));
+ },
+
+ /**
+ * Turn off title.
+ * @param {cc.Point} pos
+ */
+ turnOffTile:function (pos) {
+ this.setTile(pos, new cc.Quad3());
+ },
+
+ /**
+ * called before the action start. It will also set the target.
+ * @param {cc.Node} target
+ */
+ startWithTarget:function (target) {
+ cc.TiledGrid3DAction.prototype.startWithTarget.call(this, target);
+
+ this._tilesCount = this._gridSize.width * this._gridSize.height;
+ var locTilesOrder = this._tilesOrder;
+ locTilesOrder.length = 0;
+ for (var i = 0; i < this._tilesCount; ++i)
+ locTilesOrder[i] = i;
+ this.shuffle(locTilesOrder, this._tilesCount);
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var l = 0 | (dt * this._tilesCount), locGridSize = this._gridSize;
+ var t,tilePos = cc.p(0,0), locTilesOrder = this._tilesOrder;
+ for (var i = 0; i < this._tilesCount; i++) {
+ t = locTilesOrder[i];
+ tilePos.x = 0 | (t / locGridSize.height);
+ tilePos.y = t % (0 | locGridSize.height);
+ if (i < l)
+ this.turnOffTile(tilePos);
+ else
+ this.turnOnTile(tilePos);
+ }
+ }
+});
+
+/**
+ * Creates the action with a random seed, the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number|Null} [seed=0]
+ * @return {cc.TurnOffTiles}
+ * @example
+ * // example
+ * // turnOffTiles without seed
+ * var toff = cc.turnOffTiles(this._duration, cc.size(x, y));
+ *
+ * // turnOffTiles with seed
+ * var toff = cc.turnOffTiles(this._duration, cc.size(x, y), 0);
+ */
+cc.turnOffTiles = function (duration, gridSize, seed) {
+ return new cc.TurnOffTiles(duration, gridSize, seed);
+};
+/**
+ * Please use cc.turnOffTiles instead.
+ * Creates the action with a random seed, the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number|Null} [seed=0]
+ * @return {cc.TurnOffTiles}
+ * @static
+ * @deprecated since v3.0 Please use cc.turnOffTiles instead.
+ */
+cc.TurnOffTiles.create = cc.turnOffTiles;
+
+/**
+ * cc.WavesTiles3D action.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.TiledGrid3DAction
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ */
+cc.WavesTiles3D = cc.TiledGrid3DAction.extend(/** @lends cc.WavesTiles3D# */{
+ _waves:0,
+ _amplitude:0,
+ _amplitudeRate:0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * creates the action with a number of waves, the waves amplitude, the grid size and the duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ */
+ ctor:function (duration, gridSize, waves, amplitude) {
+ cc.GridAction.prototype.ctor.call(this);
+ amplitude !== undefined && this.initWithDuration(duration, gridSize, waves, amplitude);
+ },
+
+ /**
+ * get amplitude of waves
+ * @return {Number}
+ */
+ getAmplitude:function () {
+ return this._amplitude;
+ },
+
+ /**
+ * set amplitude of waves
+ * @param {Number} amplitude
+ */
+ setAmplitude:function (amplitude) {
+ this._amplitude = amplitude;
+ },
+
+ /**
+ * get amplitude rate of waves
+ * @return {Number}
+ */
+ getAmplitudeRate:function () {
+ return this._amplitudeRate;
+ },
+
+ /**
+ * set amplitude rate of waves
+ * @param {Number} amplitudeRate
+ */
+ setAmplitudeRate:function (amplitudeRate) {
+ this._amplitudeRate = amplitudeRate;
+ },
+
+ /**
+ * initializes the action with a number of waves, the waves amplitude, the grid size and the duration
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, gridSize, waves, amplitude) {
+ if (cc.TiledGrid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
+ this._waves = waves;
+ this._amplitude = amplitude;
+ this._amplitudeRate = 1.0;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var locGridSize = this._gridSize, locWaves = this._waves, locAmplitude = this._amplitude, locAmplitudeRate = this._amplitudeRate;
+ var locPos = cc.p(0, 0), coords;
+ for (var i = 0; i < locGridSize.width; i++) {
+ for (var j = 0; j < locGridSize.height; j++) {
+ locPos.x = i;
+ locPos.y = j;
+ coords = this.originalTile(locPos);
+ coords.bl.z = (Math.sin(dt * Math.PI * locWaves * 2 +
+ (coords.bl.y + coords.bl.x) * 0.01) * locAmplitude * locAmplitudeRate);
+ coords.br.z = coords.bl.z;
+ coords.tl.z = coords.bl.z;
+ coords.tr.z = coords.bl.z;
+ this.setTile(locPos, coords);
+ }
+ }
+ }
+});
+
+/**
+ * creates the action with a number of waves, the waves amplitude, the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @return {cc.WavesTiles3D}
+ */
+cc.wavesTiles3D = function (duration, gridSize, waves, amplitude) {
+ return new cc.WavesTiles3D(duration, gridSize, waves, amplitude);
+};
+/**
+ * Please use cc.wavesTiles3D instead
+ * creates the action with a number of waves, the waves amplitude, the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} waves
+ * @param {Number} amplitude
+ * @return {cc.WavesTiles3D}
+ * @static
+ * @deprecated since v3.0 Please use cc.wavesTiles3D instead.
+ */
+cc.WavesTiles3D.create = cc.wavesTiles3D;
+
+/**
+ * cc.JumpTiles3D action. A sin function is executed to move the tiles across the Z axis.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.TiledGrid3DAction
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} numberOfJumps
+ * @param {Number} amplitude
+ */
+cc.JumpTiles3D = cc.TiledGrid3DAction.extend(/** @lends cc.JumpTiles3D# */{
+ _jumps:0,
+ _amplitude:0,
+ _amplitudeRate:0,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * creates the action with the number of jumps, the sin amplitude, the grid size and the duration.
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} numberOfJumps
+ * @param {Number} amplitude
+ */
+ ctor:function (duration, gridSize, numberOfJumps, amplitude) {
+ cc.GridAction.prototype.ctor.call(this);
+ amplitude !== undefined && this.initWithDuration(duration, gridSize, numberOfJumps, amplitude);
+ },
+
+ /**
+ * get amplitude of the sin
+ * @return {Number}
+ */
+ getAmplitude:function () {
+ return this._amplitude;
+ },
+
+ /**
+ * set amplitude of the sin
+ * @param {Number} amplitude
+ */
+ setAmplitude:function (amplitude) {
+ this._amplitude = amplitude;
+ },
+
+ /**
+ * get amplitude rate
+ * @return {Number}
+ */
+ getAmplitudeRate:function () {
+ return this._amplitudeRate;
+ },
+
+ /**
+ * set amplitude rate
+ * @param amplitudeRate
+ */
+ setAmplitudeRate:function (amplitudeRate) {
+ this._amplitudeRate = amplitudeRate;
+ },
+
+ /**
+ * initializes the action with the number of jumps, the sin amplitude, the grid size and the duration
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} numberOfJumps
+ * @param {Number} amplitude
+ */
+ initWithDuration:function (duration, gridSize, numberOfJumps, amplitude) {
+ if (cc.TiledGrid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
+ this._jumps = numberOfJumps;
+ this._amplitude = amplitude;
+ this._amplitudeRate = 1.0;
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var sinz = (Math.sin(Math.PI * dt * this._jumps * 2) * this._amplitude * this._amplitudeRate );
+ var sinz2 = (Math.sin(Math.PI * (dt * this._jumps * 2 + 1)) * this._amplitude * this._amplitudeRate );
+
+ var locGridSize = this._gridSize;
+ var locGrid = this.target.grid;
+ var coords, locPos = cc.p(0, 0);
+ for (var i = 0; i < locGridSize.width; i++) {
+ for (var j = 0; j < locGridSize.height; j++) {
+ locPos.x = i;
+ locPos.y = j;
+ //hack for html5
+ //var coords = this.originalTile(cc.p(i, j));
+ coords = locGrid.originalTile(locPos);
+
+ if (((i + j) % 2) === 0) {
+ coords.bl.z += sinz;
+ coords.br.z += sinz;
+ coords.tl.z += sinz;
+ coords.tr.z += sinz;
+ } else {
+ coords.bl.z += sinz2;
+ coords.br.z += sinz2;
+ coords.tl.z += sinz2;
+ coords.tr.z += sinz2;
+ }
+ //hack for html5
+ //this.setTile(cc.p(i, j), coords);
+ locGrid.setTile(locPos, coords);
+ }
+ }
+ }
+});
+
+/**
+ * creates the action with the number of jumps, the sin amplitude, the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @function
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} numberOfJumps
+ * @param {Number} amplitude
+ * @return {cc.JumpTiles3D}
+ */
+cc.jumpTiles3D = function (duration, gridSize, numberOfJumps, amplitude) {
+ return new cc.JumpTiles3D(duration, gridSize, numberOfJumps, amplitude);
+};
+
+/**
+ * Please use cc.jumpTiles3D instead
+ * creates the action with the number of jumps, the sin amplitude, the grid size and the duration.
+ * Reference the test cases (Effects Test)
+ * @param {Number} duration
+ * @param {cc.Size} gridSize
+ * @param {Number} numberOfJumps
+ * @param {Number} amplitude
+ * @return {cc.JumpTiles3D}
+ * @static
+ * @deprecated since v3.0 Please use cc.jumpTiles3D instead.
+ */
+cc.JumpTiles3D.create = cc.jumpTiles3D;
+
+/**
+ * cc.SplitRows action.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.TiledGrid3DAction
+ * @param {Number} duration
+ * @param {Number} rows
+ */
+cc.SplitRows = cc.TiledGrid3DAction.extend(/** @lends cc.SplitRows# */{
+ _rows:0,
+ _winSize:null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * creates the action with the number of rows to split and the duration.
+ * @param {Number} duration
+ * @param {Number} rows
+ */
+ ctor:function (duration, rows) {
+ cc.GridAction.prototype.ctor.call(this);
+ rows !== undefined && this.initWithDuration(duration, rows);
+ },
+
+ /**
+ * initializes the action with the number of rows to split and the duration
+ * @param {Number} duration
+ * @param {Number} rows
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, rows) {
+ this._rows = rows;
+ return cc.TiledGrid3DAction.prototype.initWithDuration.call(this, duration, cc.size(1, rows));
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var locGridSize = this._gridSize, locWinSizeWidth = this._winSize.width;
+ var coords, direction, locPos = cc.p(0, 0);
+ for (var j = 0; j < locGridSize.height; ++j) {
+ locPos.y = j;
+ coords = this.originalTile(locPos);
+ direction = 1;
+
+ if ((j % 2 ) === 0)
+ direction = -1;
+
+ coords.bl.x += direction * locWinSizeWidth * dt;
+ coords.br.x += direction * locWinSizeWidth * dt;
+ coords.tl.x += direction * locWinSizeWidth * dt;
+ coords.tr.x += direction * locWinSizeWidth * dt;
+
+ this.setTile(locPos, coords);
+ }
+ },
+
+ /**
+ * called before the action start. It will also set the target.
+ * @param {cc.Node} target
+ */
+ startWithTarget:function (target) {
+ cc.TiledGrid3DAction.prototype.startWithTarget.call(this, target);
+ this._winSize = cc.director.getWinSizeInPixels();
+ }
+});
+
+/**
+ * creates the action with the number of rows to split and the duration.
+ * Reference the test cases (Effects Test)
+ * @function
+ * @param {Number} duration
+ * @param {Number} rows
+ * @return {cc.SplitRows}
+ */
+cc.splitRows = function (duration, rows) {
+ return new cc.SplitRows(duration, rows);
+};
+
+/**
+ * Please use cc.splitRows instead
+ * creates the action with the number of rows to split and the duration.
+ * Reference the test cases (Effects Test)
+ * @param {Number} duration
+ * @param {Number} rows
+ * @return {cc.SplitRows}
+ * @static
+ * @deprecated since v3.0 Please use cc.splitRows instead.
+ */
+cc.SplitRows.create = cc.splitRows;
+
+/**
+ * cc.SplitCols action.
+ * Reference the test cases (Effects Test)
+ * @class
+ * @extends cc.TiledGrid3DAction
+ * @param {Number} duration
+ * @param {Number} cols
+ */
+cc.SplitCols = cc.TiledGrid3DAction.extend(/** @lends cc.SplitCols# */{
+ _cols:0,
+ _winSize:null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Creates the action with the number of columns to split and the duration.
+ * @param {Number} duration
+ * @param {Number} cols
+ */
+ ctor:function (duration, cols) {
+ cc.GridAction.prototype.ctor.call(this);
+ cols !== undefined && this.initWithDuration(duration, cols);
+ },
+ /**
+ * initializes the action with the number of columns to split and the duration
+ * @param {Number} duration
+ * @param {Number} cols
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, cols) {
+ this._cols = cols;
+ return cc.TiledGrid3DAction.prototype.initWithDuration.call(this, duration, cc.size(cols, 1));
+ },
+
+ /**
+ * Called once per frame. Time is the number of seconds of a frame interval.
+ * @param {Number} dt
+ */
+ update:function (dt) {
+ var locGridSizeWidth = this._gridSize.width, locWinSizeHeight = this._winSize.height;
+ var coords, direction, locPos = cc.p(0, 0);
+ for (var i = 0; i < locGridSizeWidth; ++i) {
+ locPos.x = i;
+ coords = this.originalTile(locPos);
+ direction = 1;
+
+ if ((i % 2 ) === 0)
+ direction = -1;
+
+ coords.bl.y += direction * locWinSizeHeight * dt;
+ coords.br.y += direction * locWinSizeHeight * dt;
+ coords.tl.y += direction * locWinSizeHeight * dt;
+ coords.tr.y += direction * locWinSizeHeight * dt;
+
+ this.setTile(locPos, coords);
+ }
+ cc.renderer.childrenOrderDirty = true;
+ },
+
+ /**
+ * called before the action start. It will also set the target.
+ * @param {cc.Node} target
+ */
+ startWithTarget:function (target) {
+ cc.TiledGrid3DAction.prototype.startWithTarget.call(this, target);
+ this._winSize = cc.director.getWinSizeInPixels();
+ }
+});
+
+/**
+ * creates the action with the number of columns to split and the duration.
+ * Reference the test cases (Effects Test)
+ * @function
+ * @param {Number} duration
+ * @param {Number} cols
+ * @return {cc.SplitCols}
+ */
+cc.splitCols = function (duration, cols) {
+ return new cc.SplitCols(duration, cols);
+};
+
+/**
+ * Please use cc.splitCols instead.
+ * creates the action with the number of columns to split and the duration.
+ * Reference the test cases (Effects Test)
+ * @param {Number} duration
+ * @param {Number} cols
+ * @return {cc.SplitCols}
+ * @static
+ * @deprecated since v3.0 Please use cc.splitCols instead.
+ */
+cc.SplitCols.create = cc.splitCols;
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/audio/CCAudio.js b/frameworks/cocos2d-html5/cocos2d/audio/CCAudio.js
new file mode 100644
index 0000000..7762bf4
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/audio/CCAudio.js
@@ -0,0 +1,941 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Audio support in the browser
+ *
+ * MULTI_CHANNEL : Multiple audio while playing - If it doesn't, you can only play background music
+ * WEB_AUDIO : Support for WebAudio - Support W3C WebAudio standards, all of the audio can be played
+ * AUTOPLAY : Supports auto-play audio - if Don‘t support it, On a touch detecting background music canvas, and then replay
+ * REPLAY_AFTER_TOUCH : The first music will fail, must be replay after touchstart
+ * USE_EMPTIED_EVENT : Whether to use the emptied event to replace load callback
+ * DELAY_CREATE_CTX : delay created the context object - only webAudio
+ * NEED_MANUAL_LOOP : loop attribute failure, need to perform loop manually
+ *
+ * May be modifications for a few browser version
+ */
+(function () {
+
+ var DEBUG = false;
+
+ var sys = cc.sys;
+ var version = sys.browserVersion;
+
+ // check if browser supports Web Audio
+ // check Web Audio's context
+ var supportWebAudio = !!(window.AudioContext || window.webkitAudioContext || window.mozAudioContext);
+
+ var support = {ONLY_ONE: false, WEB_AUDIO: supportWebAudio, DELAY_CREATE_CTX: false, ONE_SOURCE: false};
+
+ if (sys.browserType === sys.BROWSER_TYPE_FIREFOX) {
+ support.DELAY_CREATE_CTX = true;
+ support.USE_LOADER_EVENT = 'canplay';
+ }
+
+ if (sys.os === sys.OS_IOS) {
+ support.USE_LOADER_EVENT = 'loadedmetadata';
+ }
+
+ if (sys.os === sys.OS_ANDROID) {
+ if (sys.browserType === sys.BROWSER_TYPE_UC) {
+ support.ONE_SOURCE = true;
+ }
+ }
+
+ window.__audioSupport = support;
+
+ if (DEBUG) {
+ setTimeout(function () {
+ cc.log("browse type: " + sys.browserType);
+ cc.log("browse version: " + version);
+ cc.log("MULTI_CHANNEL: " + window.__audioSupport.MULTI_CHANNEL);
+ cc.log("WEB_AUDIO: " + window.__audioSupport.WEB_AUDIO);
+ cc.log("AUTOPLAY: " + window.__audioSupport.AUTOPLAY);
+ }, 0);
+ }
+
+})();
+
+/**
+ * Encapsulate DOM and webAudio
+ */
+cc.Audio = cc.Class.extend({
+ interruptPlay: false,
+ src: null,
+ _element: null,
+ _AUDIO_TYPE: "AUDIO",
+
+ ctor: function (url) {
+ this.src = url;
+ },
+
+ setBuffer: function (buffer) {
+ this._AUDIO_TYPE = "WEBAUDIO";
+ this._element = new cc.Audio.WebAudio(buffer);
+ },
+
+ setElement: function (element) {
+ this._AUDIO_TYPE = "AUDIO";
+ this._element = element;
+
+ // Prevent partial browser from playing after the end does not reset the paused tag
+ // Will cause the player to judge the status of the error
+ element.addEventListener('ended', function () {
+ if (!element.loop) {
+ element.paused = true;
+ }
+ });
+ },
+
+ play: function (offset, loop) {
+ if (!this._element) {
+ this.interruptPlay = false;
+ return;
+ }
+ this._element.loop = loop;
+ this._element.play();
+ if (this._AUDIO_TYPE === 'AUDIO' && this._element.paused) {
+ this.stop();
+ cc.Audio.touchPlayList.push({ loop: loop, offset: offset, audio: this._element });
+ }
+
+ if (cc.Audio.bindTouch === false) {
+ cc.Audio.bindTouch = true;
+ // Listen to the touchstart body event and play the audio when necessary.
+ cc.game.canvas.addEventListener('touchstart', cc.Audio.touchStart);
+ }
+ },
+
+ getPlaying: function () {
+ if (!this._element) return true;
+ return !this._element.paused;
+ },
+
+ stop: function () {
+ if (!this._element) {
+ this.interruptPlay = true;
+ return;
+ }
+ this._element.pause();
+ try {
+ this._element.currentTime = 0;
+ } catch (err) {
+ }
+ },
+
+ pause: function () {
+ if (!this._element) {
+ this.interruptPlay = true;
+ return;
+ }
+ this._element.pause();
+ },
+
+ resume: function () {
+ if (!this._element) {
+ this.interruptPlay = false;
+ return;
+ }
+ this._element.play();
+ },
+
+ setVolume: function (volume) {
+ if (!this._element) return;
+ this._element.volume = volume;
+ },
+
+ getVolume: function () {
+ if (!this._element) return;
+ return this._element.volume;
+ },
+
+ cloneNode: function () {
+ var audio = new cc.Audio(this.src);
+ if (this._AUDIO_TYPE === "AUDIO") {
+ var elem = document.createElement("audio");
+ var sources = elem.getElementsByTagName('source');
+ for (var i = 0; i < sources.length; i++) {
+ elem.appendChild(sources[i]);
+ }
+ elem.src = this.src;
+ audio.setElement(elem);
+ } else {
+ audio.setBuffer(this._element.buffer);
+ }
+ return audio;
+ }
+});
+
+cc.Audio.touchPlayList = [
+ //{ offset: 0, audio: audio }
+];
+
+cc.Audio.bindTouch = false;
+cc.Audio.touchStart = function () {
+ var list = cc.Audio.touchPlayList;
+ var item = null;
+ while (item = list.pop()) {
+ item.audio.loop = !!item.loop;
+ item.audio.play(item.offset);
+ }
+};
+
+cc.Audio.WebAudio = function (buffer) {
+ this.buffer = buffer;
+ this.context = cc.Audio._context;
+
+ var volume = this.context['createGain']();
+ volume['gain'].value = 1;
+ volume['connect'](this.context['destination']);
+ this._volume = volume;
+
+ this._loop = false;
+
+ // The time stamp on the audio time axis when the recording begins to play.
+ this._startTime = -1;
+ // Record the currently playing Source
+ this._currentSource = null;
+ // Record the time has been played
+ this.playedLength = 0;
+
+ this._currextTimer = null;
+};
+
+cc.Audio.WebAudio.prototype = {
+ constructor: cc.Audio.WebAudio,
+
+ get paused() {
+ // If the current audio is a loop, then paused is false
+ if (this._currentSource && this._currentSource.loop)
+ return false;
+
+ // StartTime does not have value, as the default -1, it does not begin to play
+ if (this._startTime === -1)
+ return true;
+
+ // currentTime - startTime > durationTime
+ return this.context.currentTime - this._startTime > this.buffer.duration;
+ },
+ set paused(bool) {
+ },
+
+ get loop() {
+ return this._loop;
+ },
+ set loop(bool) {
+ return this._loop = bool;
+ },
+
+ get volume() {
+ return this._volume['gain'].value;
+ },
+ set volume(num) {
+ return this._volume['gain'].value = num;
+ },
+
+ get currentTime() {
+ return this.playedLength;
+ },
+ set currentTime(num) {
+ return this.playedLength = num;
+ },
+
+ play: function (offset) {
+
+ // If repeat play, you need to stop before an audio
+ if (this._currentSource && !this.paused) {
+ this._currentSource.stop(0);
+ this.playedLength = 0;
+ }
+
+ var audio = this.context["createBufferSource"]();
+ audio.buffer = this.buffer;
+ audio["connect"](this._volume);
+ audio.loop = this._loop;
+
+ this._startTime = this.context.currentTime;
+ offset = offset || this.playedLength;
+
+ var duration = this.buffer.duration;
+ if (!this._loop) {
+ if (audio.start)
+ audio.start(0, offset, duration - offset);
+ else if (audio["notoGrainOn"])
+ audio["noteGrainOn"](0, offset, duration - offset);
+ else
+ audio["noteOn"](0, offset, duration - offset);
+ } else {
+ if (audio.start)
+ audio.start(0);
+ else if (audio["notoGrainOn"])
+ audio["noteGrainOn"](0);
+ else
+ audio["noteOn"](0);
+ }
+
+ this._currentSource = audio;
+
+ // If the current audio context time stamp is 0
+ // There may be a need to touch events before you can actually start playing audio
+ // So here to add a timer to determine whether the real start playing audio, if not, then the incoming touchPlay queue
+ if (this.context.currentTime === 0) {
+ var self = this;
+ clearTimeout(this._currextTimer);
+ this._currextTimer = setTimeout(function () {
+ if (self.context.currentTime === 0) {
+ cc.Audio.touchPlayList.push({
+ offset: offset,
+ audio: self
+ });
+ }
+ }, 10);
+ }
+ },
+ pause: function () {
+ // Record the time the current has been played
+ this.playedLength = this.context.currentTime - this._startTime;
+ //If the duration of playedLendth exceeds the audio, you should take the remainder
+ this.playedLength %= this.buffer.duration;
+ var audio = this._currentSource;
+ this._currentSource = null;
+ this._startTime = -1;
+ if (audio)
+ audio.stop(0);
+ }
+};
+
+(function (polyfill) {
+
+ var SWA = polyfill.WEB_AUDIO, SWB = polyfill.ONLY_ONE;
+
+ var support = [];
+
+ (function () {
+ var audio = document.createElement("audio");
+ if (audio.canPlayType) {
+ var ogg = audio.canPlayType('audio/ogg; codecs="vorbis"');
+ if (ogg && ogg !== "") support.push(".ogg");
+ var mp3 = audio.canPlayType("audio/mpeg");
+ if (mp3 && mp3 !== "") support.push(".mp3");
+ var wav = audio.canPlayType('audio/wav; codecs="1"');
+ if (wav && wav !== "") support.push(".wav");
+ var mp4 = audio.canPlayType("audio/mp4");
+ if (mp4 && mp4 !== "") support.push(".mp4");
+ var m4a = audio.canPlayType("audio/x-m4a");
+ if (m4a && m4a !== "") support.push(".m4a");
+ }
+ })();
+ try {
+ if (SWA) {
+ var context = new (window.AudioContext || window.webkitAudioContext || window.mozAudioContext)();
+ cc.Audio._context = context;
+ // check context integrity
+ if (
+ !context["createBufferSource"] ||
+ !context["createGain"] ||
+ !context["destination"] ||
+ !context["decodeAudioData"]
+ ) {
+ throw 'context is incomplete';
+ }
+ if (polyfill.DELAY_CREATE_CTX)
+ setTimeout(function () {
+ context = new (window.AudioContext || window.webkitAudioContext || window.mozAudioContext)();
+ cc.Audio._context = context;
+ }, 0);
+ }
+ } catch (error) {
+ SWA = false;
+ cc.log("browser don't support web audio");
+ }
+
+ var loader = {
+
+ cache: {},
+
+ useWebAudio: true,
+
+ loadBuffer: function (url, cb) {
+ if (!SWA) return; // WebAudio Buffer
+
+ var request = cc.loader.getXMLHttpRequest();
+ request.open("GET", url, true);
+ request.responseType = "arraybuffer";
+
+ // Our asynchronous callback
+ request.onload = function () {
+ if (request._timeoutId >= 0) {
+ clearTimeout(request._timeoutId);
+ }
+ context["decodeAudioData"](request.response, function (buffer) {
+ //success
+ cb(null, buffer);
+ //audio.setBuffer(buffer);
+ }, function () {
+ //error
+ cb('decode error - ' + url);
+ });
+ };
+
+ request.onerror = function () {
+ cb('request error - ' + url);
+ };
+ if (request.ontimeout === undefined) {
+ request._timeoutId = setTimeout(function () {
+ request.ontimeout();
+ }, request.timeout);
+ }
+ request.ontimeout = function () {
+ cb('request timeout - ' + url);
+ };
+
+ request.send();
+ },
+
+ load: function (realUrl, url, res, cb) {
+
+ if (support.length === 0)
+ return cb("can not support audio!");
+
+ var audio = cc.loader.getRes(url);
+ if (audio)
+ return cb(null, audio);
+
+ if (cc.loader.audioPath)
+ realUrl = cc.path.join(cc.loader.audioPath, realUrl);
+
+ var extname = cc.path.extname(realUrl);
+
+ var typeList = [extname];
+ for (var i = 0; i < support.length; i++) {
+ if (extname !== support[i]) {
+ typeList.push(support[i]);
+ }
+ }
+
+ audio = new cc.Audio(realUrl);
+ cc.loader.cache[url] = audio;
+ this.loadAudioFromExtList(realUrl, typeList, audio, cb);
+ return audio;
+ },
+
+ loadAudioFromExtList: function (realUrl, typeList, audio, cb) {
+ if (typeList.length === 0) {
+ var ERRSTR = "can not found the resource of audio! Last match url is : ";
+ ERRSTR += realUrl.replace(/\.(.*)?$/, "(");
+ support.forEach(function (ext) {
+ ERRSTR += ext + "|";
+ });
+ ERRSTR = ERRSTR.replace(/\|$/, ")");
+ return cb({status: 520, errorMessage: ERRSTR}, null);
+ }
+
+ if (SWA && this.useWebAudio) {
+ this.loadBuffer(realUrl, function (error, buffer) {
+ if (error)
+ cc.log(error);
+
+ if (buffer)
+ audio.setBuffer(buffer);
+
+ cb(null, audio);
+ });
+ return;
+ }
+
+ var num = polyfill.ONE_SOURCE ? 1 : typeList.length;
+
+ // 加载统一使用dom
+ var dom = document.createElement('audio');
+ for (var i = 0; i < num; i++) {
+ var source = document.createElement('source');
+ source.src = cc.path.changeExtname(realUrl, typeList[i]);
+ dom.appendChild(source);
+ }
+
+ audio.setElement(dom);
+
+ var timer = setTimeout(function () {
+ if (dom.readyState === 0) {
+ failure();
+ } else {
+ success();
+ }
+ }, 8000);
+
+ var success = function () {
+ dom.removeEventListener("canplaythrough", success, false);
+ dom.removeEventListener("error", failure, false);
+ dom.removeEventListener("emptied", success, false);
+ if (polyfill.USE_LOADER_EVENT)
+ dom.removeEventListener(polyfill.USE_LOADER_EVENT, success, false);
+ clearTimeout(timer);
+ cb(null, audio);
+ };
+ var failure = function () {
+ cc.log('load audio failure - ' + realUrl);
+ success();
+ };
+ dom.addEventListener("canplaythrough", success, false);
+ dom.addEventListener("error", failure, false);
+ if (polyfill.USE_LOADER_EVENT)
+ dom.addEventListener(polyfill.USE_LOADER_EVENT, success, false);
+ }
+ };
+ cc.loader.register(["mp3", "ogg", "wav", "mp4", "m4a"], loader);
+
+ /**
+ * cc.audioEngine is the singleton object, it provide simple audio APIs.
+ * @namespace
+ */
+ cc.audioEngine = {
+ _currMusic: null,
+ _musicVolume: 1,
+
+ features: polyfill,
+
+ /**
+ * Indicates whether any background music can be played or not.
+ * @returns {boolean} true if the background music is playing, otherwise false
+ */
+ willPlayMusic: function () {
+ return false;
+ },
+
+ /**
+ * Play music.
+ * @param {String} url The path of the music file without filename extension.
+ * @param {Boolean} loop Whether the music loop or not.
+ * @example
+ * //example
+ * cc.audioEngine.playMusic(path, false);
+ */
+ playMusic: function(url, loop){
+ var bgMusic = this._currMusic;
+ if (bgMusic && bgMusic.getPlaying()) {
+ bgMusic.stop();
+ }
+ var musicVolume = this._musicVolume;
+ var audio = cc.loader.getRes(url);
+ if (!audio) {
+ cc.loader.load(url, function () {
+ if (!audio.getPlaying() && !audio.interruptPlay) {
+ audio.setVolume(musicVolume);
+ audio.play(0, loop || false);
+ }
+ });
+ audio = cc.loader.getRes(url);
+ }
+ audio.setVolume(musicVolume);
+ audio.play(0, loop || false);
+
+ this._currMusic = audio;
+ },
+
+ /**
+ * Stop playing music.
+ * @param {Boolean} [releaseData] If release the music data or not.As default value is false.
+ * @example
+ * //example
+ * cc.audioEngine.stopMusic();
+ */
+ stopMusic: function(releaseData){
+ var audio = this._currMusic;
+ if (audio) {
+ var list = cc.Audio.touchPlayList;
+ for (var i=list.length-1; i>=0; --i) {
+ if (this[i] && this[i].audio === audio._element)
+ list.splice(i, 1);
+ }
+
+ audio.stop();
+ this._currMusic = null;
+ if (releaseData)
+ cc.loader.release(audio.src);
+ }
+ },
+
+ /**
+ * Pause playing music.
+ * @example
+ * //example
+ * cc.audioEngine.pauseMusic();
+ */
+ pauseMusic: function () {
+ var audio = this._currMusic;
+ if (audio)
+ audio.pause();
+ },
+
+ /**
+ * Resume playing music.
+ * @example
+ * //example
+ * cc.audioEngine.resumeMusic();
+ */
+ resumeMusic: function () {
+ var audio = this._currMusic;
+ if (audio)
+ audio.resume();
+ },
+
+ /**
+ * Rewind playing music.
+ * @example
+ * //example
+ * cc.audioEngine.rewindMusic();
+ */
+ rewindMusic: function () {
+ var audio = this._currMusic;
+ if (audio) {
+ audio.stop();
+ audio.play();
+ }
+ },
+
+ /**
+ * The volume of the music max value is 1.0,the min value is 0.0 .
+ * @return {Number}
+ * @example
+ * //example
+ * var volume = cc.audioEngine.getMusicVolume();
+ */
+ getMusicVolume: function () {
+ return this._musicVolume;
+ },
+
+ /**
+ * Set the volume of music.
+ * @param {Number} volume Volume must be in 0.0~1.0 .
+ * @example
+ * //example
+ * cc.audioEngine.setMusicVolume(0.5);
+ */
+ setMusicVolume: function (volume) {
+ volume = volume - 0;
+ if (isNaN(volume)) volume = 1;
+ if (volume > 1) volume = 1;
+ if (volume < 0) volume = 0;
+
+ this._musicVolume = volume;
+ var audio = this._currMusic;
+ if (audio) {
+ audio.setVolume(volume);
+ }
+ },
+
+ /**
+ * Whether the music is playing.
+ * @return {Boolean} If is playing return true,or return false.
+ * @example
+ * //example
+ * if (cc.audioEngine.isMusicPlaying()) {
+ * cc.log("music is playing");
+ * }
+ * else {
+ * cc.log("music is not playing");
+ * }
+ */
+ isMusicPlaying: function () {
+ var audio = this._currMusic;
+ if (audio) {
+ return audio.getPlaying();
+ } else {
+ return false;
+ }
+ },
+
+ _audioPool: {},
+ _maxAudioInstance: 10,
+ _effectVolume: 1,
+ /**
+ * Play sound effect.
+ * @param {String} url The path of the sound effect with filename extension.
+ * @param {Boolean} loop Whether to loop the effect playing, default value is false
+ * @return {Number|null} the audio id
+ * @example
+ * //example
+ * var soundId = cc.audioEngine.playEffect(path);
+ */
+ playEffect: function (url, loop) {
+
+ if (SWB && this._currMusic && this._currMusic.getPlaying()) {
+ cc.log('Browser is only allowed to play one audio');
+ return null;
+ }
+
+ var effectList = this._audioPool[url];
+ if (!effectList) {
+ effectList = this._audioPool[url] = [];
+ }
+
+ for (var i = 0; i < effectList.length; i++) {
+ if (!effectList[i].getPlaying()) {
+ break;
+ }
+ }
+
+ if (!SWA && i > this._maxAudioInstance) {
+ var first = effectList.shift();
+ first.stop();
+ effectList.push(first);
+ i = effectList.length - 1;
+ // cc.log("Error: %s greater than %d", url, this._maxAudioInstance);
+ }
+
+ var audio;
+ if (effectList[i]) {
+ audio = effectList[i];
+ audio.setVolume(this._effectVolume);
+ audio.play(0, loop || false);
+ return audio;
+ }
+
+ audio = cc.loader.getRes(url);
+
+ if (audio && SWA && audio._AUDIO_TYPE === 'AUDIO') {
+ cc.loader.release(url);
+ audio = null;
+ }
+
+ if (audio) {
+
+ if (SWA && audio._AUDIO_TYPE === 'AUDIO') {
+ loader.loadBuffer(url, function (error, buffer) {
+ audio.setBuffer(buffer);
+ audio.setVolume(cc.audioEngine._effectVolume);
+ if (!audio.getPlaying())
+ audio.play(0, loop || false);
+ });
+ } else {
+ audio = audio.cloneNode();
+ audio.setVolume(this._effectVolume);
+ audio.play(0, loop || false);
+ effectList.push(audio);
+ return audio;
+ }
+
+ }
+
+ var cache = loader.useWebAudio;
+ loader.useWebAudio = true;
+ cc.loader.load(url, function (audio) {
+ audio = cc.loader.getRes(url);
+ audio = audio.cloneNode();
+ audio.setVolume(cc.audioEngine._effectVolume);
+ audio.play(0, loop || false);
+ effectList.push(audio);
+ });
+ loader.useWebAudio = cache;
+
+ return audio;
+ },
+
+ /**
+ * Set the volume of sound effects.
+ * @param {Number} volume Volume must be in 0.0~1.0 .
+ * @example
+ * //example
+ * cc.audioEngine.setEffectsVolume(0.5);
+ */
+ setEffectsVolume: function (volume) {
+ volume = volume - 0;
+ if (isNaN(volume)) volume = 1;
+ if (volume > 1) volume = 1;
+ if (volume < 0) volume = 0;
+
+ this._effectVolume = volume;
+ var audioPool = this._audioPool;
+ for (var p in audioPool) {
+ var audioList = audioPool[p];
+ if (Array.isArray(audioList))
+ for (var i = 0; i < audioList.length; i++) {
+ audioList[i].setVolume(volume);
+ }
+ }
+ },
+
+ /**
+ * The volume of the effects max value is 1.0,the min value is 0.0 .
+ * @return {Number}
+ * @example
+ * //example
+ * var effectVolume = cc.audioEngine.getEffectsVolume();
+ */
+ getEffectsVolume: function () {
+ return this._effectVolume;
+ },
+
+ /**
+ * Pause playing sound effect.
+ * @param {Number} audio The return value of function playEffect.
+ * @example
+ * //example
+ * cc.audioEngine.pauseEffect(audioID);
+ */
+ pauseEffect: function (audio) {
+ if (audio) {
+ audio.pause();
+ }
+ },
+
+ /**
+ * Pause all playing sound effect.
+ * @example
+ * //example
+ * cc.audioEngine.pauseAllEffects();
+ */
+ pauseAllEffects: function () {
+ var ap = this._audioPool;
+ for (var p in ap) {
+ var list = ap[p];
+ for (var i = 0; i < ap[p].length; i++) {
+ if (list[i].getPlaying()) {
+ list[i].pause();
+ }
+ }
+ }
+ },
+
+ /**
+ * Resume playing sound effect.
+ * @param {Number} audio The return value of function playEffect.
+ * @audioID
+ * //example
+ * cc.audioEngine.resumeEffect(audioID);
+ */
+ resumeEffect: function (audio) {
+ if (audio)
+ audio.resume();
+ },
+
+ /**
+ * Resume all playing sound effect
+ * @example
+ * //example
+ * cc.audioEngine.resumeAllEffects();
+ */
+ resumeAllEffects: function () {
+ var ap = this._audioPool;
+ for (var p in ap) {
+ var list = ap[p];
+ for (var i = 0; i < ap[p].length; i++) {
+ list[i].resume();
+ }
+ }
+ },
+
+ /**
+ * Stop playing sound effect.
+ * @param {Number} audio The return value of function playEffect.
+ * @example
+ * //example
+ * cc.audioEngine.stopEffect(audioID);
+ */
+ stopEffect: function (audio) {
+ if (audio) {
+ audio.stop();
+ }
+ },
+
+ /**
+ * Stop all playing sound effects.
+ * @example
+ * //example
+ * cc.audioEngine.stopAllEffects();
+ */
+ stopAllEffects: function () {
+ var ap = this._audioPool;
+ for (var p in ap) {
+ var list = ap[p];
+ for (var i = 0; i < list.length; i++) {
+ list[i].stop();
+ }
+ list.length = 0;
+ }
+ ap.length = 0;
+ },
+
+ /**
+ * Unload the preloaded effect from internal buffer
+ * @param {String} url
+ * @example
+ * //example
+ * cc.audioEngine.unloadEffect(EFFECT_FILE);
+ */
+ unloadEffect: function (url) {
+ if (!url) {
+ return;
+ }
+
+ cc.loader.release(url);
+ var pool = this._audioPool[url];
+ if (pool) {
+ for (var i = 0; i < pool.length; i++) {
+ pool[i].stop();
+ }
+ pool.length = 0;
+ }
+ delete this._audioPool[url];
+ },
+
+ /**
+ * End music and effects.
+ */
+ end: function () {
+ this.stopMusic();
+ this.stopAllEffects();
+ },
+
+ _pauseCache: [],
+ _pausePlaying: function () {
+ var bgMusic = this._currMusic;
+ if (bgMusic && bgMusic.getPlaying()) {
+ bgMusic.pause();
+ this._pauseCache.push(bgMusic);
+ }
+ var ap = this._audioPool;
+ for (var p in ap) {
+ var list = ap[p];
+ for (var i = 0; i < ap[p].length; i++) {
+ if (list[i].getPlaying()) {
+ list[i].pause();
+ this._pauseCache.push(list[i]);
+ }
+ }
+ }
+ },
+
+ _resumePlaying: function () {
+ var list = this._pauseCache;
+ for (var i = 0; i < list.length; i++) {
+ list[i].resume();
+ }
+ list.length = 0;
+ }
+ };
+
+})(window.__audioSupport);
diff --git a/frameworks/cocos2d-html5/cocos2d/clipping-nodes/CCClippingNode.js b/frameworks/cocos2d-html5/cocos2d/clipping-nodes/CCClippingNode.js
new file mode 100644
index 0000000..7214ea1
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/clipping-nodes/CCClippingNode.js
@@ -0,0 +1,247 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2012 Pierre-David Bélanger
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * the value of stencil bits.
+ * @type Number
+ */
+cc.stencilBits = -1;
+
+/**
+ *
+ * cc.ClippingNode is a subclass of cc.Node.
+ * It draws its content (children) clipped using a stencil.
+ * The stencil is an other cc.Node that will not be drawn.
+ * The clipping is done using the alpha part of the stencil (adjusted with an alphaThreshold).
+ *
+ * @class
+ * @extends cc.Node
+ * @param {cc.Node} [stencil=null]
+ *
+ * @property {Number} alphaThreshold - Threshold for alpha value.
+ * @property {Boolean} inverted - Indicate whether in inverted mode.
+ * @property {cc.Node} stencil - he cc.Node to use as a stencil to do the clipping.
+ */
+cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{
+ inverted: false,
+ _alphaThreshold: 0,
+
+ _stencil: null,
+ _className: "ClippingNode",
+
+ _originStencilProgram: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {cc.Node} [stencil=null]
+ */
+ ctor: function (stencil) {
+ stencil = stencil || null;
+ cc.Node.prototype.ctor.call(this);
+ this._stencil = stencil;
+ if (stencil) {
+ this._originStencilProgram = stencil.getShaderProgram();
+ }
+ this.alphaThreshold = 1;
+ this.inverted = false;
+ this._renderCmd.initStencilBits();
+ },
+
+ /**
+ *
+ * Event callback that is invoked every time when node enters the 'stage'.
+ * If the CCNode enters the 'stage' with a transition, this event is called when the transition starts.
+ * During onEnter you can't access a "sister/brother" node.
+ * If you override onEnter, you must call its parent's onEnter function with this._super().
+ *
+ * @function
+ */
+ onEnter: function () {
+ cc.Node.prototype.onEnter.call(this);
+ if (this._stencil)
+ this._stencil._performRecursive(cc.Node._stateCallbackType.onEnter);
+ },
+
+ /**
+ *
+ * Event callback that is invoked when the node enters in the 'stage'.
+ * If the node enters the 'stage' with a transition, this event is called when the transition finishes.
+ * If you override onEnterTransitionDidFinish, you shall call its parent's onEnterTransitionDidFinish with this._super()
+ *
+ * @function
+ */
+ onEnterTransitionDidFinish: function () {
+ cc.Node.prototype.onEnterTransitionDidFinish.call(this);
+ if (this._stencil)
+ this._stencil._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
+ },
+
+ /**
+ *
+ * callback that is called every time the node leaves the 'stage'.
+ * If the node leaves the 'stage' with a transition, this callback is called when the transition starts.
+ * If you override onExitTransitionDidStart, you shall call its parent's onExitTransitionDidStart with this._super()
+ *
+ * @function
+ */
+ onExitTransitionDidStart: function () {
+ this._stencil._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ cc.Node.prototype.onExitTransitionDidStart.call(this);
+ },
+
+ /**
+ *
+ * callback that is called every time the node leaves the 'stage'.
+ * If the node leaves the 'stage' with a transition, this callback is called when the transition finishes.
+ * During onExit you can't access a sibling node.
+ * If you override onExit, you shall call its parent's onExit with this._super().
+ *
+ * @function
+ */
+ onExit: function () {
+ this._stencil._performRecursive(cc.Node._stateCallbackType.onExit);
+ cc.Node.prototype.onExit.call(this);
+ },
+
+ visit: function (parent) {
+ this._renderCmd.clippingVisit(parent && parent._renderCmd);
+ },
+
+ _visitChildren: function () {
+ var renderer = cc.renderer;
+ if (this._reorderChildDirty) {
+ this.sortAllChildren();
+ }
+ var children = this._children, child;
+ for (var i = 0, len = children.length; i < len; i++) {
+ child = children[i];
+ if (child && child._visible) {
+ child.visit(this);
+ }
+ }
+ this._renderCmd._dirtyFlag = 0;
+ },
+
+ /**
+ *
+ * The alpha threshold.
+ * The content is drawn only where the stencil have pixel with alpha greater than the alphaThreshold.
+ * Should be a float between 0 and 1.
+ * This default to 1 (so alpha test is disabled).
+ *
+ * @return {Number}
+ */
+ getAlphaThreshold: function () {
+ return this._alphaThreshold;
+ },
+
+ /**
+ * set alpha threshold.
+ * @param {Number} alphaThreshold
+ */
+ setAlphaThreshold: function (alphaThreshold) {
+ if (alphaThreshold === 1 && alphaThreshold !== this._alphaThreshold) {
+ // should reset program used by _stencil
+ this._renderCmd.resetProgramByStencil();
+ }
+ this._alphaThreshold = alphaThreshold;
+ },
+
+ /**
+ *
+ * Inverted. If this is set to YES,
+ * the stencil is inverted, so the content is drawn where the stencil is NOT drawn.
+ * This default to NO.
+ *
+ * @return {Boolean}
+ */
+ isInverted: function () {
+ return this.inverted;
+ },
+
+ /**
+ * set whether or not invert of stencil
+ * @param {Boolean} inverted
+ */
+ setInverted: function (inverted) {
+ this.inverted = inverted;
+ },
+
+ /**
+ * The cc.Node to use as a stencil to do the clipping.
+ * The stencil node will be retained. This default to nil.
+ * @return {cc.Node}
+ */
+ getStencil: function () {
+ return this._stencil;
+ },
+
+ /**
+ * Set stencil.
+ * @function
+ * @param {cc.Node} stencil
+ */
+ setStencil: function (stencil) {
+ if (this._stencil === stencil)
+ return;
+ if (stencil)
+ this._originStencilProgram = stencil.getShaderProgram();
+ this._renderCmd.setStencil(stencil);
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.ClippingNode.CanvasRenderCmd(this);
+ else
+ return new cc.ClippingNode.WebGLRenderCmd(this);
+ }
+});
+
+var _p = cc.ClippingNode.prototype;
+
+// Extended properties
+/** @expose */
+_p.stencil;
+cc.defineGetterSetter(_p, "stencil", _p.getStencil, _p.setStencil);
+/** @expose */
+_p.alphaThreshold;
+cc.defineGetterSetter(_p, "alphaThreshold", _p.getAlphaThreshold, _p.setAlphaThreshold);
+
+
+/**
+ * Creates and initializes a clipping node with an other node as its stencil.
+ * The stencil node will be retained.
+ * @deprecated since v3.0, please use "new cc.ClippingNode(stencil)" instead
+ * @param {cc.Node} [stencil=null]
+ * @return {cc.ClippingNode}
+ * @example
+ * //example
+ * new cc.ClippingNode(stencil);
+ */
+cc.ClippingNode.create = function (stencil) {
+ return new cc.ClippingNode(stencil);
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js
new file mode 100644
index 0000000..de49899
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js
@@ -0,0 +1,223 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+//-------------------------- ClippingNode's canvas render cmd --------------------------------
+(function () {
+ cc.ClippingNode.CanvasRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._needDraw = false;
+
+ this._godhelpme = false;
+ this._clipElemType = false;
+
+ this._rendererSaveCmd = new cc.CustomRenderCmd(this, this._saveCmdCallback);
+ this._rendererClipCmd = new cc.CustomRenderCmd(this, this._clipCmdCallback);
+ this._rendererRestoreCmd = new cc.CustomRenderCmd(this, this._restoreCmdCallback);
+ };
+ var proto = cc.ClippingNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ proto.constructor = cc.ClippingNode.CanvasRenderCmd;
+
+ proto.resetProgramByStencil = function () {
+
+ };
+
+ proto.initStencilBits = function () {
+ };
+
+ proto.setStencil = function (stencil) {
+ if (stencil == null)
+ return;
+
+ this._node._stencil = stencil;
+
+ // For shape stencil, rewrite the draw of stencil ,only init the clip path and draw nothing.
+ //else
+ if (stencil instanceof cc.DrawNode) {
+ if (stencil._buffer) {
+ for (var i = 0; i < stencil._buffer.length; i++) {
+ stencil._buffer[i].isFill = false;
+ stencil._buffer[i].isStroke = false;
+ }
+ }
+
+ stencil._renderCmd.rendering = function (ctx, scaleX, scaleY) {
+ //make it do nothing and draw it in clipp render command
+ return;
+ };
+
+ stencil._renderCmd._canUseDirtyRegion = true;
+ this._rendererSaveCmd._canUseDirtyRegion = true;
+ this._rendererClipCmd._canUseDirtyRegion = true;
+ this._rendererRestoreCmd._canUseDirtyRegion = true;
+
+ } else {
+ stencil._parent = this._node;
+ }
+ };
+
+ proto._saveCmdCallback = function (ctx, scaleX, scaleY) {
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext();
+
+ if (this._clipElemType) {
+ var locCache = cc.ClippingNode.CanvasRenderCmd._getSharedCache();
+ var canvas = context.canvas;
+ locCache.width = canvas.width;
+ locCache.height = canvas.height; //note: on some browser, it can't clear the canvas, e.g. baidu
+ var locCacheCtx = locCache.getContext("2d");
+ locCacheCtx.drawImage(canvas, 0, 0); //save the result to shareCache canvas
+ } else {
+ wrapper.save();
+ //Because drawNode's content size is zero
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+
+ if (this._node.inverted) {
+ context.beginPath(); //save for clip
+ context.rect(0, 0, context.canvas.width, -context.canvas.height);
+ context.clip();
+ }
+ }
+ };
+
+ proto._setStencilCompositionOperation = function (stencil) {
+ if (!stencil)
+ return;
+ var node = this._node;
+ if (stencil._renderCmd && stencil._renderCmd._blendFuncStr) //it is a hack way.
+ stencil._renderCmd._blendFuncStr = (node.inverted ? "destination-out" : "destination-in");
+
+ if (!stencil._children)
+ return;
+ var children = stencil._children;
+ for (var i = 0, len = children.length; i < len; i++) {
+ this._setStencilCompositionOperation(children[i]);
+ }
+ };
+
+ proto._clipCmdCallback = function (ctx) {
+ var node = this._node;
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext();
+
+ if (this._clipElemType) {
+ //hack
+ this._setStencilCompositionOperation(node._stencil);
+ } else {
+ var stencil = this._node._stencil;
+ if (stencil instanceof cc.DrawNode) {
+ context.beginPath();
+ var t = stencil._renderCmd._transform;
+ context.transform(t.a, t.b, t.c, t.d, t.tx, -t.ty);
+ for (var i = 0; i < stencil._buffer.length; i++) {
+ var vertices = stencil._buffer[i].verts;
+ //TODO: need support circle etc
+ //cc.assert(cc.vertexListIsClockwise(vertices),
+ // "Only clockwise polygons should be used as stencil");
+
+ var firstPoint = vertices[0];
+ context.moveTo(firstPoint.x, -firstPoint.y);
+ for (var j = vertices.length - 1; j > 0; j--)
+ context.lineTo(vertices[j].x, -vertices[j].y);
+ }
+ }
+ context.clip();
+ }
+ };
+
+ proto._restoreCmdCallback = function (ctx) {
+ var locCache = cc.ClippingNode.CanvasRenderCmd._getSharedCache();
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext();
+ if (this._clipElemType) {
+ // Redraw the cached canvas, so that the clipped area shows the background etc.
+ context.save();
+ context.setTransform(1, 0, 0, 1, 0, 0);
+ context.globalCompositeOperation = "destination-over";
+ context.drawImage(locCache, 0, 0);
+ context.restore();
+ this._dirtyFlag = 0;
+ } else {
+ wrapper.restore(); //use for restore clip operation
+ }
+ };
+
+ proto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
+ var node = this._node;
+ if (node._stencil && node._stencil._renderCmd) {
+ node._stencil._renderCmd.transform(this, true);
+ node._stencil._dirtyFlag &= ~cc.Node._dirtyFlags.transformDirty;
+ }
+ };
+
+ proto._cangodhelpme = function (godhelpme) {
+ if (godhelpme === true || godhelpme === false)
+ cc.ClippingNode.CanvasRenderCmd.prototype._godhelpme = godhelpme;
+ return cc.ClippingNode.CanvasRenderCmd.prototype._godhelpme;
+ };
+
+ proto.clippingVisit = function (parentCmd) {
+ var node = this._node;
+ parentCmd = parentCmd || this.getParentRenderCmd();
+ this.visit(parentCmd);
+
+ // Composition mode, costy but support texture stencil
+ this._clipElemType = !(!this._cangodhelpme() && node._stencil instanceof cc.DrawNode);
+ if (!node._stencil || !node._stencil.visible) {
+ if (this.inverted)
+ node._visitChildren(); // draw everything
+ return;
+ }
+
+ cc.renderer.pushRenderCommand(this._rendererSaveCmd);
+ if (this._clipElemType) {
+ // Draw everything first using node visit function
+ node._visitChildren();
+ } else {
+ node._stencil.visit(node);
+ }
+ cc.renderer.pushRenderCommand(this._rendererClipCmd);
+
+ if (this._clipElemType) {
+ node._stencil.visit(node);
+ } else {
+ // Clip mode doesn't support recursive stencil, so once we used a clip stencil,
+ // so if it has ClippingNode as a child, the child must uses composition stencil.
+ this._cangodhelpme(true);
+ var children = node._children;
+ var i, len = children.length;
+ if (len > 0) {
+ node.sortAllChildren();
+ for (i = 0; i < len; i++)
+ children[i].visit(node);
+ }
+ this._cangodhelpme(false);
+ }
+
+ cc.renderer.pushRenderCommand(this._rendererRestoreCmd);
+ this._dirtyFlag = 0;
+ };
+
+ cc.ClippingNode.CanvasRenderCmd._sharedCache = null;
+ cc.ClippingNode.CanvasRenderCmd._getSharedCache = function () {
+ return (cc.ClippingNode.CanvasRenderCmd._sharedCache) || (cc.ClippingNode.CanvasRenderCmd._sharedCache = document.createElement("canvas"));
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js
new file mode 100644
index 0000000..6d8956a
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js
@@ -0,0 +1,207 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+function setProgram (node, program) {
+ node.shaderProgram = program;
+
+ var children = node.children;
+ if (!children)
+ return;
+
+ for (var i = 0; i < children.length; i++)
+ setProgram(children[i], program);
+}
+
+// ------------------------------- ClippingNode's WebGL render cmd ------------------------------
+(function () {
+ cc.ClippingNode.WebGLRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._needDraw = false;
+
+ this._beforeVisitCmd = new cc.CustomRenderCmd(this, this._onBeforeVisit);
+ this._afterDrawStencilCmd = new cc.CustomRenderCmd(this, this._onAfterDrawStencil);
+ this._afterVisitCmd = new cc.CustomRenderCmd(this, this._onAfterVisit);
+
+ this._currentStencilEnabled = null;
+ this._mask_layer_le = null;
+ };
+
+ var proto = cc.ClippingNode.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ proto.constructor = cc.ClippingNode.WebGLRenderCmd;
+
+ cc.ClippingNode.WebGLRenderCmd._init_once = null;
+ cc.ClippingNode.WebGLRenderCmd._visit_once = null;
+ cc.ClippingNode.WebGLRenderCmd._layer = -1;
+
+ proto.initStencilBits = function () {
+ // get (only once) the number of bits of the stencil buffer
+ cc.ClippingNode.WebGLRenderCmd._init_once = true;
+ if (cc.ClippingNode.WebGLRenderCmd._init_once) {
+ cc.stencilBits = cc._renderContext.getParameter(cc._renderContext.STENCIL_BITS);
+ if (cc.stencilBits <= 0)
+ cc.log("Stencil buffer is not enabled.");
+ cc.ClippingNode.WebGLRenderCmd._init_once = false;
+ }
+ };
+
+ proto.transform = function (parentCmd, recursive) {
+ var node = this._node;
+ this.originTransform(parentCmd, recursive);
+ if (node._stencil) {
+ node._stencil._renderCmd.transform(this, true);
+ node._stencil._dirtyFlag &= ~cc.Node._dirtyFlags.transformDirty;
+ }
+ };
+
+ proto.clippingVisit = function (parentCmd) {
+ var node = this._node;
+ parentCmd = parentCmd || this.getParentRenderCmd();
+ this.visit(parentCmd);
+
+ // if stencil buffer disabled
+ if (cc.stencilBits < 1) {
+ // draw everything, as if there were no stencil
+ node._visitChildren();
+ return;
+ }
+
+ if (!node._stencil || !node._stencil.visible) {
+ if (node.inverted)
+ node._visitChildren(); // draw everything
+ return;
+ }
+
+ if (cc.ClippingNode.WebGLRenderCmd._layer + 1 === cc.stencilBits) {
+ cc.ClippingNode.WebGLRenderCmd._visit_once = true;
+ if (cc.ClippingNode.WebGLRenderCmd._visit_once) {
+ cc.log("Nesting more than " + cc.stencilBits + "stencils is not supported. Everything will be drawn without stencil for this node and its children.");
+ cc.ClippingNode.WebGLRenderCmd._visit_once = false;
+ }
+ // draw everything, as if there were no stencil
+ node._visitChildren();
+ return;
+ }
+
+ cc.renderer.pushRenderCommand(this._beforeVisitCmd);
+
+ // node._stencil._stackMatrix = node._stackMatrix;
+ node._stencil.visit(node);
+
+ cc.renderer.pushRenderCommand(this._afterDrawStencilCmd);
+
+ // draw (according to the stencil test func) this node and its children
+ var locChildren = node._children;
+ if (locChildren && locChildren.length > 0) {
+ var childLen = locChildren.length;
+ node.sortAllChildren();
+ // draw children zOrder < 0
+ for (var i = 0; i < childLen; i++) {
+ locChildren[i].visit(node);
+ }
+ }
+
+ cc.renderer.pushRenderCommand(this._afterVisitCmd);
+
+ this._dirtyFlag = 0;
+ };
+
+ proto.setStencil = function (stencil) {
+ var node = this._node;
+ if (node._stencil)
+ node._stencil._parent = null;
+ node._stencil = stencil;
+ if (node._stencil)
+ node._stencil._parent = node;
+ };
+
+ proto.resetProgramByStencil = function () {
+ var node = this._node;
+ if (node._stencil) {
+ var program = node._originStencilProgram;
+ setProgram(node._stencil, program);
+ }
+ };
+
+ proto._onBeforeVisit = function (ctx) {
+ var gl = ctx || cc._renderContext, node = this._node;
+ cc.ClippingNode.WebGLRenderCmd._layer++;
+
+ // mask of the current layer (ie: for layer 3: 00000100)
+ var mask_layer = 0x1 << cc.ClippingNode.WebGLRenderCmd._layer;
+ // mask of all layers less than the current (ie: for layer 3: 00000011)
+ var mask_layer_l = mask_layer - 1;
+ // mask of all layers less than or equal to the current (ie: for layer 3: 00000111)
+ //var mask_layer_le = mask_layer | mask_layer_l;
+ this._mask_layer_le = mask_layer | mask_layer_l;
+ // manually save the stencil state
+ this._currentStencilEnabled = gl.isEnabled(gl.STENCIL_TEST);
+
+ gl.clear(gl.DEPTH_BUFFER_BIT);
+ // enable stencil use
+ gl.enable(gl.STENCIL_TEST);
+
+ gl.depthMask(false);
+
+ gl.stencilFunc(gl.NEVER, mask_layer, mask_layer);
+ gl.stencilOp(gl.REPLACE, gl.KEEP, gl.KEEP);
+
+ gl.stencilMask(mask_layer);
+ gl.clear(gl.STENCIL_BUFFER_BIT);
+
+ if (node.alphaThreshold < 1) { //TODO desktop
+ var program = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLORALPHATEST);
+ // set our alphaThreshold
+ cc.glUseProgram(program.getProgram());
+ program.setUniformLocationWith1f(cc.UNIFORM_ALPHA_TEST_VALUE_S, node.alphaThreshold);
+ program.setUniformLocationWithMatrix4fv(cc.UNIFORM_MVMATRIX_S, cc.renderer.mat4Identity.mat);
+ cc.setProgram(node._stencil, program);
+ }
+ };
+
+ proto._onAfterDrawStencil = function (ctx) {
+ var gl = ctx || cc._renderContext;
+ gl.depthMask(true);
+ gl.stencilFunc(!this._node.inverted ? gl.EQUAL : gl.NOTEQUAL, this._mask_layer_le, this._mask_layer_le);
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
+ };
+
+ proto._onAfterVisit = function (ctx) {
+ var gl = ctx || cc._renderContext;
+
+ cc.ClippingNode.WebGLRenderCmd._layer--;
+
+ if (this._currentStencilEnabled) {
+ var mask_layer = 0x1 << cc.ClippingNode.WebGLRenderCmd._layer;
+ var mask_layer_l = mask_layer - 1;
+ var mask_layer_le = mask_layer | mask_layer_l;
+
+ gl.stencilMask(mask_layer);
+ gl.stencilFunc(gl.EQUAL, mask_layer_le, mask_layer_le);
+ }
+ else {
+ gl.disable(gl.STENCIL_TEST);
+
+ }
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/compression/ZipUtils.js b/frameworks/cocos2d-html5/cocos2d/compression/ZipUtils.js
new file mode 100644
index 0000000..ccecd63
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/compression/ZipUtils.js
@@ -0,0 +1,82 @@
+/*--
+ Copyright 2009-2010 by Stefan Rusterholz.
+ All rights reserved.
+ You can choose between MIT and BSD-3-Clause license. License file will be added later.
+ --*/
+
+/**
+ * mixin cc.Codec
+ */
+cc.Codec = {name:'Jacob__Codec'};
+
+/**
+ * Unpack a gzipped byte array
+ * @param {Array} input Byte array
+ * @returns {String} Unpacked byte string
+ */
+cc.unzip = function () {
+ return cc.Codec.GZip.gunzip.apply(cc.Codec.GZip, arguments);
+};
+
+/**
+ * Unpack a gzipped byte string encoded as base64
+ * @param {String} input Byte string encoded as base64
+ * @returns {String} Unpacked byte string
+ */
+cc.unzipBase64 = function () {
+ var tmpInput = cc.Codec.Base64.decode.apply(cc.Codec.Base64, arguments);
+ return cc.Codec.GZip.gunzip.apply(cc.Codec.GZip, [tmpInput]);
+};
+
+/**
+ * Unpack a gzipped byte string encoded as base64
+ * @param {String} input Byte string encoded as base64
+ * @param {Number} bytes Bytes per array item
+ * @returns {Array} Unpacked byte array
+ */
+cc.unzipBase64AsArray = function (input, bytes) {
+ bytes = bytes || 1;
+
+ var dec = this.unzipBase64(input),
+ ar = [], i, j, len;
+ for (i = 0, len = dec.length / bytes; i < len; i++) {
+ ar[i] = 0;
+ for (j = bytes - 1; j >= 0; --j) {
+ ar[i] += dec.charCodeAt((i * bytes) + j) << (j * 8);
+ }
+ }
+ return ar;
+};
+
+/**
+ * Unpack a gzipped byte array
+ * @param {Array} input Byte array
+ * @param {Number} bytes Bytes per array item
+ * @returns {Array} Unpacked byte array
+ */
+cc.unzipAsArray = function (input, bytes) {
+ bytes = bytes || 1;
+
+ var dec = this.unzip(input),
+ ar = [], i, j, len;
+ for (i = 0, len = dec.length / bytes; i < len; i++) {
+ ar[i] = 0;
+ for (j = bytes - 1; j >= 0; --j) {
+ ar[i] += dec.charCodeAt((i * bytes) + j) << (j * 8);
+ }
+ }
+ return ar;
+};
+
+/**
+ * string to array
+ * @param {String} input
+ * @returns {Array} array
+ */
+cc.StringToArray = function (input) {
+ var tmp = input.split(","), ar = [], i;
+ for (i = 0; i < tmp.length; i++) {
+ ar.push(parseInt(tmp[i]));
+ }
+ return ar;
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/compression/base64.js b/frameworks/cocos2d-html5/cocos2d/compression/base64.js
new file mode 100644
index 0000000..adb0d68
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/compression/base64.js
@@ -0,0 +1,95 @@
+/*--
+ Copyright 2009-2010 by Stefan Rusterholz.
+ All rights reserved.
+ You can choose between MIT and BSD-3-Clause license. License file will be added later.
+ --*/
+
+/**
+ * mixin cc.Codec.Base64
+ */
+cc.Codec.Base64 = {name:'Jacob__Codec__Base64'};
+
+cc.Codec.Base64._keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+
+/**
+ *
+ * cc.Codec.Base64.decode(input[, unicode=false]) -> String (http://en.wikipedia.org/wiki/Base64).
+ *
+ * @function
+ * @param {String} input The base64 encoded string to decode
+ * @return {String} Decodes a base64 encoded String
+ * @example
+ * //decode string
+ * cc.Codec.Base64.decode("U29tZSBTdHJpbmc="); // => "Some String"
+ */
+cc.Codec.Base64.decode = function Jacob__Codec__Base64__decode(input) {
+ var output = [],
+ chr1, chr2, chr3,
+ enc1, enc2, enc3, enc4,
+ i = 0;
+
+ input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
+
+ while (i < input.length) {
+ enc1 = this._keyStr.indexOf(input.charAt(i++));
+ enc2 = this._keyStr.indexOf(input.charAt(i++));
+ enc3 = this._keyStr.indexOf(input.charAt(i++));
+ enc4 = this._keyStr.indexOf(input.charAt(i++));
+
+ chr1 = (enc1 << 2) | (enc2 >> 4);
+ chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
+ chr3 = ((enc3 & 3) << 6) | enc4;
+
+ output.push(String.fromCharCode(chr1));
+
+ if (enc3 !== 64) {
+ output.push(String.fromCharCode(chr2));
+ }
+ if (enc4 !== 64) {
+ output.push(String.fromCharCode(chr3));
+ }
+ }
+
+ output = output.join('');
+
+ return output;
+};
+
+/**
+ *
+ * Converts an input string encoded in base64 to an array of integers whose
+ * values represent the decoded string's characters' bytes.
+ *
+ * @function
+ * @param {String} input The String to convert to an array of Integers
+ * @param {Number} bytes
+ * @return {Array}
+ * @example
+ * //decode string to array
+ * var decodeArr = cc.Codec.Base64.decodeAsArray("U29tZSBTdHJpbmc=");
+ */
+cc.Codec.Base64.decodeAsArray = function Jacob__Codec__Base64___decodeAsArray(input, bytes) {
+ var dec = this.decode(input),
+ ar = [], i, j, len;
+ for (i = 0, len = dec.length / bytes; i < len; i++) {
+ ar[i] = 0;
+ for (j = bytes - 1; j >= 0; --j) {
+ ar[i] += dec.charCodeAt((i * bytes) + j) << (j * 8);
+ }
+ }
+
+ return ar;
+};
+
+cc.uint8ArrayToUint32Array = function(uint8Arr){
+ if(uint8Arr.length % 4 !== 0)
+ return null;
+
+ var arrLen = uint8Arr.length /4;
+ var retArr = window.Uint32Array? new Uint32Array(arrLen) : [];
+ for(var i = 0; i < arrLen; i++){
+ var offset = i * 4;
+ retArr[i] = uint8Arr[offset] + uint8Arr[offset + 1] * (1 << 8) + uint8Arr[offset + 2] * (1 << 16) + uint8Arr[offset + 3] * (1<<24);
+ }
+ return retArr;
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/compression/gzip.js b/frameworks/cocos2d-html5/cocos2d/compression/gzip.js
new file mode 100644
index 0000000..baed633
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/compression/gzip.js
@@ -0,0 +1,731 @@
+/*--
+ Copyright 2009-2010 by Stefan Rusterholz.
+ All rights reserved.
+ You can choose between MIT and BSD-3-Clause license. License file will be added later.
+ --*/
+
+/**
+ * See cc.Codec.GZip.gunzip.
+ * @param {Array | String} data The bytestream to decompress
+ * Constructor
+ */
+cc.Codec.GZip = function Jacob__GZip(data) {
+ this.data = data;
+
+ this.debug = false;
+ this.gpflags = undefined;
+ this.files = 0;
+ this.unzipped = [];
+ this.buf32k = new Array(32768);
+ this.bIdx = 0;
+ this.modeZIP = false;
+ this.bytepos = 0;
+ this.bb = 1;
+ this.bits = 0;
+ this.nameBuf = [];
+ this.fileout = undefined;
+ this.literalTree = new Array(cc.Codec.GZip.LITERALS);
+ this.distanceTree = new Array(32);
+ this.treepos = 0;
+ this.Places = null;
+ this.len = 0;
+ this.fpos = new Array(17);
+ this.fpos[0] = 0;
+ this.flens = undefined;
+ this.fmax = undefined;
+};
+
+/**
+ * Unzips the gzipped data of the 'data' argument.
+ * @param string The bytestream to decompress. Either an array of Integers between 0 and 255, or a String.
+ * @return {String}
+ */
+cc.Codec.GZip.gunzip = function (string) {
+ if (string.constructor === Array) {
+ } else if (string.constructor === String) {
+ }
+ var gzip = new cc.Codec.GZip(string);
+ return gzip.gunzip()[0][0];
+};
+
+cc.Codec.GZip.HufNode = function () {
+ this.b0 = 0;
+ this.b1 = 0;
+ this.jump = null;
+ this.jumppos = -1;
+};
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.Codec.GZip.LITERALS = 288;
+/**
+ * @constant
+ * @type Number
+ */
+cc.Codec.GZip.NAMEMAX = 256;
+
+cc.Codec.GZip.bitReverse = [
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+];
+cc.Codec.GZip.cplens = [
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
+];
+cc.Codec.GZip.cplext = [
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99
+];
+/* 99==invalid */
+cc.Codec.GZip.cpdist = [
+ 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d,
+ 0x0011, 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1,
+ 0x0101, 0x0181, 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01,
+ 0x1001, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001
+];
+cc.Codec.GZip.cpdext = [
+ 0, 0, 0, 0, 1, 1, 2, 2,
+ 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10,
+ 11, 11, 12, 12, 13, 13
+];
+cc.Codec.GZip.border = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
+
+
+/**
+ * gunzip
+ * @return {Array}
+ */
+cc.Codec.GZip.prototype.gunzip = function () {
+ this.outputArr = [];
+
+ //convertToByteArray(input);
+ //if (this.debug) alert(this.data);
+
+ this.nextFile();
+ return this.unzipped;
+};
+
+cc.Codec.GZip.prototype.readByte = function () {
+ this.bits += 8;
+ if (this.bytepos < this.data.length) {
+ //return this.data[this.bytepos++]; // Array
+ return this.data.charCodeAt(this.bytepos++);
+ } else {
+ return -1;
+ }
+};
+
+cc.Codec.GZip.prototype.byteAlign = function () {
+ this.bb = 1;
+};
+
+cc.Codec.GZip.prototype.readBit = function () {
+ var carry;
+ this.bits++;
+ carry = (this.bb & 1);
+ this.bb >>= 1;
+ if (this.bb === 0) {
+ this.bb = this.readByte();
+ carry = (this.bb & 1);
+ this.bb = (this.bb >> 1) | 0x80;
+ }
+ return carry;
+};
+
+cc.Codec.GZip.prototype.readBits = function (a) {
+ var res = 0,
+ i = a;
+
+ while (i--) res = (res << 1) | this.readBit();
+ if (a) res = cc.Codec.GZip.bitReverse[res] >> (8 - a);
+
+ return res;
+};
+
+cc.Codec.GZip.prototype.flushBuffer = function () {
+ this.bIdx = 0;
+};
+
+cc.Codec.GZip.prototype.addBuffer = function (a) {
+ this.buf32k[this.bIdx++] = a;
+ this.outputArr.push(String.fromCharCode(a));
+ if (this.bIdx === 0x8000) this.bIdx = 0;
+};
+
+cc.Codec.GZip.prototype.IsPat = function () {
+ while (1) {
+ if (this.fpos[this.len] >= this.fmax) return -1;
+ if (this.flens[this.fpos[this.len]] === this.len) return this.fpos[this.len]++;
+ this.fpos[this.len]++;
+ }
+};
+
+cc.Codec.GZip.prototype.Rec = function () {
+ var curplace = this.Places[this.treepos];
+ var tmp;
+ //if (this.debug) document.write(" len:"+this.len+" treepos:"+this.treepos);
+ if (this.len === 17) { //war 17
+ return -1;
+ }
+ this.treepos++;
+ this.len++;
+
+ tmp = this.IsPat();
+ //if (this.debug) document.write(" IsPat "+tmp);
+ if (tmp >= 0) {
+ curplace.b0 = tmp;
+ /* leaf cell for 0-bit */
+ //if (this.debug) document.write(" b0 "+curplace.b0);
+ } else {
+ /* Not a Leaf cell */
+ curplace.b0 = 0x8000;
+ //if (this.debug) document.write(" b0 "+curplace.b0);
+ if (this.Rec()) return -1;
+ }
+ tmp = this.IsPat();
+ if (tmp >= 0) {
+ curplace.b1 = tmp;
+ /* leaf cell for 1-bit */
+ //if (this.debug) document.write(" b1 "+curplace.b1);
+ curplace.jump = null;
+ /* Just for the display routine */
+ } else {
+ /* Not a Leaf cell */
+ curplace.b1 = 0x8000;
+ //if (this.debug) document.write(" b1 "+curplace.b1);
+ curplace.jump = this.Places[this.treepos];
+ curplace.jumppos = this.treepos;
+ if (this.Rec()) return -1;
+ }
+ this.len--;
+ return 0;
+};
+
+cc.Codec.GZip.prototype.CreateTree = function (currentTree, numval, lengths, show) {
+ var i;
+ /* Create the Huffman decode tree/table */
+ //if (this.debug) document.write("currentTree "+currentTree+" numval "+numval+" lengths "+lengths+" show "+show);
+ this.Places = currentTree;
+ this.treepos = 0;
+ this.flens = lengths;
+ this.fmax = numval;
+ for (i = 0; i < 17; i++) this.fpos[i] = 0;
+ this.len = 0;
+ if (this.Rec()) {
+ //if (this.debug) alert("invalid huffman tree\n");
+ return -1;
+ }
+ // if (this.debug) {
+ // document.write(' Tree: '+this.Places.length);
+ // for (var a=0;a<32;a++){
+ // document.write("Places["+a+"].b0="+this.Places[a].b0+" ");
+ // document.write("Places["+a+"].b1="+this.Places[a].b1+" ");
+ // }
+ // }
+
+ return 0;
+};
+
+cc.Codec.GZip.prototype.DecodeValue = function (currentTree) {
+ var len, i,
+ xtreepos = 0,
+ X = currentTree[xtreepos],
+ b;
+
+ /* decode one symbol of the data */
+ while (1) {
+ b = this.readBit();
+ // if (this.debug) document.write("b="+b);
+ if (b) {
+ if (!(X.b1 & 0x8000)) {
+ // if (this.debug) document.write("ret1");
+ return X.b1;
+ /* If leaf node, return data */
+ }
+ X = X.jump;
+ len = currentTree.length;
+ for (i = 0; i < len; i++) {
+ if (currentTree[i] === X) {
+ xtreepos = i;
+ break;
+ }
+ }
+ } else {
+ if (!(X.b0 & 0x8000)) {
+ // if (this.debug) document.write("ret2");
+ return X.b0;
+ /* If leaf node, return data */
+ }
+ xtreepos++;
+ X = currentTree[xtreepos];
+ }
+ }
+ // if (this.debug) document.write("ret3");
+
+ return -1;
+};
+
+cc.Codec.GZip.prototype.DeflateLoop = function () {
+ var last, c, type, i, len;
+ do {
+ last = this.readBit();
+ type = this.readBits(2);
+
+ if (type === 0) {
+ var blockLen, cSum;
+
+ // Stored
+ this.byteAlign();
+ blockLen = this.readByte();
+ blockLen |= (this.readByte() << 8);
+
+ cSum = this.readByte();
+ cSum |= (this.readByte() << 8);
+
+ if (((blockLen ^ ~cSum) & 0xffff)) {
+ document.write("BlockLen checksum mismatch\n"); // FIXME: use throw
+ }
+ while (blockLen--) {
+ c = this.readByte();
+ this.addBuffer(c);
+ }
+ } else if (type === 1) {
+ var j;
+
+ /* Fixed Huffman tables -- fixed decode routine */
+ while (1) {
+ /*
+ 256 0000000 0
+ : : :
+ 279 0010111 23
+ 0 00110000 48
+ : : :
+ 143 10111111 191
+ 280 11000000 192
+ : : :
+ 287 11000111 199
+ 144 110010000 400
+ : : :
+ 255 111111111 511
+
+ Note the bit order!
+ */
+ j = (cc.Codec.GZip.bitReverse[this.readBits(7)] >> 1);
+ if (j > 23) {
+ j = (j << 1) | this.readBit();
+ /* 48..255 */
+
+ if (j > 199) { /* 200..255 */
+ j -= 128;
+ /* 72..127 */
+ j = (j << 1) | this.readBit();
+ /* 144..255 << */
+ } else { /* 48..199 */
+ j -= 48;
+ /* 0..151 */
+ if (j > 143) {
+ j = j + 136;
+ /* 280..287 << */
+ /* 0..143 << */
+ }
+ }
+ } else { /* 0..23 */
+ j += 256;
+ /* 256..279 << */
+ }
+ if (j < 256) {
+ this.addBuffer(j);
+ } else if (j === 256) {
+ /* EOF */
+ break; // FIXME: make this the loop-condition
+ } else {
+ var len, dist;
+
+ j -= 256 + 1;
+ /* bytes + EOF */
+ len = this.readBits(cc.Codec.GZip.cplext[j]) + cc.Codec.GZip.cplens[j];
+
+ j = cc.Codec.GZip.bitReverse[this.readBits(5)] >> 3;
+ if (cc.Codec.GZip.cpdext[j] > 8) {
+ dist = this.readBits(8);
+ dist |= (this.readBits(cc.Codec.GZip.cpdext[j] - 8) << 8);
+ } else {
+ dist = this.readBits(cc.Codec.GZip.cpdext[j]);
+ }
+ dist += cc.Codec.GZip.cpdist[j];
+
+ for (j = 0; j < len; j++) {
+ var c = this.buf32k[(this.bIdx - dist) & 0x7fff];
+ this.addBuffer(c);
+ }
+ }
+ } // while
+
+ } else if (type === 2) {
+ var j, n, literalCodes, distCodes, lenCodes;
+ var ll = new Array(288 + 32); // "static" just to preserve stack
+
+ // Dynamic Huffman tables
+
+ literalCodes = 257 + this.readBits(5);
+ distCodes = 1 + this.readBits(5);
+ lenCodes = 4 + this.readBits(4);
+ for (j = 0; j < 19; j++) {
+ ll[j] = 0;
+ }
+
+ // Get the decode tree code lengths
+
+ for (j = 0; j < lenCodes; j++) {
+ ll[cc.Codec.GZip.border[j]] = this.readBits(3);
+ }
+ len = this.distanceTree.length;
+ for (i = 0; i < len; i++) this.distanceTree[i] = new cc.Codec.GZip.HufNode();
+ if (this.CreateTree(this.distanceTree, 19, ll, 0)) {
+ this.flushBuffer();
+ return 1;
+ }
+ // if (this.debug) {
+ // document.write(" distanceTree");
+ // for(var a=0;a"+this.distanceTree[a].b0+" "+this.distanceTree[a].b1+" "+this.distanceTree[a].jump+" "+this.distanceTree[a].jumppos);
+ // }
+ // }
+
+ //read in literal and distance code lengths
+ n = literalCodes + distCodes;
+ i = 0;
+ var z = -1;
+ // if (this.debug) document.write(" n="+n+" bits: "+this.bits+" ");
+ while (i < n) {
+ z++;
+ j = this.DecodeValue(this.distanceTree);
+ // if (this.debug) document.write(" "+z+" i:"+i+" decode: "+j+" bits "+this.bits+" ");
+ if (j < 16) { // length of code in bits (0..15)
+ ll[i++] = j;
+ } else if (j === 16) { // repeat last length 3 to 6 times
+ var l;
+ j = 3 + this.readBits(2);
+ if (i + j > n) {
+ this.flushBuffer();
+ return 1;
+ }
+ l = i ? ll[i - 1] : 0;
+ while (j--) {
+ ll[i++] = l;
+ }
+ } else {
+ if (j === 17) { // 3 to 10 zero length codes
+ j = 3 + this.readBits(3);
+ } else { // j == 18: 11 to 138 zero length codes
+ j = 11 + this.readBits(7);
+ }
+ if (i + j > n) {
+ this.flushBuffer();
+ return 1;
+ }
+ while (j--) {
+ ll[i++] = 0;
+ }
+ }
+ } // while
+
+ // Can overwrite tree decode tree as it is not used anymore
+ len = this.literalTree.length;
+ for (i = 0; i < len; i++)
+ this.literalTree[i] = new cc.Codec.GZip.HufNode();
+ if (this.CreateTree(this.literalTree, literalCodes, ll, 0)) {
+ this.flushBuffer();
+ return 1;
+ }
+ len = this.literalTree.length;
+ for (i = 0; i < len; i++) this.distanceTree[i] = new cc.Codec.GZip.HufNode();
+ var ll2 = new Array();
+ for (i = literalCodes; i < ll.length; i++) ll2[i - literalCodes] = ll[i];
+ if (this.CreateTree(this.distanceTree, distCodes, ll2, 0)) {
+ this.flushBuffer();
+ return 1;
+ }
+ // if (this.debug) document.write(" literalTree");
+ while (1) {
+ j = this.DecodeValue(this.literalTree);
+ if (j >= 256) { // In C64: if carry set
+ var len, dist;
+ j -= 256;
+ if (j === 0) {
+ // EOF
+ break;
+ }
+ j--;
+ len = this.readBits(cc.Codec.GZip.cplext[j]) + cc.Codec.GZip.cplens[j];
+
+ j = this.DecodeValue(this.distanceTree);
+ if (cc.Codec.GZip.cpdext[j] > 8) {
+ dist = this.readBits(8);
+ dist |= (this.readBits(cc.Codec.GZip.cpdext[j] - 8) << 8);
+ } else {
+ dist = this.readBits(cc.Codec.GZip.cpdext[j]);
+ }
+ dist += cc.Codec.GZip.cpdist[j];
+ while (len--) {
+ var c = this.buf32k[(this.bIdx - dist) & 0x7fff];
+ this.addBuffer(c);
+ }
+ } else {
+ this.addBuffer(j);
+ }
+ } // while
+ }
+ } while (!last);
+ this.flushBuffer();
+
+ this.byteAlign();
+ return 0;
+};
+
+cc.Codec.GZip.prototype.unzipFile = function (name) {
+ var i;
+ this.gunzip();
+ for (i = 0; i < this.unzipped.length; i++) {
+ if (this.unzipped[i][1] === name) {
+ return this.unzipped[i][0];
+ }
+ }
+};
+
+cc.Codec.GZip.prototype.nextFile = function () {
+ // if (this.debug) alert("NEXTFILE");
+
+ this.outputArr = [];
+ this.modeZIP = false;
+
+ var tmp = [];
+ tmp[0] = this.readByte();
+ tmp[1] = this.readByte();
+ // if (this.debug) alert("type: "+tmp[0]+" "+tmp[1]);
+
+ if (tmp[0] === 0x78 && tmp[1] === 0xda) { //GZIP
+ // if (this.debug) alert("GEONExT-GZIP");
+ this.DeflateLoop();
+ // if (this.debug) alert(this.outputArr.join(''));
+ this.unzipped[this.files] = [this.outputArr.join(''), "geonext.gxt"];
+ this.files++;
+ }
+ if (tmp[0] === 0x1f && tmp[1] === 0x8b) { //GZIP
+ // if (this.debug) alert("GZIP");
+ this.skipdir();
+ // if (this.debug) alert(this.outputArr.join(''));
+ this.unzipped[this.files] = [this.outputArr.join(''), "file"];
+ this.files++;
+ }
+ if (tmp[0] === 0x50 && tmp[1] === 0x4b) { //ZIP
+ this.modeZIP = true;
+ tmp[2] = this.readByte();
+ tmp[3] = this.readByte();
+ if (tmp[2] === 0x03 && tmp[3] === 0x04) {
+ //MODE_ZIP
+ tmp[0] = this.readByte();
+ tmp[1] = this.readByte();
+ // if (this.debug) alert("ZIP-Version: "+tmp[1]+" "+tmp[0]/10+"."+tmp[0]%10);
+
+ this.gpflags = this.readByte();
+ this.gpflags |= (this.readByte() << 8);
+ // if (this.debug) alert("gpflags: "+this.gpflags);
+
+ var method = this.readByte();
+ method |= (this.readByte() << 8);
+ // if (this.debug) alert("method: "+method);
+
+ this.readByte();
+ this.readByte();
+ this.readByte();
+ this.readByte();
+
+// var crc = this.readByte();
+// crc |= (this.readByte()<<8);
+// crc |= (this.readByte()<<16);
+// crc |= (this.readByte()<<24);
+
+ var compSize = this.readByte();
+ compSize |= (this.readByte() << 8);
+ compSize |= (this.readByte() << 16);
+ compSize |= (this.readByte() << 24);
+
+ var size = this.readByte();
+ size |= (this.readByte() << 8);
+ size |= (this.readByte() << 16);
+ size |= (this.readByte() << 24);
+
+ // if (this.debug) alert("local CRC: "+crc+"\nlocal Size: "+size+"\nlocal CompSize: "+compSize);
+
+ var filelen = this.readByte();
+ filelen |= (this.readByte() << 8);
+
+ var extralen = this.readByte();
+ extralen |= (this.readByte() << 8);
+
+ // if (this.debug) alert("filelen "+filelen);
+ i = 0;
+ this.nameBuf = [];
+ while (filelen--) {
+ var c = this.readByte();
+ if (c === "/" | c === ":") {
+ i = 0;
+ } else if (i < cc.Codec.GZip.NAMEMAX - 1) {
+ this.nameBuf[i++] = String.fromCharCode(c);
+ }
+ }
+ // if (this.debug) alert("nameBuf: "+this.nameBuf);
+
+ if (!this.fileout) this.fileout = this.nameBuf;
+
+ var i = 0;
+ while (i < extralen) {
+ c = this.readByte();
+ i++;
+ }
+
+ // if (size = 0 && this.fileOut.charAt(this.fileout.length-1)=="/"){
+ // //skipdir
+ // // if (this.debug) alert("skipdir");
+ // }
+ if (method === 8) {
+ this.DeflateLoop();
+ // if (this.debug) alert(this.outputArr.join(''));
+ this.unzipped[this.files] = [this.outputArr.join(''), this.nameBuf.join('')];
+ this.files++;
+ }
+ this.skipdir();
+ }
+ }
+};
+
+cc.Codec.GZip.prototype.skipdir = function () {
+ var tmp = [];
+ var compSize, size, os, i, c;
+
+ if ((this.gpflags & 8)) {
+ tmp[0] = this.readByte();
+ tmp[1] = this.readByte();
+ tmp[2] = this.readByte();
+ tmp[3] = this.readByte();
+
+// if (tmp[0] == 0x50 && tmp[1] == 0x4b && tmp[2] == 0x07 && tmp[3] == 0x08) {
+// crc = this.readByte();
+// crc |= (this.readByte()<<8);
+// crc |= (this.readByte()<<16);
+// crc |= (this.readByte()<<24);
+// } else {
+// crc = tmp[0] | (tmp[1]<<8) | (tmp[2]<<16) | (tmp[3]<<24);
+// }
+
+ compSize = this.readByte();
+ compSize |= (this.readByte() << 8);
+ compSize |= (this.readByte() << 16);
+ compSize |= (this.readByte() << 24);
+
+ size = this.readByte();
+ size |= (this.readByte() << 8);
+ size |= (this.readByte() << 16);
+ size |= (this.readByte() << 24);
+ }
+
+ if (this.modeZIP) this.nextFile();
+
+ tmp[0] = this.readByte();
+ if (tmp[0] !== 8) {
+ // if (this.debug) alert("Unknown compression method!");
+ return 0;
+ }
+
+ this.gpflags = this.readByte();
+ // if (this.debug && (this.gpflags & ~(0x1f))) alert("Unknown flags set!");
+
+ this.readByte();
+ this.readByte();
+ this.readByte();
+ this.readByte();
+
+ this.readByte();
+ os = this.readByte();
+
+ if ((this.gpflags & 4)) {
+ tmp[0] = this.readByte();
+ tmp[2] = this.readByte();
+ this.len = tmp[0] + 256 * tmp[1];
+ // if (this.debug) alert("Extra field size: "+this.len);
+ for (i = 0; i < this.len; i++)
+ this.readByte();
+ }
+
+ if ((this.gpflags & 8)) {
+ i = 0;
+ this.nameBuf = [];
+ while (c = this.readByte()) {
+ if (c === "7" || c === ":")
+ i = 0;
+ if (i < cc.Codec.GZip.NAMEMAX - 1)
+ this.nameBuf[i++] = c;
+ }
+ //this.nameBuf[i] = "\0";
+ // if (this.debug) alert("original file name: "+this.nameBuf);
+ }
+
+ if ((this.gpflags & 16)) {
+ while (c = this.readByte()) { // FIXME: looks like they read to the end of the stream, should be doable more efficiently
+ //FILE COMMENT
+ }
+ }
+
+ if ((this.gpflags & 2)) {
+ this.readByte();
+ this.readByte();
+ }
+
+ this.DeflateLoop();
+
+// crc = this.readByte();
+// crc |= (this.readByte()<<8);
+// crc |= (this.readByte()<<16);
+// crc |= (this.readByte()<<24);
+
+ size = this.readByte();
+ size |= (this.readByte() << 8);
+ size |= (this.readByte() << 16);
+ size |= (this.readByte() << 24);
+
+ if (this.modeZIP) this.nextFile();
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/compression/zlib.min.js b/frameworks/cocos2d-html5/cocos2d/compression/zlib.min.js
new file mode 100644
index 0000000..6839e7b
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/compression/zlib.min.js
@@ -0,0 +1,55 @@
+/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */
+(function() {'use strict';function i(a){throw a;}var r=void 0,v=!0,aa=this;function y(a,c){var b=a.split("."),e=aa;!(b[0]in e)&&e.execScript&&e.execScript("var "+b[0]);for(var f;b.length&&(f=b.shift());)!b.length&&c!==r?e[f]=c:e=e[f]?e[f]:e[f]={}};var H="undefined"!==typeof Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array;function ba(a){if("string"===typeof a){var c=a.split(""),b,e;b=0;for(e=c.length;b>>0;a=c}for(var f=1,d=0,g=a.length,h,m=0;0>>0};function J(a,c){this.index="number"===typeof c?c:0;this.i=0;this.buffer=a instanceof(H?Uint8Array:Array)?a:new (H?Uint8Array:Array)(32768);2*this.buffer.length<=this.index&&i(Error("invalid index"));this.buffer.length<=this.index&&this.f()}J.prototype.f=function(){var a=this.buffer,c,b=a.length,e=new (H?Uint8Array:Array)(b<<1);if(H)e.set(a);else for(c=0;c>>8&255]<<16|N[a>>>16&255]<<8|N[a>>>24&255])>>32-c:N[a]>>8-c);if(8>c+d)g=g<>c-h-1&1,8===++d&&(d=0,e[f++]=N[g],g=0,f===e.length&&(e=this.f()));e[f]=g;this.buffer=e;this.i=d;this.index=f};J.prototype.finish=function(){var a=this.buffer,c=this.index,b;0ha;++ha){for(var R=ha,ia=R,ja=7,R=R>>>1;R;R>>>=1)ia<<=1,ia|=R&1,--ja;ca[ha]=(ia<>>0}var N=ca;var ka=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,
+2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,
+2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,
+2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,
+3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,
+936918E3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];H&&new Uint32Array(ka);function la(a){this.buffer=new (H?Uint16Array:Array)(2*a);this.length=0}la.prototype.getParent=function(a){return 2*((a-2)/4|0)};la.prototype.push=function(a,c){var b,e,f=this.buffer,d;b=this.length;f[this.length++]=c;for(f[this.length++]=a;0f[e])d=f[b],f[b]=f[e],f[e]=d,d=f[b+1],f[b+1]=f[e+1],f[e+1]=d,b=e;else break;return this.length};
+la.prototype.pop=function(){var a,c,b=this.buffer,e,f,d;c=b[0];a=b[1];this.length-=2;b[0]=b[this.length];b[1]=b[this.length+1];for(d=0;;){f=2*d+2;if(f>=this.length)break;f+2b[f]&&(f+=2);if(b[f]>b[d])e=b[d],b[d]=b[f],b[f]=e,e=b[d+1],b[d+1]=b[f+1],b[f+1]=e;else break;d=f}return{index:a,value:c,length:this.length}};function S(a){var c=a.length,b=0,e=Number.POSITIVE_INFINITY,f,d,g,h,m,j,s,n,l;for(n=0;nb&&(b=a[n]),a[n]>=1;for(l=j;lT;T++)switch(v){case 143>=T:ra.push([T+48,8]);break;case 255>=T:ra.push([T-144+400,9]);break;case 279>=T:ra.push([T-256+0,7]);break;case 287>=T:ra.push([T-280+192,8]);break;default:i("invalid literal: "+T)}
+ma.prototype.n=function(){var a,c,b,e,f=this.input;switch(this.h){case 0:b=0;for(e=f.length;b>>8&255;l[q++]=j&255;l[q++]=j>>>8&255;if(H)l.set(d,q),q+=d.length,l=l.subarray(0,q);else{s=0;for(n=d.length;sw)for(;0w?w:138,G>w-3&&G=G?(L[I++]=17,L[I++]=G-3,P[17]++):(L[I++]=18,L[I++]=G-11,P[18]++),w-=G;else if(L[I++]=M[u],P[M[u]]++,w--,3>w)for(;0w?w:6,G>w-3&&GF;F++)va[F]=na[da[F]];for(C=19;4=a:return[265,a-11,1];case 14>=a:return[266,a-13,1];case 16>=a:return[267,a-15,1];case 18>=a:return[268,a-17,1];case 22>=a:return[269,a-19,2];case 26>=a:return[270,a-23,2];case 30>=a:return[271,a-27,2];case 34>=a:return[272,a-
+31,2];case 42>=a:return[273,a-35,3];case 50>=a:return[274,a-43,3];case 58>=a:return[275,a-51,3];case 66>=a:return[276,a-59,3];case 82>=a:return[277,a-67,4];case 98>=a:return[278,a-83,4];case 114>=a:return[279,a-99,4];case 130>=a:return[280,a-115,4];case 162>=a:return[281,a-131,5];case 194>=a:return[282,a-163,5];case 226>=a:return[283,a-195,5];case 257>=a:return[284,a-227,5];case 258===a:return[285,a-258,0];default:i("invalid length: "+a)}}var Aa=[],za,Ba;
+for(za=3;258>=za;za++)Ba=xa(),Aa[za]=Ba[2]<<24|Ba[1]<<16|Ba[0];var Ca=H?new Uint32Array(Aa):Aa;
+function sa(a,c){function b(a,c){var b=a.G,d=[],e=0,f;f=Ca[a.length];d[e++]=f&65535;d[e++]=f>>16&255;d[e++]=f>>24;var g;switch(v){case 1===b:g=[0,b-1,0];break;case 2===b:g=[1,b-2,0];break;case 3===b:g=[2,b-3,0];break;case 4===b:g=[3,b-4,0];break;case 6>=b:g=[4,b-5,1];break;case 8>=b:g=[5,b-7,1];break;case 12>=b:g=[6,b-9,2];break;case 16>=b:g=[7,b-13,2];break;case 24>=b:g=[8,b-17,3];break;case 32>=b:g=[9,b-25,3];break;case 48>=b:g=[10,b-33,4];break;case 64>=b:g=[11,b-49,4];break;case 96>=b:g=[12,b-
+65,5];break;case 128>=b:g=[13,b-97,5];break;case 192>=b:g=[14,b-129,6];break;case 256>=b:g=[15,b-193,6];break;case 384>=b:g=[16,b-257,7];break;case 512>=b:g=[17,b-385,7];break;case 768>=b:g=[18,b-513,8];break;case 1024>=b:g=[19,b-769,8];break;case 1536>=b:g=[20,b-1025,9];break;case 2048>=b:g=[21,b-1537,9];break;case 3072>=b:g=[22,b-2049,10];break;case 4096>=b:g=[23,b-3073,10];break;case 6144>=b:g=[24,b-4097,11];break;case 8192>=b:g=[25,b-6145,11];break;case 12288>=b:g=[26,b-8193,12];break;case 16384>=
+b:g=[27,b-12289,12];break;case 24576>=b:g=[28,b-16385,13];break;case 32768>=b:g=[29,b-24577,13];break;default:i("invalid distance")}f=g;d[e++]=f[0];d[e++]=f[1];d[e++]=f[2];var h,j;h=0;for(j=d.length;h=d;)t[d++]=0;for(d=0;29>=d;)z[d++]=0}t[256]=1;e=0;for(f=c.length;e=f){n&&b(n,-1);d=0;for(g=f-e;dp&&e+pk&&(B=x,k=p);if(258===p)break}s=new wa(k,e-B);n?n.length2*l[k-1]+q[k]&&(l[k]=2*l[k-1]+q[k]),t[k]=Array(l[k]),z[k]=Array(l[k]);for(B=0;Bh[B]?(t[k][p]=D,z[k][p]=n,C+=2):
+(t[k][p]=h[B],z[k][p]=B,++B);K[k]=0;1===q[k]&&b(k)}m=E;j=0;for(s=g.length;j1<f&&i("undercommitted");d=0;for(g=a.length;d>>=1}return c};function Da(a,c){this.input=a;this.a=new (H?Uint8Array:Array)(32768);this.h=U.j;var b={},e;if((c||!(c={}))&&"number"===typeof c.compressionType)this.h=c.compressionType;for(e in c)b[e]=c[e];b.outputBuffer=this.a;this.z=new ma(this.input,b)}var U=qa;
+Da.prototype.n=function(){var a,c,b,e,f,d,g,h=0;g=this.a;a=Ea;switch(a){case Ea:c=Math.LOG2E*Math.log(32768)-8;break;default:i(Error("invalid compression method"))}b=c<<4|a;g[h++]=b;switch(a){case Ea:switch(this.h){case U.NONE:f=0;break;case U.r:f=1;break;case U.j:f=2;break;default:i(Error("unsupported compression type"))}break;default:i(Error("invalid compression method"))}e=f<<6|0;g[h++]=e|31-(256*b+e)%31;d=ba(this.input);this.z.b=h;g=this.z.n();h=g.length;H&&(g=new Uint8Array(g.buffer),g.length<=
+h+4&&(this.a=new Uint8Array(g.length+4),this.a.set(g),g=this.a),g=g.subarray(0,h+4));g[h++]=d>>24&255;g[h++]=d>>16&255;g[h++]=d>>8&255;g[h++]=d&255;return g};y("Zlib.Deflate",Da);y("Zlib.Deflate.compress",function(a,c){return(new Da(a,c)).n()});y("Zlib.Deflate.CompressionType",U);y("Zlib.Deflate.CompressionType.NONE",U.NONE);y("Zlib.Deflate.CompressionType.FIXED",U.r);y("Zlib.Deflate.CompressionType.DYNAMIC",U.j);function V(a,c){this.k=[];this.l=32768;this.e=this.g=this.c=this.q=0;this.input=H?new Uint8Array(a):a;this.s=!1;this.m=Fa;this.B=!1;if(c||!(c={}))c.index&&(this.c=c.index),c.bufferSize&&(this.l=c.bufferSize),c.bufferType&&(this.m=c.bufferType),c.resize&&(this.B=c.resize);switch(this.m){case Ga:this.b=32768;this.a=new (H?Uint8Array:Array)(32768+this.l+258);break;case Fa:this.b=0;this.a=new (H?Uint8Array:Array)(this.l);this.f=this.J;this.t=this.H;this.o=this.I;break;default:i(Error("invalid inflate mode"))}}
+var Ga=0,Fa=1,Ha={D:Ga,C:Fa};
+V.prototype.p=function(){for(;!this.s;){var a=X(this,3);a&1&&(this.s=v);a>>>=1;switch(a){case 0:var c=this.input,b=this.c,e=this.a,f=this.b,d=r,g=r,h=r,m=e.length,j=r;this.e=this.g=0;d=c[b++];d===r&&i(Error("invalid uncompressed block header: LEN (first byte)"));g=d;d=c[b++];d===r&&i(Error("invalid uncompressed block header: LEN (second byte)"));g|=d<<8;d=c[b++];d===r&&i(Error("invalid uncompressed block header: NLEN (first byte)"));h=d;d=c[b++];d===r&&i(Error("invalid uncompressed block header: NLEN (second byte)"));h|=
+d<<8;g===~h&&i(Error("invalid uncompressed block header: length verify"));b+g>c.length&&i(Error("input buffer is broken"));switch(this.m){case Ga:for(;f+g>e.length;){j=m-f;g-=j;if(H)e.set(c.subarray(b,b+j),f),f+=j,b+=j;else for(;j--;)e[f++]=c[b++];this.b=f;e=this.f();f=this.b}break;case Fa:for(;f+g>e.length;)e=this.f({v:2});break;default:i(Error("invalid inflate mode"))}if(H)e.set(c.subarray(b,b+g),f),f+=g,b+=g;else for(;g--;)e[f++]=c[b++];this.c=b;this.b=f;this.a=e;break;case 1:this.o(Ia,Ja);break;
+case 2:Ka(this);break;default:i(Error("unknown BTYPE: "+a))}}return this.t()};
+var La=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],Za=H?new Uint16Array(La):La,$a=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258],ab=H?new Uint16Array($a):$a,bb=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0],cb=H?new Uint8Array(bb):bb,db=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],eb=H?new Uint16Array(db):db,fb=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,
+10,11,11,12,12,13,13],gb=H?new Uint8Array(fb):fb,hb=new (H?Uint8Array:Array)(288),Y,ib;Y=0;for(ib=hb.length;Y=Y?8:255>=Y?9:279>=Y?7:8;var Ia=S(hb),jb=new (H?Uint8Array:Array)(30),kb,lb;kb=0;for(lb=jb.length;kb>>c;a.e=e-c;a.c=d;return g}
+function mb(a,c){for(var b=a.g,e=a.e,f=a.input,d=a.c,g=c[0],h=c[1],m,j,s;e>>16;a.g=b>>s;a.e=e-s;a.c=d;return j&65535}
+function Ka(a){function c(a,b,c){var d,e,f,g;for(g=0;gd)e>=f&&(this.b=e,b=this.f(),e=this.b),b[e++]=d;else{g=d-257;m=ab[g];0=f&&(this.b=e,b=this.f(),e=this.b);for(;m--;)b[e]=b[e++-h]}for(;8<=this.e;)this.e-=8,this.c--;this.b=e};
+V.prototype.I=function(a,c){var b=this.a,e=this.b;this.u=a;for(var f=b.length,d,g,h,m;256!==(d=mb(this,a));)if(256>d)e>=f&&(b=this.f(),f=b.length),b[e++]=d;else{g=d-257;m=ab[g];0f&&(b=this.f(),f=b.length);for(;m--;)b[e]=b[e++-h]}for(;8<=this.e;)this.e-=8,this.c--;this.b=e};
+V.prototype.f=function(){var a=new (H?Uint8Array:Array)(this.b-32768),c=this.b-32768,b,e,f=this.a;if(H)a.set(f.subarray(32768,a.length));else{b=0;for(e=a.length;bb;++b)f[b]=f[c+b];this.b=32768;return f};
+V.prototype.J=function(a){var c,b=this.input.length/this.c+1|0,e,f,d,g=this.input,h=this.a;a&&("number"===typeof a.v&&(b=a.v),"number"===typeof a.F&&(b+=a.F));2>b?(e=(g.length-this.c)/this.u[2],d=258*(e/2)|0,f=dc&&(this.a.length=c),a=this.a);return this.buffer=a};function nb(a,c){var b,e;this.input=a;this.c=0;if(c||!(c={}))c.index&&(this.c=c.index),c.verify&&(this.M=c.verify);b=a[this.c++];e=a[this.c++];switch(b&15){case Ea:this.method=Ea;break;default:i(Error("unsupported compression method"))}0!==((b<<8)+e)%31&&i(Error("invalid fcheck flag:"+((b<<8)+e)%31));e&32&&i(Error("fdict flag is not supported"));this.A=new V(a,{index:this.c,bufferSize:c.bufferSize,bufferType:c.bufferType,resize:c.resize})}
+nb.prototype.p=function(){var a=this.input,c,b;c=this.A.p();this.c=this.A.c;this.M&&(b=(a[this.c++]<<24|a[this.c++]<<16|a[this.c++]<<8|a[this.c++])>>>0,b!==ba(c)&&i(Error("invalid adler-32 checksum")));return c};y("Zlib.Inflate",nb);y("Zlib.Inflate.BufferType",Ha);Ha.ADAPTIVE=Ha.C;Ha.BLOCK=Ha.D;y("Zlib.Inflate.prototype.decompress",nb.prototype.p);var ob=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];H&&new Uint16Array(ob);var pb=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258];H&&new Uint16Array(pb);var qb=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0];H&&new Uint8Array(qb);var rb=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577];H&&new Uint16Array(rb);
+var sb=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13];H&&new Uint8Array(sb);var tb=new (H?Uint8Array:Array)(288),Z,ub;Z=0;for(ub=tb.length;Z=Z?8:255>=Z?9:279>=Z?7:8;S(tb);var vb=new (H?Uint8Array:Array)(30),wb,xb;wb=0;for(xb=vb.length;wb
+ * Normally you won't need to use this class directly. 99% of the cases you will use the CCNode interface,
+ * which uses this class's singleton object.
+ * But there are some cases where you might need to use this class.
+ * Examples:
+ * - When you want to run an action where the target is different from a CCNode.
+ * - When you want to pause / resume the actions
+ * @class
+ * @extends cc.Class
+ * @example
+ * var mng = new cc.ActionManager();
+ */
+cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
+ _elementPool: [],
+
+ _searchElementByTarget:function (arr, target) {
+ for (var k = 0; k < arr.length; k++) {
+ if (target === arr[k].target)
+ return arr[k];
+ }
+ return null;
+ },
+
+ ctor:function () {
+ this._hashTargets = {};
+ this._arrayTargets = [];
+ this._currentTarget = null;
+ },
+
+ _getElement: function (target, paused) {
+ var element = this._elementPool.pop();
+ if (!element) {
+ element = new cc.HashElement();
+ }
+ element.target = target;
+ element.paused = !!paused;
+ return element;
+ },
+
+ _putElement: function (element) {
+ element.actions.length = 0;
+ element.actionIndex = 0;
+ element.currentAction = null;
+ element.paused = false;
+ element.target = null;
+ element.lock = false;
+ this._elementPool.push(element);
+ },
+
+ /** Adds an action with a target.
+ * If the target is already present, then the action will be added to the existing target.
+ * If the target is not present, a new instance of this target will be created either paused or not, and the action will be added to the newly created target.
+ * When the target is paused, the queued actions won't be 'ticked'.
+ * @param {cc.Action} action
+ * @param {cc.Node} target
+ * @param {Boolean} paused
+ */
+ addAction:function (action, target, paused) {
+ if(!action)
+ throw new Error("cc.ActionManager.addAction(): action must be non-null");
+ if(!target)
+ throw new Error("cc.ActionManager.addAction(): target must be non-null");
+
+ //check if the action target already exists
+ var element = this._hashTargets[target.__instanceId];
+ //if doesn't exists, create a hashelement and push in mpTargets
+ if (!element) {
+ element = this._getElement(target, paused);
+ this._hashTargets[target.__instanceId] = element;
+ this._arrayTargets.push(element);
+ }
+ else if (!element.actions) {
+ element.actions = [];
+ }
+
+ element.actions.push(action);
+ action.startWithTarget(target);
+ },
+
+ /**
+ * Removes all actions from all the targets.
+ */
+ removeAllActions:function () {
+ var locTargets = this._arrayTargets;
+ for (var i = 0; i < locTargets.length; i++) {
+ var element = locTargets[i];
+ if (element)
+ this.removeAllActionsFromTarget(element.target, true);
+ }
+ },
+ /** Removes all actions from a certain target.
+ * All the actions that belongs to the target will be removed.
+ * @param {object} target
+ * @param {boolean} forceDelete
+ */
+ removeAllActionsFromTarget:function (target, forceDelete) {
+ // explicit null handling
+ if (target == null)
+ return;
+ var element = this._hashTargets[target.__instanceId];
+ if (element) {
+ element.actions.length = 0;
+ this._deleteHashElement(element);
+ }
+ },
+ /** Removes an action given an action reference.
+ * @param {cc.Action} action
+ */
+ removeAction:function (action) {
+ // explicit null handling
+ if (action == null)
+ return;
+ var target = action.getOriginalTarget();
+ var element = this._hashTargets[target.__instanceId];
+
+ if (element) {
+ for (var i = 0; i < element.actions.length; i++) {
+ if (element.actions[i] === action) {
+ element.actions.splice(i, 1);
+ // update actionIndex in case we are in tick. looping over the actions
+ if (element.actionIndex >= i)
+ element.actionIndex--;
+ break;
+ }
+ }
+ } else {
+ cc.log(cc._LogInfos.ActionManager_removeAction);
+ }
+ },
+
+ /** Removes an action given its tag and the target
+ * @param {Number} tag
+ * @param {object} target
+ */
+ removeActionByTag:function (tag, target) {
+ if(tag === cc.ACTION_TAG_INVALID)
+ cc.log(cc._LogInfos.ActionManager_addAction);
+
+ cc.assert(target, cc._LogInfos.ActionManager_addAction);
+
+ var element = this._hashTargets[target.__instanceId];
+
+ if (element) {
+ var limit = element.actions.length;
+ for (var i = 0; i < limit; ++i) {
+ var action = element.actions[i];
+ if (action && action.getTag() === tag && action.getOriginalTarget() === target) {
+ this._removeActionAtIndex(i, element);
+ break;
+ }
+ }
+ }
+ },
+
+ /** Gets an action given its tag an a target
+ * @param {Number} tag
+ * @param {object} target
+ * @return {cc.Action|Null} return the Action with the given tag on success
+ */
+ getActionByTag:function (tag, target) {
+ if(tag === cc.ACTION_TAG_INVALID)
+ cc.log(cc._LogInfos.ActionManager_getActionByTag);
+
+ var element = this._hashTargets[target.__instanceId];
+ if (element) {
+ if (element.actions != null) {
+ for (var i = 0; i < element.actions.length; ++i) {
+ var action = element.actions[i];
+ if (action && action.getTag() === tag)
+ return action;
+ }
+ }
+ cc.log(cc._LogInfos.ActionManager_getActionByTag_2, tag);
+ }
+ return null;
+ },
+
+
+ /** Returns the numbers of actions that are running in a certain target.
+ * Composable actions are counted as 1 action.
+ * Example:
+ * - If you are running 1 Sequence of 7 actions, it will return 1.
+ * - If you are running 7 Sequences of 2 actions, it will return 7.
+ * @param {object} target
+ * @return {Number}
+ */
+ numberOfRunningActionsInTarget:function (target) {
+ var element = this._hashTargets[target.__instanceId];
+ if (element)
+ return (element.actions) ? element.actions.length : 0;
+
+ return 0;
+ },
+ /** Pauses the target: all running actions and newly added actions will be paused.
+ * @param {object} target
+ */
+ pauseTarget:function (target) {
+ var element = this._hashTargets[target.__instanceId];
+ if (element)
+ element.paused = true;
+ },
+ /** Resumes the target. All queued actions will be resumed.
+ * @param {object} target
+ */
+ resumeTarget:function (target) {
+ var element = this._hashTargets[target.__instanceId];
+ if (element)
+ element.paused = false;
+ },
+
+ /**
+ * Pauses all running actions, returning a list of targets whose actions were paused.
+ * @return {Array} a list of targets whose actions were paused.
+ */
+ pauseAllRunningActions:function(){
+ var idsWithActions = [];
+ var locTargets = this._arrayTargets;
+ for(var i = 0; i< locTargets.length; i++){
+ var element = locTargets[i];
+ if(element && !element.paused){
+ element.paused = true;
+ idsWithActions.push(element.target);
+ }
+ }
+ return idsWithActions;
+ },
+
+ /**
+ * Resume a set of targets (convenience function to reverse a pauseAllRunningActions call)
+ * @param {Array} targetsToResume
+ */
+ resumeTargets:function(targetsToResume){
+ if (!targetsToResume)
+ return;
+
+ for (var i = 0; i< targetsToResume.length; i++) {
+ if(targetsToResume[i])
+ this.resumeTarget(targetsToResume[i]);
+ }
+ },
+
+ /** purges the shared action manager. It releases the retained instance.
+ * because it uses this, so it can not be static
+ */
+ purgeSharedManager:function () {
+ cc.director.getScheduler().unscheduleUpdate(this);
+ },
+
+ //protected
+ _removeActionAtIndex:function (index, element) {
+ var action = element.actions[index];
+
+ element.actions.splice(index, 1);
+
+ // update actionIndex in case we are in tick. looping over the actions
+ if (element.actionIndex >= index)
+ element.actionIndex--;
+
+ if (element.actions.length === 0) {
+ this._deleteHashElement(element);
+ }
+ },
+
+ _deleteHashElement:function (element) {
+ var ret = false;
+ if (element && !element.lock) {
+ if (this._hashTargets[element.target.__instanceId]) {
+ delete this._hashTargets[element.target.__instanceId];
+ var targets = this._arrayTargets;
+ for (var i = 0, l = targets.length; i < l; i++) {
+ if (targets[i] === element) {
+ targets.splice(i, 1);
+ break;
+ }
+ }
+ this._putElement(element);
+ ret = true;
+ }
+ }
+ return ret;
+ },
+
+ /**
+ * @param {Number} dt delta time in seconds
+ */
+ update:function (dt) {
+ var locTargets = this._arrayTargets , locCurrTarget;
+ for (var elt = 0; elt < locTargets.length; elt++) {
+ this._currentTarget = locTargets[elt];
+ locCurrTarget = this._currentTarget;
+ if (!locCurrTarget.paused && locCurrTarget.actions) {
+ locCurrTarget.lock = true;
+ // The 'actions' CCMutableArray may change while inside this loop.
+ for (locCurrTarget.actionIndex = 0; locCurrTarget.actionIndex < locCurrTarget.actions.length; locCurrTarget.actionIndex++) {
+ locCurrTarget.currentAction = locCurrTarget.actions[locCurrTarget.actionIndex];
+ if (!locCurrTarget.currentAction)
+ continue;
+
+ //use for speed
+ locCurrTarget.currentAction.step(dt * ( locCurrTarget.currentAction._speedMethod ? locCurrTarget.currentAction._speed : 1 ) );
+
+ if (locCurrTarget.currentAction && locCurrTarget.currentAction.isDone()) {
+ locCurrTarget.currentAction.stop();
+ var action = locCurrTarget.currentAction;
+ locCurrTarget.currentAction = null;
+ this.removeAction(action);
+ }
+
+ locCurrTarget.currentAction = null;
+ }
+ locCurrTarget.lock = false;
+ }
+ // only delete currentTarget if no actions were scheduled during the cycle (issue #481)
+ if (locCurrTarget.actions.length === 0) {
+ this._deleteHashElement(locCurrTarget) && elt--;
+ }
+ }
+ }
+});
diff --git a/frameworks/cocos2d-html5/cocos2d/core/CCConfiguration.js b/frameworks/cocos2d-html5/cocos2d/core/CCConfiguration.js
new file mode 100644
index 0000000..db58df2
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/CCConfiguration.js
@@ -0,0 +1,294 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.configuration is a singleton object which contains some openGL variables
+ * @class
+ * @name cc.configuration
+ * @example
+ * var textureSize = cc.configuration.getMaxTextureSize();
+ */
+cc.configuration = /** @lends cc.configuration# */{
+ // Type constants
+ /*
+ * ERROR type
+ * @public
+ * @const
+ * @type {Number}
+ */
+ ERROR:0,
+
+ /*
+ * STRING type
+ * @public
+ * @const
+ * @type {Number}
+ */
+ STRING:1,
+
+ /*
+ * INT type
+ * @public
+ * @const
+ * @type {Number}
+ */
+ INT:2,
+
+ /*
+ * DOUBLE type
+ * @public
+ * @const
+ * @type {Number}
+ */
+ DOUBLE:3,
+
+ /*
+ * BOOLEAN type
+ * @public
+ * @const
+ * @type {Number}
+ */
+ BOOLEAN:4,
+
+ _maxTextureSize:0,
+ _maxModelviewStackDepth:0,
+ _supportsPVRTC:false,
+ _supportsNPOT:false,
+ _supportsBGRA8888:false,
+ _supportsDiscardFramebuffer:false,
+ _supportsShareableVAO:false,
+ _maxSamplesAllowed:0,
+ _maxTextureUnits:0,
+ _GlExtensions:"",
+ _valueDict:{},
+
+ _inited: false,
+
+ _init:function () {
+ var locValueDict = this._valueDict;
+ locValueDict["cocos2d.x.version"] = cc.ENGINE_VERSION;
+ locValueDict["cocos2d.x.compiled_with_profiler"] = false;
+ locValueDict["cocos2d.x.compiled_with_gl_state_cache"] = cc.ENABLE_GL_STATE_CACHE;
+ this._inited = true;
+ },
+
+ /**
+ * OpenGL Max texture size.
+ * @return {Number}
+ */
+ getMaxTextureSize:function () {
+ return this._maxTextureSize;
+ },
+
+ /**
+ * OpenGL Max Modelview Stack Depth.
+ * @return {Number}
+ */
+ getMaxModelviewStackDepth:function () {
+ return this._maxModelviewStackDepth;
+ },
+
+ /**
+ * returns the maximum texture units
+ * @return {Number}
+ */
+ getMaxTextureUnits:function () {
+ return this._maxTextureUnits;
+ },
+
+ /**
+ * Whether or not the GPU supports NPOT (Non Power Of Two) textures.
+ * OpenGL ES 2.0 already supports NPOT (iOS).
+ * @return {Boolean}
+ */
+ supportsNPOT:function () {
+ return this._supportsNPOT;
+ },
+
+ /**
+ * Whether or not PVR Texture Compressed is supported
+ * @return {Boolean}
+ */
+ supportsPVRTC: function () {
+ return this._supportsPVRTC;
+ },
+
+ /**
+ * Whether or not ETC Texture Compressed is supported
+ * @return {Boolean}
+ */
+ supportsETC: function() {
+ return false;
+ },
+
+ /**
+ * Whether or not S3TC Texture Compressed is supported
+ * @return {Boolean}
+ */
+ supportsS3TC: function() {
+ return false;
+ },
+
+ /**
+ * Whether or not ATITC Texture Compressed is supported
+ * @return {Boolean}
+ */
+ supportsATITC: function() {
+ return false;
+ },
+
+ /**
+ * Whether or not BGRA8888 textures are supported.
+ * @return {Boolean}
+ */
+ supportsBGRA8888:function () {
+ return this._supportsBGRA8888;
+ },
+
+ /**
+ * Whether or not glDiscardFramebufferEXT is supported
+ * @return {Boolean}
+ */
+ supportsDiscardFramebuffer:function () {
+ return this._supportsDiscardFramebuffer;
+ },
+
+ /**
+ * Whether or not shareable VAOs are supported.
+ * @return {Boolean}
+ */
+ supportsShareableVAO:function () {
+ return this._supportsShareableVAO;
+ },
+
+ /**
+ * returns whether or not an OpenGL is supported
+ * @param {String} searchName
+ */
+ checkForGLExtension:function (searchName) {
+ return this._GlExtensions.indexOf(searchName) > -1;
+ },
+
+ /**
+ * Returns the value of a given key. If the key is not found, it will return the default value
+ * @param {String} key
+ * @param {String|Bool|Number|Object} [default_value=null]
+ * @returns {String|Bool|Number|Object}
+ */
+ getValue: function(key, default_value){
+ if(!this._inited)
+ this._init();
+ var locValueDict = this._valueDict;
+ if(locValueDict[key])
+ return locValueDict[key];
+ return default_value;
+ },
+
+ /**
+ * Sets a new key/value pair in the configuration dictionary
+ * @param {string} key
+ * @param {String|Bool|Number|Object} value
+ */
+ setValue: function(key, value){
+ this._valueDict[key] = value;
+ },
+
+ /**
+ * Dumps the current configuration on the console
+ */
+ dumpInfo: function(){
+ if(cc.ENABLE_GL_STATE_CACHE === 0){
+ cc.log("");
+ cc.log(cc._LogInfos.configuration_dumpInfo);
+ cc.log("")
+ }
+ },
+
+ /**
+ * gathers OpenGL / GPU information
+ */
+ gatherGPUInfo: function(){
+ if(cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return;
+
+ if(!this._inited)
+ this._init();
+ var gl = cc._renderContext;
+ var locValueDict = this._valueDict;
+ locValueDict["gl.vendor"] = gl.getParameter(gl.VENDOR);
+ locValueDict["gl.renderer"] = gl.getParameter(gl.RENDERER);
+ locValueDict["gl.version"] = gl.getParameter(gl.VERSION);
+
+ this._GlExtensions = "";
+ var extArr = gl.getSupportedExtensions();
+ for (var i = 0; i < extArr.length; i++)
+ this._GlExtensions += extArr[i] + " ";
+
+ this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
+ locValueDict["gl.max_texture_size"] = this._maxTextureSize;
+ this._maxTextureUnits = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+ locValueDict["gl.max_texture_units"] = this._maxTextureUnits;
+
+ this._supportsPVRTC = this.checkForGLExtension("GL_IMG_texture_compression_pvrtc");
+ locValueDict["gl.supports_PVRTC"] = this._supportsPVRTC;
+
+ this._supportsNPOT = false; //true;
+ locValueDict["gl.supports_NPOT"] = this._supportsNPOT;
+
+ this._supportsBGRA8888 = this.checkForGLExtension("GL_IMG_texture_format_BGRA888");
+ locValueDict["gl.supports_BGRA8888"] = this._supportsBGRA8888;
+
+ this._supportsDiscardFramebuffer = this.checkForGLExtension("GL_EXT_discard_framebuffer");
+ locValueDict["gl.supports_discard_framebuffer"] = this._supportsDiscardFramebuffer;
+
+ this._supportsShareableVAO = this.checkForGLExtension("vertex_array_object");
+ locValueDict["gl.supports_vertex_array_object"] = this._supportsShareableVAO;
+
+ cc.checkGLErrorDebug();
+ },
+
+ /**
+ * Loads a config file. If the keys are already present, then they are going to be replaced. Otherwise the new keys are added.
+ * @param {string} url
+ */
+ loadConfigFile: function( url){
+ if(!this._inited)
+ this._init();
+ var dict = cc.loader.getRes(url);
+ if(!dict) throw new Error("Please load the resource first : " + url);
+ cc.assert(dict, cc._LogInfos.configuration_loadConfigFile_2, url);
+
+ var getDatas = dict["data"];
+ if(!getDatas){
+ cc.log(cc._LogInfos.configuration_loadConfigFile, url);
+ return;
+ }
+
+ // Add all keys in the existing dictionary
+ for(var selKey in getDatas)
+ this._valueDict[selKey] = getDatas[selKey];
+ }
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/CCDirector.js b/frameworks/cocos2d-html5/cocos2d/core/CCDirector.js
new file mode 100644
index 0000000..b8a021f
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/CCDirector.js
@@ -0,0 +1,946 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.g_NumberOfDraws = 0;
+
+//----------------------------------------------------------------------------------------------------------------------
+
+/**
+ *
+ * ATTENTION: USE cc.director INSTEAD OF cc.Director.
+ * cc.director is a singleton object which manage your game's logic flow.
+ * Since the cc.director is a singleton, you don't need to call any constructor or create functions,
+ * the standard way to use it is by calling:
+ * - cc.director.methodName();
+ *
+ * It creates and handle the main Window and manages how and when to execute the Scenes.
+ *
+ * The cc.director is also responsible for:
+ * - initializing the OpenGL context
+ * - setting the OpenGL pixel format (default on is RGB565)
+ * - setting the OpenGL pixel format (default on is RGB565)
+ * - setting the OpenGL buffer depth (default one is 0-bit)
+ * - setting the color for clear screen (default one is BLACK)
+ * - setting the projection (default one is 3D)
+ * - setting the orientation (default one is Portrait)
+ *
+ *
+ * The cc.director also sets the default OpenGL context:
+ * - GL_TEXTURE_2D is enabled
+ * - GL_VERTEX_ARRAY is enabled
+ * - GL_COLOR_ARRAY is enabled
+ * - GL_TEXTURE_COORD_ARRAY is enabled
+ *
+ *
+ * cc.director also synchronizes timers with the refresh rate of the display.
+ * Features and Limitations:
+ * - Scheduled timers & drawing are synchronizes with the refresh rate of the display
+ * - Only supports animation intervals of 1/60 1/30 & 1/15
+ *
+ * @class
+ * @name cc.Director
+ */
+cc.Director = cc.Class.extend(/** @lends cc.Director# */{
+ //Variables
+ _landscape: false,
+ _nextDeltaTimeZero: false,
+ _paused: false,
+ _purgeDirectorInNextLoop: false,
+ _sendCleanupToScene: false,
+ _animationInterval: 0.0,
+ _oldAnimationInterval: 0.0,
+ _projection: 0,
+ _contentScaleFactor: 1.0,
+
+ _deltaTime: 0.0,
+
+ _winSizeInPoints: null,
+
+ _lastUpdate: null,
+ _nextScene: null,
+ _notificationNode: null,
+ _openGLView: null,
+ _scenesStack: null,
+ _projectionDelegate: null,
+ _runningScene: null,
+
+ _totalFrames: 0,
+ _secondsPerFrame: 0,
+
+ _dirtyRegion: null,
+
+ _scheduler: null,
+ _actionManager: null,
+ _eventProjectionChanged: null,
+ _eventAfterUpdate: null,
+ _eventAfterVisit: null,
+ _eventAfterDraw: null,
+
+ ctor: function () {
+ var self = this;
+ self._lastUpdate = Date.now();
+ cc.eventManager.addCustomListener(cc.game.EVENT_SHOW, function () {
+ self._lastUpdate = Date.now();
+ });
+ },
+
+ init: function () {
+ // scenes
+ this._oldAnimationInterval = this._animationInterval = 1.0 / cc.defaultFPS;
+ this._scenesStack = [];
+ // Set default projection (3D)
+ this._projection = cc.Director.PROJECTION_DEFAULT;
+ // projection delegate if "Custom" projection is used
+ this._projectionDelegate = null;
+
+ // FPS
+ this._totalFrames = 0;
+ this._lastUpdate = Date.now();
+
+ //Paused?
+ this._paused = false;
+
+ //purge?
+ this._purgeDirectorInNextLoop = false;
+
+ this._winSizeInPoints = cc.size(0, 0);
+
+ this._openGLView = null;
+ this._contentScaleFactor = 1.0;
+
+ //scheduler
+ this._scheduler = new cc.Scheduler();
+ //action manager
+ if (cc.ActionManager) {
+ this._actionManager = new cc.ActionManager();
+ this._scheduler.scheduleUpdate(this._actionManager, cc.Scheduler.PRIORITY_SYSTEM, false);
+ } else {
+ this._actionManager = null;
+ }
+
+ this._eventAfterUpdate = new cc.EventCustom(cc.Director.EVENT_AFTER_UPDATE);
+ this._eventAfterUpdate.setUserData(this);
+ this._eventAfterVisit = new cc.EventCustom(cc.Director.EVENT_AFTER_VISIT);
+ this._eventAfterVisit.setUserData(this);
+ this._eventAfterDraw = new cc.EventCustom(cc.Director.EVENT_AFTER_DRAW);
+ this._eventAfterDraw.setUserData(this);
+ this._eventProjectionChanged = new cc.EventCustom(cc.Director.EVENT_PROJECTION_CHANGED);
+ this._eventProjectionChanged.setUserData(this);
+
+ return true;
+ },
+
+ /**
+ * calculates delta time since last time it was called
+ */
+ calculateDeltaTime: function () {
+ var now = Date.now();
+
+ // new delta time.
+ if (this._nextDeltaTimeZero) {
+ this._deltaTime = 0;
+ this._nextDeltaTimeZero = false;
+ } else {
+ this._deltaTime = (now - this._lastUpdate) / 1000;
+ }
+
+ if ((cc.game.config[cc.game.CONFIG_KEY.debugMode] > 0) && (this._deltaTime > 0.2))
+ this._deltaTime = 1 / 60.0;
+
+ this._lastUpdate = now;
+ },
+
+ /**
+ * Converts a view coordinate to an WebGL coordinate
+ * Useful to convert (multi) touches coordinates to the current layout (portrait or landscape)
+ * Implementation can be found in CCDirectorWebGL
+ * @function
+ * @param {cc.Point} uiPoint
+ * @return {cc.Point}
+ */
+ convertToGL: function (uiPoint) {
+ var docElem = document.documentElement;
+ var view = cc.view;
+ var box = docElem.getBoundingClientRect();
+ box.left += window.pageXOffset - docElem.clientLeft;
+ box.top += window.pageYOffset - docElem.clientTop;
+ var x = view._devicePixelRatio * (uiPoint.x - box.left);
+ var y = view._devicePixelRatio * (box.top + box.height - uiPoint.y);
+ return view._isRotated ? {x: view._viewPortRect.width - y, y: x} : {x: x, y: y};
+ },
+
+ /**
+ * Converts an WebGL coordinate to a view coordinate
+ * Useful to convert node points to window points for calls such as glScissor
+ * Implementation can be found in CCDirectorWebGL
+ * @function
+ * @param {cc.Point} glPoint
+ * @return {cc.Point}
+ */
+ convertToUI: function (glPoint) {
+ var docElem = document.documentElement;
+ var view = cc.view;
+ var box = docElem.getBoundingClientRect();
+ box.left += window.pageXOffset - docElem.clientLeft;
+ box.top += window.pageYOffset - docElem.clientTop;
+ var uiPoint = {x: 0, y: 0};
+ if (view._isRotated) {
+ uiPoint.x = box.left + glPoint.y / view._devicePixelRatio;
+ uiPoint.y = box.top + box.height - (view._viewPortRect.width - glPoint.x) / view._devicePixelRatio;
+ }
+ else {
+ uiPoint.x = box.left + glPoint.x / view._devicePixelRatio;
+ uiPoint.y = box.top + box.height - glPoint.y / view._devicePixelRatio;
+ }
+ return uiPoint;
+ },
+
+ /**
+ * Draw the scene. This method is called every frame. Don't call it manually.
+ */
+ drawScene: function () {
+ var renderer = cc.renderer;
+
+ // calculate "global" dt
+ this.calculateDeltaTime();
+
+ //tick before glClear: issue #533
+ if (!this._paused) {
+ this._scheduler.update(this._deltaTime);
+ cc.eventManager.dispatchEvent(this._eventAfterUpdate);
+ }
+
+ /* to avoid flickr, nextScene MUST be here: after tick and before draw.
+ XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */
+ if (this._nextScene) {
+ this.setNextScene();
+ }
+
+ // draw the scene
+ if (this._runningScene) {
+ if (renderer.childrenOrderDirty) {
+ cc.renderer.clearRenderCommands();
+ cc.renderer.assignedZ = 0;
+ this._runningScene._renderCmd._curLevel = 0; //level start from 0;
+ this._runningScene.visit();
+ renderer.resetFlag();
+ }
+ else if (renderer.transformDirty()) {
+ renderer.transform();
+ }
+ }
+
+ renderer.clear();
+
+ // draw the notifications node
+ if (this._notificationNode)
+ this._notificationNode.visit();
+
+ cc.eventManager.dispatchEvent(this._eventAfterVisit);
+ cc.g_NumberOfDraws = 0;
+
+ renderer.rendering(cc._renderContext);
+ this._totalFrames++;
+
+ cc.eventManager.dispatchEvent(this._eventAfterDraw);
+ cc.eventManager.frameUpdateListeners();
+
+ this._calculateMPF();
+ },
+
+ /**
+ * End the life of director in the next frame
+ */
+ end: function () {
+ this._purgeDirectorInNextLoop = true;
+ },
+
+ /**
+ * Returns the size in pixels of the surface. It could be different than the screen size.
+ * High-res devices might have a higher surface size than the screen size.
+ * @return {Number}
+ */
+ getContentScaleFactor: function () {
+ return this._contentScaleFactor;
+ },
+
+ /**
+ * This object will be visited after the main scene is visited.
+ * This object MUST implement the "visit" selector.
+ * Useful to hook a notification object
+ * @return {cc.Node}
+ */
+ getNotificationNode: function () {
+ return this._notificationNode;
+ },
+
+ /**
+ * Returns the size of the WebGL view in points.
+ * It takes into account any possible rotation (device orientation) of the window
+ * @return {cc.Size}
+ */
+ getWinSize: function () {
+ return cc.size(this._winSizeInPoints);
+ },
+
+ /**
+ * Returns the size of the OpenGL view in pixels.
+ * It takes into account any possible rotation (device orientation) of the window.
+ * On Mac winSize and winSizeInPixels return the same value.
+ * @return {cc.Size}
+ */
+ getWinSizeInPixels: function () {
+ return cc.size(this._winSizeInPoints.width * this._contentScaleFactor, this._winSizeInPoints.height * this._contentScaleFactor);
+ },
+
+ /**
+ * getVisibleSize/getVisibleOrigin move to CCDirectorWebGL/CCDirectorCanvas
+ * getZEye move to CCDirectorWebGL
+ */
+
+ /**
+ * Returns the visible size of the running scene
+ * @function
+ * @return {cc.Size}
+ */
+ getVisibleSize: null,
+
+ /**
+ * Returns the visible origin of the running scene
+ * @function
+ * @return {cc.Point}
+ */
+ getVisibleOrigin: null,
+
+ /**
+ * Returns the z eye, only available in WebGL mode
+ * @function
+ * @return {Number}
+ */
+ getZEye: null,
+
+ /**
+ * Pause the director's ticker
+ */
+ pause: function () {
+ if (this._paused)
+ return;
+
+ this._oldAnimationInterval = this._animationInterval;
+ // when paused, don't consume CPU
+ this.setAnimationInterval(1 / 4.0);
+ this._paused = true;
+ },
+
+ /**
+ * Pops out a scene from the queue.
+ * This scene will replace the running one.
+ * The running scene will be deleted. If there are no more scenes in the stack the execution is terminated.
+ * ONLY call it if there is a running scene.
+ */
+ popScene: function () {
+
+ cc.assert(this._runningScene, cc._LogInfos.Director_popScene);
+
+ this._scenesStack.pop();
+ var c = this._scenesStack.length;
+
+ if (c === 0)
+ this.end();
+ else {
+ this._sendCleanupToScene = true;
+ this._nextScene = this._scenesStack[c - 1];
+ }
+ },
+
+ /**
+ * Removes cached all cocos2d cached data. It will purge the cc.textureCache, cc.spriteFrameCache, cc.animationCache
+ */
+ purgeCachedData: function () {
+ cc.animationCache._clear();
+ cc.spriteFrameCache._clear();
+ cc.textureCache._clear();
+ },
+
+ /**
+ * Purge the cc.director itself, including unschedule all schedule, remove all event listeners, clean up and exit the running scene, stops all animations, clear cached data.
+ */
+ purgeDirector: function () {
+ //cleanup scheduler
+ this.getScheduler().unscheduleAll();
+
+ // Disable event dispatching
+ if (cc.eventManager)
+ cc.eventManager.setEnabled(false);
+
+ // don't release the event handlers
+ // They are needed in case the director is run again
+
+ if (this._runningScene) {
+ this._runningScene._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ this._runningScene._performRecursive(cc.Node._stateCallbackType.onExit);
+ this._runningScene._performRecursive(cc.Node._stateCallbackType.cleanup);
+ }
+
+ this._runningScene = null;
+ this._nextScene = null;
+
+ // remove all objects, but don't release it.
+ // runScene might be executed after 'end'.
+ this._scenesStack.length = 0;
+
+ this.stopAnimation();
+
+ // Clear all caches
+ this.purgeCachedData();
+
+ cc.checkGLErrorDebug();
+ },
+
+ /**
+ * Suspends the execution of the running scene, pushing it on the stack of suspended scenes.
+ * The new scene will be executed.
+ * Try to avoid big stacks of pushed scenes to reduce memory allocation.
+ * ONLY call it if there is a running scene.
+ * @param {cc.Scene} scene
+ */
+ pushScene: function (scene) {
+
+ cc.assert(scene, cc._LogInfos.Director_pushScene);
+
+ this._sendCleanupToScene = false;
+
+ this._scenesStack.push(scene);
+ this._nextScene = scene;
+ },
+
+ /**
+ * Run a scene. Replaces the running scene with a new one or enter the first scene.
+ * @param {cc.Scene} scene
+ */
+ runScene: function (scene) {
+
+ cc.assert(scene, cc._LogInfos.Director_pushScene);
+
+ if (!this._runningScene) {
+ //start scene
+ this.pushScene(scene);
+ this.startAnimation();
+ } else {
+ //replace scene
+ var i = this._scenesStack.length;
+ if (i === 0) {
+ this._sendCleanupToScene = true;
+ this._scenesStack[i] = scene;
+ this._nextScene = scene;
+ } else {
+ this._sendCleanupToScene = true;
+ this._scenesStack[i - 1] = scene;
+ this._nextScene = scene;
+ }
+ }
+ },
+
+ /**
+ * Resume director after pause, if the current scene is not paused, nothing will happen.
+ */
+ resume: function () {
+ if (!this._paused) {
+ return;
+ }
+
+ this.setAnimationInterval(this._oldAnimationInterval);
+ this._lastUpdate = Date.now();
+ if (!this._lastUpdate) {
+ cc.log(cc._LogInfos.Director_resume);
+ }
+
+ this._paused = false;
+ this._deltaTime = 0;
+ },
+
+ /**
+ * The size in pixels of the surface. It could be different than the screen size.
+ * High-res devices might have a higher surface size than the screen size.
+ * @param {Number} scaleFactor
+ */
+ setContentScaleFactor: function (scaleFactor) {
+ if (scaleFactor !== this._contentScaleFactor) {
+ this._contentScaleFactor = scaleFactor;
+ }
+ },
+
+ /**
+ * Enables or disables WebGL depth test.
+ * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js
+ * @function
+ * @param {Boolean} on
+ */
+ setDepthTest: null,
+
+ /**
+ * set color for clear screen.
+ * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js
+ * @function
+ * @param {cc.Color} clearColor
+ */
+ setClearColor: null,
+ /**
+ * Sets the default values based on the CCConfiguration info
+ */
+ setDefaultValues: function () {
+
+ },
+
+ /**
+ * Sets whether next delta time equals to zero
+ * @param {Boolean} nextDeltaTimeZero
+ */
+ setNextDeltaTimeZero: function (nextDeltaTimeZero) {
+ this._nextDeltaTimeZero = nextDeltaTimeZero;
+ },
+
+ /**
+ * Starts the registered next scene
+ */
+ setNextScene: function () {
+ var runningIsTransition = false, newIsTransition = false;
+ if (cc.TransitionScene) {
+ runningIsTransition = this._runningScene ? this._runningScene instanceof cc.TransitionScene : false;
+ newIsTransition = this._nextScene ? this._nextScene instanceof cc.TransitionScene : false;
+ }
+
+ // If it is not a transition, call onExit/cleanup
+ if (!newIsTransition) {
+ var locRunningScene = this._runningScene;
+ if (locRunningScene) {
+ locRunningScene._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ locRunningScene._performRecursive(cc.Node._stateCallbackType.onExit);
+ }
+
+ // issue #709. the root node (scene) should receive the cleanup message too
+ // otherwise it might be leaked.
+ if (this._sendCleanupToScene && locRunningScene)
+ locRunningScene._performRecursive(cc.Node._stateCallbackType.cleanup);
+ }
+
+ this._runningScene = this._nextScene;
+ cc.renderer.childrenOrderDirty = true;
+
+ this._nextScene = null;
+ if ((!runningIsTransition) && (this._runningScene !== null)) {
+ this._runningScene._performRecursive(cc.Node._stateCallbackType.onEnter);
+ this._runningScene._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
+ }
+ },
+
+ /**
+ * Sets Notification Node
+ * @param {cc.Node} node
+ */
+ setNotificationNode: function (node) {
+ cc.renderer.childrenOrderDirty = true;
+ if (this._notificationNode) {
+ this._notificationNode._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ this._notificationNode._performRecursive(cc.Node._stateCallbackType.onExit);
+ this._notificationNode._performRecursive(cc.Node._stateCallbackType.cleanup);
+ }
+ this._notificationNode = node;
+ if (!node)
+ return;
+ this._notificationNode._performRecursive(cc.Node._stateCallbackType.onEnter);
+ this._notificationNode._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
+ },
+
+ /**
+ * Returns the cc.director delegate.
+ * @return {cc.DirectorDelegate}
+ */
+ getDelegate: function () {
+ return this._projectionDelegate;
+ },
+
+ /**
+ * Sets the cc.director delegate. It shall implement the CCDirectorDelegate protocol
+ * @return {cc.DirectorDelegate}
+ */
+ setDelegate: function (delegate) {
+ this._projectionDelegate = delegate;
+ },
+
+ /**
+ * Sets the view, where everything is rendered, do not call this function.
+ * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js.
+ * @function
+ * @param {cc.view} openGLView
+ */
+ setOpenGLView: null,
+
+ /**
+ * Sets an OpenGL projection.
+ * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js.
+ * @function
+ * @param {Number} projection
+ */
+ setProjection: null,
+
+ /**
+ * Update the view port.
+ * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js.
+ * @function
+ */
+ setViewport: null,
+
+ /**
+ * Get the CCEGLView, where everything is rendered.
+ * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js.
+ * @function
+ * @return {cc.view}
+ */
+ getOpenGLView: null,
+
+ /**
+ * Sets an OpenGL projection.
+ * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js.
+ * @function
+ * @return {Number}
+ */
+ getProjection: null,
+
+ /**
+ * Enables/disables OpenGL alpha blending.
+ * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js.
+ * @function
+ * @param {Boolean} on
+ */
+ setAlphaBlending: null,
+
+ /**
+ * Returns whether or not the replaced scene will receive the cleanup message.
+ * If the new scene is pushed, then the old scene won't receive the "cleanup" message.
+ * If the new scene replaces the old one, the it will receive the "cleanup" message.
+ * @return {Boolean}
+ */
+ isSendCleanupToScene: function () {
+ return this._sendCleanupToScene;
+ },
+
+ /**
+ * Returns current running Scene. Director can only run one Scene at the time
+ * @return {cc.Scene}
+ */
+ getRunningScene: function () {
+ return this._runningScene;
+ },
+
+ /**
+ * Returns the FPS value
+ * @return {Number}
+ */
+ getAnimationInterval: function () {
+ return this._animationInterval;
+ },
+
+ /**
+ * Returns whether or not to display the FPS informations
+ * @return {Boolean}
+ */
+ isDisplayStats: function () {
+ return cc.profiler ? cc.profiler.isShowingStats() : false;
+ },
+
+ /**
+ * Sets whether display the FPS on the bottom-left corner
+ * @param {Boolean} displayStats
+ */
+ setDisplayStats: function (displayStats) {
+ if (cc.profiler) {
+ displayStats ? cc.profiler.showStats() : cc.profiler.hideStats();
+ }
+ },
+
+ /**
+ * Returns seconds per frame
+ * @return {Number}
+ */
+ getSecondsPerFrame: function () {
+ return this._secondsPerFrame;
+ },
+
+ /**
+ * Returns whether next delta time equals to zero
+ * @return {Boolean}
+ */
+ isNextDeltaTimeZero: function () {
+ return this._nextDeltaTimeZero;
+ },
+
+ /**
+ * Returns whether or not the Director is paused
+ * @return {Boolean}
+ */
+ isPaused: function () {
+ return this._paused;
+ },
+
+ /**
+ * Returns how many frames were called since the director started
+ * @return {Number}
+ */
+ getTotalFrames: function () {
+ return this._totalFrames;
+ },
+
+ /**
+ * Pops out all scenes from the queue until the root scene in the queue.
+ * This scene will replace the running one.
+ * Internally it will call "popToSceneStackLevel(1)"
+ */
+ popToRootScene: function () {
+ this.popToSceneStackLevel(1);
+ },
+
+ /**
+ * Pops out all scenes from the queue until it reaches "level".
+ * If level is 0, it will end the director.
+ * If level is 1, it will pop all scenes until it reaches to root scene.
+ * If level is <= than the current stack level, it won't do anything.
+ * @param {Number} level
+ */
+ popToSceneStackLevel: function (level) {
+ cc.assert(this._runningScene, cc._LogInfos.Director_popToSceneStackLevel_2);
+
+ var locScenesStack = this._scenesStack;
+ var c = locScenesStack.length;
+
+ if (level === 0) {
+ this.end();
+ return;
+ }
+ // stack overflow
+ if (level >= c)
+ return;
+
+ // pop stack until reaching desired level
+ while (c > level) {
+ var current = locScenesStack.pop();
+ if (current.running) {
+ current._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ current._performRecursive(cc.Node._stateCallbackType.onExit);
+ }
+ current._performRecursive(cc.Node._stateCallbackType.cleanup);
+ c--;
+ }
+ this._nextScene = locScenesStack[locScenesStack.length - 1];
+ this._sendCleanupToScene = true;
+ },
+
+ /**
+ * Returns the cc.Scheduler associated with this director
+ * @return {cc.Scheduler}
+ */
+ getScheduler: function () {
+ return this._scheduler;
+ },
+
+ /**
+ * Sets the cc.Scheduler associated with this director
+ * @param {cc.Scheduler} scheduler
+ */
+ setScheduler: function (scheduler) {
+ if (this._scheduler !== scheduler) {
+ this._scheduler = scheduler;
+ }
+ },
+
+ /**
+ * Returns the cc.ActionManager associated with this director
+ * @return {cc.ActionManager}
+ */
+ getActionManager: function () {
+ return this._actionManager;
+ },
+ /**
+ * Sets the cc.ActionManager associated with this director
+ * @param {cc.ActionManager} actionManager
+ */
+ setActionManager: function (actionManager) {
+ if (this._actionManager !== actionManager) {
+ this._actionManager = actionManager;
+ }
+ },
+
+ /**
+ * Returns the delta time since last frame
+ * @return {Number}
+ */
+ getDeltaTime: function () {
+ return this._deltaTime;
+ },
+
+ _calculateMPF: function () {
+ var now = Date.now();
+ this._secondsPerFrame = (now - this._lastUpdate) / 1000;
+ }
+});
+
+/**
+ * The event projection changed of cc.Director
+ * @constant
+ * @type {string}
+ * @example
+ * cc.eventManager.addCustomListener(cc.Director.EVENT_PROJECTION_CHANGED, function(event) {
+ * cc.log("Projection changed.");
+ * });
+ */
+cc.Director.EVENT_PROJECTION_CHANGED = "director_projection_changed";
+
+/**
+ * The event after update of cc.Director
+ * @constant
+ * @type {string}
+ * @example
+ * cc.eventManager.addCustomListener(cc.Director.EVENT_AFTER_UPDATE, function(event) {
+ * cc.log("after update event.");
+ * });
+ */
+cc.Director.EVENT_AFTER_UPDATE = "director_after_update";
+
+/**
+ * The event after visit of cc.Director
+ * @constant
+ * @type {string}
+ * @example
+ * cc.eventManager.addCustomListener(cc.Director.EVENT_AFTER_VISIT, function(event) {
+ * cc.log("after visit event.");
+ * });
+ */
+cc.Director.EVENT_AFTER_VISIT = "director_after_visit";
+
+/**
+ * The event after draw of cc.Director
+ * @constant
+ * @type {string}
+ * @example
+ * cc.eventManager.addCustomListener(cc.Director.EVENT_AFTER_DRAW, function(event) {
+ * cc.log("after draw event.");
+ * });
+ */
+cc.Director.EVENT_AFTER_DRAW = "director_after_draw";
+
+/***************************************************
+ * implementation of DisplayLinkDirector
+ **************************************************/
+cc.DisplayLinkDirector = cc.Director.extend(/** @lends cc.Director# */{
+ invalid: false,
+
+ /**
+ * Starts Animation
+ */
+ startAnimation: function () {
+ this._nextDeltaTimeZero = true;
+ this.invalid = false;
+ },
+
+ /**
+ * Run main loop of director
+ */
+ mainLoop: function () {
+ if (this._purgeDirectorInNextLoop) {
+ this._purgeDirectorInNextLoop = false;
+ this.purgeDirector();
+ }
+ else if (!this.invalid) {
+ this.drawScene();
+ }
+ },
+
+ /**
+ * Stops animation
+ */
+ stopAnimation: function () {
+ this.invalid = true;
+ },
+
+ /**
+ * Sets animation interval
+ * @param {Number} value the animation interval desired
+ */
+ setAnimationInterval: function (value) {
+ this._animationInterval = value;
+ if (!this.invalid) {
+ this.stopAnimation();
+ this.startAnimation();
+ }
+ }
+});
+
+cc.Director.sharedDirector = null;
+cc.Director.firstUseDirector = true;
+
+cc.Director._getInstance = function () {
+ if (cc.Director.firstUseDirector) {
+ cc.Director.firstUseDirector = false;
+ cc.Director.sharedDirector = new cc.DisplayLinkDirector();
+ cc.Director.sharedDirector.init();
+ }
+ return cc.Director.sharedDirector;
+};
+
+/**
+ * Default fps is 60
+ * @type {Number}
+ */
+cc.defaultFPS = 60;
+
+//Possible OpenGL projections used by director
+/**
+ * Constant for 2D projection (orthogonal projection)
+ * @constant
+ * @type {Number}
+ */
+cc.Director.PROJECTION_2D = 0;
+
+/**
+ * Constant for 3D projection with a fovy=60, znear=0.5f and zfar=1500.
+ * @constant
+ * @type {Number}
+ */
+cc.Director.PROJECTION_3D = 1;
+
+/**
+ * Constant for custom projection, if cc.Director's projection set to it, it calls "updateProjection" on the projection delegate.
+ * @constant
+ * @type {Number}
+ */
+cc.Director.PROJECTION_CUSTOM = 3;
+
+/**
+ * Constant for default projection of cc.Director, default projection is 2D projection
+ * @constant
+ * @type {Number}
+ */
+cc.Director.PROJECTION_DEFAULT = cc.Director.PROJECTION_3D;
diff --git a/frameworks/cocos2d-html5/cocos2d/core/CCDirectorCanvas.js b/frameworks/cocos2d-html5/cocos2d/core/CCDirectorCanvas.js
new file mode 100644
index 0000000..12deec5
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/CCDirectorCanvas.js
@@ -0,0 +1,82 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
+
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
+ var _p = cc.Director.prototype;
+
+ _p.getProjection = function (projection) {
+ return this._projection;
+ };
+
+ _p.setProjection = function (projection) {
+ this._projection = projection;
+ cc.eventManager.dispatchEvent(this._eventProjectionChanged);
+ };
+
+ _p.setDepthTest = function () {
+ };
+
+ _p.setClearColor = function (clearColor) {
+ cc.renderer._clearColor = clearColor;
+ cc.renderer._clearFillStyle = 'rgb(' + clearColor.r + ',' + clearColor.g + ',' + clearColor.b +')' ;
+ };
+
+ _p.setOpenGLView = function (openGLView) {
+ // set size
+ this._winSizeInPoints.width = cc._canvas.width; //this._openGLView.getDesignResolutionSize();
+ this._winSizeInPoints.height = cc._canvas.height;
+ this._openGLView = openGLView || cc.view;
+ if (cc.eventManager)
+ cc.eventManager.setEnabled(true);
+ };
+
+ _p.getVisibleSize = function () {
+ //if (this._openGLView) {
+ //return this._openGLView.getVisibleSize();
+ //} else {
+ return this.getWinSize();
+ //}
+ };
+
+ _p.getVisibleOrigin = function () {
+ //if (this._openGLView) {
+ //return this._openGLView.getVisibleOrigin();
+ //} else {
+ return cc.p(0, 0);
+ //}
+ };
+ } else {
+ cc.Director._fpsImage = new Image();
+ cc.Director._fpsImage.addEventListener("load", function () {
+ cc.Director._fpsImageLoaded = true;
+ });
+ if (cc._fpsImage) {
+ cc.Director._fpsImage.src = cc._fpsImage;
+ }
+ }
+});
diff --git a/frameworks/cocos2d-html5/cocos2d/core/CCDirectorWebGL.js b/frameworks/cocos2d-html5/cocos2d/core/CCDirectorWebGL.js
new file mode 100644
index 0000000..50ae30b
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/CCDirectorWebGL.js
@@ -0,0 +1,215 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
+
+ // Do nothing under other render mode
+ if (cc._renderType !== cc.game.RENDER_TYPE_WEBGL) {
+ return;
+ }
+
+ /**
+ * OpenGL projection protocol
+ * @class
+ * @extends cc.Class
+ */
+ cc.DirectorDelegate = cc.Class.extend(/** @lends cc.DirectorDelegate# */{
+ /**
+ * Called by CCDirector when the projection is updated, and "custom" projection is used
+ */
+ updateProjection: function () {
+ }
+ });
+
+ var _p = cc.Director.prototype;
+
+ var recursiveChild = function(node){
+ if(node && node._renderCmd){
+ node._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ var i, children = node._children;
+ for(i=0; i 0);
+ this._repeat = repeat;
+ this._runForever = (this._repeat === cc.REPEAT_FOREVER);
+ return true;
+ },
+ /**
+ * @return {Number} returns interval of timer
+ */
+ getInterval : function(){return this._interval;},
+ /**
+ * @param {Number} interval set interval in seconds
+ */
+ setInterval : function(interval){this._interval = interval;},
+
+ /**
+ * triggers the timer
+ * @param {Number} dt delta time
+ */
+ update:function (dt) {
+ if (this._elapsed === -1) {
+ this._elapsed = 0;
+ this._timesExecuted = 0;
+ } else {
+ this._elapsed += dt;
+ if (this._runForever && !this._useDelay) {//standard timer usage
+ if (this._elapsed >= this._interval) {
+ this.trigger();
+ this._elapsed = 0;
+ }
+ } else {//advanced usage
+ if (this._useDelay) {
+ if (this._elapsed >= this._delay) {
+ this.trigger();
+
+ this._elapsed -= this._delay;
+ this._timesExecuted += 1;
+ this._useDelay = false;
+ }
+ } else {
+ if (this._elapsed >= this._interval) {
+ this.trigger();
+
+ this._elapsed = 0;
+ this._timesExecuted += 1;
+ }
+ }
+
+ if (this._callback && !this._runForever && this._timesExecuted > this._repeat)
+ this.cancel();
+ }
+ }
+ },
+
+ getCallback: function(){
+ return this._callback;
+ },
+
+ getKey: function(){
+ return this._key;
+ },
+
+ trigger: function () {
+ if (this._target && this._callback){
+ this._callback.call(this._target, this._elapsed);
+ }
+ },
+
+ cancel: function () {
+ //override
+ this._scheduler.unschedule(this._callback, this._target);
+ }
+}, CallbackTimer.prototype);
+
+var _timers = [];
+CallbackTimer.get = function () {
+ return _timers.pop() || new CallbackTimer();
+};
+CallbackTimer.put = function (timer) {
+ timer._scheduler = null;
+ timer._elapsed = -1;
+ timer._runForever = false;
+ timer._useDelay = false;
+ timer._timesExecuted = 0;
+ timer._repeat = 0;
+ timer._delay = 0;
+ timer._interval = 0;
+ timer._target = null;
+ timer._callback = null;
+ timer._key = null;
+ if (_timers.length < MAX_POOL_SIZE)
+ _timers.push(timer);
+};
+
+/**
+ *
+ * Scheduler is responsible of triggering the scheduled callbacks.
+ * You should not use NSTimer. Instead use this class.
+ *
+ * There are 2 different types of callbacks (selectors):
+ * - update callback: the 'update' callback will be called every frame. You can customize the priority.
+ * - custom callback: A custom callback will be called every frame, or with a custom interval of time
+ *
+ * The 'custom selectors' should be avoided when possible. It is faster, and consumes less memory to use the 'update callback'. *
+ *
+ * @class
+ * @extends cc.Class
+ *
+ * @example
+ * //register a schedule to scheduler
+ * cc.director.getScheduler().schedule(callback, this, interval, !this._isRunning);
+ */
+cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{
+ _timeScale:1.0,
+
+ //_updates : null, //_updates[0] list of priority < 0, _updates[1] list of priority == 0, _updates[2] list of priority > 0,
+ _updatesNegList: null,
+ _updates0List: null,
+ _updatesPosList: null,
+
+ _hashForTimers:null, //Used for "selectors with interval"
+ _arrayForTimers:null, //Speed up indexing
+ _hashForUpdates:null, // hash used to fetch quickly the list entries for pause,delete,etc
+ //_arrayForUpdates:null, //Speed up indexing
+
+ _currentTarget:null,
+ _currentTargetSalvaged:false,
+ _updateHashLocked:false, //If true unschedule will not remove anything from a hash. Elements will only be marked for deletion.
+
+
+ ctor:function () {
+ this._timeScale = 1.0;
+ this._updatesNegList = [];
+ this._updates0List = [];
+ this._updatesPosList = [];
+
+ this._hashForUpdates = {};
+ this._hashForTimers = {};
+ this._currentTarget = null;
+ this._currentTargetSalvaged = false;
+ this._updateHashLocked = false;
+
+ this._arrayForTimers = [];
+ //this._arrayForUpdates = [];
+
+ },
+
+ //-----------------------private method----------------------
+
+ _schedulePerFrame: function(callback, target, priority, paused){
+ var hashElement = this._hashForUpdates[target.__instanceId];
+ if (hashElement && hashElement.entry){
+ // check if priority has changed
+ if (hashElement.entry.priority !== priority){
+ if (this._updateHashLocked){
+ cc.log("warning: you CANNOT change update priority in scheduled function");
+ hashElement.entry.markedForDeletion = false;
+ hashElement.entry.paused = paused;
+ return;
+ }else{
+ // will be added again outside if (hashElement).
+ this.unscheduleUpdate(target);
+ }
+ }else{
+ hashElement.entry.markedForDeletion = false;
+ hashElement.entry.paused = paused;
+ return;
+ }
+ }
+
+ // most of the updates are going to be 0, that's why there
+ // is an special list for updates with priority 0
+ if (priority === 0){
+ this._appendIn(this._updates0List, callback, target, paused);
+ }else if (priority < 0){
+ this._priorityIn(this._updatesNegList, callback, target, priority, paused);
+ }else{
+ // priority > 0
+ this._priorityIn(this._updatesPosList, callback, target, priority, paused);
+ }
+ },
+
+ _removeHashElement:function (element) {
+ delete this._hashForTimers[element.target.__instanceId];
+ var arr = this._arrayForTimers;
+ for (var i = 0, l = arr.length; i < l; i++) {
+ if (arr[i] === element) {
+ arr.splice(i, 1);
+ break;
+ }
+ }
+ HashTimerEntry.put(element);
+ },
+
+ _removeUpdateFromHash:function (entry) {
+ var self = this;
+ var element = self._hashForUpdates[entry.target.__instanceId];
+ if (element) {
+ // Remove list entry from list
+ var list = element.list, listEntry = element.entry;
+ for (var i = 0, l = list.length; i < l; i++) {
+ if (list[i] === listEntry) {
+ list.splice(i, 1);
+ break;
+ }
+ }
+
+ delete self._hashForUpdates[element.target.__instanceId];
+ ListEntry.put(listEntry);
+ HashUpdateEntry.put(element);
+ }
+ },
+
+ _priorityIn:function (ppList, callback, target, priority, paused) {
+ var self = this,
+ listElement = ListEntry.get(null, null, callback, target, priority, paused, false);
+
+ // empey list ?
+ if (!ppList) {
+ ppList = [];
+ ppList.push(listElement);
+ } else {
+ var index2Insert = ppList.length - 1;
+ for(var i = 0; i <= index2Insert; i++){
+ if (priority < ppList[i].priority) {
+ index2Insert = i;
+ break;
+ }
+ }
+ ppList.splice(i, 0, listElement);
+ }
+
+ //update hash entry for quick access
+ self._hashForUpdates[target.__instanceId] = HashUpdateEntry.get(ppList, listElement, target, null);
+
+ return ppList;
+ },
+
+ _appendIn:function (ppList, callback, target, paused) {
+ var self = this,
+ listElement = ListEntry.get(null, null, callback, target, 0, paused, false);
+ ppList.push(listElement);
+
+ //update hash entry for quicker access
+ self._hashForUpdates[target.__instanceId] = HashUpdateEntry.get(ppList, listElement, target, null, null);
+ },
+
+ //-----------------------public method-------------------------
+ /**
+ *
+ * Modifies the time of all scheduled callbacks.
+ * You can use this property to create a 'slow motion' or 'fast forward' effect.
+ * Default is 1.0. To create a 'slow motion' effect, use values below 1.0.
+ * To create a 'fast forward' effect, use values higher than 1.0.
+ * @warning It will affect EVERY scheduled selector / action.
+ *
+ * @param {Number} timeScale
+ */
+ setTimeScale:function (timeScale) {
+ this._timeScale = timeScale;
+ },
+
+ /**
+ * Returns time scale of scheduler
+ * @return {Number}
+ */
+ getTimeScale:function () {
+ return this._timeScale;
+ },
+
+ /**
+ * 'update' the scheduler. (You should NEVER call this method, unless you know what you are doing.)
+ * @param {Number} dt delta time
+ */
+ update:function (dt) {
+ this._updateHashLocked = true;
+ if(this._timeScale !== 1)
+ dt *= this._timeScale;
+
+ var i, list, len, entry;
+
+ for(i=0,list=this._updatesNegList, len = list.length; i
+ * The scheduled method will be called every 'interval' seconds.
+ * If paused is YES, then it won't be called until it is resumed.
+ * If 'interval' is 0, it will be called every frame, but if so, it recommended to use 'scheduleUpdateForTarget:' instead.
+ * If the callback function is already scheduled, then only the interval parameter will be updated without re-scheduling it again.
+ * repeat let the action be repeated repeat + 1 times, use cc.REPEAT_FOREVER to let the action run continuously
+ * delay is the amount of time the action will wait before it'll start
+ *
+ * @deprecated since v3.4 please use .schedule
+ * @param {cc.Class} target
+ * @param {function} callback_fn
+ * @param {Number} interval
+ * @param {Number} repeat
+ * @param {Number} delay
+ * @param {Boolean} paused
+ * @example
+ * //register a schedule to scheduler
+ * cc.director.getScheduler().scheduleCallbackForTarget(this, function, interval, repeat, delay, !this._isRunning );
+ */
+ scheduleCallbackForTarget: function(target, callback_fn, interval, repeat, delay, paused){
+ //cc.log("scheduleCallbackForTarget is deprecated. Please use schedule.");
+ this.schedule(callback_fn, target, interval, repeat, delay, paused, target.__instanceId + "");
+ },
+
+ schedule: function (callback, target, interval, repeat, delay, paused, key) {
+ var isSelector = false;
+ if (typeof callback !== "function") {
+ var tmp = callback;
+ callback = target;
+ target = tmp;
+ isSelector = true;
+ }
+ //callback, target, interval, repeat, delay, paused, key
+ //callback, target, interval, paused, key
+ if(arguments.length === 4 || arguments.length === 5){
+ key = delay;
+ paused = repeat;
+ repeat = cc.REPEAT_FOREVER;
+ delay = 0;
+ }
+ if (key === undefined) {
+ key = target.__instanceId + "";
+ }
+
+ cc.assert(target, cc._LogInfos.Scheduler_scheduleCallbackForTarget_3);
+
+ var element = this._hashForTimers[target.__instanceId];
+
+ if (!element) {
+ // Is this the 1st element ? Then set the pause level to all the callback_fns of this target
+ element = HashTimerEntry.get(null, target, 0, null, null, paused);
+ this._arrayForTimers.push(element);
+ this._hashForTimers[target.__instanceId] = element;
+ } else {
+ cc.assert(element.paused === paused, "");
+ }
+
+ var timer, i;
+ if (element.timers == null) {
+ element.timers = [];
+ } else {
+ for (i = 0; i < element.timers.length; i++) {
+ timer = element.timers[i];
+ if (callback === timer._callback) {
+ cc.log(cc._LogInfos.Scheduler_scheduleCallbackForTarget, timer.getInterval().toFixed(4), interval.toFixed(4));
+ timer._interval = interval;
+ return;
+ }
+ }
+ }
+
+ timer = CallbackTimer.get();
+ timer.initWithCallback(this, callback, target, interval, repeat, delay, key);
+ element.timers.push(timer);
+ },
+
+ scheduleUpdate: function(target, priority, paused){
+ this._schedulePerFrame(function(dt){
+ target.update(dt);
+ }, target, priority, paused);
+ },
+
+ _getUnscheduleMark: function(key, timer){
+ //key, callback
+ switch (typeof key){
+ case "number":
+ case "string":
+ return key === timer._key;
+ case "function":
+ return key === timer._callback;
+ }
+ },
+ unschedule: function (key, target) {
+ //key, target
+ //selector, target
+ //callback, target - This is in order to increase compatibility
+
+ // explicity handle nil arguments when removing an object
+ if (!target || !key)
+ return;
+
+ var self = this, element = self._hashForTimers[target.__instanceId];
+ if (element) {
+ var timers = element.timers;
+ for(var i = 0, li = timers.length; i < li; i++){
+ var timer = timers[i];
+ if (this._getUnscheduleMark(key, timer)) {
+ if ((timer === element.currentTimer) && (!element.currentTimerSalvaged)) {
+ element.currentTimerSalvaged = true;
+ }
+ timers.splice(i, 1);
+ CallbackTimer.put(timer);
+ //update timerIndex in case we are in tick;, looping over the actions
+ if (element.timerIndex >= i) {
+ element.timerIndex--;
+ }
+
+ if (timers.length === 0) {
+ if (self._currentTarget === element) {
+ self._currentTargetSalvaged = true;
+ } else {
+ self._removeHashElement(element);
+ }
+ }
+ return;
+ }
+ }
+ }
+ },
+
+ unscheduleUpdate: function (target) {
+ if (!target)
+ return;
+
+ var element = this._hashForUpdates[target.__instanceId];
+
+ if (element) {
+ if (this._updateHashLocked) {
+ element.entry.markedForDeletion = true;
+ } else {
+ this._removeUpdateFromHash(element.entry);
+ }
+ }
+ },
+
+ unscheduleAllForTarget: function (target) {
+ // explicit nullptr handling
+ if (!target){
+ return;
+ }
+
+ // Custom Selectors
+ var element = this._hashForTimers[target.__instanceId];
+
+ if (element) {
+ var timers = element.timers;
+ if (timers.indexOf(element.currentTimer) > -1 &&
+ (!element.currentTimerSalvaged)) {
+ element.currentTimerSalvaged = true;
+ }
+ for (var i = 0, l = timers.length; i < l; i++) {
+ CallbackTimer.put(timers[i]);
+ }
+ timers.length = 0;
+
+ if (this._currentTarget === element){
+ this._currentTargetSalvaged = true;
+ }else{
+ this._removeHashElement(element);
+ }
+ }
+
+ // update selector
+ this.unscheduleUpdate(target);
+ },
+
+ unscheduleAll: function(){
+ this.unscheduleAllWithMinPriority(cc.Scheduler.PRIORITY_SYSTEM);
+ },
+
+ unscheduleAllWithMinPriority: function(minPriority){
+ // Custom Selectors
+ var i, element, arr = this._arrayForTimers;
+ for(i=arr.length-1; i>=0; i--){
+ element = arr[i];
+ this.unscheduleAllForTarget(element.target);
+ }
+
+ // Updates selectors
+ var entry;
+ var temp_length = 0;
+ if(minPriority < 0){
+ for(i=0; i= minPriority)
+ this.unscheduleUpdate(entry.target);
+ if (temp_length == this._updatesNegList.length)
+ i++;
+ }
+ }
+
+ if(minPriority <= 0){
+ for(i=0; i= minPriority)
+ this.unscheduleUpdate(entry.target);
+ if (temp_length == this._updatesPosList.length)
+ i++;
+ }
+ },
+
+ isScheduled: function(callback, target){
+ //key, target
+ //selector, target
+ cc.assert(callback, "Argument callback must not be empty");
+ cc.assert(target, "Argument target must be non-nullptr");
+
+ var element = this._hashForTimers[target.__instanceId];
+
+ if (!element) {
+ return false;
+ }
+
+ if (element.timers == null){
+ return false;
+ }
+ else {
+ var timers = element.timers;
+ for (var i = 0; i < timers.length; ++i) {
+ var timer = timers[i];
+
+ if (callback === timer._callback){
+ return true;
+ }
+ }
+ return false;
+ }
+ },
+
+ /**
+ *
+ * Pause all selectors from all targets.
+ * You should NEVER call this method, unless you know what you are doing.
+ *
+ */
+ pauseAllTargets:function () {
+ return this.pauseAllTargetsWithMinPriority(cc.Scheduler.PRIORITY_SYSTEM);
+ },
+
+ /**
+ * Pause all selectors from all targets with a minimum priority.
+ * You should only call this with kCCPriorityNonSystemMin or higher.
+ * @param {Number} minPriority
+ */
+ pauseAllTargetsWithMinPriority:function (minPriority) {
+ var idsWithSelectors = [];
+
+ var self = this, element, locArrayForTimers = self._arrayForTimers;
+ var i, li;
+ // Custom Selectors
+ for(i = 0, li = locArrayForTimers.length; i < li; i++){
+ element = locArrayForTimers[i];
+ if (element) {
+ element.paused = true;
+ idsWithSelectors.push(element.target);
+ }
+ }
+
+ var entry;
+ if(minPriority < 0){
+ for(i=0; i= minPriority){
+ entry.paused = true;
+ idsWithSelectors.push(entry.target);
+ }
+ }
+ }
+ }
+
+ if(minPriority <= 0){
+ for(i=0; i= minPriority){
+ entry.paused = true;
+ idsWithSelectors.push(entry.target);
+ }
+ }
+ }
+
+ return idsWithSelectors;
+ },
+
+ /**
+ * Resume selectors on a set of targets.
+ * This can be useful for undoing a call to pauseAllCallbacks.
+ * @param {Array} targetsToResume
+ */
+ resumeTargets:function (targetsToResume) {
+ if (!targetsToResume)
+ return;
+
+ for (var i = 0; i < targetsToResume.length; i++) {
+ this.resumeTarget(targetsToResume[i]);
+ }
+ },
+
+ /**
+ *
+ * Pauses the target.
+ * All scheduled selectors/update for a given target won't be 'ticked' until the target is resumed.
+ * If the target is not present, nothing happens.
+ *
+ * @param {cc.Class} target
+ */
+ pauseTarget:function (target) {
+
+ cc.assert(target, cc._LogInfos.Scheduler_pauseTarget);
+
+ //customer selectors
+ var self = this, element = self._hashForTimers[target.__instanceId];
+ if (element) {
+ element.paused = true;
+ }
+
+ //update callback
+ var elementUpdate = self._hashForUpdates[target.__instanceId];
+ if (elementUpdate) {
+ elementUpdate.entry.paused = true;
+ }
+ },
+
+ /**
+ * Resumes the target.
+ * The 'target' will be unpaused, so all schedule selectors/update will be 'ticked' again.
+ * If the target is not present, nothing happens.
+ * @param {cc.Class} target
+ */
+ resumeTarget:function (target) {
+
+ cc.assert(target, cc._LogInfos.Scheduler_resumeTarget);
+
+ // custom selectors
+ var self = this, element = self._hashForTimers[target.__instanceId];
+
+ if (element) {
+ element.paused = false;
+ }
+
+ //update callback
+ var elementUpdate = self._hashForUpdates[target.__instanceId];
+
+ if (elementUpdate) {
+ elementUpdate.entry.paused = false;
+ }
+ },
+
+ /**
+ * Returns whether or not the target is paused
+ * @param {cc.Class} target
+ * @return {Boolean}
+ */
+ isTargetPaused:function (target) {
+
+ cc.assert(target, cc._LogInfos.Scheduler_isTargetPaused);
+
+ // Custom selectors
+ var element = this._hashForTimers[target.__instanceId];
+ if (element) {
+ return element.paused;
+ }
+ var elementUpdate = this._hashForUpdates[target.__instanceId];
+ if (elementUpdate) {
+ return elementUpdate.entry.paused;
+ }
+ return false;
+ },
+
+ /**
+ *
+ * Schedules the 'update' callback_fn for a given target with a given priority.
+ * The 'update' callback_fn will be called every frame.
+ * The lower the priority, the earlier it is called.
+ *
+ * @deprecated since v3.4 please use .scheduleUpdate
+ * @param {cc.Class} target
+ * @param {Number} priority
+ * @param {Boolean} paused
+ * @example
+ * //register this object to scheduler
+ * cc.director.getScheduler().scheduleUpdateForTarget(this, priority, !this._isRunning );
+ */
+ scheduleUpdateForTarget: function(target, priority, paused){
+ //cc.log("scheduleUpdateForTarget is deprecated. Please use scheduleUpdate.");
+ this.scheduleUpdate(target, priority, paused);
+ },
+
+ /**
+ *
+ * Unschedule a callback function for a given target.
+ * If you want to unschedule the "update", use unscheudleUpdateForTarget.
+ *
+ * @deprecated since v3.4 please use .unschedule
+ * @param {cc.Class} target
+ * @param {function} callback callback[Function] or key[String]
+ * @example
+ * //unschedule a callback of target
+ * cc.director.getScheduler().unscheduleCallbackForTarget(function, this);
+ */
+ unscheduleCallbackForTarget:function (target, callback) {
+ //cc.log("unscheduleCallbackForTarget is deprecated. Please use unschedule.");
+ this.unschedule(callback, target);
+ },
+
+ /**
+ * Unschedules the update callback function for a given target
+ * @param {cc.Class} target
+ * @deprecated since v3.4 please use .unschedule
+ * @example
+ * //unschedules the "update" method.
+ * cc.director.getScheduler().unscheduleUpdateForTarget(this);
+ */
+ unscheduleUpdateForTarget:function (target) {
+ //cc.log("unscheduleUpdateForTarget is deprecated. Please use unschedule.");
+ this.unscheduleUpdate(target);
+ },
+
+ /**
+ * Unschedules all function callbacks for a given target. This also includes the "update" callback function.
+ * @deprecated since v3.4 please use .unscheduleAll
+ * @param {cc.Class} target
+ */
+ unscheduleAllCallbacksForTarget: function(target){
+ //cc.log("unscheduleAllCallbacksForTarget is deprecated. Please use unscheduleAll.");
+ this.unschedule(target.__instanceId + "", target);
+ },
+
+ /**
+ *
+ * Unschedules all function callbacks from all targets.
+ * You should NEVER call this method, unless you know what you are doing.
+ *
+ * @deprecated since v3.4 please use .unscheduleAllWithMinPriority
+ */
+ unscheduleAllCallbacks: function(){
+ //cc.log("unscheduleAllCallbacks is deprecated. Please use unscheduleAll.");
+ this.unscheduleAllWithMinPriority(cc.Scheduler.PRIORITY_SYSTEM);
+ },
+
+ /**
+ *
+ * Unschedules all function callbacks from all targets with a minimum priority.
+ * You should only call this with kCCPriorityNonSystemMin or higher.
+ *
+ * @deprecated since v3.4 please use .unscheduleAllWithMinPriority
+ * @param {Number} minPriority
+ */
+ unscheduleAllCallbacksWithMinPriority:function (minPriority) {
+ //cc.log("unscheduleAllCallbacksWithMinPriority is deprecated. Please use unscheduleAllWithMinPriority.");
+ this.unscheduleAllWithMinPriority(minPriority);
+ }
+});
+
+/**
+ * Priority level reserved for system services.
+ * @constant
+ * @type Number
+ */
+cc.Scheduler.PRIORITY_SYSTEM = (-2147483647 - 1);
+
+/**
+ * Minimum priority level for user scheduling.
+ * @constant
+ * @type Number
+ */
+cc.Scheduler.PRIORITY_NON_SYSTEM = cc.Scheduler.PRIORITY_SYSTEM + 1;
+
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/base-nodes/BaseNodesPropertyDefine.js b/frameworks/cocos2d-html5/cocos2d/core/base-nodes/BaseNodesPropertyDefine.js
new file mode 100644
index 0000000..2b2639c
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/base-nodes/BaseNodesPropertyDefine.js
@@ -0,0 +1,127 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc._tmp.PrototypeCCNode = function () {
+
+ var _p = cc.Node.prototype;
+
+ cc.defineGetterSetter(_p, "x", _p.getPositionX, _p.setPositionX);
+ cc.defineGetterSetter(_p, "y", _p.getPositionY, _p.setPositionY);
+ /** @expose */
+ _p.width;
+ cc.defineGetterSetter(_p, "width", _p._getWidth, _p._setWidth);
+ /** @expose */
+ _p.height;
+ cc.defineGetterSetter(_p, "height", _p._getHeight, _p._setHeight);
+ /** @expose */
+ _p.anchorX;
+ cc.defineGetterSetter(_p, "anchorX", _p._getAnchorX, _p._setAnchorX);
+ /** @expose */
+ _p.anchorY;
+ cc.defineGetterSetter(_p, "anchorY", _p._getAnchorY, _p._setAnchorY);
+ /** @expose */
+ _p.skewX;
+ cc.defineGetterSetter(_p, "skewX", _p.getSkewX, _p.setSkewX);
+ /** @expose */
+ _p.skewY;
+ cc.defineGetterSetter(_p, "skewY", _p.getSkewY, _p.setSkewY);
+ /** @expose */
+ _p.zIndex;
+ cc.defineGetterSetter(_p, "zIndex", _p.getLocalZOrder, _p.setLocalZOrder);
+ /** @expose */
+ _p.vertexZ;
+ cc.defineGetterSetter(_p, "vertexZ", _p.getVertexZ, _p.setVertexZ);
+ /** @expose */
+ _p.rotation;
+ cc.defineGetterSetter(_p, "rotation", _p.getRotation, _p.setRotation);
+ /** @expose */
+ _p.rotationX;
+ cc.defineGetterSetter(_p, "rotationX", _p.getRotationX, _p.setRotationX);
+ /** @expose */
+ _p.rotationY;
+ cc.defineGetterSetter(_p, "rotationY", _p.getRotationY, _p.setRotationY);
+ /** @expose */
+ _p.scale;
+ cc.defineGetterSetter(_p, "scale", _p.getScale, _p.setScale);
+ /** @expose */
+ _p.scaleX;
+ cc.defineGetterSetter(_p, "scaleX", _p.getScaleX, _p.setScaleX);
+ /** @expose */
+ _p.scaleY;
+ cc.defineGetterSetter(_p, "scaleY", _p.getScaleY, _p.setScaleY);
+ /** @expose */
+ _p.children;
+ cc.defineGetterSetter(_p, "children", _p.getChildren);
+ /** @expose */
+ _p.childrenCount;
+ cc.defineGetterSetter(_p, "childrenCount", _p.getChildrenCount);
+ /** @expose */
+ _p.parent;
+ cc.defineGetterSetter(_p, "parent", _p.getParent, _p.setParent);
+ /** @expose */
+ _p.visible;
+ cc.defineGetterSetter(_p, "visible", _p.isVisible, _p.setVisible);
+ /** @expose */
+ _p.running;
+ cc.defineGetterSetter(_p, "running", _p.isRunning);
+ /** @expose */
+ _p.ignoreAnchor;
+ cc.defineGetterSetter(_p, "ignoreAnchor", _p.isIgnoreAnchorPointForPosition, _p.ignoreAnchorPointForPosition);
+ /** @expose */
+ _p.tag;
+ /** @expose */
+ _p.userData;
+ /** @expose */
+ _p.userObject;
+ /** @expose */
+ _p.arrivalOrder;
+ /** @expose */
+ _p.actionManager;
+ cc.defineGetterSetter(_p, "actionManager", _p.getActionManager, _p.setActionManager);
+ /** @expose */
+ _p.scheduler;
+ cc.defineGetterSetter(_p, "scheduler", _p.getScheduler, _p.setScheduler);
+ //cc.defineGetterSetter(_p, "boundingBox", _p.getBoundingBox);
+ /** @expose */
+ _p.shaderProgram;
+ cc.defineGetterSetter(_p, "shaderProgram", _p.getShaderProgram, _p.setShaderProgram);
+
+ /** @expose */
+ _p.opacity;
+ cc.defineGetterSetter(_p, "opacity", _p.getOpacity, _p.setOpacity);
+ /** @expose */
+ _p.opacityModifyRGB;
+ cc.defineGetterSetter(_p, "opacityModifyRGB", _p.isOpacityModifyRGB);
+ /** @expose */
+ _p.cascadeOpacity;
+ cc.defineGetterSetter(_p, "cascadeOpacity", _p.isCascadeOpacityEnabled, _p.setCascadeOpacityEnabled);
+ /** @expose */
+ _p.color;
+ cc.defineGetterSetter(_p, "color", _p.getColor, _p.setColor);
+ /** @expose */
+ _p.cascadeColor;
+ cc.defineGetterSetter(_p, "cascadeColor", _p.isCascadeColorEnabled, _p.setCascadeColorEnabled);
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCAtlasNode.js b/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCAtlasNode.js
new file mode 100644
index 0000000..336ab7c
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCAtlasNode.js
@@ -0,0 +1,295 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.AtlasNode is a subclass of cc.Node, it knows how to render a TextureAtlas object.
+ *
+ * If you are going to render a TextureAtlas consider subclassing cc.AtlasNode (or a subclass of cc.AtlasNode)
+ *
+ * All features from cc.Node are valid
+ *
+ * You can create a cc.AtlasNode with an Atlas file, the width, the height of each item and the quantity of items to render
+ *
+ * @class
+ * @extends cc.Node
+ *
+ * @param {String} tile
+ * @param {Number} tileWidth
+ * @param {Number} tileHeight
+ * @param {Number} itemsToRender
+ * @example
+ * var node = new cc.AtlasNode("pathOfTile", 16, 16, 1);
+ *
+ * @property {cc.Texture2D} texture - Current used texture
+ * @property {cc.TextureAtlas} textureAtlas - Texture atlas for cc.AtlasNode
+ * @property {Number} quadsToDraw - Number of quads to draw
+ */
+cc.AtlasNode = cc.Node.extend(/** @lends cc.AtlasNode# */{
+ textureAtlas: null,
+ quadsToDraw: 0,
+
+ //! chars per row
+ _itemsPerRow: 0,
+ //! chars per column
+ _itemsPerColumn: 0,
+ //! width of each char
+ _itemWidth: 0,
+ //! height of each char
+ _itemHeight: 0,
+
+ // protocol variables
+ _opacityModifyRGB: false,
+ _blendFunc: null,
+
+ // This variable is only used for CCLabelAtlas FPS display. So plz don't modify its value.
+ _ignoreContentScaleFactor: false,
+ _className: "AtlasNode",
+
+ _texture: null,
+ _textureForCanvas: null,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {String} tile
+ * @param {Number} tileWidth
+ * @param {Number} tileHeight
+ * @param {Number} itemsToRender
+ */
+ ctor: function (tile, tileWidth, tileHeight, itemsToRender) {
+ cc.Node.prototype.ctor.call(this);
+ this._blendFunc = {src: cc.BLEND_SRC, dst: cc.BLEND_DST};
+ this._ignoreContentScaleFactor = false;
+ itemsToRender !== undefined && this.initWithTileFile(tile, tileWidth, tileHeight, itemsToRender);
+ },
+
+ _createRenderCmd: function(){
+ if(cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ this._renderCmd = new cc.AtlasNode.CanvasRenderCmd(this);
+ else
+ this._renderCmd = new cc.AtlasNode.WebGLRenderCmd(this);
+ },
+
+ /**
+ * Updates the Atlas (indexed vertex array).
+ * Empty implementation, shall be overridden in subclasses
+ * @function
+ */
+ updateAtlasValues: function () {
+ cc.log(cc._LogInfos.AtlasNode_updateAtlasValues);
+ },
+
+ /**
+ * Get color value of the atlas node
+ * @function
+ * @return {cc.Color}
+ */
+ getColor: function () {
+ if (this._opacityModifyRGB)
+ return this._renderCmd._colorUnmodified;
+ return cc.Node.prototype.getColor.call(this);
+ },
+
+ /**
+ * Set whether color should be changed with the opacity value,
+ * if true, node color will change while opacity changes.
+ * @function
+ * @param {Boolean} value
+ */
+ setOpacityModifyRGB: function (value) {
+ var oldColor = this.color;
+ this._opacityModifyRGB = value;
+ this.setColor(oldColor);
+ },
+
+ /**
+ * Get whether color should be changed with the opacity value
+ * @function
+ * @return {Boolean}
+ */
+ isOpacityModifyRGB: function () {
+ return this._opacityModifyRGB;
+ },
+
+ /**
+ * Get node's blend function
+ * @function
+ * @return {cc.BlendFunc}
+ */
+ getBlendFunc: function () {
+ return this._blendFunc;
+ },
+
+ /**
+ * Set node's blend function
+ * This function accept either cc.BlendFunc object or source value and destination value
+ * @function
+ * @param {Number | cc.BlendFunc} src
+ * @param {Number} dst
+ */
+ setBlendFunc: function (src, dst) {
+ if (dst === undefined)
+ this._blendFunc = src;
+ else
+ this._blendFunc = {src: src, dst: dst};
+ },
+
+ /**
+ * Set the atlas texture
+ * @function
+ * @param {cc.TextureAtlas} value The texture
+ */
+ setTextureAtlas: function (value) {
+ this.textureAtlas = value;
+ },
+
+ /**
+ * Get the atlas texture
+ * @function
+ * @return {cc.TextureAtlas}
+ */
+ getTextureAtlas: function () {
+ return this.textureAtlas;
+ },
+
+ /**
+ * Get the number of quads to be rendered
+ * @function
+ * @return {Number}
+ */
+ getQuadsToDraw: function () {
+ return this.quadsToDraw;
+ },
+
+ /**
+ * Set the number of quads to be rendered
+ * @function
+ * @param {Number} quadsToDraw
+ */
+ setQuadsToDraw: function (quadsToDraw) {
+ this.quadsToDraw = quadsToDraw;
+ },
+
+ /**
+ * Initializes an cc.AtlasNode object with an atlas texture file name, the width, the height of each tile and the quantity of tiles to render
+ * @function
+ * @param {String} tile The atlas texture file name
+ * @param {Number} tileWidth The width of each tile
+ * @param {Number} tileHeight The height of each tile
+ * @param {Number} itemsToRender The quantity of tiles to be rendered
+ * @return {Boolean}
+ */
+ initWithTileFile: function (tile, tileWidth, tileHeight, itemsToRender) {
+ if (!tile)
+ throw new Error("cc.AtlasNode.initWithTileFile(): title should not be null");
+ var texture = cc.textureCache.addImage(tile);
+ return this.initWithTexture(texture, tileWidth, tileHeight, itemsToRender);
+ },
+
+ /**
+ * Initializes an CCAtlasNode with an atlas texture, the width, the height of each tile and the quantity of tiles to render
+ * @function
+ * @param {cc.Texture2D} texture The atlas texture
+ * @param {Number} tileWidth The width of each tile
+ * @param {Number} tileHeight The height of each tile
+ * @param {Number} itemsToRender The quantity of tiles to be rendered
+ * @return {Boolean}
+ */
+ initWithTexture: function(texture, tileWidth, tileHeight, itemsToRender){
+ return this._renderCmd.initWithTexture(texture, tileWidth, tileHeight, itemsToRender);
+ },
+
+ /**
+ * Set node's color
+ * @function
+ * @param {cc.Color} color Color object created with cc.color(r, g, b).
+ */
+ setColor: function(color){
+ this._renderCmd.setColor(color);
+ },
+
+ /**
+ * Set node's opacity
+ * @function
+ * @param {Number} opacity The opacity value
+ */
+ setOpacity: function (opacity) {
+ this._renderCmd.setOpacity(opacity);
+ },
+
+ /**
+ * Get the current texture
+ * @function
+ * @return {cc.Texture2D}
+ */
+ getTexture: function(){
+ return this._texture;
+ },
+
+ /**
+ * Replace the current texture with a new one
+ * @function
+ * @param {cc.Texture2D} texture The new texture
+ */
+ setTexture: function(texture){
+ this._texture = texture;
+ },
+
+ _setIgnoreContentScaleFactor: function (ignoreContentScaleFactor) {
+ this._ignoreContentScaleFactor = ignoreContentScaleFactor;
+ }
+});
+
+
+var _p = cc.AtlasNode.prototype;
+// Override properties
+cc.defineGetterSetter(_p, "opacity", _p.getOpacity, _p.setOpacity);
+cc.defineGetterSetter(_p, "color", _p.getColor, _p.setColor);
+
+// Extended properties
+/** @expose */
+_p.texture;
+cc.defineGetterSetter(_p, "texture", _p.getTexture, _p.setTexture);
+/** @expose */
+_p.textureAtlas;
+/** @expose */
+_p.quadsToDraw;
+
+cc.EventHelper.prototype.apply(_p);
+
+/**
+ * Creates a cc.AtlasNode with an Atlas file the width and height of each item and the quantity of items to render
+ * @deprecated since v3.0, please use new construction instead
+ * @function
+ * @static
+ * @param {String} tile
+ * @param {Number} tileWidth
+ * @param {Number} tileHeight
+ * @param {Number} itemsToRender
+ * @return {cc.AtlasNode}
+ */
+cc.AtlasNode.create = function (tile, tileWidth, tileHeight, itemsToRender) {
+ return new cc.AtlasNode(tile, tileWidth, tileHeight, itemsToRender);
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCAtlasNodeCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCAtlasNodeCanvasRenderCmd.js
new file mode 100644
index 0000000..4fb324f
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCAtlasNodeCanvasRenderCmd.js
@@ -0,0 +1,91 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.AtlasNode's rendering objects of Canvas
+ */
+(function () {
+ cc.AtlasNode.CanvasRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = false;
+ this._colorUnmodified = cc.color.WHITE;
+ this._textureToRender = null;
+ };
+
+ var proto = cc.AtlasNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ proto.constructor = cc.AtlasNode.CanvasRenderCmd;
+
+ proto.initWithTexture = function (texture, tileWidth, tileHeight, itemsToRender) {
+ var node = this._node;
+ node._itemWidth = tileWidth;
+ node._itemHeight = tileHeight;
+
+ node._opacityModifyRGB = true;
+ node._texture = texture;
+ if (!node._texture) {
+ cc.log(cc._LogInfos.AtlasNode__initWithTexture);
+ return false;
+ }
+ this._textureToRender = texture;
+ this._calculateMaxItems();
+
+ node.quadsToDraw = itemsToRender;
+ return true;
+ };
+
+ proto.setColor = function (color3) {
+ var node = this._node;
+ var locRealColor = node._realColor;
+ if ((locRealColor.r === color3.r) && (locRealColor.g === color3.g) && (locRealColor.b === color3.b))
+ return;
+ this._colorUnmodified = color3;
+ this._changeTextureColor();
+ };
+
+ proto._changeTextureColor = function () {
+ var node = this._node;
+ var texture = node._texture,
+ color = this._colorUnmodified,
+ element = texture.getHtmlElementObj();
+ var textureRect = cc.rect(0, 0, element.width, element.height);
+ if (texture === this._textureToRender)
+ this._textureToRender = texture._generateColorTexture(color.r, color.g, color.b, textureRect);
+ else
+ texture._generateColorTexture(color.r, color.g, color.b, textureRect, this._textureToRender.getHtmlElementObj());
+ };
+
+ proto.setOpacity = function (opacity) {
+ var node = this._node;
+ cc.Node.prototype.setOpacity.call(node, opacity);
+ };
+
+ proto._calculateMaxItems = function () {
+ var node = this._node;
+ var selTexture = node._texture;
+ var size = selTexture.getContentSize();
+
+ node._itemsPerColumn = 0 | (size.height / node._itemHeight);
+ node._itemsPerRow = 0 | (size.width / node._itemWidth);
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js
new file mode 100644
index 0000000..5810d00
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js
@@ -0,0 +1,159 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.AtlasNode's rendering objects of WebGL
+ */
+(function () {
+ cc.AtlasNode.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+ this._textureAtlas = null;
+ this._colorUnmodified = cc.color.WHITE;
+ this._colorF32Array = null;
+ this._uniformColor = null;
+
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+
+ //shader stuff
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE_UCOLOR);
+ this._uniformColor = cc._renderContext.getUniformLocation(this._shaderProgram.getProgram(), "u_color");
+ };
+
+ var proto = cc.AtlasNode.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ proto.constructor = cc.AtlasNode.WebGLRenderCmd;
+
+ proto._updateBlendFunc = function () {
+ var node = this._node;
+ if (!this._textureAtlas.texture.hasPremultipliedAlpha()) {
+ node._blendFunc.src = cc.SRC_ALPHA;
+ node._blendFunc.dst = cc.ONE_MINUS_SRC_ALPHA;
+ }
+ };
+
+ proto._updateOpacityModifyRGB = function () {
+ this._node._opacityModifyRGB = this._textureAtlas.texture.hasPremultipliedAlpha();
+ };
+
+ proto.rendering = function (ctx) {
+ var context = ctx || cc._renderContext, node = this._node;
+
+ var wt = this._worldTransform;
+ this._matrix.mat[0] = wt.a;
+ this._matrix.mat[4] = wt.c;
+ this._matrix.mat[12] = wt.tx;
+ this._matrix.mat[1] = wt.b;
+ this._matrix.mat[5] = wt.d;
+ this._matrix.mat[13] = wt.ty;
+
+ this._glProgramState.apply(this._matrix);
+
+ cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
+ if (this._uniformColor && this._colorF32Array) {
+ context.uniform4fv(this._uniformColor, this._colorF32Array);
+ this._textureAtlas.drawNumberOfQuads(node.quadsToDraw, 0);
+ }
+ };
+
+ proto.initWithTexture = function (texture, tileWidth, tileHeight, itemsToRender) {
+ var node = this._node;
+ node._itemWidth = tileWidth;
+ node._itemHeight = tileHeight;
+ this._colorUnmodified = cc.color.WHITE;
+ node._opacityModifyRGB = true;
+
+ node._blendFunc.src = cc.BLEND_SRC;
+ node._blendFunc.dst = cc.BLEND_DST;
+
+ var locRealColor = node._realColor;
+ this._colorF32Array = new Float32Array([locRealColor.r / 255.0, locRealColor.g / 255.0, locRealColor.b / 255.0, node._realOpacity / 255.0]);
+ this._textureAtlas = new cc.TextureAtlas();
+ this._textureAtlas.initWithTexture(texture, itemsToRender);
+
+ if (!this._textureAtlas) {
+ cc.log(cc._LogInfos.AtlasNode__initWithTexture);
+ return false;
+ }
+
+ this._updateBlendFunc();
+ this._updateOpacityModifyRGB();
+ this._calculateMaxItems();
+ node.quadsToDraw = itemsToRender;
+
+ return true;
+ };
+
+ proto.setColor = function (color3) {
+ var temp = cc.color(color3.r, color3.g, color3.b), node = this._node;
+ this._colorUnmodified = color3;
+ var locDisplayedOpacity = this._displayedOpacity;
+ if (node._opacityModifyRGB) {
+ temp.r = temp.r * locDisplayedOpacity / 255;
+ temp.g = temp.g * locDisplayedOpacity / 255;
+ temp.b = temp.b * locDisplayedOpacity / 255;
+ }
+ cc.Node.prototype.setColor.call(node, temp);
+ };
+
+ proto.setOpacity = function (opacity) {
+ var node = this._node;
+ cc.Node.prototype.setOpacity.call(node, opacity);
+ // special opacity for premultiplied textures
+ if (node._opacityModifyRGB) {
+ node.color = this._colorUnmodified;
+ }
+ };
+
+ proto._updateColor = function () {
+ if (this._colorF32Array) {
+ var locDisplayedColor = this._displayedColor;
+ this._colorF32Array[0] = locDisplayedColor.r / 255.0;
+ this._colorF32Array[1] = locDisplayedColor.g / 255.0;
+ this._colorF32Array[2] = locDisplayedColor.b / 255.0;
+ this._colorF32Array[3] = this._displayedOpacity / 255.0;
+ }
+ };
+
+ proto.getTexture = function () {
+ return this._textureAtlas.texture;
+ };
+
+ proto.setTexture = function (texture) {
+ this._textureAtlas.texture = texture;
+ this._updateBlendFunc();
+ this._updateOpacityModifyRGB();
+ };
+
+ proto._calculateMaxItems = function () {
+ var node = this._node;
+ var selTexture = this._textureAtlas.texture;
+ var size = selTexture.getContentSize();
+ if (node._ignoreContentScaleFactor)
+ size = selTexture.getContentSizeInPixels();
+
+ node._itemsPerColumn = 0 | (size.height / node._itemHeight);
+ node._itemsPerRow = 0 | (size.width / node._itemWidth);
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCNode.js b/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCNode.js
new file mode 100644
index 0000000..9d3e6f1
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCNode.js
@@ -0,0 +1,2604 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Default Node tag
+ * @constant
+ * @type Number
+ */
+cc.NODE_TAG_INVALID = -1;
+
+/**
+ * XXX: Yes, nodes might have a sort problem once every 15 days if the game runs at 60 FPS and each frame sprites are reordered.
+ */
+cc.s_globalOrderOfArrival = 1;
+
+/**
+ * cc.Node is the root class of all node. Anything that gets drawn or contains things that get drawn is a cc.Node.
+ * The most popular cc.Nodes are: cc.Scene, cc.Layer, cc.Sprite, cc.Menu.
+ *
+ * The main features of a cc.Node are:
+ * - They can contain other cc.Node nodes (addChild, getChildByTag, removeChild, etc)
+ * - They can schedule periodic callback (schedule, unschedule, etc)
+ * - They can execute actions (runAction, stopAction, etc)
+ *
+ * Some cc.Node nodes provide extra functionality for them or their children.
+ *
+ * Subclassing a cc.Node usually means (one/all) of:
+ * - overriding constructor function "ctor" to initialize resources and schedule callbacks
+ * - create callbacks to handle the advancement of time
+ *
+ * Features of cc.Node:
+ * - position
+ * - scale (x, y)
+ * - rotation (in degrees, clockwise)
+ * - anchor point
+ * - size
+ * - color
+ * - opacity
+ * - visible
+ * - z-order
+ * - WebGL z position
+ *
+ * Default values:
+ * - rotation: 0
+ * - position: (x=0,y=0)
+ * - scale: (x=1,y=1)
+ * - contentSize: (x=0,y=0)
+ * - anchorPoint: (x=0,y=0)
+ * - color: (r=255,g=255,b=255)
+ * - opacity: 255
+ *
+ * Limitations:
+ * - A cc.Node is a "void" object. It doesn't have a texture
+ *
+ * Order in transformations with grid disabled
+ * -# The node will be translated (position)
+ * -# The node will be rotated (rotation)
+ * -# The node will be scaled (scale)
+ *
+ *
Order in transformations with grid enabled
+ * -# The node will be translated (position)
+ * -# The node will be rotated (rotation)
+ * -# The node will be scaled (scale)
+ * -# The grid will capture the screen
+ * -# The grid will render the captured screen
+ *
+ * @class
+ * @extends cc.Class
+ *
+ * @property {Number} x - x axis position of node
+ * @property {Number} y - y axis position of node
+ * @property {Number} width - Width of node
+ * @property {Number} height - Height of node
+ * @property {Number} anchorX - Anchor point's position on x axis
+ * @property {Number} anchorY - Anchor point's position on y axis
+ * @property {Boolean} ignoreAnchor - Indicate whether ignore the anchor point property for positioning
+ * @property {Number} skewX - Skew x
+ * @property {Number} skewY - Skew y
+ * @property {Number} zIndex - Z order in depth which stands for the drawing order
+ * @property {Number} vertexZ - WebGL Z vertex of this node, z order works OK if all the nodes uses the same openGL Z vertex
+ * @property {Number} rotation - Rotation of node
+ * @property {Number} rotationX - Rotation on x axis
+ * @property {Number} rotationY - Rotation on y axis
+ * @property {Number} scale - Scale of node
+ * @property {Number} scaleX - Scale on x axis
+ * @property {Number} scaleY - Scale on y axis
+ * @property {Boolean} visible - Indicate whether node is visible or not
+ * @property {cc.Color} color - Color of node, default value is white: (255, 255, 255)
+ * @property {Boolean} cascadeColor - Indicate whether node's color value affect its child nodes, default value is false
+ * @property {Number} opacity - Opacity of node, default value is 255
+ * @property {Boolean} opacityModifyRGB - Indicate whether opacity affect the color value, default value is false
+ * @property {Boolean} cascadeOpacity - Indicate whether node's opacity value affect its child nodes, default value is false
+ * @property {Array} children - <@readonly> All children nodes
+ * @property {Number} childrenCount - <@readonly> Number of children
+ * @property {cc.Node} parent - Parent node
+ * @property {Boolean} running - <@readonly> Indicate whether node is running or not
+ * @property {Number} tag - Tag of node
+ * @property {Object} userData - Custom user data
+ * @property {Object} userObject - User assigned CCObject, similar to userData, but instead of holding a void* it holds an id
+ * @property {Number} arrivalOrder - The arrival order, indicates which children is added previously
+ * @property {cc.ActionManager} actionManager - The CCActionManager object that is used by all actions.
+ * @property {cc.Scheduler} scheduler - cc.Scheduler used to schedule all "updates" and timers.
+ * @property {cc.GridBase} grid - grid object that is used when applying effects
+ * @property {cc.GLProgram} shaderProgram - The shader program currently used for this node
+ * @property {Number} glServerState - The state of OpenGL server side
+ */
+cc.Node = cc.Class.extend(/** @lends cc.Node# */{
+ _localZOrder: 0, ///< Local order (relative to its siblings) used to sort the node
+ _globalZOrder: 0, ///< Global order used to sort the node
+ _vertexZ: 0.0,
+ _customZ: NaN,
+
+ _rotationX: 0,
+ _rotationY: 0.0,
+ _scaleX: 1.0,
+ _scaleY: 1.0,
+ _position: null,
+
+ _normalizedPosition:null,
+ _usingNormalizedPosition: false,
+ _normalizedPositionDirty: false,
+
+ _skewX: 0.0,
+ _skewY: 0.0,
+ // children (lazy allocs),
+ _children: null,
+ // lazy alloc,
+ _visible: true,
+ _anchorPoint: null,
+ _contentSize: null,
+ _running: false,
+ _parent: null,
+
+ // "whole screen" objects. like Scenes and Layers, should set _ignoreAnchorPointForPosition to true
+ _ignoreAnchorPointForPosition: false,
+ tag: cc.NODE_TAG_INVALID,
+ // userData is always initialized as nil
+ userData: null,
+ userObject: null,
+
+ //since 2.0 api
+ _reorderChildDirty: false,
+ arrivalOrder: 0,
+
+ _actionManager: null,
+ _scheduler: null,
+
+ _additionalTransformDirty: false,
+ _additionalTransform: null,
+ _componentContainer: null,
+ _isTransitionFinished: false,
+
+ _className: "Node",
+ _showNode: false,
+ _name: "", ///Properties configuration function
+ * All properties in attrs will be set to the node,
+ * when the setter of the node is available,
+ * the property will be set via setter function.
+ *
+ * @function
+ * @param {Object} attrs Properties to be set to node
+ */
+ attr: function (attrs) {
+ for (var key in attrs) {
+ this[key] = attrs[key];
+ }
+ },
+
+ /**
+ * Returns the skew degrees in X
+ * The X skew angle of the node in degrees.
+ * This angle describes the shear distortion in the X direction.
+ * Thus, it is the angle between the Y axis and the left edge of the shape
+ * The default skewX angle is 0. Positive values distort the node in a CW direction.
+ *
+ * @function
+ * @return {Number} The X skew angle of the node in degrees.
+ */
+ getSkewX: function () {
+ return this._skewX;
+ },
+
+ /**
+ *
+ * Changes the X skew angle of the node in degrees.
+ *
+ * This angle describes the shear distortion in the X direction.
+ * Thus, it is the angle between the Y axis and the left edge of the shape
+ * The default skewX angle is 0. Positive values distort the node in a CW direction.
+ *
+ * @function
+ * @param {Number} newSkewX The X skew angle of the node in degrees.
+ */
+ setSkewX: function (newSkewX) {
+ this._skewX = newSkewX;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns the skew degrees in Y
+ * The Y skew angle of the node in degrees.
+ * This angle describes the shear distortion in the Y direction.
+ * Thus, it is the angle between the X axis and the bottom edge of the shape
+ * The default skewY angle is 0. Positive values distort the node in a CCW direction.
+ *
+ * @function
+ * @return {Number} The Y skew angle of the node in degrees.
+ */
+ getSkewY: function () {
+ return this._skewY;
+ },
+
+ /**
+ *
+ * Changes the Y skew angle of the node in degrees.
+ *
+ * This angle describes the shear distortion in the Y direction.
+ * Thus, it is the angle between the X axis and the bottom edge of the shape
+ * The default skewY angle is 0. Positive values distort the node in a CCW direction.
+ *
+ * @function
+ * @param {Number} newSkewY The Y skew angle of the node in degrees.
+ */
+ setSkewY: function (newSkewY) {
+ this._skewY = newSkewY;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * LocalZOrder is the 'key' used to sort the node relative to its siblings.
+ *
+ * The Node's parent will sort all its children based ont the LocalZOrder value.
+ * If two nodes have the same LocalZOrder, then the node that was added first to the children's array
+ * will be in front of the other node in the array.
+ *
+ * Also, the Scene Graph is traversed using the "In-Order" tree traversal algorithm ( http://en.wikipedia.org/wiki/Tree_traversal#In-order )
+ *
+ * And Nodes that have LocalZOder values < 0 are the "left" subtree
+ * While Nodes with LocalZOder >=0 are the "right" subtree.
+ * @function
+ * @param {Number} localZOrder
+ */
+ setLocalZOrder: function (localZOrder) {
+ if (localZOrder === this._localZOrder)
+ return;
+ if (this._parent)
+ this._parent.reorderChild(this, localZOrder);
+ else
+ this._localZOrder = localZOrder;
+ cc.eventManager._setDirtyForNode(this);
+ },
+
+ //Helper function used by `setLocalZOrder`. Don't use it unless you know what you are doing.
+ _setLocalZOrder: function (localZOrder) {
+ this._localZOrder = localZOrder;
+ },
+
+ /**
+ * Returns the local Z order of this node.
+ * @function
+ * @returns {Number} The local (relative to its siblings) Z order.
+ */
+ getLocalZOrder: function () {
+ return this._localZOrder;
+ },
+
+ /**
+ * Returns z order of this node
+ * @function
+ * @return {Number}
+ * @deprecated since 3.0, please use getLocalZOrder instead
+ */
+ getZOrder: function () {
+ cc.log(cc._LogInfos.Node_getZOrder);
+ return this.getLocalZOrder();
+ },
+
+ /**
+ *
+ * Sets the Z order which stands for the drawing order, and reorder this node in its parent's children array.
+ *
+ * The Z order of node is relative to its "brothers": children of the same parent.
+ * It's nothing to do with OpenGL's z vertex. This one only affects the draw order of nodes in cocos2d.
+ * The larger number it is, the later this node will be drawn in each message loop.
+ * Please refer to setVertexZ(float) for the difference.
+ *
+ * @function
+ * @param {Number} z Z order of this node.
+ * @deprecated since 3.0, please use setLocalZOrder instead
+ */
+ setZOrder: function (z) {
+ cc.log(cc._LogInfos.Node_setZOrder);
+ this.setLocalZOrder(z);
+ },
+
+ /**
+ * Defines the oder in which the nodes are renderer.
+ * Nodes that have a Global Z Order lower, are renderer first.
+ *
+ * In case two or more nodes have the same Global Z Order, the oder is not guaranteed.
+ * The only exception if the Nodes have a Global Z Order == 0. In that case, the Scene Graph order is used.
+ *
+ * By default, all nodes have a Global Z Order = 0. That means that by default, the Scene Graph order is used to render the nodes.
+ *
+ * Global Z Order is useful when you need to render nodes in an order different than the Scene Graph order.
+ *
+ * Limitations: Global Z Order can't be used used by Nodes that have SpriteBatchNode as one of their ancestors.
+ * And if ClippingNode is one of the ancestors, then "global Z order" will be relative to the ClippingNode.
+ * @function
+ * @param {Number} globalZOrder
+ */
+ setGlobalZOrder: function (globalZOrder) {
+ if (this._globalZOrder !== globalZOrder) {
+ this._globalZOrder = globalZOrder;
+ cc.eventManager._setDirtyForNode(this);
+ }
+ },
+
+ /**
+ * Return the Node's Global Z Order.
+ * @function
+ * @returns {number} The node's global Z order
+ */
+ getGlobalZOrder: function () {
+ return this._globalZOrder;
+ },
+
+ /**
+ * Returns WebGL Z vertex of this node.
+ * @function
+ * @return {Number} WebGL Z vertex of this node
+ */
+ getVertexZ: function () {
+ return this._vertexZ;
+ },
+
+ /**
+ *
+ * Sets the real WebGL Z vertex.
+ *
+ * Differences between openGL Z vertex and cocos2d Z order:
+ * - WebGL Z modifies the Z vertex, and not the Z order in the relation between parent-children
+ * - WebGL Z might require to set 2D projection
+ * - cocos2d Z order works OK if all the nodes uses the same WebGL Z vertex. eg: vertexZ = 0
+ *
+ * @warning Use it at your own risk since it might break the cocos2d parent-children z order
+ *
+ * @function
+ * @param {Number} Var
+ */
+ setVertexZ: function (Var) {
+ this._customZ = this._vertexZ = Var;
+ },
+
+ /**
+ * Returns the rotation (angle) of the node in degrees. 0 is the default rotation angle. Positive values rotate node clockwise.
+ * @function
+ * @return {Number} The rotation of the node in degrees.
+ */
+ getRotation: function () {
+ if (this._rotationX !== this._rotationY)
+ cc.log(cc._LogInfos.Node_getRotation);
+ return this._rotationX;
+ },
+
+ /**
+ *
+ * Sets the rotation (angle) of the node in degrees.
+ *
+ * 0 is the default rotation angle.
+ * Positive values rotate node clockwise, and negative values for anti-clockwise.
+ *
+ * @function
+ * @param {Number} newRotation The rotation of the node in degrees.
+ */
+ setRotation: function (newRotation) {
+ this._rotationX = this._rotationY = newRotation;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns the X axis rotation (angle) which represent a horizontal rotational skew of the node in degrees.
+ * 0 is the default rotation angle. Positive values rotate node clockwise
+ * (support only in WebGL rendering mode)
+ * @function
+ * @return {Number} The X rotation in degrees.
+ */
+ getRotationX: function () {
+ return this._rotationX;
+ },
+
+ /**
+ *
+ * Sets the X rotation (angle) of the node in degrees which performs a horizontal rotational skew.
+ * (support only in WebGL rendering mode)
+ * 0 is the default rotation angle.
+ * Positive values rotate node clockwise, and negative values for anti-clockwise.
+ *
+ * @param {Number} rotationX The X rotation in degrees which performs a horizontal rotational skew.
+ */
+ setRotationX: function (rotationX) {
+ this._rotationX = rotationX;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns the Y axis rotation (angle) which represent a vertical rotational skew of the node in degrees.
+ * 0 is the default rotation angle. Positive values rotate node clockwise
+ * (support only in WebGL rendering mode)
+ * @function
+ * @return {Number} The Y rotation in degrees.
+ */
+ getRotationY: function () {
+ return this._rotationY;
+ },
+
+ /**
+ *
+ * Sets the Y rotation (angle) of the node in degrees which performs a vertical rotational skew.
+ * (support only in WebGL rendering mode)
+ * 0 is the default rotation angle.
+ * Positive values rotate node clockwise, and negative values for anti-clockwise.
+ *
+ * @param rotationY The Y rotation in degrees.
+ */
+ setRotationY: function (rotationY) {
+ this._rotationY = rotationY;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns the scale factor of the node.
+ * @warning: Assertion will fail when _scaleX != _scaleY.
+ * @function
+ * @return {Number} The scale factor
+ */
+ getScale: function () {
+ if (this._scaleX !== this._scaleY)
+ cc.log(cc._LogInfos.Node_getScale);
+ return this._scaleX;
+ },
+
+ /**
+ * Sets the scale factor of the node. 1.0 is the default scale factor. This function can modify the X and Y scale at the same time.
+ * @function
+ * @param {Number} scale or scaleX value
+ * @param {Number} [scaleY=]
+ */
+ setScale: function (scale, scaleY) {
+ this._scaleX = scale;
+ this._scaleY = (scaleY || scaleY === 0) ? scaleY : scale;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns the scale factor on X axis of this node
+ * @function
+ * @return {Number} The scale factor on X axis.
+ */
+ getScaleX: function () {
+ return this._scaleX;
+ },
+
+ /**
+ *
+ * Changes the scale factor on X axis of this node
+ * The default value is 1.0 if you haven't changed it before
+ *
+ * @function
+ * @param {Number} newScaleX The scale factor on X axis.
+ */
+ setScaleX: function (newScaleX) {
+ this._scaleX = newScaleX;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns the scale factor on Y axis of this node
+ * @function
+ * @return {Number} The scale factor on Y axis.
+ */
+ getScaleY: function () {
+ return this._scaleY;
+ },
+
+ /**
+ *
+ * Changes the scale factor on Y axis of this node
+ * The Default value is 1.0 if you haven't changed it before.
+ *
+ * @function
+ * @param {Number} newScaleY The scale factor on Y axis.
+ */
+ setScaleY: function (newScaleY) {
+ this._scaleY = newScaleY;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ *
+ * Changes the position (x,y) of the node in cocos2d coordinates.
+ * The original point (0,0) is at the left-bottom corner of screen.
+ * Usually we use cc.p(x,y) to compose CCPoint object.
+ * and Passing two numbers (x,y) is more efficient than passing CCPoint object.
+ *
+ * @function
+ * @param {cc.Point|Number} newPosOrxValue The position (x,y) of the node in coordinates or the X coordinate for position
+ * @param {Number} [yValue] Y coordinate for position
+ * @example
+ * var size = cc.winSize;
+ * node.setPosition(size.width/2, size.height/2);
+ */
+ setPosition: function (newPosOrxValue, yValue) {
+ var locPosition = this._position;
+ if (yValue === undefined) {
+ if (locPosition.x === newPosOrxValue.x && locPosition.y === newPosOrxValue.y)
+ return;
+ locPosition.x = newPosOrxValue.x;
+ locPosition.y = newPosOrxValue.y;
+ } else {
+ if (locPosition.x === newPosOrxValue && locPosition.y === yValue)
+ return;
+ locPosition.x = newPosOrxValue;
+ locPosition.y = yValue;
+ }
+ this._usingNormalizedPosition = false;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ *
+ * Sets the position (x,y) using values between 0 and 1.
+ * The positions in pixels is calculated like the following:
+ * _position = _normalizedPosition * parent.getContentSize()
+ *
+ * @param {cc.Point|Number} posOrX
+ * @param {Number} [y]
+ */
+ setNormalizedPosition: function(posOrX, y){
+ var locPosition = this._normalizedPosition;
+ if (y === undefined) {
+ locPosition.x = posOrX.x;
+ locPosition.y = posOrX.y;
+ } else {
+ locPosition.x = posOrX;
+ locPosition.y = y;
+ }
+ this._normalizedPositionDirty = this._usingNormalizedPosition = true;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns a copy of the position (x,y) of the node in cocos2d coordinates. (0,0) is the left-bottom corner.
+ * @function
+ * @return {cc.Point} The position (x,y) of the node in OpenGL coordinates
+ */
+ getPosition: function () {
+ return cc.p(this._position);
+ },
+
+ /**
+ * returns the normalized position
+ * @returns {cc.Point}
+ */
+ getNormalizedPosition: function(){
+ return cc.p(this._normalizedPosition);
+ },
+
+ /**
+ * Returns the x axis position of the node in cocos2d coordinates.
+ * @function
+ * @return {Number}
+ */
+ getPositionX: function () {
+ return this._position.x;
+ },
+
+ /**
+ * Sets the x axis position of the node in cocos2d coordinates.
+ * @function
+ * @param {Number} x The new position in x axis
+ */
+ setPositionX: function (x) {
+ this._position.x = x;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns the y axis position of the node in cocos2d coordinates.
+ * @function
+ * @return {Number}
+ */
+ getPositionY: function () {
+ return this._position.y;
+ },
+
+ /**
+ * Sets the y axis position of the node in cocos2d coordinates.
+ * @function
+ * @param {Number} y The new position in y axis
+ */
+ setPositionY: function (y) {
+ this._position.y = y;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns the amount of children.
+ * @function
+ * @return {Number} The amount of children.
+ */
+ getChildrenCount: function () {
+ return this._children.length;
+ },
+
+ /**
+ * Returns an array of all children
+ * Composing a "tree" structure is a very important feature of CCNode
+ * @function
+ * @return {Array} An array of children
+ * @example
+ * //This sample code traverses all children nodes, and set their position to (0,0)
+ * var allChildren = parent.getChildren();
+ * for(var i = 0; i< allChildren.length; i++) {
+ * allChildren[i].setPosition(0,0);
+ * }
+ */
+ getChildren: function () {
+ return this._children;
+ },
+
+ /**
+ * Returns if the node is visible
+ * @function
+ * @see cc.Node#setVisible
+ * @return {Boolean} true if the node is visible, false if the node is hidden.
+ */
+ isVisible: function () {
+ return this._visible;
+ },
+
+ /**
+ * Sets whether the node is visible
+ * The default value is true
+ * @function
+ * @param {Boolean} visible Pass true to make the node visible, false to hide the node.
+ */
+ setVisible: function (visible) {
+ if (this._visible !== visible) {
+ this._visible = visible;
+ //if(visible)
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ cc.renderer.childrenOrderDirty = true;
+ }
+ },
+
+ /**
+ * Returns a copy of the anchor point.
+ * Anchor point is the point around which all transformations and positioning manipulations take place.
+ * It's like a pin in the node where it is "attached" to its parent.
+ * The anchorPoint is normalized, like a percentage. (0,0) means the bottom-left corner and (1,1) means the top-right corner.
+ * But you can use values higher than (1,1) and lower than (0,0) too.
+ * The default anchor point is (0.5,0.5), so it starts at the center of the node.
+ * @function
+ * @return {cc.Point} The anchor point of node.
+ */
+ getAnchorPoint: function () {
+ return cc.p(this._anchorPoint);
+ },
+
+ /**
+ *
+ * Sets the anchor point in percent.
+ *
+ * anchor point is the point around which all transformations and positioning manipulations take place.
+ * It's like a pin in the node where it is "attached" to its parent.
+ * The anchorPoint is normalized, like a percentage. (0,0) means the bottom-left corner and (1,1) means the top-right corner.
+ * But you can use values higher than (1,1) and lower than (0,0) too.
+ * The default anchor point is (0.5,0.5), so it starts at the center of the node.
+ *
+ * @function
+ * @param {cc.Point|Number} point The anchor point of node or The x axis anchor of node.
+ * @param {Number} [y] The y axis anchor of node.
+ */
+ setAnchorPoint: function (point, y) {
+ var locAnchorPoint = this._anchorPoint;
+ if (y === undefined) {
+ if ((point.x === locAnchorPoint.x) && (point.y === locAnchorPoint.y))
+ return;
+ locAnchorPoint.x = point.x;
+ locAnchorPoint.y = point.y;
+ } else {
+ if ((point === locAnchorPoint.x) && (y === locAnchorPoint.y))
+ return;
+ locAnchorPoint.x = point;
+ locAnchorPoint.y = y;
+ }
+ this._renderCmd._updateAnchorPointInPoint();
+ },
+
+ _getAnchorX: function () {
+ return this._anchorPoint.x;
+ },
+ _setAnchorX: function (x) {
+ if (this._anchorPoint.x === x) return;
+ this._anchorPoint.x = x;
+ this._renderCmd._updateAnchorPointInPoint();
+ },
+ _getAnchorY: function () {
+ return this._anchorPoint.y;
+ },
+ _setAnchorY: function (y) {
+ if (this._anchorPoint.y === y) return;
+ this._anchorPoint.y = y;
+ this._renderCmd._updateAnchorPointInPoint();
+ },
+
+ /**
+ * Returns a copy of the anchor point in absolute pixels.
+ * you can only read it. If you wish to modify it, use setAnchorPoint
+ * @see cc.Node#getAnchorPoint
+ * @function
+ * @return {cc.Point} The anchor point in absolute pixels.
+ */
+ getAnchorPointInPoints: function () {
+ return this._renderCmd.getAnchorPointInPoints();
+ },
+
+ _getWidth: function () {
+ return this._contentSize.width;
+ },
+ _setWidth: function (width) {
+ this._contentSize.width = width;
+ this._renderCmd._updateAnchorPointInPoint();
+ },
+ _getHeight: function () {
+ return this._contentSize.height;
+ },
+ _setHeight: function (height) {
+ this._contentSize.height = height;
+ this._renderCmd._updateAnchorPointInPoint();
+ },
+
+ /**
+ * Returns a copy the untransformed size of the node.
+ * The contentSize remains the same no matter the node is scaled or rotated.
+ * All nodes has a size. Layer and Scene has the same size of the screen by default.
+ * @function
+ * @return {cc.Size} The untransformed size of the node.
+ */
+ getContentSize: function () {
+ return cc.size(this._contentSize);
+ },
+
+ /**
+ *
+ * Sets the untransformed size of the node.
+ *
+ * The contentSize remains the same no matter the node is scaled or rotated.
+ * All nodes has a size. Layer and Scene has the same size of the screen.
+ *
+ * @function
+ * @param {cc.Size|Number} size The untransformed size of the node or The untransformed size's width of the node.
+ * @param {Number} [height] The untransformed size's height of the node.
+ */
+ setContentSize: function (size, height) {
+ var locContentSize = this._contentSize;
+ if (height === undefined) {
+ if ((size.width === locContentSize.width) && (size.height === locContentSize.height))
+ return;
+ locContentSize.width = size.width;
+ locContentSize.height = size.height;
+ } else {
+ if ((size === locContentSize.width) && (height === locContentSize.height))
+ return;
+ locContentSize.width = size;
+ locContentSize.height = height;
+ }
+ this._renderCmd._updateAnchorPointInPoint();
+ },
+
+ /**
+ *
+ * Returns whether or not the node accepts event callbacks.
+ * Running means the node accept event callbacks like onEnter(), onExit(), update()
+ *
+ * @function
+ * @return {Boolean} Whether or not the node is running.
+ */
+ isRunning: function () {
+ return this._running;
+ },
+
+ /**
+ * Returns a reference to the parent node
+ * @function
+ * @return {cc.Node} A reference to the parent node
+ */
+ getParent: function () {
+ return this._parent;
+ },
+
+ /**
+ * Sets the parent node
+ * @param {cc.Node} parent A reference to the parent node
+ */
+ setParent: function (parent) {
+ this._parent = parent;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns whether the anchor point will be ignored when you position this node.
+ * When anchor point ignored, position will be calculated based on the origin point (0, 0) in parent's coordinates.
+ * @function
+ * @see cc.Node#ignoreAnchorPointForPosition
+ * @return {Boolean} true if the anchor point will be ignored when you position this node.
+ */
+ isIgnoreAnchorPointForPosition: function () {
+ return this._ignoreAnchorPointForPosition;
+ },
+
+ /**
+ *
+ * Sets whether the anchor point will be ignored when you position this node.
+ * When anchor point ignored, position will be calculated based on the origin point (0, 0) in parent's coordinates.
+ * This is an internal method, only used by CCLayer and CCScene. Don't call it outside framework.
+ * The default value is false, while in CCLayer and CCScene are true
+ *
+ * @function
+ * @param {Boolean} newValue true if anchor point will be ignored when you position this node
+ */
+ ignoreAnchorPointForPosition: function (newValue) {
+ if (newValue !== this._ignoreAnchorPointForPosition) {
+ this._ignoreAnchorPointForPosition = newValue;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ }
+ },
+
+ /**
+ * Returns a tag that is used to identify the node easily.
+ * @function
+ * @return {Number} An integer that identifies the node.
+ * @example
+ * //You can set tags to node then identify them easily.
+ * // set tags
+ * node1.setTag(TAG_PLAYER);
+ * node2.setTag(TAG_MONSTER);
+ * node3.setTag(TAG_BOSS);
+ * parent.addChild(node1);
+ * parent.addChild(node2);
+ * parent.addChild(node3);
+ * // identify by tags
+ * var allChildren = parent.getChildren();
+ * for(var i = 0; i < allChildren.length; i++){
+ * switch(node.getTag()) {
+ * case TAG_PLAYER:
+ * break;
+ * case TAG_MONSTER:
+ * break;
+ * case TAG_BOSS:
+ * break;
+ * }
+ * }
+ */
+ getTag: function () {
+ return this.tag;
+ },
+
+ /**
+ * Changes the tag that is used to identify the node easily.
+ * Please refer to getTag for the sample code.
+ * @function
+ * @see cc.Node#getTag
+ * @param {Number} tag A integer that identifies the node.
+ */
+ setTag: function (tag) {
+ this.tag = tag;
+ },
+
+ /**
+ * Changes the name that is used to identify the node easily.
+ * @function
+ * @param {String} name
+ */
+ setName: function (name) {
+ this._name = name;
+ },
+
+ /**
+ * Returns a string that is used to identify the node.
+ * @function
+ * @returns {string} A string that identifies the node.
+ */
+ getName: function () {
+ return this._name;
+ },
+
+ /**
+ *
+ * Returns a custom user data pointer
+ * You can set everything in UserData pointer, a data block, a structure or an object.
+ *
+ * @function
+ * @return {object} A custom user data pointer
+ */
+ getUserData: function () {
+ return this.userData;
+ },
+
+ /**
+ *
+ * Sets a custom user data reference
+ * You can set everything in UserData reference, a data block, a structure or an object, etc.
+ *
+ * @function
+ * @warning Don't forget to release the memory manually in JSB, especially before you change this data pointer, and before this node is autoreleased.
+ * @param {object} Var A custom user data
+ */
+ setUserData: function (Var) {
+ this.userData = Var;
+ },
+
+ /**
+ * Returns a user assigned cocos2d object.
+ * Similar to userData, but instead of holding all kinds of data it can only hold a cocos2d object
+ * @function
+ * @return {object} A user assigned CCObject
+ */
+ getUserObject: function () {
+ return this.userObject;
+ },
+
+ /**
+ *
+ * Sets a user assigned cocos2d object
+ * Similar to UserData, but instead of holding all kinds of data it can only hold a cocos2d object
+ * In JSB, the UserObject will be retained once in this method, and the previous UserObject (if existed) will be release.
+ * The UserObject will be released in CCNode's destruction.
+ *
+ * @param {object} newValue A user cocos2d object
+ */
+ setUserObject: function (newValue) {
+ if (this.userObject !== newValue)
+ this.userObject = newValue;
+ },
+
+
+ /**
+ * Returns the arrival order, indicates which children should be added previously.
+ * @function
+ * @return {Number} The arrival order.
+ */
+ getOrderOfArrival: function () {
+ return this.arrivalOrder;
+ },
+
+ /**
+ *
+ * Sets the arrival order when this node has a same ZOrder with other children.
+ *
+ * A node which called addChild subsequently will take a larger arrival order,
+ * If two children have the same Z order, the child with larger arrival order will be drawn later.
+ *
+ * @function
+ * @warning This method is used internally for zOrder sorting, don't change this manually
+ * @param {Number} Var The arrival order.
+ */
+ setOrderOfArrival: function (Var) {
+ this.arrivalOrder = Var;
+ },
+
+ /**
+ * Returns the CCActionManager object that is used by all actions.
+ * (IMPORTANT: If you set a new cc.ActionManager, then previously created actions are going to be removed.)
+ * @function
+ * @see cc.Node#setActionManager
+ * @return {cc.ActionManager} A CCActionManager object.
+ */
+ getActionManager: function () {
+ return this._actionManager || cc.director.getActionManager();
+ },
+
+ /**
+ * Sets the cc.ActionManager object that is used by all actions.
+ * @function
+ * @warning If you set a new CCActionManager, then previously created actions will be removed.
+ * @param {cc.ActionManager} actionManager A CCActionManager object that is used by all actions.
+ */
+ setActionManager: function (actionManager) {
+ if (this._actionManager !== actionManager) {
+ this.stopAllActions();
+ this._actionManager = actionManager;
+ }
+ },
+
+ /**
+ *
+ * Returns the cc.Scheduler object used to schedule all "updates" and timers.
+ *
+ * @function
+ * @return {cc.Scheduler} A CCScheduler object.
+ */
+ getScheduler: function () {
+ return this._scheduler || cc.director.getScheduler();
+ },
+
+ /**
+ *
+ * Sets a CCScheduler object that is used to schedule all "updates" and timers.
+ * IMPORTANT: If you set a new cc.Scheduler, then previously created timers/update are going to be removed.
+ *
+ * @function
+ * @warning If you set a new CCScheduler, then previously created timers/update are going to be removed.
+ * @param scheduler A cc.Scheduler object that is used to schedule all "update" and timers.
+ */
+ setScheduler: function (scheduler) {
+ if (this._scheduler !== scheduler) {
+ this.unscheduleAllCallbacks();
+ this._scheduler = scheduler;
+ }
+ },
+
+ /**
+ * Returns a "local" axis aligned bounding box of the node.
+ * @deprecated since v3.0, please use getBoundingBox instead
+ * @return {cc.Rect}
+ */
+ boundingBox: function () {
+ cc.log(cc._LogInfos.Node_boundingBox);
+ return this.getBoundingBox();
+ },
+
+ /**
+ * Returns a "local" axis aligned bounding box of the node.
+ * The returned box is relative only to its parent.
+ * @function
+ * @return {cc.Rect} The calculated bounding box of the node
+ */
+ getBoundingBox: function () {
+ var rect = cc.rect(0, 0, this._contentSize.width, this._contentSize.height);
+ return cc._rectApplyAffineTransformIn(rect, this.getNodeToParentTransform());
+ },
+
+ /**
+ * Stops all running actions and schedulers
+ * @function
+ */
+ cleanup: function () {
+ // actions
+ this.stopAllActions();
+ this.unscheduleAllCallbacks();
+
+ // event
+ cc.eventManager.removeListeners(this);
+ },
+
+ // composition: GET
+ /**
+ * Returns a child from the container given its tag
+ * @function
+ * @param {Number} aTag An identifier to find the child node.
+ * @return {cc.Node} a CCNode object whose tag equals to the input parameter
+ */
+ getChildByTag: function (aTag) {
+ var __children = this._children;
+ if (__children !== null) {
+ for (var i = 0; i < __children.length; i++) {
+ var node = __children[i];
+ if (node && node.tag === aTag)
+ return node;
+ }
+ }
+ return null;
+ },
+
+ /**
+ * Returns a child from the container given its name
+ * @function
+ * @param {String} name A name to find the child node.
+ * @return {cc.Node} a CCNode object whose name equals to the input parameter
+ */
+ getChildByName: function (name) {
+ if (!name) {
+ cc.log("Invalid name");
+ return null;
+ }
+
+ var locChildren = this._children;
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ if (locChildren[i]._name === name)
+ return locChildren[i];
+ }
+ return null;
+ },
+
+ // composition: ADD
+
+ /** "add" logic MUST only be in this method
+ *
+ * If the child is added to a 'running' node, then 'onEnter' and 'onEnterTransitionDidFinish' will be called immediately.
+ * @function
+ * @param {cc.Node} child A child node
+ * @param {Number} [localZOrder=] Z order for drawing priority. Please refer to setZOrder(int)
+ * @param {Number|String} [tag=] An integer or a name to identify the node easily. Please refer to setTag(int) and setName(string)
+ */
+ addChild: function (child, localZOrder, tag) {
+ localZOrder = localZOrder === undefined ? child._localZOrder : localZOrder;
+ var name, setTag = false;
+ if (tag === undefined) {
+ name = child._name;
+ } else if (typeof tag === 'string') {
+ name = tag;
+ tag = undefined;
+ } else if (typeof tag === 'number') {
+ setTag = true;
+ name = "";
+ }
+
+ cc.assert(child, cc._LogInfos.Node_addChild_3);
+ cc.assert(child._parent === null, "child already added. It can't be added again");
+
+ this._addChildHelper(child, localZOrder, tag, name, setTag);
+ },
+
+ _addChildHelper: function (child, localZOrder, tag, name, setTag) {
+ if (!this._children)
+ this._children = [];
+
+ this._insertChild(child, localZOrder);
+ if (setTag)
+ child.setTag(tag);
+ else
+ child.setName(name);
+
+ child.setParent(this);
+ child.setOrderOfArrival(cc.s_globalOrderOfArrival++);
+
+ if (this._running) {
+ child._performRecursive(cc.Node._stateCallbackType.onEnter);
+ // prevent onEnterTransitionDidFinish to be called twice when a node is added in onEnter
+ if (this._isTransitionFinished)
+ child._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
+ }
+ child._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ if (this._cascadeColorEnabled)
+ child._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty);
+ if (this._cascadeOpacityEnabled)
+ child._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty);
+ },
+
+ // composition: REMOVE
+ /**
+ * Remove itself from its parent node. If cleanup is true, then also remove all actions and callbacks.
+ * If the cleanup parameter is not passed, it will force a cleanup.
+ * If the node orphan, then nothing happens.
+ * @function
+ * @param {Boolean} [cleanup=true] true if all actions and callbacks on this node should be removed, false otherwise.
+ * @see cc.Node#removeFromParentAndCleanup
+ */
+ removeFromParent: function (cleanup) {
+ if (this._parent) {
+ if (cleanup === undefined)
+ cleanup = true;
+ this._parent.removeChild(this, cleanup);
+ }
+ },
+
+ /**
+ * Removes this node itself from its parent node.
+ * If the node orphan, then nothing happens.
+ * @deprecated since v3.0, please use removeFromParent() instead
+ * @param {Boolean} [cleanup=true] true if all actions and callbacks on this node should be removed, false otherwise.
+ */
+ removeFromParentAndCleanup: function (cleanup) {
+ cc.log(cc._LogInfos.Node_removeFromParentAndCleanup);
+ this.removeFromParent(cleanup);
+ },
+
+ /** Removes a child from the container. It will also cleanup all running actions depending on the cleanup parameter.
+ * If the cleanup parameter is not passed, it will force a cleanup.
+ * "remove" logic MUST only be on this method
+ * If a class wants to extend the 'removeChild' behavior it only needs
+ * to override this method
+ * @function
+ * @param {cc.Node} child The child node which will be removed.
+ * @param {Boolean} [cleanup=true] true if all running actions and callbacks on the child node will be cleanup, false otherwise.
+ */
+ removeChild: function (child, cleanup) {
+ // explicit nil handling
+ if (this._children.length === 0)
+ return;
+
+ if (cleanup === undefined)
+ cleanup = true;
+ if (this._children.indexOf(child) > -1)
+ this._detachChild(child, cleanup);
+
+ //this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.visibleDirty);
+ cc.renderer.childrenOrderDirty = true;
+ },
+
+ /**
+ * Removes a child from the container by tag value. It will also cleanup all running actions depending on the cleanup parameter.
+ * If the cleanup parameter is not passed, it will force a cleanup.
+ * @function
+ * @param {Number} tag An integer number that identifies a child node
+ * @param {Boolean} [cleanup=true] true if all running actions and callbacks on the child node will be cleanup, false otherwise.
+ * @see cc.Node#removeChildByTag
+ */
+ removeChildByTag: function (tag, cleanup) {
+ if (tag === cc.NODE_TAG_INVALID)
+ cc.log(cc._LogInfos.Node_removeChildByTag);
+
+ var child = this.getChildByTag(tag);
+ if (!child)
+ cc.log(cc._LogInfos.Node_removeChildByTag_2, tag);
+ else
+ this.removeChild(child, cleanup);
+ },
+
+ /**
+ * Removes all children from the container and do a cleanup all running actions depending on the cleanup parameter.
+ * @param {Boolean} [cleanup=true]
+ */
+ removeAllChildrenWithCleanup: function (cleanup) {
+ this.removeAllChildren(cleanup);
+ },
+
+ /**
+ * Removes all children from the container and do a cleanup all running actions depending on the cleanup parameter.
+ * If the cleanup parameter is not passed, it will force a cleanup.
+ * @function
+ * @param {Boolean} [cleanup=true] true if all running actions on all children nodes should be cleanup, false otherwise.
+ */
+ removeAllChildren: function (cleanup) {
+ // not using detachChild improves speed here
+ var __children = this._children;
+ if (__children !== null) {
+ if (cleanup === undefined)
+ cleanup = true;
+ for (var i = 0; i < __children.length; i++) {
+ var node = __children[i];
+ if (node) {
+ if (this._running) {
+ node._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ node._performRecursive(cc.Node._stateCallbackType.onExit);
+ }
+
+ // If you don't do cleanup, the node's actions will not get removed and the
+ if (cleanup)
+ node._performRecursive(cc.Node._stateCallbackType.cleanup);
+
+ // set parent nil at the end
+ node.parent = null;
+ node._renderCmd.detachFromParent();
+ }
+ }
+ this._children.length = 0;
+ cc.renderer.childrenOrderDirty = true;
+ }
+ },
+
+ _detachChild: function (child, doCleanup) {
+ // IMPORTANT:
+ // -1st do onExit
+ // -2nd cleanup
+ if (this._running) {
+ child._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ child._performRecursive(cc.Node._stateCallbackType.onExit);
+ }
+
+ // If you don't do cleanup, the child's actions will not get removed and the
+ if (doCleanup)
+ child._performRecursive(cc.Node._stateCallbackType.cleanup);
+
+ // set parent nil at the end
+ child.parent = null;
+ child._renderCmd.detachFromParent();
+ cc.arrayRemoveObject(this._children, child);
+ },
+
+ _insertChild: function (child, z) {
+ cc.renderer.childrenOrderDirty = this._reorderChildDirty = true;
+ this._children.push(child);
+ child._setLocalZOrder(z);
+ },
+
+ setNodeDirty: function () {
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /** Reorders a child according to a new z value.
+ * The child MUST be already added.
+ * @function
+ * @param {cc.Node} child An already added child node. It MUST be already added.
+ * @param {Number} zOrder Z order for drawing priority. Please refer to setZOrder(int)
+ */
+ reorderChild: function (child, zOrder) {
+ cc.assert(child, cc._LogInfos.Node_reorderChild);
+ if (this._children.indexOf(child) === -1) {
+ cc.log(cc._LogInfos.Node_reorderChild_2);
+ return;
+ }
+ cc.renderer.childrenOrderDirty = this._reorderChildDirty = true;
+ child.arrivalOrder = cc.s_globalOrderOfArrival;
+ cc.s_globalOrderOfArrival++;
+ child._setLocalZOrder(zOrder);
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.orderDirty);
+ },
+
+ /**
+ *
+ * Sorts the children array once before drawing, instead of every time when a child is added or reordered.
+ * This approach can improves the performance massively.
+ *
+ * @function
+ * @note Don't call this manually unless a child added needs to be removed in the same frame
+ */
+ sortAllChildren: function () {
+ if (this._reorderChildDirty) {
+ var _children = this._children;
+
+ // insertion sort
+ var len = _children.length, i, j, tmp;
+ for (i = 1; i < len; i++) {
+ tmp = _children[i];
+ j = i - 1;
+
+ //continue moving element downwards while zOrder is smaller or when zOrder is the same but mutatedIndex is smaller
+ while (j >= 0) {
+ if (tmp._localZOrder < _children[j]._localZOrder) {
+ _children[j + 1] = _children[j];
+ } else if (tmp._localZOrder === _children[j]._localZOrder && tmp.arrivalOrder < _children[j].arrivalOrder) {
+ _children[j + 1] = _children[j];
+ } else {
+ break;
+ }
+ j--;
+ }
+ _children[j + 1] = tmp;
+ }
+
+ //don't need to check children recursively, that's done in visit of each child
+ this._reorderChildDirty = false;
+ }
+ },
+
+ /**
+ * Render function using the canvas 2d context or WebGL context, internal usage only, please do not call this function
+ * @function
+ * @param {CanvasRenderingContext2D | WebGLRenderingContext} ctx The render context
+ */
+ draw: function (ctx) {
+ // override me
+ // Only use- this function to draw your staff.
+ // DON'T draw your stuff outside this method
+ },
+
+ // Internal use only, do not call it by yourself,
+ transformAncestors: function () {
+ if (this._parent !== null) {
+ this._parent.transformAncestors();
+ this._parent.transform();
+ }
+ },
+
+ //scene management
+ /**
+ *
+ * Event callback that is invoked every time when CCNode enters the 'stage'.
+ * If the CCNode enters the 'stage' with a transition, this event is called when the transition starts.
+ * During onEnter you can't access a "sister/brother" node.
+ * If you override onEnter, you must call its parent's onEnter function with this._super().
+ *
+ * @function
+ */
+ onEnter: function () {
+ this._isTransitionFinished = false;
+ this._running = true;//should be running before resumeSchedule
+ this.resume();
+ },
+
+ _performRecursive: function (callbackType) {
+ var nodeCallbackType = cc.Node._stateCallbackType;
+ if (callbackType >= nodeCallbackType.max) {
+ return;
+ }
+
+ var index = 0;
+ var children, child, curr, i, len;
+ var stack = cc.Node._performStacks[cc.Node._performing];
+ if (!stack) {
+ stack = [];
+ cc.Node._performStacks.push(stack);
+ }
+ stack.length = 0;
+ cc.Node._performing++;
+ curr = stack[0] = this;
+ while (curr) {
+ // Walk through children
+ children = curr._children;
+ if (children && children.length > 0) {
+ for (i = 0, len = children.length; i < len; ++i) {
+ child = children[i];
+ stack.push(child);
+ }
+ }
+ children = curr._protectedChildren;
+ if (children && children.length > 0) {
+ for (i = 0, len = children.length; i < len; ++i) {
+ child = children[i];
+ stack.push(child);
+ }
+ }
+
+ index++;
+ curr = stack[index];
+ }
+ for (i = stack.length - 1; i >= 0; --i) {
+ curr = stack[i];
+ stack[i] = null;
+ if (!curr) continue;
+
+ // Perform actual action
+ switch (callbackType) {
+ case nodeCallbackType.onEnter:
+ curr.onEnter();
+ break;
+ case nodeCallbackType.onExit:
+ curr.onExit();
+ break;
+ case nodeCallbackType.onEnterTransitionDidFinish:
+ curr.onEnterTransitionDidFinish();
+ break;
+ case nodeCallbackType.cleanup:
+ curr.cleanup();
+ break;
+ case nodeCallbackType.onExitTransitionDidStart:
+ curr.onExitTransitionDidStart();
+ break;
+ }
+ }
+ cc.Node._performing--;
+ },
+
+ /**
+ *
+ * Event callback that is invoked when the CCNode enters in the 'stage'.
+ * If the CCNode enters the 'stage' with a transition, this event is called when the transition finishes.
+ * If you override onEnterTransitionDidFinish, you shall call its parent's onEnterTransitionDidFinish with this._super()
+ *
+ * @function
+ */
+ onEnterTransitionDidFinish: function () {
+ this._isTransitionFinished = true;
+ },
+
+ /**
+ * callback that is called every time the cc.Node leaves the 'stage'.
+ * If the cc.Node leaves the 'stage' with a transition, this callback is called when the transition starts.
+ * If you override onExitTransitionDidStart, you shall call its parent's onExitTransitionDidStart with this._super()
+ * @function
+ */
+ onExitTransitionDidStart: function () {
+ },
+
+ /**
+ *
+ * callback that is called every time the cc.Node leaves the 'stage'.
+ * If the cc.Node leaves the 'stage' with a transition, this callback is called when the transition finishes.
+ * During onExit you can't access a sibling node.
+ * If you override onExit, you shall call its parent's onExit with this._super().
+ *
+ * @function
+ */
+ onExit: function () {
+ this._running = false;
+ this.pause();
+ this.removeAllComponents();
+ },
+
+ // actions
+ /**
+ * Executes an action, and returns the action that is executed.
+ * The node becomes the action's target. Refer to cc.Action's getTarget()
+ * @function
+ * @warning Starting from v0.8 actions don't retain their target anymore.
+ * @param {cc.Action} action
+ * @return {cc.Action} An Action pointer
+ */
+ runAction: function (action) {
+ cc.assert(action, cc._LogInfos.Node_runAction);
+
+ this.actionManager.addAction(action, this, !this._running);
+ return action;
+ },
+
+ /**
+ * Stops and removes all actions from the running action list .
+ * @function
+ */
+ stopAllActions: function () {
+ this.actionManager && this.actionManager.removeAllActionsFromTarget(this);
+ },
+
+ /**
+ * Stops and removes an action from the running action list.
+ * @function
+ * @param {cc.Action} action An action object to be removed.
+ */
+ stopAction: function (action) {
+ this.actionManager.removeAction(action);
+ },
+
+ /**
+ * Removes an action from the running action list by its tag.
+ * @function
+ * @param {Number} tag A tag that indicates the action to be removed.
+ */
+ stopActionByTag: function (tag) {
+ if (tag === cc.ACTION_TAG_INVALID) {
+ cc.log(cc._LogInfos.Node_stopActionByTag);
+ return;
+ }
+ this.actionManager.removeActionByTag(tag, this);
+ },
+
+ /**
+ * Returns an action from the running action list by its tag.
+ * @function
+ * @see cc.Node#getTag and cc.Node#setTag
+ * @param {Number} tag
+ * @return {cc.Action} The action object with the given tag.
+ */
+ getActionByTag: function (tag) {
+ if (tag === cc.ACTION_TAG_INVALID) {
+ cc.log(cc._LogInfos.Node_getActionByTag);
+ return null;
+ }
+ return this.actionManager.getActionByTag(tag, this);
+ },
+
+ /** Returns the numbers of actions that are running plus the ones that are schedule to run (actions in actionsToAdd and actions arrays).
+ * Composable actions are counted as 1 action. Example:
+ * If you are running 1 Sequence of 7 actions, it will return 1.
+ * If you are running 7 Sequences of 2 actions, it will return 7.
+ * @function
+ * @return {Number} The number of actions that are running plus the ones that are schedule to run
+ */
+ getNumberOfRunningActions: function () {
+ return this.actionManager.numberOfRunningActionsInTarget(this);
+ },
+
+ // cc.Node - Callbacks
+ // timers
+ /**
+ * schedules the "update" method.
+ * It will use the order number 0. This method will be called every frame.
+ * Scheduled methods with a lower order value will be called before the ones that have a higher order value.
+ * Only one "update" method could be scheduled per node.
+ * @function
+ */
+ scheduleUpdate: function () {
+ this.scheduleUpdateWithPriority(0);
+ },
+
+ /**
+ *
+ * schedules the "update" callback function with a custom priority.
+ * This callback function will be called every frame.
+ * Scheduled callback functions with a lower priority will be called before the ones that have a higher value.
+ * Only one "update" callback function could be scheduled per node (You can't have 2 'update' callback functions).
+ *
+ * @function
+ * @param {Number} priority
+ */
+ scheduleUpdateWithPriority: function (priority) {
+ this.scheduler.scheduleUpdate(this, priority, !this._running);
+ },
+
+ /**
+ * Unschedules the "update" method.
+ * @function
+ * @see cc.Node#scheduleUpdate
+ */
+ unscheduleUpdate: function () {
+ this.scheduler.unscheduleUpdate(this);
+ },
+
+ /**
+ * Schedules a custom selector.
+ * If the selector is already scheduled, then the interval parameter will be updated without scheduling it again.
+ * @function
+ * @param {function} callback A function wrapped as a selector
+ * @param {Number} interval Tick interval in seconds. 0 means tick every frame. If interval = 0, it's recommended to use scheduleUpdate() instead.
+ * @param {Number} repeat The selector will be executed (repeat + 1) times, you can use kCCRepeatForever for tick infinitely.
+ * @param {Number} delay The amount of time that the first tick will wait before execution.
+ * @param {String} key The only string identifying the callback
+ */
+ schedule: function (callback, interval, repeat, delay, key) {
+ var len = arguments.length;
+ if (typeof callback === "function") {
+ //callback, interval, repeat, delay, key
+ if (len === 1) {
+ //callback
+ interval = 0;
+ repeat = cc.REPEAT_FOREVER;
+ delay = 0;
+ key = this.__instanceId;
+ } else if (len === 2) {
+ if (typeof interval === "number") {
+ //callback, interval
+ repeat = cc.REPEAT_FOREVER;
+ delay = 0;
+ key = this.__instanceId;
+ } else {
+ //callback, key
+ key = interval;
+ interval = 0;
+ repeat = cc.REPEAT_FOREVER;
+ delay = 0;
+ }
+ } else if (len === 3) {
+ if (typeof repeat === "string") {
+ //callback, interval, key
+ key = repeat;
+ repeat = cc.REPEAT_FOREVER;
+ } else {
+ //callback, interval, repeat
+ key = this.__instanceId;
+ }
+ delay = 0;
+ } else if (len === 4) {
+ key = this.__instanceId;
+ }
+ } else {
+ //selector
+ //selector, interval
+ //selector, interval, repeat, delay
+ if (len === 1) {
+ interval = 0;
+ repeat = cc.REPEAT_FOREVER;
+ delay = 0;
+ } else if (len === 2) {
+ repeat = cc.REPEAT_FOREVER;
+ delay = 0;
+ }
+ }
+
+ cc.assert(callback, cc._LogInfos.Node_schedule);
+ cc.assert(interval >= 0, cc._LogInfos.Node_schedule_2);
+
+ interval = interval || 0;
+ repeat = isNaN(repeat) ? cc.REPEAT_FOREVER : repeat;
+ delay = delay || 0;
+
+ this.scheduler.schedule(callback, this, interval, repeat, delay, !this._running, key);
+ },
+
+ /**
+ * Schedules a callback function that runs only once, with a delay of 0 or larger
+ * @function
+ * @see cc.Node#schedule
+ * @param {function} callback A function wrapped as a selector
+ * @param {Number} delay The amount of time that the first tick will wait before execution.
+ * @param {String} key The only string identifying the callback
+ */
+ scheduleOnce: function (callback, delay, key) {
+ //selector, delay
+ //callback, delay, key
+ if (key === undefined)
+ key = this.__instanceId;
+ this.schedule(callback, 0, 0, delay, key);
+ },
+
+ /**
+ * unschedules a custom callback function.
+ * @function
+ * @see cc.Node#schedule
+ * @param {function} callback_fn A function wrapped as a selector
+ */
+ unschedule: function (callback_fn) {
+ //key
+ //selector
+ if (!callback_fn)
+ return;
+
+ this.scheduler.unschedule(callback_fn, this);
+ },
+
+ /**
+ * unschedule all scheduled callback functions: custom callback functions, and the 'update' callback function.
+ * Actions are not affected by this method.
+ * @function
+ */
+ unscheduleAllCallbacks: function () {
+ this.scheduler.unscheduleAllForTarget(this);
+ },
+
+ /**
+ * Resumes all scheduled selectors and actions.
+ * This method is called internally by onEnter
+ * @function
+ * @deprecated since v3.0, please use resume() instead
+ */
+ resumeSchedulerAndActions: function () {
+ cc.log(cc._LogInfos.Node_resumeSchedulerAndActions);
+ this.resume();
+ },
+
+ /**
+ * Resumes all scheduled selectors and actions.
+ * This method is called internally by onEnter
+ */
+ resume: function () {
+ this.scheduler.resumeTarget(this);
+ this.actionManager && this.actionManager.resumeTarget(this);
+ cc.eventManager.resumeTarget(this);
+ },
+
+ /**
+ * Pauses all scheduled selectors and actions.
+ * This method is called internally by onExit
+ * @deprecated since v3.0, please use pause instead
+ * @function
+ */
+ pauseSchedulerAndActions: function () {
+ cc.log(cc._LogInfos.Node_pauseSchedulerAndActions);
+ this.pause();
+ },
+
+ /**
+ * Pauses all scheduled selectors and actions.
+ * This method is called internally by onExit
+ * @function
+ */
+ pause: function () {
+ this.scheduler.pauseTarget(this);
+ this.actionManager && this.actionManager.pauseTarget(this);
+ cc.eventManager.pauseTarget(this);
+ },
+
+ /**
+ *Sets the additional transform.
+ * The additional transform will be concatenated at the end of getNodeToParentTransform.
+ * It could be used to simulate `parent-child` relationship between two nodes (e.g. one is in BatchNode, another isn't).
+ *
+ * @function
+ * @param {cc.AffineTransform} additionalTransform The additional transform
+ * @example
+ * // create a batchNode
+ * var batch = new cc.SpriteBatchNode("Icon-114.png");
+ * this.addChild(batch);
+ *
+ * // create two sprites, spriteA will be added to batchNode, they are using different textures.
+ * var spriteA = new cc.Sprite(batch->getTexture());
+ * var spriteB = new cc.Sprite("Icon-72.png");
+ *
+ * batch.addChild(spriteA);
+ *
+ * // We can't make spriteB as spriteA's child since they use different textures. So just add it to layer.
+ * // But we want to simulate `parent-child` relationship for these two node.
+ * this.addChild(spriteB);
+ *
+ * //position
+ * spriteA.setPosition(ccp(200, 200));
+ *
+ * // Gets the spriteA's transform.
+ * var t = spriteA.getNodeToParentTransform();
+ *
+ * // Sets the additional transform to spriteB, spriteB's position will based on its pseudo parent i.e. spriteA.
+ * spriteB.setAdditionalTransform(t);
+ *
+ * //scale
+ * spriteA.setScale(2);
+ *
+ * // Gets the spriteA's transform.
+ * t = spriteA.getNodeToParentTransform();
+ *
+ * // Sets the additional transform to spriteB, spriteB's scale will based on its pseudo parent i.e. spriteA.
+ * spriteB.setAdditionalTransform(t);
+ *
+ * //rotation
+ * spriteA.setRotation(20);
+ *
+ * // Gets the spriteA's transform.
+ * t = spriteA.getNodeToParentTransform();
+ *
+ * // Sets the additional transform to spriteB, spriteB's rotation will based on its pseudo parent i.e. spriteA.
+ * spriteB.setAdditionalTransform(t);
+ */
+ setAdditionalTransform: function (additionalTransform) {
+ if(additionalTransform === undefined)
+ return this._additionalTransformDirty = false;
+ this._additionalTransform = additionalTransform;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ this._additionalTransformDirty = true;
+ },
+
+ /**
+ * Returns the matrix that transform parent's space coordinates to the node's (local) space coordinates.
+ * The matrix is in Pixels.
+ * @function
+ * @return {cc.AffineTransform}
+ */
+ getParentToNodeTransform: function () {
+ return this._renderCmd.getParentToNodeTransform();
+ },
+
+ /**
+ * @function
+ * @deprecated since v3.0, please use getParentToNodeTransform instead
+ */
+ parentToNodeTransform: function () {
+ return this.getParentToNodeTransform();
+ },
+
+ /**
+ * Returns the world affine transform matrix. The matrix is in Pixels.
+ * @function
+ * @return {cc.AffineTransform}
+ */
+ getNodeToWorldTransform: function () {
+ var t = this.getNodeToParentTransform();
+ for (var p = this._parent; p !== null; p = p.parent)
+ t = cc.affineTransformConcat(t, p.getNodeToParentTransform());
+ return t;
+ },
+
+ /**
+ * @function
+ * @deprecated since v3.0, please use getNodeToWorldTransform instead
+ */
+ nodeToWorldTransform: function () {
+ return this.getNodeToWorldTransform();
+ },
+
+ /**
+ * Returns the inverse world affine transform matrix. The matrix is in Pixels.
+ * @function
+ * @return {cc.AffineTransform}
+ */
+ getWorldToNodeTransform: function () {
+ return cc.affineTransformInvert(this.getNodeToWorldTransform());
+ },
+
+ /**
+ * @function
+ * @deprecated since v3.0, please use getWorldToNodeTransform instead
+ */
+ worldToNodeTransform: function () {
+ return this.getWorldToNodeTransform();
+ },
+
+ /**
+ * Converts a Point to node (local) space coordinates. The result is in Points.
+ * @function
+ * @param {cc.Point} worldPoint
+ * @return {cc.Point}
+ */
+ convertToNodeSpace: function (worldPoint) {
+ return cc.pointApplyAffineTransform(worldPoint, this.getWorldToNodeTransform());
+ },
+
+ /**
+ * Converts a Point to world space coordinates. The result is in Points.
+ * @function
+ * @param {cc.Point} nodePoint
+ * @return {cc.Point}
+ */
+ convertToWorldSpace: function (nodePoint) {
+ nodePoint = nodePoint || cc.p(0, 0);
+ return cc.pointApplyAffineTransform(nodePoint, this.getNodeToWorldTransform());
+ },
+
+ /**
+ * Converts a Point to node (local) space coordinates. The result is in Points.
+ * treating the returned/received node point as anchor relative.
+ * @function
+ * @param {cc.Point} worldPoint
+ * @return {cc.Point}
+ */
+ convertToNodeSpaceAR: function (worldPoint) {
+ return cc.pSub(this.convertToNodeSpace(worldPoint), this._renderCmd.getAnchorPointInPoints());
+ },
+
+ /**
+ * Converts a local Point to world space coordinates.The result is in Points.
+ * treating the returned/received node point as anchor relative.
+ * @function
+ * @param {cc.Point} nodePoint
+ * @return {cc.Point}
+ */
+ convertToWorldSpaceAR: function (nodePoint) {
+ nodePoint = nodePoint || cc.p(0, 0);
+ var pt = cc.pAdd(nodePoint, this._renderCmd.getAnchorPointInPoints());
+ return this.convertToWorldSpace(pt);
+ },
+
+ _convertToWindowSpace: function (nodePoint) {
+ var worldPoint = this.convertToWorldSpace(nodePoint);
+ return cc.director.convertToUI(worldPoint);
+ },
+
+ /** convenience methods which take a cc.Touch instead of cc.Point
+ * @function
+ * @param {cc.Touch} touch The touch object
+ * @return {cc.Point}
+ */
+ convertTouchToNodeSpace: function (touch) {
+ var point = touch.getLocation();
+ return this.convertToNodeSpace(point);
+ },
+
+ /**
+ * converts a cc.Touch (world coordinates) into a local coordinate. This method is AR (Anchor Relative).
+ * @function
+ * @param {cc.Touch} touch The touch object
+ * @return {cc.Point}
+ */
+ convertTouchToNodeSpaceAR: function (touch) {
+ var point = cc.director.convertToGL(touch.getLocation());
+ return this.convertToNodeSpaceAR(point);
+ },
+
+ /**
+ * Update will be called automatically every frame if "scheduleUpdate" is called when the node is "live".
+ * The default behavior is to invoke the visit function of node's componentContainer.
+ * Override me to implement your own update logic.
+ * @function
+ * @param {Number} dt Delta time since last update
+ */
+ update: function (dt) {
+ if (this._componentContainer && !this._componentContainer.isEmpty())
+ this._componentContainer.visit(dt);
+ },
+
+ /**
+ *
+ * Calls children's updateTransform() method recursively.
+ *
+ * This method is moved from CCSprite, so it's no longer specific to CCSprite.
+ * As the result, you apply CCSpriteBatchNode's optimization on your customed CCNode.
+ * e.g., batchNode->addChild(myCustomNode), while you can only addChild(sprite) before.
+ *
+ * @function
+ */
+ updateTransform: function () {
+ var children = this._children, node;
+ for (var i = 0; i < children.length; i++) {
+ node = children[i];
+ if (node)
+ node.updateTransform();
+ }
+ },
+
+ /**
+ * Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
+ * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
+ * This is a hack, and should be removed once JSB fixes the retain/release bug
+ * You will need to retain an object if you created an engine object and haven't added it into the scene graph during the same frame.
+ * Otherwise, JSB's native autorelease pool will consider this object a useless one and release it directly,
+ * when you want to use it later, a "Invalid Native Object" error will be raised.
+ * The retain function can increase a reference count for the native object to avoid it being released,
+ * you need to manually invoke release function when you think this object is no longer needed, otherwise, there will be memory learks.
+ * retain and release function call should be paired in developer's game code.
+ * @function
+ * @see cc.Node#release
+ */
+ retain: function () {
+ },
+ /**
+ * Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
+ * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
+ * This is a hack, and should be removed once JSB fixes the retain/release bug
+ * You will need to retain an object if you created an engine object and haven't added it into the scene graph during the same frame.
+ * Otherwise, JSB's native autorelease pool will consider this object a useless one and release it directly,
+ * when you want to use it later, a "Invalid Native Object" error will be raised.
+ * The retain function can increase a reference count for the native object to avoid it being released,
+ * you need to manually invoke release function when you think this object is no longer needed, otherwise, there will be memory learks.
+ * retain and release function call should be paired in developer's game code.
+ * @function
+ * @see cc.Node#retain
+ */
+ release: function () {
+ },
+
+ /**
+ * Returns a component identified by the name given.
+ * @function
+ * @param {String} name The name to search for
+ * @return {cc.Component} The component found
+ */
+ getComponent: function (name) {
+ if(this._componentContainer)
+ return this._componentContainer.getComponent(name);
+ return null;
+ },
+
+ /**
+ * Adds a component to the node's component container.
+ * @function
+ * @param {cc.Component} component
+ */
+ addComponent: function (component) {
+ if(this._componentContainer)
+ this._componentContainer.add(component);
+ },
+
+ /**
+ * Removes a component identified by the given name or removes the component object given
+ * @function
+ * @param {String|cc.Component} component
+ */
+ removeComponent: function (component) {
+ if(this._componentContainer)
+ return this._componentContainer.remove(component);
+ return false;
+ },
+
+ /**
+ * Removes all components of cc.Node, it called when cc.Node is exiting from stage.
+ * @function
+ */
+ removeAllComponents: function () {
+ if(this._componentContainer)
+ this._componentContainer.removeAll();
+ },
+
+ grid: null,
+
+ /**
+ * Recursive method that visit its children and draw them
+ * @function
+ * @param {cc.Node} parent
+ */
+ visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
+
+ var renderer = cc.renderer;
+ cmd.visit(parentCmd);
+
+ var i, children = this._children, len = children.length, child;
+ if (len > 0) {
+ if (this._reorderChildDirty) {
+ this.sortAllChildren();
+ }
+ // draw children zOrder < 0
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder < 0) {
+ child.visit(this);
+ }
+ else {
+ break;
+ }
+ }
+
+ renderer.pushRenderCommand(cmd);
+ for (; i < len; i++) {
+ children[i].visit(this);
+ }
+ } else {
+ renderer.pushRenderCommand(cmd);
+ }
+ cmd._dirtyFlag = 0;
+ },
+
+ /**
+ * Performs view-matrix transformation based on position, scale, rotation and other attributes.
+ * @function
+ * @param {cc.Node.RenderCmd} parentCmd parent's render command
+ * @param {boolean} recursive whether call its children's transform
+ */
+ transform: function (parentCmd, recursive) {
+ this._renderCmd.transform(parentCmd, recursive);
+ },
+
+ /**
+ * Returns the matrix that transform the node's (local) space coordinates into the parent's space coordinates.
+ * The matrix is in Pixels.
+ * @function
+ * @return {cc.AffineTransform}
+ * @deprecated since v3.0, please use getNodeToParentTransform instead
+ */
+ nodeToParentTransform: function () {
+ return this.getNodeToParentTransform();
+ },
+
+ /**
+ * Returns the matrix that transform the node's (local) space coordinates into the parent's space coordinates.
+ * The matrix is in Pixels.
+ * @function
+ * @return {cc.AffineTransform} The affine transform object
+ */
+ getNodeToParentTransform: function (ancestor) {
+ var t = this._renderCmd.getNodeToParentTransform();
+ if (ancestor) {
+ var T = {a: t.a, b: t.b, c: t.c, d: t.d, tx: t.tx, ty: t.ty};
+ for (var p = this._parent; p != null && p != ancestor; p = p.getParent()) {
+ cc.affineTransformConcatIn(T, p.getNodeToParentTransform());
+ }
+ return T;
+ } else {
+ return t;
+ }
+ },
+
+ getNodeToParentAffineTransform: function (ancestor) {
+ return this.getNodeToParentTransform(ancestor);
+ },
+
+ /**
+ * Returns null
+ * @function
+ * @return {null}
+ * @deprecated since v3.0, no alternative function
+ */
+ getCamera: function () {
+ return null;
+ },
+
+ /**
+ * Returns a grid object that is used when applying effects.
+ * This function have been deprecated, please use cc.NodeGrid to run grid actions
+ * @function
+ * @return {cc.GridBase} A CCGrid object that is used when applying effects
+ * @deprecated since v3.0, no alternative function
+ */
+ getGrid: function () {
+ return this.grid;
+ },
+
+ /**
+ * Changes a grid object that is used when applying effects
+ * This function have been deprecated, please use cc.NodeGrid to run grid actions
+ * @function
+ * @param {cc.GridBase} grid A CCGrid object that is used when applying effects
+ * @deprecated since v3.0, no alternative function
+ */
+ setGrid: function (grid) {
+ this.grid = grid;
+ },
+
+ /**
+ * Return the shader program currently used for this node
+ * @function
+ * @return {cc.GLProgram} The shader program currently used for this node
+ */
+ getShaderProgram: function () {
+ return this._renderCmd.getShaderProgram();
+ },
+
+ /**
+ *
+ * Sets the shader program for this node
+ *
+ * Since v2.0, each rendering node must set its shader program.
+ * It should be set in initialize phase.
+ *
+ * @function
+ * @param {cc.GLProgram} newShaderProgram The shader program which fetches from CCShaderCache.
+ * @example
+ * node.setGLProgram(cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR));
+ */
+ setShaderProgram: function (newShaderProgram) {
+ this._renderCmd.setShaderProgram(newShaderProgram);
+ },
+
+ setGLProgramState: function (glProgramState) {
+ this._renderCmd.setGLProgramState(glProgramState);
+ },
+
+ getGLProgramState: function () {
+ return this._renderCmd.getGLProgramState();
+ },
+
+ /**
+ * Returns the state of OpenGL server side.
+ * @function
+ * @return {Number} The state of OpenGL server side.
+ * @deprecated since v3.0, no need anymore
+ */
+ getGLServerState: function () {
+ return 0;
+ },
+
+ /**
+ * Sets the state of OpenGL server side.
+ * @function
+ * @param {Number} state The state of OpenGL server side.
+ * @deprecated since v3.0, no need anymore
+ */
+ setGLServerState: function (state) {
+ },
+
+ /**
+ * Returns a "world" axis aligned bounding box of the node.
+ * @function
+ * @return {cc.Rect}
+ */
+ getBoundingBoxToWorld: function () {
+ var rect = cc.rect(0, 0, this._contentSize.width, this._contentSize.height);
+ var trans = this.getNodeToWorldTransform();
+ rect = cc.rectApplyAffineTransform(rect, trans);
+
+ //query child's BoundingBox
+ if (!this._children)
+ return rect;
+
+ var locChildren = this._children;
+ for (var i = 0; i < locChildren.length; i++) {
+ var child = locChildren[i];
+ if (child && child._visible) {
+ var childRect = child._getBoundingBoxToCurrentNode(trans);
+ if (childRect)
+ rect = cc.rectUnion(rect, childRect);
+ }
+ }
+ return rect;
+ },
+
+ _getBoundingBoxToCurrentNode: function (parentTransform) {
+ var rect = cc.rect(0, 0, this._contentSize.width, this._contentSize.height);
+ var trans = (parentTransform === undefined) ? this.getNodeToParentTransform() : cc.affineTransformConcat(this.getNodeToParentTransform(), parentTransform);
+ rect = cc.rectApplyAffineTransform(rect, trans);
+
+ //query child's BoundingBox
+ if (!this._children)
+ return rect;
+
+ var locChildren = this._children;
+ for (var i = 0; i < locChildren.length; i++) {
+ var child = locChildren[i];
+ if (child && child._visible) {
+ var childRect = child._getBoundingBoxToCurrentNode(trans);
+ if (childRect)
+ rect = cc.rectUnion(rect, childRect);
+ }
+ }
+ return rect;
+ },
+
+ /**
+ * Returns the opacity of Node
+ * @function
+ * @returns {number} opacity
+ */
+ getOpacity: function () {
+ return this._realOpacity;
+ },
+
+ /**
+ * Returns the displayed opacity of Node,
+ * the difference between displayed opacity and opacity is that displayed opacity is calculated based on opacity and parent node's opacity when cascade opacity enabled.
+ * @function
+ * @returns {number} displayed opacity
+ */
+ getDisplayedOpacity: function () {
+ return this._renderCmd.getDisplayedOpacity();
+ },
+
+ /**
+ * Sets the opacity of Node
+ * @function
+ * @param {Number} opacity
+ */
+ setOpacity: function (opacity) {
+ this._realOpacity = opacity;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty);
+ },
+
+ /**
+ * Update displayed opacity
+ * @function
+ * @param {Number} parentOpacity
+ */
+ updateDisplayedOpacity: function (parentOpacity) {
+ //TODO this API shouldn't be public.
+ this._renderCmd._updateDisplayOpacity(parentOpacity);
+ },
+
+ /**
+ * Returns whether node's opacity value affect its child nodes.
+ * @function
+ * @returns {boolean}
+ */
+ isCascadeOpacityEnabled: function () {
+ return this._cascadeOpacityEnabled;
+ },
+
+ /**
+ * Enable or disable cascade opacity, if cascade enabled, child nodes' opacity will be the multiplication of parent opacity and its own opacity.
+ * @function
+ * @param {boolean} cascadeOpacityEnabled
+ */
+ setCascadeOpacityEnabled: function (cascadeOpacityEnabled) {
+ if (this._cascadeOpacityEnabled === cascadeOpacityEnabled)
+ return;
+ this._cascadeOpacityEnabled = cascadeOpacityEnabled;
+ this._renderCmd.setCascadeOpacityEnabledDirty();
+ },
+
+ /**
+ * Returns the color of Node
+ * @function
+ * @returns {cc.Color}
+ */
+ getColor: function () {
+ var locRealColor = this._realColor;
+ return cc.color(locRealColor.r, locRealColor.g, locRealColor.b, locRealColor.a);
+ },
+
+ /**
+ * Returns the displayed color of Node,
+ * the difference between displayed color and color is that displayed color is calculated based on color and parent node's color when cascade color enabled.
+ * @function
+ * @returns {cc.Color}
+ */
+ getDisplayedColor: function () {
+ return this._renderCmd.getDisplayedColor();
+ },
+
+ /**
+ * Sets the color of Node.
+ * When color doesn't include opacity value like cc.color(128,128,128), this function only change the color.
+ * When color include opacity like cc.color(128,128,128,100), then this function will change the color and the opacity.
+ * @function
+ * @param {cc.Color} color The new color given
+ */
+ setColor: function (color) {
+ var locRealColor = this._realColor;
+ locRealColor.r = color.r;
+ locRealColor.g = color.g;
+ locRealColor.b = color.b;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty);
+ },
+
+ /**
+ * Update the displayed color of Node
+ * @function
+ * @param {cc.Color} parentColor
+ */
+ updateDisplayedColor: function (parentColor) {
+ //TODO this API shouldn't be public.
+ this._renderCmd._updateDisplayColor(parentColor);
+ },
+
+ /**
+ * Returns whether node's color value affect its child nodes.
+ * @function
+ * @returns {boolean}
+ */
+ isCascadeColorEnabled: function () {
+ return this._cascadeColorEnabled;
+ },
+
+ /**
+ * Enable or disable cascade color, if cascade enabled, child nodes' opacity will be the cascade value of parent color and its own color.
+ * @param {boolean} cascadeColorEnabled
+ */
+ setCascadeColorEnabled: function (cascadeColorEnabled) {
+ if (this._cascadeColorEnabled === cascadeColorEnabled)
+ return;
+ this._cascadeColorEnabled = cascadeColorEnabled;
+ this._renderCmd.setCascadeColorEnabledDirty();
+ },
+
+ /**
+ * Set whether color should be changed with the opacity value,
+ * useless in cc.Node, but this function is override in some class to have such behavior.
+ * @function
+ * @param {Boolean} opacityValue
+ */
+ setOpacityModifyRGB: function (opacityValue) {
+ },
+
+ /**
+ * Get whether color should be changed with the opacity value
+ * @function
+ * @return {Boolean}
+ */
+ isOpacityModifyRGB: function () {
+ return false;
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.Node.CanvasRenderCmd(this);
+ else
+ return new cc.Node.WebGLRenderCmd(this);
+ },
+
+ /** Search the children of the receiving node to perform processing for nodes which share a name.
+ *
+ * @param name The name to search for, supports c++11 regular expression.
+ * Search syntax options:
+ * `//`: Can only be placed at the begin of the search string. This indicates that it will search recursively.
+ * `..`: The search should move up to the node's parent. Can only be placed at the end of string.
+ * `/` : When placed anywhere but the start of the search string, this indicates that the search should move to the node's children.
+ *
+ * @code
+ * enumerateChildren("//MyName", ...): This searches the children recursively and matches any node with the name `MyName`.
+ * enumerateChildren("[[:alnum:]]+", ...): This search string matches every node of its children.
+ * enumerateChildren("A[[:digit:]]", ...): This searches the node's children and returns any child named `A0`, `A1`, ..., `A9`.
+ * enumerateChildren("Abby/Normal", ...): This searches the node's grandchildren and returns any node whose name is `Normal`
+ * and whose parent is named `Abby`.
+ * enumerateChildren("//Abby/Normal", ...): This searches recursively and returns any node whose name is `Normal` and whose
+ * parent is named `Abby`.
+ * @endcode
+ *
+ * @warning Only support alpha or number for name, and not support unicode.
+ *
+ * @param callback A callback function to execute on nodes that match the `name` parameter. The function takes the following arguments:
+ * `node`
+ * A node that matches the name
+ * And returns a boolean result. Your callback can return `true` to terminate the enumeration.
+ *
+ */
+ enumerateChildren: function (name, callback) {
+ cc.assert(name && name.length != 0, "Invalid name");
+ cc.assert(callback != null, "Invalid callback function");
+
+ var length = name.length;
+ var subStrStartPos = 0;
+ var subStrlength = length;
+
+ // Starts with '//'?
+ var searchRecursively = false;
+ if (length > 2 && name[0] === "/" && name[1] === "/") {
+ searchRecursively = true;
+ subStrStartPos = 2;
+ subStrlength -= 2;
+ }
+
+ var searchFromParent = false;
+ if (length > 3 && name[length - 3] === "/" && name[length - 2] === "." && name[length - 1] === ".") {
+ searchFromParent = true;
+ subStrlength -= 3;
+ }
+
+ var newName = name.substr(subStrStartPos, subStrlength);
+
+ if (searchFromParent)
+ newName = "[[:alnum:]]+/" + newName;
+
+ if (searchRecursively)
+ this.doEnumerateRecursive(this, newName, callback);
+ else
+ this.doEnumerate(newName, callback);
+ },
+
+ doEnumerateRecursive: function (node, name, callback) {
+ var ret = false;
+ if (node.doEnumerate(name, callback)) {
+ ret = true;
+ } else {
+ var child,
+ children = node.getChildren(),
+ length = children.length;
+ // search its children
+ for (var i = 0; i < length; i++) {
+ child = children[i];
+ if (this.doEnumerateRecursive(child, name, callback)) {
+ ret = true;
+ break;
+ }
+ }
+ }
+ return ret;
+ },
+
+ doEnumerate: function (name, callback) {
+ // name may be xxx/yyy, should find its parent
+ var pos = name.indexOf('/');
+ var searchName = name;
+ var needRecursive = false;
+ if (pos !== -1) {
+ searchName = name.substr(0, pos);
+ //name.erase(0, pos+1);
+ needRecursive = true;
+ }
+
+ var ret = false;
+ var child,
+ children = this._children,
+ length = children.length;
+ for (var i = 0; i < length; i++) {
+ child = children[i];
+ if (child._name.indexOf(searchName) !== -1) {
+ if (!needRecursive) {
+ // terminate enumeration if callback return true
+ if (callback(child)) {
+ ret = true;
+ break;
+ }
+ } else {
+ ret = child.doEnumerate(name, callback);
+ if (ret)
+ break;
+ }
+ }
+ }
+
+ return ret;
+ }
+});
+
+/**
+ * Allocates and initializes a node.
+ * @deprecated since v3.0, please use new construction instead.
+ * @see cc.Node
+ * @return {cc.Node}
+ */
+cc.Node.create = function () {
+ return new cc.Node();
+};
+
+cc.Node._stateCallbackType = {
+ onEnter: 1,
+ onExit: 2,
+ cleanup: 3,
+ onEnterTransitionDidFinish: 4,
+ onExitTransitionDidStart: 5,
+ max: 6
+};
+cc.Node._performStacks = [[]];
+cc.Node._performing = 0;
+
+cc.assert(cc.isFunction(cc._tmp.PrototypeCCNode), cc._LogInfos.MissingFile, "BaseNodesPropertyDefine.js");
+cc._tmp.PrototypeCCNode();
+delete cc._tmp.PrototypeCCNode;
diff --git a/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js
new file mode 100644
index 0000000..43c46d0
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js
@@ -0,0 +1,657 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+//---------------------- Customer render cmd --------------------
+cc.CustomRenderCmd = function (target, func) {
+ this._needDraw = true;
+ this._target = target;
+ this._callback = func;
+};
+cc.CustomRenderCmd.prototype.rendering = function (ctx, scaleX, scaleY) {
+ if (!this._callback)
+ return;
+ this._callback.call(this._target, ctx, scaleX, scaleY);
+};
+cc.CustomRenderCmd.prototype.needDraw = function () {
+ return this._needDraw;
+};
+
+var dirtyFlags = cc.Node._dirtyFlags = {
+ transformDirty: 1 << 0, visibleDirty: 1 << 1, colorDirty: 1 << 2, opacityDirty: 1 << 3, cacheDirty: 1 << 4,
+ orderDirty: 1 << 5, textDirty: 1 << 6, gradientDirty: 1 << 7, textureDirty: 1 << 8,
+ contentDirty: 1 << 9,
+ COUNT: 10,
+ all: (1 << 10) - 1
+};
+
+var ONE_DEGREE = Math.PI / 180;
+
+function transformChildTree(root) {
+ var index = 1;
+ var children, child, curr, parentCmd, i, len;
+ var stack = cc.Node._performStacks[cc.Node._performing];
+ if (!stack) {
+ stack = [];
+ cc.Node._performStacks.push(stack);
+ }
+ stack.length = 0;
+ cc.Node._performing++;
+ stack[0] = root;
+ while (index) {
+ index--;
+ curr = stack[index];
+ // Avoid memory leak
+ stack[index] = null;
+ if (!curr) continue;
+ children = curr._children;
+ if (children && children.length > 0) {
+ parentCmd = curr._renderCmd;
+ for (i = 0, len = children.length; i < len; ++i) {
+ child = children[i];
+ stack[index] = child;
+ index++;
+ child._renderCmd.transform(parentCmd);
+ }
+ }
+ var pChildren = curr._protectedChildren;
+ if (pChildren && pChildren.length > 0) {
+ parentCmd = curr._renderCmd;
+ for (i = 0, len = pChildren.length; i < len; ++i) {
+ child = pChildren[i];
+ stack[index] = child;
+ index++;
+ child._renderCmd.transform(parentCmd);
+ }
+ }
+ }
+ cc.Node._performing--;
+}
+
+//-------------------------Base -------------------------
+cc.Node.RenderCmd = function (renderable) {
+ this._node = renderable;
+ this._anchorPointInPoints = {x: 0, y: 0};
+ this._displayedColor = cc.color(255, 255, 255, 255);
+};
+
+cc.Node.RenderCmd.prototype = {
+ constructor: cc.Node.RenderCmd,
+
+ _needDraw: false,
+ _dirtyFlag: 1,
+ _curLevel: -1,
+
+ _displayedOpacity: 255,
+ _cascadeColorEnabledDirty: false,
+ _cascadeOpacityEnabledDirty: false,
+
+ _transform: null,
+ _worldTransform: null,
+ _inverse: null,
+
+ needDraw: function () {
+ return this._needDraw;
+ },
+
+ getAnchorPointInPoints: function () {
+ return cc.p(this._anchorPointInPoints);
+ },
+
+ getDisplayedColor: function () {
+ var tmpColor = this._displayedColor;
+ return cc.color(tmpColor.r, tmpColor.g, tmpColor.b, tmpColor.a);
+ },
+
+ getDisplayedOpacity: function () {
+ return this._displayedOpacity;
+ },
+
+ setCascadeColorEnabledDirty: function () {
+ this._cascadeColorEnabledDirty = true;
+ this.setDirtyFlag(cc.Node._dirtyFlags.colorDirty);
+ },
+
+ setCascadeOpacityEnabledDirty: function () {
+ this._cascadeOpacityEnabledDirty = true;
+ this.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty);
+ },
+
+ getParentToNodeTransform: function () {
+ if (!this._inverse) {
+ this._inverse = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ }
+ if (this._dirtyFlag & cc.Node._dirtyFlags.transformDirty) {
+ cc.affineTransformInvertOut(this.getNodeToParentTransform(), this._inverse);
+ }
+ return this._inverse;
+ },
+
+ detachFromParent: function () {
+ },
+
+ _updateAnchorPointInPoint: function () {
+ var locAPP = this._anchorPointInPoints, locSize = this._node._contentSize, locAnchorPoint = this._node._anchorPoint;
+ locAPP.x = locSize.width * locAnchorPoint.x;
+ locAPP.y = locSize.height * locAnchorPoint.y;
+ this.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ setDirtyFlag: function (dirtyFlag) {
+ if (this._dirtyFlag === 0 && dirtyFlag !== 0)
+ cc.renderer.pushDirtyNode(this);
+ this._dirtyFlag |= dirtyFlag;
+ },
+
+ getParentRenderCmd: function () {
+ if (this._node && this._node._parent && this._node._parent._renderCmd)
+ return this._node._parent._renderCmd;
+ return null;
+ },
+
+ transform: function (parentCmd, recursive) {
+ if (!this._transform) {
+ this._transform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ this._worldTransform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ }
+
+ var node = this._node,
+ pt = parentCmd ? parentCmd._worldTransform : null,
+ t = this._transform,
+ wt = this._worldTransform; //get the world transform
+
+ if (node._usingNormalizedPosition && node._parent) {
+ var conSize = node._parent._contentSize;
+ node._position.x = node._normalizedPosition.x * conSize.width;
+ node._position.y = node._normalizedPosition.y * conSize.height;
+ node._normalizedPositionDirty = false;
+ }
+
+ var hasRotation = node._rotationX || node._rotationY;
+ var hasSkew = node._skewX || node._skewY;
+ var sx = node._scaleX, sy = node._scaleY;
+ var appX = this._anchorPointInPoints.x, appY = this._anchorPointInPoints.y;
+ var a = 1, b = 0, c = 0, d = 1;
+ if (hasRotation || hasSkew) {
+ // position
+ t.tx = node._position.x;
+ t.ty = node._position.y;
+
+ // rotation
+ if (hasRotation) {
+ var rotationRadiansX = node._rotationX * ONE_DEGREE;
+ c = Math.sin(rotationRadiansX);
+ d = Math.cos(rotationRadiansX);
+ if (node._rotationY === node._rotationX) {
+ a = d;
+ b = -c;
+ }
+ else {
+ var rotationRadiansY = node._rotationY * ONE_DEGREE;
+ a = Math.cos(rotationRadiansY);
+ b = -Math.sin(rotationRadiansY);
+ }
+ }
+
+ // scale
+ t.a = a *= sx;
+ t.b = b *= sx;
+ t.c = c *= sy;
+ t.d = d *= sy;
+
+ // skew
+ if (hasSkew) {
+ var skx = Math.tan(node._skewX * ONE_DEGREE);
+ var sky = Math.tan(node._skewY * ONE_DEGREE);
+ if (skx === Infinity)
+ skx = 99999999;
+ if (sky === Infinity)
+ sky = 99999999;
+ t.a = a + c * sky;
+ t.b = b + d * sky;
+ t.c = c + a * skx;
+ t.d = d + b * skx;
+ }
+
+ if (appX || appY) {
+ t.tx -= t.a * appX + t.c * appY;
+ t.ty -= t.b * appX + t.d * appY;
+ // adjust anchorPoint
+ if (node._ignoreAnchorPointForPosition) {
+ t.tx += appX;
+ t.ty += appY;
+ }
+ }
+
+ if (node._additionalTransformDirty) {
+ cc.affineTransformConcatIn(t, node._additionalTransform);
+ }
+
+ if (pt) {
+ // cc.AffineTransformConcat is incorrect at get world transform
+ wt.a = t.a * pt.a + t.b * pt.c; //a
+ wt.b = t.a * pt.b + t.b * pt.d; //b
+ wt.c = t.c * pt.a + t.d * pt.c; //c
+ wt.d = t.c * pt.b + t.d * pt.d; //d
+ wt.tx = pt.a * t.tx + pt.c * t.ty + pt.tx;
+ wt.ty = pt.d * t.ty + pt.ty + pt.b * t.tx;
+ } else {
+ wt.a = t.a;
+ wt.b = t.b;
+ wt.c = t.c;
+ wt.d = t.d;
+ wt.tx = t.tx;
+ wt.ty = t.ty;
+ }
+ }
+ else {
+ t.a = sx;
+ t.b = 0;
+ t.c = 0;
+ t.d = sy;
+ t.tx = node._position.x;
+ t.ty = node._position.y;
+
+ if (appX || appY) {
+ t.tx -= t.a * appX;
+ t.ty -= t.d * appY;
+ // adjust anchorPoint
+ if (node._ignoreAnchorPointForPosition) {
+ t.tx += appX;
+ t.ty += appY;
+ }
+ }
+
+ if (node._additionalTransformDirty) {
+ cc.affineTransformConcatIn(t, node._additionalTransform);
+ }
+
+ if (pt) {
+ wt.a = t.a * pt.a + t.b * pt.c;
+ wt.b = t.a * pt.b + t.b * pt.d;
+ wt.c = t.c * pt.a + t.d * pt.c;
+ wt.d = t.c * pt.b + t.d * pt.d;
+ wt.tx = t.tx * pt.a + t.ty * pt.c + pt.tx;
+ wt.ty = t.tx * pt.b + t.ty * pt.d + pt.ty;
+ } else {
+ wt.a = t.a;
+ wt.b = t.b;
+ wt.c = t.c;
+ wt.d = t.d;
+ wt.tx = t.tx;
+ wt.ty = t.ty;
+ }
+ }
+
+ if (this._updateCurrentRegions) {
+ this._updateCurrentRegions();
+ this._notifyRegionStatus && this._notifyRegionStatus(cc.Node.CanvasRenderCmd.RegionStatus.DirtyDouble);
+ }
+
+ if (recursive) {
+ transformChildTree(node);
+ }
+
+ this._cacheDirty = true;
+ },
+
+ getNodeToParentTransform: function () {
+ if (!this._transform || this._dirtyFlag & cc.Node._dirtyFlags.transformDirty) {
+ this.transform();
+ }
+ return this._transform;
+ },
+
+ visit: function (parentCmd) {
+ var node = this._node, renderer = cc.renderer;
+
+ parentCmd = parentCmd || this.getParentRenderCmd();
+ if (parentCmd)
+ this._curLevel = parentCmd._curLevel + 1;
+
+ if (isNaN(node._customZ)) {
+ node._vertexZ = renderer.assignedZ;
+ renderer.assignedZ += renderer.assignedZStep;
+ }
+
+ this._syncStatus(parentCmd);
+ },
+
+ _updateDisplayColor: function (parentColor) {
+ var node = this._node;
+ var locDispColor = this._displayedColor, locRealColor = node._realColor;
+ var i, len, selChildren, item;
+ this._notifyRegionStatus && this._notifyRegionStatus(cc.Node.CanvasRenderCmd.RegionStatus.Dirty);
+ if (this._cascadeColorEnabledDirty && !node._cascadeColorEnabled) {
+ locDispColor.r = locRealColor.r;
+ locDispColor.g = locRealColor.g;
+ locDispColor.b = locRealColor.b;
+ var whiteColor = new cc.Color(255, 255, 255, 255);
+ selChildren = node._children;
+ for (i = 0, len = selChildren.length; i < len; i++) {
+ item = selChildren[i];
+ if (item && item._renderCmd)
+ item._renderCmd._updateDisplayColor(whiteColor);
+ }
+ this._cascadeColorEnabledDirty = false;
+ } else {
+ if (parentColor === undefined) {
+ var locParent = node._parent;
+ if (locParent && locParent._cascadeColorEnabled)
+ parentColor = locParent.getDisplayedColor();
+ else
+ parentColor = cc.color.WHITE;
+ }
+ locDispColor.r = 0 | (locRealColor.r * parentColor.r / 255.0);
+ locDispColor.g = 0 | (locRealColor.g * parentColor.g / 255.0);
+ locDispColor.b = 0 | (locRealColor.b * parentColor.b / 255.0);
+ if (node._cascadeColorEnabled) {
+ selChildren = node._children;
+ for (i = 0, len = selChildren.length; i < len; i++) {
+ item = selChildren[i];
+ if (item && item._renderCmd) {
+ item._renderCmd._updateDisplayColor(locDispColor);
+ item._renderCmd._updateColor();
+ }
+ }
+ }
+ }
+ this._dirtyFlag &= ~dirtyFlags.colorDirty;
+ },
+
+ _updateDisplayOpacity: function (parentOpacity) {
+ var node = this._node;
+ var i, len, selChildren, item;
+ this._notifyRegionStatus && this._notifyRegionStatus(cc.Node.CanvasRenderCmd.RegionStatus.Dirty);
+ if (this._cascadeOpacityEnabledDirty && !node._cascadeOpacityEnabled) {
+ this._displayedOpacity = node._realOpacity;
+ selChildren = node._children;
+ for (i = 0, len = selChildren.length; i < len; i++) {
+ item = selChildren[i];
+ if (item && item._renderCmd)
+ item._renderCmd._updateDisplayOpacity(255);
+ }
+ this._cascadeOpacityEnabledDirty = false;
+ } else {
+ if (parentOpacity === undefined) {
+ var locParent = node._parent;
+ parentOpacity = 255;
+ if (locParent && locParent._cascadeOpacityEnabled)
+ parentOpacity = locParent.getDisplayedOpacity();
+ }
+ this._displayedOpacity = node._realOpacity * parentOpacity / 255.0;
+ if (node._cascadeOpacityEnabled) {
+ selChildren = node._children;
+ for (i = 0, len = selChildren.length; i < len; i++) {
+ item = selChildren[i];
+ if (item && item._renderCmd) {
+ item._renderCmd._updateDisplayOpacity(this._displayedOpacity);
+ item._renderCmd._updateColor();
+ }
+ }
+ }
+ }
+ this._dirtyFlag &= ~dirtyFlags.opacityDirty;
+ },
+
+ _syncDisplayColor: function (parentColor) {
+ var node = this._node, locDispColor = this._displayedColor, locRealColor = node._realColor;
+ if (parentColor === undefined) {
+ var locParent = node._parent;
+ if (locParent && locParent._cascadeColorEnabled)
+ parentColor = locParent.getDisplayedColor();
+ else
+ parentColor = cc.color.WHITE;
+ }
+ locDispColor.r = 0 | (locRealColor.r * parentColor.r / 255.0);
+ locDispColor.g = 0 | (locRealColor.g * parentColor.g / 255.0);
+ locDispColor.b = 0 | (locRealColor.b * parentColor.b / 255.0);
+ },
+
+ _syncDisplayOpacity: function (parentOpacity) {
+ var node = this._node;
+ if (parentOpacity === undefined) {
+ var locParent = node._parent;
+ parentOpacity = 255;
+ if (locParent && locParent._cascadeOpacityEnabled)
+ parentOpacity = locParent.getDisplayedOpacity();
+ }
+ this._displayedOpacity = node._realOpacity * parentOpacity / 255.0;
+ },
+
+ _updateColor: function () {
+ },
+
+ _propagateFlagsDown: function (parentCmd) {
+ var locFlag = this._dirtyFlag;
+ var parentNode = parentCmd ? parentCmd._node : null;
+
+ if(parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & dirtyFlags.colorDirty))
+ locFlag |= dirtyFlags.colorDirty;
+
+ if(parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & dirtyFlags.opacityDirty))
+ locFlag |= dirtyFlags.opacityDirty;
+
+ if(parentCmd && (parentCmd._dirtyFlag & dirtyFlags.transformDirty))
+ locFlag |= dirtyFlags.transformDirty;
+
+ this._dirtyFlag = locFlag;
+ },
+
+ updateStatus: function () {
+ var locFlag = this._dirtyFlag;
+ var colorDirty = locFlag & dirtyFlags.colorDirty,
+ opacityDirty = locFlag & dirtyFlags.opacityDirty;
+
+ if (locFlag & dirtyFlags.contentDirty) {
+ this._notifyRegionStatus && this._notifyRegionStatus(cc.Node.CanvasRenderCmd.RegionStatus.Dirty);
+ this._dirtyFlag &= ~dirtyFlags.contentDirty;
+ }
+
+ if (colorDirty)
+ this._updateDisplayColor();
+
+ if (opacityDirty)
+ this._updateDisplayOpacity();
+
+ if (colorDirty || opacityDirty)
+ this._updateColor();
+
+ if (locFlag & dirtyFlags.transformDirty) {
+ //update the transform
+ this.transform(this.getParentRenderCmd(), true);
+ this._dirtyFlag &= ~dirtyFlags.transformDirty;
+ }
+
+ if (locFlag & dirtyFlags.orderDirty)
+ this._dirtyFlag &= ~dirtyFlags.orderDirty;
+ },
+
+ _syncStatus: function (parentCmd) {
+ // In the visit logic does not restore the _dirtyFlag
+ // Because child elements need parent's _dirtyFlag to change himself
+ var locFlag = this._dirtyFlag, parentNode = parentCmd ? parentCmd._node : null;
+
+ // There is a possibility:
+ // The parent element changed color, child element not change
+ // This will cause the parent element changed color
+ // But while the child element does not enter the circulation
+ // Here will be reset state in last
+ // In order the child elements get the parent state
+ if (parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & dirtyFlags.colorDirty))
+ locFlag |= dirtyFlags.colorDirty;
+
+ if (parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & dirtyFlags.opacityDirty))
+ locFlag |= dirtyFlags.opacityDirty;
+
+ if (parentCmd && (parentCmd._dirtyFlag & dirtyFlags.transformDirty))
+ locFlag |= dirtyFlags.transformDirty;
+
+ this._dirtyFlag = locFlag;
+
+ var colorDirty = locFlag & dirtyFlags.colorDirty,
+ opacityDirty = locFlag & dirtyFlags.opacityDirty;
+
+ if (colorDirty)
+ //update the color
+ this._syncDisplayColor();
+
+ if (opacityDirty)
+ //update the opacity
+ this._syncDisplayOpacity();
+
+ if (colorDirty || opacityDirty)
+ this._updateColor();
+
+ if (locFlag & dirtyFlags.transformDirty)
+ //update the transform
+ this.transform(parentCmd);
+
+ if (locFlag & dirtyFlags.orderDirty)
+ this._dirtyFlag &= ~dirtyFlags.orderDirty;
+ },
+
+ setShaderProgram: function (shaderProgram) {
+ //do nothing.
+ },
+
+ getShaderProgram: function () {
+ return null;
+ },
+
+ getGLProgramState: function () {
+ return null;
+ },
+
+ setGLProgramState: function (glProgramState) {
+ // do nothing
+ },
+};
+
+cc.Node.RenderCmd.prototype.originTransform = cc.Node.RenderCmd.prototype.transform;
+cc.Node.RenderCmd.prototype.originUpdateStatus = cc.Node.RenderCmd.prototype.updateStatus;
+cc.Node.RenderCmd.prototype._originSyncStatus = cc.Node.RenderCmd.prototype._syncStatus;
+
+//-----------------------Canvas ---------------------------
+
+(function () {
+//The cc.Node's render command for Canvas
+ cc.Node.CanvasRenderCmd = function (renderable) {
+ this._node = renderable;
+ this._anchorPointInPoints = {x: 0, y: 0};
+ this._displayedColor = cc.color(255, 255, 255, 255);
+ this._cachedParent = null;
+ this._cacheDirty = false;
+ this._currentRegion = new cc.Region();
+ this._oldRegion = new cc.Region();
+ this._regionFlag = 0;
+ this._canUseDirtyRegion = false;
+ };
+
+ cc.Node.CanvasRenderCmd.RegionStatus = {
+ NotDirty: 0, //the region is not dirty
+ Dirty: 1, //the region is dirty, because of color, opacity or context
+ DirtyDouble: 2 //the region is moved, the old and the new one need considered when rendering
+ };
+
+ var proto = cc.Node.CanvasRenderCmd.prototype = Object.create(cc.Node.RenderCmd.prototype);
+ proto.constructor = cc.Node.CanvasRenderCmd;
+ proto._rootCtor = cc.Node.CanvasRenderCmd;
+
+ proto._notifyRegionStatus = function (status) {
+ if (this._needDraw && this._regionFlag < status) {
+ this._regionFlag = status;
+ }
+ };
+
+ var localBB = new cc.Rect();
+ proto.getLocalBB = function () {
+ var node = this._node;
+ localBB.x = localBB.y = 0;
+ localBB.width = node._contentSize.width;
+ localBB.height = node._contentSize.height;
+ return localBB;
+ };
+
+ proto._updateCurrentRegions = function () {
+ var temp = this._currentRegion;
+ this._currentRegion = this._oldRegion;
+ this._oldRegion = temp;
+ //hittest will call the transform, and set region flag to DirtyDouble, and the changes need to be considered for rendering
+ if (cc.Node.CanvasRenderCmd.RegionStatus.DirtyDouble === this._regionFlag && (!this._currentRegion.isEmpty())) {
+ this._oldRegion.union(this._currentRegion);
+ }
+ this._currentRegion.updateRegion(this.getLocalBB(), this._worldTransform);
+ };
+
+ proto.setDirtyFlag = function (dirtyFlag, child) {
+ cc.Node.RenderCmd.prototype.setDirtyFlag.call(this, dirtyFlag, child);
+ this._setCacheDirty(child); //TODO it should remove from here.
+ if (this._cachedParent)
+ this._cachedParent.setDirtyFlag(dirtyFlag, true);
+ };
+
+ proto._setCacheDirty = function () {
+ if (this._cacheDirty === false) {
+ this._cacheDirty = true;
+ var cachedP = this._cachedParent;
+ cachedP && cachedP !== this && cachedP._setNodeDirtyForCache && cachedP._setNodeDirtyForCache();
+ }
+ };
+
+ proto._setCachedParent = function (cachedParent) {
+ if (this._cachedParent === cachedParent)
+ return;
+
+ this._cachedParent = cachedParent;
+ var children = this._node._children;
+ for (var i = 0, len = children.length; i < len; i++)
+ children[i]._renderCmd._setCachedParent(cachedParent);
+ };
+
+ proto.detachFromParent = function () {
+ this._cachedParent = null;
+ var selChildren = this._node._children, item;
+ for (var i = 0, len = selChildren.length; i < len; i++) {
+ item = selChildren[i];
+ if (item && item._renderCmd)
+ item._renderCmd.detachFromParent();
+ }
+ };
+
+ //util functions
+ cc.Node.CanvasRenderCmd._getCompositeOperationByBlendFunc = function (blendFunc) {
+ if (!blendFunc)
+ return "source-over";
+ else {
+ if (( blendFunc.src === cc.SRC_ALPHA && blendFunc.dst === cc.ONE) || (blendFunc.src === cc.ONE && blendFunc.dst === cc.ONE))
+ return "lighter";
+ else if (blendFunc.src === cc.ZERO && blendFunc.dst === cc.SRC_ALPHA)
+ return "destination-in";
+ else if (blendFunc.src === cc.ZERO && blendFunc.dst === cc.ONE_MINUS_SRC_ALPHA)
+ return "destination-out";
+ else
+ return "source-over";
+ }
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js
new file mode 100644
index 0000000..7680017
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js
@@ -0,0 +1,65 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+// ------------------------------ The cc.Node's render command for WebGL ----------------------------------
+(function () {
+ cc.Node.WebGLRenderCmd = function (renderable) {
+ this._node = renderable;
+ this._anchorPointInPoints = {x: 0, y: 0};
+ this._displayedColor = cc.color(255, 255, 255, 255);
+ this._glProgramState = null;
+ };
+
+ var proto = cc.Node.WebGLRenderCmd.prototype = Object.create(cc.Node.RenderCmd.prototype);
+ proto.constructor = cc.Node.WebGLRenderCmd;
+ proto._rootCtor = cc.Node.WebGLRenderCmd;
+
+ proto._updateColor = function () {
+ };
+
+ proto.setShaderProgram = function (shaderProgram) {
+ this._glProgramState = cc.GLProgramState.getOrCreateWithGLProgram(shaderProgram);
+ };
+
+ proto.getShaderProgram = function () {
+ return this._glProgramState ? this._glProgramState.getGLProgram() : null;
+ };
+
+ proto.getGLProgramState = function () {
+ return this._glProgramState;
+ };
+
+ proto.setGLProgramState = function (glProgramState) {
+ this._glProgramState = glProgramState;
+ };
+
+ // Use a property getter/setter for backwards compatability, and
+ // to ease the transition from using glPrograms directly, to
+ // using glProgramStates.
+ Object.defineProperty(proto, '_shaderProgram', {
+ set: function (value) { this.setShaderProgram(value); },
+ get: function () { return this.getShaderProgram(); }
+ });
+ /** @expose */
+ proto._shaderProgram;
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/cocoa/CCAffineTransform.js b/frameworks/cocos2d-html5/cocos2d/core/cocoa/CCAffineTransform.js
new file mode 100644
index 0000000..8ff0957
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/cocoa/CCAffineTransform.js
@@ -0,0 +1,305 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.AffineTransform class represent an affine transform matrix. It's composed basically by translation, rotation, scale transformations.
+ * Please do not use its constructor directly, use cc.affineTransformMake alias function instead.
+ *
+ * @class cc.AffineTransform
+ * @param {Number} a
+ * @param {Number} b
+ * @param {Number} c
+ * @param {Number} d
+ * @param {Number} tx
+ * @param {Number} ty
+ * @see cc.affineTransformMake
+ */
+cc.AffineTransform = function (a, b, c, d, tx, ty) {
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ this.d = d;
+ this.tx = tx;
+ this.ty = ty;
+};
+
+/**
+ * Create a cc.AffineTransform object with all contents in the matrix
+ * @function
+ *
+ * @param {Number} a
+ * @param {Number} b
+ * @param {Number} c
+ * @param {Number} d
+ * @param {Number} tx
+ * @param {Number} ty
+ * @return {cc.AffineTransform}
+ */
+cc.affineTransformMake = function (a, b, c, d, tx, ty) {
+ return {a: a, b: b, c: c, d: d, tx: tx, ty: ty};
+};
+
+/**
+ * Apply the affine transformation on a point.
+ * @function
+ *
+ * @param {cc.Point|Number} point or x
+ * @param {cc.AffineTransform|Number} transOrY transform matrix or y
+ * @param {cc.AffineTransform} t transform matrix or y
+ * @return {cc.Point}
+ */
+cc.pointApplyAffineTransform = function (point, transOrY, t) {
+ var x, y;
+ if (t === undefined) {
+ t = transOrY;
+ x = point.x;
+ y = point.y;
+ } else {
+ x = point;
+ y = transOrY;
+ }
+ return {x: t.a * x + t.c * y + t.tx, y: t.b * x + t.d * y + t.ty};
+};
+
+cc._pointApplyAffineTransform = function (x, y, t) { //it will remove.
+ return cc.pointApplyAffineTransform(x, y, t);
+};
+
+/**
+ * Apply the affine transformation on a size.
+ * @function
+ *
+ * @param {cc.Size} size
+ * @param {cc.AffineTransform} t
+ * @return {cc.Size}
+ */
+cc.sizeApplyAffineTransform = function (size, t) {
+ return {width: t.a * size.width + t.c * size.height, height: t.b * size.width + t.d * size.height};
+};
+
+/**
+ * Create a identity transformation matrix:
+ * [ 1, 0, 0,
+ * 0, 1, 0 ]
+ * @function
+ *
+ * @return {cc.AffineTransform}
+ */
+cc.affineTransformMakeIdentity = function () {
+ return {a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0};
+};
+
+/**
+ * Create a identity transformation matrix:
+ * [ 1, 0, 0,
+ * 0, 1, 0 ]
+ * @function
+ *
+ * @return {cc.AffineTransform}
+ * @deprecated since v3.0, please use cc.affineTransformMakeIdentity() instead
+ * @see cc.affineTransformMakeIdentity
+ */
+cc.affineTransformIdentity = function () {
+ return {a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0};
+};
+
+/**
+ * Apply the affine transformation on a rect.
+ * @function
+ *
+ * @param {cc.Rect} rect
+ * @param {cc.AffineTransform} anAffineTransform
+ * @return {cc.Rect}
+ */
+cc.rectApplyAffineTransform = function (rect, anAffineTransform) {
+ var top = cc.rectGetMinY(rect);
+ var left = cc.rectGetMinX(rect);
+ var right = cc.rectGetMaxX(rect);
+ var bottom = cc.rectGetMaxY(rect);
+
+ var topLeft = cc.pointApplyAffineTransform(left, top, anAffineTransform);
+ var topRight = cc.pointApplyAffineTransform(right, top, anAffineTransform);
+ var bottomLeft = cc.pointApplyAffineTransform(left, bottom, anAffineTransform);
+ var bottomRight = cc.pointApplyAffineTransform(right, bottom, anAffineTransform);
+
+ var minX = Math.min(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
+ var maxX = Math.max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
+ var minY = Math.min(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
+ var maxY = Math.max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
+
+ return cc.rect(minX, minY, (maxX - minX), (maxY - minY));
+};
+
+cc._rectApplyAffineTransformIn = function (rect, anAffineTransform) {
+ var top = cc.rectGetMinY(rect);
+ var left = cc.rectGetMinX(rect);
+ var right = cc.rectGetMaxX(rect);
+ var bottom = cc.rectGetMaxY(rect);
+
+ var topLeft = cc.pointApplyAffineTransform(left, top, anAffineTransform);
+ var topRight = cc.pointApplyAffineTransform(right, top, anAffineTransform);
+ var bottomLeft = cc.pointApplyAffineTransform(left, bottom, anAffineTransform);
+ var bottomRight = cc.pointApplyAffineTransform(right, bottom, anAffineTransform);
+
+ var minX = Math.min(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
+ var maxX = Math.max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
+ var minY = Math.min(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
+ var maxY = Math.max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
+
+ rect.x = minX;
+ rect.y = minY;
+ rect.width = maxX - minX;
+ rect.height = maxY - minY;
+ return rect;
+};
+
+/**
+ * Create a new affine transformation with a base transformation matrix and a translation based on it.
+ * @function
+ *
+ * @param {cc.AffineTransform} t The base affine transform object
+ * @param {Number} tx The translation on x axis
+ * @param {Number} ty The translation on y axis
+ * @return {cc.AffineTransform}
+ */
+cc.affineTransformTranslate = function (t, tx, ty) {
+ return {
+ a: t.a,
+ b: t.b,
+ c: t.c,
+ d: t.d,
+ tx: t.tx + t.a * tx + t.c * ty,
+ ty: t.ty + t.b * tx + t.d * ty
+ };
+};
+
+/**
+ * Create a new affine transformation with a base transformation matrix and a scale based on it.
+ * @function
+ * @param {cc.AffineTransform} t The base affine transform object
+ * @param {Number} sx The scale on x axis
+ * @param {Number} sy The scale on y axis
+ * @return {cc.AffineTransform}
+ */
+cc.affineTransformScale = function (t, sx, sy) {
+ return {a: t.a * sx, b: t.b * sx, c: t.c * sy, d: t.d * sy, tx: t.tx, ty: t.ty};
+};
+
+/**
+ * Create a new affine transformation with a base transformation matrix and a rotation based on it.
+ * @function
+ * @param {cc.AffineTransform} aTransform The base affine transform object
+ * @param {Number} anAngle The angle to rotate
+ * @return {cc.AffineTransform}
+ */
+cc.affineTransformRotate = function (aTransform, anAngle) {
+ var fSin = Math.sin(anAngle);
+ var fCos = Math.cos(anAngle);
+
+ return {
+ a: aTransform.a * fCos + aTransform.c * fSin,
+ b: aTransform.b * fCos + aTransform.d * fSin,
+ c: aTransform.c * fCos - aTransform.a * fSin,
+ d: aTransform.d * fCos - aTransform.b * fSin,
+ tx: aTransform.tx,
+ ty: aTransform.ty
+ };
+};
+
+/**
+ * Concatenate a transform matrix to another and return the result:
+ * t' = t1 * t2
+ * @function
+ * @param {cc.AffineTransform} t1 The first transform object
+ * @param {cc.AffineTransform} t2 The transform object to concatenate
+ * @return {cc.AffineTransform} The result of concatenation
+ */
+cc.affineTransformConcat = function (t1, t2) {
+ return {
+ a: t1.a * t2.a + t1.b * t2.c, //a
+ b: t1.a * t2.b + t1.b * t2.d, //b
+ c: t1.c * t2.a + t1.d * t2.c, //c
+ d: t1.c * t2.b + t1.d * t2.d, //d
+ tx: t1.tx * t2.a + t1.ty * t2.c + t2.tx, //tx
+ ty: t1.tx * t2.b + t1.ty * t2.d + t2.ty
+ }; //ty
+};
+
+/**
+ * Concatenate a transform matrix to another
+ * The results are reflected in the first matrix.
+ * t' = t1 * t2
+ * @function
+ * @param {cc.AffineTransform} t1 The first transform object
+ * @param {cc.AffineTransform} t2 The transform object to concatenate
+ * @return {cc.AffineTransform} The result of concatenation
+ */
+cc.affineTransformConcatIn = function (t1, t2) {
+ var a = t1.a, b = t1.b, c = t1.c, d = t1.d, tx = t1.tx, ty = t1.ty;
+ t1.a = a * t2.a + b * t2.c;
+ t1.b = a * t2.b + b * t2.d;
+ t1.c = c * t2.a + d * t2.c;
+ t1.d = c * t2.b + d * t2.d;
+ t1.tx = tx * t2.a + ty * t2.c + t2.tx;
+ t1.ty = tx * t2.b + ty * t2.d + t2.ty;
+ return t1;
+};
+
+/**
+ * Return true if an affine transform equals to another, false otherwise.
+ * @function
+ * @param {cc.AffineTransform} t1
+ * @param {cc.AffineTransform} t2
+ * @return {Boolean}
+ */
+cc.affineTransformEqualToTransform = function (t1, t2) {
+ return ((t1.a === t2.a) && (t1.b === t2.b) && (t1.c === t2.c) && (t1.d === t2.d) && (t1.tx === t2.tx) && (t1.ty === t2.ty));
+};
+
+/**
+ * Get the invert transform of an AffineTransform object
+ * @function
+ * @param {cc.AffineTransform} t
+ * @return {cc.AffineTransform} The inverted transform object
+ */
+cc.affineTransformInvert = function (t) {
+ var determinant = 1 / (t.a * t.d - t.b * t.c);
+ return {
+ a: determinant * t.d, b: -determinant * t.b, c: -determinant * t.c, d: determinant * t.a,
+ tx: determinant * (t.c * t.ty - t.d * t.tx), ty: determinant * (t.b * t.tx - t.a * t.ty)
+ };
+};
+
+cc.affineTransformInvertOut = function (t, out) {
+ var a = t.a, b = t.b, c = t.c, d = t.d;
+ var determinant = 1 / (a * d - b * c);
+ out.a = determinant * d;
+ out.b = -determinant * b;
+ out.c = -determinant * c;
+ out.d = determinant * a;
+ out.tx = determinant * (c * t.ty - d * t.tx);
+ out.ty = determinant * (b * t.tx - a * t.ty);
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/core/cocoa/CCGeometry.js b/frameworks/cocos2d-html5/cocos2d/core/cocoa/CCGeometry.js
new file mode 100644
index 0000000..a3690f2
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/cocoa/CCGeometry.js
@@ -0,0 +1,338 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.Point is the class for point object, please do not use its constructor to create points, use cc.p() alias function instead.
+ * @class cc.Point
+ * @param {Number} x
+ * @param {Number} y
+ *
+ * @property x {Number}
+ * @property y {Number}
+ * @see cc.p
+ */
+cc.Point = function (x, y) {
+ this.x = x || 0;
+ this.y = y || 0;
+};
+
+/**
+ * Helper function that creates a cc.Point.
+ * @function
+ * @param {Number|cc.Point} x a Number or a size object
+ * @param {Number} y
+ * @return {cc.Point}
+ * @example
+ * var point1 = cc.p();
+ * var point2 = cc.p(100, 100);
+ * var point3 = cc.p(point2);
+ * var point4 = cc.p({x: 100, y: 100});
+ */
+cc.p = function (x, y) {
+ // This can actually make use of "hidden classes" in JITs and thus decrease
+ // memory usage and overall performance drastically
+ // return cc.p(x, y);
+ // but this one will instead flood the heap with newly allocated hash maps
+ // giving little room for optimization by the JIT,
+ // note: we have tested this item on Chrome and firefox, it is faster than cc.p(x, y)
+ if (x === undefined)
+ return {x: 0, y: 0};
+ if (y === undefined)
+ return {x: x.x, y: x.y};
+ return {x: x, y: y};
+};
+
+/**
+ * Check whether a point's value equals to another
+ * @function
+ * @param {cc.Point} point1
+ * @param {cc.Point} point2
+ * @return {Boolean}
+ */
+cc.pointEqualToPoint = function (point1, point2) {
+ return point1 && point2 && (point1.x === point2.x) && (point1.y === point2.y);
+};
+
+
+/**
+ * cc.Size is the class for size object, please do not use its constructor to create sizes, use cc.size() alias function instead.
+ * @class cc.Size
+ * @param {Number} width
+ * @param {Number} height
+ * @property {Number} width
+ * @property {Number} height
+ * @see cc.size
+ */
+cc.Size = function (width, height) {
+ this.width = width || 0;
+ this.height = height || 0;
+};
+
+/**
+ * Helper function that creates a cc.Size.
+ * @function
+ * @param {Number|cc.Size} w width or a size object
+ * @param {Number} h height
+ * @return {cc.Size}
+ * @example
+ * var size1 = cc.size();
+ * var size2 = cc.size(100,100);
+ * var size3 = cc.size(size2);
+ * var size4 = cc.size({width: 100, height: 100});
+ */
+cc.size = function (w, h) {
+ // This can actually make use of "hidden classes" in JITs and thus decrease
+ // memory usage and overall performance drastically
+ //return cc.size(w, h);
+ // but this one will instead flood the heap with newly allocated hash maps
+ // giving little room for optimization by the JIT
+ // note: we have tested this item on Chrome and firefox, it is faster than cc.size(w, h)
+ if (w === undefined)
+ return {width: 0, height: 0};
+ if (h === undefined)
+ return {width: w.width, height: w.height};
+ return {width: w, height: h};
+};
+
+/**
+ * Check whether a point's value equals to another
+ * @function
+ * @param {cc.Size} size1
+ * @param {cc.Size} size2
+ * @return {Boolean}
+ */
+cc.sizeEqualToSize = function (size1, size2) {
+ return (size1 && size2 && (size1.width === size2.width) && (size1.height === size2.height));
+};
+
+
+/**
+ * cc.Rect is the class for rect object, please do not use its constructor to create rects, use cc.rect() alias function instead.
+ * @class cc.Rect
+ * @param {Number} x
+ * @param {Number} y
+ * @param {Number} width
+ * @param {Number} height
+ *
+ * @property {Number} x
+ * @property {Number} y
+ * @property {Number} width
+ * @property {Number} height
+ *
+ * @see cc.rect
+ */
+cc.Rect = function (x, y, width, height) {
+ this.x = x||0;
+ this.y = y||0;
+ this.width = width||0;
+ this.height = height||0;
+};
+
+/**
+ * Helper function that creates a cc.Rect.
+ * @function
+ * @param {Number|cc.Rect} x a number or a rect object
+ * @param {Number} y
+ * @param {Number} w
+ * @param {Number} h
+ * @returns {cc.Rect}
+ * @example
+ * var rect1 = cc.rect();
+ * var rect2 = cc.rect(100,100,100,100);
+ * var rect3 = cc.rect(rect2);
+ * var rect4 = cc.rect({x: 100, y: 100, width: 100, height: 100});
+ */
+cc.rect = function (x, y, w, h) {
+ if (x === undefined)
+ return {x: 0, y: 0, width: 0, height: 0};
+ if (y === undefined)
+ return {x: x.x, y: x.y, width: x.width, height: x.height};
+ return {x: x, y: y, width: w, height: h };
+};
+
+/**
+ * Check whether a rect's value equals to another
+ * @function
+ * @param {cc.Rect} rect1
+ * @param {cc.Rect} rect2
+ * @return {Boolean}
+ */
+cc.rectEqualToRect = function (rect1, rect2) {
+ return rect1 && rect2 && (rect1.x === rect2.x) && (rect1.y === rect2.y) && (rect1.width === rect2.width) && (rect1.height === rect2.height);
+};
+
+cc._rectEqualToZero = function(rect){
+ return rect && (rect.x === 0) && (rect.y === 0) && (rect.width === 0) && (rect.height === 0);
+};
+
+/**
+ * Check whether the rect1 contains rect2
+ * @function
+ * @param {cc.Rect} rect1
+ * @param {cc.Rect} rect2
+ * @return {Boolean}
+ */
+cc.rectContainsRect = function (rect1, rect2) {
+ if (!rect1 || !rect2)
+ return false;
+ return !((rect1.x >= rect2.x) || (rect1.y >= rect2.y) ||
+ ( rect1.x + rect1.width <= rect2.x + rect2.width) ||
+ ( rect1.y + rect1.height <= rect2.y + rect2.height));
+};
+
+/**
+ * Returns the rightmost x-value of a rect
+ * @function
+ * @param {cc.Rect} rect
+ * @return {Number} The rightmost x value
+ */
+cc.rectGetMaxX = function (rect) {
+ return (rect.x + rect.width);
+};
+
+/**
+ * Return the midpoint x-value of a rect
+ * @function
+ * @param {cc.Rect} rect
+ * @return {Number} The midpoint x value
+ */
+cc.rectGetMidX = function (rect) {
+ return (rect.x + rect.width / 2.0);
+};
+/**
+ * Returns the leftmost x-value of a rect
+ * @function
+ * @param {cc.Rect} rect
+ * @return {Number} The leftmost x value
+ */
+cc.rectGetMinX = function (rect) {
+ return rect.x;
+};
+
+/**
+ * Return the topmost y-value of a rect
+ * @function
+ * @param {cc.Rect} rect
+ * @return {Number} The topmost y value
+ */
+cc.rectGetMaxY = function (rect) {
+ return(rect.y + rect.height);
+};
+
+/**
+ * Return the midpoint y-value of `rect'
+ * @function
+ * @param {cc.Rect} rect
+ * @return {Number} The midpoint y value
+ */
+cc.rectGetMidY = function (rect) {
+ return rect.y + rect.height / 2.0;
+};
+
+/**
+ * Return the bottommost y-value of a rect
+ * @function
+ * @param {cc.Rect} rect
+ * @return {Number} The bottommost y value
+ */
+cc.rectGetMinY = function (rect) {
+ return rect.y;
+};
+
+/**
+ * Check whether a rect contains a point
+ * @function
+ * @param {cc.Rect} rect
+ * @param {cc.Point} point
+ * @return {Boolean}
+ */
+cc.rectContainsPoint = function (rect, point) {
+ return (point.x >= cc.rectGetMinX(rect) && point.x <= cc.rectGetMaxX(rect) &&
+ point.y >= cc.rectGetMinY(rect) && point.y <= cc.rectGetMaxY(rect)) ;
+};
+
+/**
+ * Check whether a rect intersect with another
+ * @function
+ * @param {cc.Rect} rectA
+ * @param {cc.Rect} rectB
+ * @return {Boolean}
+ */
+cc.rectIntersectsRect = function (ra, rb) {
+ var maxax = ra.x + ra.width,
+ maxay = ra.y + ra.height,
+ maxbx = rb.x + rb.width,
+ maxby = rb.y + rb.height;
+ return !(maxax < rb.x || maxbx < ra.x || maxay < rb.y || maxby < ra.y);
+};
+
+/**
+ * Check whether a rect overlaps another
+ * @function
+ * @param {cc.Rect} rectA
+ * @param {cc.Rect} rectB
+ * @return {Boolean}
+ */
+cc.rectOverlapsRect = function (rectA, rectB) {
+ return !((rectA.x + rectA.width < rectB.x) ||
+ (rectB.x + rectB.width < rectA.x) ||
+ (rectA.y + rectA.height < rectB.y) ||
+ (rectB.y + rectB.height < rectA.y));
+};
+
+/**
+ * Returns the smallest rectangle that contains the two source rectangles.
+ * @function
+ * @param {cc.Rect} rectA
+ * @param {cc.Rect} rectB
+ * @return {cc.Rect}
+ */
+cc.rectUnion = function (rectA, rectB) {
+ var rect = cc.rect(0, 0, 0, 0);
+ rect.x = Math.min(rectA.x, rectB.x);
+ rect.y = Math.min(rectA.y, rectB.y);
+ rect.width = Math.max(rectA.x + rectA.width, rectB.x + rectB.width) - rect.x;
+ rect.height = Math.max(rectA.y + rectA.height, rectB.y + rectB.height) - rect.y;
+ return rect;
+};
+
+/**
+ * Returns the overlapping portion of 2 rectangles
+ * @function
+ * @param {cc.Rect} rectA
+ * @param {cc.Rect} rectB
+ * @return {cc.Rect}
+ */
+cc.rectIntersection = function (rectA, rectB) {
+ var intersection = cc.rect(
+ Math.max(cc.rectGetMinX(rectA), cc.rectGetMinX(rectB)),
+ Math.max(cc.rectGetMinY(rectA), cc.rectGetMinY(rectB)),
+ 0, 0);
+
+ intersection.width = Math.min(cc.rectGetMaxX(rectA), cc.rectGetMaxX(rectB)) - cc.rectGetMinX(intersection);
+ intersection.height = Math.min(cc.rectGetMaxY(rectA), cc.rectGetMaxY(rectB)) - cc.rectGetMinY(intersection);
+ return intersection;
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/core/cocos2d_externs.js b/frameworks/cocos2d-html5/cocos2d/core/cocos2d_externs.js
new file mode 100644
index 0000000..97c8397
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/cocos2d_externs.js
@@ -0,0 +1,66 @@
+/**
+ * @fileoverview Java Script Builtins for windows properties.
+ *
+ * @externs
+ */
+
+ /**
+ * @see https://cocos2d-x.org
+ */
+
+/**
+ * cocos2d-html5-only.
+ * @type {string}
+ */
+CSSProperties.prototype._super;
+
+/**
+ * cocos2d-html5-only. We need this because the cc.Class.extend's new
+ * infrastructure requires it.
+ * @type {string}
+ */
+CSSProperties.prototype.ctor;
+
+/**
+ * cocos2d-html5-only.
+ * @type {string}
+ */
+CSSProperties.prototype.Inflate;
+
+/**
+ * cocos2d-html5-only.
+ * @type {string}
+ */
+CSSProperties.prototype.decompress;
+
+/**
+ * Accelerometer api
+ * cocos2d-html5-only.
+ * @type {string}
+ */
+CSSProperties.prototype.DeviceOrientationEvent;
+CSSProperties.prototype.DeviceMotionEvent;
+CSSProperties.prototype.accelerationIncludingGravity;
+CSSProperties.prototype.gamma;
+CSSProperties.prototype.beta;
+CSSProperties.prototype.alpha;
+
+
+var gl = gl || {};
+CSSProperties.prototype.gl;
+
+CSSProperties.prototype.AudioContext;
+CSSProperties.prototype.webkitAudioContext;
+CSSProperties.prototype.mozAudioContext;
+CSSProperties.prototype.createBufferSource;
+CSSProperties.prototype.createGain;
+CSSProperties.prototype.createGainNode;
+CSSProperties.prototype.destination;
+CSSProperties.prototype.decodeAudioData;
+CSSProperties.prototype.gain;
+CSSProperties.prototype.connect;
+CSSProperties.prototype.playbackState;
+CSSProperties.prototype.noteGrainOn;
+CSSProperties.prototype.noteOn;
+
+
diff --git a/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEvent.js b/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEvent.js
new file mode 100644
index 0000000..fa5c47f
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEvent.js
@@ -0,0 +1,449 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Base class of all kinds of events.
+ * @class
+ * @extends cc.Class
+ */
+cc.Event = cc.Class.extend(/** @lends cc.Event# */{
+ _type: 0, // Event type
+ _isStopped: false, //< whether the event has been stopped.
+ _currentTarget: null, //< Current target
+
+ _setCurrentTarget: function (target) {
+ this._currentTarget = target;
+ },
+
+ ctor: function (type) {
+ this._type = type;
+ },
+
+ /**
+ * Gets the event type
+ * @function
+ * @returns {Number}
+ */
+ getType: function () {
+ return this._type;
+ },
+
+ /**
+ * Stops propagation for current event
+ * @function
+ */
+ stopPropagation: function () {
+ this._isStopped = true;
+ },
+
+ /**
+ * Checks whether the event has been stopped
+ * @function
+ * @returns {boolean}
+ */
+ isStopped: function () {
+ return this._isStopped;
+ },
+
+ /**
+ *
+ * Gets current target of the event
+ * note: It only be available when the event listener is associated with node.
+ * It returns 0 when the listener is associated with fixed priority.
+ *
+ * @function
+ * @returns {cc.Node} The target with which the event associates.
+ */
+ getCurrentTarget: function () {
+ return this._currentTarget;
+ }
+});
+
+//event type
+/**
+ * The type code of Touch event.
+ * @constant
+ * @type {number}
+ */
+cc.Event.TOUCH = 0;
+/**
+ * The type code of Keyboard event.
+ * @constant
+ * @type {number}
+ */
+cc.Event.KEYBOARD = 1;
+/**
+ * The type code of Acceleration event.
+ * @constant
+ * @type {number}
+ */
+cc.Event.ACCELERATION = 2;
+/**
+ * The type code of Mouse event.
+ * @constant
+ * @type {number}
+ */
+cc.Event.MOUSE = 3;
+/**
+ * The type code of UI focus event.
+ * @constant
+ * @type {number}
+ */
+cc.Event.FOCUS = 4;
+/**
+ * The type code of Custom event.
+ * @constant
+ * @type {number}
+ */
+cc.Event.CUSTOM = 6;
+
+/**
+ * The Custom event
+ * @class
+ * @extends cc.Event
+ */
+cc.EventCustom = cc.Event.extend(/** @lends cc.EventCustom# */{
+ _eventName: null,
+ _userData: null, // User data
+
+ ctor: function (eventName) {
+ cc.Event.prototype.ctor.call(this, cc.Event.CUSTOM);
+ this._eventName = eventName;
+ },
+
+ /**
+ * Sets user data
+ * @param {*} data
+ */
+ setUserData: function (data) {
+ this._userData = data;
+ },
+
+ /**
+ * Gets user data
+ * @returns {*}
+ */
+ getUserData: function () {
+ return this._userData;
+ },
+
+ /**
+ * Gets event name
+ * @returns {String}
+ */
+ getEventName: function () {
+ return this._eventName;
+ }
+});
+
+/**
+ * The mouse event
+ * @class
+ * @extends cc.Event
+ */
+cc.EventMouse = cc.Event.extend(/** @lends cc.EventMouse# */{
+ _eventType: 0,
+ _button: 0,
+ _x: 0,
+ _y: 0,
+ _prevX: 0,
+ _prevY: 0,
+ _scrollX: 0,
+ _scrollY: 0,
+
+ ctor: function (eventType) {
+ cc.Event.prototype.ctor.call(this, cc.Event.MOUSE);
+ this._eventType = eventType;
+ },
+
+ /**
+ * Sets scroll data
+ * @param {number} scrollX
+ * @param {number} scrollY
+ */
+ setScrollData: function (scrollX, scrollY) {
+ this._scrollX = scrollX;
+ this._scrollY = scrollY;
+ },
+
+ /**
+ * Returns the x axis scroll value
+ * @returns {number}
+ */
+ getScrollX: function () {
+ return this._scrollX;
+ },
+
+ /**
+ * Returns the y axis scroll value
+ * @returns {number}
+ */
+ getScrollY: function () {
+ return this._scrollY;
+ },
+
+ /**
+ * Sets cursor location
+ * @param {number} x
+ * @param {number} y
+ */
+ setLocation: function (x, y) {
+ this._x = x;
+ this._y = y;
+ },
+
+ /**
+ * Returns cursor location
+ * @return {cc.Point} location
+ */
+ getLocation: function () {
+ return {x: this._x, y: this._y};
+ },
+
+ /**
+ * Returns the current cursor location in screen coordinates
+ * @return {cc.Point}
+ */
+ getLocationInView: function() {
+ return {x: this._x, y: cc.view._designResolutionSize.height - this._y};
+ },
+
+ _setPrevCursor: function (x, y) {
+ this._prevX = x;
+ this._prevY = y;
+ },
+
+ /**
+ * Returns the delta distance from the previous location to current location
+ * @return {cc.Point}
+ */
+ getDelta: function () {
+ return {x: this._x - this._prevX, y: this._y - this._prevY};
+ },
+
+ /**
+ * Returns the X axis delta distance from the previous location to current location
+ * @return {Number}
+ */
+ getDeltaX: function () {
+ return this._x - this._prevX;
+ },
+
+ /**
+ * Returns the Y axis delta distance from the previous location to current location
+ * @return {Number}
+ */
+ getDeltaY: function () {
+ return this._y - this._prevY;
+ },
+
+ /**
+ * Sets mouse button
+ * @param {number} button
+ */
+ setButton: function (button) {
+ this._button = button;
+ },
+
+ /**
+ * Returns mouse button
+ * @returns {number}
+ */
+ getButton: function () {
+ return this._button;
+ },
+
+ /**
+ * Returns location X axis data
+ * @returns {number}
+ */
+ getLocationX: function () {
+ return this._x;
+ },
+
+ /**
+ * Returns location Y axis data
+ * @returns {number}
+ */
+ getLocationY: function () {
+ return this._y;
+ }
+});
+
+//Different types of MouseEvent
+/**
+ * The none event code of mouse event.
+ * @constant
+ * @type {number}
+ */
+cc.EventMouse.NONE = 0;
+/**
+ * The event type code of mouse down event.
+ * @constant
+ * @type {number}
+ */
+cc.EventMouse.DOWN = 1;
+/**
+ * The event type code of mouse up event.
+ * @constant
+ * @type {number}
+ */
+cc.EventMouse.UP = 2;
+/**
+ * The event type code of mouse move event.
+ * @constant
+ * @type {number}
+ */
+cc.EventMouse.MOVE = 3;
+/**
+ * The event type code of mouse scroll event.
+ * @constant
+ * @type {number}
+ */
+cc.EventMouse.SCROLL = 4;
+
+/**
+ * The tag of Mouse left button
+ * @constant
+ * @type {Number}
+ */
+cc.EventMouse.BUTTON_LEFT = 0;
+
+/**
+ * The tag of Mouse right button (The right button number is 2 on browser)
+ * @constant
+ * @type {Number}
+ */
+cc.EventMouse.BUTTON_RIGHT = 2;
+
+/**
+ * The tag of Mouse middle button (The right button number is 1 on browser)
+ * @constant
+ * @type {Number}
+ */
+cc.EventMouse.BUTTON_MIDDLE = 1;
+
+/**
+ * The tag of Mouse button 4
+ * @constant
+ * @type {Number}
+ */
+cc.EventMouse.BUTTON_4 = 3;
+
+/**
+ * The tag of Mouse button 5
+ * @constant
+ * @type {Number}
+ */
+cc.EventMouse.BUTTON_5 = 4;
+
+/**
+ * The tag of Mouse button 6
+ * @constant
+ * @type {Number}
+ */
+cc.EventMouse.BUTTON_6 = 5;
+
+/**
+ * The tag of Mouse button 7
+ * @constant
+ * @type {Number}
+ */
+cc.EventMouse.BUTTON_7 = 6;
+
+/**
+ * The tag of Mouse button 8
+ * @constant
+ * @type {Number}
+ */
+cc.EventMouse.BUTTON_8 = 7;
+
+/**
+ * The touch event
+ * @class
+ * @extends cc.Event
+ */
+cc.EventTouch = cc.Event.extend(/** @lends cc.EventTouch# */{
+ _eventCode: 0,
+ _touches: null,
+
+ ctor: function (arr) {
+ cc.Event.prototype.ctor.call(this, cc.Event.TOUCH);
+ this._touches = arr || [];
+ },
+
+ /**
+ * Returns event code
+ * @returns {number}
+ */
+ getEventCode: function () {
+ return this._eventCode;
+ },
+
+ /**
+ * Returns touches of event
+ * @returns {Array}
+ */
+ getTouches: function () {
+ return this._touches;
+ },
+
+ _setEventCode: function (eventCode) {
+ this._eventCode = eventCode;
+ },
+
+ _setTouches: function (touches) {
+ this._touches = touches;
+ }
+});
+
+/**
+ * The maximum touch numbers
+ * @constant
+ * @type {Number}
+ */
+cc.EventTouch.MAX_TOUCHES = 5;
+
+cc.EventTouch.EventCode = {BEGAN: 0, MOVED: 1, ENDED: 2, CANCELLED: 3};
+
+/**
+ * Focus change event for UI widget
+ * @class
+ * @extends cc.Event
+ */
+cc.EventFocus = cc.Event.extend(/** @lends cc.EventTouch# */{
+ _widgetGetFocus: null,
+ _widgetLoseFocus: null,
+ /**
+ * Constructor function.
+ * @param {ccui.Widget} widgetLoseFocus
+ * @param {ccui.Widget} widgetGetFocus
+ */
+ ctor: function(widgetLoseFocus, widgetGetFocus){
+ cc.Event.prototype.ctor.call(this, cc.Event.FOCUS);
+ this._widgetGetFocus = widgetGetFocus;
+ this._widgetLoseFocus = widgetLoseFocus;
+ }
+});
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEventExtension.js b/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEventExtension.js
new file mode 100644
index 0000000..a14968f
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEventExtension.js
@@ -0,0 +1,126 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The acceleration event
+ * @class
+ * @extends cc.Event
+ */
+cc.EventAcceleration = cc.Event.extend(/** @lends cc.EventAcceleration# */{
+ _acc: null,
+ ctor: function (acc) {
+ cc.Event.prototype.ctor.call(this, cc.Event.ACCELERATION);
+ this._acc = acc;
+ }
+});
+
+/**
+ * The keyboard event
+ * @class
+ * @extends cc.Event
+ */
+cc.EventKeyboard = cc.Event.extend(/** @lends cc.EventKeyboard# */{
+ _keyCode: 0,
+ _isPressed: false,
+ ctor: function (keyCode, isPressed) {
+ cc.Event.prototype.ctor.call(this, cc.Event.KEYBOARD);
+ this._keyCode = keyCode;
+ this._isPressed = isPressed;
+ }
+});
+
+
+//Acceleration
+cc._EventListenerAcceleration = cc.EventListener.extend({
+ _onAccelerationEvent: null,
+
+ ctor: function (callback) {
+ this._onAccelerationEvent = callback;
+ var selfPointer = this;
+ var listener = function (event) {
+ selfPointer._onAccelerationEvent(event._acc, event);
+ };
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.ACCELERATION, cc._EventListenerAcceleration.LISTENER_ID, listener);
+ },
+
+ checkAvailable: function () {
+
+ cc.assert(this._onAccelerationEvent, cc._LogInfos._EventListenerAcceleration_checkAvailable);
+
+ return true;
+ },
+
+ clone: function () {
+ return new cc._EventListenerAcceleration(this._onAccelerationEvent);
+ }
+});
+
+cc._EventListenerAcceleration.LISTENER_ID = "__cc_acceleration";
+
+cc._EventListenerAcceleration.create = function (callback) {
+ return new cc._EventListenerAcceleration(callback);
+};
+
+
+//Keyboard
+cc._EventListenerKeyboard = cc.EventListener.extend({
+ onKeyPressed: null,
+ onKeyReleased: null,
+
+ ctor: function () {
+ var selfPointer = this;
+ var listener = function (event) {
+ if (event._isPressed) {
+ if (selfPointer.onKeyPressed)
+ selfPointer.onKeyPressed(event._keyCode, event);
+ } else {
+ if (selfPointer.onKeyReleased)
+ selfPointer.onKeyReleased(event._keyCode, event);
+ }
+ };
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.KEYBOARD, cc._EventListenerKeyboard.LISTENER_ID, listener);
+ },
+
+ clone: function () {
+ var eventListener = new cc._EventListenerKeyboard();
+ eventListener.onKeyPressed = this.onKeyPressed;
+ eventListener.onKeyReleased = this.onKeyReleased;
+ return eventListener;
+ },
+
+ checkAvailable: function () {
+ if (this.onKeyPressed === null && this.onKeyReleased === null) {
+ cc.log(cc._LogInfos._EventListenerKeyboard_checkAvailable);
+ return false;
+ }
+ return true;
+ }
+});
+
+cc._EventListenerKeyboard.LISTENER_ID = "__cc_keyboard";
+
+cc._EventListenerKeyboard.create = function () {
+ return new cc._EventListenerKeyboard();
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEventHelper.js b/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEventHelper.js
new file mode 100644
index 0000000..b005e71
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEventHelper.js
@@ -0,0 +1,138 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2015 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+// The event helper
+cc.EventHelper = function () {
+};
+
+cc.EventHelper.prototype = {
+ constructor: cc.EventHelper,
+
+ apply: function (object) {
+ object.addEventListener = cc.EventHelper.prototype.addEventListener;
+ object.hasEventListener = cc.EventHelper.prototype.hasEventListener;
+ object.removeEventListener = cc.EventHelper.prototype.removeEventListener;
+ object.dispatchEvent = cc.EventHelper.prototype.dispatchEvent;
+ },
+
+ addEventListener: function (type, listener, target) {
+ //check 'type' status, if the status is ready, dispatch event next frame
+ if (type === "load" && this._textureLoaded) { //only load event checked.
+ setTimeout(function () {
+ listener.call(target);
+ }, 0);
+ return;
+ }
+
+ if (this._listeners === undefined)
+ this._listeners = {};
+
+ var listeners = this._listeners;
+ if (listeners[type] === undefined)
+ listeners[type] = [];
+
+ if (!this.hasEventListener(type, listener, target))
+ listeners[type].push({callback: listener, eventTarget: target});
+ },
+
+ hasEventListener: function (type, listener, target) {
+ if (this._listeners === undefined)
+ return false;
+
+ var listeners = this._listeners;
+ if (listeners[type] !== undefined) {
+ for (var i = 0, len = listeners.length; i < len; i++) {
+ var selListener = listeners[i];
+ if (selListener.callback === listener && selListener.eventTarget === target)
+ return true;
+ }
+ }
+ return false;
+ },
+
+ removeEventListener: function (type, listener, target) {
+ if (this._listeners === undefined)
+ return;
+
+ var listeners = this._listeners;
+ var listenerArray = listeners[type];
+
+ if (listenerArray !== undefined) {
+ for (var i = 0; i < listenerArray.length;) {
+ var selListener = listenerArray[i];
+ if (selListener.eventTarget === target && selListener.callback === listener)
+ listenerArray.splice(i, 1);
+ else
+ i++
+ }
+ }
+ },
+
+ removeEventTarget: function (type, listener, target) {
+ if (this._listeners === undefined)
+ return;
+
+ var listeners = this._listeners;
+ var listenerArray = listeners[type];
+
+ if (listenerArray !== undefined) {
+ for (var i = 0; i < listenerArray.length;) {
+ var selListener = listenerArray[i];
+ if (selListener.eventTarget === target)
+ listenerArray.splice(i, 1);
+ else
+ i++
+ }
+ }
+ },
+
+ dispatchEvent: function (event, clearAfterDispatch) {
+ if (this._listeners === undefined)
+ return;
+
+ if (clearAfterDispatch == null)
+ clearAfterDispatch = true;
+ var listeners = this._listeners;
+ var listenerArray = listeners[event];
+
+ if (listenerArray !== undefined) {
+ var array = [];
+ var length = listenerArray.length;
+
+ for (var i = 0; i < length; i++) {
+ array[i] = listenerArray[i];
+ }
+
+ for (i = 0; i < length; i++) {
+ array[i].callback.call(array[i].eventTarget, this);
+ }
+
+ if (clearAfterDispatch)
+ listenerArray.length = 0;
+ }
+ }
+};
+
+cc.EventHelper.prototype.apply(cc.game);
diff --git a/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEventListener.js b/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEventListener.js
new file mode 100644
index 0000000..c970c43
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEventListener.js
@@ -0,0 +1,514 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ *
+ * The base class of event listener.
+ * If you need custom listener which with different callback, you need to inherit this class.
+ * For instance, you could refer to EventListenerAcceleration, EventListenerKeyboard,
+ * EventListenerTouchOneByOne, EventListenerCustom.
+ *
+ * @class
+ * @extends cc.Class
+ */
+cc.EventListener = cc.Class.extend(/** @lends cc.EventListener# */{
+ _onEvent: null, // Event callback function
+ _type: 0, // Event listener type
+ _listenerID: null, // Event listener ID
+ _registered: false, // Whether the listener has been added to dispatcher.
+
+ _fixedPriority: 0, // The higher the number, the higher the priority, 0 is for scene graph base priority.
+ _node: null, // scene graph based priority
+ _paused: true, // Whether the listener is paused
+ _isEnabled: true, // Whether the listener is enabled
+
+ /**
+ * Initializes event with type and callback function
+ * @param {number} type
+ * @param {string} listenerID
+ * @param {function} callback
+ */
+ ctor: function (type, listenerID, callback) {
+ this._onEvent = callback;
+ this._type = type || 0;
+ this._listenerID = listenerID || "";
+ },
+
+ /**
+ *
+ * Sets paused state for the listener
+ * The paused state is only used for scene graph priority listeners.
+ * `EventDispatcher::resumeAllEventListenersForTarget(node)` will set the paused state to `true`,
+ * while `EventDispatcher::pauseAllEventListenersForTarget(node)` will set it to `false`.
+ * @note 1) Fixed priority listeners will never get paused. If a fixed priority doesn't want to receive events,
+ * call `setEnabled(false)` instead.
+ * 2) In `Node`'s onEnter and onExit, the `paused state` of the listeners which associated with that node will be automatically updated.
+ *
+ * @param {boolean} paused
+ * @private
+ */
+ _setPaused: function (paused) {
+ this._paused = paused;
+ },
+
+ /**
+ * Checks whether the listener is paused
+ * @returns {boolean}
+ * @private
+ */
+ _isPaused: function () {
+ return this._paused;
+ },
+
+ /**
+ * Marks the listener was registered by EventDispatcher
+ * @param {boolean} registered
+ * @private
+ */
+ _setRegistered: function (registered) {
+ this._registered = registered;
+ },
+
+ /**
+ * Checks whether the listener was registered by EventDispatcher
+ * @returns {boolean}
+ * @private
+ */
+ _isRegistered: function () {
+ return this._registered;
+ },
+
+ /**
+ * Gets the type of this listener
+ * @note It's different from `EventType`, e.g. TouchEvent has two kinds of event listeners - EventListenerOneByOne, EventListenerAllAtOnce
+ * @returns {number}
+ * @private
+ */
+ _getType: function () {
+ return this._type;
+ },
+
+ /**
+ * Gets the listener ID of this listener
+ * When event is being dispatched, listener ID is used as key for searching listeners according to event type.
+ * @returns {string}
+ * @private
+ */
+ _getListenerID: function () {
+ return this._listenerID;
+ },
+
+ /**
+ * Sets the fixed priority for this listener
+ * @note This method is only used for `fixed priority listeners`, it needs to access a non-zero value. 0 is reserved for scene graph priority listeners
+ * @param {number} fixedPriority
+ * @private
+ */
+ _setFixedPriority: function (fixedPriority) {
+ this._fixedPriority = fixedPriority;
+ },
+
+ /**
+ * Gets the fixed priority of this listener
+ * @returns {number} 0 if it's a scene graph priority listener, non-zero for fixed priority listener
+ * @private
+ */
+ _getFixedPriority: function () {
+ return this._fixedPriority;
+ },
+
+ /**
+ * Sets scene graph priority for this listener
+ * @param {cc.Node} node
+ * @private
+ */
+ _setSceneGraphPriority: function (node) {
+ this._node = node;
+ },
+
+ /**
+ * Gets scene graph priority of this listener
+ * @returns {cc.Node} if it's a fixed priority listener, non-null for scene graph priority listener
+ * @private
+ */
+ _getSceneGraphPriority: function () {
+ return this._node;
+ },
+
+ /**
+ * Checks whether the listener is available.
+ * @returns {boolean}
+ */
+ checkAvailable: function () {
+ return this._onEvent !== null;
+ },
+
+ /**
+ * Clones the listener, its subclasses have to override this method.
+ * @returns {cc.EventListener}
+ */
+ clone: function () {
+ return null;
+ },
+
+ /**
+ * Enables or disables the listener
+ * @note Only listeners with `enabled` state will be able to receive events.
+ * When an listener was initialized, it's enabled by default.
+ * An event listener can receive events when it is enabled and is not paused.
+ * paused state is always false when it is a fixed priority listener.
+ * @param {boolean} enabled
+ */
+ setEnabled: function(enabled){
+ this._isEnabled = enabled;
+ },
+
+ /**
+ * Checks whether the listener is enabled
+ * @returns {boolean}
+ */
+ isEnabled: function(){
+ return this._isEnabled;
+ },
+
+ /**
+ * Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
+ * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
+ * This is a hack, and should be removed once JSB fixes the retain/release bug
+ * You will need to retain an object if you created a listener and haven't added it any target node during the same frame.
+ * Otherwise, JSB's native autorelease pool will consider this object a useless one and release it directly,
+ * when you want to use it later, a "Invalid Native Object" error will be raised.
+ * The retain function can increase a reference count for the native object to avoid it being released,
+ * you need to manually invoke release function when you think this object is no longer needed, otherwise, there will be memory learks.
+ * retain and release function call should be paired in developer's game code.
+ * @function
+ * @see cc.EventListener#release
+ */
+ retain:function () {
+ },
+ /**
+ * Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
+ * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
+ * This is a hack, and should be removed once JSB fixes the retain/release bug
+ * You will need to retain an object if you created a listener and haven't added it any target node during the same frame.
+ * Otherwise, JSB's native autorelease pool will consider this object a useless one and release it directly,
+ * when you want to use it later, a "Invalid Native Object" error will be raised.
+ * The retain function can increase a reference count for the native object to avoid it being released,
+ * you need to manually invoke release function when you think this object is no longer needed, otherwise, there will be memory learks.
+ * retain and release function call should be paired in developer's game code.
+ * @function
+ * @see cc.EventListener#retain
+ */
+ release:function () {
+ }
+});
+
+// event listener type
+/**
+ * The type code of unknown event listener.
+ * @constant
+ * @type {number}
+ */
+cc.EventListener.UNKNOWN = 0;
+/**
+ * The type code of one by one touch event listener.
+ * @constant
+ * @type {number}
+ */
+cc.EventListener.TOUCH_ONE_BY_ONE = 1;
+/**
+ * The type code of all at once touch event listener.
+ * @constant
+ * @type {number}
+ */
+cc.EventListener.TOUCH_ALL_AT_ONCE = 2;
+/**
+ * The type code of keyboard event listener.
+ * @constant
+ * @type {number}
+ */
+cc.EventListener.KEYBOARD = 3;
+/**
+ * The type code of mouse event listener.
+ * @constant
+ * @type {number}
+ */
+cc.EventListener.MOUSE = 4;
+/**
+ * The type code of acceleration event listener.
+ * @constant
+ * @type {number}
+ */
+cc.EventListener.ACCELERATION = 6;
+/**
+ * The type code of Focus change event listener.
+ * @constant
+ * @type {number}
+ */
+cc.EventListener.FOCUS = 7;
+/**
+ * The type code of custom event listener.
+ * @constant
+ * @type {number}
+ */
+cc.EventListener.CUSTOM = 8;
+
+cc._EventListenerCustom = cc.EventListener.extend({
+ _onCustomEvent: null,
+ ctor: function (listenerId, callback, target) {
+ this._onCustomEvent = callback;
+ this._target = target;
+
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.CUSTOM, listenerId, this._callback);
+ },
+
+ _callback: function (event) {
+ if (this._onCustomEvent !== null)
+ this._onCustomEvent.call(this._target, event);
+ },
+
+ checkAvailable: function () {
+ return (cc.EventListener.prototype.checkAvailable.call(this) && this._onCustomEvent !== null);
+ },
+
+ clone: function () {
+ return new cc._EventListenerCustom(this._listenerID, this._onCustomEvent);
+ }
+});
+
+cc._EventListenerCustom.create = function (eventName, callback) {
+ return new cc._EventListenerCustom(eventName, callback);
+};
+
+cc._EventListenerMouse = cc.EventListener.extend({
+ onMouseDown: null,
+ onMouseUp: null,
+ onMouseMove: null,
+ onMouseScroll: null,
+
+ ctor: function () {
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.MOUSE, cc._EventListenerMouse.LISTENER_ID, this._callback);
+ },
+
+ _callback: function (event) {
+ var eventType = cc.EventMouse;
+ switch (event._eventType) {
+ case eventType.DOWN:
+ if (this.onMouseDown)
+ this.onMouseDown(event);
+ break;
+ case eventType.UP:
+ if (this.onMouseUp)
+ this.onMouseUp(event);
+ break;
+ case eventType.MOVE:
+ if (this.onMouseMove)
+ this.onMouseMove(event);
+ break;
+ case eventType.SCROLL:
+ if (this.onMouseScroll)
+ this.onMouseScroll(event);
+ break;
+ default:
+ break;
+ }
+ },
+
+ clone: function () {
+ var eventListener = new cc._EventListenerMouse();
+ eventListener.onMouseDown = this.onMouseDown;
+ eventListener.onMouseUp = this.onMouseUp;
+ eventListener.onMouseMove = this.onMouseMove;
+ eventListener.onMouseScroll = this.onMouseScroll;
+ return eventListener;
+ },
+
+ checkAvailable: function () {
+ return true;
+ }
+});
+
+cc._EventListenerMouse.LISTENER_ID = "__cc_mouse";
+
+cc._EventListenerMouse.create = function () {
+ return new cc._EventListenerMouse();
+};
+
+cc._EventListenerTouchOneByOne = cc.EventListener.extend({
+ _claimedTouches: null,
+ swallowTouches: false,
+ onTouchBegan: null,
+ onTouchMoved: null,
+ onTouchEnded: null,
+ onTouchCancelled: null,
+
+ ctor: function () {
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.TOUCH_ONE_BY_ONE, cc._EventListenerTouchOneByOne.LISTENER_ID, null);
+ this._claimedTouches = [];
+ },
+
+ setSwallowTouches: function (needSwallow) {
+ this.swallowTouches = needSwallow;
+ },
+
+ isSwallowTouches: function(){
+ return this.swallowTouches;
+ },
+
+ clone: function () {
+ var eventListener = new cc._EventListenerTouchOneByOne();
+ eventListener.onTouchBegan = this.onTouchBegan;
+ eventListener.onTouchMoved = this.onTouchMoved;
+ eventListener.onTouchEnded = this.onTouchEnded;
+ eventListener.onTouchCancelled = this.onTouchCancelled;
+ eventListener.swallowTouches = this.swallowTouches;
+ return eventListener;
+ },
+
+ checkAvailable: function () {
+ if(!this.onTouchBegan){
+ cc.log(cc._LogInfos._EventListenerTouchOneByOne_checkAvailable);
+ return false;
+ }
+ return true;
+ }
+});
+
+cc._EventListenerTouchOneByOne.LISTENER_ID = "__cc_touch_one_by_one";
+
+cc._EventListenerTouchOneByOne.create = function () {
+ return new cc._EventListenerTouchOneByOne();
+};
+
+cc._EventListenerTouchAllAtOnce = cc.EventListener.extend({
+ onTouchesBegan: null,
+ onTouchesMoved: null,
+ onTouchesEnded: null,
+ onTouchesCancelled: null,
+
+ ctor: function(){
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.TOUCH_ALL_AT_ONCE, cc._EventListenerTouchAllAtOnce.LISTENER_ID, null);
+ },
+
+ clone: function(){
+ var eventListener = new cc._EventListenerTouchAllAtOnce();
+ eventListener.onTouchesBegan = this.onTouchesBegan;
+ eventListener.onTouchesMoved = this.onTouchesMoved;
+ eventListener.onTouchesEnded = this.onTouchesEnded;
+ eventListener.onTouchesCancelled = this.onTouchesCancelled;
+ return eventListener;
+ },
+
+ checkAvailable: function(){
+ if (this.onTouchesBegan === null && this.onTouchesMoved === null
+ && this.onTouchesEnded === null && this.onTouchesCancelled === null) {
+ cc.log(cc._LogInfos._EventListenerTouchAllAtOnce_checkAvailable);
+ return false;
+ }
+ return true;
+ }
+});
+
+cc._EventListenerTouchAllAtOnce.LISTENER_ID = "__cc_touch_all_at_once";
+
+cc._EventListenerTouchAllAtOnce.create = function(){
+ return new cc._EventListenerTouchAllAtOnce();
+};
+
+/**
+ * Create a EventListener object by json object
+ * @function
+ * @static
+ * @param {object} argObj a json object
+ * @returns {cc.EventListener}
+ * todo: It should be the direct use new
+ * @example
+ * cc.EventListener.create({
+ * event: cc.EventListener.TOUCH_ONE_BY_ONE,
+ * swallowTouches: true,
+ * onTouchBegan: function (touch, event) {
+ * //do something
+ * return true;
+ * }
+ * });
+ */
+cc.EventListener.create = function(argObj){
+
+ cc.assert(argObj&&argObj.event, cc._LogInfos.EventListener_create);
+
+ var listenerType = argObj.event;
+ delete argObj.event;
+
+ var listener = null;
+ if(listenerType === cc.EventListener.TOUCH_ONE_BY_ONE)
+ listener = new cc._EventListenerTouchOneByOne();
+ else if(listenerType === cc.EventListener.TOUCH_ALL_AT_ONCE)
+ listener = new cc._EventListenerTouchAllAtOnce();
+ else if(listenerType === cc.EventListener.MOUSE)
+ listener = new cc._EventListenerMouse();
+ else if(listenerType === cc.EventListener.CUSTOM){
+ listener = new cc._EventListenerCustom(argObj.eventName, argObj.callback);
+ delete argObj.eventName;
+ delete argObj.callback;
+ } else if(listenerType === cc.EventListener.KEYBOARD)
+ listener = new cc._EventListenerKeyboard();
+ else if(listenerType === cc.EventListener.ACCELERATION){
+ listener = new cc._EventListenerAcceleration(argObj.callback);
+ delete argObj.callback;
+ } else if(listenerType === cc.EventListener.FOCUS)
+ listener = new cc._EventListenerFocus();
+
+ for(var key in argObj) {
+ listener[key] = argObj[key];
+ }
+
+ return listener;
+};
+
+cc._EventListenerFocus = cc.EventListener.extend({
+ clone: function(){
+ var listener = new cc._EventListenerFocus();
+ listener.onFocusChanged = this.onFocusChanged;
+ return listener;
+ },
+ checkAvailable: function(){
+ if(!this.onFocusChanged){
+ cc.log("Invalid EventListenerFocus!");
+ return false;
+ }
+ return true;
+ },
+ onFocusChanged: null,
+ ctor: function(){
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.FOCUS, cc._EventListenerFocus.LISTENER_ID, this._callback);
+ },
+ _callback: function (event) {
+ if (this.onFocusChanged) {
+ this.onFocusChanged(event._widgetLoseFocus, event._widgetGetFocus);
+ }
+ }
+});
+
+cc._EventListenerFocus.LISTENER_ID = "__cc_focus_event";
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEventManager.js b/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEventManager.js
new file mode 100644
index 0000000..7f54f03
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCEventManager.js
@@ -0,0 +1,1016 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2015 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+
+/**
+ * @ignore
+ */
+cc._EventListenerVector = cc.Class.extend({
+ _fixedListeners: null,
+ _sceneGraphListeners: null,
+ gt0Index: 0,
+
+ ctor: function () {
+ this._fixedListeners = [];
+ this._sceneGraphListeners = [];
+ },
+
+ size: function () {
+ return this._fixedListeners.length + this._sceneGraphListeners.length;
+ },
+
+ empty: function () {
+ return (this._fixedListeners.length === 0) && (this._sceneGraphListeners.length === 0);
+ },
+
+ push: function (listener) {
+ if (listener._getFixedPriority() === 0)
+ this._sceneGraphListeners.push(listener);
+ else
+ this._fixedListeners.push(listener);
+ },
+
+ clearSceneGraphListeners: function () {
+ this._sceneGraphListeners.length = 0;
+ },
+
+ clearFixedListeners: function () {
+ this._fixedListeners.length = 0;
+ },
+
+ clear: function () {
+ this._sceneGraphListeners.length = 0;
+ this._fixedListeners.length = 0;
+ },
+
+ getFixedPriorityListeners: function () {
+ return this._fixedListeners;
+ },
+
+ getSceneGraphPriorityListeners: function () {
+ return this._sceneGraphListeners;
+ }
+});
+
+function __getListenerID (event) {
+ var eventType = cc.Event, getType = event._type;
+ if (getType === eventType.ACCELERATION)
+ return cc._EventListenerAcceleration.LISTENER_ID;
+ if (getType === eventType.CUSTOM)
+ return event._eventName;
+ if (getType === eventType.KEYBOARD)
+ return cc._EventListenerKeyboard.LISTENER_ID;
+ if (getType === eventType.MOUSE)
+ return cc._EventListenerMouse.LISTENER_ID;
+ if (getType === eventType.FOCUS)
+ return cc._EventListenerFocus.LISTENER_ID;
+ if (getType === eventType.TOUCH) {
+ // Touch listener is very special, it contains two kinds of listeners, EventListenerTouchOneByOne and EventListenerTouchAllAtOnce.
+ // return UNKNOWN instead.
+ cc.log(cc._LogInfos.__getListenerID);
+ }
+ return "";
+}
+
+/**
+ *
+ * cc.eventManager is a singleton object which manages event listener subscriptions and event dispatching.
+ *
+ * The EventListener list is managed in such way so that event listeners can be added and removed
+ * while events are being dispatched.
+ *
+ * @class
+ * @name cc.eventManager
+ */
+cc.eventManager = /** @lends cc.eventManager# */{
+ //Priority dirty flag
+ DIRTY_NONE: 0,
+ DIRTY_FIXED_PRIORITY: 1 << 0,
+ DIRTY_SCENE_GRAPH_PRIORITY: 1 << 1,
+ DIRTY_ALL: 3,
+
+ _listenersMap: {},
+ _priorityDirtyFlagMap: {},
+ _nodeListenersMap: {},
+ _nodePriorityMap: {},
+ _globalZOrderNodeMap: {},
+ _toAddedListeners: [],
+ _toRemovedListeners: [],
+ _dirtyNodes: [],
+ _inDispatch: 0,
+ _isEnabled: false,
+ _nodePriorityIndex: 0,
+
+ _internalCustomListenerIDs: [cc.game.EVENT_HIDE, cc.game.EVENT_SHOW],
+
+ _setDirtyForNode: function (node) {
+ // Mark the node dirty only when there is an event listener associated with it.
+ if (this._nodeListenersMap[node.__instanceId] != null)
+ this._dirtyNodes.push(node);
+ var _children = node.getChildren();
+ for(var i = 0, len = _children.length; i < len; i++)
+ this._setDirtyForNode(_children[i]);
+ },
+
+ /**
+ * Pauses all listeners which are associated the specified target.
+ * @param {cc.Node} node
+ * @param {Boolean} [recursive=false]
+ */
+ pauseTarget: function (node, recursive) {
+ var listeners = this._nodeListenersMap[node.__instanceId], i, len;
+ if (listeners) {
+ for (i = 0, len = listeners.length; i < len; i++)
+ listeners[i]._setPaused(true);
+ }
+ if (recursive === true) {
+ var locChildren = node.getChildren();
+ for (i = 0, len = locChildren.length; i < len; i++)
+ this.pauseTarget(locChildren[i], true);
+ }
+ },
+
+ /**
+ * Resumes all listeners which are associated the specified target.
+ * @param {cc.Node} node
+ * @param {Boolean} [recursive=false]
+ */
+ resumeTarget: function (node, recursive) {
+ var listeners = this._nodeListenersMap[node.__instanceId], i, len;
+ if (listeners) {
+ for (i = 0, len = listeners.length; i < len; i++)
+ listeners[i]._setPaused(false);
+ }
+ this._setDirtyForNode(node);
+ if (recursive === true) {
+ var locChildren = node.getChildren();
+ for (i = 0, len = locChildren.length; i< len; i++)
+ this.resumeTarget(locChildren[i], true);
+ }
+ },
+
+ _addListener: function (listener) {
+ if (this._inDispatch === 0)
+ this._forceAddEventListener(listener);
+ else
+ this._toAddedListeners.push(listener);
+ },
+
+ _forceAddEventListener: function (listener) {
+ var listenerID = listener._getListenerID();
+ var listeners = this._listenersMap[listenerID];
+ if (!listeners) {
+ listeners = new cc._EventListenerVector();
+ this._listenersMap[listenerID] = listeners;
+ }
+ listeners.push(listener);
+
+ if (listener._getFixedPriority() === 0) {
+ this._setDirty(listenerID, this.DIRTY_SCENE_GRAPH_PRIORITY);
+
+ var node = listener._getSceneGraphPriority();
+ if (node === null)
+ cc.log(cc._LogInfos.eventManager__forceAddEventListener);
+
+ this._associateNodeAndEventListener(node, listener);
+ if (node.isRunning())
+ this.resumeTarget(node);
+ } else
+ this._setDirty(listenerID, this.DIRTY_FIXED_PRIORITY);
+ },
+
+ _getListeners: function (listenerID) {
+ return this._listenersMap[listenerID];
+ },
+
+ _updateDirtyFlagForSceneGraph: function () {
+ if (this._dirtyNodes.length === 0)
+ return;
+
+ var locDirtyNodes = this._dirtyNodes, selListeners, selListener, locNodeListenersMap = this._nodeListenersMap;
+ for (var i = 0, len = locDirtyNodes.length; i < len; i++) {
+ selListeners = locNodeListenersMap[locDirtyNodes[i].__instanceId];
+ if (selListeners) {
+ for (var j = 0, listenersLen = selListeners.length; j < listenersLen; j++) {
+ selListener = selListeners[j];
+ if (selListener)
+ this._setDirty(selListener._getListenerID(), this.DIRTY_SCENE_GRAPH_PRIORITY);
+ }
+ }
+ }
+ this._dirtyNodes.length = 0;
+ },
+
+ _removeAllListenersInVector: function (listenerVector) {
+ if (!listenerVector)
+ return;
+ var selListener;
+ for (var i = 0; i < listenerVector.length;) {
+ selListener = listenerVector[i];
+ selListener._setRegistered(false);
+ if (selListener._getSceneGraphPriority() != null) {
+ this._dissociateNodeAndEventListener(selListener._getSceneGraphPriority(), selListener);
+ selListener._setSceneGraphPriority(null); // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.
+ }
+
+ if (this._inDispatch === 0)
+ cc.arrayRemoveObject(listenerVector, selListener);
+ else
+ ++i;
+ }
+ },
+
+ _removeListenersForListenerID: function (listenerID) {
+ var listeners = this._listenersMap[listenerID], i;
+ if (listeners) {
+ var fixedPriorityListeners = listeners.getFixedPriorityListeners();
+ var sceneGraphPriorityListeners = listeners.getSceneGraphPriorityListeners();
+
+ this._removeAllListenersInVector(sceneGraphPriorityListeners);
+ this._removeAllListenersInVector(fixedPriorityListeners);
+
+ // Remove the dirty flag according the 'listenerID'.
+ // No need to check whether the dispatcher is dispatching event.
+ delete this._priorityDirtyFlagMap[listenerID];
+
+ if (!this._inDispatch) {
+ listeners.clear();
+ }
+ delete this._listenersMap[listenerID];
+ }
+
+ var locToAddedListeners = this._toAddedListeners, listener;
+ for (i = 0; i < locToAddedListeners.length;) {
+ listener = locToAddedListeners[i];
+ if (listener && listener._getListenerID() === listenerID)
+ cc.arrayRemoveObject(locToAddedListeners, listener);
+ else
+ ++i;
+ }
+ },
+
+ _sortEventListeners: function (listenerID) {
+ var dirtyFlag = this.DIRTY_NONE, locFlagMap = this._priorityDirtyFlagMap;
+ if (locFlagMap[listenerID])
+ dirtyFlag = locFlagMap[listenerID];
+
+ if (dirtyFlag !== this.DIRTY_NONE) {
+ // Clear the dirty flag first, if `rootNode` is null, then set its dirty flag of scene graph priority
+ locFlagMap[listenerID] = this.DIRTY_NONE;
+
+ if (dirtyFlag & this.DIRTY_FIXED_PRIORITY)
+ this._sortListenersOfFixedPriority(listenerID);
+
+ if (dirtyFlag & this.DIRTY_SCENE_GRAPH_PRIORITY) {
+ var rootNode = cc.director.getRunningScene();
+ if (rootNode)
+ this._sortListenersOfSceneGraphPriority(listenerID, rootNode);
+ else
+ locFlagMap[listenerID] = this.DIRTY_SCENE_GRAPH_PRIORITY;
+ }
+ }
+ },
+
+ _sortListenersOfSceneGraphPriority: function (listenerID, rootNode) {
+ var listeners = this._getListeners(listenerID);
+ if (!listeners)
+ return;
+
+ var sceneGraphListener = listeners.getSceneGraphPriorityListeners();
+ if (!sceneGraphListener || sceneGraphListener.length === 0)
+ return;
+
+ // Reset priority index
+ this._nodePriorityIndex = 0;
+ this._nodePriorityMap = {};
+
+ this._visitTarget(rootNode, true);
+
+ // After sort: priority < 0, > 0
+ listeners.getSceneGraphPriorityListeners().sort(this._sortEventListenersOfSceneGraphPriorityDes);
+ },
+
+ _sortEventListenersOfSceneGraphPriorityDes: function (l1, l2) {
+ var locNodePriorityMap = cc.eventManager._nodePriorityMap, node1 = l1._getSceneGraphPriority(),
+ node2 = l2._getSceneGraphPriority();
+ if (!l2 || !node2 || !locNodePriorityMap[node2.__instanceId])
+ return -1;
+ else if (!l1 || !node1 || !locNodePriorityMap[node1.__instanceId])
+ return 1;
+ return locNodePriorityMap[l2._getSceneGraphPriority().__instanceId] - locNodePriorityMap[l1._getSceneGraphPriority().__instanceId];
+ },
+
+ _sortListenersOfFixedPriority: function (listenerID) {
+ var listeners = this._listenersMap[listenerID];
+ if (!listeners)
+ return;
+
+ var fixedListeners = listeners.getFixedPriorityListeners();
+ if (!fixedListeners || fixedListeners.length === 0)
+ return;
+ // After sort: priority < 0, > 0
+ fixedListeners.sort(this._sortListenersOfFixedPriorityAsc);
+
+ // FIXME: Should use binary search
+ var index = 0;
+ for (var len = fixedListeners.length; index < len;) {
+ if (fixedListeners[index]._getFixedPriority() >= 0)
+ break;
+ ++index;
+ }
+ listeners.gt0Index = index;
+ },
+
+ _sortListenersOfFixedPriorityAsc: function (l1, l2) {
+ return l1._getFixedPriority() - l2._getFixedPriority();
+ },
+
+ _onUpdateListeners: function (listeners) {
+ var fixedPriorityListeners = listeners.getFixedPriorityListeners();
+ var sceneGraphPriorityListeners = listeners.getSceneGraphPriorityListeners();
+ var i, selListener, idx, toRemovedListeners = this._toRemovedListeners;
+
+ if (sceneGraphPriorityListeners) {
+ for (i = 0; i < sceneGraphPriorityListeners.length;) {
+ selListener = sceneGraphPriorityListeners[i];
+ if (!selListener._isRegistered()) {
+ cc.arrayRemoveObject(sceneGraphPriorityListeners, selListener);
+ // if item in toRemove list, remove it from the list
+ idx = toRemovedListeners.indexOf(selListener);
+ if(idx !== -1)
+ toRemovedListeners.splice(idx, 1);
+ } else
+ ++i;
+ }
+ }
+
+ if (fixedPriorityListeners) {
+ for (i = 0; i < fixedPriorityListeners.length;) {
+ selListener = fixedPriorityListeners[i];
+ if (!selListener._isRegistered()) {
+ cc.arrayRemoveObject(fixedPriorityListeners, selListener);
+ // if item in toRemove list, remove it from the list
+ idx = toRemovedListeners.indexOf(selListener);
+ if(idx !== -1)
+ toRemovedListeners.splice(idx, 1);
+ } else
+ ++i;
+ }
+ }
+
+ if (sceneGraphPriorityListeners && sceneGraphPriorityListeners.length === 0)
+ listeners.clearSceneGraphListeners();
+
+ if (fixedPriorityListeners && fixedPriorityListeners.length === 0)
+ listeners.clearFixedListeners();
+ },
+
+ frameUpdateListeners: function () {
+ var locListenersMap = this._listenersMap, locPriorityDirtyFlagMap = this._priorityDirtyFlagMap;
+ for (var selKey in locListenersMap) {
+ if (locListenersMap[selKey].empty()) {
+ delete locPriorityDirtyFlagMap[selKey];
+ delete locListenersMap[selKey];
+ }
+ }
+
+ var locToAddedListeners = this._toAddedListeners;
+ if (locToAddedListeners.length !== 0) {
+ for (var i = 0, len = locToAddedListeners.length; i < len; i++)
+ this._forceAddEventListener(locToAddedListeners[i]);
+ locToAddedListeners.length = 0;
+ }
+ if (this._toRemovedListeners.length !== 0) {
+ this._cleanToRemovedListeners();
+ }
+ },
+
+ _updateTouchListeners: function (event) {
+ var locInDispatch = this._inDispatch;
+ cc.assert(locInDispatch > 0, cc._LogInfos.EventManager__updateListeners);
+
+ if (locInDispatch > 1)
+ return;
+
+ var listeners;
+ listeners = this._listenersMap[cc._EventListenerTouchOneByOne.LISTENER_ID];
+ if (listeners) {
+ this._onUpdateListeners(listeners);
+ }
+ listeners = this._listenersMap[cc._EventListenerTouchAllAtOnce.LISTENER_ID];
+ if (listeners) {
+ this._onUpdateListeners(listeners);
+ }
+
+ cc.assert(locInDispatch === 1, cc._LogInfos.EventManager__updateListeners_2);
+
+ var locToAddedListeners = this._toAddedListeners;
+ if (locToAddedListeners.length !== 0) {
+ for (var i = 0, len = locToAddedListeners.length; i < len; i++)
+ this._forceAddEventListener(locToAddedListeners[i]);
+ locToAddedListeners.length = 0;
+ }
+ if (this._toRemovedListeners.length !== 0) {
+ this._cleanToRemovedListeners();
+ }
+ },
+
+ //Remove all listeners in _toRemoveListeners list and cleanup
+ _cleanToRemovedListeners: function () {
+ var toRemovedListeners = this._toRemovedListeners;
+ for (var i = 0; i < toRemovedListeners.length; i++) {
+ var selListener = toRemovedListeners[i];
+ var listeners = this._listenersMap[selListener._getListenerID()];
+ if (!listeners)
+ continue;
+
+ var idx, fixedPriorityListeners = listeners.getFixedPriorityListeners(),
+ sceneGraphPriorityListeners = listeners.getSceneGraphPriorityListeners();
+
+ if (sceneGraphPriorityListeners) {
+ idx = sceneGraphPriorityListeners.indexOf(selListener);
+ if (idx !== -1) {
+ sceneGraphPriorityListeners.splice(idx, 1);
+ }
+ }
+ if (fixedPriorityListeners) {
+ idx = fixedPriorityListeners.indexOf(selListener);
+ if (idx !== -1) {
+ fixedPriorityListeners.splice(idx, 1);
+ }
+ }
+ }
+ toRemovedListeners.length = 0;
+ },
+
+ _onTouchEventCallback: function (listener, argsObj) {
+ // Skip if the listener was removed.
+ if (!listener._isRegistered)
+ return false;
+
+ var event = argsObj.event, selTouch = argsObj.selTouch;
+ event._setCurrentTarget(listener._node);
+
+ var isClaimed = false, removedIdx;
+ var getCode = event.getEventCode(), eventCode = cc.EventTouch.EventCode;
+ if (getCode === eventCode.BEGAN) {
+ if (listener.onTouchBegan) {
+ isClaimed = listener.onTouchBegan(selTouch, event);
+ if (isClaimed && listener._registered)
+ listener._claimedTouches.push(selTouch);
+ }
+ } else if (listener._claimedTouches.length > 0
+ && ((removedIdx = listener._claimedTouches.indexOf(selTouch)) !== -1)) {
+ isClaimed = true;
+ if (getCode === eventCode.MOVED && listener.onTouchMoved) {
+ listener.onTouchMoved(selTouch, event);
+ } else if (getCode === eventCode.ENDED) {
+ if (listener.onTouchEnded)
+ listener.onTouchEnded(selTouch, event);
+ if (listener._registered)
+ listener._claimedTouches.splice(removedIdx, 1);
+ } else if (getCode === eventCode.CANCELLED) {
+ if (listener.onTouchCancelled)
+ listener.onTouchCancelled(selTouch, event);
+ if (listener._registered)
+ listener._claimedTouches.splice(removedIdx, 1);
+ }
+ }
+
+ // If the event was stopped, return directly.
+ if (event.isStopped()) {
+ cc.eventManager._updateTouchListeners(event);
+ return true;
+ }
+
+ if (isClaimed && listener._registered && listener.swallowTouches) {
+ if (argsObj.needsMutableSet)
+ argsObj.touches.splice(selTouch, 1);
+ return true;
+ }
+ return false;
+ },
+
+ _dispatchTouchEvent: function (event) {
+ this._sortEventListeners(cc._EventListenerTouchOneByOne.LISTENER_ID);
+ this._sortEventListeners(cc._EventListenerTouchAllAtOnce.LISTENER_ID);
+
+ var oneByOneListeners = this._getListeners(cc._EventListenerTouchOneByOne.LISTENER_ID);
+ var allAtOnceListeners = this._getListeners(cc._EventListenerTouchAllAtOnce.LISTENER_ID);
+
+ // If there aren't any touch listeners, return directly.
+ if (null === oneByOneListeners && null === allAtOnceListeners)
+ return;
+
+ var originalTouches = event.getTouches(), mutableTouches = cc.copyArray(originalTouches);
+ var oneByOneArgsObj = {event: event, needsMutableSet: (oneByOneListeners && allAtOnceListeners), touches: mutableTouches, selTouch: null};
+
+ //
+ // process the target handlers 1st
+ //
+ if (oneByOneListeners) {
+ for (var i = 0; i < originalTouches.length; i++) {
+ oneByOneArgsObj.selTouch = originalTouches[i];
+ this._dispatchEventToListeners(oneByOneListeners, this._onTouchEventCallback, oneByOneArgsObj);
+ if (event.isStopped())
+ return;
+ }
+ }
+
+ //
+ // process standard handlers 2nd
+ //
+ if (allAtOnceListeners && mutableTouches.length > 0) {
+ this._dispatchEventToListeners(allAtOnceListeners, this._onTouchesEventCallback, {event: event, touches: mutableTouches});
+ if (event.isStopped())
+ return;
+ }
+ this._updateTouchListeners(event);
+ },
+
+ _onTouchesEventCallback: function (listener, callbackParams) {
+ // Skip if the listener was removed.
+ if (!listener._registered)
+ return false;
+
+ var eventCode = cc.EventTouch.EventCode, event = callbackParams.event, touches = callbackParams.touches, getCode = event.getEventCode();
+ event._setCurrentTarget(listener._node);
+ if (getCode === eventCode.BEGAN && listener.onTouchesBegan)
+ listener.onTouchesBegan(touches, event);
+ else if (getCode === eventCode.MOVED && listener.onTouchesMoved)
+ listener.onTouchesMoved(touches, event);
+ else if (getCode === eventCode.ENDED && listener.onTouchesEnded)
+ listener.onTouchesEnded(touches, event);
+ else if (getCode === eventCode.CANCELLED && listener.onTouchesCancelled)
+ listener.onTouchesCancelled(touches, event);
+
+ // If the event was stopped, return directly.
+ if (event.isStopped()) {
+ cc.eventManager._updateTouchListeners(event);
+ return true;
+ }
+ return false;
+ },
+
+ _associateNodeAndEventListener: function (node, listener) {
+ var listeners = this._nodeListenersMap[node.__instanceId];
+ if (!listeners) {
+ listeners = [];
+ this._nodeListenersMap[node.__instanceId] = listeners;
+ }
+ listeners.push(listener);
+ },
+
+ _dissociateNodeAndEventListener: function (node, listener) {
+ var listeners = this._nodeListenersMap[node.__instanceId];
+ if (listeners) {
+ cc.arrayRemoveObject(listeners, listener);
+ if (listeners.length === 0)
+ delete this._nodeListenersMap[node.__instanceId];
+ }
+ },
+
+ _dispatchEventToListeners: function (listeners, onEvent, eventOrArgs) {
+ var shouldStopPropagation = false;
+ var fixedPriorityListeners = listeners.getFixedPriorityListeners();
+ var sceneGraphPriorityListeners = listeners.getSceneGraphPriorityListeners();
+
+ var i = 0, j, selListener;
+ if (fixedPriorityListeners) { // priority < 0
+ if (fixedPriorityListeners.length !== 0) {
+ for (; i < listeners.gt0Index; ++i) {
+ selListener = fixedPriorityListeners[i];
+ if (selListener.isEnabled() && !selListener._isPaused() && selListener._isRegistered() && onEvent(selListener, eventOrArgs)) {
+ shouldStopPropagation = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (sceneGraphPriorityListeners && !shouldStopPropagation) { // priority == 0, scene graph priority
+ for (j = 0; j < sceneGraphPriorityListeners.length; j++) {
+ selListener = sceneGraphPriorityListeners[j];
+ if (selListener.isEnabled() && !selListener._isPaused() && selListener._isRegistered() && onEvent(selListener, eventOrArgs)) {
+ shouldStopPropagation = true;
+ break;
+ }
+ }
+ }
+
+ if (fixedPriorityListeners && !shouldStopPropagation) { // priority > 0
+ for (; i < fixedPriorityListeners.length; ++i) {
+ selListener = fixedPriorityListeners[i];
+ if (selListener.isEnabled() && !selListener._isPaused() && selListener._isRegistered() && onEvent(selListener, eventOrArgs)) {
+ shouldStopPropagation = true;
+ break;
+ }
+ }
+ }
+ },
+
+ _setDirty: function (listenerID, flag) {
+ var locDirtyFlagMap = this._priorityDirtyFlagMap;
+ if (locDirtyFlagMap[listenerID] == null)
+ locDirtyFlagMap[listenerID] = flag;
+ else
+ locDirtyFlagMap[listenerID] = flag | locDirtyFlagMap[listenerID];
+ },
+
+ _visitTarget: function (node, isRootNode) {
+ var children = node.getChildren(), i = 0;
+ var childrenCount = children.length, locGlobalZOrderNodeMap = this._globalZOrderNodeMap, locNodeListenersMap = this._nodeListenersMap;
+
+ if (childrenCount > 0) {
+ var child;
+ // visit children zOrder < 0
+ for (; i < childrenCount; i++) {
+ child = children[i];
+ if (child && child.getLocalZOrder() < 0)
+ this._visitTarget(child, false);
+ else
+ break;
+ }
+
+ if (locNodeListenersMap[node.__instanceId] != null) {
+ if (!locGlobalZOrderNodeMap[node.getGlobalZOrder()])
+ locGlobalZOrderNodeMap[node.getGlobalZOrder()] = [];
+ locGlobalZOrderNodeMap[node.getGlobalZOrder()].push(node.__instanceId);
+ }
+
+ for (; i < childrenCount; i++) {
+ child = children[i];
+ if (child)
+ this._visitTarget(child, false);
+ }
+ } else {
+ if (locNodeListenersMap[node.__instanceId] != null) {
+ if (!locGlobalZOrderNodeMap[node.getGlobalZOrder()])
+ locGlobalZOrderNodeMap[node.getGlobalZOrder()] = [];
+ locGlobalZOrderNodeMap[node.getGlobalZOrder()].push(node.__instanceId);
+ }
+ }
+
+ if (isRootNode) {
+ var globalZOrders = [];
+ for (var selKey in locGlobalZOrderNodeMap)
+ globalZOrders.push(selKey);
+
+ globalZOrders.sort(this._sortNumberAsc);
+
+ var zOrdersLen = globalZOrders.length, selZOrders, j, locNodePriorityMap = this._nodePriorityMap;
+ for (i = 0; i < zOrdersLen; i++) {
+ selZOrders = locGlobalZOrderNodeMap[globalZOrders[i]];
+ for (j = 0; j < selZOrders.length; j++)
+ locNodePriorityMap[selZOrders[j]] = ++this._nodePriorityIndex;
+ }
+ this._globalZOrderNodeMap = {};
+ }
+ },
+
+ _sortNumberAsc: function (a, b) {
+ return a - b;
+ },
+
+ /**
+ *
+ * Adds a event listener for a specified event.
+ * if the parameter "nodeOrPriority" is a node, it means to add a event listener for a specified event with the priority of scene graph.
+ * if the parameter "nodeOrPriority" is a Number, it means to add a event listener for a specified event with the fixed priority.
+ *
+ * @param {cc.EventListener|Object} listener The listener of a specified event or a object of some event parameters.
+ * @param {cc.Node|Number} nodeOrPriority The priority of the listener is based on the draw order of this node or fixedPriority The fixed priority of the listener.
+ * @note The priority of scene graph will be fixed value 0. So the order of listener item in the vector will be ' <0, scene graph (0 priority), >0'.
+ * A lower priority will be called before the ones that have a higher value. 0 priority is forbidden for fixed priority since it's used for scene graph based priority.
+ * The listener must be a cc.EventListener object when adding a fixed priority listener, because we can't remove a fixed priority listener without the listener handler,
+ * except calls removeAllListeners().
+ * @return {cc.EventListener} Return the listener. Needed in order to remove the event from the dispatcher.
+ */
+ addListener: function (listener, nodeOrPriority) {
+ cc.assert(listener && nodeOrPriority, cc._LogInfos.eventManager_addListener_2);
+ if (!(listener instanceof cc.EventListener)) {
+ cc.assert(!cc.isNumber(nodeOrPriority), cc._LogInfos.eventManager_addListener_3);
+ listener = cc.EventListener.create(listener);
+ } else {
+ if (listener._isRegistered()) {
+ cc.log(cc._LogInfos.eventManager_addListener_4);
+ return;
+ }
+ }
+
+ if (!listener.checkAvailable())
+ return;
+
+ if (cc.isNumber(nodeOrPriority)) {
+ if (nodeOrPriority === 0) {
+ cc.log(cc._LogInfos.eventManager_addListener);
+ return;
+ }
+
+ listener._setSceneGraphPriority(null);
+ listener._setFixedPriority(nodeOrPriority);
+ listener._setRegistered(true);
+ listener._setPaused(false);
+ this._addListener(listener);
+ } else {
+ listener._setSceneGraphPriority(nodeOrPriority);
+ listener._setFixedPriority(0);
+ listener._setRegistered(true);
+ this._addListener(listener);
+ }
+
+ return listener;
+ },
+
+ /**
+ * Adds a Custom event listener. It will use a fixed priority of 1.
+ * @param {string} eventName
+ * @param {function} callback
+ * @return {cc.EventListener} the generated event. Needed in order to remove the event from the dispatcher
+ */
+ addCustomListener: function (eventName, callback, target) {
+ var listener = new cc._EventListenerCustom(eventName, callback, target);
+ this.addListener(listener, 1);
+ return listener;
+ },
+
+ /**
+ * Remove a listener
+ * @param {cc.EventListener} listener an event listener or a registered node target
+ */
+ removeListener: function (listener) {
+ if (listener == null)
+ return;
+
+ var isFound, locListener = this._listenersMap;
+ for (var selKey in locListener) {
+ var listeners = locListener[selKey];
+ var fixedPriorityListeners = listeners.getFixedPriorityListeners(), sceneGraphPriorityListeners = listeners.getSceneGraphPriorityListeners();
+
+ isFound = this._removeListenerInVector(sceneGraphPriorityListeners, listener);
+ if (isFound){
+ // fixed #4160: Dirty flag need to be updated after listeners were removed.
+ this._setDirty(listener._getListenerID(), this.DIRTY_SCENE_GRAPH_PRIORITY);
+ }else{
+ isFound = this._removeListenerInVector(fixedPriorityListeners, listener);
+ if (isFound)
+ this._setDirty(listener._getListenerID(), this.DIRTY_FIXED_PRIORITY);
+ }
+
+ if (listeners.empty()) {
+ delete this._priorityDirtyFlagMap[listener._getListenerID()];
+ delete locListener[selKey];
+ }
+
+ if (isFound)
+ break;
+ }
+
+ if (!isFound) {
+ var locToAddedListeners = this._toAddedListeners;
+ for (var i = 0, len = locToAddedListeners.length; i < len; i++) {
+ var selListener = locToAddedListeners[i];
+ if (selListener === listener) {
+ cc.arrayRemoveObject(locToAddedListeners, selListener);
+ selListener._setRegistered(false);
+ break;
+ }
+ }
+ }
+ },
+
+ _removeListenerInCallback: function (listeners, callback) {
+ if (listeners == null)
+ return false;
+
+ for (var i = 0, len = listeners.length; i < len; i++) {
+ var selListener = listeners[i];
+ if (selListener._onCustomEvent === callback || selListener._onEvent === callback) {
+ selListener._setRegistered(false);
+ if (selListener._getSceneGraphPriority() != null) {
+ this._dissociateNodeAndEventListener(selListener._getSceneGraphPriority(), selListener);
+ selListener._setSceneGraphPriority(null); // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.
+ }
+
+ if (this._inDispatch === 0)
+ cc.arrayRemoveObject(listeners, selListener);
+ return true;
+ }
+ }
+ return false;
+ },
+
+ _removeListenerInVector: function (listeners, listener) {
+ if (listeners == null)
+ return false;
+
+ for (var i = 0, len = listeners.length; i < len; i++) {
+ var selListener = listeners[i];
+ if (selListener === listener) {
+ selListener._setRegistered(false);
+ if (selListener._getSceneGraphPriority() != null) {
+ this._dissociateNodeAndEventListener(selListener._getSceneGraphPriority(), selListener);
+ selListener._setSceneGraphPriority(null); // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.
+ }
+
+ if (this._inDispatch === 0)
+ cc.arrayRemoveObject(listeners, selListener);
+ else
+ this._toRemovedListeners.push(selListener);
+ return true;
+ }
+ }
+ return false;
+ },
+
+ /**
+ * Removes all listeners with the same event listener type or removes all listeners of a node
+ * @param {Number|cc.Node} listenerType listenerType or a node
+ * @param {Boolean} [recursive=false]
+ */
+ removeListeners: function (listenerType, recursive) {
+ var _t = this;
+ if (listenerType instanceof cc.Node) {
+ // Ensure the node is removed from these immediately also.
+ // Don't want any dangling pointers or the possibility of dealing with deleted objects..
+ delete _t._nodePriorityMap[listenerType.__instanceId];
+ cc.arrayRemoveObject(_t._dirtyNodes, listenerType);
+ var listeners = _t._nodeListenersMap[listenerType.__instanceId], i;
+ if (listeners) {
+ var listenersCopy = cc.copyArray(listeners);
+ for (i = 0; i < listenersCopy.length; i++)
+ _t.removeListener(listenersCopy[i]);
+ listenersCopy.length = 0;
+ }
+
+ // Bug fix: ensure there are no references to the node in the list of listeners to be added.
+ // If we find any listeners associated with the destroyed node in this list then remove them.
+ // This is to catch the scenario where the node gets destroyed before it's listener
+ // is added into the event dispatcher fully. This could happen if a node registers a listener
+ // and gets destroyed while we are dispatching an event (touch etc.)
+ var locToAddedListeners = _t._toAddedListeners;
+ for (i = 0; i < locToAddedListeners.length; ) {
+ var listener = locToAddedListeners[i];
+ if (listener._getSceneGraphPriority() === listenerType) {
+ listener._setSceneGraphPriority(null); // Ensure no dangling ptr to the target node.
+ listener._setRegistered(false);
+ locToAddedListeners.splice(i, 1);
+ } else
+ ++i;
+ }
+
+ if (recursive === true) {
+ var locChildren = listenerType.getChildren(), len;
+ for (i = 0, len = locChildren.length; i< len; i++)
+ _t.removeListeners(locChildren[i], true);
+ }
+ } else {
+ if (listenerType === cc.EventListener.TOUCH_ONE_BY_ONE)
+ _t._removeListenersForListenerID(cc._EventListenerTouchOneByOne.LISTENER_ID);
+ else if (listenerType === cc.EventListener.TOUCH_ALL_AT_ONCE)
+ _t._removeListenersForListenerID(cc._EventListenerTouchAllAtOnce.LISTENER_ID);
+ else if (listenerType === cc.EventListener.MOUSE)
+ _t._removeListenersForListenerID(cc._EventListenerMouse.LISTENER_ID);
+ else if (listenerType === cc.EventListener.ACCELERATION)
+ _t._removeListenersForListenerID(cc._EventListenerAcceleration.LISTENER_ID);
+ else if (listenerType === cc.EventListener.KEYBOARD)
+ _t._removeListenersForListenerID(cc._EventListenerKeyboard.LISTENER_ID);
+ else
+ cc.log(cc._LogInfos.eventManager_removeListeners);
+ }
+ },
+
+ /**
+ * Removes all custom listeners with the same event name
+ * @param {string} customEventName
+ */
+ removeCustomListeners: function (customEventName) {
+ this._removeListenersForListenerID(customEventName);
+ },
+
+ /**
+ * Removes all listeners
+ */
+ removeAllListeners: function () {
+ var locListeners = this._listenersMap, locInternalCustomEventIDs = this._internalCustomListenerIDs;
+ for (var selKey in locListeners) {
+ if (locInternalCustomEventIDs.indexOf(selKey) === -1)
+ this._removeListenersForListenerID(selKey);
+ }
+ },
+
+ /**
+ * Sets listener's priority with fixed value.
+ * @param {cc.EventListener} listener
+ * @param {Number} fixedPriority
+ */
+ setPriority: function (listener, fixedPriority) {
+ if (listener == null)
+ return;
+
+ var locListeners = this._listenersMap;
+ for (var selKey in locListeners) {
+ var selListeners = locListeners[selKey];
+ var fixedPriorityListeners = selListeners.getFixedPriorityListeners();
+ if (fixedPriorityListeners) {
+ var found = fixedPriorityListeners.indexOf(listener);
+ if (found !== -1) {
+ if (listener._getSceneGraphPriority() != null)
+ cc.log(cc._LogInfos.eventManager_setPriority);
+ if (listener._getFixedPriority() !== fixedPriority) {
+ listener._setFixedPriority(fixedPriority);
+ this._setDirty(listener._getListenerID(), this.DIRTY_FIXED_PRIORITY);
+ }
+ return;
+ }
+ }
+ }
+ },
+
+ /**
+ * Whether to enable dispatching events
+ * @param {boolean} enabled
+ */
+ setEnabled: function (enabled) {
+ this._isEnabled = enabled;
+ },
+
+ /**
+ * Checks whether dispatching events is enabled
+ * @returns {boolean}
+ */
+ isEnabled: function () {
+ return this._isEnabled;
+ },
+
+ /**
+ * Dispatches the event, also removes all EventListeners marked for deletion from the event dispatcher list.
+ * @param {cc.Event} event
+ */
+ dispatchEvent: function (event) {
+ if (!this._isEnabled)
+ return;
+
+ this._updateDirtyFlagForSceneGraph();
+ this._inDispatch++;
+ if (!event || !event.getType)
+ throw new Error("event is undefined");
+ if (event._type === cc.Event.TOUCH) {
+ this._dispatchTouchEvent(event);
+ this._inDispatch--;
+ return;
+ }
+
+ var listenerID = __getListenerID(event);
+ this._sortEventListeners(listenerID);
+ var selListeners = this._listenersMap[listenerID];
+ if (selListeners) {
+ this._dispatchEventToListeners(selListeners, this._onListenerCallback, event);
+ this._onUpdateListeners(selListeners);
+ }
+
+ this._inDispatch--;
+ },
+
+ _onListenerCallback: function (listener, event) {
+ event._setCurrentTarget(listener._getSceneGraphPriority());
+ listener._onEvent(event);
+ return event.isStopped();
+ },
+
+ /**
+ * Dispatches a Custom Event with a event name an optional user data
+ * @param {string} eventName
+ * @param {*} optionalUserData
+ */
+ dispatchCustomEvent: function (eventName, optionalUserData) {
+ var ev = new cc.EventCustom(eventName);
+ ev.setUserData(optionalUserData);
+ this.dispatchEvent(ev);
+ }
+};
+
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCTouch.js b/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCTouch.js
new file mode 100644
index 0000000..3c8ea79
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/event-manager/CCTouch.js
@@ -0,0 +1,176 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The touch event class
+ * @class
+ * @extends cc.Class
+ *
+ * @param {Number} x
+ * @param {Number} y
+ * @param {Number} id
+ */
+cc.Touch = cc.Class.extend(/** @lends cc.Touch# */{
+ _lastModified: 0,
+ _point:null,
+ _prevPoint:null,
+ _id:0,
+ _startPointCaptured: false,
+ _startPoint:null,
+
+ ctor:function (x, y, id) {
+ this.setTouchInfo(id, x, y);
+ },
+
+ /**
+ * Returns the current touch location in OpenGL coordinates
+ * @return {cc.Point}
+ */
+ getLocation:function () {
+ //TODO
+ //return cc.director.convertToGL(this._point);
+ return {x: this._point.x, y: this._point.y};
+ },
+
+ /**
+ * Returns X axis location value
+ * @returns {number}
+ */
+ getLocationX: function () {
+ return this._point.x;
+ },
+
+ /**
+ * Returns Y axis location value
+ * @returns {number}
+ */
+ getLocationY: function () {
+ return this._point.y;
+ },
+
+ /**
+ * Returns the previous touch location in OpenGL coordinates
+ * @return {cc.Point}
+ */
+ getPreviousLocation:function () {
+ //TODO
+ //return cc.director.convertToGL(this._prevPoint);
+ return {x: this._prevPoint.x, y: this._prevPoint.y};
+ },
+
+ /**
+ * Returns the start touch location in OpenGL coordinates
+ * @returns {cc.Point}
+ */
+ getStartLocation: function() {
+ //TODO
+ //return cc.director.convertToGL(this._startPoint);
+ return {x: this._startPoint.x, y: this._startPoint.y};
+ },
+
+ /**
+ * Returns the delta distance from the previous touche to the current one in screen coordinates
+ * @return {cc.Point}
+ */
+ getDelta:function () {
+ return cc.pSub(this._point, this._prevPoint);
+ },
+
+ /**
+ * Returns the current touch location in screen coordinates
+ * @return {cc.Point}
+ */
+ getLocationInView: function() {
+ return {x: this._point.x, y: this._point.y};
+ },
+
+ /**
+ * Returns the previous touch location in screen coordinates
+ * @return {cc.Point}
+ */
+ getPreviousLocationInView: function(){
+ return {x: this._prevPoint.x, y: this._prevPoint.y};
+ },
+
+ /**
+ * Returns the start touch location in screen coordinates
+ * @return {cc.Point}
+ */
+ getStartLocationInView: function(){
+ return {x: this._startPoint.x, y: this._startPoint.y};
+ },
+
+ /**
+ * Returns the id of cc.Touch
+ * @return {Number}
+ */
+ getID:function () {
+ return this._id;
+ },
+
+ /**
+ * Returns the id of cc.Touch
+ * @return {Number}
+ * @deprecated since v3.0, please use getID() instead
+ */
+ getId:function () {
+ cc.log("getId is deprecated. Please use getID instead.");
+ return this._id;
+ },
+
+ /**
+ * Sets information to touch
+ * @param {Number} id
+ * @param {Number} x
+ * @param {Number} y
+ */
+ setTouchInfo:function (id, x, y) {
+ this._prevPoint = this._point;
+ this._point = cc.p(x || 0, y || 0);
+ this._id = id;
+ if (!this._startPointCaptured) {
+ this._startPoint = cc.p(this._point);
+ cc.view._convertPointWithScale(this._startPoint);
+ this._startPointCaptured = true;
+ }
+ },
+
+ _setPoint: function(x, y){
+ if(y === undefined){
+ this._point.x = x.x;
+ this._point.y = x.y;
+ }else{
+ this._point.x = x;
+ this._point.y = y;
+ }
+ },
+
+ _setPrevPoint:function (x, y) {
+ if(y === undefined)
+ this._prevPoint = cc.p(x.x, x.y);
+ else
+ this._prevPoint = cc.p(x || 0, y || 0);
+ }
+});
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/labelttf/CCLabelTTF.js b/frameworks/cocos2d-html5/cocos2d/core/labelttf/CCLabelTTF.js
new file mode 100644
index 0000000..ac98810
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/labelttf/CCLabelTTF.js
@@ -0,0 +1,974 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.LabelTTF is a subclass of cc.TextureNode that knows how to render text labels with system font or a ttf font file
+ * All features from cc.Sprite are valid in cc.LabelTTF
+ * cc.LabelTTF objects are slow for js-binding on mobile devices.
+ * Consider using cc.LabelAtlas or cc.LabelBMFont instead.
+ * You can create a cc.LabelTTF from a font name, alignment, dimension and font size or a cc.FontDefinition object.
+ * @class
+ * @extends cc.Sprite
+ *
+ * @param {String} text
+ * @param {String|cc.FontDefinition} [fontName="Arial"]
+ * @param {Number} [fontSize=16]
+ * @param {cc.Size} [dimensions=cc.size(0,0)]
+ * @param {Number} [hAlignment=cc.TEXT_ALIGNMENT_LEFT]
+ * @param {Number} [vAlignment=cc.VERTICAL_TEXT_ALIGNMENT_TOP]
+ * @example
+ * var myLabel = new cc.LabelTTF('label text', 'Times New Roman', 32, cc.size(320,32), cc.TEXT_ALIGNMENT_LEFT);
+ *
+ * var fontDef = new cc.FontDefinition();
+ * fontDef.fontName = "Arial";
+ * fontDef.fontSize = "32";
+ * var myLabel = new cc.LabelTTF('label text', fontDef);
+ *
+ * @property {String} string - Content string of label
+ * @property {Number} textAlign - Horizontal Alignment of label: cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT
+ * @property {Number} verticalAlign - Vertical Alignment of label: cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM
+ * @property {Number} fontSize - Font size of label
+ * @property {String} fontName - Font name of label
+ * @property {String} font - The label font with a style string: e.g. "18px Verdana"
+ * @property {Number} boundingWidth - Width of the bounding box of label, the real content width is limited by boundingWidth
+ * @property {Number} boundingHeight - Height of the bounding box of label, the real content height is limited by boundingHeight
+ * @property {cc.Color} fillStyle - The fill color
+ * @property {cc.Color} strokeStyle - The stroke color
+ * @property {Number} lineWidth - The line width for stroke
+ * @property {Number} shadowOffsetX - The x axis offset of shadow
+ * @property {Number} shadowOffsetY - The y axis offset of shadow
+ * @property {Number} shadowOpacity - The opacity of shadow
+ * @property {Number} shadowBlur - The blur size of shadow
+ */
+cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
+ _dimensions: null,
+ _hAlignment: cc.TEXT_ALIGNMENT_CENTER,
+ _vAlignment: cc.VERTICAL_TEXT_ALIGNMENT_TOP,
+ _fontName: null,
+ _fontSize: 0.0,
+ _string: "",
+ _originalText: null,
+ _onCacheCanvasMode: true,
+
+ // font shadow
+ _shadowEnabled: false,
+ _shadowOffset: null,
+ _shadowOpacity: 0,
+ _shadowBlur: 0,
+ _shadowColor: null,
+
+ // font stroke
+ _strokeEnabled: false,
+ _strokeColor: null,
+ _strokeSize: 0,
+
+ // font tint
+ _textFillColor: null,
+
+ _strokeShadowOffsetX: 0,
+ _strokeShadowOffsetY: 0,
+ _needUpdateTexture: false,
+
+ _lineWidths: null,
+ _className: "LabelTTF",
+
+ //for web
+ _fontStyle: "normal",
+ _fontWeight: "normal",
+ _lineHeight: "normal",
+
+ /**
+ * Initializes the cc.LabelTTF with a font name, alignment, dimension and font size, do not call it by yourself,
+ * you should pass the correct arguments in constructor to initialize the label.
+ * @param {String} label string
+ * @param {String} fontName
+ * @param {Number} fontSize
+ * @param {cc.Size} [dimensions=]
+ * @param {Number} [hAlignment=]
+ * @param {Number} [vAlignment=]
+ * @return {Boolean} return false on error
+ */
+ initWithString: function (label, fontName, fontSize, dimensions, hAlignment, vAlignment) {
+ var strInfo;
+ if (label)
+ strInfo = label + "";
+ else
+ strInfo = "";
+
+ fontSize = fontSize || 16;
+ dimensions = dimensions || cc.size(0, 0/*fontSize*/);
+ hAlignment = hAlignment || cc.TEXT_ALIGNMENT_LEFT;
+ vAlignment = vAlignment || cc.VERTICAL_TEXT_ALIGNMENT_TOP;
+
+ this._opacityModifyRGB = false;
+ this._dimensions = cc.size(dimensions.width, dimensions.height);
+ this._fontName = fontName || "Arial";
+ this._hAlignment = hAlignment;
+ this._vAlignment = vAlignment;
+
+ this._fontSize = fontSize;
+ this._renderCmd._setFontStyle(this._fontName, fontSize, this._fontStyle, this._fontWeight);
+ this.string = strInfo;
+ this._renderCmd._setColorsString();
+ this._renderCmd._updateTexture();
+ this._setUpdateTextureDirty();
+
+ // Needed for high dpi text.
+ // In order to render it crisp, we request devicePixelRatio times the
+ // font size and scale it down 1/devicePixelRatio.
+ this._scaleX = this._scaleY = 1 / cc.view.getDevicePixelRatio();
+ return true;
+ },
+
+ _setUpdateTextureDirty: function () {
+ this._needUpdateTexture = true;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.textDirty);
+ },
+
+ ctor: function (text, fontName, fontSize, dimensions, hAlignment, vAlignment) {
+ cc.Sprite.prototype.ctor.call(this);
+
+ this._dimensions = cc.size(0, 0);
+ this._hAlignment = cc.TEXT_ALIGNMENT_LEFT;
+ this._vAlignment = cc.VERTICAL_TEXT_ALIGNMENT_TOP;
+ this._opacityModifyRGB = false;
+ this._fontName = "Arial";
+
+ this._shadowEnabled = false;
+ this._shadowOffset = cc.p(0, 0);
+ this._shadowOpacity = 0;
+ this._shadowBlur = 0;
+
+ this._strokeEnabled = false;
+ this._strokeColor = cc.color(255, 255, 255, 255);
+ this._strokeSize = 0;
+
+ this._textFillColor = cc.color(255, 255, 255, 255);
+ this._strokeShadowOffsetX = 0;
+ this._strokeShadowOffsetY = 0;
+ this._needUpdateTexture = false;
+
+ this._lineWidths = [];
+ this._renderCmd._setColorsString();
+ this._textureLoaded = true;
+
+ if (fontName && fontName instanceof cc.FontDefinition) {
+ this.initWithStringAndTextDefinition(text, fontName);
+ } else {
+ cc.LabelTTF.prototype.initWithString.call(this, text, fontName, fontSize, dimensions, hAlignment, vAlignment);
+ }
+ },
+
+ init: function () {
+ return this.initWithString(" ", this._fontName, this._fontSize);
+ },
+
+ description: function () {
+ return "";
+ },
+
+ getLineHeight: function () {
+ return !this._lineHeight || this._lineHeight.charAt ?
+ this._renderCmd._getFontClientHeight() :
+ this._lineHeight || this._renderCmd._getFontClientHeight();
+ },
+
+ setLineHeight: function (lineHeight) {
+ this._lineHeight = lineHeight;
+ },
+
+ /**
+ * Returns the text of the label
+ * @return {String}
+ */
+ getString: function () {
+ return this._string;
+ },
+
+ /**
+ * Returns Horizontal Alignment of cc.LabelTTF
+ * @return {cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT}
+ */
+ getHorizontalAlignment: function () {
+ return this._hAlignment;
+ },
+
+ /**
+ * Returns Vertical Alignment of cc.LabelTTF
+ * @return {cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM}
+ */
+ getVerticalAlignment: function () {
+ return this._vAlignment;
+ },
+
+ /**
+ * Returns the dimensions of cc.LabelTTF, the dimension is the maximum size of the label, set it so that label will automatically change lines when necessary.
+ * @see cc.LabelTTF#setDimensions, cc.LabelTTF#boundingWidth and cc.LabelTTF#boundingHeight
+ * @return {cc.Size}
+ */
+ getDimensions: function () {
+ return cc.size(this._dimensions);
+ },
+
+ /**
+ * Returns font size of cc.LabelTTF
+ * @return {Number}
+ */
+ getFontSize: function () {
+ return this._fontSize;
+ },
+
+ /**
+ * Returns font name of cc.LabelTTF
+ * @return {String}
+ */
+ getFontName: function () {
+ return this._fontName;
+ },
+
+ /**
+ * Initializes the CCLabelTTF with a font name, alignment, dimension and font size, do not call it by yourself, you should pass the correct arguments in constructor to initialize the label.
+ * @param {String} text
+ * @param {cc.FontDefinition} textDefinition
+ * @return {Boolean}
+ */
+ initWithStringAndTextDefinition: function (text, textDefinition) {
+ // prepare everything needed to render the label
+ this._updateWithTextDefinition(textDefinition, false);
+ // set the string
+ this.string = text;
+ return true;
+ },
+
+ /**
+ * Sets the text definition used by this label
+ * @param {cc.FontDefinition} theDefinition
+ */
+ setTextDefinition: function (theDefinition) {
+ if (theDefinition)
+ this._updateWithTextDefinition(theDefinition, true);
+ },
+
+ /**
+ * Extract the text definition used by this label
+ * @return {cc.FontDefinition}
+ */
+ getTextDefinition: function () {
+ return this._prepareTextDefinition(false);
+ },
+
+ /**
+ * Enable or disable shadow for the label
+ * @param {cc.Color | Number} a Color or The x axis offset of the shadow
+ * @param {cc.Size | Number} b Size or The y axis offset of the shadow
+ * @param {Number} c The blur size of the shadow or The opacity of the shadow (0 to 1)
+ * @param {null | Number} d Null or The blur size of the shadow
+ * @example
+ * old:
+ * labelttf.enableShadow(shadowOffsetX, shadowOffsetY, shadowOpacity, shadowBlur);
+ * new:
+ * labelttf.enableShadow(shadowColor, offset, blurRadius);
+ */
+ enableShadow: function (a, b, c, d) {
+ if (a.r != null && a.g != null && a.b != null && a.a != null) {
+ this._enableShadow(a, b, c);
+ } else {
+ this._enableShadowNoneColor(a, b, c, d);
+ }
+ },
+
+ _enableShadowNoneColor: function (shadowOffsetX, shadowOffsetY, shadowOpacity, shadowBlur) {
+ shadowOpacity = shadowOpacity || 0.5;
+ if (false === this._shadowEnabled)
+ this._shadowEnabled = true;
+
+ var locShadowOffset = this._shadowOffset;
+ if (locShadowOffset && (locShadowOffset.x !== shadowOffsetX) || (locShadowOffset._y !== shadowOffsetY)) {
+ locShadowOffset.x = shadowOffsetX;
+ locShadowOffset.y = shadowOffsetY;
+ }
+
+ if (this._shadowOpacity !== shadowOpacity) {
+ this._shadowOpacity = shadowOpacity;
+ }
+ this._renderCmd._setColorsString();
+
+ if (this._shadowBlur !== shadowBlur)
+ this._shadowBlur = shadowBlur;
+ this._setUpdateTextureDirty();
+ },
+
+ _enableShadow: function (shadowColor, offset, blurRadius) {
+ if (!this._shadowColor) {
+ this._shadowColor = cc.color(255, 255, 255, 128);
+ }
+ this._shadowColor.r = shadowColor.r;
+ this._shadowColor.g = shadowColor.g;
+ this._shadowColor.b = shadowColor.b;
+
+ var x, y, a, b;
+ x = offset.width || offset.x || 0;
+ y = offset.height || offset.y || 0;
+ a = (shadowColor.a != null) ? (shadowColor.a / 255) : 0.5;
+ b = blurRadius;
+
+ this._enableShadowNoneColor(x, y, a, b);
+ },
+
+ _getShadowOffsetX: function () {
+ return this._shadowOffset.x;
+ },
+ _setShadowOffsetX: function (x) {
+ if (false === this._shadowEnabled)
+ this._shadowEnabled = true;
+
+ if (this._shadowOffset.x !== x) {
+ this._shadowOffset.x = x;
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ _getShadowOffsetY: function () {
+ return this._shadowOffset._y;
+ },
+ _setShadowOffsetY: function (y) {
+ if (false === this._shadowEnabled)
+ this._shadowEnabled = true;
+
+ if (this._shadowOffset._y !== y) {
+ this._shadowOffset._y = y;
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ _getShadowOffset: function () {
+ return cc.p(this._shadowOffset.x, this._shadowOffset.y);
+ },
+ _setShadowOffset: function (offset) {
+ if (false === this._shadowEnabled)
+ this._shadowEnabled = true;
+
+ if (this._shadowOffset.x !== offset.x || this._shadowOffset.y !== offset.y) {
+ this._shadowOffset.x = offset.x;
+ this._shadowOffset.y = offset.y;
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ _getShadowOpacity: function () {
+ return this._shadowOpacity;
+ },
+ _setShadowOpacity: function (shadowOpacity) {
+ if (false === this._shadowEnabled)
+ this._shadowEnabled = true;
+
+ if (this._shadowOpacity !== shadowOpacity) {
+ this._shadowOpacity = shadowOpacity;
+ this._renderCmd._setColorsString();
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ _getShadowBlur: function () {
+ return this._shadowBlur;
+ },
+ _setShadowBlur: function (shadowBlur) {
+ if (false === this._shadowEnabled)
+ this._shadowEnabled = true;
+
+ if (this._shadowBlur !== shadowBlur) {
+ this._shadowBlur = shadowBlur;
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ /**
+ * Disable shadow rendering
+ */
+ disableShadow: function () {
+ if (this._shadowEnabled) {
+ this._shadowEnabled = false;
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ /**
+ * Enable label stroke with stroke parameters
+ * @param {cc.Color} strokeColor The color of stroke
+ * @param {Number} strokeSize The size of stroke
+ */
+ enableStroke: function (strokeColor, strokeSize) {
+ if (this._strokeEnabled === false)
+ this._strokeEnabled = true;
+
+ var locStrokeColor = this._strokeColor;
+ if ((locStrokeColor.r !== strokeColor.r) || (locStrokeColor.g !== strokeColor.g) || (locStrokeColor.b !== strokeColor.b)) {
+ locStrokeColor.r = strokeColor.r;
+ locStrokeColor.g = strokeColor.g;
+ locStrokeColor.b = strokeColor.b;
+ this._renderCmd._setColorsString();
+ }
+
+ if (this._strokeSize !== strokeSize)
+ this._strokeSize = strokeSize || 0;
+ this._setUpdateTextureDirty();
+ },
+
+ _getStrokeStyle: function () {
+ return this._strokeColor;
+ },
+ _setStrokeStyle: function (strokeStyle) {
+ if (this._strokeEnabled === false)
+ this._strokeEnabled = true;
+
+ var locStrokeColor = this._strokeColor;
+ if ((locStrokeColor.r !== strokeStyle.r) || (locStrokeColor.g !== strokeStyle.g) || (locStrokeColor.b !== strokeStyle.b)) {
+ locStrokeColor.r = strokeStyle.r;
+ locStrokeColor.g = strokeStyle.g;
+ locStrokeColor.b = strokeStyle.b;
+ this._renderCmd._setColorsString();
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ _getLineWidth: function () {
+ return this._strokeSize;
+ },
+ _setLineWidth: function (lineWidth) {
+ if (this._strokeEnabled === false)
+ this._strokeEnabled = true;
+ if (this._strokeSize !== lineWidth) {
+ this._strokeSize = lineWidth || 0;
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ /**
+ * Disable label stroke
+ */
+ disableStroke: function () {
+ if (this._strokeEnabled) {
+ this._strokeEnabled = false;
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ /**
+ * Sets the text fill color
+ * @function
+ * @param {cc.Color} fillColor The fill color of the label
+ */
+ setFontFillColor: function (fillColor) {
+ var locTextFillColor = this._textFillColor;
+ if (locTextFillColor.r !== fillColor.r || locTextFillColor.g !== fillColor.g || locTextFillColor.b !== fillColor.b) {
+ locTextFillColor.r = fillColor.r;
+ locTextFillColor.g = fillColor.g;
+ locTextFillColor.b = fillColor.b;
+ this._renderCmd._setColorsString();
+ this._needUpdateTexture = true;
+ }
+ },
+
+ _getFillStyle: function () {
+ return this._textFillColor;
+ },
+
+ //set the text definition for this label
+ _updateWithTextDefinition: function (textDefinition, mustUpdateTexture) {
+ if (textDefinition.fontDimensions) {
+ this._dimensions.width = textDefinition.boundingWidth;
+ this._dimensions.height = textDefinition.boundingHeight;
+ } else {
+ this._dimensions.width = 0;
+ this._dimensions.height = 0;
+ }
+
+ this._hAlignment = textDefinition.textAlign;
+ this._vAlignment = textDefinition.verticalAlign;
+
+ this._fontName = textDefinition.fontName;
+ this._fontSize = textDefinition.fontSize || 12;
+
+ if (textDefinition.lineHeight)
+ this._lineHeight = textDefinition.lineHeight;
+ else
+ this._lineHeight = this._fontSize;
+
+ this._renderCmd._setFontStyle(textDefinition);
+
+
+ // shadow
+ if (textDefinition.shadowEnabled)
+ this.enableShadow(textDefinition.shadowOffsetX,
+ textDefinition.shadowOffsetY,
+ textDefinition.shadowOpacity,
+ textDefinition.shadowBlur);
+
+ // stroke
+ if (textDefinition.strokeEnabled)
+ this.enableStroke(textDefinition.strokeStyle, textDefinition.lineWidth);
+
+ // fill color
+ this.setFontFillColor(textDefinition.fillStyle);
+
+ if (mustUpdateTexture)
+ this._renderCmd._updateTexture();
+ var flags = cc.Node._dirtyFlags;
+ this._renderCmd.setDirtyFlag(flags.colorDirty | flags.opacityDirty | flags.textDirty);
+ },
+
+ _prepareTextDefinition: function (adjustForResolution) {
+ var texDef = new cc.FontDefinition();
+
+ if (adjustForResolution) {
+ texDef.fontSize = this._fontSize;
+ texDef.boundingWidth = cc.contentScaleFactor() * this._dimensions.width;
+ texDef.boundingHeight = cc.contentScaleFactor() * this._dimensions.height;
+ } else {
+ texDef.fontSize = this._fontSize;
+ texDef.boundingWidth = this._dimensions.width;
+ texDef.boundingHeight = this._dimensions.height;
+ }
+
+ texDef.fontName = this._fontName;
+ texDef.textAlign = this._hAlignment;
+ texDef.verticalAlign = this._vAlignment;
+
+ // stroke
+ if (this._strokeEnabled) {
+ texDef.strokeEnabled = true;
+ var locStrokeColor = this._strokeColor;
+ texDef.strokeStyle = cc.color(locStrokeColor.r, locStrokeColor.g, locStrokeColor.b);
+ texDef.lineWidth = this._strokeSize;
+ } else
+ texDef.strokeEnabled = false;
+
+ // shadow
+ if (this._shadowEnabled) {
+ texDef.shadowEnabled = true;
+ texDef.shadowBlur = this._shadowBlur;
+ texDef.shadowOpacity = this._shadowOpacity;
+
+ texDef.shadowOffsetX = (adjustForResolution ? cc.contentScaleFactor() : 1) * this._shadowOffset.x;
+ texDef.shadowOffsetY = (adjustForResolution ? cc.contentScaleFactor() : 1) * this._shadowOffset.y;
+ } else
+ texDef._shadowEnabled = false;
+
+ // text tint
+ var locTextFillColor = this._textFillColor;
+ texDef.fillStyle = cc.color(locTextFillColor.r, locTextFillColor.g, locTextFillColor.b);
+ return texDef;
+ },
+
+ /*
+ * BEGIN SCALE METHODS
+ *
+ * In order to make the value of scaleX and scaleY consistent across
+ * screens, we provide patched versions that return the same values as if
+ * the screen was not HiDPI.
+ */
+
+ /**
+ * Returns the scale factor of the node.
+ * @warning: Assertion will fail when _scaleX != _scaleY.
+ * @function
+ * @return {Number} The scale factor
+ */
+ getScale: function () {
+ if (this._scaleX !== this._scaleY)
+ cc.log(cc._LogInfos.Node_getScale);
+ return this._scaleX * cc.view.getDevicePixelRatio();
+ },
+
+ /**
+ * Sets the scale factor of the node. 1.0 is the default scale factor. This function can modify the X and Y scale at the same time.
+ * @function
+ * @param {Number} scale or scaleX value
+ * @param {Number} [scaleY=]
+ */
+ setScale: function (scale, scaleY) {
+ var ratio = cc.view.getDevicePixelRatio();
+ this._scaleX = scale / ratio;
+ this._scaleY = ((scaleY || scaleY === 0) ? scaleY : scale) / ratio;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns the scale factor on X axis of this node
+ * @function
+ * @return {Number} The scale factor on X axis.
+ */
+ getScaleX: function () {
+ return this._scaleX * cc.view.getDevicePixelRatio();
+ },
+
+ /**
+ *
+ * Changes the scale factor on X axis of this node
+ * The default value is 1.0 if you haven't changed it before
+ *
+ * @function
+ * @param {Number} newScaleX The scale factor on X axis.
+ */
+ setScaleX: function (newScaleX) {
+ this._scaleX = newScaleX / cc.view.getDevicePixelRatio();
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns the scale factor on Y axis of this node
+ * @function
+ * @return {Number} The scale factor on Y axis.
+ */
+ getScaleY: function () {
+ return this._scaleY * cc.view.getDevicePixelRatio();
+ },
+
+ /**
+ *
+ * Changes the scale factor on Y axis of this node
+ * The Default value is 1.0 if you haven't changed it before.
+ *
+ * @function
+ * @param {Number} newScaleY The scale factor on Y axis.
+ */
+ setScaleY: function (newScaleY) {
+ this._scaleY = newScaleY / cc.view.getDevicePixelRatio();
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /*
+ * END SCALE METHODS
+ */
+
+ /**
+ * Changes the text content of the label
+ * @warning Changing the string is as expensive as creating a new cc.LabelTTF. To obtain better performance use cc.LabelAtlas
+ * @param {String} text Text content for the label
+ */
+ setString: function (text) {
+ text = String(text);
+ if (this._originalText !== text) {
+ this._originalText = text + "";
+
+ this._updateString();
+
+ // Force update
+ this._setUpdateTextureDirty();
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ }
+ },
+ _updateString: function () {
+ if ((!this._string || this._string === "") && this._string !== this._originalText)
+ cc.renderer.childrenOrderDirty = true;
+ this._string = this._originalText;
+ },
+
+ /**
+ * Sets Horizontal Alignment of cc.LabelTTF
+ * @param {cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT} alignment Horizontal Alignment
+ */
+ setHorizontalAlignment: function (alignment) {
+ if (alignment !== this._hAlignment) {
+ this._hAlignment = alignment;
+ // Force update
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ /**
+ * Sets Vertical Alignment of cc.LabelTTF
+ * @param {cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM} verticalAlignment
+ */
+ setVerticalAlignment: function (verticalAlignment) {
+ if (verticalAlignment !== this._vAlignment) {
+ this._vAlignment = verticalAlignment;
+
+ // Force update
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ /**
+ * Set Dimensions of cc.LabelTTF, the dimension is the maximum size of the label, set it so that label will automatically change lines when necessary.
+ * @param {cc.Size|Number} dim dimensions or width of dimensions
+ * @param {Number} [height] height of dimensions
+ */
+ setDimensions: function (dim, height) {
+ var width;
+ if (height === undefined) {
+ width = dim.width;
+ height = dim.height;
+ } else
+ width = dim;
+
+ if (width !== this._dimensions.width || height !== this._dimensions.height) {
+ this._dimensions.width = width;
+ this._dimensions.height = height;
+ this._updateString();
+ // Force update
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ _getBoundingWidth: function () {
+ return this._dimensions.width;
+ },
+ _setBoundingWidth: function (width) {
+ if (width !== this._dimensions.width) {
+ this._dimensions.width = width;
+ this._updateString();
+ // Force update
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ _getBoundingHeight: function () {
+ return this._dimensions.height;
+ },
+ _setBoundingHeight: function (height) {
+ if (height !== this._dimensions.height) {
+ this._dimensions.height = height;
+ this._updateString();
+ // Force update
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ /**
+ * Sets font size of cc.LabelTTF
+ * @param {Number} fontSize
+ */
+ setFontSize: function (fontSize) {
+ if (this._fontSize !== fontSize) {
+ this._fontSize = fontSize;
+ this._renderCmd._setFontStyle(this._fontName, this._fontSize, this._fontStyle, this._fontWeight);
+ // Force update
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ /**
+ * Sets font name of cc.LabelTTF
+ * @param {String} fontName
+ */
+ setFontName: function (fontName) {
+ if (this._fontName && this._fontName !== fontName) {
+ this._fontName = fontName;
+ this._renderCmd._setFontStyle(this._fontName, this._fontSize, this._fontStyle, this._fontWeight);
+ // Force update
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ _getFont: function () {
+ return this._renderCmd._getFontStyle();
+ },
+ _setFont: function (fontStyle) {
+ var res = cc.LabelTTF._fontStyleRE.exec(fontStyle);
+ if (res) {
+ this._fontSize = parseInt(res[1]);
+ this._fontName = res[2];
+ this._renderCmd._setFontStyle(this._fontName, this._fontSize, this._fontStyle, this._fontWeight);
+
+ // Force update
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ /**
+ * Returns the actual content size of the label, the content size is the real size that the label occupied while dimension is the outer bounding box of the label.
+ * @returns {cc.Size} The content size
+ */
+ getContentSize: function () {
+ if (this._needUpdateTexture)
+ this._renderCmd._updateTTF();
+ var ratio = cc.view.getDevicePixelRatio();
+ return cc.size( this._contentSize.width / ratio, this._contentSize.height / ratio );
+ },
+
+ _getWidth: function () {
+ if (this._needUpdateTexture)
+ this._renderCmd._updateTTF();
+ return this._contentSize.width / cc.view.getDevicePixelRatio();
+ },
+ _getHeight: function () {
+ if (this._needUpdateTexture)
+ this._renderCmd._updateTTF();
+ return this._contentSize.height / cc.view.getDevicePixelRatio();
+ },
+
+ setTextureRect: function (rect, rotated, untrimmedSize) {
+ var _t = this;
+ _t._rectRotated = rotated || false;
+ _t.setContentSize(untrimmedSize || rect);
+
+ var locRect = _t._rect;
+ locRect.x = rect.x;
+ locRect.y = rect.y;
+ locRect.width = rect.width;
+ locRect.height = rect.height;
+ _t._renderCmd._setTextureCoords(rect, false);
+
+ var relativeOffsetX = _t._unflippedOffsetPositionFromCenter.x, relativeOffsetY = _t._unflippedOffsetPositionFromCenter.y;
+ if (_t._flippedX)
+ relativeOffsetX = -relativeOffsetX;
+ if (_t._flippedY)
+ relativeOffsetY = -relativeOffsetY;
+ _t._offsetPosition.x = relativeOffsetX + (rect.width - locRect.width) / 2;
+ _t._offsetPosition.y = relativeOffsetY + (rect.height - locRect.height) / 2;
+ },
+
+ /**
+ * set Target to draw on
+ * @param boolean onCanvas
+ */
+ setDrawMode: function (onCacheMode) {
+ this._onCacheCanvasMode = onCacheMode;
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ return new cc.LabelTTF.WebGLRenderCmd(this);
+ else if (this._onCacheCanvasMode)
+ return new cc.LabelTTF.CacheCanvasRenderCmd(this);
+ else
+ return new cc.LabelTTF.CanvasRenderCmd(this);
+ },
+
+ //For web only
+ _setFontStyle: function (fontStyle) {
+ if (this._fontStyle !== fontStyle) {
+ this._fontStyle = fontStyle;
+ this._renderCmd._setFontStyle(this._fontName, this._fontSize, this._fontStyle, this._fontWeight);
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ _getFontStyle: function () {
+ return this._fontStyle;
+ },
+
+ _setFontWeight: function (fontWeight) {
+ if (this._fontWeight !== fontWeight) {
+ this._fontWeight = fontWeight;
+ this._renderCmd._setFontStyle(this._fontName, this._fontSize, this._fontStyle, this._fontWeight);
+ this._setUpdateTextureDirty();
+ }
+ },
+
+ _getFontWeight: function () {
+ return this._fontWeight;
+ }
+});
+
+cc.assert(cc.isFunction(cc._tmp.PrototypeLabelTTF), cc._LogInfos.MissingFile, "LabelTTFPropertyDefine.js");
+cc._tmp.PrototypeLabelTTF();
+delete cc._tmp.PrototypeLabelTTF;
+
+// Only support style in this format: "18px Verdana" or "18px 'Helvetica Neue'"
+cc.LabelTTF._fontStyleRE = /^(\d+)px\s+['"]?([\w\s\d]+)['"]?$/;
+
+/**
+ * creates a cc.LabelTTF from a font name, alignment, dimension and font size
+ * @deprecated since v3.0, please use the new construction instead
+ * @see cc.LabelTTF
+ * @static
+ * @param {String} text
+ * @param {String|cc.FontDefinition} [fontName="Arial"]
+ * @param {Number} [fontSize=16]
+ * @param {cc.Size} [dimensions=cc.size(0,0)]
+ * @param {Number} [hAlignment=cc.TEXT_ALIGNMENT_LEFT]
+ * @param {Number} [vAlignment=cc.VERTICAL_TEXT_ALIGNMENT_TOP]
+ * @return {cc.LabelTTF|Null}
+ */
+cc.LabelTTF.create = function (text, fontName, fontSize, dimensions, hAlignment, vAlignment) {
+ return new cc.LabelTTF(text, fontName, fontSize, dimensions, hAlignment, vAlignment);
+};
+
+/**
+ * @deprecated since v3.0, please use the new construction instead
+ * @function
+ * @static
+ */
+cc.LabelTTF.createWithFontDefinition = cc.LabelTTF.create;
+
+cc.LabelTTF.__labelHeightDiv = document.createElement("div");
+cc.LabelTTF.__labelHeightDiv.style.fontFamily = "Arial";
+cc.LabelTTF.__labelHeightDiv.style.position = "absolute";
+cc.LabelTTF.__labelHeightDiv.style.left = "-100px";
+cc.LabelTTF.__labelHeightDiv.style.top = "-100px";
+cc.LabelTTF.__labelHeightDiv.style.lineHeight = "normal";
+
+document.body ?
+ document.body.appendChild(cc.LabelTTF.__labelHeightDiv) :
+ window.addEventListener('load', function () {
+ this.removeEventListener('load', arguments.callee, false);
+ document.body.appendChild(cc.LabelTTF.__labelHeightDiv);
+ }, false);
+
+/**
+ * Returns the height of text with an specified font family and font size, in
+ * device independent pixels.
+ *
+ * @param {string|cc.FontDefinition} fontName
+ * @param {number} fontSize
+ * @returns {number}
+ * @private
+ */
+cc.LabelTTF.__getFontHeightByDiv = function (fontName, fontSize) {
+ var clientHeight, labelDiv = cc.LabelTTF.__labelHeightDiv;
+ if(fontName instanceof cc.FontDefinition){
+ /** @type cc.FontDefinition */
+ var fontDef = fontName;
+ clientHeight = cc.LabelTTF.__fontHeightCache[fontDef._getCanvasFontStr()];
+ if (clientHeight > 0) return clientHeight;
+ labelDiv.innerHTML = "ajghl~!";
+ labelDiv.style.fontFamily = fontDef.fontName;
+ labelDiv.style.fontSize = fontDef.fontSize + "px";
+ labelDiv.style.fontStyle = fontDef.fontStyle;
+ labelDiv.style.fontWeight = fontDef.fontWeight;
+
+ clientHeight = labelDiv.clientHeight;
+ cc.LabelTTF.__fontHeightCache[fontDef._getCanvasFontStr()] = clientHeight;
+ labelDiv.innerHTML = "";
+ }
+ else {
+ //Default
+ clientHeight = cc.LabelTTF.__fontHeightCache[fontName + "." + fontSize];
+ if (clientHeight > 0) return clientHeight;
+ labelDiv.innerHTML = "ajghl~!";
+ labelDiv.style.fontFamily = fontName;
+ labelDiv.style.fontSize = fontSize + "px";
+ clientHeight = labelDiv.clientHeight;
+ cc.LabelTTF.__fontHeightCache[fontName + "." + fontSize] = clientHeight;
+ labelDiv.innerHTML = "";
+ }
+ return clientHeight;
+
+};
+
+cc.LabelTTF.__fontHeightCache = {};
diff --git a/frameworks/cocos2d-html5/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js
new file mode 100644
index 0000000..44c8f18
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js
@@ -0,0 +1,570 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ http://www.cocos2d-x.org
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.LabelTTF._textAlign = ["left", "center", "right"];
+cc.LabelTTF._textBaseline = ["top", "middle", "bottom"];
+
+//check the first character
+cc.LabelTTF.wrapInspection = true;
+
+// These regular expressions consider a word any sequence of characters
+// from these Unicode (sub)blocks:
+// - Basic Latin (letters and numbers, plus the hypen-minus '-')
+// - Latin-1 Supplement (accentuated letters and ¿¡ only)
+// - Latin Extended-A (complete)
+// - Latin Extended-B (complete)
+// - IPA Extensions (complete)
+// - Spacing Modifier Letters (complete)
+// - Combining Diacritical Marks (Combining Grapheme Joiner excluded)
+// - Greek and Coptic (complete, including reserved code points)
+// - Cyrillic (complete)
+// - Cyrillic Supplement (complete)
+// - General Punctuation (Non-Breaking Hyphen* [U+2011] and quotation marks)
+// * Note that Hyphen [U+2010] is considered a word boundary.
+cc.LabelTTF._wordRex = /([a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]+|\S)/;
+cc.LabelTTF._symbolRex = /^[!,.:;}\]%\?>、‘“》»?。,!\u2010′-‴›‼⁆⁇-⁉]/;
+cc.LabelTTF._lastWordRex = /([a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]+|\S)$/;
+cc.LabelTTF._lastEnglish = /[a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]+$/;
+cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]/;
+
+(function () {
+ cc.LabelTTF.RenderCmd = function () {
+ this._fontClientHeight = 18;
+ this._fontStyleStr = "";
+ this._shadowColorStr = "rgba(128, 128, 128, 0.5)";
+ this._strokeColorStr = "";
+ this._fillColorStr = "rgba(255,255,255,1)";
+
+ this._labelCanvas = null;
+ this._labelContext = null;
+ this._lineWidths = [];
+ this._strings = [];
+ this._isMultiLine = false;
+ this._status = [];
+ this._renderingIndex = 0;
+
+ this._canUseDirtyRegion = true;
+ };
+ var proto = cc.LabelTTF.RenderCmd.prototype;
+ proto.constructor = cc.LabelTTF.RenderCmd;
+ proto._labelCmdCtor = cc.LabelTTF.RenderCmd;
+
+ proto._setFontStyle = function (fontNameOrFontDef, fontSize, fontStyle, fontWeight) {
+ if (fontNameOrFontDef instanceof cc.FontDefinition) {
+ this._fontStyleStr = fontNameOrFontDef._getCanvasFontStr();
+ this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(fontNameOrFontDef);
+ } else {
+ var deviceFontSize = fontSize * cc.view.getDevicePixelRatio();
+ this._fontStyleStr = fontStyle + " " + fontWeight + " " + deviceFontSize + "px '" + fontNameOrFontDef + "'";
+ this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(fontNameOrFontDef, fontSize);
+ }
+ };
+
+ proto._getFontStyle = function () {
+ return this._fontStyleStr;
+ };
+
+ proto._getFontClientHeight = function () {
+ return this._fontClientHeight;
+ };
+
+ proto._updateColor = function () {
+ this._setColorsString();
+ this._updateTexture();
+ };
+
+ proto._setColorsString = function () {
+ var locDisplayColor = this._displayedColor, node = this._node,
+ locShadowColor = node._shadowColor || this._displayedColor;
+ var locStrokeColor = node._strokeColor, locFontFillColor = node._textFillColor;
+ var dr = locDisplayColor.r / 255, dg = locDisplayColor.g / 255, db = locDisplayColor.b / 255;
+
+ this._shadowColorStr = "rgba(" + (0 | (dr * locShadowColor.r)) + "," + (0 | ( dg * locShadowColor.g)) + ","
+ + (0 | (db * locShadowColor.b)) + "," + node._shadowOpacity + ")";
+ this._fillColorStr = "rgba(" + (0 | (dr * locFontFillColor.r)) + "," + (0 | (dg * locFontFillColor.g)) + ","
+ + (0 | (db * locFontFillColor.b)) + ", 1)";
+ this._strokeColorStr = "rgba(" + (0 | (dr * locStrokeColor.r)) + "," + (0 | (dg * locStrokeColor.g)) + ","
+ + (0 | (db * locStrokeColor.b)) + ", 1)";
+ };
+
+ var localBB = new cc.Rect();
+ proto.getLocalBB = function () {
+ var node = this._node;
+ localBB.x = localBB.y = 0;
+ var pixelRatio = cc.view.getDevicePixelRatio();
+ localBB.width = node._getWidth() * pixelRatio;
+ localBB.height = node._getHeight() * pixelRatio;
+ return localBB;
+ };
+
+ proto._updateTTF = function () {
+ var node = this._node;
+ var pixelRatio = cc.view.getDevicePixelRatio();
+ var locDimensionsWidth = node._dimensions.width * pixelRatio, i, strLength;
+ var locLineWidth = this._lineWidths;
+ locLineWidth.length = 0;
+
+ this._isMultiLine = false;
+ this._measureConfig();
+ var textWidthCache = {};
+ if (locDimensionsWidth !== 0) {
+ // Content processing
+ this._strings = node._string.split('\n');
+
+ for (i = 0; i < this._strings.length; i++) {
+ this._checkWarp(this._strings, i, locDimensionsWidth);
+ }
+ } else {
+ this._strings = node._string.split('\n');
+ for (i = 0, strLength = this._strings.length; i < strLength; i++) {
+ if(this._strings[i]) {
+ var measuredWidth = this._measure(this._strings[i]);
+ locLineWidth.push(measuredWidth);
+ textWidthCache[this._strings[i]] = measuredWidth;
+ } else {
+ locLineWidth.push(0);
+ }
+ }
+ }
+
+ if (this._strings.length > 1)
+ this._isMultiLine = true;
+
+ var locSize, locStrokeShadowOffsetX = 0, locStrokeShadowOffsetY = 0;
+ if (node._strokeEnabled)
+ locStrokeShadowOffsetX = locStrokeShadowOffsetY = node._strokeSize * 2;
+ if (node._shadowEnabled) {
+ var locOffsetSize = node._shadowOffset;
+ locStrokeShadowOffsetX += Math.abs(locOffsetSize.x) * 2;
+ locStrokeShadowOffsetY += Math.abs(locOffsetSize.y) * 2;
+ }
+
+ //get offset for stroke and shadow
+ if (locDimensionsWidth === 0) {
+ if (this._isMultiLine) {
+ locSize = cc.size(Math.ceil(Math.max.apply(Math, locLineWidth) + locStrokeShadowOffsetX),
+ Math.ceil((this._fontClientHeight * pixelRatio * this._strings.length) + locStrokeShadowOffsetY));
+ }
+ else {
+ var measuredWidth = textWidthCache[node._string];
+ if(!measuredWidth && node._string) {
+ measuredWidth = this._measure(node._string);
+ }
+ locSize = cc.size(Math.ceil((measuredWidth ? measuredWidth : 0) + locStrokeShadowOffsetX),
+ Math.ceil(this._fontClientHeight * pixelRatio + locStrokeShadowOffsetY));
+ }
+ } else {
+ if (node._dimensions.height === 0) {
+ if (this._isMultiLine)
+ locSize = cc.size(
+ Math.ceil(locDimensionsWidth + locStrokeShadowOffsetX),
+ Math.ceil((node.getLineHeight() * pixelRatio * this._strings.length) + locStrokeShadowOffsetY));
+ else
+ locSize = cc.size(
+ Math.ceil(locDimensionsWidth + locStrokeShadowOffsetX),
+ Math.ceil(node.getLineHeight() * pixelRatio + locStrokeShadowOffsetY));
+ } else {
+ //dimension is already set, contentSize must be same as dimension
+ locSize = cc.size(
+ Math.ceil(locDimensionsWidth + locStrokeShadowOffsetX),
+ Math.ceil(node._dimensions.height * pixelRatio + locStrokeShadowOffsetY));
+ }
+ }
+ if (node._getFontStyle() !== "normal") { //add width for 'italic' and 'oblique'
+ locSize.width = Math.ceil(locSize.width + node._fontSize * 0.3);
+ }
+ node.setContentSize(locSize);
+ node._strokeShadowOffsetX = locStrokeShadowOffsetX;
+ node._strokeShadowOffsetY = locStrokeShadowOffsetY;
+
+ // need computing _anchorPointInPoints
+ var locAP = node._anchorPoint;
+ this._anchorPointInPoints.x = (locStrokeShadowOffsetX * 0.5) + ((locSize.width - locStrokeShadowOffsetX) * locAP.x);
+ this._anchorPointInPoints.y = (locStrokeShadowOffsetY * 0.5) + ((locSize.height - locStrokeShadowOffsetY) * locAP.y);
+ };
+
+ proto._saveStatus = function () {
+ var node = this._node;
+ var scale = cc.view.getDevicePixelRatio();
+ var locStrokeShadowOffsetX = node._strokeShadowOffsetX, locStrokeShadowOffsetY = node._strokeShadowOffsetY;
+ var locContentSizeHeight = node._contentSize.height - locStrokeShadowOffsetY, locVAlignment = node._vAlignment,
+ locHAlignment = node._hAlignment;
+ var dx = locStrokeShadowOffsetX * 0.5,
+ dy = locContentSizeHeight + locStrokeShadowOffsetY * 0.5;
+ var xOffset = 0, yOffset = 0, OffsetYArray = [];
+ var locContentWidth = node._contentSize.width - locStrokeShadowOffsetX;
+
+ //lineHeight
+ var lineHeight = node.getLineHeight() * scale;
+ var transformTop = (lineHeight - this._fontClientHeight * scale) / 2;
+
+ if (locHAlignment === cc.TEXT_ALIGNMENT_RIGHT)
+ xOffset += locContentWidth;
+ else if (locHAlignment === cc.TEXT_ALIGNMENT_CENTER)
+ xOffset += locContentWidth / 2;
+ else
+ xOffset += 0;
+
+ if (this._isMultiLine) {
+ var locStrLen = this._strings.length;
+ if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM)
+ yOffset = lineHeight - transformTop * 2 + locContentSizeHeight - lineHeight * locStrLen;
+ else if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_CENTER)
+ yOffset = (lineHeight - transformTop * 2) / 2 + (locContentSizeHeight - lineHeight * locStrLen) / 2;
+
+ for (var i = 0; i < locStrLen; i++) {
+ var tmpOffsetY = -locContentSizeHeight + (lineHeight * i + transformTop) + yOffset;
+ OffsetYArray.push(tmpOffsetY);
+ }
+ } else {
+ if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM) {
+ //do nothing
+ } else if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_TOP) {
+ yOffset -= locContentSizeHeight;
+ } else {
+ yOffset -= locContentSizeHeight * 0.5;
+ }
+ OffsetYArray.push(yOffset);
+ }
+ var tmpStatus = {
+ contextTransform: cc.p(dx, dy),
+ xOffset: xOffset,
+ OffsetYArray: OffsetYArray
+ };
+ this._status.push(tmpStatus);
+ };
+
+ proto._drawTTFInCanvas = function (context) {
+ if (!context)
+ return;
+ var locStatus = this._status.pop();
+ context.setTransform(1, 0, 0, 1, locStatus.contextTransform.x, locStatus.contextTransform.y);
+ var xOffset = locStatus.xOffset;
+ var yOffsetArray = locStatus.OffsetYArray;
+ this.drawLabels(context, xOffset, yOffsetArray);
+ };
+
+ proto._checkWarp = function (strArr, i, maxWidth) {
+ var text = strArr[i];
+ var allWidth = this._measure(text);
+ if (allWidth > maxWidth && text.length > 1) {
+
+ var fuzzyLen = text.length * ( maxWidth / allWidth ) | 0;
+ var tmpText = text.substr(fuzzyLen);
+ var width = allWidth - this._measure(tmpText);
+ var sLine;
+ var pushNum = 0;
+
+ //Increased while cycle maximum ceiling. default 100 time
+ var checkWhile = 0;
+
+ //Exceeded the size
+ while (width > maxWidth && checkWhile++ < 100) {
+ fuzzyLen *= maxWidth / width;
+ fuzzyLen = fuzzyLen | 0;
+ tmpText = text.substr(fuzzyLen);
+ width = allWidth - this._measure(tmpText);
+ }
+
+ checkWhile = 0;
+
+ //Find the truncation point
+ while (width < maxWidth && checkWhile++ < 100) {
+ if (tmpText) {
+ var exec = cc.LabelTTF._wordRex.exec(tmpText);
+ pushNum = exec ? exec[0].length : 1;
+ sLine = tmpText;
+ }
+
+ fuzzyLen = fuzzyLen + pushNum;
+ tmpText = text.substr(fuzzyLen);
+ width = allWidth - this._measure(tmpText);
+ }
+
+ fuzzyLen -= pushNum;
+ if (fuzzyLen === 0) {
+ fuzzyLen = 1;
+ sLine = sLine.substr(1);
+ }
+
+ var sText = text.substr(0, fuzzyLen), result;
+
+ //symbol in the first
+ if (cc.LabelTTF.wrapInspection) {
+ if (cc.LabelTTF._symbolRex.test(sLine || tmpText)) {
+ result = cc.LabelTTF._lastWordRex.exec(sText);
+ fuzzyLen -= result ? result[0].length : 0;
+ if (fuzzyLen === 0) fuzzyLen = 1;
+
+ sLine = text.substr(fuzzyLen);
+ sText = text.substr(0, fuzzyLen);
+ }
+ }
+
+ //To judge whether a English words are truncated
+ if (cc.LabelTTF._firsrEnglish.test(sLine)) {
+ result = cc.LabelTTF._lastEnglish.exec(sText);
+ if (result && sText !== result[0]) {
+ fuzzyLen -= result[0].length;
+ sLine = text.substr(fuzzyLen);
+ sText = text.substr(0, fuzzyLen);
+ }
+ }
+
+ strArr[i] = sLine || tmpText;
+ strArr.splice(i, 0, sText);
+ }
+ };
+
+ proto.updateStatus = function () {
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+
+ if (locFlag & flags.textDirty)
+ this._updateTexture();
+
+ this.originUpdateStatus();
+ };
+
+ proto._syncStatus = function (parentCmd) {
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+
+ if (locFlag & flags.textDirty)
+ this._updateTexture();
+
+ this._originSyncStatus(parentCmd);
+
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL || locFlag & flags.transformDirty)
+ this.transform(parentCmd);
+ };
+
+ proto.drawLabels = function (context, xOffset, yOffsetArray) {
+ var node = this._node;
+ //shadow style setup
+ if (node._shadowEnabled) {
+ var locShadowOffset = node._shadowOffset;
+ context.shadowColor = this._shadowColorStr;
+ context.shadowOffsetX = locShadowOffset.x;
+ context.shadowOffsetY = -locShadowOffset.y;
+ context.shadowBlur = node._shadowBlur;
+ }
+
+ var locHAlignment = node._hAlignment,
+ locVAlignment = node._vAlignment,
+ locStrokeSize = node._strokeSize;
+
+ //this is fillText for canvas
+ if (context.font !== this._fontStyleStr)
+ context.font = this._fontStyleStr;
+ context.fillStyle = this._fillColorStr;
+
+ //stroke style setup
+ var locStrokeEnabled = node._strokeEnabled;
+ if (locStrokeEnabled) {
+ context.lineWidth = locStrokeSize * 2;
+ context.strokeStyle = this._strokeColorStr;
+ }
+
+ context.textBaseline = cc.LabelTTF._textBaseline[locVAlignment];
+ context.textAlign = cc.LabelTTF._textAlign[locHAlignment];
+
+ var locStrLen = this._strings.length;
+ for (var i = 0; i < locStrLen; i++) {
+ var line = this._strings[i];
+ if (locStrokeEnabled) {
+ context.lineJoin = 'round';
+ context.strokeText(line, xOffset, yOffsetArray[i]);
+ }
+ context.fillText(line, xOffset, yOffsetArray[i]);
+ }
+ cc.g_NumberOfDraws++;
+ };
+})();
+
+(function () {
+ cc.LabelTTF.CacheRenderCmd = function () {
+ this._labelCmdCtor();
+ var locCanvas = this._labelCanvas = document.createElement("canvas");
+ locCanvas.width = 1;
+ locCanvas.height = 1;
+ this._labelContext = locCanvas.getContext("2d");
+ };
+
+ cc.LabelTTF.CacheRenderCmd.prototype = Object.create(cc.LabelTTF.RenderCmd.prototype);
+ cc.inject(cc.LabelTTF.RenderCmd.prototype, cc.LabelTTF.CacheRenderCmd.prototype);
+
+ var proto = cc.LabelTTF.CacheRenderCmd.prototype;
+ proto.constructor = cc.LabelTTF.CacheRenderCmd;
+ proto._cacheCmdCtor = cc.LabelTTF.CacheRenderCmd;
+
+ proto._updateTexture = function () {
+ this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.textDirty ^ this._dirtyFlag;
+ var node = this._node;
+ node._needUpdateTexture = false;
+ var locContentSize = node._contentSize;
+ this._updateTTF();
+ var width = locContentSize.width, height = locContentSize.height;
+
+ var locContext = this._labelContext, locLabelCanvas = this._labelCanvas;
+
+ if (!node._texture) {
+ var labelTexture = new cc.Texture2D();
+ labelTexture.initWithElement(this._labelCanvas);
+ node.setTexture(labelTexture);
+ }
+
+ if (node._string.length === 0) {
+ locLabelCanvas.width = 1;
+ locLabelCanvas.height = locContentSize.height || 1;
+ if (node._texture) {
+ node._texture._htmlElementObj = this._labelCanvas;
+ node._texture.handleLoadedTexture();
+ }
+ node.setTextureRect(cc.rect(0, 0, 1, locContentSize.height));
+ return true;
+ }
+
+ //set size for labelCanvas
+ locContext.font = this._fontStyleStr;
+
+ var flag = locLabelCanvas.width === width && locLabelCanvas.height === height;
+ locLabelCanvas.width = width;
+ locLabelCanvas.height = height;
+ if (flag) locContext.clearRect(0, 0, width, height);
+ this._saveStatus();
+ this._drawTTFInCanvas(locContext);
+ if (node._texture) {
+ node._texture._htmlElementObj = this._labelCanvas;
+ node._texture.handleLoadedTexture();
+ }
+ node.setTextureRect(cc.rect(0, 0, width, height));
+ return true;
+ };
+
+ proto._measureConfig = function () {
+ this._labelContext.font = this._fontStyleStr;
+ };
+
+ proto._measure = function (text) {
+ if (text) {
+ return this._labelContext.measureText(text).width;
+ } else {
+ return 0;
+ }
+ };
+
+})();
+
+(function () {
+ cc.LabelTTF.CacheCanvasRenderCmd = function (renderable) {
+ this._spriteCmdCtor(renderable);
+ this._cacheCmdCtor();
+ };
+
+ var proto = cc.LabelTTF.CacheCanvasRenderCmd.prototype = Object.create(cc.Sprite.CanvasRenderCmd.prototype);
+ cc.inject(cc.LabelTTF.CacheRenderCmd.prototype, proto);
+ proto.constructor = cc.LabelTTF.CacheCanvasRenderCmd;
+})();
+
+(function () {
+ cc.LabelTTF.CanvasRenderCmd = function (renderable) {
+ this._spriteCmdCtor(renderable);
+ this._labelCmdCtor();
+ };
+
+ cc.LabelTTF.CanvasRenderCmd.prototype = Object.create(cc.Sprite.CanvasRenderCmd.prototype);
+ cc.inject(cc.LabelTTF.RenderCmd.prototype, cc.LabelTTF.CanvasRenderCmd.prototype);
+
+ var proto = cc.LabelTTF.CanvasRenderCmd.prototype;
+ proto.constructor = cc.LabelTTF.CanvasRenderCmd;
+
+ proto._measureConfig = function () {
+ };
+
+ proto._measure = function (text) {
+ if(text) {
+ var context = cc._renderContext.getContext();
+ context.font = this._fontStyleStr;
+ return context.measureText(text).width;
+ } else {
+ return 0;
+ }
+ };
+
+ proto._updateTexture = function () {
+ this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.textDirty ^ this._dirtyFlag;
+ var node = this._node;
+ var locContentSize = node._contentSize;
+ this._updateTTF();
+ var width = locContentSize.width, height = locContentSize.height;
+ if (node._string.length === 0) {
+ node.setTextureRect(cc.rect(0, 0, 1, locContentSize.height));
+ return true;
+ }
+ this._saveStatus();
+ node.setTextureRect(cc.rect(0, 0, width, height));
+ return true;
+ };
+
+ proto.rendering = function (ctx) {
+ var scaleX = cc.view.getScaleX(),
+ scaleY = cc.view.getScaleY();
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext();
+ if (!context)
+ return;
+ var node = this._node;
+ wrapper.computeRealOffsetY();
+ if (this._status.length <= 0)
+ return;
+ var locIndex = (this._renderingIndex >= this._status.length) ? this._renderingIndex - this._status.length : this._renderingIndex;
+ var status = this._status[locIndex];
+ this._renderingIndex = locIndex + 1;
+
+ var locHeight = node._rect.height,
+ locX = node._offsetPosition.x,
+ locY = -node._offsetPosition.y - locHeight;
+
+ var alpha = (this._displayedOpacity / 255);
+
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+ wrapper.setCompositeOperation(this._blendFuncStr);
+ wrapper.setGlobalAlpha(alpha);
+
+ wrapper.save();
+
+ if (node._flippedX) {
+ locX = -locX - node._rect.width;
+ context.scale(-1, 1);
+ }
+ if (node._flippedY) {
+ locY = node._offsetPosition.y;
+ context.scale(1, -1);
+ }
+
+ var xOffset = status.xOffset + status.contextTransform.x + locX * scaleX;
+ var yOffsetArray = [];
+
+ var locStrLen = this._strings.length;
+ for (var i = 0; i < locStrLen; i++)
+ yOffsetArray.push(status.OffsetYArray[i] + status.contextTransform.y + locY * scaleY);
+
+ this.drawLabels(context, xOffset, yOffsetArray);
+ wrapper.restore();
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js
new file mode 100644
index 0000000..e1e8411
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js
@@ -0,0 +1,37 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+// ----------------------------------- LabelTTF WebGL render cmd ----------------------------
+(function () {
+ cc.LabelTTF.WebGLRenderCmd = function (renderable) {
+ this._spriteCmdCtor(renderable);
+ this._cacheCmdCtor();
+ };
+ var proto = cc.LabelTTF.WebGLRenderCmd.prototype = Object.create(cc.Sprite.WebGLRenderCmd.prototype);
+
+ cc.inject(cc.LabelTTF.CacheRenderCmd.prototype, proto);
+ proto.constructor = cc.LabelTTF.WebGLRenderCmd;
+ proto._updateColor = function () {
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/labelttf/LabelTTFPropertyDefine.js b/frameworks/cocos2d-html5/cocos2d/core/labelttf/LabelTTFPropertyDefine.js
new file mode 100644
index 0000000..71ff3a9
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/labelttf/LabelTTFPropertyDefine.js
@@ -0,0 +1,88 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+
+cc._tmp.PrototypeLabelTTF = function () {
+ var _p = cc.LabelTTF.prototype;
+
+ // Override properties
+ cc.defineGetterSetter(_p, "color", _p.getColor, _p.setColor);
+ cc.defineGetterSetter(_p, "opacity", _p.getOpacity, _p.setOpacity);
+
+ // Extended properties
+ /** @expose */
+ _p.string;
+ cc.defineGetterSetter(_p, "string", _p.getString, _p.setString);
+ /** @expose */
+ _p.textAlign;
+ cc.defineGetterSetter(_p, "textAlign", _p.getHorizontalAlignment, _p.setHorizontalAlignment);
+ /** @expose */
+ _p.verticalAlign;
+ cc.defineGetterSetter(_p, "verticalAlign", _p.getVerticalAlignment, _p.setVerticalAlignment);
+ /** @expose */
+ _p.fontSize;
+ cc.defineGetterSetter(_p, "fontSize", _p.getFontSize, _p.setFontSize);
+ /** @expose */
+ _p.fontName;
+ cc.defineGetterSetter(_p, "fontName", _p.getFontName, _p.setFontName);
+ /** @expose */
+ _p.font;
+ cc.defineGetterSetter(_p, "font", _p._getFont, _p._setFont);
+ /** @expose */
+ _p.boundingSize;
+ //cc.defineGetterSetter(_p, "boundingSize", _p.getDimensions, _p.setDimensions);
+ /** @expose */
+ _p.boundingWidth;
+ cc.defineGetterSetter(_p, "boundingWidth", _p._getBoundingWidth, _p._setBoundingWidth);
+ /** @expose */
+ _p.boundingHeight;
+ cc.defineGetterSetter(_p, "boundingHeight", _p._getBoundingHeight, _p._setBoundingHeight);
+ /** @expose */
+ _p.fillStyle;
+ cc.defineGetterSetter(_p, "fillStyle", _p._getFillStyle, _p.setFontFillColor);
+ /** @expose */
+ _p.strokeStyle;
+ cc.defineGetterSetter(_p, "strokeStyle", _p._getStrokeStyle, _p._setStrokeStyle);
+ /** @expose */
+ _p.lineWidth;
+ cc.defineGetterSetter(_p, "lineWidth", _p._getLineWidth, _p._setLineWidth);
+ /** @expose */
+ _p.shadowOffset;
+ //cc.defineGetterSetter(_p, "shadowOffset", _p._getShadowOffset, _p._setShadowOffset);
+ /** @expose */
+ _p.shadowOffsetX;
+ cc.defineGetterSetter(_p, "shadowOffsetX", _p._getShadowOffsetX, _p._setShadowOffsetX);
+ /** @expose */
+ _p.shadowOffsetY;
+ cc.defineGetterSetter(_p, "shadowOffsetY", _p._getShadowOffsetY, _p._setShadowOffsetY);
+ /** @expose */
+ _p.shadowOpacity;
+ cc.defineGetterSetter(_p, "shadowOpacity", _p._getShadowOpacity, _p._setShadowOpacity);
+ /** @expose */
+ _p.shadowBlur;
+ cc.defineGetterSetter(_p, "shadowBlur", _p._getShadowBlur, _p._setShadowBlur);
+
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/layers/CCLayer.js b/frameworks/cocos2d-html5/cocos2d/core/layers/CCLayer.js
new file mode 100644
index 0000000..c752ad8
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/layers/CCLayer.js
@@ -0,0 +1,782 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/** cc.Layer is a subclass of cc.Node that implements the TouchEventsDelegate protocol.
+ * All features from cc.Node are valid, plus the bake feature: Baked layer can cache a static layer to improve performance
+ * @class
+ * @extends cc.Node
+ */
+cc.Layer = cc.Node.extend(/** @lends cc.Layer# */{
+ _className: "Layer",
+
+ /**
+ * Constructor of cc.Layer, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor: function () {
+ cc.Node.prototype.ctor.call(this);
+ this._ignoreAnchorPointForPosition = true;
+ this.setAnchorPoint(0.5, 0.5);
+ this.setContentSize(cc.winSize);
+ this._cascadeColorEnabled = false;
+ this._cascadeOpacityEnabled = false;
+ },
+
+ /**
+ * Sets the layer to cache all of children to a bake sprite, and draw itself by bake sprite. recommend using it in UI.
+ * This is useful only in html5 engine
+ * @function
+ * @see cc.Layer#unbake
+ */
+ bake: function () {
+ this._renderCmd.bake();
+ },
+
+ /**
+ * Cancel the layer to cache all of children to a bake sprite.
+ * This is useful only in html5 engine
+ * @function
+ * @see cc.Layer#bake
+ */
+ unbake: function () {
+ this._renderCmd.unbake();
+ },
+
+ /**
+ * Determines if the layer is baked.
+ * @function
+ * @returns {boolean}
+ * @see cc.Layer#bake and cc.Layer#unbake
+ */
+ isBaked: function () {
+ return this._renderCmd._isBaked;
+ },
+
+ visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
+
+ var renderer = cc.renderer;
+ cmd.visit(parentCmd);
+
+ if (cmd._isBaked) {
+ renderer.pushRenderCommand(cmd);
+ cmd._bakeSprite.visit(this);
+ }
+ else {
+ var i, children = this._children, len = children.length, child;
+ if (len > 0) {
+ if (this._reorderChildDirty) {
+ this.sortAllChildren();
+ }
+ // draw children zOrder < 0
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder < 0) {
+ child.visit(this);
+ }
+ else {
+ break;
+ }
+ }
+
+ renderer.pushRenderCommand(cmd);
+ for (; i < len; i++) {
+ children[i].visit(this);
+ }
+ } else {
+ renderer.pushRenderCommand(cmd);
+ }
+ }
+ cmd._dirtyFlag = 0;
+ },
+
+ addChild: function (child, localZOrder, tag) {
+ cc.Node.prototype.addChild.call(this, child, localZOrder, tag);
+ this._renderCmd._bakeForAddChild(child);
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.Layer.CanvasRenderCmd(this);
+ else
+ return new cc.Layer.WebGLRenderCmd(this);
+ }
+});
+
+/**
+ * Creates a layer
+ * @deprecated since v3.0, please use the new construction instead
+ * @see cc.Layer
+ * @return {cc.Layer|Null}
+ */
+cc.Layer.create = function () {
+ return new cc.Layer();
+};
+
+/**
+ *
+ * CCLayerColor is a subclass of CCLayer that implements the CCRGBAProtocol protocol.
+ * All features from CCLayer are valid, plus the following new features:
+ * - opacity
+ * - RGB colors
+ * @class
+ * @extends cc.Layer
+ *
+ * @param {cc.Color} [color=] The color of the layer
+ * @param {Number} [width=] The width of the layer
+ * @param {Number} [height=] The height of the layer
+ *
+ * @example
+ * // Example
+ * //Create a yellow color layer as background
+ * var yellowBackground = new cc.LayerColor(cc.color(255,255,0,255));
+ * //If you didn't pass in width and height, it defaults to the same size as the canvas
+ *
+ * //create a yellow box, 200 by 200 in size
+ * var yellowBox = new cc.LayerColor(cc.color(255,255,0,255), 200, 200);
+ */
+cc.LayerColor = cc.Layer.extend(/** @lends cc.LayerColor# */{
+ _blendFunc: null,
+ _className: "LayerColor",
+
+ /**
+ * Returns the blend function
+ * @return {cc.BlendFunc}
+ */
+ getBlendFunc: function () {
+ return this._blendFunc;
+ },
+
+ /**
+ * Changes width and height
+ * @deprecated since v3.0 please use setContentSize instead
+ * @see cc.Node#setContentSize
+ * @param {Number} w width
+ * @param {Number} h height
+ */
+ changeWidthAndHeight: function (w, h) {
+ this.width = w;
+ this.height = h;
+ },
+
+ /**
+ * Changes width in Points
+ * @deprecated since v3.0 please use setContentSize instead
+ * @see cc.Node#setContentSize
+ * @param {Number} w width
+ */
+ changeWidth: function (w) {
+ this.width = w;
+ },
+
+ /**
+ * change height in Points
+ * @deprecated since v3.0 please use setContentSize instead
+ * @see cc.Node#setContentSize
+ * @param {Number} h height
+ */
+ changeHeight: function (h) {
+ this.height = h;
+ },
+
+ setOpacityModifyRGB: function (value) {
+ },
+
+ isOpacityModifyRGB: function () {
+ return false;
+ },
+
+ /**
+ * Constructor of cc.LayerColor
+ * @function
+ * @param {cc.Color} [color=]
+ * @param {Number} [width=]
+ * @param {Number} [height=]
+ */
+ ctor: function (color, width, height) {
+ cc.Layer.prototype.ctor.call(this);
+ this._blendFunc = cc.BlendFunc._alphaNonPremultiplied();
+ cc.LayerColor.prototype.init.call(this, color, width, height);
+ },
+
+ /**
+ * Initialization of the layer, please do not call this function by yourself, you should pass the parameters to constructor to initialize a layer
+ * @param {cc.Color} [color=]
+ * @param {Number} [width=]
+ * @param {Number} [height=]
+ * @return {Boolean}
+ */
+ init: function (color, width, height) {
+ var winSize = cc.director.getWinSize();
+ color = color || cc.color(0, 0, 0, 255);
+ width = width === undefined ? winSize.width : width;
+ height = height === undefined ? winSize.height : height;
+
+ var locRealColor = this._realColor;
+ locRealColor.r = color.r;
+ locRealColor.g = color.g;
+ locRealColor.b = color.b;
+ this._realOpacity = color.a;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty | cc.Node._dirtyFlags.opacityDirty);
+
+ cc.LayerColor.prototype.setContentSize.call(this, width, height);
+ return true;
+ },
+
+ visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
+
+ var renderer = cc.renderer;
+ cmd.visit(parentCmd);
+
+ if (cmd._isBaked) {
+ renderer.pushRenderCommand(cmd._bakeRenderCmd);
+ //the bakeSprite is drawing
+ cmd._bakeSprite._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ cmd._bakeSprite.visit(this);
+ }
+ else {
+ var i, children = this._children, len = children.length;
+ if (len > 0) {
+ if (this._reorderChildDirty) {
+ this.sortAllChildren();
+ }
+ // draw children zOrder < 0
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder < 0) {
+ child.visit(this);
+ }
+ else {
+ break;
+ }
+ }
+
+ renderer.pushRenderCommand(cmd);
+ for (; i < len; i++) {
+ children[i].visit(this);
+ }
+ } else {
+ renderer.pushRenderCommand(cmd);
+ }
+ }
+
+ cmd._dirtyFlag = 0;
+ },
+
+ /**
+ * Sets the blend func, you can pass either a cc.BlendFunc object or source and destination value separately
+ * @param {Number|cc.BlendFunc} src
+ * @param {Number} [dst]
+ */
+ setBlendFunc: function (src, dst) {
+ var locBlendFunc = this._blendFunc;
+ if (dst === undefined) {
+ locBlendFunc.src = src.src;
+ locBlendFunc.dst = src.dst;
+ } else {
+ locBlendFunc.src = src;
+ locBlendFunc.dst = dst;
+ }
+ this._renderCmd.updateBlendFunc(locBlendFunc);
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.LayerColor.CanvasRenderCmd(this);
+ else
+ return new cc.LayerColor.WebGLRenderCmd(this);
+ }
+});
+
+/**
+ * Creates a cc.Layer with color, width and height in Points
+ * @deprecated since v3.0 please use the new construction instead
+ * @see cc.LayerColor
+ * @param {cc.Color} color
+ * @param {Number|Null} [width=]
+ * @param {Number|Null} [height=]
+ * @return {cc.LayerColor}
+ */
+cc.LayerColor.create = function (color, width, height) {
+ return new cc.LayerColor(color, width, height);
+};
+
+//LayerColor - Getter Setter
+(function () {
+ var proto = cc.LayerColor.prototype;
+ cc.defineGetterSetter(proto, "width", proto._getWidth, proto._setWidth);
+ cc.defineGetterSetter(proto, "height", proto._getHeight, proto._setHeight);
+})();
+
+/**
+ *
+ * CCLayerGradient is a subclass of cc.LayerColor that draws gradients across the background.
+ *
+ * All features from cc.LayerColor are valid, plus the following new features:
+ *
direction
+ * final color
+ * interpolation mode
+ *
+ * Color is interpolated between the startColor and endColor along the given
+ * vector (starting at the origin, ending at the terminus). If no vector is
+ * supplied, it defaults to (0, -1) -- a fade from top to bottom.
+ *
+ * If 'compressedInterpolation' is disabled, you will not see either the start or end color for
+ * non-cardinal vectors; a smooth gradient implying both end points will be still
+ * be drawn, however.
+ *
+ * If 'compressedInterpolation' is enabled (default mode) you will see both the start and end colors of the gradient.
+ *
+ * @class
+ * @extends cc.LayerColor
+ *
+ * @param {cc.Color} start Starting color
+ * @param {cc.Color} end Ending color
+ * @param {cc.Point} [v=cc.p(0, -1)] A vector defines the gradient direction, default direction is from top to bottom
+ *
+ * @property {cc.Color} startColor - Start color of the color gradient
+ * @property {cc.Color} endColor - End color of the color gradient
+ * @property {Number} startOpacity - Start opacity of the color gradient
+ * @property {Number} endOpacity - End opacity of the color gradient
+ * @property {Number} vector - Direction vector of the color gradient
+ * @property {Number} compressedInterpolation - Indicate whether or not the interpolation will be compressed
+ */
+cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{
+ _endColor: null,
+ _startOpacity: 255,
+ _endOpacity: 255,
+ _alongVector: null,
+ _compressedInterpolation: false,
+ _className: "LayerGradient",
+ _colorStops: [],
+
+ /**
+ * Constructor of cc.LayerGradient
+ * @param {cc.Color} start
+ * @param {cc.Color} end
+ * @param {cc.Point} [v=cc.p(0, -1)]
+ * @param {Array|Null} stops
+ *
+ * @example Using ColorStops argument:
+ * //startColor & endColor are for default and backward compatibility
+ * var layerGradient = new cc.LayerGradient(cc.color.RED, new cc.Color(255,0,0,0), cc.p(0, -1),
+ * [{p:0, color: cc.color.RED},
+ * {p:.5, color: new cc.Color(0,0,0,0)},
+ * {p:1, color: cc.color.RED}]);
+ * //where p = A value between 0.0 and 1.0 that represents the position between start and end in a gradient
+ *
+ */
+ ctor: function (start, end, v, stops) {
+ cc.LayerColor.prototype.ctor.call(this);
+ this._endColor = cc.color(0, 0, 0, 255);
+ this._alongVector = cc.p(0, -1);
+ this._startOpacity = 255;
+ this._endOpacity = 255;
+
+ if (stops && stops instanceof Array) {
+ this._colorStops = stops;
+ stops.splice(0, 0, {p: 0, color: start || cc.color.BLACK});
+ stops.push({p: 1, color: end || cc.color.BLACK});
+ } else
+ this._colorStops = [{p: 0, color: start || cc.color.BLACK}, {p: 1, color: end || cc.color.BLACK}];
+
+ cc.LayerGradient.prototype.init.call(this, start, end, v, stops);
+ },
+
+ /**
+ * Initialization of the layer, please do not call this function by yourself, you should pass the parameters to constructor to initialize a layer
+ * @param {cc.Color} start starting color
+ * @param {cc.Color} end
+ * @param {cc.Point|Null} v
+ * @param {Array|Null} stops
+ * @return {Boolean}
+ */
+ init: function (start, end, v, stops) {
+ start = start || cc.color(0, 0, 0, 255);
+ end = end || cc.color(0, 0, 0, 255);
+ v = v || cc.p(0, -1);
+ var _t = this;
+
+ // Initializes the CCLayer with a gradient between start and end in the direction of v.
+ var locEndColor = _t._endColor;
+ _t._startOpacity = start.a;
+
+ locEndColor.r = end.r;
+ locEndColor.g = end.g;
+ locEndColor.b = end.b;
+ _t._endOpacity = end.a;
+
+ _t._alongVector = v;
+ _t._compressedInterpolation = true;
+
+ cc.LayerColor.prototype.init.call(_t, cc.color(start.r, start.g, start.b, 255));
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty | cc.Node._dirtyFlags.opacityDirty | cc.Node._dirtyFlags.gradientDirty);
+ return true;
+ },
+
+ /**
+ * Sets the untransformed size of the LayerGradient.
+ * @param {cc.Size|Number} size The untransformed size of the LayerGradient or The untransformed size's width of the LayerGradient.
+ * @param {Number} [height] The untransformed size's height of the LayerGradient.
+ */
+ setContentSize: function (size, height) {
+ cc.LayerColor.prototype.setContentSize.call(this, size, height);
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.gradientDirty);
+ },
+
+ _setWidth: function (width) {
+ cc.LayerColor.prototype._setWidth.call(this, width);
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.gradientDirty);
+ },
+ _setHeight: function (height) {
+ cc.LayerColor.prototype._setHeight.call(this, height);
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.gradientDirty);
+ },
+
+ /**
+ * Returns the starting color
+ * @return {cc.Color}
+ */
+ getStartColor: function () {
+ return cc.color(this._realColor);
+ },
+
+ /**
+ * Sets the starting color
+ * @param {cc.Color} color
+ * @example
+ * // Example
+ * myGradientLayer.setStartColor(cc.color(255,0,0));
+ * //set the starting gradient to red
+ */
+ setStartColor: function (color) {
+ this.color = color;
+ //update the color stops
+ var stops = this._colorStops;
+ if (stops && stops.length > 0) {
+ var selColor = stops[0].color;
+ selColor.r = color.r;
+ selColor.g = color.g;
+ selColor.b = color.b;
+ }
+ },
+
+ /**
+ * Sets the end gradient color
+ * @param {cc.Color} color
+ * @example
+ * // Example
+ * myGradientLayer.setEndColor(cc.color(255,0,0));
+ * //set the ending gradient to red
+ */
+ setEndColor: function (color) {
+ var locColor = this._endColor;
+ locColor.r = color.r;
+ locColor.g = color.g;
+ locColor.b = color.b;
+ //update the color stops
+ var stops = this._colorStops;
+ if (stops && stops.length > 0) {
+ var selColor = stops[stops.length - 1].color;
+ selColor.r = color.r;
+ selColor.g = color.g;
+ selColor.b = color.b;
+ }
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty);
+ },
+
+ /**
+ * Returns the end color
+ * @return {cc.Color}
+ */
+ getEndColor: function () {
+ return cc.color(this._endColor);
+ },
+
+ /**
+ * Sets starting gradient opacity
+ * @param {Number} o from 0 to 255, 0 is transparent
+ */
+ setStartOpacity: function (o) {
+ this._startOpacity = o;
+ //update the color stops
+ var stops = this._colorStops;
+ if (stops && stops.length > 0)
+ stops[0].color.a = o;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty);
+ },
+
+ /**
+ * Returns the starting gradient opacity
+ * @return {Number}
+ */
+ getStartOpacity: function () {
+ return this._startOpacity;
+ },
+
+ /**
+ * Sets the end gradient opacity
+ * @param {Number} o
+ */
+ setEndOpacity: function (o) {
+ this._endOpacity = o;
+ var stops = this._colorStops;
+ if (stops && stops.length > 0)
+ stops[stops.length - 1].color.a = o;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty);
+ },
+
+ /**
+ * Returns the end gradient opacity
+ * @return {Number}
+ */
+ getEndOpacity: function () {
+ return this._endOpacity;
+ },
+
+ /**
+ * Sets the direction vector of the gradient
+ * @param {cc.Point} Var
+ */
+ setVector: function (Var) {
+ this._alongVector.x = Var.x;
+ this._alongVector.y = Var.y;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.gradientDirty);
+ },
+
+ /**
+ * Returns the direction vector of the gradient
+ * @return {cc.Point}
+ */
+ getVector: function () {
+ return cc.p(this._alongVector.x, this._alongVector.y);
+ },
+
+ /**
+ * Returns whether compressed interpolation is enabled
+ * @return {Boolean}
+ */
+ isCompressedInterpolation: function () {
+ return this._compressedInterpolation;
+ },
+
+ /**
+ * Sets whether compressed interpolation is enabled
+ * @param {Boolean} compress
+ */
+ setCompressedInterpolation: function (compress) {
+ this._compressedInterpolation = compress;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.gradientDirty);
+ },
+
+ /**
+ * Return an array of Object representing a colorStop for the gradient, if no stops was specified
+ * start & endColor will be provided as default values
+ * @example
+ * [{p: 0, color: cc.color.RED},{p: 1, color: cc.color.RED},...]
+ * @returns {Array}
+ */
+ getColorStops: function () {
+ return this._colorStops;
+ },
+ /**
+ * Set the colorStops to create the gradient using multiple point & color
+ *
+ * @param colorStops
+ *
+ * @example
+ * //startColor & endColor are for default and backward compatibility
+ * var layerGradient = new cc.LayerGradient(cc.color.RED, new cc.Color(255,0,0,0), cc.p(0, -1));
+ * layerGradient.setColorStops([{p:0, color: cc.color.RED},
+ * {p:.5, color: new cc.Color(0,0,0,0)},
+ * {p:1, color: cc.color.RED}]);
+ * //where p = A value between 0.0 and 1.0 that represents the position between start and end in a gradient
+ *
+ */
+ setColorStops: function (colorStops) {
+ this._colorStops = colorStops;
+ //todo need update the start color and end color
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty | cc.Node._dirtyFlags.opacityDirty | cc.Node._dirtyFlags.gradientDirty);
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.LayerGradient.CanvasRenderCmd(this);
+ else
+ return new cc.LayerGradient.WebGLRenderCmd(this);
+ }
+});
+
+/**
+ * Creates a gradient layer
+ * @deprecated since v3.0, please use the new construction instead
+ * @see cc.layerGradient
+ * @param {cc.Color} start starting color
+ * @param {cc.Color} end ending color
+ * @param {cc.Point|Null} v
+ * @param {Array|NULL} stops
+ * @return {cc.LayerGradient}
+ */
+cc.LayerGradient.create = function (start, end, v, stops) {
+ return new cc.LayerGradient(start, end, v, stops);
+};
+//LayerGradient - Getter Setter
+(function () {
+ var proto = cc.LayerGradient.prototype;
+ // Extended properties
+ /** @expose */
+ proto.startColor;
+ cc.defineGetterSetter(proto, "startColor", proto.getStartColor, proto.setStartColor);
+ /** @expose */
+ proto.endColor;
+ cc.defineGetterSetter(proto, "endColor", proto.getEndColor, proto.setEndColor);
+ /** @expose */
+ proto.startOpacity;
+ cc.defineGetterSetter(proto, "startOpacity", proto.getStartOpacity, proto.setStartOpacity);
+ /** @expose */
+ proto.endOpacity;
+ cc.defineGetterSetter(proto, "endOpacity", proto.getEndOpacity, proto.setEndOpacity);
+ /** @expose */
+ proto.vector;
+ cc.defineGetterSetter(proto, "vector", proto.getVector, proto.setVector);
+ /** @expose */
+ proto.colorStops;
+ cc.defineGetterSetter(proto, "colorStops", proto.getColorStops, proto.setColorStops);
+})();
+
+/**
+ * CCMultipleLayer is a CCLayer with the ability to multiplex it's children.
+ * Features:
+ * - It supports one or more children
+ * - Only one children will be active a time
+ * @class
+ * @extends cc.Layer
+ * @param {Array} layers an array of cc.Layer
+ * @example
+ * // Example
+ * var multiLayer = new cc.LayerMultiple(layer1, layer2, layer3);//any number of layers
+ */
+cc.LayerMultiplex = cc.Layer.extend(/** @lends cc.LayerMultiplex# */{
+ _enabledLayer: 0,
+ _layers: null,
+ _className: "LayerMultiplex",
+
+ /**
+ * Constructor of cc.LayerMultiplex
+ * @param {Array} layers an array of cc.Layer
+ */
+ ctor: function (layers) {
+ cc.Layer.prototype.ctor.call(this);
+ if (layers instanceof Array)
+ cc.LayerMultiplex.prototype.initWithLayers.call(this, layers);
+ else
+ cc.LayerMultiplex.prototype.initWithLayers.call(this, Array.prototype.slice.call(arguments));
+ },
+
+ /**
+ * Initialization of the layer multiplex, please do not call this function by yourself, you should pass the parameters to constructor to initialize a layer multiplex
+ * @param {Array} layers an array of cc.Layer
+ * @return {Boolean}
+ */
+ initWithLayers: function (layers) {
+ if ((layers.length > 0) && (layers[layers.length - 1] == null))
+ cc.log(cc._LogInfos.LayerMultiplex_initWithLayers);
+
+ this._layers = layers;
+ this._enabledLayer = 0;
+ this.addChild(this._layers[this._enabledLayer]);
+ return true;
+ },
+
+ /**
+ * Switches to a certain layer indexed by n.
+ * The current (old) layer will be removed from it's parent with 'cleanup:YES'.
+ * @param {Number} n the layer index to switch to
+ */
+ switchTo: function (n) {
+ if (n >= this._layers.length) {
+ cc.log(cc._LogInfos.LayerMultiplex_switchTo);
+ return;
+ }
+
+ this.removeChild(this._layers[this._enabledLayer], true);
+ this._enabledLayer = n;
+ this.addChild(this._layers[n]);
+ },
+
+ /**
+ * Release the current layer and switches to another layer indexed by n.
+ * The current (old) layer will be removed from it's parent with 'cleanup:YES'.
+ * @param {Number} n the layer index to switch to
+ */
+ switchToAndReleaseMe: function (n) {
+ if (n >= this._layers.length) {
+ cc.log(cc._LogInfos.LayerMultiplex_switchToAndReleaseMe);
+ return;
+ }
+
+ this.removeChild(this._layers[this._enabledLayer], true);
+
+ //[layers replaceObjectAtIndex:_enabledLayer withObject:[NSNull null]];
+ this._layers[this._enabledLayer] = null;
+ this._enabledLayer = n;
+ this.addChild(this._layers[n]);
+ },
+
+ /**
+ * Add a layer to the multiplex layers list
+ * @param {cc.Layer} layer
+ */
+ addLayer: function (layer) {
+ if (!layer) {
+ cc.log(cc._LogInfos.LayerMultiplex_addLayer);
+ return;
+ }
+ this._layers.push(layer);
+ }
+});
+
+/**
+ * Creates a cc.LayerMultiplex with one or more layers using a variable argument list.
+ * @deprecated since v3.0, please use new construction instead
+ * @see cc.LayerMultiplex
+ * @return {cc.LayerMultiplex|Null}
+ */
+cc.LayerMultiplex.create = function (/*Multiple Arguments*/) {
+ return new cc.LayerMultiplex(Array.prototype.slice.call(arguments));
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/core/layers/CCLayerCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/core/layers/CCLayerCanvasRenderCmd.js
new file mode 100644
index 0000000..3149895
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/layers/CCLayerCanvasRenderCmd.js
@@ -0,0 +1,419 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+//-----------------------//
+// 1. cc.Layer //
+// 2. cc.LayerColor //
+// 3. cc.LayerGradient //
+//-----------------------//
+
+/**
+ * cc.Layer's rendering objects of Canvas
+ */
+(function () {
+ //Layer's canvas render command
+ cc.Layer.CanvasRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._isBaked = false;
+ this._bakeSprite = null;
+ this._canUseDirtyRegion = true;
+ this._updateCache = 2; // 2: Updated child visit 1: Rendering 0: Nothing to do
+ };
+
+ var proto = cc.Layer.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ proto.constructor = cc.Layer.CanvasRenderCmd;
+ proto._layerCmdCtor = cc.Layer.CanvasRenderCmd;
+
+ proto._setCacheDirty = function (child) {
+ if (child && this._updateCache === 0)
+ this._updateCache = 2;
+ if (this._cacheDirty === false) {
+ this._cacheDirty = true;
+ var cachedP = this._cachedParent;
+ cachedP && cachedP !== this && cachedP._setNodeDirtyForCache && cachedP._setNodeDirtyForCache();
+ }
+ };
+
+ proto.updateStatus = function () {
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ if (locFlag & flags.orderDirty) {
+ this._cacheDirty = true;
+ if (this._updateCache === 0)
+ this._updateCache = 2;
+ this._dirtyFlag &= ~flags.orderDirty;
+ }
+
+ this.originUpdateStatus();
+ };
+
+ proto._syncStatus = function (parentCmd) {
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ // if (locFlag & flags.orderDirty) {
+ if (this._isBaked || locFlag & flags.orderDirty) {
+ this._cacheDirty = true;
+ if (this._updateCache === 0)
+ this._updateCache = 2;
+ this._dirtyFlag &= ~flags.orderDirty;
+ }
+ this._originSyncStatus(parentCmd);
+ };
+
+ proto.transform = function (parentCmd, recursive) {
+ if (!this._worldTransform) {
+ this._worldTransform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ }
+ var wt = this._worldTransform;
+ var a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty;
+ this.originTransform(parentCmd, recursive);
+ if (( wt.a !== a || wt.b !== b || wt.c !== c || wt.d !== d ) && this._updateCache === 0)
+ this._updateCache = 2;
+ };
+
+ proto.bake = function () {
+ if (!this._isBaked) {
+ this._needDraw = true;
+ cc.renderer.childrenOrderDirty = true;
+ //limit: 1. its children's blendfunc are invalid.
+ this._isBaked = this._cacheDirty = true;
+ if (this._updateCache === 0)
+ this._updateCache = 2;
+
+ var children = this._node._children;
+ for (var i = 0, len = children.length; i < len; i++)
+ children[i]._renderCmd._setCachedParent(this);
+
+ if (!this._bakeSprite) {
+ this._bakeSprite = new cc.BakeSprite();
+ this._bakeSprite.setAnchorPoint(0, 0);
+ }
+ }
+ };
+
+ proto.unbake = function () {
+ if (this._isBaked) {
+ cc.renderer.childrenOrderDirty = true;
+ this._needDraw = false;
+ this._isBaked = false;
+ this._cacheDirty = true;
+ if (this._updateCache === 0)
+ this._updateCache = 2;
+
+ var children = this._node._children;
+ for (var i = 0, len = children.length; i < len; i++)
+ children[i]._renderCmd._setCachedParent(null);
+ }
+ };
+
+ proto.isBaked = function () {
+ return this._isBaked;
+ };
+
+ proto.rendering = function () {
+ if (this._cacheDirty) {
+ var node = this._node;
+ var children = node._children, locBakeSprite = this._bakeSprite;
+
+ //compute the bounding box of the bake layer.
+ this.transform(this.getParentRenderCmd(), true);
+
+ var boundingBox = this._getBoundingBoxForBake();
+ boundingBox.width = 0 | (boundingBox.width + 0.5);
+ boundingBox.height = 0 | (boundingBox.height + 0.5);
+
+ var bakeContext = locBakeSprite.getCacheContext();
+ var ctx = bakeContext.getContext();
+
+ locBakeSprite.setPosition(boundingBox.x, boundingBox.y);
+
+ if (this._updateCache > 0) {
+ locBakeSprite.resetCanvasSize(boundingBox.width, boundingBox.height);
+ bakeContext.setOffset(0 - boundingBox.x, ctx.canvas.height - boundingBox.height + boundingBox.y);
+ //visit for canvas
+ node.sortAllChildren();
+ cc.renderer._turnToCacheMode(this.__instanceId);
+ for (var i = 0, len = children.length; i < len; i++) {
+ children[i].visit(this);
+ }
+ cc.renderer._renderingToCacheCanvas(bakeContext, this.__instanceId);
+ locBakeSprite.transform(); //because bake sprite's position was changed at rendering.
+ this._updateCache--;
+ }
+
+ this._cacheDirty = false;
+ }
+ };
+
+ proto._bakeForAddChild = function (child) {
+ if (child._parent === this._node && this._isBaked)
+ child._renderCmd._setCachedParent(this);
+ };
+
+ proto._getBoundingBoxForBake = function () {
+ var rect = null, node = this._node;
+
+ //query child's BoundingBox
+ if (!node._children || node._children.length === 0)
+ return cc.rect(0, 0, 10, 10);
+ var trans = node.getNodeToWorldTransform();
+
+ var locChildren = node._children;
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ var child = locChildren[i];
+ if (child && child._visible) {
+ if (rect) {
+ var childRect = child._getBoundingBoxToCurrentNode(trans);
+ if (childRect)
+ rect = cc.rectUnion(rect, childRect);
+ } else {
+ rect = child._getBoundingBoxToCurrentNode(trans);
+ }
+ }
+ }
+ return rect;
+ };
+})();
+
+/**
+ * cc.LayerColor's rendering objects of Canvas
+ */
+(function () {
+ //LayerColor's canvas render command
+ cc.LayerColor.CanvasRenderCmd = function (renderable) {
+ this._layerCmdCtor(renderable);
+ this._needDraw = true;
+ this._blendFuncStr = "source-over";
+ this._bakeRenderCmd = new cc.CustomRenderCmd(this, this._bakeRendering);
+ };
+ var proto = cc.LayerColor.CanvasRenderCmd.prototype = Object.create(cc.Layer.CanvasRenderCmd.prototype);
+ proto.constructor = cc.LayerColor.CanvasRenderCmd;
+
+ proto.unbake = function () {
+ cc.Layer.CanvasRenderCmd.prototype.unbake.call(this);
+ this._needDraw = true;
+ };
+
+ proto.rendering = function (ctx, scaleX, scaleY) {
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext(),
+ node = this._node,
+ curColor = this._displayedColor,
+ opacity = this._displayedOpacity / 255,
+ locWidth = node._contentSize.width,
+ locHeight = node._contentSize.height;
+
+ if (opacity === 0)
+ return;
+
+ wrapper.setCompositeOperation(this._blendFuncStr);
+ wrapper.setGlobalAlpha(opacity);
+ wrapper.setFillStyle("rgba(" + (0 | curColor.r) + "," + (0 | curColor.g) + ","
+ + (0 | curColor.b) + ", 1)"); //TODO: need cache the color string
+
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+ context.fillRect(0, 0, locWidth, -locHeight);
+
+ cc.g_NumberOfDraws++;
+ };
+
+ proto.updateBlendFunc = function (blendFunc) {
+ this._blendFuncStr = cc.Node.CanvasRenderCmd._getCompositeOperationByBlendFunc(blendFunc);
+ };
+
+ proto._updateSquareVertices =
+ proto._updateSquareVerticesWidth =
+ proto._updateSquareVerticesHeight = function () {};
+
+ proto._bakeRendering = function () {
+ if (this._cacheDirty) {
+ var node = this._node;
+ var locBakeSprite = this._bakeSprite, children = node._children;
+ var i, len = children.length;
+
+ //compute the bounding box of the bake layer.
+ this.transform(this.getParentRenderCmd(), true);
+ //compute the bounding box of the bake layer.
+ var boundingBox = this._getBoundingBoxForBake();
+ boundingBox.width = 0 | (boundingBox.width + 0.5);
+ boundingBox.height = 0 | (boundingBox.height + 0.5);
+
+ var bakeContext = locBakeSprite.getCacheContext();
+ var ctx = bakeContext.getContext();
+
+ locBakeSprite.setPosition(boundingBox.x, boundingBox.y);
+
+ if (this._updateCache > 0) {
+ ctx.fillStyle = bakeContext._currentFillStyle;
+ locBakeSprite.resetCanvasSize(boundingBox.width, boundingBox.height);
+ bakeContext.setOffset(0 - boundingBox.x, ctx.canvas.height - boundingBox.height + boundingBox.y);
+
+ var child;
+ cc.renderer._turnToCacheMode(this.__instanceId);
+ //visit for canvas
+ if (len > 0) {
+ node.sortAllChildren();
+ // draw children zOrder < 0
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder < 0)
+ child.visit(node);
+ else
+ break;
+ }
+ cc.renderer.pushRenderCommand(this);
+ for (; i < len; i++) {
+ children[i].visit(node);
+ }
+ } else
+ cc.renderer.pushRenderCommand(this);
+ cc.renderer._renderingToCacheCanvas(bakeContext, this.__instanceId);
+ locBakeSprite.transform();
+ this._updateCache--;
+ }
+ this._cacheDirty = false;
+ }
+ };
+
+ proto._getBoundingBoxForBake = function () {
+ var node = this._node;
+ //default size
+ var rect = cc.rect(0, 0, node._contentSize.width, node._contentSize.height);
+ var trans = node.getNodeToWorldTransform();
+ rect = cc.rectApplyAffineTransform(rect, node.getNodeToWorldTransform());
+
+ //query child's BoundingBox
+ if (!node._children || node._children.length === 0)
+ return rect;
+
+ var locChildren = node._children;
+ for (var i = 0; i < locChildren.length; i++) {
+ var child = locChildren[i];
+ if (child && child._visible) {
+ var childRect = child._getBoundingBoxToCurrentNode(trans);
+ rect = cc.rectUnion(rect, childRect);
+ }
+ }
+ return rect;
+ };
+})();
+
+/**
+ * cc.LayerGradient's rendering objects of Canvas
+ */
+(function () {
+ cc.LayerGradient.CanvasRenderCmd = function (renderable) {
+ cc.LayerColor.CanvasRenderCmd.call(this, renderable);
+ this._needDraw = true;
+ this._startPoint = cc.p(0, 0);
+ this._endPoint = cc.p(0, 0);
+ this._startStopStr = null;
+ this._endStopStr = null;
+ };
+ var proto = cc.LayerGradient.CanvasRenderCmd.prototype = Object.create(cc.LayerColor.CanvasRenderCmd.prototype);
+ proto.constructor = cc.LayerGradient.CanvasRenderCmd;
+
+ proto.rendering = function (ctx, scaleX, scaleY) {
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext(),
+ node = this._node,
+ opacity = this._displayedOpacity / 255;
+
+ if (opacity === 0)
+ return;
+
+ var locWidth = node._contentSize.width, locHeight = node._contentSize.height;
+ wrapper.setCompositeOperation(this._blendFuncStr);
+ wrapper.setGlobalAlpha(opacity);
+ var gradient = context.createLinearGradient(this._startPoint.x, this._startPoint.y, this._endPoint.x, this._endPoint.y);
+
+ if (node._colorStops) { //Should always fall here now
+ for (var i = 0; i < node._colorStops.length; i++) {
+ var stop = node._colorStops[i];
+ gradient.addColorStop(stop.p, this._colorStopsStr[i]);
+ }
+ } else {
+ gradient.addColorStop(0, this._startStopStr);
+ gradient.addColorStop(1, this._endStopStr);
+ }
+
+ wrapper.setFillStyle(gradient);
+
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+ context.fillRect(0, 0, locWidth, -locHeight);
+ cc.g_NumberOfDraws++;
+ };
+
+ proto.updateStatus = function () {
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ if (locFlag & flags.gradientDirty) {
+ this._dirtyFlag |= flags.colorDirty;
+ this._dirtyFlag &= ~flags.gradientDirty;
+ }
+
+ this.originUpdateStatus();
+ };
+
+ proto._syncStatus = function (parentCmd) {
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ if (locFlag & flags.gradientDirty) {
+ this._dirtyFlag |= flags.colorDirty;
+ this._dirtyFlag &= ~flags.gradientDirty;
+ }
+
+ this._originSyncStatus(parentCmd);
+ };
+
+ proto._updateColor = function () {
+ var node = this._node;
+ var contentSize = node._contentSize;
+ var tWidth = contentSize.width * 0.5, tHeight = contentSize.height * 0.5;
+
+ //fix the bug of gradient layer
+ var angle = cc.pAngleSigned(cc.p(0, -1), node._alongVector);
+ var p1 = cc.pRotateByAngle(cc.p(0, -1), cc.p(0, 0), angle);
+ var factor = Math.min(Math.abs(1 / p1.x), Math.abs(1 / p1.y));
+
+ this._startPoint.x = tWidth * (-p1.x * factor) + tWidth;
+ this._startPoint.y = tHeight * (p1.y * factor) - tHeight;
+ this._endPoint.x = tWidth * (p1.x * factor) + tWidth;
+ this._endPoint.y = tHeight * (-p1.y * factor) - tHeight;
+
+ var locStartColor = this._displayedColor, locEndColor = node._endColor;
+ var startOpacity = node._startOpacity / 255, endOpacity = node._endOpacity / 255;
+ this._startStopStr = "rgba(" + Math.round(locStartColor.r) + "," + Math.round(locStartColor.g) + ","
+ + Math.round(locStartColor.b) + "," + startOpacity.toFixed(4) + ")";
+ this._endStopStr = "rgba(" + Math.round(locEndColor.r) + "," + Math.round(locEndColor.g) + ","
+ + Math.round(locEndColor.b) + "," + endOpacity.toFixed(4) + ")";
+
+ if (node._colorStops) {
+ this._startOpacity = 0;
+ this._endOpacity = 0;
+
+ this._colorStopsStr = [];
+ for (var i = 0; i < node._colorStops.length; i++) {
+ var stopColor = node._colorStops[i].color;
+ var stopOpacity = stopColor.a == null ? 1 : stopColor.a / 255;
+ this._colorStopsStr.push("rgba(" + Math.round(stopColor.r) + "," + Math.round(stopColor.g) + ","
+ + Math.round(stopColor.b) + "," + stopOpacity.toFixed(4) + ")");
+ }
+ }
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/layers/CCLayerWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/core/layers/CCLayerWebGLRenderCmd.js
new file mode 100644
index 0000000..4acf7f2
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/layers/CCLayerWebGLRenderCmd.js
@@ -0,0 +1,328 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+//-----------------------//
+// 1. cc.Layer //
+// 2. cc.LayerColor //
+// 3. cc.LayerGradient //
+//-----------------------//
+
+/**
+ * cc.Layer's rendering objects of WebGL
+ */
+(function () {
+ cc.Layer.WebGLRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._isBaked = false;
+ };
+
+ var proto = cc.Layer.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ proto.constructor = cc.Layer.WebGLRenderCmd;
+ proto._layerCmdCtor = cc.Layer.WebGLRenderCmd;
+
+ proto.bake = function () {
+ };
+
+ proto.unbake = function () {
+ };
+
+ proto._bakeForAddChild = function () {
+ };
+})();
+
+/**
+ * cc.LayerColor's rendering objects of WebGL
+ */
+(function () {
+ var FLOAT_PER_VERTEX = 4;
+
+ cc.LayerColor.WebGLRenderCmd = function (renderable) {
+ this._layerCmdCtor(renderable);
+ this._needDraw = true;
+
+ this._matrix = null;
+
+ this.initData(4);
+ this._color = new Uint32Array(1);
+ this._vertexBuffer = null;
+
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_COLOR);
+ };
+ var proto = cc.LayerColor.WebGLRenderCmd.prototype = Object.create(cc.Layer.WebGLRenderCmd.prototype);
+ proto.constructor = cc.LayerColor.WebGLRenderCmd;
+
+ proto.initData = function (vertexCount) {
+ this._data = new ArrayBuffer(16 * vertexCount);
+ this._positionView = new Float32Array(this._data);
+ this._colorView = new Uint32Array(this._data);
+ this._dataDirty = true;
+ };
+
+ proto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
+
+ var node = this._node,
+ width = node._contentSize.width,
+ height = node._contentSize.height;
+
+ var pos = this._positionView;
+ pos[FLOAT_PER_VERTEX] = width; // br.x
+ pos[FLOAT_PER_VERTEX * 2 + 1] = height; // tl.y
+ pos[FLOAT_PER_VERTEX * 3] = width; // tr.x
+ pos[FLOAT_PER_VERTEX * 3 + 1] = height; // tr.y
+ pos[2].z =
+ pos[FLOAT_PER_VERTEX + 2] =
+ pos[FLOAT_PER_VERTEX * 2 + 2] =
+ pos[FLOAT_PER_VERTEX * 3 + 2] = node._vertexZ;
+
+ this._dataDirty = true;
+ };
+
+ proto._updateColor = function () {
+ var color = this._displayedColor;
+ this._color[0] = ((this._displayedOpacity << 24) | (color.b << 16) | (color.g << 8) | color.r);
+
+ var colors = this._colorView;
+ for (var i = 0; i < 4; i++) {
+ colors[i * FLOAT_PER_VERTEX + 3] = this._color[0];
+ }
+ this._dataDirty = true;
+ };
+
+ proto.rendering = function (ctx) {
+ var gl = ctx || cc._renderContext;
+ var node = this._node;
+
+ if (!this._matrix) {
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+ }
+
+ var wt = this._worldTransform;
+ this._matrix.mat[0] = wt.a;
+ this._matrix.mat[4] = wt.c;
+ this._matrix.mat[12] = wt.tx;
+ this._matrix.mat[1] = wt.b;
+ this._matrix.mat[5] = wt.d;
+ this._matrix.mat[13] = wt.ty;
+
+ if (this._dataDirty) {
+ if (!this._vertexBuffer) {
+ this._vertexBuffer = gl.createBuffer();
+ }
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this._data, gl.DYNAMIC_DRAW);
+ this._dataDirty = false;
+ }
+
+ this._glProgramState.apply(this._matrix);
+ cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
+
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 16, 0);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 16, 12);
+
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ };
+
+ proto.updateBlendFunc = function (blendFunc) {
+ };
+})();
+
+/**
+ * cc.LayerGradient's rendering objects of WebGL
+ */
+(function () {
+ var FLOAT_PER_VERTEX = 4;
+
+ cc.LayerGradient.WebGLRenderCmd = function (renderable) {
+ cc.LayerColor.WebGLRenderCmd.call(this, renderable);
+ this._needDraw = true;
+ this._clipRect = new cc.Rect();
+ this._clippingRectDirty = false;
+ };
+ var proto = cc.LayerGradient.WebGLRenderCmd.prototype = Object.create(cc.LayerColor.WebGLRenderCmd.prototype);
+ proto.constructor = cc.LayerGradient.WebGLRenderCmd;
+
+ proto.updateStatus = function () {
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ if (locFlag & flags.gradientDirty) {
+ this._dirtyFlag |= flags.colorDirty;
+ this._updateVertex();
+ this._dirtyFlag &= ~flags.gradientDirty;
+ }
+
+ this.originUpdateStatus();
+ };
+
+ proto._syncStatus = function (parentCmd) {
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ if (locFlag & flags.gradientDirty) {
+ this._dirtyFlag |= flags.colorDirty;
+ this._updateVertex();
+ this._dirtyFlag &= ~flags.gradientDirty;
+ }
+
+ this._originSyncStatus(parentCmd);
+ };
+
+ proto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
+ this._updateVertex();
+ };
+
+ proto._updateVertex = function () {
+ var node = this._node, stops = node._colorStops;
+ if (!stops || stops.length < 2)
+ return;
+
+ this._clippingRectDirty = true;
+ var i, stopsLen = stops.length, verticesLen = stopsLen * 2, contentSize = node._contentSize;
+ if (this._positionView.length / FLOAT_PER_VERTEX < verticesLen) {
+ this.initData(verticesLen);
+ }
+
+ //init vertex
+ var angle = Math.PI + cc.pAngleSigned(cc.p(0, -1), node._alongVector), locAnchor = cc.p(contentSize.width / 2, contentSize.height / 2);
+ var degrees = Math.round(cc.radiansToDegrees(angle));
+ var transMat = cc.affineTransformMake(1, 0, 0, 1, locAnchor.x, locAnchor.y);
+ transMat = cc.affineTransformRotate(transMat, angle);
+ var a, b;
+ if (degrees < 90) {
+ a = cc.p(-locAnchor.x, locAnchor.y);
+ b = cc.p(locAnchor.x, locAnchor.y);
+ } else if (degrees < 180) {
+ a = cc.p(locAnchor.x, locAnchor.y);
+ b = cc.p(locAnchor.x, -locAnchor.y);
+ } else if (degrees < 270) {
+ a = cc.p(locAnchor.x, -locAnchor.y);
+ b = cc.p(-locAnchor.x, -locAnchor.y);
+ } else {
+ a = cc.p(-locAnchor.x, -locAnchor.y);
+ b = cc.p(-locAnchor.x, locAnchor.y);
+ }
+
+ var sin = Math.sin(angle), cos = Math.cos(angle);
+ var tx = Math.abs((a.x * cos - a.y * sin) / locAnchor.x), ty = Math.abs((b.x * sin + b.y * cos) / locAnchor.y);
+ transMat = cc.affineTransformScale(transMat, tx, ty);
+ var pos = this._positionView;
+ for (i = 0; i < stopsLen; i++) {
+ var stop = stops[i], y = stop.p * contentSize.height;
+ var p0 = cc.pointApplyAffineTransform(-locAnchor.x, y - locAnchor.y, transMat);
+ var offset = i * 2 * FLOAT_PER_VERTEX;
+ pos[offset] = p0.x;
+ pos[offset + 1] = p0.y;
+ pos[offset + 2] = node._vertexZ;
+ var p1 = cc.pointApplyAffineTransform(contentSize.width - locAnchor.x, y - locAnchor.y, transMat);
+ offset += FLOAT_PER_VERTEX;
+ pos[offset] = p1.x;
+ pos[offset + 1] = p1.y;
+ pos[offset + 2] = node._vertexZ;
+ }
+
+ this._dataDirty = true;
+ };
+
+ proto._updateColor = function () {
+ var node = this._node, stops = node._colorStops;
+ if (!stops || stops.length < 2)
+ return;
+
+ var stopsLen = stops.length,
+ stopColor,
+ offset,
+ colors = this._colorView,
+ opacityf = this._displayedOpacity / 255;
+ for (i = 0; i < stopsLen; i++) {
+ stopColor = stops[i].color;
+ this._color[0] = ((stopColor.a*opacityf) << 24) | (stopColor.b << 16) | (stopColor.g << 8) | stopColor.r;
+
+ offset = i * 2 * FLOAT_PER_VERTEX;
+ colors[offset + 3] = this._color[0];
+ offset += FLOAT_PER_VERTEX;
+ colors[offset + 3] = this._color[0];
+ }
+ this._dataDirty = true;
+ };
+
+ proto.rendering = function (ctx) {
+ var context = ctx || cc._renderContext, node = this._node;
+
+ if (!this._matrix) {
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+ }
+
+ //it is too expensive to use stencil to clip, so it use Scissor,
+ //but it has a bug when layer rotated and layer's content size less than canvas's size.
+ var clippingRect = this._getClippingRect();
+ context.enable(context.SCISSOR_TEST);
+ cc.view.setScissorInPoints(clippingRect.x, clippingRect.y, clippingRect.width, clippingRect.height);
+
+ var wt = this._worldTransform;
+ this._matrix.mat[0] = wt.a;
+ this._matrix.mat[4] = wt.c;
+ this._matrix.mat[12] = wt.tx;
+ this._matrix.mat[1] = wt.b;
+ this._matrix.mat[5] = wt.d;
+ this._matrix.mat[13] = wt.ty;
+
+ if (this._dataDirty) {
+ if (!this._vertexBuffer) {
+ this._vertexBuffer = gl.createBuffer();
+ }
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this._data, gl.DYNAMIC_DRAW);
+ this._dataDirty = false;
+ }
+
+ //draw gradient layer
+ this._glProgramState.apply(this._matrix);
+ cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
+
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 16, 0);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 16, 12);
+
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+
+ context.disable(context.SCISSOR_TEST);
+ };
+
+ proto._getClippingRect = function () {
+ if (this._clippingRectDirty) {
+ var node = this._node;
+ var rect = cc.rect(0, 0, node._contentSize.width, node._contentSize.height);
+ var trans = node.getNodeToWorldTransform();
+ this._clipRect = cc._rectApplyAffineTransformIn(rect, trans);
+ }
+ return this._clipRect;
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/platform/CCClass.js b/frameworks/cocos2d-html5/cocos2d/core/platform/CCClass.js
new file mode 100644
index 0000000..be34ad9
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/platform/CCClass.js
@@ -0,0 +1,311 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+var cc = cc || {};
+
+/**
+ * Common getter setter configuration function
+ * @function
+ * @param {Object} proto A class prototype or an object to config
+ * @param {String} prop Property name
+ * @param {function} getter Getter function for the property
+ * @param {function} setter Setter function for the property
+ * @param {String} getterName Name of getter function for the property
+ * @param {String} setterName Name of setter function for the property
+ */
+cc.defineGetterSetter = function (proto, prop, getter, setter, getterName, setterName) {
+ if (proto.__defineGetter__) {
+ getter && proto.__defineGetter__(prop, getter);
+ setter && proto.__defineSetter__(prop, setter);
+ } else if (Object.defineProperty) {
+ var desc = {enumerable: false, configurable: true};
+ getter && (desc.get = getter);
+ setter && (desc.set = setter);
+ Object.defineProperty(proto, prop, desc);
+ } else {
+ throw new Error("browser does not support getters");
+ }
+
+ if (!getterName && !setterName) {
+ // Lookup getter/setter function
+ var hasGetter = (getter != null), hasSetter = (setter != undefined), props = Object.getOwnPropertyNames(proto);
+ for (var i = 0; i < props.length; i++) {
+ var name = props[i];
+
+ if ((proto.__lookupGetter__ ? proto.__lookupGetter__(name)
+ : Object.getOwnPropertyDescriptor(proto, name))
+ || typeof proto[name] !== "function")
+ continue;
+
+ var func = proto[name];
+ if (hasGetter && func === getter) {
+ getterName = name;
+ if (!hasSetter || setterName) break;
+ }
+ if (hasSetter && func === setter) {
+ setterName = name;
+ if (!hasGetter || getterName) break;
+ }
+ }
+ }
+
+ // Found getter/setter
+ var ctor = proto.constructor;
+ if (getterName) {
+ if (!ctor.__getters__) {
+ ctor.__getters__ = {};
+ }
+ ctor.__getters__[getterName] = prop;
+ }
+ if (setterName) {
+ if (!ctor.__setters__) {
+ ctor.__setters__ = {};
+ }
+ ctor.__setters__[setterName] = prop;
+ }
+};
+
+/**
+ * Create a new object and copy all properties in an exist object to the new object
+ * @function
+ * @param {object|Array} obj The source object
+ * @return {Array|object} The created object
+ */
+cc.clone = function (obj) {
+ // Cloning is better if the new object is having the same prototype chain
+ // as the copied obj (or otherwise, the cloned object is certainly going to
+ // have a different hidden class). Play with C1/C2 of the
+ // PerformanceVirtualMachineTests suite to see how this makes an impact
+ // under extreme conditions.
+ //
+ // Object.create(Object.getPrototypeOf(obj)) doesn't work well because the
+ // prototype lacks a link to the constructor (Carakan, V8) so the new
+ // object wouldn't have the hidden class that's associated with the
+ // constructor (also, for whatever reasons, utilizing
+ // Object.create(Object.getPrototypeOf(obj)) + Object.defineProperty is even
+ // slower than the original in V8). Therefore, we call the constructor, but
+ // there is a big caveat - it is possible that the this.init() in the
+ // constructor would throw with no argument. It is also possible that a
+ // derived class forgets to set "constructor" on the prototype. We ignore
+ // these possibities for and the ultimate solution is a standardized
+ // Object.clone().
+ var newObj = (obj.constructor) ? new obj.constructor : {};
+
+ // Assuming that the constuctor above initialized all properies on obj, the
+ // following keyed assignments won't turn newObj into dictionary mode
+ // because they're not *appending new properties* but *assigning existing
+ // ones* (note that appending indexed properties is another story). See
+ // CCClass.js for a link to the devils when the assumption fails.
+ for (var key in obj) {
+ var copy = obj[key];
+ // Beware that typeof null == "object" !
+ if (((typeof copy) === "object") && copy && !(copy instanceof cc.Node) && !(copy instanceof HTMLElement)) {
+ newObj[key] = cc.clone(copy);
+ } else {
+ newObj[key] = copy;
+ }
+ }
+ return newObj;
+};
+
+cc.inject = function (srcPrototype, destPrototype) {
+ for (var key in srcPrototype)
+ destPrototype[key] = srcPrototype[key];
+};
+
+/**
+ * @namespace
+ * @name ClassManager
+ */
+var ClassManager = function () {
+ var id = (0|(Math.random()*998));
+ var instanceId = (0|(Math.random()*998));
+
+ this.getNewID = function () {
+ return id++;
+ };
+
+ this.getNewInstanceId = function () {
+ return instanceId++;
+ };
+};
+var classManager = new ClassManager();
+
+/* Managed JavaScript Inheritance
+ * Based on John Resig's Simple JavaScript Inheritance http://ejohn.org/blog/simple-javascript-inheritance/
+ * MIT Licensed.
+ */
+(function () {
+ var fnTest = /\b_super\b/;
+
+ /**
+ * The base Class implementation (does nothing)
+ * @class
+ */
+ cc.Class = function () {
+ };
+
+ /**
+ * Create a new Class that inherits from this Class
+ * @static
+ * @param {object} props
+ * @return {function}
+ */
+ cc.Class.extend = function (props) {
+ var _super = this.prototype;
+
+ // Instantiate a base Class (but only create the instance,
+ // don't run the init constructor)
+ var prototype = Object.create(_super);
+
+ // Copy the properties over onto the new prototype. We make function
+ // properties non-eumerable as this makes typeof === 'function' check
+ // unnecessary in the for...in loop used 1) for generating Class()
+ // 2) for cc.clone and perhaps more. It is also required to make
+ // these function properties cacheable in Carakan.
+ var desc = {writable: true, enumerable: false, configurable: true};
+
+ // The dummy Class constructor
+ var Class;
+ if (cc.game.config && cc.game.config[cc.game.CONFIG_KEY.exposeClassName]) {
+ var constructor = "(function " + (props._className || "Class") + " (arg0, arg1, arg2, arg3, arg4, arg5) {\n";
+ constructor += " this.__instanceId = classManager.getNewInstanceId();\n";
+ constructor += " if (this.ctor) {\n";
+ constructor += " switch (arguments.length) {\n";
+ constructor += " case 0: this.ctor(); break;\n";
+ constructor += " case 1: this.ctor(arg0); break;\n";
+ constructor += " case 3: this.ctor(arg0, arg1, arg2); break;\n";
+ constructor += " case 4: this.ctor(arg0, arg1, arg2, arg3); break;\n";
+ constructor += " case 5: this.ctor(arg0, arg1, arg2, arg3, arg4); break;\n";
+ constructor += " default: this.ctor.apply(this, arguments);\n";
+ constructor += " }\n";
+ constructor += " }\n";
+ constructor += "})";
+ Class = eval(constructor);
+ }
+ else {
+ Class = function (arg0, arg1, arg2, arg3, arg4) {
+ this.__instanceId = classManager.getNewInstanceId();
+ if (this.ctor) {
+ switch (arguments.length) {
+ case 0: this.ctor(); break;
+ case 1: this.ctor(arg0); break;
+ case 2: this.ctor(arg0, arg1); break;
+ case 3: this.ctor(arg0, arg1, arg2); break;
+ case 4: this.ctor(arg0, arg1, arg2, arg3); break;
+ case 5: this.ctor(arg0, arg1, arg2, arg3, arg4); break;
+ default: this.ctor.apply(this, arguments);
+ }
+ }
+ };
+ }
+
+ desc.value = classManager.getNewID();
+ Object.defineProperty(prototype, '__pid', desc);
+
+ // Populate our constructed prototype object
+ Class.prototype = prototype;
+
+ // Enforce the constructor to be what we expect
+ desc.value = Class;
+ Object.defineProperty(prototype, 'constructor', desc);
+
+ // Copy getter/setter
+ this.__getters__ && (Class.__getters__ = cc.clone(this.__getters__));
+ this.__setters__ && (Class.__setters__ = cc.clone(this.__setters__));
+
+ for (var idx = 0, li = arguments.length; idx < li; ++idx) {
+ var prop = arguments[idx];
+ for (var name in prop) {
+ var isFunc = (typeof prop[name] === "function");
+ var override = (typeof _super[name] === "function");
+ var hasSuperCall = fnTest.test(prop[name]);
+
+ if (isFunc && override && hasSuperCall) {
+ desc.value = (function (name, fn) {
+ return function () {
+ var tmp = this._super;
+
+ // Add a new ._super() method that is the same method
+ // but on the super-Class
+ this._super = _super[name];
+
+ // The method only need to be bound temporarily, so we
+ // remove it when we're done executing
+ var ret = fn.apply(this, arguments);
+ this._super = tmp;
+
+ return ret;
+ };
+ })(name, prop[name]);
+ Object.defineProperty(prototype, name, desc);
+ } else if (isFunc) {
+ desc.value = prop[name];
+ Object.defineProperty(prototype, name, desc);
+ } else {
+ prototype[name] = prop[name];
+ }
+
+ if (isFunc) {
+ // Override registered getter/setter
+ var getter, setter, propertyName;
+ if (this.__getters__ && this.__getters__[name]) {
+ propertyName = this.__getters__[name];
+ for (var i in this.__setters__) {
+ if (this.__setters__[i] === propertyName) {
+ setter = i;
+ break;
+ }
+ }
+ cc.defineGetterSetter(prototype, propertyName, prop[name], prop[setter] ? prop[setter] : prototype[setter], name, setter);
+ }
+ if (this.__setters__ && this.__setters__[name]) {
+ propertyName = this.__setters__[name];
+ for (var i in this.__getters__) {
+ if (this.__getters__[i] === propertyName) {
+ getter = i;
+ break;
+ }
+ }
+ cc.defineGetterSetter(prototype, propertyName, prop[getter] ? prop[getter] : prototype[getter], prop[name], getter, name);
+ }
+ }
+ }
+ }
+
+ // And make this Class extendable
+ Class.extend = cc.Class.extend;
+
+ //add implementation method
+ Class.implement = function (prop) {
+ for (var name in prop) {
+ prototype[name] = prop[name];
+ }
+ };
+ return Class;
+ };
+})();
+
diff --git a/frameworks/cocos2d-html5/cocos2d/core/platform/CCCommon.js b/frameworks/cocos2d-html5/cocos2d/core/platform/CCCommon.js
new file mode 100644
index 0000000..b99ee95
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/platform/CCCommon.js
@@ -0,0 +1,248 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+var cc = cc || {};
+cc._tmp = cc._tmp || {};
+
+/**
+ * Function added for JS bindings compatibility. Not needed in cocos2d-html5.
+ * @function
+ * @param {object} jsObj subclass
+ * @param {object} superclass
+ */
+cc.associateWithNative = function (jsObj, superclass) {
+};
+
+/**
+ * Key map for keyboard event
+ *
+ * @constant
+ * @type {Object}
+ * @example
+ cc.eventManager.addListener({
+ event: cc.EventListener.KEYBOARD,
+ onKeyPressed: function(keyCode, event){
+ if (cc.KEY["a"] == keyCode) {
+ cc.log("A is pressed");
+ }
+ }
+ }, this);
+ */
+cc.KEY = {
+ none: 0,
+
+ // android
+ back: 6,
+ menu: 18,
+
+ backspace: 8,
+ tab: 9,
+
+ enter: 13,
+
+ shift: 16, //should use shiftkey instead
+ ctrl: 17, //should use ctrlkey
+ alt: 18, //should use altkey
+ pause: 19,
+ capslock: 20,
+
+ escape: 27,
+ space: 32,
+ pageup: 33,
+ pagedown: 34,
+ end: 35,
+ home: 36,
+ left: 37,
+ up: 38,
+ right: 39,
+ down: 40,
+ select: 41,
+
+ insert: 45,
+ Delete: 46,
+ 0: 48,
+ 1: 49,
+ 2: 50,
+ 3: 51,
+ 4: 52,
+ 5: 53,
+ 6: 54,
+ 7: 55,
+ 8: 56,
+ 9: 57,
+ a: 65,
+ b: 66,
+ c: 67,
+ d: 68,
+ e: 69,
+ f: 70,
+ g: 71,
+ h: 72,
+ i: 73,
+ j: 74,
+ k: 75,
+ l: 76,
+ m: 77,
+ n: 78,
+ o: 79,
+ p: 80,
+ q: 81,
+ r: 82,
+ s: 83,
+ t: 84,
+ u: 85,
+ v: 86,
+ w: 87,
+ x: 88,
+ y: 89,
+ z: 90,
+
+ num0: 96,
+ num1: 97,
+ num2: 98,
+ num3: 99,
+ num4: 100,
+ num5: 101,
+ num6: 102,
+ num7: 103,
+ num8: 104,
+ num9: 105,
+ '*': 106,
+ '+': 107,
+ '-': 109,
+ 'numdel': 110,
+ '/': 111,
+ f1: 112, //f1-f12 don't work on ie
+ f2: 113,
+ f3: 114,
+ f4: 115,
+ f5: 116,
+ f6: 117,
+ f7: 118,
+ f8: 119,
+ f9: 120,
+ f10: 121,
+ f11: 122,
+ f12: 123,
+
+ numlock: 144,
+ scrolllock: 145,
+
+ ';': 186,
+ semicolon: 186,
+ equal: 187,
+ '=': 187,
+ ',': 188,
+ comma: 188,
+ dash: 189,
+ '.': 190,
+ period: 190,
+ forwardslash: 191,
+ grave: 192,
+ '[': 219,
+ openbracket: 219,
+ backslash: 220,
+ ']': 221,
+ closebracket: 221,
+ quote: 222,
+
+ // gamepad control
+ dpadLeft: 1000,
+ dpadRight: 1001,
+ dpadUp: 1003,
+ dpadDown: 1004,
+ dpadCenter: 1005
+};
+
+/**
+ * Image Format:JPG
+ * @constant
+ * @type {Number}
+ */
+cc.FMT_JPG = 0;
+
+/**
+ * Image Format:PNG
+ * @constant
+ * @type {Number}
+ */
+cc.FMT_PNG = 1;
+
+/**
+ * Image Format:TIFF
+ * @constant
+ * @type {Number}
+ */
+cc.FMT_TIFF = 2;
+
+/**
+ * Image Format:RAWDATA
+ * @constant
+ * @type {Number}
+ */
+cc.FMT_RAWDATA = 3;
+
+/**
+ * Image Format:WEBP
+ * @constant
+ * @type {Number}
+ */
+cc.FMT_WEBP = 4;
+
+/**
+ * Image Format:UNKNOWN
+ * @constant
+ * @type {Number}
+ */
+cc.FMT_UNKNOWN = 5;
+
+/**
+ * get image format by image data
+ * @function
+ * @param {Array} imgData
+ * @returns {Number}
+ */
+cc.getImageFormatByData = function (imgData) {
+ // if it is a png file buffer.
+ if (imgData.length > 8 && imgData[0] === 0x89
+ && imgData[1] === 0x50
+ && imgData[2] === 0x4E
+ && imgData[3] === 0x47
+ && imgData[4] === 0x0D
+ && imgData[5] === 0x0A
+ && imgData[6] === 0x1A
+ && imgData[7] === 0x0A) {
+ return cc.FMT_PNG;
+ }
+
+ // if it is a tiff file buffer.
+ if (imgData.length > 2 && ((imgData[0] === 0x49 && imgData[1] === 0x49)
+ || (imgData[0] === 0x4d && imgData[1] === 0x4d)
+ || (imgData[0] === 0xff && imgData[1] === 0xd8))) {
+ return cc.FMT_TIFF;
+ }
+ return cc.FMT_UNKNOWN;
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/platform/CCConfig.js b/frameworks/cocos2d-html5/cocos2d/core/platform/CCConfig.js
new file mode 100644
index 0000000..b479515
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/platform/CCConfig.js
@@ -0,0 +1,281 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The current version of Cocos2d-JS being used.
+ * Please DO NOT remove this String, it is an important flag for bug tracking.
+ * If you post a bug to forum, please attach this flag.
+ * @type {String}
+ * @name cc.ENGINE_VERSION
+ */
+window["CocosEngine"] = cc.ENGINE_VERSION = "Cocos2d-JS v3.17";
+
+/**
+ *
+ * If enabled, the texture coordinates will be calculated by using this formula:
+ * - texCoord.left = (rect.x*2+1) / (texture.wide*2);
+ * - texCoord.right = texCoord.left + (rect.width*2-2)/(texture.wide*2);
+ *
+ * The same for bottom and top.
+ *
+ * This formula prevents artifacts by using 99% of the texture.
+ * The "correct" way to prevent artifacts is by using the spritesheet-artifact-fixer.py or a similar tool.
+ *
+ * Affected nodes:
+ * - cc.Sprite / cc.SpriteBatchNode and subclasses: cc.LabelBMFont, cc.TMXTiledMap
+ * - cc.LabelAtlas
+ * - cc.QuadParticleSystem
+ * - cc.TileMap
+ *
+ * To enabled set it to 1. Disabled by default.
+ * To modify it, in Web engine please refer to CCConfig.js, in JSB please refer to CCConfig.h
+ *
+ * @constant
+ * @type {Number}
+ */
+cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL = 0;
+
+/**
+ * Position of the FPS (Default: 0,0 (bottom-left corner))
+ * To modify it, in Web engine please refer to CCConfig.js, in JSB please refer to CCConfig.h
+ * @constant
+ * @type {cc.Point}
+ */
+cc.DIRECTOR_STATS_POSITION = cc.p(0, 0);
+
+/**
+ *
+ * Seconds between FPS updates.
+ * 0.5 seconds, means that the FPS number will be updated every 0.5 seconds.
+ * Having a bigger number means a more reliable FPS
+ *
+ * Default value: 0.1f
+ * To modify it, in Web engine please refer to CCConfig.js, in JSB please refer to CCConfig.h
+ *
+ * @constant
+ * @type {Number}
+ */
+cc.DIRECTOR_FPS_INTERVAL = 0.5;
+
+/**
+ *
+ * If enabled, the cc.Node objects (cc.Sprite, cc.Label,etc) will be able to render in subpixels.
+ * If disabled, integer pixels will be used.
+ *
+ * To enable set it to 1. Enabled by default.
+ * To modify it, in Web engine please refer to CCConfig.js, in JSB please refer to CCConfig.h
+ *
+ * @constant
+ * @type {Number}
+ */
+cc.COCOSNODE_RENDER_SUBPIXEL = 1;
+
+/**
+ *
+ * If enabled, the cc.Sprite objects rendered with cc.SpriteBatchNode will be able to render in subpixels.
+ * If disabled, integer pixels will be used.
+ *
+ * To enable set it to 1. Enabled by default.
+ * To modify it, in Web engine please refer to CCConfig.js, in JSB please refer to CCConfig.h
+ *
+ * @constant
+ * @type {Number}
+ */
+cc.SPRITEBATCHNODE_RENDER_SUBPIXEL = 1;
+
+/**
+ *
+ * If most of your images have pre-multiplied alpha, set it to 1 (if you are going to use .PNG/.JPG file images).
+ * Only set to 0 if ALL your images by-pass Apple UIImage loading system (eg: if you use libpng or PVR images)
+ *
+ * To enable set it to a value different than 0. Enabled by default.
+ * To modify it, in Web engine please refer to CCConfig.js, in JSB please refer to CCConfig.h
+ *
+ * @constant
+ * @type {Number}
+ */
+cc.OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA = 1;
+
+/**
+ *
+ * Use GL_TRIANGLE_STRIP instead of GL_TRIANGLES when rendering the texture atlas.
+ * It seems it is the recommend way, but it is much slower, so, enable it at your own risk
+ *
+ * To enable set it to a value different than 0. Disabled by default.
+ * To modify it, in Web engine please refer to CCConfig.js, in JSB please refer to CCConfig.h
+ *
+ * @constant
+ * @type {Number}
+ */
+cc.TEXTURE_ATLAS_USE_TRIANGLE_STRIP = 0;
+
+/**
+ *
+ * By default, cc.TextureAtlas (used by many cocos2d classes) will use VAO (Vertex Array Objects).
+ * Apple recommends its usage but they might consume a lot of memory, specially if you use many of them.
+ * So for certain cases, where you might need hundreds of VAO objects, it might be a good idea to disable it.
+ *
+ * To disable it set it to 0. disable by default.(Not Supported on WebGL)
+ * To modify it, in Web engine please refer to CCConfig.js, in JSB please refer to CCConfig.h
+ *
+ * @constant
+ * @type {Number}
+ */
+cc.TEXTURE_ATLAS_USE_VAO = 0;
+
+/**
+ *
+ * If enabled, NPOT textures will be used where available. Only 3rd gen (and newer) devices support NPOT textures.
+ * NPOT textures have the following limitations:
+ * - They can't have mipmaps
+ * - They only accept GL_CLAMP_TO_EDGE in GL_TEXTURE_WRAP_{S,T}
+ *
+ * To enable set it to a value different than 0. Disabled by default.
+ *
+ * This value governs only the PNG, GIF, BMP, images.
+ * This value DOES NOT govern the PVR (PVR.GZ, PVR.CCZ) files. If NPOT PVR is loaded, then it will create an NPOT texture ignoring this value.
+ * To modify it, in Web engine please refer to CCConfig.js, in JSB please refer to CCConfig.h
+ *
+ * @constant
+ * @type {Number}
+ * @deprecated This value will be removed in 1.1 and NPOT textures will be loaded by default if the device supports it.
+ */
+cc.TEXTURE_NPOT_SUPPORT = 0;
+
+/**
+ *
+ * It's the suffix that will be appended to the files in order to load "retina display" images.
+ *
+ * On an iPhone4 with Retina Display support enabled, the file @"sprite-hd.png" will be loaded instead of @"sprite.png".
+ * If the file doesn't exist it will use the non-retina display image.
+ *
+ * Platforms: Only used on Retina Display devices like iPhone 4.
+ *
+ * @constant
+ * @type {String}
+ */
+cc.RETINA_DISPLAY_FILENAME_SUFFIX = "-hd";
+
+/**
+ *
+ * If enabled, it will use LA88 (Luminance Alpha 16-bit textures) for CCLabelTTF objects.
+ * If it is disabled, it will use A8 (Alpha 8-bit textures).
+ * LA88 textures are 6% faster than A8 textures, but they will consume 2x memory.
+ *
+ * This feature is enabled by default.
+ *
+ * @constant
+ * @type {Number}
+ */
+cc.USE_LA88_LABELS = 1;
+
+/**
+ *
+ * If enabled, all subclasses of cc.Sprite will draw a bounding box
+ * Useful for debugging purposes only. It is recommend to leave it disabled.
+ *
+ * To enable set it to a value different than 0. Disabled by default:
+ * 0 -- disabled
+ * 1 -- draw bounding box
+ * 2 -- draw texture box
+ *
+ * @constant
+ * @type {Number}
+ */
+cc.SPRITE_DEBUG_DRAW = 0;
+
+/**
+ *
+ * If enabled, all subclasses of cc.Sprite that are rendered using an cc.SpriteBatchNode draw a bounding box.
+ * Useful for debugging purposes only. It is recommend to leave it disabled.
+ *
+ * To enable set it to a value different than 0. Disabled by default.
+ *
+ * @constant
+ * @type {Number}
+ */
+cc.SPRITEBATCHNODE_DEBUG_DRAW = 0;
+
+/**
+ *
+ * If enabled, all subclasses of cc.LabelBMFont will draw a bounding box
+ * Useful for debugging purposes only. It is recommend to leave it disabled.
+ *
+ * To enable set it to a value different than 0. Disabled by default.
+ *
+ * @constant
+ * @type {Number}
+ */
+cc.LABELBMFONT_DEBUG_DRAW = 0;
+
+/**
+ *
+ * If enabled, all subclasses of cc.LabelAtlas will draw a bounding box
+ * Useful for debugging purposes only. It is recommend to leave it disabled.
+ *
+ * To enable set it to a value different than 0. Disabled by default.
+ *
+ * @constant
+ * @type {Number}
+ */
+cc.LABELATLAS_DEBUG_DRAW = 0;
+
+cc.DRAWNODE_TOTAL_VERTICES = 20000;
+
+/**
+ * Default engine
+ * @constant
+ * @type {String}
+ */
+cc.DEFAULT_ENGINE = cc.ENGINE_VERSION + "-canvas";
+
+/**
+ *
+ * If enabled, actions that alter the position property (eg: CCMoveBy, CCJumpBy, CCBezierBy, etc..) will be stacked.
+ * If you run 2 or more 'position' actions at the same time on a node, then end position will be the sum of all the positions.
+ * If disabled, only the last run action will take effect.
+ *
+ * @constant
+ * @type {number}
+ */
+cc.ENABLE_STACKABLE_ACTIONS = 1;
+
+/**
+ *
+ * If enabled, cocos2d will maintain an OpenGL state cache internally to avoid unnecessary switches.
+ * In order to use them, you have to use the following functions, instead of the the GL ones:
+ * - ccGLUseProgram() instead of glUseProgram()
+ * - ccGLDeleteProgram() instead of glDeleteProgram()
+ * - ccGLBlendFunc() instead of glBlendFunc()
+ *
+ * If this functionality is disabled, then ccGLUseProgram(), ccGLDeleteProgram(), ccGLBlendFunc() will call the GL ones, without using the cache.
+ * It is recommend to enable whenever possible to improve speed.
+ * If you are migrating your code from GL ES 1.1, then keep it disabled. Once all your code works as expected, turn it on.
+ *
+ * @constant
+ * @type {Number}
+ */
+cc.ENABLE_GL_STATE_CACHE = 1;
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/platform/CCEGLView.js b/frameworks/cocos2d-html5/cocos2d/core/platform/CCEGLView.js
new file mode 100755
index 0000000..f91e54b
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/platform/CCEGLView.js
@@ -0,0 +1,1411 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * @ignore
+ */
+cc.Touches = [];
+cc.TouchesIntergerDict = {};
+
+cc.DENSITYDPI_DEVICE = "device-dpi";
+cc.DENSITYDPI_HIGH = "high-dpi";
+cc.DENSITYDPI_MEDIUM = "medium-dpi";
+cc.DENSITYDPI_LOW = "low-dpi";
+
+var __BrowserGetter = {
+ init: function () {
+ this.html = document.documentElement;
+ },
+ availWidth: function (frame) {
+ if (!frame || frame === this.html)
+ return window.innerWidth;
+ else
+ return frame.clientWidth;
+ },
+ availHeight: function (frame) {
+ if (!frame || frame === this.html)
+ return window.innerHeight;
+ else
+ return frame.clientHeight;
+ },
+ meta: {
+ "width": "device-width"
+ },
+ adaptationType: cc.sys.browserType
+};
+
+if (window.navigator.userAgent.indexOf("OS 8_1_") > -1) //this mistake like MIUI, so use of MIUI treatment method
+ __BrowserGetter.adaptationType = cc.sys.BROWSER_TYPE_MIUI;
+
+if (cc.sys.os === cc.sys.OS_IOS) // All browsers are WebView
+ __BrowserGetter.adaptationType = cc.sys.BROWSER_TYPE_SAFARI;
+
+switch (__BrowserGetter.adaptationType) {
+ case cc.sys.BROWSER_TYPE_SAFARI:
+ __BrowserGetter.meta["minimal-ui"] = "true";
+ break;
+ case cc.sys.BROWSER_TYPE_CHROME:
+ __BrowserGetter.__defineGetter__("target-densitydpi", function () {
+ return cc.view._targetDensityDPI;
+ });
+ break;
+ case cc.sys.BROWSER_TYPE_MIUI:
+ __BrowserGetter.init = function (view) {
+ if (view.__resizeWithBrowserSize) return;
+ var resize = function () {
+ view.setDesignResolutionSize(
+ view._designResolutionSize.width,
+ view._designResolutionSize.height,
+ view._resolutionPolicy
+ );
+ window.removeEventListener("resize", resize, false);
+ };
+ window.addEventListener("resize", resize, false);
+ };
+ break;
+}
+
+var _scissorRect = null;
+
+/**
+ * cc.view is the singleton object which represents the game window.
+ * It's main task include:
+ * - Apply the design resolution policy
+ * - Provide interaction with the window, like resize event on web, retina display support, etc...
+ * - Manage the game view port which can be different with the window
+ * - Manage the content scale and translation
+ *
+ * Since the cc.view is a singleton, you don't need to call any constructor or create functions,
+ * the standard way to use it is by calling:
+ * - cc.view.methodName();
+ * @class
+ * @name cc.view
+ * @extend cc.Class
+ */
+cc.EGLView = cc.Class.extend(/** @lends cc.view# */{
+ _delegate: null,
+ // Size of parent node that contains cc.container and cc._canvas
+ _frameSize: null,
+ // resolution size, it is the size appropriate for the app resources.
+ _designResolutionSize: null,
+ _originalDesignResolutionSize: null,
+ // Viewport is the container's rect related to content's coordinates in pixel
+ _viewPortRect: null,
+ // The visible rect in content's coordinate in point
+ _visibleRect: null,
+ _retinaEnabled: false,
+ _autoFullScreen: false,
+ // The device's pixel ratio (for retina displays)
+ _devicePixelRatio: 1,
+ // the view name
+ _viewName: "",
+ // Custom callback for resize event
+ _resizeCallback: null,
+
+ _orientationChanging: true,
+ _resizing: false,
+
+ _scaleX: 1,
+ _originalScaleX: 1,
+ _scaleY: 1,
+ _originalScaleY: 1,
+
+ _isRotated: false,
+ _orientation: 3,
+
+ _resolutionPolicy: null,
+ _rpExactFit: null,
+ _rpShowAll: null,
+ _rpNoBorder: null,
+ _rpFixedHeight: null,
+ _rpFixedWidth: null,
+ _initialized: false,
+
+ _contentTranslateLeftTop: null,
+
+ // Parent node that contains cc.container and cc._canvas
+ _frame: null,
+ _frameZoomFactor: 1.0,
+ __resizeWithBrowserSize: false,
+ _isAdjustViewPort: true,
+ _targetDensityDPI: null,
+
+ /**
+ * Constructor of cc.EGLView
+ */
+ ctor: function () {
+ var _t = this, d = document, _strategyer = cc.ContainerStrategy, _strategy = cc.ContentStrategy;
+
+ __BrowserGetter.init(this);
+
+ _t._frame = (cc.container.parentNode === d.body) ? d.documentElement : cc.container.parentNode;
+ _t._frameSize = cc.size(0, 0);
+ _t._initFrameSize();
+
+ var w = cc._canvas.width, h = cc._canvas.height;
+ _t._designResolutionSize = cc.size(w, h);
+ _t._originalDesignResolutionSize = cc.size(w, h);
+ _t._viewPortRect = cc.rect(0, 0, w, h);
+ _t._visibleRect = cc.rect(0, 0, w, h);
+ _t._contentTranslateLeftTop = {left: 0, top: 0};
+ _t._viewName = "Cocos2dHTML5";
+
+ var sys = cc.sys;
+ cc.visibleRect && cc.visibleRect.init(_t._visibleRect);
+
+ // Setup system default resolution policies
+ _t._rpExactFit = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.EXACT_FIT);
+ _t._rpShowAll = new cc.ResolutionPolicy(_strategyer.PROPORTION_TO_FRAME, _strategy.SHOW_ALL);
+ _t._rpNoBorder = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.NO_BORDER);
+ _t._rpFixedHeight = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.FIXED_HEIGHT);
+ _t._rpFixedWidth = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.FIXED_WIDTH);
+
+ _t._targetDensityDPI = cc.DENSITYDPI_HIGH;
+
+ if (sys.isMobile) {
+ window.addEventListener('orientationchange', this._orientationChange);
+ } else {
+ this._orientationChanging = false;
+ }
+ },
+
+ // Resize helper functions
+ _resizeEvent: function () {
+ var view;
+ if (this.setDesignResolutionSize) {
+ view = this;
+ } else {
+ view = cc.view;
+ }
+ if (view._orientationChanging) {
+ return;
+ }
+
+ // Check frame size changed or not
+ var prevFrameW = view._frameSize.width, prevFrameH = view._frameSize.height, prevRotated = view._isRotated;
+ if (cc.sys.isMobile) {
+ var containerStyle = cc.game.container.style,
+ margin = containerStyle.margin;
+ containerStyle.margin = '0';
+ containerStyle.display = 'none';
+ view._initFrameSize();
+ containerStyle.margin = margin;
+ containerStyle.display = 'block';
+ }
+ else {
+ view._initFrameSize();
+ }
+ if (view._isRotated === prevRotated && view._frameSize.width === prevFrameW && view._frameSize.height === prevFrameH)
+ return;
+
+ // Frame size changed, do resize works
+ var width = view._originalDesignResolutionSize.width;
+ var height = view._originalDesignResolutionSize.height;
+ view._resizing = true;
+ if (width > 0) {
+ view.setDesignResolutionSize(width, height, view._resolutionPolicy);
+ }
+ view._resizing = false;
+
+ cc.eventManager.dispatchCustomEvent('canvas-resize');
+ if (view._resizeCallback) {
+ view._resizeCallback.call();
+ }
+ },
+
+ _orientationChange: function () {
+ cc.view._orientationChanging = true;
+ if (cc.sys.isMobile) {
+ cc.game.container.style.display = "none";
+ }
+ setTimeout(function () {
+ cc.view._orientationChanging = false;
+ cc.view._resizeEvent();
+ }, 300);
+ },
+
+ /**
+ *
+ * Sets view's target-densitydpi for android mobile browser. it can be set to:
+ * 1. cc.DENSITYDPI_DEVICE, value is "device-dpi"
+ * 2. cc.DENSITYDPI_HIGH, value is "high-dpi" (default value)
+ * 3. cc.DENSITYDPI_MEDIUM, value is "medium-dpi" (browser's default value)
+ * 4. cc.DENSITYDPI_LOW, value is "low-dpi"
+ * 5. Custom value, e.g: "480"
+ *
+ * @param {String} densityDPI
+ */
+ setTargetDensityDPI: function (densityDPI) {
+ this._targetDensityDPI = densityDPI;
+ this._adjustViewportMeta();
+ },
+
+ /**
+ * Returns the current target-densitydpi value of cc.view.
+ * @returns {String}
+ */
+ getTargetDensityDPI: function () {
+ return this._targetDensityDPI;
+ },
+
+ /**
+ * Sets whether resize canvas automatically when browser's size changed.
+ * Useful only on web.
+ * @param {Boolean} enabled Whether enable automatic resize with browser's resize event
+ */
+ resizeWithBrowserSize: function (enabled) {
+ if (enabled) {
+ //enable
+ if (!this.__resizeWithBrowserSize) {
+ this.__resizeWithBrowserSize = true;
+ window.addEventListener('resize', this._resizeEvent);
+ }
+ } else {
+ //disable
+ if (this.__resizeWithBrowserSize) {
+ this.__resizeWithBrowserSize = false;
+ window.removeEventListener('resize', this._resizeEvent);
+ }
+ }
+ },
+
+ /**
+ * Sets the callback function for cc.view's resize action,
+ * this callback will be invoked before applying resolution policy,
+ * so you can do any additional modifications within the callback.
+ * Useful only on web.
+ * @param {Function|null} callback The callback function
+ */
+ setResizeCallback: function (callback) {
+ if (typeof callback === 'function' || callback == null) {
+ this._resizeCallback = callback;
+ }
+ },
+
+ /**
+ * Sets the orientation of the game, it can be landscape, portrait or auto.
+ * When set it to landscape or portrait, and screen w/h ratio doesn't fit,
+ * cc.view will automatically rotate the game canvas using CSS.
+ * Note that this function doesn't have any effect in native,
+ * in native, you need to set the application orientation in native project settings
+ * @param {Number} orientation - Possible values: cc.ORIENTATION_LANDSCAPE | cc.ORIENTATION_PORTRAIT | cc.ORIENTATION_AUTO
+ */
+ setOrientation: function (orientation) {
+ orientation = orientation & cc.ORIENTATION_AUTO;
+ if (orientation && this._orientation !== orientation) {
+ this._orientation = orientation;
+ if (this._resolutionPolicy) {
+ var designWidth = this._originalDesignResolutionSize.width;
+ var designHeight = this._originalDesignResolutionSize.height;
+ this.setDesignResolutionSize(designWidth, designHeight, this._resolutionPolicy);
+ }
+ }
+ },
+
+ setDocumentPixelWidth: function (width) {
+ // Set viewport's width
+ this._setViewportMeta({"width": width}, true);
+
+ // Set body width to the exact pixel resolution
+ document.documentElement.style.width = width + 'px';
+ document.body.style.width = "100%";
+
+ // Reset the resolution size and policy
+ this.setDesignResolutionSize(this._designResolutionSize.width, this._designResolutionSize.height, this._resolutionPolicy);
+ },
+
+ _initFrameSize: function () {
+ var locFrameSize = this._frameSize;
+ var w = __BrowserGetter.availWidth(this._frame);
+ var h = __BrowserGetter.availHeight(this._frame);
+ var isLandscape = w >= h;
+
+ if (!cc.sys.isMobile ||
+ (isLandscape && this._orientation & cc.ORIENTATION_LANDSCAPE) ||
+ (!isLandscape && this._orientation & cc.ORIENTATION_PORTRAIT)) {
+ locFrameSize.width = w;
+ locFrameSize.height = h;
+ cc.container.style['-webkit-transform'] = 'rotate(0deg)';
+ cc.container.style.transform = 'rotate(0deg)';
+ this._isRotated = false;
+ }
+ else {
+ locFrameSize.width = h;
+ locFrameSize.height = w;
+ cc.container.style['-webkit-transform'] = 'rotate(90deg)';
+ cc.container.style.transform = 'rotate(90deg)';
+ cc.container.style['-webkit-transform-origin'] = '0px 0px 0px';
+ cc.container.style.transformOrigin = '0px 0px 0px';
+ this._isRotated = true;
+ }
+ },
+
+ // hack
+ _adjustSizeKeepCanvasSize: function () {
+ var designWidth = this._originalDesignResolutionSize.width;
+ var designHeight = this._originalDesignResolutionSize.height;
+ if (designWidth > 0)
+ this.setDesignResolutionSize(designWidth, designHeight, this._resolutionPolicy);
+ },
+
+ _setViewportMeta: function (metas, overwrite) {
+ var vp = document.getElementById("cocosMetaElement");
+ if (vp && overwrite) {
+ document.head.removeChild(vp);
+ }
+
+ var elems = document.getElementsByName("viewport"),
+ currentVP = elems ? elems[0] : null,
+ content, key, pattern;
+
+ content = currentVP ? currentVP.content : "";
+ vp = vp || document.createElement("meta");
+ vp.id = "cocosMetaElement";
+ vp.name = "viewport";
+ vp.content = "";
+
+ for (key in metas) {
+ if (content.indexOf(key) == -1) {
+ content += "," + key + "=" + metas[key];
+ }
+ else if (overwrite) {
+ pattern = new RegExp(key + "\s*=\s*[^,]+");
+ content.replace(pattern, key + "=" + metas[key]);
+ }
+ }
+ if (/^,/.test(content))
+ content = content.substr(1);
+
+ vp.content = content;
+ // For adopting certain android devices which don't support second viewport
+ if (currentVP)
+ currentVP.content = content;
+
+ document.head.appendChild(vp);
+ },
+
+ _adjustViewportMeta: function () {
+ if (this._isAdjustViewPort) {
+ this._setViewportMeta(__BrowserGetter.meta, false);
+ // Only adjust viewport once
+ this._isAdjustViewPort = false;
+ }
+ },
+
+ // RenderTexture hacker
+ _setScaleXYForRenderTexture: function () {
+ //hack for RenderTexture on canvas mode when adapting multiple resolution resources
+ var scaleFactor = cc.contentScaleFactor();
+ this._scaleX = scaleFactor;
+ this._scaleY = scaleFactor;
+ },
+
+ // Other helper functions
+ _resetScale: function () {
+ this._scaleX = this._originalScaleX;
+ this._scaleY = this._originalScaleY;
+ },
+
+ // Useless, just make sure the compatibility temporarily, should be removed
+ _adjustSizeToBrowser: function () {
+ },
+
+ initialize: function () {
+ this._initialized = true;
+ },
+
+ /**
+ * Sets whether the engine modify the "viewport" meta in your web page.
+ * It's enabled by default, we strongly suggest you not to disable it.
+ * And even when it's enabled, you can still set your own "viewport" meta, it won't be overridden
+ * Only useful on web
+ * @param {Boolean} enabled Enable automatic modification to "viewport" meta
+ */
+ adjustViewPort: function (enabled) {
+ this._isAdjustViewPort = enabled;
+ },
+
+ /**
+ * Retina support is enabled by default for Apple device but disabled for other devices,
+ * it takes effect only when you called setDesignResolutionPolicy
+ * Only useful on web
+ * @param {Boolean} enabled Enable or disable retina display
+ */
+ enableRetina: function (enabled) {
+ this._retinaEnabled = !!enabled;
+ },
+
+ /**
+ * Check whether retina display is enabled.
+ * Only useful on web
+ * @return {Boolean}
+ */
+ isRetinaEnabled: function () {
+ return this._retinaEnabled;
+ },
+
+ /**
+ * If enabled, the application will try automatically to enter full screen mode on mobile devices
+ * You can pass true as parameter to enable it and disable it by passing false.
+ * Only useful on web
+ * @param {Boolean} enabled Enable or disable auto full screen on mobile devices
+ */
+ enableAutoFullScreen: function (enabled) {
+ if (enabled && enabled !== this._autoFullScreen && cc.sys.isMobile && this._frame === document.documentElement) {
+ // Automatically full screen when user touches on mobile version
+ this._autoFullScreen = true;
+ cc.screen.autoFullScreen(this._frame);
+ }
+ else {
+ this._autoFullScreen = false;
+ }
+ },
+
+ /**
+ * Check whether auto full screen is enabled.
+ * Only useful on web
+ * @return {Boolean} Auto full screen enabled or not
+ */
+ isAutoFullScreenEnabled: function () {
+ return this._autoFullScreen;
+ },
+
+ /**
+ * Get whether render system is ready(no matter opengl or canvas),
+ * this name is for the compatibility with cocos2d-x, subclass must implement this method.
+ * @return {Boolean}
+ */
+ isOpenGLReady: function () {
+ return (cc.game.canvas && cc._renderContext);
+ },
+
+ /*
+ * Set zoom factor for frame. This method is for debugging big resolution (e.g.new ipad) app on desktop.
+ * @param {Number} zoomFactor
+ */
+ setFrameZoomFactor: function (zoomFactor) {
+ this._frameZoomFactor = zoomFactor;
+ this.centerWindow();
+ cc.director.setProjection(cc.director.getProjection());
+ },
+
+ /**
+ * Exchanges the front and back buffers, subclass must implement this method.
+ */
+ swapBuffers: function () {
+ },
+
+ /**
+ * Open or close IME keyboard , subclass must implement this method.
+ * @param {Boolean} isOpen
+ */
+ setIMEKeyboardState: function (isOpen) {
+ },
+
+ /**
+ * Sets the resolution translate on EGLView
+ * @param {Number} offsetLeft
+ * @param {Number} offsetTop
+ */
+ setContentTranslateLeftTop: function (offsetLeft, offsetTop) {
+ this._contentTranslateLeftTop = {left: offsetLeft, top: offsetTop};
+ },
+
+ /**
+ * Returns the resolution translate on EGLView
+ * @return {cc.Size|Object}
+ */
+ getContentTranslateLeftTop: function () {
+ return this._contentTranslateLeftTop;
+ },
+
+ /**
+ * Returns the canvas size of the view.
+ * On native platforms, it returns the screen size since the view is a fullscreen view.
+ * On web, it returns the size of the canvas element.
+ * @return {cc.Size}
+ */
+ getCanvasSize: function () {
+ return cc.size(cc._canvas.width, cc._canvas.height);
+ },
+
+ /**
+ * Returns the frame size of the view.
+ * On native platforms, it returns the screen size since the view is a fullscreen view.
+ * On web, it returns the size of the canvas's outer DOM element.
+ * @return {cc.Size}
+ */
+ getFrameSize: function () {
+ return cc.size(this._frameSize.width, this._frameSize.height);
+ },
+
+ /**
+ * On native, it sets the frame size of view.
+ * On web, it sets the size of the canvas's outer DOM element.
+ * @param {Number} width
+ * @param {Number} height
+ */
+ setFrameSize: function (width, height) {
+ this._frameSize.width = width;
+ this._frameSize.height = height;
+ this._frame.style.width = width + "px";
+ this._frame.style.height = height + "px";
+ this._resizeEvent();
+ cc.director.setProjection(cc.director.getProjection());
+ },
+
+ /**
+ * Returns the visible area size of the view port.
+ * @return {cc.Size}
+ */
+ getVisibleSize: function () {
+ return cc.size(this._visibleRect.width, this._visibleRect.height);
+ },
+
+ /**
+ * Returns the visible area size of the view port.
+ * @return {cc.Size}
+ */
+ getVisibleSizeInPixel: function () {
+ return cc.size( this._visibleRect.width * this._scaleX,
+ this._visibleRect.height * this._scaleY );
+ },
+
+ /**
+ * Returns the visible origin of the view port.
+ * @return {cc.Point}
+ */
+ getVisibleOrigin: function () {
+ return cc.p(this._visibleRect.x, this._visibleRect.y);
+ },
+
+ /**
+ * Returns the visible origin of the view port.
+ * @return {cc.Point}
+ */
+ getVisibleOriginInPixel: function () {
+ return cc.p(this._visibleRect.x * this._scaleX,
+ this._visibleRect.y * this._scaleY);
+ },
+
+ /**
+ * Returns whether developer can set content's scale factor.
+ * @return {Boolean}
+ */
+ canSetContentScaleFactor: function () {
+ return true;
+ },
+
+ /**
+ * Returns the current resolution policy
+ * @see cc.ResolutionPolicy
+ * @return {cc.ResolutionPolicy}
+ */
+ getResolutionPolicy: function () {
+ return this._resolutionPolicy;
+ },
+
+ /**
+ * Sets the current resolution policy
+ * @see cc.ResolutionPolicy
+ * @param {cc.ResolutionPolicy|Number} resolutionPolicy
+ */
+ setResolutionPolicy: function (resolutionPolicy) {
+ var _t = this;
+ if (resolutionPolicy instanceof cc.ResolutionPolicy) {
+ _t._resolutionPolicy = resolutionPolicy;
+ }
+ // Ensure compatibility with JSB
+ else {
+ var _locPolicy = cc.ResolutionPolicy;
+ if (resolutionPolicy === _locPolicy.EXACT_FIT)
+ _t._resolutionPolicy = _t._rpExactFit;
+ if (resolutionPolicy === _locPolicy.SHOW_ALL)
+ _t._resolutionPolicy = _t._rpShowAll;
+ if (resolutionPolicy === _locPolicy.NO_BORDER)
+ _t._resolutionPolicy = _t._rpNoBorder;
+ if (resolutionPolicy === _locPolicy.FIXED_HEIGHT)
+ _t._resolutionPolicy = _t._rpFixedHeight;
+ if (resolutionPolicy === _locPolicy.FIXED_WIDTH)
+ _t._resolutionPolicy = _t._rpFixedWidth;
+ }
+ },
+
+ /**
+ * Sets the resolution policy with designed view size in points.
+ * The resolution policy include:
+ * [1] ResolutionExactFit Fill screen by stretch-to-fit: if the design resolution ratio of width to height is different from the screen resolution ratio, your game view will be stretched.
+ * [2] ResolutionNoBorder Full screen without black border: if the design resolution ratio of width to height is different from the screen resolution ratio, two areas of your game view will be cut.
+ * [3] ResolutionShowAll Full screen with black border: if the design resolution ratio of width to height is different from the screen resolution ratio, two black borders will be shown.
+ * [4] ResolutionFixedHeight Scale the content's height to screen's height and proportionally scale its width
+ * [5] ResolutionFixedWidth Scale the content's width to screen's width and proportionally scale its height
+ * [cc.ResolutionPolicy] [Web only feature] Custom resolution policy, constructed by cc.ResolutionPolicy
+ * @param {Number} width Design resolution width.
+ * @param {Number} height Design resolution height.
+ * @param {cc.ResolutionPolicy|Number} resolutionPolicy The resolution policy desired
+ */
+ setDesignResolutionSize: function (width, height, resolutionPolicy) {
+ // Defensive code
+ if (!(width > 0 || height > 0)) {
+ cc.log(cc._LogInfos.EGLView_setDesignResolutionSize);
+ return;
+ }
+
+ this.setResolutionPolicy(resolutionPolicy);
+ var policy = this._resolutionPolicy;
+ if (policy) {
+ policy.preApply(this);
+ }
+
+ // Reinit frame size
+ if (cc.sys.isMobile)
+ this._adjustViewportMeta();
+
+ // If resizing, then frame size is already initialized, this logic should be improved
+ if (!this._resizing)
+ this._initFrameSize();
+
+ if (!policy) {
+ cc.log(cc._LogInfos.EGLView_setDesignResolutionSize_2);
+ return;
+ }
+
+ this._originalDesignResolutionSize.width = this._designResolutionSize.width = width;
+ this._originalDesignResolutionSize.height = this._designResolutionSize.height = height;
+
+ var result = policy.apply(this, this._designResolutionSize);
+
+ if (result.scale && result.scale.length === 2) {
+ this._scaleX = result.scale[0];
+ this._scaleY = result.scale[1];
+ }
+
+ if (result.viewport) {
+ var vp = this._viewPortRect,
+ vb = this._visibleRect,
+ rv = result.viewport;
+
+ vp.x = rv.x;
+ vp.y = rv.y;
+ vp.width = rv.width;
+ vp.height = rv.height;
+
+ vb.x = -vp.x / this._scaleX;
+ vb.y = -vp.y / this._scaleY;
+ vb.width = cc._canvas.width / this._scaleX;
+ vb.height = cc._canvas.height / this._scaleY;
+ cc._renderContext.setOffset && cc._renderContext.setOffset(vp.x, -vp.y);
+ }
+
+ // reset director's member variables to fit visible rect
+ var director = cc.director;
+ director._winSizeInPoints.width = this._designResolutionSize.width;
+ director._winSizeInPoints.height = this._designResolutionSize.height;
+ policy.postApply(this);
+ cc.winSize.width = director._winSizeInPoints.width;
+ cc.winSize.height = director._winSizeInPoints.height;
+
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ // reset director's member variables to fit visible rect
+ director.setGLDefaultValues();
+ }
+ else if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
+ cc.renderer._allNeedDraw = true;
+ }
+
+ this._originalScaleX = this._scaleX;
+ this._originalScaleY = this._scaleY;
+ cc.visibleRect && cc.visibleRect.init(this._visibleRect);
+ },
+
+ /**
+ * Returns the designed size for the view.
+ * Default resolution size is the same as 'getFrameSize'.
+ * @return {cc.Size}
+ */
+ getDesignResolutionSize: function () {
+ return cc.size(this._designResolutionSize.width, this._designResolutionSize.height);
+ },
+
+ /**
+ * Sets the document body to desired pixel resolution and fit the game content to it.
+ * This function is very useful for adaptation in mobile browsers.
+ * In some HD android devices, the resolution is very high, but its browser performance may not be very good.
+ * In this case, enabling retina display is very costy and not suggested, and if retina is disabled, the image may be blurry.
+ * But this API can be helpful to set a desired pixel resolution which is in between.
+ * This API will do the following:
+ * 1. Set viewport's width to the desired width in pixel
+ * 2. Set body width to the exact pixel resolution
+ * 3. The resolution policy will be reset with designed view size in points.
+ * @param {Number} width Design resolution width.
+ * @param {Number} height Design resolution height.
+ * @param {cc.ResolutionPolicy|Number} resolutionPolicy The resolution policy desired
+ */
+ setRealPixelResolution: function (width, height, resolutionPolicy) {
+ // Set viewport's width
+ this._setViewportMeta({"width": width}, true);
+
+ // Set body width to the exact pixel resolution
+ document.documentElement.style.width = width + "px";
+ document.body.style.width = width + "px";
+ document.body.style.left = "0px";
+ document.body.style.top = "0px";
+
+ // Reset the resolution size and policy
+ this.setDesignResolutionSize(width, height, resolutionPolicy);
+ },
+
+ /**
+ * Sets view port rectangle with points.
+ * @param {Number} x
+ * @param {Number} y
+ * @param {Number} w width
+ * @param {Number} h height
+ */
+ setViewPortInPoints: function (x, y, w, h) {
+ var locFrameZoomFactor = this._frameZoomFactor, locScaleX = this._scaleX, locScaleY = this._scaleY;
+ cc._renderContext.viewport((x * locScaleX * locFrameZoomFactor + this._viewPortRect.x * locFrameZoomFactor),
+ (y * locScaleY * locFrameZoomFactor + this._viewPortRect.y * locFrameZoomFactor),
+ (w * locScaleX * locFrameZoomFactor),
+ (h * locScaleY * locFrameZoomFactor));
+ },
+
+ /**
+ * Sets Scissor rectangle with points.
+ * @param {Number} x
+ * @param {Number} y
+ * @param {Number} w
+ * @param {Number} h
+ */
+ setScissorInPoints: function (x, y, w, h) {
+ var locFrameZoomFactor = this._frameZoomFactor, locScaleX = this._scaleX, locScaleY = this._scaleY;
+ var sx = Math.ceil(x * locScaleX * locFrameZoomFactor + this._viewPortRect.x * locFrameZoomFactor);
+ var sy = Math.ceil(y * locScaleY * locFrameZoomFactor + this._viewPortRect.y * locFrameZoomFactor);
+ var sw = Math.ceil(w * locScaleX * locFrameZoomFactor);
+ var sh = Math.ceil(h * locScaleY * locFrameZoomFactor);
+
+ if (!_scissorRect) {
+ var boxArr = gl.getParameter(gl.SCISSOR_BOX);
+ _scissorRect = cc.rect(boxArr[0], boxArr[1], boxArr[2], boxArr[3]);
+ }
+
+ if (_scissorRect.x != sx || _scissorRect.y != sy || _scissorRect.width != sw || _scissorRect.height != sh) {
+ _scissorRect.x = sx;
+ _scissorRect.y = sy;
+ _scissorRect.width = sw;
+ _scissorRect.height = sh;
+ cc._renderContext.scissor(sx, sy, sw, sh);
+ }
+ },
+
+ /**
+ * Returns whether GL_SCISSOR_TEST is enable
+ * @return {Boolean}
+ */
+ isScissorEnabled: function () {
+ return cc._renderContext.isEnabled(gl.SCISSOR_TEST);
+ },
+
+ /**
+ * Returns the current scissor rectangle
+ * @return {cc.Rect}
+ */
+ getScissorRect: function () {
+ if (!_scissorRect) {
+ var boxArr = gl.getParameter(gl.SCISSOR_BOX);
+ _scissorRect = cc.rect(boxArr[0], boxArr[1], boxArr[2], boxArr[3]);
+ }
+ var scaleXFactor = 1 / this._scaleX;
+ var scaleYFactor = 1 / this._scaleY;
+ return cc.rect(
+ (_scissorRect.x - this._viewPortRect.x) * scaleXFactor,
+ (_scissorRect.y - this._viewPortRect.y) * scaleYFactor,
+ _scissorRect.width * scaleXFactor,
+ _scissorRect.height * scaleYFactor
+ );
+ },
+
+ /**
+ * Sets the name of the view
+ * @param {String} viewName
+ */
+ setViewName: function (viewName) {
+ if (viewName != null && viewName.length > 0) {
+ this._viewName = viewName;
+ }
+ },
+
+ /**
+ * Returns the name of the view
+ * @return {String}
+ */
+ getViewName: function () {
+ return this._viewName;
+ },
+
+ /**
+ * Returns the view port rectangle.
+ * @return {cc.Rect}
+ */
+ getViewPortRect: function () {
+ return this._viewPortRect;
+ },
+
+ /**
+ * Returns scale factor of the horizontal direction (X axis).
+ * @return {Number}
+ */
+ getScaleX: function () {
+ return this._scaleX;
+ },
+
+ /**
+ * Returns scale factor of the vertical direction (Y axis).
+ * @return {Number}
+ */
+ getScaleY: function () {
+ return this._scaleY;
+ },
+
+ /**
+ * Returns device pixel ratio for retina display.
+ * @return {Number}
+ */
+ getDevicePixelRatio: function () {
+ return this._devicePixelRatio;
+ },
+
+ /**
+ * Returns the real location in view for a translation based on a related position
+ * @param {Number} tx The X axis translation
+ * @param {Number} ty The Y axis translation
+ * @param {Object} relatedPos The related position object including "left", "top", "width", "height" informations
+ * @return {cc.Point}
+ */
+ convertToLocationInView: function (tx, ty, relatedPos) {
+ var x = this._devicePixelRatio * (tx - relatedPos.left);
+ var y = this._devicePixelRatio * (relatedPos.top + relatedPos.height - ty);
+ return this._isRotated ? {x: this._viewPortRect.width - y, y: x} : {x: x, y: y};
+ },
+
+ _convertMouseToLocationInView: function (point, relatedPos) {
+ var viewport = this._viewPortRect, _t = this;
+ point.x = ((_t._devicePixelRatio * (point.x - relatedPos.left)) - viewport.x) / _t._scaleX;
+ point.y = (_t._devicePixelRatio * (relatedPos.top + relatedPos.height - point.y) - viewport.y) / _t._scaleY;
+ },
+
+ _convertPointWithScale: function (point) {
+ var viewport = this._viewPortRect;
+ point.x = (point.x - viewport.x) / this._scaleX;
+ point.y = (point.y - viewport.y) / this._scaleY;
+ },
+
+ _convertTouchesWithScale: function (touches) {
+ var viewport = this._viewPortRect, scaleX = this._scaleX, scaleY = this._scaleY,
+ selTouch, selPoint, selPrePoint;
+ for (var i = 0; i < touches.length; i++) {
+ selTouch = touches[i];
+ selPoint = selTouch._point;
+ selPrePoint = selTouch._prevPoint;
+
+ selPoint.x = (selPoint.x - viewport.x) / scaleX;
+ selPoint.y = (selPoint.y - viewport.y) / scaleY;
+ selPrePoint.x = (selPrePoint.x - viewport.x) / scaleX;
+ selPrePoint.y = (selPrePoint.y - viewport.y) / scaleY;
+ }
+ }
+});
+
+/**
+ * @function
+ * @return {cc.EGLView}
+ * @private
+ */
+cc.EGLView._getInstance = function () {
+ if (!this._instance) {
+ this._instance = this._instance || new cc.EGLView();
+ this._instance.initialize();
+ }
+ return this._instance;
+};
+
+/**
+ * cc.ContainerStrategy class is the root strategy class of container's scale strategy,
+ * it controls the behavior of how to scale the cc.container and cc._canvas object
+ *
+ * @class
+ * @extends cc.Class
+ */
+cc.ContainerStrategy = cc.Class.extend(/** @lends cc.ContainerStrategy# */{
+ /**
+ * Manipulation before appling the strategy
+ * @param {cc.view} The target view
+ */
+ preApply: function (view) {
+ },
+
+ /**
+ * Function to apply this strategy
+ * @param {cc.view} view
+ * @param {cc.Size} designedResolution
+ */
+ apply: function (view, designedResolution) {
+ },
+
+ /**
+ * Manipulation after applying the strategy
+ * @param {cc.view} view The target view
+ */
+ postApply: function (view) {
+
+ },
+
+ _setupContainer: function (view, w, h) {
+ var locCanvas = cc.game.canvas, locContainer = cc.game.container;
+ if (cc.sys.os === cc.sys.OS_ANDROID) {
+ document.body.style.width = (view._isRotated ? h : w) + 'px';
+ document.body.style.height = (view._isRotated ? w : h) + 'px';
+ }
+
+ // Setup style
+ locContainer.style.width = locCanvas.style.width = w + 'px';
+ locContainer.style.height = locCanvas.style.height = h + 'px';
+ // Setup pixel ratio for retina display
+ var devicePixelRatio = view._devicePixelRatio = 1;
+ if (view.isRetinaEnabled())
+ devicePixelRatio = view._devicePixelRatio = Math.min(2, window.devicePixelRatio || 1);
+ // Setup canvas
+ locCanvas.width = w * devicePixelRatio;
+ locCanvas.height = h * devicePixelRatio;
+ cc._renderContext.resetCache && cc._renderContext.resetCache();
+ },
+
+ _fixContainer: function () {
+ // Add container to document body
+ document.body.insertBefore(cc.container, document.body.firstChild);
+ // Set body's width height to window's size, and forbid overflow, so that game will be centered
+ var bs = document.body.style;
+ bs.width = window.innerWidth + "px";
+ bs.height = window.innerHeight + "px";
+ bs.overflow = "hidden";
+ // Body size solution doesn't work on all mobile browser so this is the aleternative: fixed container
+ var contStyle = cc.container.style;
+ contStyle.position = "fixed";
+ contStyle.left = contStyle.top = "0px";
+ // Reposition body
+ document.body.scrollTop = 0;
+ }
+});
+
+/**
+ * cc.ContentStrategy class is the root strategy class of content's scale strategy,
+ * it controls the behavior of how to scale the scene and setup the viewport for the game
+ *
+ * @class
+ * @extends cc.Class
+ */
+cc.ContentStrategy = cc.Class.extend(/** @lends cc.ContentStrategy# */{
+
+ _result: {
+ scale: [1, 1],
+ viewport: null
+ },
+
+ _buildResult: function (containerW, containerH, contentW, contentH, scaleX, scaleY) {
+ // Makes content fit better the canvas
+ Math.abs(containerW - contentW) < 2 && (contentW = containerW);
+ Math.abs(containerH - contentH) < 2 && (contentH = containerH);
+
+ var viewport = cc.rect(Math.round((containerW - contentW) / 2),
+ Math.round((containerH - contentH) / 2),
+ contentW, contentH);
+
+ // Translate the content
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
+ //TODO: modify something for setTransform
+ //cc._renderContext.translate(viewport.x, viewport.y + contentH);
+ }
+
+ this._result.scale = [scaleX, scaleY];
+ this._result.viewport = viewport;
+ return this._result;
+ },
+
+ /**
+ * Manipulation before applying the strategy
+ * @param {cc.view} view The target view
+ */
+ preApply: function (view) {
+ },
+
+ /**
+ * Function to apply this strategy
+ * The return value is {scale: [scaleX, scaleY], viewport: {cc.Rect}},
+ * The target view can then apply these value to itself, it's preferred not to modify directly its private variables
+ * @param {cc.view} view
+ * @param {cc.Size} designedResolution
+ * @return {object} scaleAndViewportRect
+ */
+ apply: function (view, designedResolution) {
+ return {"scale": [1, 1]};
+ },
+
+ /**
+ * Manipulation after applying the strategy
+ * @param {cc.view} view The target view
+ */
+ postApply: function (view) {
+ }
+});
+
+(function () {
+
+// Container scale strategys
+ /**
+ * @class
+ * @extends cc.ContainerStrategy
+ */
+ var EqualToFrame = cc.ContainerStrategy.extend({
+ apply: function (view) {
+ var frameH = view._frameSize.height, containerStyle = cc.container.style;
+ this._setupContainer(view, view._frameSize.width, view._frameSize.height);
+ // Setup container's margin and padding
+ if (view._isRotated) {
+ containerStyle.margin = '0 0 0 ' + frameH + 'px';
+ }
+ else {
+ containerStyle.margin = '0px';
+ }
+ }
+ });
+
+ /**
+ * @class
+ * @extends cc.ContainerStrategy
+ */
+ var ProportionalToFrame = cc.ContainerStrategy.extend({
+ apply: function (view, designedResolution) {
+ var frameW = view._frameSize.width, frameH = view._frameSize.height, containerStyle = cc.container.style,
+ designW = designedResolution.width, designH = designedResolution.height,
+ scaleX = frameW / designW, scaleY = frameH / designH,
+ containerW, containerH;
+
+ scaleX < scaleY ? (containerW = frameW, containerH = designH * scaleX) : (containerW = designW * scaleY, containerH = frameH);
+
+ // Adjust container size with integer value
+ var offx = Math.round((frameW - containerW) / 2);
+ var offy = Math.round((frameH - containerH) / 2);
+ containerW = frameW - 2 * offx;
+ containerH = frameH - 2 * offy;
+
+ this._setupContainer(view, containerW, containerH);
+ // Setup container's margin and padding
+ if (view._isRotated) {
+ containerStyle.margin = '0 0 0 ' + frameH + 'px';
+ }
+ else {
+ containerStyle.margin = '0px';
+ }
+ containerStyle.paddingLeft = offx + "px";
+ containerStyle.paddingRight = offx + "px";
+ containerStyle.paddingTop = offy + "px";
+ containerStyle.paddingBottom = offy + "px";
+ }
+ });
+
+ /**
+ * @class
+ * @extends EqualToFrame
+ */
+ var EqualToWindow = EqualToFrame.extend({
+ preApply: function (view) {
+ this._super(view);
+ view._frame = document.documentElement;
+ },
+
+ apply: function (view) {
+ this._super(view);
+ this._fixContainer();
+ }
+ });
+
+ /**
+ * @class
+ * @extends ProportionalToFrame
+ */
+ var ProportionalToWindow = ProportionalToFrame.extend({
+ preApply: function (view) {
+ this._super(view);
+ view._frame = document.documentElement;
+ },
+
+ apply: function (view, designedResolution) {
+ this._super(view, designedResolution);
+ this._fixContainer();
+ }
+ });
+
+ /**
+ * @class
+ * @extends cc.ContainerStrategy
+ */
+ var OriginalContainer = cc.ContainerStrategy.extend({
+ apply: function (view) {
+ this._setupContainer(view, cc._canvas.width, cc._canvas.height);
+ }
+ });
+
+// #NOT STABLE on Android# Alias: Strategy that makes the container's size equals to the window's size
+// cc.ContainerStrategy.EQUAL_TO_WINDOW = new EqualToWindow();
+// #NOT STABLE on Android# Alias: Strategy that scale proportionally the container's size to window's size
+// cc.ContainerStrategy.PROPORTION_TO_WINDOW = new ProportionalToWindow();
+// Alias: Strategy that makes the container's size equals to the frame's size
+ cc.ContainerStrategy.EQUAL_TO_FRAME = new EqualToFrame();
+// Alias: Strategy that scale proportionally the container's size to frame's size
+ cc.ContainerStrategy.PROPORTION_TO_FRAME = new ProportionalToFrame();
+// Alias: Strategy that keeps the original container's size
+ cc.ContainerStrategy.ORIGINAL_CONTAINER = new OriginalContainer();
+
+// Content scale strategys
+ var ExactFit = cc.ContentStrategy.extend({
+ apply: function (view, designedResolution) {
+ var containerW = cc._canvas.width, containerH = cc._canvas.height,
+ scaleX = containerW / designedResolution.width, scaleY = containerH / designedResolution.height;
+
+ return this._buildResult(containerW, containerH, containerW, containerH, scaleX, scaleY);
+ }
+ });
+
+ var ShowAll = cc.ContentStrategy.extend({
+ apply: function (view, designedResolution) {
+ var containerW = cc._canvas.width, containerH = cc._canvas.height,
+ designW = designedResolution.width, designH = designedResolution.height,
+ scaleX = containerW / designW, scaleY = containerH / designH, scale = 0,
+ contentW, contentH;
+
+ scaleX < scaleY ? (scale = scaleX, contentW = containerW, contentH = designH * scale)
+ : (scale = scaleY, contentW = designW * scale, contentH = containerH);
+
+ return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);
+ }
+ });
+
+ var NoBorder = cc.ContentStrategy.extend({
+ apply: function (view, designedResolution) {
+ var containerW = cc._canvas.width, containerH = cc._canvas.height,
+ designW = designedResolution.width, designH = designedResolution.height,
+ scaleX = containerW / designW, scaleY = containerH / designH, scale,
+ contentW, contentH;
+
+ scaleX < scaleY ? (scale = scaleY, contentW = designW * scale, contentH = containerH)
+ : (scale = scaleX, contentW = containerW, contentH = designH * scale);
+
+ return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);
+ }
+ });
+
+ var FixedHeight = cc.ContentStrategy.extend({
+ apply: function (view, designedResolution) {
+ var containerW = cc._canvas.width, containerH = cc._canvas.height,
+ designH = designedResolution.height, scale = containerH / designH,
+ contentW = containerW, contentH = containerH;
+
+ return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);
+ },
+
+ postApply: function (view) {
+ cc.director._winSizeInPoints = view.getVisibleSize();
+ }
+ });
+
+ var FixedWidth = cc.ContentStrategy.extend({
+ apply: function (view, designedResolution) {
+ var containerW = cc._canvas.width, containerH = cc._canvas.height,
+ designW = designedResolution.width, scale = containerW / designW,
+ contentW = containerW, contentH = containerH;
+
+ return this._buildResult(containerW, containerH, contentW, contentH, scale, scale);
+ },
+
+ postApply: function (view) {
+ cc.director._winSizeInPoints = view.getVisibleSize();
+ }
+ });
+
+// Alias: Strategy to scale the content's size to container's size, non proportional
+ cc.ContentStrategy.EXACT_FIT = new ExactFit();
+// Alias: Strategy to scale the content's size proportionally to maximum size and keeps the whole content area to be visible
+ cc.ContentStrategy.SHOW_ALL = new ShowAll();
+// Alias: Strategy to scale the content's size proportionally to fill the whole container area
+ cc.ContentStrategy.NO_BORDER = new NoBorder();
+// Alias: Strategy to scale the content's height to container's height and proportionally scale its width
+ cc.ContentStrategy.FIXED_HEIGHT = new FixedHeight();
+// Alias: Strategy to scale the content's width to container's width and proportionally scale its height
+ cc.ContentStrategy.FIXED_WIDTH = new FixedWidth();
+
+})();
+
+/**
+ * cc.ResolutionPolicy class is the root strategy class of scale strategy,
+ * its main task is to maintain the compatibility with Cocos2d-x
+ *
+ * @class
+ * @extends cc.Class
+ * @param {cc.ContainerStrategy} containerStg The container strategy
+ * @param {cc.ContentStrategy} contentStg The content strategy
+ */
+cc.ResolutionPolicy = cc.Class.extend(/** @lends cc.ResolutionPolicy# */{
+ _containerStrategy: null,
+ _contentStrategy: null,
+
+ /**
+ * Constructor of cc.ResolutionPolicy
+ * @param {cc.ContainerStrategy} containerStg
+ * @param {cc.ContentStrategy} contentStg
+ */
+ ctor: function (containerStg, contentStg) {
+ this.setContainerStrategy(containerStg);
+ this.setContentStrategy(contentStg);
+ },
+
+ /**
+ * Manipulation before applying the resolution policy
+ * @param {cc.view} view The target view
+ */
+ preApply: function (view) {
+ this._containerStrategy.preApply(view);
+ this._contentStrategy.preApply(view);
+ },
+
+ /**
+ * Function to apply this resolution policy
+ * The return value is {scale: [scaleX, scaleY], viewport: {cc.Rect}},
+ * The target view can then apply these value to itself, it's preferred not to modify directly its private variables
+ * @param {cc.view} view The target view
+ * @param {cc.Size} designedResolution The user defined design resolution
+ * @return {object} An object contains the scale X/Y values and the viewport rect
+ */
+ apply: function (view, designedResolution) {
+ this._containerStrategy.apply(view, designedResolution);
+ return this._contentStrategy.apply(view, designedResolution);
+ },
+
+ /**
+ * Manipulation after appyling the strategy
+ * @param {cc.view} view The target view
+ */
+ postApply: function (view) {
+ this._containerStrategy.postApply(view);
+ this._contentStrategy.postApply(view);
+ },
+
+ /**
+ * Setup the container's scale strategy
+ * @param {cc.ContainerStrategy} containerStg
+ */
+ setContainerStrategy: function (containerStg) {
+ if (containerStg instanceof cc.ContainerStrategy)
+ this._containerStrategy = containerStg;
+ },
+
+ /**
+ * Setup the content's scale strategy
+ * @param {cc.ContentStrategy} contentStg
+ */
+ setContentStrategy: function (contentStg) {
+ if (contentStg instanceof cc.ContentStrategy)
+ this._contentStrategy = contentStg;
+ }
+});
+
+/**
+ * @memberOf cc.ResolutionPolicy#
+ * @name EXACT_FIT
+ * @constant
+ * @type Number
+ * @static
+ * The entire application is visible in the specified area without trying to preserve the original aspect ratio.
+ * Distortion can occur, and the application may appear stretched or compressed.
+ */
+cc.ResolutionPolicy.EXACT_FIT = 0;
+
+/**
+ * @memberOf cc.ResolutionPolicy#
+ * @name NO_BORDER
+ * @constant
+ * @type Number
+ * @static
+ * The entire application fills the specified area, without distortion but possibly with some cropping,
+ * while maintaining the original aspect ratio of the application.
+ */
+cc.ResolutionPolicy.NO_BORDER = 1;
+
+/**
+ * @memberOf cc.ResolutionPolicy#
+ * @name SHOW_ALL
+ * @constant
+ * @type Number
+ * @static
+ * The entire application is visible in the specified area without distortion while maintaining the original
+ * aspect ratio of the application. Borders can appear on two sides of the application.
+ */
+cc.ResolutionPolicy.SHOW_ALL = 2;
+
+/**
+ * @memberOf cc.ResolutionPolicy#
+ * @name FIXED_HEIGHT
+ * @constant
+ * @type Number
+ * @static
+ * The application takes the height of the design resolution size and modifies the width of the internal
+ * canvas so that it fits the aspect ratio of the device
+ * no distortion will occur however you must make sure your application works on different
+ * aspect ratios
+ */
+cc.ResolutionPolicy.FIXED_HEIGHT = 3;
+
+/**
+ * @memberOf cc.ResolutionPolicy#
+ * @name FIXED_WIDTH
+ * @constant
+ * @type Number
+ * @static
+ * The application takes the width of the design resolution size and modifies the height of the internal
+ * canvas so that it fits the aspect ratio of the device
+ * no distortion will occur however you must make sure your application works on different
+ * aspect ratios
+ */
+cc.ResolutionPolicy.FIXED_WIDTH = 4;
+
+/**
+ * @memberOf cc.ResolutionPolicy#
+ * @name UNKNOWN
+ * @constant
+ * @type Number
+ * @static
+ * Unknow policy
+ */
+cc.ResolutionPolicy.UNKNOWN = 5;
diff --git a/frameworks/cocos2d-html5/cocos2d/core/platform/CCInputExtension.js b/frameworks/cocos2d-html5/cocos2d/core/platform/CCInputExtension.js
new file mode 100644
index 0000000..e61f584
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/platform/CCInputExtension.js
@@ -0,0 +1,139 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+var _p = cc.inputManager;
+
+/**
+ * whether enable accelerometer event
+ * @function
+ * @param {Boolean} isEnable
+ */
+_p.setAccelerometerEnabled = function(isEnable){
+ var _t = this;
+ if(_t._accelEnabled === isEnable)
+ return;
+
+ _t._accelEnabled = isEnable;
+ var scheduler = cc.director.getScheduler();
+ if(_t._accelEnabled){
+ _t._accelCurTime = 0;
+ _t._registerAccelerometerEvent();
+ scheduler.scheduleUpdate(_t);
+ } else {
+ _t._accelCurTime = 0;
+ _t._unregisterAccelerometerEvent();
+ scheduler.unscheduleUpdate(_t);
+ }
+};
+
+/**
+ * set accelerometer interval value
+ * @function
+ * @param {Number} interval
+ */
+_p.setAccelerometerInterval = function(interval){
+ if (this._accelInterval !== interval) {
+ this._accelInterval = interval;
+ }
+};
+
+_p._registerKeyboardEvent = function(){
+ cc._canvas.addEventListener("keydown", function (e) {
+ cc.eventManager.dispatchEvent(new cc.EventKeyboard(e.keyCode, true));
+ e.stopPropagation();
+ e.preventDefault();
+ }, false);
+ cc._canvas.addEventListener("keyup", function (e) {
+ cc.eventManager.dispatchEvent(new cc.EventKeyboard(e.keyCode, false));
+ e.stopPropagation();
+ e.preventDefault();
+ }, false);
+};
+
+_p._registerAccelerometerEvent = function(){
+ var w = window, _t = this;
+ _t._acceleration = new cc.Acceleration();
+ _t._accelDeviceEvent = w.DeviceMotionEvent || w.DeviceOrientationEvent;
+
+ //TODO fix DeviceMotionEvent bug on QQ Browser version 4.1 and below.
+ if (cc.sys.browserType === cc.sys.BROWSER_TYPE_MOBILE_QQ)
+ _t._accelDeviceEvent = window.DeviceOrientationEvent;
+
+ var _deviceEventType = (_t._accelDeviceEvent === w.DeviceMotionEvent) ? "devicemotion" : "deviceorientation";
+ var ua = navigator.userAgent;
+ if (/Android/.test(ua) || (/Adr/.test(ua) && cc.sys.browserType === cc.BROWSER_TYPE_UC)) {
+ _t._minus = -1;
+ }
+
+ _t.didAccelerateCallback = _t.didAccelerate.bind(_t);
+ w.addEventListener(_deviceEventType, _t.didAccelerateCallback, false);
+};
+
+_p._unregisterAccelerometerEvent = function () {
+ this._acceleration = null;
+ var _deviceEventType = (this._accelDeviceEvent === window.DeviceMotionEvent) ? "devicemotion" : "deviceorientation";
+ window.removeEventListener(_deviceEventType, this.didAccelerateCallback, false);
+};
+
+_p.didAccelerate = function (eventData) {
+ var _t = this, w = window;
+ if (!_t._accelEnabled)
+ return;
+
+ var mAcceleration = _t._acceleration;
+
+ var x, y, z;
+
+ if (_t._accelDeviceEvent === window.DeviceMotionEvent) {
+ var eventAcceleration = eventData["accelerationIncludingGravity"];
+ x = _t._accelMinus * eventAcceleration.x * 0.1;
+ y = _t._accelMinus * eventAcceleration.y * 0.1;
+ z = eventAcceleration.z * 0.1;
+ } else {
+ x = (eventData["gamma"] / 90) * 0.981;
+ y = -(eventData["beta"] / 90) * 0.981;
+ z = (eventData["alpha"] / 90) * 0.981;
+ }
+
+ mAcceleration.x = x;
+ mAcceleration.y = y;
+ mAcceleration.z = z;
+
+ mAcceleration.timestamp = eventData.timeStamp || Date.now();
+
+ var tmpX = mAcceleration.x;
+ if(w.orientation === cc.UIInterfaceOrientationLandscapeRight){
+ mAcceleration.x = -mAcceleration.y;
+ mAcceleration.y = tmpX;
+ }else if(w.orientation === cc.UIInterfaceOrientationLandscapeLeft){
+ mAcceleration.x = mAcceleration.y;
+ mAcceleration.y = -tmpX;
+ }else if(w.orientation === cc.UIInterfaceOrientationPortraitUpsideDown){
+ mAcceleration.x = -mAcceleration.x;
+ mAcceleration.y = -mAcceleration.y;
+ }
+};
+
+delete _p;
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/platform/CCInputManager.js b/frameworks/cocos2d-html5/cocos2d/core/platform/CCInputManager.js
new file mode 100644
index 0000000..270c535
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/platform/CCInputManager.js
@@ -0,0 +1,630 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * ignore
+ */
+
+/**
+ * @constant
+ * @type {number}
+ */
+cc.UIInterfaceOrientationLandscapeLeft = -90;
+/**
+ * @constant
+ * @type {number}
+ */
+cc.UIInterfaceOrientationLandscapeRight = 90;
+/**
+ * @constant
+ * @type {number}
+ */
+cc.UIInterfaceOrientationPortraitUpsideDown = 180;
+/**
+ * @constant
+ * @type {number}
+ */
+cc.UIInterfaceOrientationPortrait = 0;
+
+/**
+ *
+ * This class manages all events of input. include: touch, mouse, accelerometer, keyboard
+ *
+ * @class
+ * @name cc.inputManager
+ */
+cc.inputManager = /** @lends cc.inputManager# */{
+ TOUCH_TIMEOUT: 5000,
+
+ _mousePressed: false,
+
+ _isRegisterEvent: false,
+
+ _preTouchPoint: cc.p(0, 0),
+ _prevMousePoint: cc.p(0, 0),
+
+ _preTouchPool: [],
+ _preTouchPoolPointer: 0,
+
+ _touches: [],
+ _touchesIntegerDict: {},
+
+ _indexBitsUsed: 0,
+ _maxTouches: 5,
+
+ _accelEnabled: false,
+ _accelInterval: 1 / 30,
+ _accelMinus: 1,
+ _accelCurTime: 0,
+ _acceleration: null,
+ _accelDeviceEvent: null,
+
+ _getUnUsedIndex: function () {
+ var temp = this._indexBitsUsed;
+ var now = cc.sys.now();
+
+ for (var i = 0; i < this._maxTouches; i++) {
+ if (!(temp & 0x00000001)) {
+ this._indexBitsUsed |= (1 << i);
+ return i;
+ }
+ else {
+ var touch = this._touches[i];
+ if (now - touch._lastModified > this.TOUCH_TIMEOUT) {
+ this._removeUsedIndexBit(i);
+ delete this._touchesIntegerDict[touch.getID()];
+ return i;
+ }
+ }
+ temp >>= 1;
+ }
+
+ // all bits are used
+ return -1;
+ },
+
+ _removeUsedIndexBit: function (index) {
+ if (index < 0 || index >= this._maxTouches)
+ return;
+
+ var temp = 1 << index;
+ temp = ~temp;
+ this._indexBitsUsed &= temp;
+ },
+
+ _glView: null,
+
+ /**
+ * @function
+ * @param {Array} touches
+ */
+ handleTouchesBegin: function (touches) {
+ var selTouch, index, curTouch, touchID,
+ handleTouches = [], locTouchIntDict = this._touchesIntegerDict,
+ now = cc.sys.now();
+ for (var i = 0, len = touches.length; i < len; i++) {
+ selTouch = touches[i];
+ touchID = selTouch.getID();
+ index = locTouchIntDict[touchID];
+
+ if (index == null) {
+ var unusedIndex = this._getUnUsedIndex();
+ if (unusedIndex === -1) {
+ cc.log(cc._LogInfos.inputManager_handleTouchesBegin, unusedIndex);
+ continue;
+ }
+ //curTouch = this._touches[unusedIndex] = selTouch;
+ curTouch = this._touches[unusedIndex] = new cc.Touch(selTouch._point.x, selTouch._point.y, selTouch.getID());
+ curTouch._lastModified = now;
+ curTouch._setPrevPoint(selTouch._prevPoint);
+ locTouchIntDict[touchID] = unusedIndex;
+ handleTouches.push(curTouch);
+ }
+ }
+ if (handleTouches.length > 0) {
+ this._glView._convertTouchesWithScale(handleTouches);
+ var touchEvent = new cc.EventTouch(handleTouches);
+ touchEvent._eventCode = cc.EventTouch.EventCode.BEGAN;
+ cc.eventManager.dispatchEvent(touchEvent);
+ }
+ },
+
+ /**
+ * @function
+ * @param {Array} touches
+ */
+ handleTouchesMove: function (touches) {
+ var selTouch, index, touchID,
+ handleTouches = [], locTouches = this._touches,
+ now = cc.sys.now();
+ for (var i = 0, len = touches.length; i < len; i++) {
+ selTouch = touches[i];
+ touchID = selTouch.getID();
+ index = this._touchesIntegerDict[touchID];
+
+ if (index == null) {
+ //cc.log("if the index doesn't exist, it is an error");
+ continue;
+ }
+ if (locTouches[index]) {
+ locTouches[index]._setPoint(selTouch._point);
+ locTouches[index]._setPrevPoint(selTouch._prevPoint);
+ locTouches[index]._lastModified = now;
+ handleTouches.push(locTouches[index]);
+ }
+ }
+ if (handleTouches.length > 0) {
+ this._glView._convertTouchesWithScale(handleTouches);
+ var touchEvent = new cc.EventTouch(handleTouches);
+ touchEvent._eventCode = cc.EventTouch.EventCode.MOVED;
+ cc.eventManager.dispatchEvent(touchEvent);
+ }
+ },
+
+ /**
+ * @function
+ * @param {Array} touches
+ */
+ handleTouchesEnd: function (touches) {
+ var handleTouches = this.getSetOfTouchesEndOrCancel(touches);
+ if (handleTouches.length > 0) {
+ this._glView._convertTouchesWithScale(handleTouches);
+ var touchEvent = new cc.EventTouch(handleTouches);
+ touchEvent._eventCode = cc.EventTouch.EventCode.ENDED;
+ cc.eventManager.dispatchEvent(touchEvent);
+ }
+ },
+
+ /**
+ * @function
+ * @param {Array} touches
+ */
+ handleTouchesCancel: function (touches) {
+ var handleTouches = this.getSetOfTouchesEndOrCancel(touches);
+ if (handleTouches.length > 0) {
+ this._glView._convertTouchesWithScale(handleTouches);
+ var touchEvent = new cc.EventTouch(handleTouches);
+ touchEvent._eventCode = cc.EventTouch.EventCode.CANCELLED;
+ cc.eventManager.dispatchEvent(touchEvent);
+ }
+ },
+
+ /**
+ * @function
+ * @param {Array} touches
+ * @returns {Array}
+ */
+ getSetOfTouchesEndOrCancel: function (touches) {
+ var selTouch, index, touchID, handleTouches = [], locTouches = this._touches, locTouchesIntDict = this._touchesIntegerDict;
+ for (var i = 0, len = touches.length; i < len; i++) {
+ selTouch = touches[i];
+ touchID = selTouch.getID();
+ index = locTouchesIntDict[touchID];
+
+ if (index == null) {
+ continue; //cc.log("if the index doesn't exist, it is an error");
+ }
+ if (locTouches[index]) {
+ locTouches[index]._setPoint(selTouch._point);
+ locTouches[index]._setPrevPoint(selTouch._prevPoint);
+ handleTouches.push(locTouches[index]);
+ this._removeUsedIndexBit(index);
+ delete locTouchesIntDict[touchID];
+ }
+ }
+ return handleTouches;
+ },
+
+ /**
+ * @function
+ * @param {HTMLElement} element
+ * @return {Object}
+ */
+ getHTMLElementPosition: function (element) {
+ var docElem = document.documentElement;
+ var win = window;
+ var box = null;
+ if (cc.isFunction(element.getBoundingClientRect)) {
+ box = element.getBoundingClientRect();
+ } else {
+ box = {
+ left: 0,
+ top: 0,
+ width: parseInt(element.style.width),
+ height: parseInt(element.style.height)
+ };
+ }
+ return {
+ left: box.left + win.pageXOffset - docElem.clientLeft,
+ top: box.top + win.pageYOffset - docElem.clientTop,
+ width: box.width,
+ height: box.height
+ };
+ },
+
+ /**
+ * @function
+ * @param {cc.Touch} touch
+ * @return {cc.Touch}
+ */
+ getPreTouch: function (touch) {
+ var preTouch = null;
+ var locPreTouchPool = this._preTouchPool;
+ var id = touch.getID();
+ for (var i = locPreTouchPool.length - 1; i >= 0; i--) {
+ if (locPreTouchPool[i].getID() === id) {
+ preTouch = locPreTouchPool[i];
+ break;
+ }
+ }
+ if (!preTouch)
+ preTouch = touch;
+ return preTouch;
+ },
+
+ /**
+ * @function
+ * @param {cc.Touch} touch
+ */
+ setPreTouch: function (touch) {
+ var find = false;
+ var locPreTouchPool = this._preTouchPool;
+ var id = touch.getID();
+ for (var i = locPreTouchPool.length - 1; i >= 0; i--) {
+ if (locPreTouchPool[i].getID() === id) {
+ locPreTouchPool[i] = touch;
+ find = true;
+ break;
+ }
+ }
+ if (!find) {
+ if (locPreTouchPool.length <= 50) {
+ locPreTouchPool.push(touch);
+ } else {
+ locPreTouchPool[this._preTouchPoolPointer] = touch;
+ this._preTouchPoolPointer = (this._preTouchPoolPointer + 1) % 50;
+ }
+ }
+ },
+
+ /**
+ * @function
+ * @param {Number} tx
+ * @param {Number} ty
+ * @param {cc.Point} pos
+ * @return {cc.Touch}
+ */
+ getTouchByXY: function (tx, ty, pos) {
+ var locPreTouch = this._preTouchPoint;
+ var location = this._glView.convertToLocationInView(tx, ty, pos);
+ var touch = new cc.Touch(location.x, location.y);
+ touch._setPrevPoint(locPreTouch.x, locPreTouch.y);
+ locPreTouch.x = location.x;
+ locPreTouch.y = location.y;
+ return touch;
+ },
+
+ /**
+ * @function
+ * @param {cc.Point} location
+ * @param {cc.Point} pos
+ * @param {Number} eventType
+ * @returns {cc.EventMouse}
+ */
+ getMouseEvent: function (location, pos, eventType) {
+ var locPreMouse = this._prevMousePoint;
+ this._glView._convertMouseToLocationInView(location, pos);
+ var mouseEvent = new cc.EventMouse(eventType);
+ mouseEvent.setLocation(location.x, location.y);
+ mouseEvent._setPrevCursor(locPreMouse.x, locPreMouse.y);
+ locPreMouse.x = location.x;
+ locPreMouse.y = location.y;
+ return mouseEvent;
+ },
+
+ /**
+ * @function
+ * @param {Touch} event
+ * @param {cc.Point} pos
+ * @return {cc.Point}
+ */
+ getPointByEvent: function (event, pos) {
+ if (event.pageX != null) //not available in <= IE8
+ return {x: event.pageX, y: event.pageY};
+
+ pos.left -= document.body.scrollLeft;
+ pos.top -= document.body.scrollTop;
+ return {x: event.clientX, y: event.clientY};
+ },
+
+ /**
+ * @function
+ * @param {Touch} event
+ * @param {cc.Point} pos
+ * @returns {Array}
+ */
+ getTouchesByEvent: function (event, pos) {
+ var touchArr = [], locView = this._glView;
+ var touch_event, touch, preLocation;
+ var locPreTouch = this._preTouchPoint;
+
+ var length = event.changedTouches.length;
+ for (var i = 0; i < length; i++) {
+ touch_event = event.changedTouches[i];
+ if (touch_event) {
+ var location;
+ if (cc.sys.BROWSER_TYPE_FIREFOX === cc.sys.browserType)
+ location = locView.convertToLocationInView(touch_event.pageX, touch_event.pageY, pos);
+ else
+ location = locView.convertToLocationInView(touch_event.clientX, touch_event.clientY, pos);
+ if (touch_event.identifier != null) {
+ touch = new cc.Touch(location.x, location.y, touch_event.identifier);
+ //use Touch Pool
+ preLocation = this.getPreTouch(touch).getLocation();
+ touch._setPrevPoint(preLocation.x, preLocation.y);
+ this.setPreTouch(touch);
+ } else {
+ touch = new cc.Touch(location.x, location.y);
+ touch._setPrevPoint(locPreTouch.x, locPreTouch.y);
+ }
+ locPreTouch.x = location.x;
+ locPreTouch.y = location.y;
+ touchArr.push(touch);
+ }
+ }
+ return touchArr;
+ },
+
+ /**
+ * @function
+ * @param {HTMLElement} element
+ */
+ registerSystemEvent: function (element) {
+ if (this._isRegisterEvent) return;
+
+ var locView = this._glView = cc.view;
+ var selfPointer = this;
+ var supportMouse = ('mouse' in cc.sys.capabilities), supportTouches = ('touches' in cc.sys.capabilities);
+
+ //HACK
+ // - At the same time to trigger the ontouch event and onmouse event
+ // - The function will execute 2 times
+ //The known browser:
+ // liebiao
+ // miui
+ // WECHAT
+ var prohibition = false;
+ if (cc.sys.isMobile)
+ prohibition = true;
+
+ //register touch event
+ if (supportMouse) {
+ window.addEventListener('mousedown', function () {
+ selfPointer._mousePressed = true;
+ }, false);
+
+ window.addEventListener('mouseup', function (event) {
+ if (prohibition) return;
+ var savePressed = selfPointer._mousePressed;
+ selfPointer._mousePressed = false;
+
+ if (!savePressed)
+ return;
+
+ var pos = selfPointer.getHTMLElementPosition(element);
+ var location = selfPointer.getPointByEvent(event, pos);
+ if (!cc.rectContainsPoint(new cc.Rect(pos.left, pos.top, pos.width, pos.height), location)) {
+ selfPointer.handleTouchesEnd([selfPointer.getTouchByXY(location.x, location.y, pos)]);
+
+ var mouseEvent = selfPointer.getMouseEvent(location, pos, cc.EventMouse.UP);
+ mouseEvent.setButton(event.button);
+ cc.eventManager.dispatchEvent(mouseEvent);
+ }
+ }, false);
+
+ //register canvas mouse event
+ element.addEventListener("mousedown", function (event) {
+ if (prohibition) return;
+ selfPointer._mousePressed = true;
+
+ var pos = selfPointer.getHTMLElementPosition(element);
+ var location = selfPointer.getPointByEvent(event, pos);
+
+ selfPointer.handleTouchesBegin([selfPointer.getTouchByXY(location.x, location.y, pos)]);
+
+ var mouseEvent = selfPointer.getMouseEvent(location, pos, cc.EventMouse.DOWN);
+ mouseEvent.setButton(event.button);
+ cc.eventManager.dispatchEvent(mouseEvent);
+
+ event.stopPropagation();
+ event.preventDefault();
+ element.focus();
+ }, false);
+
+ element.addEventListener("mouseup", function (event) {
+ if (prohibition) return;
+ selfPointer._mousePressed = false;
+
+ var pos = selfPointer.getHTMLElementPosition(element);
+ var location = selfPointer.getPointByEvent(event, pos);
+
+ selfPointer.handleTouchesEnd([selfPointer.getTouchByXY(location.x, location.y, pos)]);
+
+ var mouseEvent = selfPointer.getMouseEvent(location, pos, cc.EventMouse.UP);
+ mouseEvent.setButton(event.button);
+ cc.eventManager.dispatchEvent(mouseEvent);
+
+ event.stopPropagation();
+ event.preventDefault();
+ }, false);
+
+ element.addEventListener("mousemove", function (event) {
+ if (prohibition) return;
+
+ var pos = selfPointer.getHTMLElementPosition(element);
+ var location = selfPointer.getPointByEvent(event, pos);
+
+ selfPointer.handleTouchesMove([selfPointer.getTouchByXY(location.x, location.y, pos)]);
+
+ var mouseEvent = selfPointer.getMouseEvent(location, pos, cc.EventMouse.MOVE);
+ if (selfPointer._mousePressed)
+ mouseEvent.setButton(event.button);
+ else
+ mouseEvent.setButton(null);
+ cc.eventManager.dispatchEvent(mouseEvent);
+
+ event.stopPropagation();
+ event.preventDefault();
+ }, false);
+
+ element.addEventListener("mousewheel", function (event) {
+ var pos = selfPointer.getHTMLElementPosition(element);
+ var location = selfPointer.getPointByEvent(event, pos);
+
+ var mouseEvent = selfPointer.getMouseEvent(location, pos, cc.EventMouse.SCROLL);
+ mouseEvent.setButton(event.button);
+ mouseEvent.setScrollData(0, event.wheelDelta);
+ cc.eventManager.dispatchEvent(mouseEvent);
+
+ event.stopPropagation();
+ event.preventDefault();
+ }, false);
+
+ /* firefox fix */
+ element.addEventListener("DOMMouseScroll", function (event) {
+ var pos = selfPointer.getHTMLElementPosition(element);
+ var location = selfPointer.getPointByEvent(event, pos);
+
+ var mouseEvent = selfPointer.getMouseEvent(location, pos, cc.EventMouse.SCROLL);
+ mouseEvent.setButton(event.button);
+ mouseEvent.setScrollData(0, event.detail * -120);
+ cc.eventManager.dispatchEvent(mouseEvent);
+
+ event.stopPropagation();
+ event.preventDefault();
+ }, false);
+ }
+
+ if (window.navigator.msPointerEnabled) {
+ var _pointerEventsMap = {
+ "MSPointerDown": selfPointer.handleTouchesBegin,
+ "MSPointerMove": selfPointer.handleTouchesMove,
+ "MSPointerUp": selfPointer.handleTouchesEnd,
+ "MSPointerCancel": selfPointer.handleTouchesCancel
+ };
+
+ for (var eventName in _pointerEventsMap) {
+ (function (_pointerEvent, _touchEvent) {
+ element.addEventListener(_pointerEvent, function (event) {
+ var pos = selfPointer.getHTMLElementPosition(element);
+ pos.left -= document.documentElement.scrollLeft;
+ pos.top -= document.documentElement.scrollTop;
+
+ _touchEvent.call(selfPointer, [selfPointer.getTouchByXY(event.clientX, event.clientY, pos)]);
+ event.stopPropagation();
+ }, false);
+ })(eventName, _pointerEventsMap[eventName]);
+ }
+ }
+
+ if (supportTouches) {
+ //register canvas touch event
+ element.addEventListener("touchstart", function (event) {
+ if (!event.changedTouches) return;
+
+ var pos = selfPointer.getHTMLElementPosition(element);
+ pos.left -= document.body.scrollLeft;
+ pos.top -= document.body.scrollTop;
+ selfPointer.handleTouchesBegin(selfPointer.getTouchesByEvent(event, pos));
+ event.stopPropagation();
+ event.preventDefault();
+ element.focus();
+ }, false);
+
+ element.addEventListener("touchmove", function (event) {
+ if (!event.changedTouches) return;
+
+ var pos = selfPointer.getHTMLElementPosition(element);
+ pos.left -= document.body.scrollLeft;
+ pos.top -= document.body.scrollTop;
+ selfPointer.handleTouchesMove(selfPointer.getTouchesByEvent(event, pos));
+ event.stopPropagation();
+ event.preventDefault();
+ }, false);
+
+ element.addEventListener("touchend", function (event) {
+ if (!event.changedTouches) return;
+
+ var pos = selfPointer.getHTMLElementPosition(element);
+ pos.left -= document.body.scrollLeft;
+ pos.top -= document.body.scrollTop;
+ selfPointer.handleTouchesEnd(selfPointer.getTouchesByEvent(event, pos));
+ event.stopPropagation();
+ event.preventDefault();
+ }, false);
+
+ element.addEventListener("touchcancel", function (event) {
+ if (!event.changedTouches) return;
+
+ var pos = selfPointer.getHTMLElementPosition(element);
+ pos.left -= document.body.scrollLeft;
+ pos.top -= document.body.scrollTop;
+ selfPointer.handleTouchesCancel(selfPointer.getTouchesByEvent(event, pos));
+ event.stopPropagation();
+ event.preventDefault();
+ }, false);
+ }
+
+ //register keyboard event
+ this._registerKeyboardEvent();
+
+ //register Accelerometer event
+ // this._registerAccelerometerEvent();
+
+ this._isRegisterEvent = true;
+ },
+
+ _registerKeyboardEvent: function () {
+ },
+
+ /**
+ * Register Accelerometer event
+ * @function
+ */
+ _registerAccelerometerEvent: function () {
+ },
+
+ /**
+ * @function
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ if (this._accelCurTime > this._accelInterval) {
+ this._accelCurTime -= this._accelInterval;
+ cc.eventManager.dispatchEvent(new cc.EventAcceleration(this._acceleration));
+ }
+ this._accelCurTime += dt;
+ }
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/core/platform/CCLoaders.js b/frameworks/cocos2d-html5/cocos2d/core/platform/CCLoaders.js
new file mode 100644
index 0000000..16749a0
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/platform/CCLoaders.js
@@ -0,0 +1,163 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc._txtLoader = {
+ load: function (realUrl, url, res, cb) {
+ cc.loader.loadTxt(realUrl, cb);
+ }
+};
+cc.loader.register(["txt", "xml", "vsh", "fsh", "atlas"], cc._txtLoader);
+
+cc._jsonLoader = {
+ load: function (realUrl, url, res, cb) {
+ cc.loader.loadJson(realUrl, cb);
+ }
+};
+cc.loader.register(["json", "ExportJson"], cc._jsonLoader);
+
+cc._jsLoader = {
+ load: function (realUrl, url, res, cb) {
+ cc.loader.loadJs(realUrl, cb);
+ }
+};
+cc.loader.register(["js"], cc._jsLoader);
+
+cc._imgLoader = {
+ load: function (realUrl, url, res, cb) {
+ var callback;
+ if (cc.loader.isLoading(realUrl)) {
+ callback = function (err, img) {
+ if (err)
+ return cb(err);
+ var tex = cc.textureCache.getTextureForKey(url) || cc.textureCache.handleLoadedTexture(url, img);
+ cb(null, tex);
+ };
+ }
+ else {
+ callback = function (err, img) {
+ if (err)
+ return cb(err);
+ var tex = cc.textureCache.handleLoadedTexture(url, img);
+ cb(null, tex);
+ };
+ }
+ cc.loader.loadImg(realUrl, callback);
+ }
+};
+cc.loader.register(["png", "jpg", "bmp", "jpeg", "gif", "ico", "tiff", "webp"], cc._imgLoader);
+cc._serverImgLoader = {
+ load: function (realUrl, url, res, cb) {
+ cc._imgLoader.load(res.src, url, res, cb);
+ }
+};
+cc.loader.register(["serverImg"], cc._serverImgLoader);
+
+cc._plistLoader = {
+ load: function (realUrl, url, res, cb) {
+ cc.loader.loadTxt(realUrl, function (err, txt) {
+ if (err)
+ return cb(err);
+ cb(null, cc.plistParser.parse(txt));
+ });
+ }
+};
+cc.loader.register(["plist"], cc._plistLoader);
+
+cc._fontLoader = {
+ TYPE: {
+ ".eot": "embedded-opentype",
+ ".ttf": "truetype",
+ ".ttc": "truetype",
+ ".woff": "woff",
+ ".svg": "svg"
+ },
+ _loadFont: function (name, srcs, type) {
+ var doc = document, path = cc.path, TYPE = this.TYPE, fontStyle = document.createElement("style");
+ fontStyle.type = "text/css";
+ doc.body.appendChild(fontStyle);
+
+ var fontStr = "";
+ if (isNaN(name - 0))
+ fontStr += "@font-face { font-family:" + name + "; src:";
+ else
+ fontStr += "@font-face { font-family:'" + name + "'; src:";
+ if (srcs instanceof Array) {
+ for (var i = 0, li = srcs.length; i < li; i++) {
+ var src = srcs[i];
+ type = path.extname(src).toLowerCase();
+ fontStr += "url('" + srcs[i] + "') format('" + TYPE[type] + "')";
+ fontStr += (i === li - 1) ? ";" : ",";
+ }
+ } else {
+ type = type.toLowerCase();
+ fontStr += "url('" + srcs + "') format('" + TYPE[type] + "');";
+ }
+ fontStyle.textContent += fontStr + "}";
+
+ //.
+ var preloadDiv = document.createElement("div");
+ var _divStyle = preloadDiv.style;
+ _divStyle.fontFamily = name;
+ preloadDiv.innerHTML = ".";
+ _divStyle.position = "absolute";
+ _divStyle.left = "-100px";
+ _divStyle.top = "-100px";
+ doc.body.appendChild(preloadDiv);
+ },
+ load: function (realUrl, url, res, cb) {
+ var self = this;
+ var type = res.type, name = res.name, srcs = res.srcs;
+ if (cc.isString(res)) {
+ type = cc.path.extname(res);
+ name = cc.path.basename(res, type);
+ self._loadFont(name, res, type);
+ } else {
+ self._loadFont(name, srcs);
+ }
+ if (document.fonts) {
+ document.fonts.load("1em " + name).then(function () {
+ cb(null, true);
+ }, function (err) {
+ cb(err);
+ });
+ } else {
+ cb(null, true);
+ }
+ }
+};
+cc.loader.register(["font", "eot", "ttf", "woff", "svg", "ttc"], cc._fontLoader);
+
+cc._binaryLoader = {
+ load: function (realUrl, url, res, cb) {
+ cc.loader.loadBinary(realUrl, cb);
+ }
+};
+
+cc._csbLoader = {
+ load: function(realUrl, url, res, cb){
+ cc.loader.loadCsb(realUrl, cb);
+ }
+};
+cc.loader.register(["csb"], cc._csbLoader);
diff --git a/frameworks/cocos2d-html5/cocos2d/core/platform/CCMacro.js b/frameworks/cocos2d-html5/cocos2d/core/platform/CCMacro.js
new file mode 100644
index 0000000..a52958c
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/platform/CCMacro.js
@@ -0,0 +1,857 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.INVALID_INDEX = -1;
+
+/**
+ * PI is the ratio of a circle's circumference to its diameter.
+ * @constant
+ * @type Number
+ */
+cc.PI = Math.PI;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.FLT_MAX = parseFloat('3.402823466e+38F');
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.FLT_MIN = parseFloat("1.175494351e-38F");
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.RAD = cc.PI / 180;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.DEG = 180 / cc.PI;
+
+/**
+ * maximum unsigned int value
+ * @constant
+ * @type Number
+ */
+cc.UINT_MAX = 0xffffffff;
+
+/**
+ *
+ * simple macro that swaps 2 variables
+ * modified from c++ macro, you need to pass in the x and y variables names in string,
+ * and then a reference to the whole object as third variable
+ *
+ * @param {String} x
+ * @param {String} y
+ * @param {Object} ref
+ * @function
+ * @deprecated since v3.0
+ */
+cc.swap = function (x, y, ref) {
+ if (cc.isObject(ref) && !cc.isUndefined(ref.x) && !cc.isUndefined(ref.y)) {
+ var tmp = ref[x];
+ ref[x] = ref[y];
+ ref[y] = tmp;
+ } else
+ cc.log(cc._LogInfos.swap);
+};
+
+/**
+ *
+ * Linear interpolation between 2 numbers, the ratio sets how much it is biased to each end
+ *
+ * @param {Number} a number A
+ * @param {Number} b number B
+ * @param {Number} r ratio between 0 and 1
+ * @function
+ * @example
+ * cc.lerp(2,10,0.5)//returns 6
+ * cc.lerp(2,10,0.2)//returns 3.6
+ */
+cc.lerp = function (a, b, r) {
+ return a + (b - a) * r;
+};
+
+/**
+ * get a random number from 0 to 0xffffff
+ * @function
+ * @returns {number}
+ */
+cc.rand = function () {
+ return Math.random() * 0xffffff;
+};
+
+/**
+ * returns a random float between -1 and 1
+ * @return {Number}
+ * @function
+ */
+cc.randomMinus1To1 = function () {
+ return (Math.random() - 0.5) * 2;
+};
+
+/**
+ * returns a random float between 0 and 1
+ * @return {Number}
+ * @function
+ */
+cc.random0To1 = Math.random;
+
+/**
+ * converts degrees to radians
+ * @param {Number} angle
+ * @return {Number}
+ * @function
+ */
+cc.degreesToRadians = function (angle) {
+ return angle * cc.RAD;
+};
+
+/**
+ * converts radians to degrees
+ * @param {Number} angle
+ * @return {Number}
+ * @function
+ */
+cc.radiansToDegrees = function (angle) {
+ return angle * cc.DEG;
+};
+/**
+ * converts radians to degrees
+ * @param {Number} angle
+ * @return {Number}
+ * @function
+ */
+cc.radiansToDegress = function (angle) {
+ cc.log(cc._LogInfos.radiansToDegress);
+ return angle * cc.DEG;
+};
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.REPEAT_FOREVER = Number.MAX_VALUE - 1;
+
+/**
+ * Helpful macro that setups the GL server state, the correct GL program and sets the Model View Projection matrix
+ * @param {cc.Node} node setup node
+ * @function
+ */
+cc.nodeDrawSetup = function (node) {
+ //cc.glEnable(node._glServerState);
+ if (node._shaderProgram) {
+ //cc._renderContext.useProgram(node._shaderProgram._programObj);
+ node._glProgramState.apply();
+ node._shaderProgram.setUniformForModelViewAndProjectionMatrixWithMat4();
+ }
+};
+
+/**
+ *
+ * GL states that are enabled:
+ * - GL_TEXTURE_2D
+ * - GL_VERTEX_ARRAY
+ * - GL_TEXTURE_COORD_ARRAY
+ * - GL_COLOR_ARRAY
+ *
+ * @function
+ */
+cc.enableDefaultGLStates = function () {
+ //TODO OPENGL STUFF
+ /*
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnable(GL_TEXTURE_2D);*/
+};
+
+/**
+ *
+ * Disable default GL states:
+ * - GL_TEXTURE_2D
+ * - GL_TEXTURE_COORD_ARRAY
+ * - GL_COLOR_ARRAY
+ *
+ * @function
+ */
+cc.disableDefaultGLStates = function () {
+ //TODO OPENGL
+ /*
+ glDisable(GL_TEXTURE_2D);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ */
+};
+
+/**
+ *
+ * Increments the GL Draws counts by one.
+ * The number of calls per frame are displayed on the screen when the CCDirector's stats are enabled.
+ *
+ * @param {Number} addNumber
+ * @function
+ */
+cc.incrementGLDraws = function (addNumber) {
+ cc.g_NumberOfDraws += addNumber;
+};
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.FLT_EPSILON = 0.0000001192092896;
+
+/**
+ *
+ * On Mac it returns 1;
+ * On iPhone it returns 2 if RetinaDisplay is On. Otherwise it returns 1
+ *
+ * @return {Number}
+ * @function
+ */
+cc.contentScaleFactor = function () {
+ return cc.director._contentScaleFactor;
+};
+
+/**
+ * Converts a Point in points to pixels
+ * @param {cc.Point} points
+ * @return {cc.Point}
+ * @function
+ */
+cc.pointPointsToPixels = function (points) {
+ var scale = cc.contentScaleFactor();
+ return cc.p(points.x * scale, points.y * scale);
+};
+
+/**
+ * Converts a Point in pixels to points
+ * @param {cc.Rect} pixels
+ * @return {cc.Point}
+ * @function
+ */
+cc.pointPixelsToPoints = function (pixels) {
+ var scale = cc.contentScaleFactor();
+ return cc.p(pixels.x / scale, pixels.y / scale);
+};
+
+cc._pointPixelsToPointsOut = function(pixels, outPoint){
+ var scale = cc.contentScaleFactor();
+ outPoint.x = pixels.x / scale;
+ outPoint.y = pixels.y / scale;
+};
+
+/**
+ * Converts a Size in points to pixels
+ * @param {cc.Size} sizeInPoints
+ * @return {cc.Size}
+ * @function
+ */
+cc.sizePointsToPixels = function (sizeInPoints) {
+ var scale = cc.contentScaleFactor();
+ return cc.size(sizeInPoints.width * scale, sizeInPoints.height * scale);
+};
+
+/**
+ * Converts a size in pixels to points
+ * @param {cc.Size} sizeInPixels
+ * @return {cc.Size}
+ * @function
+ */
+cc.sizePixelsToPoints = function (sizeInPixels) {
+ var scale = cc.contentScaleFactor();
+ return cc.size(sizeInPixels.width / scale, sizeInPixels.height / scale);
+};
+
+cc._sizePixelsToPointsOut = function (sizeInPixels, outSize) {
+ var scale = cc.contentScaleFactor();
+ outSize.width = sizeInPixels.width / scale;
+ outSize.height = sizeInPixels.height / scale;
+};
+
+/**
+ * Converts a rect in pixels to points
+ * @param {cc.Rect} pixel
+ * @return {cc.Rect}
+ * @function
+ */
+cc.rectPixelsToPoints = function (pixel) {
+ var scale = cc.contentScaleFactor();
+ return cc.rect(pixel.x / scale, pixel.y / scale,
+ pixel.width / scale, pixel.height / scale);
+};
+
+/**
+ * Converts a rect in points to pixels
+ * @param {cc.Rect} point
+ * @return {cc.Rect}
+ * @function
+ */
+cc.rectPointsToPixels = function (point) {
+ var scale = cc.contentScaleFactor();
+ return cc.rect(point.x * scale, point.y * scale,
+ point.width * scale, point.height * scale);
+};
+
+//some gl constant variable
+/**
+ * @constant
+ * @type Number
+ */
+cc.ONE = 1;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.ZERO = 0;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.SRC_ALPHA = 0x0302;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.SRC_ALPHA_SATURATE = 0x308;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.SRC_COLOR = 0x300;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.DST_ALPHA = 0x304;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.DST_COLOR = 0x306;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.ONE_MINUS_SRC_ALPHA = 0x0303;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.ONE_MINUS_SRC_COLOR = 0x301;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.ONE_MINUS_DST_ALPHA = 0x305;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.ONE_MINUS_DST_COLOR = 0x0307;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.ONE_MINUS_CONSTANT_ALPHA = 0x8004;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.ONE_MINUS_CONSTANT_COLOR = 0x8002;
+
+/**
+ * the constant variable equals gl.LINEAR for texture
+ * @constant
+ * @type Number
+ */
+cc.LINEAR = 0x2601;
+
+/**
+ * the constant variable equals gl.REPEAT for texture
+ * @constant
+ * @type Number
+ */
+cc.REPEAT = 0x2901;
+
+/**
+ * the constant variable equals gl.CLAMP_TO_EDGE for texture
+ * @constant
+ * @type Number
+ */
+cc.CLAMP_TO_EDGE = 0x812f;
+
+/**
+ * the constant variable equals gl.MIRRORED_REPEAT for texture
+ * @constant
+ * @type Number
+ */
+cc.MIRRORED_REPEAT = 0x8370;
+
+/**
+ * default gl blend src function. Compatible with premultiplied alpha images.
+ * @constant
+ * @name cc.BLEND_SRC
+ * @type Number
+ */
+cc.BLEND_SRC = cc.SRC_ALPHA;
+cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL
+ && cc.OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA) {
+ cc.BLEND_SRC = cc.ONE;
+ }
+});
+
+/**
+ * default gl blend dst function. Compatible with premultiplied alpha images.
+ * @constant
+ * @type Number
+ */
+cc.BLEND_DST = cc.ONE_MINUS_SRC_ALPHA;
+
+/**
+ * Check webgl error.Error will be shown in console if exists.
+ * @function
+ */
+cc.checkGLErrorDebug = function () {
+ if (cc.renderMode === cc.game.RENDER_TYPE_WEBGL) {
+ var _error = cc._renderContext.getError();
+ if (_error) {
+ cc.log(cc._LogInfos.checkGLErrorDebug, _error);
+ }
+ }
+};
+
+//Possible device orientations
+/**
+ * Device oriented vertically, home button on the bottom (UIDeviceOrientationPortrait)
+ * @constant
+ * @type Number
+ */
+cc.ORIENTATION_PORTRAIT = 1;
+
+/**
+ * Device oriented horizontally, home button on the right (UIDeviceOrientationLandscapeLeft)
+ * @constant
+ * @type Number
+ */
+cc.ORIENTATION_LANDSCAPE = 2;
+
+/**
+ * Device oriented vertically, home button on the top (UIDeviceOrientationPortraitUpsideDown)
+ * @constant
+ * @type Number
+ */
+cc.ORIENTATION_AUTO = 3;
+
+/**
+ * The limit count for concurrency http request, useful in some mobile browsers
+ * Adjust its value with the test results based on your game, the preset value is just a placeholder
+ * @constant
+ * @type Number
+ */
+cc.CONCURRENCY_HTTP_REQUEST_COUNT = cc.sys.isMobile ? 20 : 0;
+
+/**
+ * The maximum vertex count for a single batched draw call.
+ * @constant
+ * @type Number
+ */
+cc.BATCH_VERTEX_COUNT = 2000;
+
+
+// ------------------- vertex attrib flags -----------------------------
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.VERTEX_ATTRIB_FLAG_NONE = 0;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.VERTEX_ATTRIB_FLAG_POSITION = 1 << 0;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.VERTEX_ATTRIB_FLAG_COLOR = 1 << 1;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.VERTEX_ATTRIB_FLAG_TEX_COORDS = 1 << 2;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.VERTEX_ATTRIB_FLAG_POS_COLOR_TEX = ( cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_COLOR | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS );
+
+/**
+ * GL server side states
+ * @constant
+ * @type {Number}
+ */
+cc.GL_ALL = 0;
+
+//-------------Vertex Attributes-----------
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.VERTEX_ATTRIB_POSITION = 0;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.VERTEX_ATTRIB_COLOR = 1;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.VERTEX_ATTRIB_TEX_COORDS = 2;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.VERTEX_ATTRIB_MAX = 7;
+
+//------------Uniforms------------------
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.UNIFORM_PMATRIX = 0;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.UNIFORM_MVMATRIX = 1;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.UNIFORM_MVPMATRIX = 2;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.UNIFORM_TIME = 3;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.UNIFORM_SINTIME = 4;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.UNIFORM_COSTIME = 5;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.UNIFORM_RANDOM01 = 6;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.UNIFORM_SAMPLER = 7;
+/**
+ * @constant
+ * @type {Number}
+ */
+cc.UNIFORM_MAX = 8;
+
+//------------Shader Name---------------
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_TEXTURECOLOR = "ShaderPositionTextureColor";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_SPRITE_POSITION_TEXTURECOLOR = "ShaderSpritePositionTextureColor";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_SPRITE_POSITION_TEXTURECOLOR_GRAY = "ShaderSpritePositionTextureColorGray";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_TEXTURECOLORALPHATEST = "ShaderPositionTextureColorAlphaTest";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST = "ShaderSpritePositionTextureColorAlphaTest";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_COLOR = "ShaderPositionColor";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_SPRITE_POSITION_COLOR = "ShaderSpritePositionColor";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_TEXTURE = "ShaderPositionTexture";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_TEXTURE_UCOLOR = "ShaderPositionTextureUColor";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_TEXTUREA8COLOR = "ShaderPositionTextureA8Color";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_UCOLOR = "ShaderPositionUColor";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_LENGTHTEXTURECOLOR = "ShaderPositionLengthTextureColor";
+
+//------------uniform names----------------
+/**
+ * @constant
+ * @type {String}
+ */
+cc.UNIFORM_PMATRIX_S = "CC_PMatrix";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.UNIFORM_MVMATRIX_S = "CC_MVMatrix";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.UNIFORM_MVPMATRIX_S = "CC_MVPMatrix";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.UNIFORM_TIME_S = "CC_Time";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.UNIFORM_SINTIME_S = "CC_SinTime";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.UNIFORM_COSTIME_S = "CC_CosTime";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.UNIFORM_RANDOM01_S = "CC_Random01";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.UNIFORM_SAMPLER_S = "CC_Texture0";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.UNIFORM_ALPHA_TEST_VALUE_S = "CC_alpha_value";
+
+//------------Attribute names--------------
+/**
+ * @constant
+ * @type {String}
+ */
+cc.ATTRIBUTE_NAME_COLOR = "a_color";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.ATTRIBUTE_NAME_POSITION = "a_position";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.ATTRIBUTE_NAME_TEX_COORD = "a_texCoord";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.ATTRIBUTE_NAME_MVMAT = "a_mvMatrix";
+
+
+/**
+ * default size for font size
+ * @constant
+ * @type Number
+ */
+cc.ITEM_SIZE = 32;
+
+/**
+ * default tag for current item
+ * @constant
+ * @type Number
+ */
+cc.CURRENT_ITEM = 0xc0c05001;
+/**
+ * default tag for zoom action tag
+ * @constant
+ * @type Number
+ */
+cc.ZOOM_ACTION_TAG = 0xc0c05002;
+/**
+ * default tag for normal
+ * @constant
+ * @type Number
+ */
+cc.NORMAL_TAG = 8801;
+
+/**
+ * default selected tag
+ * @constant
+ * @type Number
+ */
+cc.SELECTED_TAG = 8802;
+
+/**
+ * default disabled tag
+ * @constant
+ * @type Number
+ */
+cc.DISABLE_TAG = 8803;
+
+
+// Array utils
+
+/**
+ * Verify Array's Type
+ * @param {Array} arr
+ * @param {function} type
+ * @return {Boolean}
+ * @function
+ */
+cc.arrayVerifyType = function (arr, type) {
+ if (arr && arr.length > 0) {
+ for (var i = 0; i < arr.length; i++) {
+ if (!(arr[i] instanceof type)) {
+ cc.log("element type is wrong!");
+ return false;
+ }
+ }
+ }
+ return true;
+};
+
+/**
+ * Searches for the first occurrence of object and removes it. If object is not found the function has no effect.
+ * @function
+ * @param {Array} arr Source Array
+ * @param {*} delObj remove object
+ */
+cc.arrayRemoveObject = function (arr, delObj) {
+ for (var i = 0, l = arr.length; i < l; i++) {
+ if (arr[i] === delObj) {
+ arr.splice(i, 1);
+ break;
+ }
+ }
+};
+
+/**
+ * Removes from arr all values in minusArr. For each Value in minusArr, the first matching instance in arr will be removed.
+ * @function
+ * @param {Array} arr Source Array
+ * @param {Array} minusArr minus Array
+ */
+cc.arrayRemoveArray = function (arr, minusArr) {
+ for (var i = 0, l = minusArr.length; i < l; i++) {
+ cc.arrayRemoveObject(arr, minusArr[i]);
+ }
+};
+
+/**
+ * Inserts some objects at index
+ * @function
+ * @param {Array} arr
+ * @param {Array} addObjs
+ * @param {Number} index
+ * @return {Array}
+ */
+cc.arrayAppendObjectsToIndex = function(arr, addObjs,index){
+ arr.splice.apply(arr, [index, 0].concat(addObjs));
+ return arr;
+};
+
+/**
+ * Copy an array's item to a new array (its performance is better than Array.slice)
+ * @param {Array} arr
+ * @return {Array}
+ */
+cc.copyArray = function(arr){
+ var i, len = arr.length, arr_clone = new Array(len);
+ for (i = 0; i < len; i += 1)
+ arr_clone[i] = arr[i];
+ return arr_clone;
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/core/platform/CCSAXParser.js b/frameworks/cocos2d-html5/cocos2d/core/platform/CCSAXParser.js
new file mode 100644
index 0000000..f504962
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/platform/CCSAXParser.js
@@ -0,0 +1,170 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * A SAX Parser
+ * @class
+ * @name cc.saxParser
+ * @extends cc.Class
+ */
+cc.SAXParser = cc.Class.extend(/** @lends cc.saxParser# */{
+ _parser: null,
+ _isSupportDOMParser: null,
+
+ /**
+ * Constructor of cc.SAXParser
+ */
+ ctor: function () {
+ if (window.DOMParser) {
+ this._isSupportDOMParser = true;
+ this._parser = new DOMParser();
+ } else {
+ this._isSupportDOMParser = false;
+ }
+ },
+
+ /**
+ * @function
+ * @param {String} xmlTxt
+ * @return {Document}
+ */
+ parse : function(xmlTxt){
+ return this._parseXML(xmlTxt);
+ },
+
+ _parseXML: function (textxml) {
+ // get a reference to the requested corresponding xml file
+ var xmlDoc;
+ if (this._isSupportDOMParser) {
+ xmlDoc = this._parser.parseFromString(textxml, "text/xml");
+ } else {
+ // Internet Explorer (untested!)
+ xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
+ xmlDoc.async = "false";
+ xmlDoc.loadXML(textxml);
+ }
+ return xmlDoc;
+ }
+
+});
+
+/**
+ *
+ * cc.plistParser is a singleton object for parsing plist files
+ * @class
+ * @name cc.plistParser
+ * @extends cc.SAXParser
+ */
+cc.PlistParser = cc.SAXParser.extend(/** @lends cc.plistParser# */{
+
+ /**
+ * parse a xml string as plist object.
+ * @param {String} xmlTxt plist xml contents
+ * @return {*} plist object
+ */
+ parse : function (xmlTxt) {
+ var xmlDoc = this._parseXML(xmlTxt);
+ var plist = xmlDoc.documentElement;
+ if (plist.tagName !== 'plist') {
+ cc.warn("Not a plist file!");
+ return {};
+ }
+
+ // Get first real node
+ var node = null;
+ for (var i = 0, len = plist.childNodes.length; i < len; i++) {
+ node = plist.childNodes[i];
+ if (node.nodeType === 1)
+ break;
+ }
+ xmlDoc = null;
+ return this._parseNode(node);
+ },
+
+ _parseNode: function (node) {
+ var data = null, tagName = node.tagName;
+ if(tagName === "dict"){
+ data = this._parseDict(node);
+ }else if(tagName === "array"){
+ data = this._parseArray(node);
+ }else if(tagName === "string"){
+ if (node.childNodes.length === 1)
+ data = node.firstChild.nodeValue;
+ else {
+ //handle Firefox's 4KB nodeValue limit
+ data = "";
+ for (var i = 0; i < node.childNodes.length; i++)
+ data += node.childNodes[i].nodeValue;
+ }
+ }else if(tagName === "false"){
+ data = false;
+ }else if(tagName === "true"){
+ data = true;
+ }else if(tagName === "real"){
+ data = parseFloat(node.firstChild.nodeValue);
+ }else if(tagName === "integer"){
+ data = parseInt(node.firstChild.nodeValue, 10);
+ }
+ return data;
+ },
+
+ _parseArray: function (node) {
+ var data = [];
+ for (var i = 0, len = node.childNodes.length; i < len; i++) {
+ var child = node.childNodes[i];
+ if (child.nodeType !== 1)
+ continue;
+ data.push(this._parseNode(child));
+ }
+ return data;
+ },
+
+ _parseDict: function (node) {
+ var data = {};
+ var key = null;
+ for (var i = 0, len = node.childNodes.length; i < len; i++) {
+ var child = node.childNodes[i];
+ if (child.nodeType !== 1)
+ continue;
+
+ // Grab the key, next noe should be the value
+ if (child.tagName === 'key')
+ key = child.firstChild.nodeValue;
+ else
+ data[key] = this._parseNode(child); // Parse the value node
+ }
+ return data;
+ }
+});
+
+cc.saxParser = new cc.SAXParser();
+/**
+ * A Plist Parser
+ * @type {cc.PlistParser}
+ * @name plistParser
+ * @memberof cc
+ */
+cc.plistParser = new cc.PlistParser();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/platform/CCScreen.js b/frameworks/cocos2d-html5/cocos2d/core/platform/CCScreen.js
new file mode 100644
index 0000000..8bc1e4d
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/platform/CCScreen.js
@@ -0,0 +1,161 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The fullscreen API provides an easy way for web content to be presented using the user's entire screen.
+ * It's invalid on safari, QQbrowser and android browser
+ * @class
+ * @name cc.screen
+ */
+cc.screen = /** @lends cc.screen# */{
+ _supportsFullScreen: false,
+ // the pre fullscreenchange function
+ _preOnFullScreenChange: null,
+ _touchEvent: "",
+ _fn: null,
+ // Function mapping for cross browser support
+ _fnMap: [
+ [
+ 'requestFullscreen',
+ 'exitFullscreen',
+ 'fullscreenchange',
+ 'fullscreenEnabled',
+ 'fullscreenElement'
+ ],
+ [
+ 'requestFullScreen',
+ 'exitFullScreen',
+ 'fullScreenchange',
+ 'fullScreenEnabled',
+ 'fullScreenElement'
+ ],
+ [
+ 'webkitRequestFullScreen',
+ 'webkitCancelFullScreen',
+ 'webkitfullscreenchange',
+ 'webkitIsFullScreen',
+ 'webkitCurrentFullScreenElement'
+ ],
+ [
+ 'mozRequestFullScreen',
+ 'mozCancelFullScreen',
+ 'mozfullscreenchange',
+ 'mozFullScreen',
+ 'mozFullScreenElement'
+ ],
+ [
+ 'msRequestFullscreen',
+ 'msExitFullscreen',
+ 'MSFullscreenChange',
+ 'msFullscreenEnabled',
+ 'msFullscreenElement'
+ ]
+ ],
+
+ /**
+ * initialize
+ * @function
+ */
+ init: function () {
+ this._fn = {};
+ var i, val, map = this._fnMap, valL;
+ for (i = 0, l = map.length; i < l; i++) {
+ val = map[i];
+ if (val && val[1] in document) {
+ for (i = 0, valL = val.length; i < valL; i++) {
+ this._fn[map[0][i]] = val[i];
+ }
+ break;
+ }
+ }
+
+ this._supportsFullScreen = (typeof this._fn.requestFullscreen !== 'undefined');
+ this._touchEvent = ('ontouchstart' in window) ? 'touchstart' : 'mousedown';
+ },
+
+ /**
+ * return true if it's full now.
+ * @returns {Boolean}
+ */
+ fullScreen: function () {
+ if(!this._supportsFullScreen) return false;
+ else if( document[this._fn.fullscreenElement] === undefined || document[this._fn.fullscreenElement] === null )
+ return false;
+ else
+ return true;
+ },
+
+ /**
+ * change the screen to full mode.
+ * @param {Element} element
+ * @param {Function} onFullScreenChange
+ */
+ requestFullScreen: function (element, onFullScreenChange) {
+ if (!this._supportsFullScreen) {
+ return;
+ }
+
+ element = element || document.documentElement;
+
+ if (onFullScreenChange) {
+ var eventName = this._fn.fullscreenchange;
+ if (this._preOnFullScreenChange) {
+ document.removeEventListener(eventName, this._preOnFullScreenChange);
+ }
+ this._preOnFullScreenChange = onFullScreenChange;
+ document.addEventListener(eventName, onFullScreenChange, false);
+ }
+
+ return element[this._fn.requestFullscreen]();
+ },
+
+ /**
+ * exit the full mode.
+ * @return {Boolean}
+ */
+ exitFullScreen: function () {
+ return this._supportsFullScreen ? document[this._fn.exitFullscreen]() : true;
+ },
+
+ /**
+ * Automatically request full screen with a touch/click event
+ * @param {Element} element
+ * @param {Function} onFullScreenChange
+ */
+ autoFullScreen: function (element, onFullScreenChange) {
+ element = element || document.body;
+ var touchTarget = cc.game.canvas || element;
+ var theScreen = this;
+ // Function bind will be too complicated here because we need the callback function's reference to remove the listener
+ function callback() {
+ touchTarget.removeEventListener(theScreen._touchEvent, callback);
+ theScreen.requestFullScreen(element, onFullScreenChange);
+ }
+ this.requestFullScreen(element, onFullScreenChange);
+ touchTarget.addEventListener(this._touchEvent, callback);
+ }
+};
+cc.screen.init();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/platform/CCTypes.js b/frameworks/cocos2d-html5/cocos2d/core/platform/CCTypes.js
new file mode 100644
index 0000000..e076fe2
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/platform/CCTypes.js
@@ -0,0 +1,1178 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Color class, please use cc.color() to construct a color
+ * @class cc.Color
+ * @param {Number} r
+ * @param {Number} g
+ * @param {Number} b
+ * @param {Number} a
+ * @see cc.color
+ */
+cc.Color = function (r, g, b, a) {
+ r = r || 0;
+ g = g || 0;
+ b = b || 0;
+ a = typeof a === 'number' ? a : 255;
+ this._val = ((r << 24) >>> 0) + (g << 16) + (b << 8) + a;
+};
+
+var _p = cc.Color.prototype;
+_p._getR = function () {
+ return (this._val & 0xff000000) >>> 24;
+};
+_p._setR = function (value) {
+ this._val = (this._val & 0x00ffffff) | ((value << 24) >>> 0);
+};
+_p._getG = function () {
+ return (this._val & 0x00ff0000) >> 16;
+};
+_p._setG = function (value) {
+ this._val = (this._val & 0xff00ffff) | (value << 16);
+};
+_p._getB = function () {
+ return (this._val & 0x0000ff00) >> 8;
+};
+_p._setB = function (value) {
+ this._val = (this._val & 0xffff00ff) | (value << 8);
+};
+_p._getA = function () {
+ return this._val & 0x000000ff;
+};
+_p._setA = function (value) {
+ this._val = (this._val & 0xffffff00) | value;
+};
+
+
+/** @expose */
+_p.r;
+cc.defineGetterSetter(_p, "r", _p._getR, _p._setR);
+/** @expose */
+_p.g;
+cc.defineGetterSetter(_p, "g", _p._getG, _p._setG);
+/** @expose */
+_p.b;
+cc.defineGetterSetter(_p, "b", _p._getB, _p._setB);
+/** @expose */
+_p.a;
+cc.defineGetterSetter(_p, "a", _p._getA, _p._setA);
+
+/**
+ * Generate a color object based on multiple forms of parameters
+ * @example
+ *
+ * // 1. All channels separately as parameters
+ * var color1 = cc.color(255, 255, 255, 255);
+ *
+ * // 2. Convert a hex string to a color
+ * var color2 = cc.color("#000000");
+ *
+ * // 3. An color object as parameter
+ * var color3 = cc.color({r: 255, g: 255, b: 255, a: 255});
+ *
+ * Alpha channel is optional. Default value is 255
+ *
+ * @param {Number|String|cc.Color} r
+ * @param {Number} [g]
+ * @param {Number} [b]
+ * @param {Number} [a=255]
+ * @return {cc.Color}
+ */
+cc.color = function (r, g, b, a) {
+ if (r === undefined)
+ return new cc.Color(0, 0, 0, 255);
+ if (typeof r === 'object')
+ return new cc.Color(r.r, r.g, r.b, (r.a == null) ? 255 : r.a);
+ if (typeof r === 'string')
+ return cc.hexToColor(r);
+ return new cc.Color(r, g, b, (a == null ? 255 : a));
+};
+
+/**
+ * returns true if both ccColor3B are equal. Otherwise it returns false.
+ * @function
+ * @param {cc.Color} color1
+ * @param {cc.Color} color2
+ * @return {Boolean} true if both ccColor3B are equal. Otherwise it returns false.
+ */
+cc.colorEqual = function (color1, color2) {
+ return color1.r === color2.r && color1.g === color2.g && color1.b === color2.b;
+};
+
+/**
+ * the device accelerometer reports values for each axis in units of g-force
+ * @class cc.Acceleration
+ * @constructor
+ * @param {Number} x
+ * @param {Number} y
+ * @param {Number} z
+ * @param {Number} timestamp
+ */
+cc.Acceleration = function (x, y, z, timestamp) {
+ this.x = x || 0;
+ this.y = y || 0;
+ this.z = z || 0;
+ this.timestamp = timestamp || 0;
+};
+
+/**
+ * @class cc.Vertex2F
+ * @param {Number} x
+ * @param {Number}y
+ * @param {Array} arrayBuffer
+ * @param {Number}offset
+ * @constructor
+ */
+cc.Vertex2F = function (x, y, arrayBuffer, offset) {
+ this._arrayBuffer = arrayBuffer || new ArrayBuffer(cc.Vertex2F.BYTES_PER_ELEMENT);
+ this._offset = offset || 0;
+
+ this._view = new Float32Array(this._arrayBuffer, this._offset, 2);
+ this._view[0] = x || 0;
+ this._view[1] = y || 0;
+};
+/**
+ * @constant
+ * @type {number}
+ */
+cc.Vertex2F.BYTES_PER_ELEMENT = 8;
+
+_p = cc.Vertex2F.prototype;
+_p._getX = function () {
+ return this._view[0];
+};
+_p._setX = function (xValue) {
+ this._view[0] = xValue;
+};
+_p._getY = function () {
+ return this._view[1];
+};
+_p._setY = function (yValue) {
+ this._view[1] = yValue;
+};
+/** @expose */
+_p.x;
+cc.defineGetterSetter(_p, "x", _p._getX, _p._setX);
+/** @expose */
+_p.y;
+cc.defineGetterSetter(_p, "y", _p._getY, _p._setY);
+
+/**
+ * @class cc.Vertex3F
+ * @param {Number} x
+ * @param {Number} y
+ * @param {Number}z
+ * @param {Array} arrayBuffer
+ * @param {Number} offset
+ * @constructor
+ */
+cc.Vertex3F = function (x, y, z, arrayBuffer, offset) {
+ this._arrayBuffer = arrayBuffer || new ArrayBuffer(cc.Vertex3F.BYTES_PER_ELEMENT);
+ this._offset = offset || 0;
+
+ var locArrayBuffer = this._arrayBuffer, locOffset = this._offset;
+ this._view = new Float32Array(locArrayBuffer, locOffset, 3);
+ this._view[0] = x || 0;
+ this._view[1] = y || 0;
+ this._view[2] = z || 0;
+};
+/**
+ * @constant
+ * @type {number}
+ */
+cc.Vertex3F.BYTES_PER_ELEMENT = 12;
+
+_p = cc.Vertex3F.prototype;
+_p._getX = function () {
+ return this._view[0];
+};
+_p._setX = function (xValue) {
+ this._view[0] = xValue;
+};
+_p._getY = function () {
+ return this._view[1];
+};
+_p._setY = function (yValue) {
+ this._view[1] = yValue;
+};
+_p._getZ = function () {
+ return this._view[2];
+};
+_p._setZ = function (zValue) {
+ this._view[2] = zValue;
+};
+/** @expose */
+_p.x;
+cc.defineGetterSetter(_p, "x", _p._getX, _p._setX);
+/** @expose */
+_p.y;
+cc.defineGetterSetter(_p, "y", _p._getY, _p._setY);
+/** @expose */
+_p.z;
+cc.defineGetterSetter(_p, "z", _p._getZ, _p._setZ);
+
+/**
+ * @class cc.Tex2F
+ * @param {Number} u
+ * @param {Number} v
+ * @param {Array} arrayBuffer
+ * @param {Number} offset
+ * @constructor
+ */
+cc.Tex2F = function (u, v, arrayBuffer, offset) {
+ this._arrayBuffer = arrayBuffer || new ArrayBuffer(cc.Tex2F.BYTES_PER_ELEMENT);
+ this._offset = offset || 0;
+
+ this._view = new Float32Array(this._arrayBuffer, this._offset, 2);
+ this._view[0] = u || 0;
+ this._view[1] = v || 0;
+};
+/**
+ * @constants
+ * @type {number}
+ */
+cc.Tex2F.BYTES_PER_ELEMENT = 8;
+
+_p = cc.Tex2F.prototype;
+_p._getU = function () {
+ return this._view[0];
+};
+_p._setU = function (xValue) {
+ this._view[0] = xValue;
+};
+_p._getV = function () {
+ return this._view[1];
+};
+_p._setV = function (yValue) {
+ this._view[1] = yValue;
+};
+/** @expose */
+_p.u;
+cc.defineGetterSetter(_p, "u", _p._getU, _p._setU);
+/** @expose */
+_p.v;
+cc.defineGetterSetter(_p, "v", _p._getV, _p._setV);
+
+/**
+ * @class cc.Quad2
+ * @param {cc.Vertex2F} tl
+ * @param {cc.Vertex2F} tr
+ * @param {cc.Vertex2F} bl
+ * @param {cc.Vertex2F} br
+ * @param {Array} arrayBuffer
+ * @param {Number} offset
+ * @constructor
+ */
+cc.Quad2 = function (tl, tr, bl, br, arrayBuffer, offset) {
+ this._arrayBuffer = arrayBuffer || new ArrayBuffer(cc.Quad2.BYTES_PER_ELEMENT);
+ this._offset = offset || 0;
+
+ var locArrayBuffer = this._arrayBuffer, locOffset = this._offset, locElementLen = cc.Vertex2F.BYTES_PER_ELEMENT;
+ this._tl = tl ? new cc.Vertex2F(tl.x, tl.y, locArrayBuffer, locOffset) : new cc.Vertex2F(0, 0, locArrayBuffer, locOffset);
+ locOffset += locElementLen;
+ this._tr = tr ? new cc.Vertex2F(tr.x, tr.y, locArrayBuffer, locOffset) : new cc.Vertex2F(0, 0, locArrayBuffer, locOffset);
+ locOffset += locElementLen;
+ this._bl = bl ? new cc.Vertex2F(bl.x, bl.y, locArrayBuffer, locOffset) : new cc.Vertex2F(0, 0, locArrayBuffer, locOffset);
+ locOffset += locElementLen;
+ this._br = br ? new cc.Vertex2F(br.x, br.y, locArrayBuffer, locOffset) : new cc.Vertex2F(0, 0, locArrayBuffer, locOffset);
+};
+/**
+ * @constant
+ * @type {number}
+ */
+cc.Quad2.BYTES_PER_ELEMENT = 32;
+
+_p = cc.Quad2.prototype;
+_p._getTL = function () {
+ return this._tl;
+};
+_p._setTL = function (tlValue) {
+ this._tl._view[0] = tlValue.x;
+ this._tl._view[1] = tlValue.y;
+};
+_p._getTR = function () {
+ return this._tr;
+};
+_p._setTR = function (trValue) {
+ this._tr._view[0] = trValue.x;
+ this._tr._view[1] = trValue.y;
+};
+_p._getBL = function () {
+ return this._bl;
+};
+_p._setBL = function (blValue) {
+ this._bl._view[0] = blValue.x;
+ this._bl._view[1] = blValue.y;
+};
+_p._getBR = function () {
+ return this._br;
+};
+_p._setBR = function (brValue) {
+ this._br._view[0] = brValue.x;
+ this._br._view[1] = brValue.y;
+};
+
+/** @expose */
+_p.tl;
+cc.defineGetterSetter(_p, "tl", _p._getTL, _p._setTL);
+/** @expose */
+_p.tr;
+cc.defineGetterSetter(_p, "tr", _p._getTR, _p._setTR);
+/** @expose */
+_p.bl;
+cc.defineGetterSetter(_p, "bl", _p._getBL, _p._setBL);
+/** @expose */
+_p.br;
+cc.defineGetterSetter(_p, "br", _p._getBR, _p._setBR);
+
+/**
+ * A 3D Quad. 4 * 3 floats
+ * @Class cc.Quad3
+ * @Construct
+ * @param {cc.Vertex3F} bl
+ * @param {cc.Vertex3F} br
+ * @param {cc.Vertex3F} tl
+ * @param {cc.Vertex3F} tr
+ */
+cc.Quad3 = function (bl, br, tl, tr, arrayBuffer, offset) {
+ this._arrayBuffer = arrayBuffer || new ArrayBuffer(cc.Quad3.BYTES_PER_ELEMENT);
+ this._offset = offset || 0;
+
+ var locArrayBuffer = this._arrayBuffer, locOffset = this._offset, locElementLen = cc.Vertex3F.BYTES_PER_ELEMENT;
+ this.bl = bl ? new cc.Vertex3F(bl.x, bl.y, bl.z, locArrayBuffer, locOffset) : new cc.Vertex3F(0, 0, 0, locArrayBuffer, locOffset);
+ locOffset += locElementLen;
+ this.br = br ? new cc.Vertex3F(br.x, br.y, br.z, locArrayBuffer, locOffset) : new cc.Vertex3F(0, 0, 0, locArrayBuffer, locOffset);
+ locOffset += locElementLen;
+ this.tl = tl ? new cc.Vertex3F(tl.x, tl.y, tl.z, locArrayBuffer, locOffset) : new cc.Vertex3F(0, 0, 0, locArrayBuffer, locOffset);
+ locOffset += locElementLen;
+ this.tr = tr ? new cc.Vertex3F(tr.x, tr.y, tr.z, locArrayBuffer, locOffset) : new cc.Vertex3F(0, 0, 0, locArrayBuffer, locOffset);
+};
+/**
+ * @constant
+ * @type {number}
+ */
+cc.Quad3.BYTES_PER_ELEMENT = 48;
+
+/**
+ * @class cc.V3F_C4B_T2F
+ * @param {cc.Vertex3F} vertices
+ * @param {cc.Color} colors
+ * @param {cc.Tex2F} texCoords
+ * @param {Array} arrayBuffer
+ * @param {Number} offset
+ * @constructor
+ */
+cc.V3F_C4B_T2F = function (vertices, colors, texCoords, arrayBuffer, offset) {
+ this._arrayBuffer = arrayBuffer || new ArrayBuffer(cc.V3F_C4B_T2F.BYTES_PER_ELEMENT);
+ this._offset = offset || 0;
+
+ var locArrayBuffer = this._arrayBuffer, locOffset = this._offset;
+ this._vertices = vertices ? new cc.Vertex3F(vertices.x, vertices.y, vertices.z, locArrayBuffer, locOffset) :
+ new cc.Vertex3F(0, 0, 0, locArrayBuffer, locOffset);
+
+ locOffset += cc.Vertex3F.BYTES_PER_ELEMENT;
+ this._colors = colors ? new cc._WebGLColor(colors.r, colors.g, colors.b, colors.a, locArrayBuffer, locOffset) :
+ new cc._WebGLColor(0, 0, 0, 0, locArrayBuffer, locOffset);
+
+ locOffset += cc._WebGLColor.BYTES_PER_ELEMENT;
+ this._texCoords = texCoords ? new cc.Tex2F(texCoords.u, texCoords.v, locArrayBuffer, locOffset) :
+ new cc.Tex2F(0, 0, locArrayBuffer, locOffset);
+};
+/**
+ * @constant
+ * @type {number}
+ */
+cc.V3F_C4B_T2F.BYTES_PER_ELEMENT = 24;
+
+_p = cc.V3F_C4B_T2F.prototype;
+_p._getVertices = function () {
+ return this._vertices;
+};
+_p._setVertices = function (verticesValue) {
+ var locVertices = this._vertices;
+ locVertices._view[0] = verticesValue.x;
+ locVertices._view[1] = verticesValue.y;
+ locVertices._view[2] = verticesValue.z;
+};
+_p._getColor = function () {
+ return this._colors;
+};
+_p._setColor = function (colorValue) {
+ var locColors = this._colors;
+ locColors._view[0] = colorValue.r;
+ locColors._view[1] = colorValue.g;
+ locColors._view[2] = colorValue.b;
+ locColors._view[3] = colorValue.a;
+};
+_p._getTexCoords = function () {
+ return this._texCoords;
+};
+_p._setTexCoords = function (texValue) {
+ this._texCoords._view[0] = texValue.u;
+ this._texCoords._view[1] = texValue.v;
+};
+/** @expose */
+_p.vertices;
+cc.defineGetterSetter(_p, "vertices", _p._getVertices, _p._setVertices);
+/** @expose */
+_p.colors;
+cc.defineGetterSetter(_p, "colors", _p._getColor, _p._setColor);
+/** @expose */
+_p.texCoords;
+cc.defineGetterSetter(_p, "texCoords", _p._getTexCoords, _p._setTexCoords);
+
+/**
+ * @cc.class cc.V3F_C4B_T2F_Quad
+ * @param {cc.V3F_C4B_T2F} tl
+ * @param {cc.V3F_C4B_T2F} bl
+ * @param {cc.V3F_C4B_T2F} tr
+ * @param {cc.V3F_C4B_T2F} br
+ * @param {Array} arrayBuffer
+ * @param {Number} offset
+ * @constructor
+ */
+cc.V3F_C4B_T2F_Quad = function (tl, bl, tr, br, arrayBuffer, offset) {
+ this._arrayBuffer = arrayBuffer || new ArrayBuffer(cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT);
+ this._offset = offset || 0;
+
+ var locArrayBuffer = this._arrayBuffer, locOffset = this._offset, locElementLen = cc.V3F_C4B_T2F.BYTES_PER_ELEMENT;
+ this._tl = tl ? new cc.V3F_C4B_T2F(tl.vertices, tl.colors, tl.texCoords, locArrayBuffer, locOffset) :
+ new cc.V3F_C4B_T2F(null, null, null, locArrayBuffer, locOffset);
+ locOffset += locElementLen;
+ this._bl = bl ? new cc.V3F_C4B_T2F(bl.vertices, bl.colors, bl.texCoords, locArrayBuffer, locOffset) :
+ new cc.V3F_C4B_T2F(null, null, null, locArrayBuffer, locOffset);
+ locOffset += locElementLen;
+ this._tr = tr ? new cc.V3F_C4B_T2F(tr.vertices, tr.colors, tr.texCoords, locArrayBuffer, locOffset) :
+ new cc.V3F_C4B_T2F(null, null, null, locArrayBuffer, locOffset);
+ locOffset += locElementLen;
+ this._br = br ? new cc.V3F_C4B_T2F(br.vertices, br.colors, br.texCoords, locArrayBuffer, locOffset) :
+ new cc.V3F_C4B_T2F(null, null, null, locArrayBuffer, locOffset);
+};
+/**
+ * @constant
+ * @type {number}
+ */
+cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT = 96;
+_p = cc.V3F_C4B_T2F_Quad.prototype;
+_p._getTL = function () {
+ return this._tl;
+};
+_p._setTL = function (tlValue) {
+ var locTl = this._tl;
+ locTl.vertices = tlValue.vertices;
+ locTl.colors = tlValue.colors;
+ locTl.texCoords = tlValue.texCoords;
+};
+_p._getBL = function () {
+ return this._bl;
+};
+_p._setBL = function (blValue) {
+ var locBl = this._bl;
+ locBl.vertices = blValue.vertices;
+ locBl.colors = blValue.colors;
+ locBl.texCoords = blValue.texCoords;
+};
+_p._getTR = function () {
+ return this._tr;
+};
+_p._setTR = function (trValue) {
+ var locTr = this._tr;
+ locTr.vertices = trValue.vertices;
+ locTr.colors = trValue.colors;
+ locTr.texCoords = trValue.texCoords;
+};
+_p._getBR = function () {
+ return this._br;
+};
+_p._setBR = function (brValue) {
+ var locBr = this._br;
+ locBr.vertices = brValue.vertices;
+ locBr.colors = brValue.colors;
+ locBr.texCoords = brValue.texCoords;
+};
+_p._getArrayBuffer = function () {
+ return this._arrayBuffer;
+};
+
+/** @expose */
+_p.tl;
+cc.defineGetterSetter(_p, "tl", _p._getTL, _p._setTL);
+/** @expose */
+_p.tr;
+cc.defineGetterSetter(_p, "tr", _p._getTR, _p._setTR);
+/** @expose */
+_p.bl;
+cc.defineGetterSetter(_p, "bl", _p._getBL, _p._setBL);
+/** @expose */
+_p.br;
+cc.defineGetterSetter(_p, "br", _p._getBR, _p._setBR);
+/** @expose */
+_p.arrayBuffer;
+cc.defineGetterSetter(_p, "arrayBuffer", _p._getArrayBuffer, null);
+
+/**
+ * @function
+ * @returns {cc.V3F_C4B_T2F_Quad}
+ */
+cc.V3F_C4B_T2F_QuadZero = function () {
+ return new cc.V3F_C4B_T2F_Quad();
+};
+
+/**
+ * @function
+ * @param {cc.V3F_C4B_T2F_Quad} sourceQuad
+ * @return {cc.V3F_C4B_T2F_Quad}
+ */
+cc.V3F_C4B_T2F_QuadCopy = function (sourceQuad) {
+ if (!sourceQuad)
+ return cc.V3F_C4B_T2F_QuadZero();
+
+ //return new cc.V3F_C4B_T2F_Quad(sourceQuad,tl,sourceQuad,bl,sourceQuad.tr,sourceQuad.br,null,0);
+ var srcTL = sourceQuad.tl, srcBL = sourceQuad.bl, srcTR = sourceQuad.tr, srcBR = sourceQuad.br;
+ return {
+ tl: {
+ vertices: {x: srcTL.vertices.x, y: srcTL.vertices.y, z: srcTL.vertices.z},
+ colors: {r: srcTL.colors.r, g: srcTL.colors.g, b: srcTL.colors.b, a: srcTL.colors.a},
+ texCoords: {u: srcTL.texCoords.u, v: srcTL.texCoords.v}
+ },
+ bl: {
+ vertices: {x: srcBL.vertices.x, y: srcBL.vertices.y, z: srcBL.vertices.z},
+ colors: {r: srcBL.colors.r, g: srcBL.colors.g, b: srcBL.colors.b, a: srcBL.colors.a},
+ texCoords: {u: srcBL.texCoords.u, v: srcBL.texCoords.v}
+ },
+ tr: {
+ vertices: {x: srcTR.vertices.x, y: srcTR.vertices.y, z: srcTR.vertices.z},
+ colors: {r: srcTR.colors.r, g: srcTR.colors.g, b: srcTR.colors.b, a: srcTR.colors.a},
+ texCoords: {u: srcTR.texCoords.u, v: srcTR.texCoords.v}
+ },
+ br: {
+ vertices: {x: srcBR.vertices.x, y: srcBR.vertices.y, z: srcBR.vertices.z},
+ colors: {r: srcBR.colors.r, g: srcBR.colors.g, b: srcBR.colors.b, a: srcBR.colors.a},
+ texCoords: {u: srcBR.texCoords.u, v: srcBR.texCoords.v}
+ }
+ };
+};
+
+/**
+ * @function
+ * @param {Array} sourceQuads
+ * @returns {Array}
+ */
+cc.V3F_C4B_T2F_QuadsCopy = function (sourceQuads) {
+ if (!sourceQuads)
+ return [];
+
+ var retArr = [];
+ for (var i = 0; i < sourceQuads.length; i++) {
+ retArr.push(cc.V3F_C4B_T2F_QuadCopy(sourceQuads[i]));
+ }
+ return retArr;
+};
+
+//redefine cc.V2F_C4B_T2F
+/**
+ * @class cc.V2F_C4B_T2F
+ * @param {cc.Vertex2F} vertices
+ * @param {cc.Color} colors
+ * @param {cc.Tex2F} texCoords
+ * @param {Array} arrayBuffer
+ * @param {Number} offset
+ * @constructor
+ */
+cc.V2F_C4B_T2F = function (vertices, colors, texCoords, arrayBuffer, offset) {
+ this._arrayBuffer = arrayBuffer || new ArrayBuffer(cc.V2F_C4B_T2F.BYTES_PER_ELEMENT);
+ this._offset = offset || 0;
+
+ var locArrayBuffer = this._arrayBuffer, locOffset = this._offset;
+ this._vertices = vertices ? new cc.Vertex2F(vertices.x, vertices.y, locArrayBuffer, locOffset) :
+ new cc.Vertex2F(0, 0, locArrayBuffer, locOffset);
+ locOffset += cc.Vertex2F.BYTES_PER_ELEMENT;
+ this._colors = colors ? new cc._WebGLColor(colors.r, colors.g, colors.b, colors.a, locArrayBuffer, locOffset) :
+ new cc._WebGLColor(0, 0, 0, 0, locArrayBuffer, locOffset);
+ locOffset += cc._WebGLColor.BYTES_PER_ELEMENT;
+ this._texCoords = texCoords ? new cc.Tex2F(texCoords.u, texCoords.v, locArrayBuffer, locOffset) :
+ new cc.Tex2F(0, 0, locArrayBuffer, locOffset);
+};
+
+/**
+ * @constant
+ * @type {number}
+ */
+cc.V2F_C4B_T2F.BYTES_PER_ELEMENT = 20;
+_p = cc.V2F_C4B_T2F.prototype;
+_p._getVertices = function () {
+ return this._vertices;
+};
+_p._setVertices = function (verticesValue) {
+ this._vertices._view[0] = verticesValue.x;
+ this._vertices._view[1] = verticesValue.y;
+};
+_p._getColor = function () {
+ return this._colors;
+};
+_p._setColor = function (colorValue) {
+ var locColors = this._colors;
+ locColors._view[0] = colorValue.r;
+ locColors._view[1] = colorValue.g;
+ locColors._view[2] = colorValue.b;
+ locColors._view[3] = colorValue.a;
+};
+_p._getTexCoords = function () {
+ return this._texCoords;
+};
+_p._setTexCoords = function (texValue) {
+ this._texCoords._view[0] = texValue.u;
+ this._texCoords._view[1] = texValue.v;
+};
+
+/** @expose */
+_p.vertices;
+cc.defineGetterSetter(_p, "vertices", _p._getVertices, _p._setVertices);
+/** @expose */
+_p.colors;
+cc.defineGetterSetter(_p, "colors", _p._getColor, _p._setColor);
+/** @expose */
+_p.texCoords;
+cc.defineGetterSetter(_p, "texCoords", _p._getTexCoords, _p._setTexCoords);
+
+//redefine cc.V2F_C4B_T2F_Triangle
+/**
+ * @class cc.V2F_C4B_T2F_Triangle
+ * @param {cc.V2F_C4B_T2F} a
+ * @param {cc.V2F_C4B_T2F} b
+ * @param {cc.V2F_C4B_T2F} c
+ * @param {Array} arrayBuffer
+ * @param {Number} offset
+ * @constructor
+ */
+cc.V2F_C4B_T2F_Triangle = function (a, b, c, arrayBuffer, offset) {
+ this._arrayBuffer = arrayBuffer || new ArrayBuffer(cc.V2F_C4B_T2F_Triangle.BYTES_PER_ELEMENT);
+ this._offset = offset || 0;
+
+ var locArrayBuffer = this._arrayBuffer, locOffset = this._offset, locElementLen = cc.V2F_C4B_T2F.BYTES_PER_ELEMENT;
+ this._a = a ? new cc.V2F_C4B_T2F(a.vertices, a.colors, a.texCoords, locArrayBuffer, locOffset) :
+ new cc.V2F_C4B_T2F(null, null, null, locArrayBuffer, locOffset);
+ locOffset += locElementLen;
+ this._b = b ? new cc.V2F_C4B_T2F(b.vertices, b.colors, b.texCoords, locArrayBuffer, locOffset) :
+ new cc.V2F_C4B_T2F(null, null, null, locArrayBuffer, locOffset);
+ locOffset += locElementLen;
+ this._c = c ? new cc.V2F_C4B_T2F(c.vertices, c.colors, c.texCoords, locArrayBuffer, locOffset) :
+ new cc.V2F_C4B_T2F(null, null, null, locArrayBuffer, locOffset);
+};
+/**
+ * @constant
+ * @type {number}
+ */
+cc.V2F_C4B_T2F_Triangle.BYTES_PER_ELEMENT = 60;
+_p = cc.V2F_C4B_T2F_Triangle.prototype;
+_p._getA = function () {
+ return this._a;
+};
+_p._setA = function (aValue) {
+ var locA = this._a;
+ locA.vertices = aValue.vertices;
+ locA.colors = aValue.colors;
+ locA.texCoords = aValue.texCoords;
+};
+_p._getB = function () {
+ return this._b;
+};
+_p._setB = function (bValue) {
+ var locB = this._b;
+ locB.vertices = bValue.vertices;
+ locB.colors = bValue.colors;
+ locB.texCoords = bValue.texCoords;
+};
+_p._getC = function () {
+ return this._c;
+};
+_p._setC = function (cValue) {
+ var locC = this._c;
+ locC.vertices = cValue.vertices;
+ locC.colors = cValue.colors;
+ locC.texCoords = cValue.texCoords;
+};
+
+/** @expose */
+_p.a;
+cc.defineGetterSetter(_p, "a", _p._getA, _p._setA);
+/** @expose */
+_p.b;
+cc.defineGetterSetter(_p, "b", _p._getB, _p._setB);
+/** @expose */
+_p.c;
+cc.defineGetterSetter(_p, "c", _p._getC, _p._setC);
+
+/**
+ * Helper macro that creates an Vertex2F type composed of 2 floats: x, y
+ * @function
+ * @param {Number} x
+ * @param {Number} y
+ * @return {cc.Vertex2F}
+ */
+cc.vertex2 = function (x, y) {
+ return new cc.Vertex2F(x, y);
+};
+
+/**
+ * Helper macro that creates an Vertex3F type composed of 3 floats: x, y, z
+ * @function
+ * @param {Number} x
+ * @param {Number} y
+ * @param {Number} z
+ * @return {cc.Vertex3F}
+ */
+cc.vertex3 = function (x, y, z) {
+ return new cc.Vertex3F(x, y, z);
+};
+
+/**
+ * Helper macro that creates an Tex2F type: A texcoord composed of 2 floats: u, y
+ * @function
+ * @param {Number} u
+ * @param {Number} v
+ * @return {cc.Tex2F}
+ */
+cc.tex2 = function (u, v) {
+ return new cc.Tex2F(u, v);
+};
+
+/**
+ * Blend Function used for textures
+ * @Class cc.BlendFunc
+ * @Constructor
+ * @param {Number} src1 source blend function
+ * @param {Number} dst1 destination blend function
+ */
+cc.BlendFunc = function (src1, dst1) {
+ this.src = src1;
+ this.dst = dst1;
+};
+
+/**
+ * @function
+ * @returns {cc.BlendFunc}
+ */
+cc.blendFuncDisable = function () {
+ return new cc.BlendFunc(cc.ONE, cc.ZERO);
+};
+
+/**
+ * convert a string of color for style to Color.
+ * e.g. "#ff06ff" to : cc.color(255,6,255)
+ * @function
+ * @param {String} hex
+ * @return {cc.Color}
+ */
+cc.hexToColor = function (hex) {
+ hex = hex.replace(/^#?/, "0x");
+ var c = parseInt(hex);
+ var r = c >> 16;
+ var g = (c >> 8) % 256;
+ var b = c % 256;
+ return new cc.Color(r, g, b);
+};
+
+/**
+ * convert Color to a string of color for style.
+ * e.g. cc.color(255,6,255) to : "#ff06ff"
+ * @function
+ * @param {cc.Color} color
+ * @return {String}
+ */
+cc.colorToHex = function (color) {
+ var hR = color.r.toString(16), hG = color.g.toString(16), hB = color.b.toString(16);
+ return "#" + (color.r < 16 ? ("0" + hR) : hR) + (color.g < 16 ? ("0" + hG) : hG) + (color.b < 16 ? ("0" + hB) : hB);
+};
+
+/**
+ * text alignment : left
+ * @constant
+ * @type Number
+ */
+cc.TEXT_ALIGNMENT_LEFT = 0;
+
+/**
+ * text alignment : center
+ * @constant
+ * @type Number
+ */
+cc.TEXT_ALIGNMENT_CENTER = 1;
+
+/**
+ * text alignment : right
+ * @constant
+ * @type Number
+ */
+cc.TEXT_ALIGNMENT_RIGHT = 2;
+
+/**
+ * text alignment : top
+ * @constant
+ * @type Number
+ */
+cc.VERTICAL_TEXT_ALIGNMENT_TOP = 0;
+
+/**
+ * text alignment : center
+ * @constant
+ * @type Number
+ */
+cc.VERTICAL_TEXT_ALIGNMENT_CENTER = 1;
+
+/**
+ * text alignment : bottom
+ * @constant
+ * @type Number
+ */
+cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM = 2;
+
+cc._Dictionary = cc.Class.extend({
+ _keyMapTb: null,
+ _valueMapTb: null,
+ __currId: 0,
+
+ ctor: function () {
+ this._keyMapTb = {};
+ this._valueMapTb = {};
+ this.__currId = 2 << (0 | (Math.random() * 10));
+ },
+
+ __getKey: function () {
+ this.__currId++;
+ return "key_" + this.__currId;
+ },
+
+ setObject: function (value, key) {
+ if (key == null)
+ return;
+
+ var keyId = this.__getKey();
+ this._keyMapTb[keyId] = key;
+ this._valueMapTb[keyId] = value;
+ },
+
+ objectForKey: function (key) {
+ if (key == null)
+ return null;
+
+ var locKeyMapTb = this._keyMapTb;
+ for (var keyId in locKeyMapTb) {
+ if (locKeyMapTb[keyId] === key)
+ return this._valueMapTb[keyId];
+ }
+ return null;
+ },
+
+ valueForKey: function (key) {
+ return this.objectForKey(key);
+ },
+
+ removeObjectForKey: function (key) {
+ if (key == null)
+ return;
+
+ var locKeyMapTb = this._keyMapTb;
+ for (var keyId in locKeyMapTb) {
+ if (locKeyMapTb[keyId] === key) {
+ delete this._valueMapTb[keyId];
+ delete locKeyMapTb[keyId];
+ return;
+ }
+ }
+ },
+
+ removeObjectsForKeys: function (keys) {
+ if (keys == null)
+ return;
+
+ for (var i = 0; i < keys.length; i++)
+ this.removeObjectForKey(keys[i]);
+ },
+
+ allKeys: function () {
+ var keyArr = [], locKeyMapTb = this._keyMapTb;
+ for (var key in locKeyMapTb)
+ keyArr.push(locKeyMapTb[key]);
+ return keyArr;
+ },
+
+ removeAllObjects: function () {
+ this._keyMapTb = {};
+ this._valueMapTb = {};
+ },
+
+ count: function () {
+ return this.allKeys().length;
+ }
+});
+
+/**
+ * Common usage:
+ *
+ * var fontDef = new cc.FontDefinition();
+ * fontDef.fontName = "Arial";
+ * fontDef.fontSize = 12;
+ * ...
+ *
+ * OR using inline definition useful for constructor injection
+ *
+ * var fontDef = new cc.FontDefinition({
+ * fontName: "Arial",
+ * fontSize: 12
+ * });
+ *
+ *
+ *
+ * @class cc.FontDefinition
+ * @param {Object} properties - (OPTIONAL) Allow inline FontDefinition
+ * @constructor
+ */
+cc.FontDefinition = function (properties) {
+ var _t = this;
+ _t.fontName = "Arial";
+ _t.fontSize = 12;
+ _t.textAlign = cc.TEXT_ALIGNMENT_CENTER;
+ _t.verticalAlign = cc.VERTICAL_TEXT_ALIGNMENT_TOP;
+ _t.fillStyle = cc.color(255, 255, 255, 255);
+ _t.boundingWidth = 0;
+ _t.boundingHeight = 0;
+
+ _t.strokeEnabled = false;
+ _t.strokeStyle = cc.color(255, 255, 255, 255);
+ _t.lineWidth = 1;
+ _t.lineHeight = "normal";
+ _t.fontStyle = "normal";
+ _t.fontWeight = "normal";
+
+ _t.shadowEnabled = false;
+ _t.shadowOffsetX = 0;
+ _t.shadowOffsetY = 0;
+ _t.shadowBlur = 0;
+ _t.shadowOpacity = 1.0;
+
+ //properties mapping:
+ if (properties && properties instanceof Object) {
+ for (var key in properties) {
+ _t[key] = properties[key];
+ }
+ }
+};
+/**
+ * Web ONLY
+ * */
+cc.FontDefinition.prototype._getCanvasFontStr = function () {
+ var lineHeight = !this.lineHeight.charAt ? this.lineHeight + "px" : this.lineHeight;
+ return this.fontStyle + " " + this.fontWeight + " " + this.fontSize + "px/" + lineHeight + " '" + this.fontName + "'";
+};
+
+cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ //redefine Color
+ cc._WebGLColor = function (r, g, b, a, arrayBuffer, offset) {
+ this._arrayBuffer = arrayBuffer || new ArrayBuffer(cc._WebGLColor.BYTES_PER_ELEMENT);
+ this._offset = offset || 0;
+
+ var locArrayBuffer = this._arrayBuffer, locOffset = this._offset;
+ this._view = new Uint8Array(locArrayBuffer, locOffset, 4);
+
+ this._view[0] = r || 0;
+ this._view[1] = g || 0;
+ this._view[2] = b || 0;
+ this._view[3] = (a == null) ? 255 : a;
+
+ if (a === undefined)
+ this.a_undefined = true;
+ };
+ cc._WebGLColor.BYTES_PER_ELEMENT = 4;
+ _p = cc._WebGLColor.prototype;
+ _p._getR = function () {
+ return this._view[0];
+ };
+ _p._setR = function (value) {
+ this._view[0] = value < 0 ? 0 : value;
+ };
+ _p._getG = function () {
+ return this._view[1];
+ };
+ _p._setG = function (value) {
+ this._view[1] = value < 0 ? 0 : value;
+ };
+ _p._getB = function () {
+ return this._view[2];
+ };
+ _p._setB = function (value) {
+ this._view[2] = value < 0 ? 0 : value;
+ };
+ _p._getA = function () {
+ return this._view[3];
+ };
+ _p._setA = function (value) {
+ this._view[3] = value < 0 ? 0 : value;
+ };
+ cc.defineGetterSetter(_p, "r", _p._getR, _p._setR);
+ cc.defineGetterSetter(_p, "g", _p._getG, _p._setG);
+ cc.defineGetterSetter(_p, "b", _p._getB, _p._setB);
+ cc.defineGetterSetter(_p, "a", _p._getA, _p._setA);
+ }
+});
+
+_p = cc.color;
+/**
+ * White color (255, 255, 255, 255)
+ * @returns {cc.Color}
+ * @private
+ */
+_p._getWhite = function () {
+ return cc.color(255, 255, 255);
+};
+
+/**
+ * Yellow color (255, 255, 0, 255)
+ * @returns {cc.Color}
+ * @private
+ */
+_p._getYellow = function () {
+ return cc.color(255, 255, 0);
+};
+
+/**
+ * Blue color (0, 0, 255, 255)
+ * @type {cc.Color}
+ * @private
+ */
+_p._getBlue = function () {
+ return cc.color(0, 0, 255);
+};
+
+/**
+ * Green Color (0, 255, 0, 255)
+ * @type {cc.Color}
+ * @private
+ */
+_p._getGreen = function () {
+ return cc.color(0, 255, 0);
+};
+
+/**
+ * Red Color (255, 0, 0, 255)
+ * @type {cc.Color}
+ * @private
+ */
+_p._getRed = function () {
+ return cc.color(255, 0, 0);
+};
+
+/**
+ * Magenta Color (255, 0, 255, 255)
+ * @type {cc.Color}
+ * @private
+ */
+_p._getMagenta = function () {
+ return cc.color(255, 0, 255);
+};
+
+/**
+ * Black Color (0, 0, 0, 255)
+ * @type {cc.Color}
+ * @private
+ */
+_p._getBlack = function () {
+ return cc.color(0, 0, 0);
+};
+
+/**
+ * Orange Color (255, 127, 0, 255)
+ * @type {_p}
+ * @private
+ */
+_p._getOrange = function () {
+ return cc.color(255, 127, 0);
+};
+
+/**
+ * Gray Color (166, 166, 166, 255)
+ * @type {_p}
+ * @private
+ */
+_p._getGray = function () {
+ return cc.color(166, 166, 166);
+};
+
+/** @expose */
+_p.WHITE;
+cc.defineGetterSetter(_p, "WHITE", _p._getWhite);
+/** @expose */
+_p.YELLOW;
+cc.defineGetterSetter(_p, "YELLOW", _p._getYellow);
+/** @expose */
+_p.BLUE;
+cc.defineGetterSetter(_p, "BLUE", _p._getBlue);
+/** @expose */
+_p.GREEN;
+cc.defineGetterSetter(_p, "GREEN", _p._getGreen);
+/** @expose */
+_p.RED;
+cc.defineGetterSetter(_p, "RED", _p._getRed);
+/** @expose */
+_p.MAGENTA;
+cc.defineGetterSetter(_p, "MAGENTA", _p._getMagenta);
+/** @expose */
+_p.BLACK;
+cc.defineGetterSetter(_p, "BLACK", _p._getBlack);
+/** @expose */
+_p.ORANGE;
+cc.defineGetterSetter(_p, "ORANGE", _p._getOrange);
+/** @expose */
+_p.GRAY;
+cc.defineGetterSetter(_p, "GRAY", _p._getGray);
+
+cc.BlendFunc._disable = function(){
+ return new cc.BlendFunc(cc.ONE, cc.ZERO);
+};
+cc.BlendFunc._alphaPremultiplied = function(){
+ return new cc.BlendFunc(cc.ONE, cc.ONE_MINUS_SRC_ALPHA);
+};
+cc.BlendFunc._alphaNonPremultiplied = function(){
+ return new cc.BlendFunc(cc.SRC_ALPHA, cc.ONE_MINUS_SRC_ALPHA);
+};
+cc.BlendFunc._additive = function(){
+ return new cc.BlendFunc(cc.SRC_ALPHA, cc.ONE);
+};
+
+/** @expose */
+cc.BlendFunc.DISABLE;
+cc.defineGetterSetter(cc.BlendFunc, "DISABLE", cc.BlendFunc._disable);
+/** @expose */
+cc.BlendFunc.ALPHA_PREMULTIPLIED;
+cc.defineGetterSetter(cc.BlendFunc, "ALPHA_PREMULTIPLIED", cc.BlendFunc._alphaPremultiplied);
+/** @expose */
+cc.BlendFunc.ALPHA_NON_PREMULTIPLIED;
+cc.defineGetterSetter(cc.BlendFunc, "ALPHA_NON_PREMULTIPLIED", cc.BlendFunc._alphaNonPremultiplied);
+/** @expose */
+cc.BlendFunc.ADDITIVE;
+cc.defineGetterSetter(cc.BlendFunc, "ADDITIVE", cc.BlendFunc._additive);
diff --git a/frameworks/cocos2d-html5/cocos2d/core/platform/CCVisibleRect.js b/frameworks/cocos2d-html5/cocos2d/core/platform/CCVisibleRect.js
new file mode 100644
index 0000000..c6545e9
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/platform/CCVisibleRect.js
@@ -0,0 +1,100 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.visibleRect is a singleton object which defines the actual visible rect of the current view,
+ * it should represent the same rect as cc.view.getViewportRect()
+ *
+ * @property {cc.Point} topLeft - Top left coordinate of the screen related to the game scene
+ * @property {cc.Point} topRight - Top right coordinate of the screen related to the game scene
+ * @property {cc.Point} top - Top center coordinate of the screen related to the game scene
+ * @property {cc.Point} bottomLeft - Bottom left coordinate of the screen related to the game scene
+ * @property {cc.Point} bottomRight - Bottom right coordinate of the screen related to the game scene
+ * @property {cc.Point} bottom - Bottom center coordinate of the screen related to the game scene
+ * @property {cc.Point} center - Center coordinate of the screen related to the game scene
+ * @property {cc.Point} left - Left center coordinate of the screen related to the game scene
+ * @property {cc.Point} right - Right center coordinate of the screen related to the game scene
+ * @property {Number} width - Width of the screen
+ * @property {Number} height - Height of the screen
+ *
+ * @class
+ * @name cc.visibleRect
+ */
+cc.visibleRect = {
+ topLeft:cc.p(0,0),
+ topRight:cc.p(0,0),
+ top:cc.p(0,0),
+ bottomLeft:cc.p(0,0),
+ bottomRight:cc.p(0,0),
+ bottom:cc.p(0,0),
+ center:cc.p(0,0),
+ left:cc.p(0,0),
+ right:cc.p(0,0),
+ width:0,
+ height:0,
+
+ /**
+ * initialize
+ * @param {cc.Rect} visibleRect
+ */
+ init:function(visibleRect){
+
+ var w = this.width = visibleRect.width;
+ var h = this.height = visibleRect.height;
+ var l = visibleRect.x,
+ b = visibleRect.y,
+ t = b + h,
+ r = l + w;
+
+ //top
+ this.topLeft.x = l;
+ this.topLeft.y = t;
+ this.topRight.x = r;
+ this.topRight.y = t;
+ this.top.x = l + w/2;
+ this.top.y = t;
+
+ //bottom
+ this.bottomLeft.x = l;
+ this.bottomLeft.y = b;
+ this.bottomRight.x = r;
+ this.bottomRight.y = b;
+ this.bottom.x = l + w/2;
+ this.bottom.y = b;
+
+ //center
+ this.center.x = l + w/2;
+ this.center.y = b + h/2;
+
+ //left
+ this.left.x = l;
+ this.left.y = b + h/2;
+
+ //right
+ this.right.x = r;
+ this.right.y = b + h/2;
+ }
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/platform/miniFramework.js b/frameworks/cocos2d-html5/cocos2d/core/platform/miniFramework.js
new file mode 100644
index 0000000..048a2db
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/platform/miniFramework.js
@@ -0,0 +1,264 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * the dollar sign, classic like jquery, this selector add extra methods to HTMLElement without touching its prototype
+ * it is also chainable like jquery
+ * @param {HTMLElement|String} x pass in a css selector in string or the whole HTMLElement
+ * @function
+ * @return {cc.$}
+ */
+cc.$ = function (x) {
+ /** @lends cc.$# */
+ var parent = (this === cc) ? document : this;
+
+ var el = (x instanceof HTMLElement) ? x : parent.querySelector(x);
+
+ if (el) {
+ /**
+ * find and return the child wth css selector (same as jquery.find)
+ * @lends cc.$#
+ * @function
+ * @param {HTMLElement|String} x pass in a css selector in string or the whole HTMLElement
+ * @return {cc.$}
+ */
+ el.find = el.find || cc.$;
+ /**
+ * check if a DOMNode has a specific class
+ * @lends cc.$#
+ * @function
+ * @param {String} cls
+ * @return {Boolean}
+ */
+ el.hasClass = el.hasClass || function (cls) {
+ return this.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
+ };
+ /**
+ * add a class to a DOMNode, returns self to allow chaining
+ * @lends cc.$#
+ * @function
+ * @param {String} cls
+ * @return {cc.$}
+ */
+ el.addClass = el.addClass || function (cls) {
+ if (!this.hasClass(cls)) {
+ if (this.className) {
+ this.className += " ";
+ }
+ this.className += cls;
+ }
+ return this;
+ };
+ /**
+ * remove a specific class from a DOMNode, returns self to allow chaining
+ * @lends cc.$#
+ * @function
+ * @param {String} cls
+ * @return {cc.$}
+ */
+ el.removeClass = el.removeClass || function (cls) {
+ if (this.hasClass(cls)) {
+ this.className = this.className.replace(cls, '');
+ }
+ return this;
+ };
+ /**
+ * detach it self from parent
+ * @lends cc.$#
+ * @function
+ */
+ el.remove = el.remove || function () {
+ if (this.parentNode)
+ this.parentNode.removeChild(this);
+ return this;
+ };
+
+ /**
+ * add to another element as a child
+ * @lends cc.$#
+ * @function
+ * @param {HTMLElement|cc.$} x
+ * @return {cc.$}
+ */
+ el.appendTo = el.appendTo || function (x) {
+ x.appendChild(this);
+ return this;
+ };
+
+ /**
+ * add to another element as a child and place on the top of the children list
+ * @lends cc.$#
+ * @function
+ * @param {HTMLElement|cc.$} x
+ * @return {cc.$}
+ */
+ el.prependTo = el.prependTo || function (x) {
+ ( x.childNodes[0]) ? x.insertBefore(this, x.childNodes[0]) : x.appendChild(this);
+ return this;
+ };
+
+ /**
+ * helper function for updating the css transform
+ * @lends cc.$#
+ * @function
+ * @return {cc.$}
+ */
+ el.transforms = el.transforms || function () {
+ this.style[cc.$.trans] = cc.$.translate(this.position) + cc.$.rotate(this.rotation) + cc.$.scale(this.scale) + cc.$.skew(this.skew);
+ return this;
+ };
+
+ el.position = el.position || {x: 0, y: 0};
+ el.rotation = el.rotation || 0;
+ el.scale = el.scale || {x: 1, y: 1};
+ el.skew = el.skew || {x: 0, y: 0};
+
+ /**
+ * move the element
+ * @memberOf cc.$#
+ * @name translates
+ * @function
+ * @param {Number} x in pixel
+ * @param {Number} y in pixel
+ * @return {cc.$}
+ */
+ el.translates = function (x, y) {
+ this.position.x = x;
+ this.position.y = y;
+ this.transforms();
+ return this
+ };
+
+ /**
+ * rotate the element
+ * @memberOf cc.$#
+ * @name rotate
+ * @function
+ * @param {Number} x in degrees
+ * @return {cc.$}
+ */
+ el.rotate = function (x) {
+ this.rotation = x;
+ this.transforms();
+ return this
+ };
+
+ /**
+ * resize the element
+ * @memberOf cc.$#
+ * @name resize
+ * @function
+ * @param {Number} x
+ * @param {Number} y
+ * @return {cc.$}
+ */
+ el.resize = function (x, y) {
+ this.scale.x = x;
+ this.scale.y = y;
+ this.transforms();
+ return this
+ };
+
+ /**
+ * skews the element
+ * @memberOf cc.$#
+ * @name setSkew
+ * @function
+ * @param {Number} x in degrees
+ * @param {Number} y
+ * @return {cc.$}
+ */
+ el.setSkew = function (x, y) {
+ this.skew.x = x;
+ this.skew.y = y;
+ this.transforms();
+ return this
+ };
+ }
+ return el;
+};
+//getting the prefix and css3 3d support
+switch (cc.sys.browserType) {
+ case cc.sys.BROWSER_TYPE_FIREFOX:
+ cc.$.pfx = "Moz";
+ cc.$.hd = true;
+ break;
+ case cc.sys.BROWSER_TYPE_CHROME:
+ case cc.sys.BROWSER_TYPE_SAFARI:
+ cc.$.pfx = "webkit";
+ cc.$.hd = true;
+ break;
+ case cc.sys.BROWSER_TYPE_OPERA:
+ cc.$.pfx = "O";
+ cc.$.hd = false;
+ break;
+ case cc.sys.BROWSER_TYPE_IE:
+ cc.$.pfx = "ms";
+ cc.$.hd = false;
+ break;
+ default:
+ cc.$.pfx = "webkit";
+ cc.$.hd = true;
+}
+//cache for prefixed transform
+cc.$.trans = cc.$.pfx + "Transform";
+//helper function for constructing transform strings
+cc.$.translate = (cc.$.hd) ? function (a) {
+ return "translate3d(" + a.x + "px, " + a.y + "px, 0) "
+} : function (a) {
+ return "translate(" + a.x + "px, " + a.y + "px) "
+};
+cc.$.rotate = (cc.$.hd) ? function (a) {
+ return "rotateZ(" + a + "deg) ";
+} : function (a) {
+ return "rotate(" + a + "deg) ";
+};
+cc.$.scale = function (a) {
+ return "scale(" + a.x + ", " + a.y + ") "
+};
+cc.$.skew = function (a) {
+ return "skewX(" + -a.x + "deg) skewY(" + a.y + "deg)";
+};
+
+
+/**
+ * Creates a new element, and adds cc.$ methods
+ * @param {String} x name of the element tag to create
+ * @return {cc.$}
+ */
+cc.$new = function (x) {
+ return cc.$(document.createElement(x))
+};
+cc.$.findpos = function (obj) {
+ var curleft = 0;
+ var curtop = 0;
+ do {
+ curleft += obj.offsetLeft;
+ curtop += obj.offsetTop;
+ } while (obj = obj.offsetParent);
+ return {x: curleft, y: curtop};
+};
+
diff --git a/frameworks/cocos2d-html5/cocos2d/core/renderer/DirtyRegion.js b/frameworks/cocos2d-html5/cocos2d/core/renderer/DirtyRegion.js
new file mode 100644
index 0000000..161d1d1
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/renderer/DirtyRegion.js
@@ -0,0 +1,337 @@
+//Region is used to label a rect which world axis aligned.
+var Region = function () {
+ this._minX = 0;
+ this._minY = 0;
+ this._maxX = 0;
+ this._maxY = 0;
+
+ this._width = 0;
+ this._height = 0;
+ this._area = 0;
+ //this.moved = false;
+};
+
+var regionProto = Region.prototype;
+
+var regionPool = [];
+
+function regionCreate() {
+ var region = regionPool.pop();
+ if (!region) {
+ region = new Region();
+ }
+ return region;
+}
+
+function regionRelease(region) {
+ regionPool.push(region);
+}
+
+regionProto.setTo = function (minX, minY, maxX, maxY) {
+ this._minX = minX;
+ this._minY = minY;
+ this._maxX = maxX;
+ this._maxY = maxY;
+ this.updateArea();
+ return this;
+};
+
+//convert region to int values which is fast for clipping
+regionProto.intValues = function () {
+ this._minX = Math.floor(this._minX);
+ this._minY = Math.floor(this._minY);
+ this._maxX = Math.ceil(this._maxX);
+ this._maxY = Math.ceil(this._maxY);
+ this.updateArea();
+};
+
+//update the area of region
+regionProto.updateArea = function () {
+ this._width = this._maxX - this._minX;
+ this._height = this._maxY - this._minY;
+ this._area = this._width * this._height;
+};
+
+//merge two region into one
+regionProto.union = function (target) {
+ if(this._width <= 0 || this._height <= 0) {
+ this.setTo(target._minX, target._minY, target._maxX, target._maxY);
+ return;
+ }
+ if (this._minX > target._minX) {
+ this._minX = target._minX;
+ }
+ if (this._minY > target._minY) {
+ this._minY = target._minY;
+ }
+ if (this._maxX < target._maxX) {
+ this._maxX = target._maxX;
+ }
+ if (this._maxY < target._maxY) {
+ this._maxY = target._maxY;
+ }
+ this.updateArea();
+};
+
+//regionProto.intersect = function (target) {
+// if (this._minX < target._minX) {
+// this._minX = target._minX;
+// }
+// if (this._maxX > target._maxX) {
+// this._maxX = target._maxX;
+// }
+// if (this._minX >= this._maxX) {
+// this.setEmpty();
+// return;
+// }
+// if (this._minY < target._minY) {
+// this._minY = target._minY;
+// }
+//
+// if (this._maxY > target._maxY) {
+// this._maxY = target._maxY;
+// }
+// if (this._minY >= this._maxY) {
+// this.setEmpty();
+// return;
+// }
+// this.updateArea();
+//};
+
+//set region to empty
+regionProto.setEmpty = function () {
+ this._minX = 0;
+ this._minY = 0;
+ this._maxX = 0;
+ this._maxY = 0;
+ this._width = 0;
+ this._height = 0;
+ this._area = 0;
+};
+
+regionProto.isEmpty = function () {
+ return this._width <= 0 || this._height <= 0;
+};
+
+//check whether two region is intersects or not
+regionProto.intersects = function (target) {
+ if (this._width <= 0 || this._height <= 0 || target._width <= 0 || target._height <= 0) {
+ return false;
+ }
+ var max = this._minX > target._minX ? this._minX : target._minX;
+ var min = this._maxX < target._maxX ? this._maxX : target._maxX;
+ if (max > min) {
+ return false;
+ }
+
+ max = this._minY > target._minY ? this._minY : target._minY;
+ min = this._maxY < target._maxY ? this._maxY : target._maxY;
+ return max <= min;
+};
+
+//update region by a rotated bounds
+regionProto.updateRegion = function (bounds, matrix) {
+ if (bounds.width == 0 || bounds.height == 0) {
+ this.setEmpty();
+ return;
+ }
+ var m = matrix;
+ var a = m.a;
+ var b = m.b;
+ var c = m.c;
+ var d = m.d;
+ var tx = m.tx;
+ var ty = m.ty;
+ var x = bounds.x;
+ var y = bounds.y;
+ var xMax = x + bounds.width;
+ var yMax = y + bounds.height;
+ var minX, minY, maxX, maxY;
+ if (a == 1.0 && b == 0.0 && c == 0.0 && d == 1.0) {
+ minX = x + tx - 1;
+ minY = y + ty - 1;
+ maxX = xMax + tx + 1;
+ maxY = yMax + ty + 1;
+ }
+ else {
+ var x0 = a * x + c * y + tx;
+ var y0 = b * x + d * y + ty;
+ var x1 = a * xMax + c * y + tx;
+ var y1 = b * xMax + d * y + ty;
+ var x2 = a * xMax + c * yMax + tx;
+ var y2 = b * xMax + d * yMax + ty;
+ var x3 = a * x + c * yMax + tx;
+ var y3 = b * x + d * yMax + ty;
+
+ var tmp = 0;
+
+ if (x0 > x1) {
+ tmp = x0;
+ x0 = x1;
+ x1 = tmp;
+ }
+ if (x2 > x3) {
+ tmp = x2;
+ x2 = x3;
+ x3 = tmp;
+ }
+
+ minX = (x0 < x2 ? x0 : x2) - 1;
+ maxX = (x1 > x3 ? x1 : x3) + 1;
+
+ if (y0 > y1) {
+ tmp = y0;
+ y0 = y1;
+ y1 = tmp;
+ }
+ if (y2 > y3) {
+ tmp = y2;
+ y2 = y3;
+ y3 = tmp;
+ }
+
+ minY = (y0 < y2 ? y0 : y2) - 1;
+ maxY = (y1 > y3 ? y1 : y3) + 1;
+ }
+ this._minX = minX;
+ this._minY = minY;
+ this._maxX = maxX;
+ this._maxY = maxY;
+ this._width = maxX - minX;
+ this._height = maxY - minY;
+ this._area = this._width * this._height;
+};
+
+//get the area of the unioned region of r1 and r2
+function unionArea(r1, r2) {
+ var minX = r1._minX < r2._minX ? r1._minX : r2._minX;
+ var minY = r1._minY < r2._minY ? r1._minY : r2._minY;
+ var maxX = r1._maxX > r2._maxX ? r1._maxX : r2._maxX;
+ var maxY = r1._maxY > r2._maxY ? r1._maxY : r2._maxY;
+ return (maxX - minX) * (maxY - minY);
+}
+
+//DirtyRegion is used to collect the dirty area which need to be rerendered in canvas
+//there may be many small regions which is dirty, the dirty region will merge it into several big one to optimise performance
+var DirtyRegion = function() {
+ this.dirtyList = [];
+ this.hasClipRect = false;
+ this.clipWidth = 0;
+ this.clipHeight = 0;
+ this.clipArea = 0;
+ this.clipRectChanged = false;
+};
+var dirtyRegionProto = DirtyRegion.prototype;
+
+//clip rect, regions will not be considered if it is outside
+dirtyRegionProto.setClipRect = function(width, height) {
+ this.hasClipRect = true;
+ this.clipRectChanged = true;
+ this.clipWidth = Math.ceil(width);
+ this.clipHeight = Math.ceil(height);
+ this.clipArea = this.clipWidth * this.clipHeight;
+};
+
+//add a new region which is dirty (need to be rendered)
+dirtyRegionProto.addRegion = function(target) {
+ var minX = target._minX, minY = target._minY, maxX = target._maxX, maxY = target._maxY;
+
+ if (this.hasClipRect) {
+ if (minX < 0) {
+ minX = 0;
+ }
+ if (minY < 0) {
+ minY = 0;
+ }
+ if (maxX > this.clipWidth) {
+ maxX = this.clipWidth;
+ }
+ if (maxY > this.clipHeight) {
+ maxY = this.clipHeight;
+ }
+ }
+ if (minX >= maxX || minY >= maxY) {
+ return false;
+ }
+ if (this.clipRectChanged) {
+ return true;
+ }
+ var dirtyList = this.dirtyList;
+ var region = regionCreate();
+ dirtyList.push(region.setTo(minX, minY, maxX, maxY));
+ this.mergeDirtyList(dirtyList);
+ return true;
+};
+
+//clear all the dirty regions
+dirtyRegionProto.clear = function() {
+ var dirtyList = this.dirtyList;
+ var length = dirtyList.length;
+ for (var i = 0; i < length; i++) {
+ regionRelease(dirtyList[i]);
+ }
+ dirtyList.length = 0;
+};
+
+//get the merged dirty regions
+dirtyRegionProto.getDirtyRegions = function() {
+ var dirtyList = this.dirtyList;
+ if (this.clipRectChanged) {
+ this.clipRectChanged = false;
+ this.clear();
+ var region = regionCreate();
+ dirtyList.push(region.setTo(0, 0, this.clipWidth, this.clipHeight));
+ }
+ else {
+ while (this.mergeDirtyList(dirtyList)) {
+ }
+ }
+ var numDirty = this.dirtyList.length;
+ if (numDirty > 0) {
+ for (var i = 0; i < numDirty; i++) {
+ this.dirtyList[i].intValues();
+ }
+ }
+ return this.dirtyList;
+};
+
+//merge the small dirty regions into bigger region, to improve the performance of dirty regions
+dirtyRegionProto.mergeDirtyList = function(dirtyList) {
+ var length = dirtyList.length;
+ if (length < 2) {
+ return false;
+ }
+ var hasClipRect = this.hasClipRect;
+ var bestDelta = length > 3 ? Number.POSITIVE_INFINITY : 0;
+ var mergeA = 0;
+ var mergeB = 0;
+ var totalArea = 0;
+ for (var i = 0; i < length - 1; i++) {
+ var regionA = dirtyList[i];
+ hasClipRect && (totalArea += regionA.area);
+ for (var j = i + 1; j < length; j++) {
+ var regionB = dirtyList[j];
+ var delta = unionArea(regionA, regionB) - regionA.area - regionB.area;
+ if (bestDelta > delta) {
+ mergeA = i;
+ mergeB = j;
+ bestDelta = delta;
+ }
+ }
+ }
+ //if the area of dirty region exceed 95% of the screen, skip the following dirty regions merge
+ if (hasClipRect && (totalArea / this.clipArea) > 0.95) {
+ this.clipRectChanged = true;
+ }
+ if (mergeA != mergeB) {
+ var region = dirtyList[mergeB];
+ dirtyList[mergeA].union(region);
+ regionRelease(region);
+ dirtyList.splice(mergeB, 1);
+ return true;
+ }
+ return false;
+};
+
+cc.Region = Region;
+cc.DirtyRegion = DirtyRegion;
diff --git a/frameworks/cocos2d-html5/cocos2d/core/renderer/GlobalVertexBuffer.js b/frameworks/cocos2d-html5/cocos2d/core/renderer/GlobalVertexBuffer.js
new file mode 100644
index 0000000..e81c95a
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/renderer/GlobalVertexBuffer.js
@@ -0,0 +1,139 @@
+/****************************************************************************
+ Copyright (c) 2016 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+var GlobalVertexBuffer = (function () {
+
+var VERTICES_SIZE = 888;
+
+var GlobalVertexBuffer = function (gl, byteLength) {
+ // WebGL buffer
+ this.gl = gl;
+ this.vertexBuffer = gl.createBuffer();
+
+ this.size = VERTICES_SIZE;
+ this.byteLength = byteLength || VERTICES_SIZE * 4 * cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT;
+
+ // buffer data and views
+ this.data = new ArrayBuffer(this.byteLength);
+ this.dataArray = new Float32Array(this.data);
+
+ // Init buffer data
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this.dataArray, gl.DYNAMIC_DRAW);
+
+ this._dirty = false;
+ this._spaces = {
+ 0: this.byteLength
+ };
+};
+GlobalVertexBuffer.prototype = {
+ constructor: GlobalVertexBuffer,
+
+ allocBuffer: function (offset, size) {
+ var space = this._spaces[offset];
+ if (space && space >= size) {
+ // Remove the space
+ delete this._spaces[offset];
+ if (space > size) {
+ var newOffset = offset + size;
+ this._spaces[newOffset] = space - size;
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+ },
+
+ requestBuffer: function (size) {
+ var key, offset, available;
+ for (key in this._spaces) {
+ offset = parseInt(key);
+ available = this._spaces[key];
+ if (available >= size && this.allocBuffer(offset, size)) {
+ return offset;
+ }
+ }
+ return -1;
+ },
+
+ freeBuffer: function (offset, size) {
+ var spaces = this._spaces;
+ var i, key, end;
+ // Merge with previous space
+ for (key in spaces) {
+ i = parseInt(key);
+ if (i > offset) {
+ break;
+ }
+ if (i + spaces[key] >= offset) {
+ size = size + offset - i;
+ offset = i;
+ break;
+ }
+ }
+
+ end = offset + size;
+ // Merge with next space
+ if (this._spaces[end]) {
+ size += this._spaces[end];
+ delete this._spaces[end];
+ }
+
+ this._spaces[offset] = size;
+ },
+
+ setDirty: function () {
+ this._dirty = true;
+ },
+
+ update: function () {
+ if (this._dirty) {
+ this.gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ // Note: Can memorize different dirty zones and update them separately, maybe faster
+ this.gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.dataArray);
+ this._dirty = false;
+ }
+ },
+
+ updateSubData: function (offset, dataArray) {
+ this.gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ this.gl.bufferSubData(gl.ARRAY_BUFFER, offset, dataArray);
+ },
+
+ destroy: function () {
+ this.gl.deleteBuffer(this.vertexBuffer);
+
+ this.data = null;
+ this.positions = null;
+ this.colors = null;
+ this.texCoords = null;
+
+ this.vertexBuffer = null;
+ }
+};
+
+return GlobalVertexBuffer;
+
+})();
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/renderer/RendererCanvas.js b/frameworks/cocos2d-html5/cocos2d/core/renderer/RendererCanvas.js
new file mode 100644
index 0000000..57e569c
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/renderer/RendererCanvas.js
@@ -0,0 +1,438 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.rendererCanvas = {
+ childrenOrderDirty: true,
+ assignedZ: 0,
+ assignedZStep: 1 / 10000,
+
+ _transformNodePool: [], //save nodes transform dirty
+ _renderCmds: [], //save renderer commands
+
+ _isCacheToCanvasOn: false, //a switch that whether cache the rendererCmd to cacheToCanvasCmds
+ _cacheToCanvasCmds: {}, // an array saves the renderer commands need for cache to other canvas
+ _cacheInstanceIds: [],
+ _currentID: 0,
+ _clearColor: cc.color(), //background color,default BLACK
+ _clearFillStyle: "rgb(0, 0, 0)",
+
+ _dirtyRegion: null,
+ _allNeedDraw: true,
+ _enableDirtyRegion: false,
+ _debugDirtyRegion: false,
+ _canUseDirtyRegion: false,
+ //max dirty Region count, default is 10
+ _dirtyRegionCountThreshold: 10,
+
+ getRenderCmd: function (renderableObject) {
+ //TODO Add renderCmd pool here
+ return renderableObject._createRenderCmd();
+ },
+
+ enableDirtyRegion: function (enabled) {
+ this._enableDirtyRegion = enabled;
+ },
+
+ isDirtyRegionEnabled: function () {
+ return this._enableDirtyRegion;
+ },
+
+ setDirtyRegionCountThreshold: function(threshold) {
+ this._dirtyRegionCountThreshold = threshold;
+ },
+
+ _collectDirtyRegion: function () {
+ //collect dirtyList
+ var locCmds = this._renderCmds, i, len;
+ var dirtyRegion = this._dirtyRegion;
+ var dirtryRegionCount = 0;
+ var result = true;
+ var localStatus = cc.Node.CanvasRenderCmd.RegionStatus;
+ for (i = 0, len = locCmds.length; i < len; i++) {
+ var cmd = locCmds[i];
+ var regionFlag = cmd._regionFlag;
+ var oldRegion = cmd._oldRegion;
+ var currentRegion = cmd._currentRegion;
+ if (regionFlag > localStatus.NotDirty) {
+ ++dirtryRegionCount;
+ if(dirtryRegionCount > this._dirtyRegionCountThreshold)
+ result = false;
+ //add
+ if(result) {
+ (!currentRegion.isEmpty()) && dirtyRegion.addRegion(currentRegion);
+ if (cmd._regionFlag > localStatus.Dirty) {
+ (!oldRegion.isEmpty()) && dirtyRegion.addRegion(oldRegion);
+ }
+ }
+ cmd._regionFlag = localStatus.NotDirty;
+ }
+
+ }
+
+ return result;
+ },
+
+ _beginDrawDirtyRegion: function (ctxWrapper) {
+ var ctx = ctxWrapper.getContext();
+ var dirtyList = this._dirtyRegion.getDirtyRegions();
+ ctx.save();
+ //add clip
+ var scaleX = ctxWrapper._scaleX;
+ var scaleY = ctxWrapper._scaleY;
+ ctxWrapper.setTransform({a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0}, scaleX, scaleY);
+ ctx.beginPath();
+ for (var index = 0, count = dirtyList.length; index < count; ++index) {
+ var region = dirtyList[index];
+ ctx.rect(region._minX , -region._maxY , region._width , region._height );
+ }
+ ctx.clip();
+ //end add clip
+ },
+
+ _endDrawDirtyRegion: function (ctx) {
+ ctx.restore();
+ },
+
+ _debugDrawDirtyRegion: function (ctxWrapper) {
+ if (!this._debugDirtyRegion) return;
+ var ctx = ctxWrapper.getContext();
+ var dirtyList = this._dirtyRegion.getDirtyRegions();
+ //add clip
+ var scaleX = ctxWrapper._scaleX;
+ var scaleY = ctxWrapper._scaleY;
+ ctxWrapper.setTransform({a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0}, scaleX, scaleY);
+ ctx.beginPath();
+ for (var index = 0, count = dirtyList.length; index < count; ++index) {
+ var region = dirtyList[index];
+ ctx.rect(region._minX, -region._maxY , region._width , region._height );
+ }
+ var oldstyle = ctx.fillStyle;
+ ctx.fillStyle = 'green';
+ ctx.fill();
+ ctx.fillStyle = oldstyle;
+ //end add clip
+ },
+ /**
+ * drawing all renderer command to context (default is cc._renderContext)
+ * @param {cc.CanvasContextWrapper} [ctx=cc._renderContext]
+ */
+ rendering: function (ctxWrapper) {
+ var dirtyRegion = this._dirtyRegion = this._dirtyRegion || new cc.DirtyRegion();
+ var viewport = cc._canvas;
+ var wrapper = ctxWrapper || cc._renderContext;
+ var ctx = wrapper.getContext();
+
+ var scaleX = cc.view.getScaleX(),
+ scaleY = cc.view.getScaleY();
+ wrapper.setViewScale(scaleX, scaleY);
+ wrapper.computeRealOffsetY();
+ var dirtyList = this._dirtyRegion.getDirtyRegions();
+ var locCmds = this._renderCmds, i, len;
+ var allNeedDraw = this._allNeedDraw || !this._enableDirtyRegion || !this._canUseDirtyRegion;
+ var collectResult = true;
+ if (!allNeedDraw) {
+ collectResult = this._collectDirtyRegion();
+ }
+
+ allNeedDraw = allNeedDraw || (!collectResult);
+
+ if(!allNeedDraw) {
+ this._beginDrawDirtyRegion(wrapper);
+ }
+
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
+ ctx.clearRect(0, 0, viewport.width, viewport.height);
+ if (this._clearColor.r !== 255 ||
+ this._clearColor.g !== 255 ||
+ this._clearColor.b !== 255) {
+ wrapper.setFillStyle(this._clearFillStyle);
+ wrapper.setGlobalAlpha(this._clearColor.a);
+ ctx.fillRect(0, 0, viewport.width, viewport.height);
+ }
+
+ for (i = 0, len = locCmds.length; i < len; i++) {
+ var cmd = locCmds[i];
+ var needRendering = false;
+ var cmdRegion = cmd._currentRegion;
+ if (!cmdRegion || allNeedDraw) {
+ needRendering = true;
+ } else {
+ for (var index = 0, count = dirtyList.length; index < count; ++index) {
+ if (dirtyList[index].intersects(cmdRegion)) {
+ needRendering = true;
+ break;
+ }
+ }
+ }
+ if (needRendering) {
+ cmd.rendering(wrapper, scaleX, scaleY);
+ }
+ }
+
+ if (!allNeedDraw) {
+ //draw debug info for dirty region if it is needed
+ this._debugDrawDirtyRegion(wrapper);
+ this._endDrawDirtyRegion(ctx);
+ }
+
+ dirtyRegion.clear();
+ this._allNeedDraw = false;
+ },
+
+ /**
+ * drawing all renderer command to cache canvas' context
+ * @param {cc.CanvasContextWrapper} ctx
+ * @param {Number} [instanceID]
+ * @param {Number} [scaleX]
+ * @param {Number} [scaleY]
+ */
+ _renderingToCacheCanvas: function (ctx, instanceID, scaleX, scaleY) {
+ if (!ctx)
+ cc.log("The context of RenderTexture is invalid.");
+ scaleX = cc.isUndefined(scaleX) ? 1 : scaleX;
+ scaleY = cc.isUndefined(scaleY) ? 1 : scaleY;
+ instanceID = instanceID || this._currentID;
+ var i, locCmds = this._cacheToCanvasCmds[instanceID], len;
+ ctx.computeRealOffsetY();
+ for (i = 0, len = locCmds.length; i < len; i++) {
+ locCmds[i].rendering(ctx, scaleX, scaleY);
+ }
+ this._removeCache(instanceID);
+
+ var locIDs = this._cacheInstanceIds;
+ if (locIDs.length === 0)
+ this._isCacheToCanvasOn = false;
+ else
+ this._currentID = locIDs[locIDs.length - 1];
+ },
+
+ _turnToCacheMode: function (renderTextureID) {
+ this._isCacheToCanvasOn = true;
+ renderTextureID = renderTextureID || 0;
+ this._cacheToCanvasCmds[renderTextureID] = [];
+ if (this._cacheInstanceIds.indexOf(renderTextureID) === -1)
+ this._cacheInstanceIds.push(renderTextureID);
+ this._currentID = renderTextureID;
+ },
+
+ _turnToNormalMode: function () {
+ this._isCacheToCanvasOn = false;
+ },
+
+ _removeCache: function (instanceID) {
+ instanceID = instanceID || this._currentID;
+ var cmds = this._cacheToCanvasCmds[instanceID];
+ if (cmds) {
+ cmds.length = 0;
+ delete this._cacheToCanvasCmds[instanceID];
+ }
+
+ var locIDs = this._cacheInstanceIds;
+ cc.arrayRemoveObject(locIDs, instanceID);
+ },
+
+ resetFlag: function () {
+ this.childrenOrderDirty = false;
+ this._transformNodePool.length = 0;
+ },
+
+ transform: function () {
+ var locPool = this._transformNodePool;
+ //sort the pool
+ locPool.sort(this._sortNodeByLevelAsc);
+
+ //transform node
+ for (var i = 0, len = locPool.length; i < len; i++) {
+ if (locPool[i]._dirtyFlag !== 0)
+ locPool[i].updateStatus();
+ }
+ locPool.length = 0;
+ },
+
+ transformDirty: function () {
+ return this._transformNodePool.length > 0;
+ },
+
+ _sortNodeByLevelAsc: function (n1, n2) {
+ return n1._curLevel - n2._curLevel;
+ },
+
+ pushDirtyNode: function (node) {
+ this._transformNodePool.push(node);
+ },
+
+ clear: function () {
+ },
+
+ clearRenderCommands: function () {
+ this._renderCmds.length = 0;
+ this._cacheInstanceIds.length = 0;
+ this._isCacheToCanvasOn = false;
+ this._allNeedDraw = true;
+ this._canUseDirtyRegion = true;
+ },
+
+ pushRenderCommand: function (cmd) {
+ if (!cmd.needDraw())
+ return;
+ if (!cmd._canUseDirtyRegion) {
+ this._canUseDirtyRegion = false;
+ }
+ if (this._isCacheToCanvasOn) {
+ var currentId = this._currentID, locCmdBuffer = this._cacheToCanvasCmds;
+ var cmdList = locCmdBuffer[currentId];
+ if (cmdList.indexOf(cmd) === -1)
+ cmdList.push(cmd);
+ } else {
+ if (this._renderCmds.indexOf(cmd) === -1)
+ this._renderCmds.push(cmd);
+ }
+ }
+};
+
+(function () {
+ cc.CanvasContextWrapper = function (context) {
+ this._context = context;
+
+ this._saveCount = 0;
+ this._currentAlpha = context.globalAlpha;
+ this._currentCompositeOperation = context.globalCompositeOperation;
+ this._currentFillStyle = context.fillStyle;
+ this._currentStrokeStyle = context.strokeStyle;
+
+ this._offsetX = 0;
+ this._offsetY = 0;
+ this._realOffsetY = this.height;
+ this._armatureMode = 0;
+ };
+
+ var proto = cc.CanvasContextWrapper.prototype;
+
+ proto.resetCache = function () {
+ var context = this._context;
+ //call it after resize cc._canvas, because context will reset.
+ this._currentAlpha = context.globalAlpha;
+ this._currentCompositeOperation = context.globalCompositeOperation;
+ this._currentFillStyle = context.fillStyle;
+ this._currentStrokeStyle = context.strokeStyle;
+ this._realOffsetY = this._context.canvas.height + this._offsetY;
+ };
+
+ proto.setOffset = function (x, y) {
+ this._offsetX = x;
+ this._offsetY = y;
+ this._realOffsetY = this._context.canvas.height + this._offsetY;
+ };
+
+ proto.computeRealOffsetY = function () {
+ this._realOffsetY = this._context.canvas.height + this._offsetY;
+ };
+
+ proto.setViewScale = function (scaleX, scaleY) {
+ //call it at cc.renderCanvas.rendering
+ this._scaleX = scaleX;
+ this._scaleY = scaleY;
+ };
+
+ proto.getContext = function () {
+ return this._context;
+ };
+
+ proto.save = function () {
+ this._context.save();
+ this._saveCount++;
+ };
+
+ proto.restore = function () {
+ this._context.restore();
+ this._saveCount--;
+ };
+
+ proto.setGlobalAlpha = function (alpha) {
+ if (this._saveCount > 0) {
+ this._context.globalAlpha = alpha;
+ } else {
+ if (this._currentAlpha !== alpha) {
+ this._currentAlpha = alpha;
+ this._context.globalAlpha = alpha;
+ }
+ }
+ };
+
+ proto.setCompositeOperation = function (compositionOperation) {
+ if (this._saveCount > 0) {
+ this._context.globalCompositeOperation = compositionOperation;
+ } else {
+ if (this._currentCompositeOperation !== compositionOperation) {
+ this._currentCompositeOperation = compositionOperation;
+ this._context.globalCompositeOperation = compositionOperation;
+ }
+ }
+ };
+
+ proto.setFillStyle = function (fillStyle) {
+ if (this._saveCount > 0) {
+ this._context.fillStyle = fillStyle;
+ } else {
+ if (this._currentFillStyle !== fillStyle) {
+ this._currentFillStyle = fillStyle;
+ this._context.fillStyle = fillStyle;
+ }
+ }
+ };
+
+ proto.setStrokeStyle = function (strokeStyle) {
+ if (this._saveCount > 0) {
+ this._context.strokeStyle = strokeStyle;
+ } else {
+ if (this._currentStrokeStyle !== strokeStyle) {
+ this._currentStrokeStyle = strokeStyle;
+ this._context.strokeStyle = strokeStyle;
+ }
+ }
+ };
+
+ proto.setTransform = function (t, scaleX, scaleY) {
+ if (this._armatureMode > 0) {
+ //ugly for armature
+ this.restore();
+ this.save();
+ this._context.transform(t.a * scaleX, -t.b * scaleY, -t.c * scaleX, t.d * scaleY, t.tx * scaleX, -(t.ty * scaleY));
+ } else {
+ this._context.setTransform(t.a * scaleX, -t.b * scaleY, -t.c * scaleX, t.d * scaleY, this._offsetX + t.tx * scaleX, this._realOffsetY - (t.ty * scaleY));
+ }
+ };
+
+ proto._switchToArmatureMode = function (enable, t, scaleX, scaleY) {
+ if (enable) {
+ this._armatureMode++;
+ this._context.setTransform(t.a, t.c, t.b, t.d, this._offsetX + t.tx * scaleX, this._realOffsetY - (t.ty * scaleY));
+ this.save();
+ } else {
+ this._armatureMode--;
+ this.restore();
+ }
+ };
+})();
+
diff --git a/frameworks/cocos2d-html5/cocos2d/core/renderer/RendererWebGL.js b/frameworks/cocos2d-html5/cocos2d/core/renderer/RendererWebGL.js
new file mode 100644
index 0000000..d0655f6
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/renderer/RendererWebGL.js
@@ -0,0 +1,462 @@
+/****************************************************************************
+ Copyright (c) 2013-2016 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.rendererWebGL = (function () {
+
+// Internal variables
+ // Batching general informations
+var _batchedInfo = {
+ // The batched texture, all batching element should have the same texture
+ texture: null,
+ // The batched blend source, all batching element should have the same blend source
+ blendSrc: null,
+ // The batched blend destination, all batching element should have the same blend destination
+ blendDst: null,
+ // The batched gl program state, all batching element should have the same state
+ glProgramState: null
+ },
+
+ _batchBroken = false,
+ _indexBuffer = null,
+ _vertexBuffer = null,
+ // Total vertex size
+ _maxVertexSize = 0,
+ // Current batching vertex size
+ _batchingSize = 0,
+ // Current batching index size
+ _indexSize = 0,
+ // Float size per vertex
+ _sizePerVertex = 6,
+ // buffer data and views
+ _vertexData = null,
+ _vertexDataSize = 0,
+ _vertexDataF32 = null,
+ _vertexDataUI32 = null,
+ _indexData = null,
+ _prevIndexSize = 0,
+ _pureQuad = true,
+ _IS_IOS = false;
+
+
+// Inspired from @Heishe's gotta-batch-them-all branch
+// https://github.com/Talisca/cocos2d-html5/commit/de731f16414eb9bcaa20480006897ca6576d362c
+function updateBuffer (numVertex) {
+ var gl = cc._renderContext;
+ // Update index buffer size
+ if (_indexBuffer) {
+ var indexCount = Math.ceil(numVertex / 4) * 6;
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, _indexBuffer);
+ _indexData = new Uint16Array(indexCount);
+ var currentQuad = 0;
+ for (var i = 0, len = indexCount; i < len; i += 6) {
+ _indexData[i] = currentQuad + 0;
+ _indexData[i + 1] = currentQuad + 1;
+ _indexData[i + 2] = currentQuad + 2;
+ _indexData[i + 3] = currentQuad + 1;
+ _indexData[i + 4] = currentQuad + 2;
+ _indexData[i + 5] = currentQuad + 3;
+ currentQuad += 4;
+ }
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, _indexData, gl.DYNAMIC_DRAW);
+ }
+ // Update vertex buffer size
+ if (_vertexBuffer) {
+ _vertexDataSize = numVertex * _sizePerVertex;
+ var byteLength = _vertexDataSize * 4;
+ _vertexData = new ArrayBuffer(byteLength);
+ _vertexDataF32 = new Float32Array(_vertexData);
+ _vertexDataUI32 = new Uint32Array(_vertexData);
+ // Init buffer data
+ gl.bindBuffer(gl.ARRAY_BUFFER, _vertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, _vertexDataF32, gl.DYNAMIC_DRAW);
+ }
+ // Downsize by 200 to avoid vertex data overflow
+ _maxVertexSize = numVertex - 200;
+}
+
+// Inspired from @Heishe's gotta-batch-them-all branch
+// https://github.com/Talisca/cocos2d-html5/commit/de731f16414eb9bcaa20480006897ca6576d362c
+function initQuadBuffer (numVertex) {
+ var gl = cc._renderContext;
+ if (_indexBuffer === null) {
+ // TODO do user need to release the memory ?
+ _vertexBuffer = gl.createBuffer();
+ _indexBuffer = gl.createBuffer();
+ }
+ updateBuffer(numVertex);
+}
+
+var VertexType = {
+ QUAD : 0,
+ TRIANGLE : 1,
+ CUSTOM: 2
+};
+
+return {
+ mat4Identity: null,
+
+ childrenOrderDirty: true,
+ assignedZ: 0,
+ assignedZStep: 1 / 100,
+
+ VertexType: VertexType,
+
+ _transformNodePool: [], //save nodes transform dirty
+ _renderCmds: [], //save renderer commands
+
+ _isCacheToBufferOn: false, //a switch that whether cache the rendererCmd to cacheToCanvasCmds
+ _cacheToBufferCmds: {}, // an array saves the renderer commands need for cache to other canvas
+ _cacheInstanceIds: [],
+ _currentID: 0,
+ _clearColor: cc.color(0, 0, 0, 255), //background color,default BLACK
+
+ init: function () {
+ var gl = cc._renderContext;
+ gl.disable(gl.CULL_FACE);
+ gl.disable(gl.DEPTH_TEST);
+
+ this.mat4Identity = new cc.math.Matrix4();
+ this.mat4Identity.identity();
+ initQuadBuffer(cc.BATCH_VERTEX_COUNT);
+ if (cc.sys.os === cc.sys.OS_IOS) {
+ _IS_IOS = true;
+ }
+ },
+
+ getVertexSize: function () {
+ return _maxVertexSize;
+ },
+
+ getRenderCmd: function (renderableObject) {
+ //TODO Add renderCmd pool here
+ return renderableObject._createRenderCmd();
+ },
+
+ _turnToCacheMode: function (renderTextureID) {
+ this._isCacheToBufferOn = true;
+ renderTextureID = renderTextureID || 0;
+ if (!this._cacheToBufferCmds[renderTextureID]) {
+ this._cacheToBufferCmds[renderTextureID] = [];
+ }
+ else {
+ this._cacheToBufferCmds[renderTextureID].length = 0;
+ }
+ if (this._cacheInstanceIds.indexOf(renderTextureID) === -1) {
+ this._cacheInstanceIds.push(renderTextureID);
+ }
+ this._currentID = renderTextureID;
+ },
+
+ _turnToNormalMode: function () {
+ this._isCacheToBufferOn = false;
+ },
+
+ _removeCache: function (instanceID) {
+ instanceID = instanceID || this._currentID;
+ var cmds = this._cacheToBufferCmds[instanceID];
+ if (cmds) {
+ cmds.length = 0;
+ delete this._cacheToBufferCmds[instanceID];
+ }
+
+ var locIDs = this._cacheInstanceIds;
+ cc.arrayRemoveObject(locIDs, instanceID);
+ },
+
+ /**
+ * drawing all renderer command to cache canvas' context
+ * @param {Number} [renderTextureId]
+ */
+ _renderingToBuffer: function (renderTextureId) {
+ renderTextureId = renderTextureId || this._currentID;
+ var locCmds = this._cacheToBufferCmds[renderTextureId];
+ var ctx = cc._renderContext;
+ this.rendering(ctx, locCmds);
+ this._removeCache(renderTextureId);
+
+ var locIDs = this._cacheInstanceIds;
+ if (locIDs.length === 0)
+ this._isCacheToBufferOn = false;
+ else
+ this._currentID = locIDs[locIDs.length - 1];
+ },
+
+ //reset renderer's flag
+ resetFlag: function () {
+ if (this.childrenOrderDirty) {
+ this.childrenOrderDirty = false;
+ }
+ this._transformNodePool.length = 0;
+ },
+
+ //update the transform data
+ transform: function () {
+ var locPool = this._transformNodePool;
+ //sort the pool
+ locPool.sort(this._sortNodeByLevelAsc);
+ //transform node
+ var i, len, cmd;
+ for (i = 0, len = locPool.length; i < len; i++) {
+ cmd = locPool[i];
+ cmd.updateStatus();
+ }
+ locPool.length = 0;
+ },
+
+ transformDirty: function () {
+ return this._transformNodePool.length > 0;
+ },
+
+ _sortNodeByLevelAsc: function (n1, n2) {
+ return n1._curLevel - n2._curLevel;
+ },
+
+ pushDirtyNode: function (node) {
+ //if (this._transformNodePool.indexOf(node) === -1)
+ this._transformNodePool.push(node);
+ },
+
+ clearRenderCommands: function () {
+ // Copy previous command list for late check in rendering
+ this._renderCmds.length = 0;
+ },
+
+ clear: function () {
+ var gl = cc._renderContext;
+ gl.clearColor(this._clearColor.r / 255, this._clearColor.g / 255, this._clearColor.b / 255, this._clearColor.a / 255);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ },
+
+ setDepthTest: function (enable) {
+ var gl = cc._renderContext;
+ if (enable) {
+ gl.clearDepth(1.0);
+ gl.enable(gl.DEPTH_TEST);
+ gl.depthFunc(gl.LEQUAL);
+ }
+ else {
+ gl.disable(gl.DEPTH_TEST);
+ }
+ },
+
+ pushRenderCommand: function (cmd) {
+ if (!cmd.rendering && !cmd.uploadData)
+ return;
+ if (this._isCacheToBufferOn) {
+ var currentId = this._currentID, locCmdBuffer = this._cacheToBufferCmds;
+ var cmdList = locCmdBuffer[currentId];
+ if (cmdList.indexOf(cmd) === -1)
+ cmdList.push(cmd);
+ } else {
+ if (this._renderCmds.indexOf(cmd) === -1) {
+ this._renderCmds.push(cmd);
+ }
+ }
+ },
+
+ _increaseBatchingSize: function (increment, vertexType, indices) {
+ vertexType = vertexType || VertexType.QUAD;
+ var i, curr;
+ switch (vertexType) {
+ case VertexType.QUAD:
+ for (i = 0; i < increment; i += 4) {
+ curr = _batchingSize + i;
+ _indexData[_indexSize++] = curr + 0;
+ _indexData[_indexSize++] = curr + 1;
+ _indexData[_indexSize++] = curr + 2;
+ _indexData[_indexSize++] = curr + 1;
+ _indexData[_indexSize++] = curr + 2;
+ _indexData[_indexSize++] = curr + 3;
+ }
+ break;
+ case VertexType.TRIANGLE:
+ _pureQuad = false;
+ for (i = 0; i < increment; i += 3) {
+ curr = _batchingSize + i;
+ _indexData[_indexSize++] = curr + 0;
+ _indexData[_indexSize++] = curr + 1;
+ _indexData[_indexSize++] = curr + 2;
+ }
+ break;
+ case VertexType.CUSTOM:
+ // CUSTOM type increase the indices data
+ _pureQuad = false;
+ var len = indices.length;
+ for (i = 0; i < len; i++) {
+ _indexData[_indexSize++] = _batchingSize + indices[i];
+ }
+ break;
+ default:
+ return;
+ }
+ _batchingSize += increment;
+ },
+
+ _updateBatchedInfo: function (texture, blendFunc, glProgramState) {
+ if (texture !== _batchedInfo.texture ||
+ blendFunc.src !== _batchedInfo.blendSrc ||
+ blendFunc.dst !== _batchedInfo.blendDst ||
+ glProgramState !== _batchedInfo.glProgramState) {
+ // Draw batched elements
+ this._batchRendering();
+ // Update _batchedInfo
+ _batchedInfo.texture = texture;
+ _batchedInfo.blendSrc = blendFunc.src;
+ _batchedInfo.blendDst = blendFunc.dst;
+ _batchedInfo.glProgramState = glProgramState;
+
+ return true;
+ }
+ else {
+ return false;
+ }
+ },
+
+ _breakBatch: function () {
+ _batchBroken = true;
+ },
+
+ _uploadBufferData: function (cmd) {
+ if (_batchingSize >= _maxVertexSize) {
+ this._batchRendering();
+ }
+
+ // Check batching
+ var node = cmd._node;
+ var texture = node._texture || (node._spriteFrame && node._spriteFrame._texture);
+ var blendSrc = node._blendFunc.src;
+ var blendDst = node._blendFunc.dst;
+ var glProgramState = cmd._glProgramState;
+ if (_batchBroken ||
+ _batchedInfo.texture !== texture ||
+ _batchedInfo.blendSrc !== blendSrc ||
+ _batchedInfo.blendDst !== blendDst ||
+ _batchedInfo.glProgramState !== glProgramState) {
+ // Draw batched elements
+ this._batchRendering();
+ // Update _batchedInfo
+ _batchedInfo.texture = texture;
+ _batchedInfo.blendSrc = blendSrc;
+ _batchedInfo.blendDst = blendDst;
+ _batchedInfo.glProgramState = glProgramState;
+ _batchBroken = false;
+ }
+
+ // Upload vertex data
+ var len = cmd.uploadData(_vertexDataF32, _vertexDataUI32, _batchingSize * _sizePerVertex);
+ if (len > 0) {
+ this._increaseBatchingSize(len, cmd.vertexType);
+ }
+ },
+
+ _batchRendering: function () {
+ if (_batchingSize === 0 || !_batchedInfo.texture) {
+ return;
+ }
+
+ var gl = cc._renderContext;
+ var texture = _batchedInfo.texture;
+ var glProgramState = _batchedInfo.glProgramState;
+ var uploadAll = _batchingSize > _maxVertexSize * 0.5;
+
+ if (glProgramState) {
+ glProgramState.apply();
+ glProgramState.getGLProgram()._updateProjectionUniform();
+ }
+
+ cc.glBlendFunc(_batchedInfo.blendSrc, _batchedInfo.blendDst);
+ cc.glBindTexture2DN(0, texture); // = cc.glBindTexture2D(texture);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, _vertexBuffer);
+ // upload the vertex data to the gl buffer
+ if (uploadAll) {
+ gl.bufferData(gl.ARRAY_BUFFER, _vertexDataF32, gl.DYNAMIC_DRAW);
+ }
+ else {
+ var view = _vertexDataF32.subarray(0, _batchingSize * _sizePerVertex);
+ gl.bufferData(gl.ARRAY_BUFFER, view, gl.DYNAMIC_DRAW);
+ }
+
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 24, 0);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, 12);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 24, 16);
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, _indexBuffer);
+ if (!_prevIndexSize || !_pureQuad || _indexSize > _prevIndexSize) {
+ if (uploadAll) {
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, _indexData, gl.DYNAMIC_DRAW);
+ }
+ else {
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, _indexData.subarray(0, _indexSize), gl.DYNAMIC_DRAW);
+ }
+ }
+ gl.drawElements(gl.TRIANGLES, _indexSize, gl.UNSIGNED_SHORT, 0);
+
+ cc.g_NumberOfDraws++;
+
+ if (_pureQuad) {
+ _prevIndexSize = _indexSize;
+ }
+ else {
+ _prevIndexSize = 0;
+ _pureQuad = true;
+ }
+ _batchingSize = 0;
+ _indexSize = 0;
+ },
+
+ /**
+ * drawing all renderer command to context (default is cc._renderContext)
+ * @param {WebGLRenderingContext} [ctx=cc._renderContext]
+ */
+ rendering: function (ctx, cmds) {
+ var locCmds = cmds || this._renderCmds,
+ i, len, cmd,
+ context = ctx || cc._renderContext;
+
+ // Reset buffer for rendering
+ context.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ for (i = 0, len = locCmds.length; i < len; ++i) {
+ cmd = locCmds[i];
+ if (!cmd.needDraw()) continue;
+
+ if (cmd.uploadData) {
+ this._uploadBufferData(cmd);
+ }
+ else {
+ if (_batchingSize > 0) {
+ this._batchRendering();
+ }
+ cmd.rendering(context);
+ }
+ }
+ this._batchRendering();
+ _batchedInfo.texture = null;
+ }
+};
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/scenes/CCLoaderScene.js b/frameworks/cocos2d-html5/cocos2d/core/scenes/CCLoaderScene.js
new file mode 100644
index 0000000..2f05181
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/scenes/CCLoaderScene.js
@@ -0,0 +1,165 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+/**
+ * cc.LoaderScene is a scene that you can load it when you loading files
+ * cc.LoaderScene can present thedownload progress
+ * @class
+ * @extends cc.Scene
+ * @example
+ * var lc = new cc.LoaderScene();
+ */
+cc.LoaderScene = cc.Scene.extend({
+ _interval : null,
+ _label : null,
+ _logo : null,
+ _className:"LoaderScene",
+ cb: null,
+ target: null,
+ /**
+ * Contructor of cc.LoaderScene
+ * @returns {boolean}
+ */
+ init : function(){
+ var self = this;
+
+ //logo
+ var logoWidth = 160;
+ var logoHeight = 200;
+
+ // bg
+ var bgLayer = self._bgLayer = new cc.LayerColor(cc.color(32, 32, 32, 255));
+ self.addChild(bgLayer, 0);
+
+ //image move to CCSceneFile.js
+ var fontSize = 24, lblHeight = -logoHeight / 2 + 100;
+ if(cc._loaderImage){
+ //loading logo
+ cc.loader.loadImg(cc._loaderImage, {isCrossOrigin : false }, function(err, img){
+ logoWidth = img.width;
+ logoHeight = img.height;
+ self._initStage(img, cc.visibleRect.center);
+ });
+ fontSize = 14;
+ lblHeight = -logoHeight / 2 - 10;
+ }
+ //loading percent
+ var label = self._label = new cc.LabelTTF("Loading... 0%", "Arial", fontSize);
+ label.setPosition(cc.pAdd(cc.visibleRect.center, cc.p(0, lblHeight)));
+ label.setColor(cc.color(180, 180, 180));
+ bgLayer.addChild(this._label, 10);
+ return true;
+ },
+
+ _initStage: function (img, centerPos) {
+ var self = this;
+ var texture2d = self._texture2d = new cc.Texture2D();
+ texture2d.initWithElement(img);
+ texture2d.handleLoadedTexture();
+ var logo = self._logo = new cc.Sprite(texture2d);
+ logo.setScale(cc.contentScaleFactor());
+ logo.x = centerPos.x;
+ logo.y = centerPos.y;
+ self._bgLayer.addChild(logo, 10);
+ },
+ /**
+ * custom onEnter
+ */
+ onEnter: function () {
+ var self = this;
+ cc.Node.prototype.onEnter.call(self);
+ self.schedule(self._startLoading, 0.3);
+ },
+ /**
+ * custom onExit
+ */
+ onExit: function () {
+ cc.Node.prototype.onExit.call(this);
+ var tmpStr = "Loading... 0%";
+ this._label.setString(tmpStr);
+ },
+
+ /**
+ * init with resources
+ * @param {Array} resources
+ * @param {Function|String} cb
+ * @param {Object} target
+ */
+ initWithResources: function (resources, cb, target) {
+ if(cc.isString(resources))
+ resources = [resources];
+ this.resources = resources || [];
+ this.cb = cb;
+ this.target = target;
+ },
+
+ _startLoading: function () {
+ var self = this;
+ self.unschedule(self._startLoading);
+ var res = self.resources;
+ cc.loader.load(res,
+ function (result, count, loadedCount) {
+ var percent = (loadedCount / count * 100) | 0;
+ percent = Math.min(percent, 100);
+ self._label.setString("Loading... " + percent + "%");
+ }, function () {
+ if (self.cb)
+ self.cb.call(self.target);
+ });
+ },
+
+ _updateTransform: function(){
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ this._bgLayer._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ this._label._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ this._logo && this._logo._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ }
+});
+/**
+ * cc.LoaderScene.preload can present a loaderScene with download progress.
+ * when all the resource are downloaded it will invoke call function
+ * @param resources
+ * @param cb
+ * @param target
+ * @returns {cc.LoaderScene|*}
+ * @example
+ * //Example
+ * cc.LoaderScene.preload(g_resources, function () {
+ cc.director.runScene(new HelloWorldScene());
+ }, this);
+ */
+cc.LoaderScene.preload = function(resources, cb, target){
+ var _cc = cc;
+ if(!_cc.loaderScene) {
+ _cc.loaderScene = new cc.LoaderScene();
+ _cc.loaderScene.init();
+ cc.eventManager.addCustomListener(cc.Director.EVENT_PROJECTION_CHANGED, function(){
+ _cc.loaderScene._updateTransform();
+ });
+ }
+ _cc.loaderScene.initWithResources(resources, cb, target);
+
+ cc.director.runScene(_cc.loaderScene);
+ return _cc.loaderScene;
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/scenes/CCScene.js b/frameworks/cocos2d-html5/cocos2d/core/scenes/CCScene.js
new file mode 100644
index 0000000..a54a179
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/scenes/CCScene.js
@@ -0,0 +1,62 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+
+/**
+ * cc.Scene is a subclass of cc.Node that is used only as an abstract concept.
+ * cc.Scene an cc.Node are almost identical with the difference that cc.Scene has it's
+ * anchor point (by default) at the center of the screen.
+ *
+ * For the moment cc.Scene has no other logic than that, but in future releases it might have
+ * additional logic.
+ *
+ * It is a good practice to use and cc.Scene as the parent of all your nodes.
+ * @class
+ * @extends cc.Node
+ * @example
+ * var scene = new cc.Scene();
+ */
+cc.Scene = cc.Node.extend(/** @lends cc.Scene# */{
+ /**
+ * Constructor of cc.Scene
+ */
+ _className:"Scene",
+ ctor:function () {
+ cc.Node.prototype.ctor.call(this);
+ this._ignoreAnchorPointForPosition = true;
+ this.setAnchorPoint(0.5, 0.5);
+ this.setContentSize(cc.director.getWinSize());
+ }
+});
+
+/**
+ * creates a scene
+ * @deprecated since v3.0,please use new cc.Scene() instead.
+ * @return {cc.Scene}
+ */
+cc.Scene.create = function () {
+ return new cc.Scene();
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/core/sprites/CCAnimation.js b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCAnimation.js
new file mode 100644
index 0000000..1c653a0
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCAnimation.js
@@ -0,0 +1,477 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ *
+ * cc.AnimationFrame
+ * A frame of the animation. It contains information like:
+ * - sprite frame name
+ * - # of delay units.
+ * - offset
+ *
+ * @class
+ * @extends cc.Class
+ * @param spriteFrame
+ * @param delayUnits
+ * @param userInfo
+ * @returns {AnimationFrame}
+ */
+cc.AnimationFrame = cc.Class.extend(/** @lends cc.AnimationFrame# */{
+ _spriteFrame:null,
+ _delayPerUnit:0,
+ _userInfo:null,
+
+ ctor:function (spriteFrame, delayUnits, userInfo) {
+ this._spriteFrame = spriteFrame || null;
+ this._delayPerUnit = delayUnits || 0;
+ this._userInfo = userInfo || null;
+ },
+
+ /**
+ * Create a new animation frame and copy all contents into it
+ * @returns {AnimationFrame}
+ */
+ clone: function(){
+ var frame = new cc.AnimationFrame();
+ frame.initWithSpriteFrame(this._spriteFrame.clone(), this._delayPerUnit, this._userInfo);
+ return frame;
+ },
+
+ /**
+ * Create a new animation frame and copy all contents into it
+ * @returns {AnimationFrame}
+ */
+ copyWithZone:function (pZone) {
+ return cc.clone(this);
+ },
+
+ /**
+ * Create a new animation frame and copy all contents into it
+ * @returns {AnimationFrame}
+ */
+ copy:function (pZone) {
+ var newFrame = new cc.AnimationFrame();
+ newFrame.initWithSpriteFrame(this._spriteFrame.clone(), this._delayPerUnit, this._userInfo);
+ return newFrame;
+ },
+
+ /**
+ * initializes the animation frame with a spriteframe, number of delay units and a notification user info
+ * @param {cc.SpriteFrame} spriteFrame
+ * @param {Number} delayUnits
+ * @param {object} userInfo
+ */
+ initWithSpriteFrame:function (spriteFrame, delayUnits, userInfo) {
+ this._spriteFrame = spriteFrame;
+ this._delayPerUnit = delayUnits;
+ this._userInfo = userInfo;
+
+ return true;
+ },
+
+ /**
+ * Returns sprite frame to be used
+ * @return {cc.SpriteFrame}
+ */
+ getSpriteFrame:function () {
+ return this._spriteFrame;
+ },
+
+ /**
+ * Sets sprite frame to be used
+ * @param {cc.SpriteFrame} spriteFrame
+ */
+ setSpriteFrame:function (spriteFrame) {
+ this._spriteFrame = spriteFrame;
+ },
+
+ /**
+ * Returns how many units of time the frame takes getter
+ * @return {Number}
+ */
+ getDelayUnits:function () {
+ return this._delayPerUnit;
+ },
+
+ /**
+ * Sets how many units of time the frame takes setter
+ * @param delayUnits
+ */
+ setDelayUnits:function (delayUnits) {
+ this._delayPerUnit = delayUnits;
+ },
+
+ /**
+ * Returns the user custom information
+ * @return {object}
+ */
+ getUserInfo:function () {
+ return this._userInfo;
+ },
+
+ /**
+ * Sets the user custom information
+ * @param {object} userInfo
+ */
+ setUserInfo:function (userInfo) {
+ this._userInfo = userInfo;
+ }
+});
+
+/**
+ * Creates an animation frame.
+ * @deprecated since v3.0, please use the new construction instead
+ * @param {cc.SpriteFrame} spriteFrame
+ * @param {Number} delayUnits
+ * @param {object} userInfo
+ * @see cc.AnimationFrame
+ */
+cc.AnimationFrame.create = function(spriteFrame,delayUnits,userInfo){
+ return new cc.AnimationFrame(spriteFrame,delayUnits,userInfo);
+};
+
+/**
+ *
+ * A cc.Animation object is used to perform animations on the cc.Sprite objects.
+ *
+ * The cc.Animation object contains cc.SpriteFrame objects, and a possible delay between the frames.
+ * You can animate a cc.Animation object by using the cc.Animate action.
+ *
+ * @class
+ * @extends cc.Class
+ * @param {Array} frames
+ * @param {Number} delay
+ * @param {Number} [loops=1]
+ *
+ * @example
+ * // 1. Creates an empty animation
+ * var animation1 = new cc.Animation();
+ *
+ * // 2. Create an animation with sprite frames, delay and loops.
+ * var spriteFrames = [];
+ * var frame = cc.spriteFrameCache.getSpriteFrame("grossini_dance_01.png");
+ * spriteFrames.push(frame);
+ * var animation1 = new cc.Animation(spriteFrames);
+ * var animation2 = new cc.Animation(spriteFrames, 0.2);
+ * var animation2 = new cc.Animation(spriteFrames, 0.2, 2);
+ *
+ * // 3. Create an animation with animation frames, delay and loops.
+ * var animationFrames = [];
+ * var frame = new cc.AnimationFrame();
+ * animationFrames.push(frame);
+ * var animation1 = new cc.Animation(animationFrames);
+ * var animation2 = new cc.Animation(animationFrames, 0.2);
+ * var animation3 = new cc.Animation(animationFrames, 0.2, 2);
+ *
+ * //create an animate with this animation
+ * var action = cc.animate(animation1);
+ *
+ * //run animate
+ * sprite.runAction(action);
+ */
+cc.Animation = cc.Class.extend(/** @lends cc.Animation# */{
+ _frames:null,
+ _loops:0,
+ _restoreOriginalFrame:false,
+ _duration:0,
+ _delayPerUnit:0,
+ _totalDelayUnits:0,
+
+ ctor:function (frames, delay, loops) {
+ this._frames = [];
+
+ if (frames === undefined) {
+ this.initWithSpriteFrames(null, 0);
+ } else {
+ var frame0 = frames[0];
+ if(frame0){
+ if (frame0 instanceof cc.SpriteFrame) {
+ //init with sprite frames , delay and loops.
+ this.initWithSpriteFrames(frames, delay, loops);
+ }else if(frame0 instanceof cc.AnimationFrame) {
+ //init with sprite frames , delay and loops.
+ this.initWithAnimationFrames(frames, delay, loops);
+ }
+ }
+ }
+ },
+
+ // attributes
+
+ /**
+ * Returns the array of animation frames
+ * @return {Array}
+ */
+ getFrames:function () {
+ return this._frames;
+ },
+
+ /**
+ * Sets array of animation frames
+ * @param {Array} frames
+ */
+ setFrames:function (frames) {
+ this._frames = frames;
+ },
+
+ /**
+ * Adds a frame to a cc.Animation, the frame will be added with one "delay unit".
+ * @param {cc.SpriteFrame} frame
+ */
+ addSpriteFrame:function (frame) {
+ var animFrame = new cc.AnimationFrame();
+
+ animFrame.initWithSpriteFrame(frame, 1, null);
+ this._frames.push(animFrame);
+ // update duration
+ this._totalDelayUnits++;
+ },
+
+ /**
+ * Adds a frame with an image filename. Internally it will create a cc.SpriteFrame and it will add it. The frame will be added with one "delay unit".
+ * @param {String} fileName
+ */
+ addSpriteFrameWithFile:function (fileName) {
+ var texture = cc.textureCache.addImage(fileName);
+ var rect = cc.rect(0, 0, 0, 0);
+ rect.width = texture.width;
+ rect.height = texture.height;
+ var frame = new cc.SpriteFrame(texture, rect);
+ this.addSpriteFrame(frame);
+ },
+
+ /**
+ * Adds a frame with a texture and a rect. Internally it will create a cc.SpriteFrame and it will add it. The frame will be added with one "delay unit".
+ * @param {cc.Texture2D} texture
+ * @param {cc.Rect} rect
+ */
+ addSpriteFrameWithTexture:function (texture, rect) {
+ var pFrame = new cc.SpriteFrame(texture, rect);
+ this.addSpriteFrame(pFrame);
+ },
+
+ /**
+ * Initializes a cc.Animation with cc.AnimationFrame, do not call this method yourself, please pass parameters to constructor to initialize.
+ * @param {Array} arrayOfAnimationFrames
+ * @param {Number} delayPerUnit
+ * @param {Number} [loops=1]
+ */
+ initWithAnimationFrames:function (arrayOfAnimationFrames, delayPerUnit, loops) {
+ cc.arrayVerifyType(arrayOfAnimationFrames, cc.AnimationFrame);
+
+ this._delayPerUnit = delayPerUnit;
+ this._loops = loops === undefined ? 1 : loops;
+ this._totalDelayUnits = 0;
+
+ var locFrames = this._frames;
+ locFrames.length = 0;
+ for (var i = 0; i < arrayOfAnimationFrames.length; i++) {
+ var animFrame = arrayOfAnimationFrames[i];
+ locFrames.push(animFrame);
+ this._totalDelayUnits += animFrame.getDelayUnits();
+ }
+
+ return true;
+ },
+
+ /**
+ * Clone the current animation
+ * @return {cc.Animation}
+ */
+ clone: function(){
+ var animation = new cc.Animation();
+ animation.initWithAnimationFrames(this._copyFrames(), this._delayPerUnit, this._loops);
+ animation.setRestoreOriginalFrame(this._restoreOriginalFrame);
+ return animation;
+ },
+
+ /**
+ * Clone the current animation
+ * @return {cc.Animation}
+ */
+ copyWithZone:function (pZone) {
+ var pCopy = new cc.Animation();
+ pCopy.initWithAnimationFrames(this._copyFrames(), this._delayPerUnit, this._loops);
+ pCopy.setRestoreOriginalFrame(this._restoreOriginalFrame);
+ return pCopy;
+ },
+
+ _copyFrames:function(){
+ var copyFrames = [];
+ for(var i = 0; i< this._frames.length;i++)
+ copyFrames.push(this._frames[i].clone());
+ return copyFrames;
+ },
+
+ /**
+ * Clone the current animation
+ * @param pZone
+ * @returns {cc.Animation}
+ */
+ copy:function (pZone) {
+ return this.copyWithZone(null);
+ },
+
+ /**
+ * Returns how many times the animation is going to loop. 0 means animation is not animated. 1, animation is executed one time, ...
+ * @return {Number}
+ */
+ getLoops:function () {
+ return this._loops;
+ },
+
+ /**
+ * Sets how many times the animation is going to loop. 0 means animation is not animated. 1, animation is executed one time, ...
+ * @param {Number} value
+ */
+ setLoops:function (value) {
+ this._loops = value;
+ },
+
+ /**
+ * Sets whether or not it shall restore the original frame when the animation finishes
+ * @param {Boolean} restOrigFrame
+ */
+ setRestoreOriginalFrame:function (restOrigFrame) {
+ this._restoreOriginalFrame = restOrigFrame;
+ },
+
+ /**
+ * Returns whether or not it shall restore the original frame when the animation finishes
+ * @return {Boolean}
+ */
+ getRestoreOriginalFrame:function () {
+ return this._restoreOriginalFrame;
+ },
+
+ /**
+ * Returns duration in seconds of the whole animation. It is the result of totalDelayUnits * delayPerUnit
+ * @return {Number}
+ */
+ getDuration:function () {
+ return this._totalDelayUnits * this._delayPerUnit;
+ },
+
+ /**
+ * Returns delay in seconds of the "delay unit"
+ * @return {Number}
+ */
+ getDelayPerUnit:function () {
+ return this._delayPerUnit;
+ },
+
+ /**
+ * Sets delay in seconds of the "delay unit"
+ * @param {Number} delayPerUnit
+ */
+ setDelayPerUnit:function (delayPerUnit) {
+ this._delayPerUnit = delayPerUnit;
+ },
+
+ /**
+ * Returns total delay units of the cc.Animation.
+ * @return {Number}
+ */
+ getTotalDelayUnits:function () {
+ return this._totalDelayUnits;
+ },
+
+ /**
+ * Initializes a cc.Animation with frames and a delay between frames, do not call this method yourself, please pass parameters to constructor to initialize.
+ * @param {Array} frames
+ * @param {Number} delay
+ * @param {Number} [loops=1]
+ */
+ initWithSpriteFrames:function (frames, delay, loops) {
+ cc.arrayVerifyType(frames, cc.SpriteFrame);
+ this._loops = loops === undefined ? 1 : loops;
+ this._delayPerUnit = delay || 0;
+ this._totalDelayUnits = 0;
+
+ var locFrames = this._frames;
+ locFrames.length = 0;
+ if (frames) {
+ for (var i = 0; i < frames.length; i++) {
+ var frame = frames[i];
+ var animFrame = new cc.AnimationFrame();
+ animFrame.initWithSpriteFrame(frame, 1, null);
+ locFrames.push(animFrame);
+ }
+ this._totalDelayUnits += frames.length;
+ }
+ return true;
+ },
+ /**
+ * Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
+ * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
+ * This is a hack, and should be removed once JSB fixes the retain/release bug
+ * You will need to retain an object if you created an engine object and haven't added it into the scene graph during the same frame.
+ * Otherwise, JSB's native autorelease pool will consider this object a useless one and release it directly,
+ * when you want to use it later, a "Invalid Native Object" error will be raised.
+ * The retain function can increase a reference count for the native object to avoid it being released,
+ * you need to manually invoke release function when you think this object is no longer needed, otherwise, there will be memory learks.
+ * retain and release function call should be paired in developer's game code.
+ * @function
+ * @see cc.Animation#release
+ */
+ retain:function () {
+ },
+ /**
+ * Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
+ * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
+ * This is a hack, and should be removed once JSB fixes the retain/release bug
+ * You will need to retain an object if you created an engine object and haven't added it into the scene graph during the same frame.
+ * Otherwise, JSB's native autorelease pool will consider this object a useless one and release it directly,
+ * when you want to use it later, a "Invalid Native Object" error will be raised.
+ * The retain function can increase a reference count for the native object to avoid it being released,
+ * you need to manually invoke release function when you think this object is no longer needed, otherwise, there will be memory learks.
+ * retain and release function call should be paired in developer's game code.
+ * @function
+ * @see cc.Animation#retain
+ */
+ release:function () {
+ }
+});
+
+/**
+ * Creates an animation.
+ * @deprecated since v3.0, please use new construction instead
+ * @see cc.Animation
+ * @param {Array} frames
+ * @param {Number} delay
+ * @param {Number} [loops=1]
+ * @return {cc.Animation}
+ */
+cc.Animation.create = function (frames, delay, loops) {
+ return new cc.Animation(frames, delay, loops);
+};
+
+/**
+ * @deprecated since v3.0, please use new construction instead
+ * @see cc.Animation
+ * @type {Function}
+ */
+cc.Animation.createWithAnimationFrames = cc.Animation.create;
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/sprites/CCAnimationCache.js b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCAnimationCache.js
new file mode 100644
index 0000000..d156393
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCAnimationCache.js
@@ -0,0 +1,213 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ *
+ * cc.animationCache is a singleton object that manages the Animations.
+ * It saves in a cache the animations. You should use this class if you want to save your animations in a cache.
+ *
+ * example
+ * cc.animationCache.addAnimation(animation,"animation1");
+ *
+ * @class
+ * @name cc.animationCache
+ */
+cc.animationCache = /** @lends cc.animationCache# */{
+ _animations: {},
+
+ /**
+ * Adds a cc.Animation with a name.
+ * @param {cc.Animation} animation
+ * @param {String} name
+ */
+ addAnimation:function (animation, name) {
+ this._animations[name] = animation;
+ },
+
+ /**
+ * Deletes a cc.Animation from the cache.
+ * @param {String} name
+ */
+ removeAnimation:function (name) {
+ if (!name) {
+ return;
+ }
+ if (this._animations[name]) {
+ delete this._animations[name];
+ }
+ },
+
+ /**
+ *
+ * Returns a cc.Animation that was previously added.
+ * If the name is not found it will return nil.
+ * You should retain the returned copy if you are going to use it.
+ *
+ * @param {String} name
+ * @return {cc.Animation}
+ */
+ getAnimation:function (name) {
+ if (this._animations[name])
+ return this._animations[name];
+ return null;
+ },
+
+ _addAnimationsWithDictionary:function (dictionary,plist) {
+ var animations = dictionary["animations"];
+ if (!animations) {
+ cc.log(cc._LogInfos.animationCache__addAnimationsWithDictionary);
+ return;
+ }
+
+ var version = 1;
+ var properties = dictionary["properties"];
+ if (properties) {
+ version = (properties["format"] != null) ? parseInt(properties["format"]) : version;
+ var spritesheets = properties["spritesheets"];
+ var spriteFrameCache = cc.spriteFrameCache;
+ var path = cc.path;
+ for (var i = 0; i < spritesheets.length; i++) {
+ spriteFrameCache.addSpriteFrames(path.changeBasename(plist, spritesheets[i]));
+ }
+ }
+
+ switch (version) {
+ case 1:
+ this._parseVersion1(animations);
+ break;
+ case 2:
+ this._parseVersion2(animations);
+ break;
+ default :
+ cc.log(cc._LogInfos.animationCache__addAnimationsWithDictionary_2);
+ break;
+ }
+ },
+
+ /**
+ *
+ * Adds an animations from a plist file.
+ * Make sure that the frames were previously loaded in the cc.SpriteFrameCache.
+ *
+ * @param {String} plist
+ */
+ addAnimations:function (plist) {
+
+ cc.assert(plist, cc._LogInfos.animationCache_addAnimations_2);
+
+ var dict = cc.loader.getRes(plist);
+
+ if(!dict){
+ cc.log(cc._LogInfos.animationCache_addAnimations);
+ return;
+ }
+
+ this._addAnimationsWithDictionary(dict,plist);
+ },
+
+ _parseVersion1:function (animations) {
+ var frameCache = cc.spriteFrameCache;
+
+ for (var key in animations) {
+ var animationDict = animations[key];
+ var frameNames = animationDict["frames"];
+ var delay = parseFloat(animationDict["delay"]) || 0;
+ var animation = null;
+ if (!frameNames) {
+ cc.log(cc._LogInfos.animationCache__parseVersion1, key);
+ continue;
+ }
+
+ var frames = [];
+ for (var i = 0; i < frameNames.length; i++) {
+ var spriteFrame = frameCache.getSpriteFrame(frameNames[i]);
+ if (!spriteFrame) {
+ cc.log(cc._LogInfos.animationCache__parseVersion1_2, key, frameNames[i]);
+ continue;
+ }
+ var animFrame = new cc.AnimationFrame();
+ animFrame.initWithSpriteFrame(spriteFrame, 1, null);
+ frames.push(animFrame);
+ }
+
+ if (frames.length === 0) {
+ cc.log(cc._LogInfos.animationCache__parseVersion1_3, key);
+ continue;
+ } else if (frames.length !== frameNames.length) {
+ cc.log(cc._LogInfos.animationCache__parseVersion1_4, key);
+ }
+ animation = new cc.Animation(frames, delay, 1);
+ cc.animationCache.addAnimation(animation, key);
+ }
+ },
+
+ _parseVersion2:function (animations) {
+ var frameCache = cc.spriteFrameCache;
+
+ for (var key in animations) {
+ var animationDict = animations[key];
+
+ var isLoop = animationDict["loop"];
+ var loopsTemp = parseInt(animationDict["loops"]);
+ var loops = isLoop ? cc.REPEAT_FOREVER : ((isNaN(loopsTemp)) ? 1 : loopsTemp);
+ var restoreOriginalFrame = (animationDict["restoreOriginalFrame"] && animationDict["restoreOriginalFrame"] == true) ? true : false;
+ var frameArray = animationDict["frames"];
+
+ if (!frameArray) {
+ cc.log(cc._LogInfos.animationCache__parseVersion2, key);
+ continue;
+ }
+
+ //Array of AnimationFrames
+ var arr = [];
+ for (var i = 0; i < frameArray.length; i++) {
+ var entry = frameArray[i];
+ var spriteFrameName = entry["spriteframe"];
+ var spriteFrame = frameCache.getSpriteFrame(spriteFrameName);
+ if (!spriteFrame) {
+ cc.log(cc._LogInfos.animationCache__parseVersion2_2, key, spriteFrameName);
+ continue;
+ }
+
+ var delayUnits = parseFloat(entry["delayUnits"]) || 0;
+ var userInfo = entry["notification"];
+ var animFrame = new cc.AnimationFrame();
+ animFrame.initWithSpriteFrame(spriteFrame, delayUnits, userInfo);
+ arr.push(animFrame);
+ }
+
+ var delayPerUnit = parseFloat(animationDict["delayPerUnit"]) || 0;
+ var animation = new cc.Animation();
+ animation.initWithAnimationFrames(arr, delayPerUnit, loops);
+ animation.setRestoreOriginalFrame(restoreOriginalFrame);
+ cc.animationCache.addAnimation(animation, key);
+ }
+ },
+
+ _clear: function () {
+ this._animations = {};
+ }
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/core/sprites/CCBakeSprite.js b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCBakeSprite.js
new file mode 100644
index 0000000..33e4ce2
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCBakeSprite.js
@@ -0,0 +1,78 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of _t software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.BakeSprite is a type of sprite that will be cached.
+ * @class
+ * @extend cc.Sprite
+ */
+cc.BakeSprite = cc.Sprite.extend(/** @lends cc.BakeSprite# */{
+ _cacheCanvas: null,
+ _cacheContext: null,
+
+ ctor: function(){
+ cc.Sprite.prototype.ctor.call(this);
+ var canvasElement = document.createElement("canvas");
+ canvasElement.width = canvasElement.height = 10;
+ this._cacheCanvas = canvasElement;
+ this._cacheContext = new cc.CanvasContextWrapper(canvasElement.getContext("2d"));
+
+ var texture = new cc.Texture2D();
+ texture.initWithElement(canvasElement);
+ texture.handleLoadedTexture();
+ this.setTexture(texture);
+ },
+
+ getCacheContext: function(){
+ return this._cacheContext;
+ },
+
+ getCacheCanvas: function(){
+ return this._cacheCanvas;
+ },
+
+ /**
+ * reset the cache canvas size
+ * @param {cc.Size|Number} sizeOrWidth size or width
+ * @param {Number} [height]
+ */
+ resetCanvasSize: function(sizeOrWidth, height){
+ var locCanvas = this._cacheCanvas,
+ locContext = this._cacheContext,
+ strokeStyle = locContext._context.strokeStyle,
+ fillStyle = locContext._context.fillStyle;
+ if(height === undefined){
+ height = sizeOrWidth.height;
+ sizeOrWidth = sizeOrWidth.width;
+ }
+ locCanvas.width = sizeOrWidth;
+ locCanvas.height = height; //TODO note baidu browser reset the context after set width or height
+ if(strokeStyle !== locContext._context.strokeStyle)
+ locContext._context.strokeStyle = strokeStyle;
+ if(fillStyle !== locContext._context.fillStyle)
+ locContext._context.fillStyle = fillStyle;
+ this.getTexture().handleLoadedTexture();
+ this.setTextureRect(cc.rect(0,0, sizeOrWidth, height), false, null, false);
+ }
+});
diff --git a/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSprite.js b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSprite.js
new file mode 100644
index 0000000..d450424
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSprite.js
@@ -0,0 +1,892 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.Sprite is a 2d image ( http://en.wikipedia.org/wiki/Sprite_(computer_graphics) )
+ *
+ * cc.Sprite can be created with an image, or with a sub-rectangle of an image.
+ *
+ * If the parent or any of its ancestors is a cc.SpriteBatchNode then the following features/limitations are valid
+ * - Features when the parent is a cc.BatchNode:
+ * - MUCH faster rendering, specially if the cc.SpriteBatchNode has many children. All the children will be drawn in a single batch.
+ *
+ * - Limitations
+ * - Camera is not supported yet (eg: CCOrbitCamera action doesn't work)
+ * - GridBase actions are not supported (eg: CCLens, CCRipple, CCTwirl)
+ * - The Alias/Antialias property belongs to CCSpriteBatchNode, so you can't individually set the aliased property.
+ * - The Blending function property belongs to CCSpriteBatchNode, so you can't individually set the blending function property.
+ * - Parallax scroller is not supported, but can be simulated with a "proxy" sprite.
+ *
+ * If the parent is an standard cc.Node, then cc.Sprite behaves like any other cc.Node:
+ * - It supports blending functions
+ * - It supports aliasing / antialiasing
+ * - But the rendering will be slower: 1 draw per children.
+ *
+ * The default anchorPoint in cc.Sprite is (0.5, 0.5).
+ * @class
+ * @extends cc.Node
+ *
+ * @param {String|cc.SpriteFrame|HTMLImageElement|cc.Texture2D} fileName The string which indicates a path to image file, e.g., "scene1/monster.png".
+ * @param {cc.Rect} [rect] Only the contents inside rect of pszFileName's texture will be applied for this sprite.
+ * @param {Boolean} [rotated] Whether or not the texture rectangle is rotated.
+ * @example
+ *
+ * 1.Create a sprite with image path and rect
+ * var sprite1 = new cc.Sprite("res/HelloHTML5World.png");
+ * var sprite2 = new cc.Sprite("res/HelloHTML5World.png",cc.rect(0,0,480,320));
+ *
+ * 2.Create a sprite with a sprite frame name. Must add "#" before frame name.
+ * var sprite = new cc.Sprite('#grossini_dance_01.png');
+ *
+ * 3.Create a sprite with a sprite frame
+ * var spriteFrame = cc.spriteFrameCache.getSpriteFrame("grossini_dance_01.png");
+ * var sprite = new cc.Sprite(spriteFrame);
+ *
+ * 4.Create a sprite with an existing texture contained in a CCTexture2D object
+ * After creation, the rect will be the size of the texture, and the offset will be (0,0).
+ * var texture = cc.textureCache.addImage("HelloHTML5World.png");
+ * var sprite1 = new cc.Sprite(texture);
+ * var sprite2 = new cc.Sprite(texture, cc.rect(0,0,480,320));
+ *
+ * @property {Boolean} dirty - Indicates whether the sprite needs to be updated.
+ * @property {Boolean} flippedX - Indicates whether or not the sprite is flipped on x axis.
+ * @property {Boolean} flippedY - Indicates whether or not the sprite is flipped on y axis.
+ * @property {Number} offsetX - <@readonly> The offset position on x axis of the sprite in texture. Calculated automatically by editors like Zwoptex.
+ * @property {Number} offsetY - <@readonly> The offset position on x axis of the sprite in texture. Calculated automatically by editors like Zwoptex.
+ * @property {Number} atlasIndex - The index used on the TextureAtlas.
+ * @property {cc.Texture2D} texture - Texture used to render the sprite.
+ * @property {Boolean} textureRectRotated - <@readonly> Indicate whether the texture rectangle is rotated.
+ * @property {cc.TextureAtlas} textureAtlas - The weak reference of the cc.TextureAtlas when the sprite is rendered using via cc.SpriteBatchNode.
+ * @property {cc.SpriteBatchNode} batchNode - The batch node object if this sprite is rendered by cc.SpriteBatchNode.
+ * @property {cc.V3F_C4B_T2F_Quad} quad - <@readonly> The quad (tex coords, vertex coords and color) information.
+ */
+cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{
+ dirty: false,
+ atlasIndex: 0,
+ textureAtlas: null,
+
+ _batchNode: null,
+ _recursiveDirty: null, //Whether all of the sprite's children needs to be updated
+ _hasChildren: null, //Whether the sprite contains children
+ _shouldBeHidden: false, //should not be drawn because one of the ancestors is not visible
+ _transformToBatch: null,
+
+ //
+ // Data used when the sprite is self-rendered
+ //
+ _blendFunc: null, //It's required for CCTextureProtocol inheritance
+ _texture: null, //cc.Texture2D object that is used to render the sprite
+
+ //
+ // Shared data
+ //
+ // texture
+ _rect: null, //Rectangle of cc.Texture2D
+ _rectRotated: false, //Whether the texture is rotated
+
+ // Offset Position (used by Zwoptex)
+ _offsetPosition: null, // absolute
+ _unflippedOffsetPositionFromCenter: null,
+
+ _opacityModifyRGB: false,
+
+ // image is flipped
+ _flippedX: false, //Whether the sprite is flipped horizontally or not.
+ _flippedY: false, //Whether the sprite is flipped vertically or not.
+
+ _textureLoaded: false,
+ _className: "Sprite",
+
+ ctor: function (fileName, rect, rotated) {
+ var self = this;
+ cc.Node.prototype.ctor.call(self);
+ // default transform anchor: center
+ this.setAnchorPoint(0.5, 0.5);
+
+ self._loader = new cc.Sprite.LoadManager();
+ self._shouldBeHidden = false;
+ self._offsetPosition = cc.p(0, 0);
+ self._unflippedOffsetPositionFromCenter = cc.p(0, 0);
+ self._blendFunc = {src: cc.BLEND_SRC, dst: cc.BLEND_DST};
+ self._rect = cc.rect(0, 0, 0, 0);
+
+ self._softInit(fileName, rect, rotated);
+ },
+
+ /**
+ * Returns whether the texture have been loaded
+ * @returns {boolean}
+ */
+ textureLoaded: function () {
+ return this._textureLoaded;
+ },
+
+ /**
+ * Add a event listener for texture loaded event.
+ * @param {Function} callback
+ * @param {Object} target
+ * @deprecated since 3.1, please use addEventListener instead
+ */
+ addLoadedEventListener: function (callback, target) {
+ this.addEventListener("load", callback, target);
+ },
+
+ /**
+ * Returns whether or not the Sprite needs to be updated in the Atlas
+ * @return {Boolean} True if the sprite needs to be updated in the Atlas, false otherwise.
+ */
+ isDirty: function () {
+ return this.dirty;
+ },
+
+ /**
+ * Makes the sprite to be updated in the Atlas.
+ * @param {Boolean} bDirty
+ */
+ setDirty: function (bDirty) {
+ this.dirty = bDirty;
+ },
+
+ /**
+ * Returns whether or not the texture rectangle is rotated.
+ * @return {Boolean}
+ */
+ isTextureRectRotated: function () {
+ return this._rectRotated;
+ },
+
+ /**
+ * Returns the index used on the TextureAtlas.
+ * @return {Number}
+ */
+ getAtlasIndex: function () {
+ return this.atlasIndex;
+ },
+
+ /**
+ * Sets the index used on the TextureAtlas.
+ * @warning Don't modify this value unless you know what you are doing
+ * @param {Number} atlasIndex
+ */
+ setAtlasIndex: function (atlasIndex) {
+ this.atlasIndex = atlasIndex;
+ },
+
+ /**
+ * Returns the rect of the cc.Sprite in points
+ * @return {cc.Rect}
+ */
+ getTextureRect: function () {
+ return cc.rect(this._rect);
+ },
+
+ /**
+ * Returns the weak reference of the cc.TextureAtlas when the sprite is rendered using via cc.SpriteBatchNode
+ * @return {cc.TextureAtlas}
+ */
+ getTextureAtlas: function () {
+ return this.textureAtlas;
+ },
+
+ /**
+ * Sets the weak reference of the cc.TextureAtlas when the sprite is rendered using via cc.SpriteBatchNode
+ * @param {cc.TextureAtlas} textureAtlas
+ */
+ setTextureAtlas: function (textureAtlas) {
+ this.textureAtlas = textureAtlas;
+ },
+
+ /**
+ * Returns the offset position of the sprite. Calculated automatically by editors like Zwoptex.
+ * @return {cc.Point}
+ */
+ getOffsetPosition: function () {
+ return cc.p(this._offsetPosition);
+ },
+
+ _getOffsetX: function () {
+ return this._offsetPosition.x;
+ },
+ _getOffsetY: function () {
+ return this._offsetPosition.y;
+ },
+
+ /**
+ * Returns the blend function
+ * @return {cc.BlendFunc}
+ */
+ getBlendFunc: function () {
+ return this._blendFunc;
+ },
+
+ /**
+ * Initializes a sprite with a SpriteFrame. The texture and rect in SpriteFrame will be applied on this sprite.
+ * Please pass parameters to the constructor to initialize the sprite, do not call this function yourself,
+ * @param {cc.SpriteFrame} spriteFrame A CCSpriteFrame object. It should includes a valid texture and a rect
+ * @return {Boolean} true if the sprite is initialized properly, false otherwise.
+ */
+ initWithSpriteFrame: function (spriteFrame) {
+ cc.assert(spriteFrame, cc._LogInfos.Sprite_initWithSpriteFrame);
+ return this.setSpriteFrame(spriteFrame);
+ },
+
+ /**
+ * Initializes a sprite with a sprite frame name.
+ * A cc.SpriteFrame will be fetched from the cc.SpriteFrameCache by name.
+ * If the cc.SpriteFrame doesn't exist it will raise an exception.
+ * Please pass parameters to the constructor to initialize the sprite, do not call this function yourself.
+ * @param {String} spriteFrameName A key string that can fected a valid cc.SpriteFrame from cc.SpriteFrameCache
+ * @return {Boolean} true if the sprite is initialized properly, false otherwise.
+ * @example
+ * var sprite = new cc.Sprite();
+ * sprite.initWithSpriteFrameName("grossini_dance_01.png");
+ */
+ initWithSpriteFrameName: function (spriteFrameName) {
+ cc.assert(spriteFrameName, cc._LogInfos.Sprite_initWithSpriteFrameName);
+ var frame = cc.spriteFrameCache.getSpriteFrame(spriteFrameName);
+ cc.assert(frame, spriteFrameName + cc._LogInfos.Sprite_initWithSpriteFrameName1);
+ return this.initWithSpriteFrame(frame);
+ },
+
+ /**
+ * Tell the sprite to use batch node render.
+ * @param {cc.SpriteBatchNode} batchNode
+ */
+ useBatchNode: function (batchNode) {
+ },
+
+ /**
+ *
+ * set the vertex rect.
+ * It will be called internally by setTextureRect.
+ * Useful if you want to create 2x images from SD images in Retina Display.
+ * Do not call it manually. Use setTextureRect instead.
+ * (override this method to generate "double scale" sprites)
+ *
+ * @param {cc.Rect} rect
+ */
+ setVertexRect: function (rect) {
+ var locRect = this._rect;
+ locRect.x = rect.x;
+ locRect.y = rect.y;
+ locRect.width = rect.width;
+ locRect.height = rect.height;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ //
+ // cc.Node property overloads
+ //
+
+ /**
+ * Sets whether the sprite should be flipped horizontally or not.
+ * @param {Boolean} flippedX true if the sprite should be flipped horizontally, false otherwise.
+ */
+ setFlippedX: function (flippedX) {
+ if (this._flippedX !== flippedX) {
+ this._flippedX = flippedX;
+ this.setTextureRect(this._rect, this._rectRotated, this._contentSize);
+ this.setNodeDirty(true);
+ }
+ },
+
+ /**
+ * Sets whether the sprite should be flipped vertically or not.
+ * @param {Boolean} flippedY true if the sprite should be flipped vertically, false otherwise.
+ */
+ setFlippedY: function (flippedY) {
+ if (this._flippedY !== flippedY) {
+ this._flippedY = flippedY;
+ this.setTextureRect(this._rect, this._rectRotated, this._contentSize);
+ this.setNodeDirty(true);
+ }
+ },
+
+ /**
+ *
+ * Returns the flag which indicates whether the sprite is flipped horizontally or not.
+ *
+ * It only flips the texture of the sprite, and not the texture of the sprite's children.
+ * Also, flipping the texture doesn't alter the anchorPoint.
+ * If you want to flip the anchorPoint too, and/or to flip the children too use:
+ * sprite.setScaleX(sprite.getScaleX() * -1);
+ * @return {Boolean} true if the sprite is flipped horizontally, false otherwise.
+ */
+ isFlippedX: function () {
+ return this._flippedX;
+ },
+
+ /**
+ *
+ * Return the flag which indicates whether the sprite is flipped vertically or not.
+ *
+ * It only flips the texture of the sprite, and not the texture of the sprite's children.
+ * Also, flipping the texture doesn't alter the anchorPoint.
+ * If you want to flip the anchorPoint too, and/or to flip the children too use:
+ * sprite.setScaleY(sprite.getScaleY() * -1);
+ * @return {Boolean} true if the sprite is flipped vertically, false otherwise.
+ */
+ isFlippedY: function () {
+ return this._flippedY;
+ },
+
+ //
+ // RGBA protocol
+ //
+ /**
+ * Sets whether opacity modify color or not.
+ * @function
+ * @param {Boolean} modify
+ */
+ setOpacityModifyRGB: function (modify) {
+ if (this._opacityModifyRGB !== modify) {
+ this._opacityModifyRGB = modify;
+ this._renderCmd._setColorDirty();
+ }
+ },
+
+ /**
+ * Returns whether opacity modify color or not.
+ * @return {Boolean}
+ */
+ isOpacityModifyRGB: function () {
+ return this._opacityModifyRGB;
+ },
+
+ // Animation
+
+ /**
+ * Changes the display frame with animation name and index.
+ * The animation name will be get from the CCAnimationCache
+ * @param {String} animationName
+ * @param {Number} frameIndex
+ */
+ setDisplayFrameWithAnimationName: function (animationName, frameIndex) {
+ cc.assert(animationName, cc._LogInfos.Sprite_setDisplayFrameWithAnimationName_3);
+
+ var cache = cc.animationCache.getAnimation(animationName);
+ if (!cache) {
+ cc.log(cc._LogInfos.Sprite_setDisplayFrameWithAnimationName);
+ return;
+ }
+ var animFrame = cache.getFrames()[frameIndex];
+ if (!animFrame) {
+ cc.log(cc._LogInfos.Sprite_setDisplayFrameWithAnimationName_2);
+ return;
+ }
+ this.setSpriteFrame(animFrame.getSpriteFrame());
+ },
+
+ /**
+ * Returns the batch node object if this sprite is rendered by cc.SpriteBatchNode
+ * @returns {cc.SpriteBatchNode|null} The cc.SpriteBatchNode object if this sprite is rendered by cc.SpriteBatchNode, null if the sprite isn't used batch node.
+ */
+ getBatchNode: function () {
+ return this._batchNode;
+ },
+
+ // CCTextureProtocol
+ /**
+ * Returns the texture of the sprite node
+ * @returns {cc.Texture2D}
+ */
+ getTexture: function () {
+ return this._texture;
+ },
+
+ _softInit: function (fileName, rect, rotated) {
+ if (fileName === undefined)
+ cc.Sprite.prototype.init.call(this);
+ else if (typeof fileName === 'string') {
+ if (fileName[0] === "#") {
+ // Init with a sprite frame name
+ var frameName = fileName.substr(1, fileName.length - 1);
+ var spriteFrame = cc.spriteFrameCache.getSpriteFrame(frameName);
+ if (spriteFrame)
+ this.initWithSpriteFrame(spriteFrame);
+ else
+ cc.log("%s does not exist", fileName);
+ } else {
+ // Init with filename and rect
+ cc.Sprite.prototype.init.call(this, fileName, rect);
+ }
+ } else if (typeof fileName === "object") {
+ if (fileName instanceof cc.Texture2D) {
+ // Init with texture and rect
+ this.initWithTexture(fileName, rect, rotated);
+ } else if (fileName instanceof cc.SpriteFrame) {
+ // Init with a sprite frame
+ this.initWithSpriteFrame(fileName);
+ } else if ((fileName instanceof HTMLImageElement) || (fileName instanceof HTMLCanvasElement)) {
+ // Init with a canvas or image element
+ var texture2d = new cc.Texture2D();
+ texture2d.initWithElement(fileName);
+ texture2d.handleLoadedTexture();
+ this.initWithTexture(texture2d);
+ }
+ }
+ },
+
+ /**
+ * Returns the quad (tex coords, vertex coords and color) information.
+ * @return {cc.V3F_C4B_T2F_Quad|null} Returns a cc.V3F_C4B_T2F_Quad object when render mode is WebGL, returns null when render mode is Canvas.
+ */
+ getQuad: function () {
+ return null;
+ },
+
+ /**
+ * conforms to cc.TextureProtocol protocol
+ * @function
+ * @param {Number|cc.BlendFunc} src
+ * @param {Number} dst
+ */
+ setBlendFunc: function (src, dst) {
+ var locBlendFunc = this._blendFunc;
+ if (dst === undefined) {
+ locBlendFunc.src = src.src;
+ locBlendFunc.dst = src.dst;
+ } else {
+ locBlendFunc.src = src;
+ locBlendFunc.dst = dst;
+ }
+ this._renderCmd.updateBlendFunc(locBlendFunc);
+ },
+
+ /**
+ * Initializes an empty sprite with nothing init.
+ * Please pass parameters to the constructor to initialize the sprite, do not call this function yourself.
+ * @function
+ * @return {Boolean}
+ */
+ init: function () {
+ var _t = this;
+ if (arguments.length > 0)
+ return _t.initWithFile(arguments[0], arguments[1]);
+
+ cc.Node.prototype.init.call(_t);
+ _t.dirty = _t._recursiveDirty = false;
+
+ _t._blendFunc.src = cc.BLEND_SRC;
+ _t._blendFunc.dst = cc.BLEND_DST;
+
+ _t.texture = null;
+ _t._flippedX = _t._flippedY = false;
+
+ // default transform anchor: center
+ _t.anchorX = 0.5;
+ _t.anchorY = 0.5;
+
+ // zwoptex default values
+ _t._offsetPosition.x = 0;
+ _t._offsetPosition.y = 0;
+ _t._hasChildren = false;
+
+ // updated in "useSelfRender"
+ // Atlas: TexCoords
+ _t.setTextureRect(cc.rect(0, 0, 0, 0), false, cc.size(0, 0));
+ return true;
+ },
+
+ /**
+ *
+ * Initializes a sprite with an image filename.
+ *
+ * This method will find pszFilename from local file system, load its content to CCTexture2D,
+ * then use CCTexture2D to create a sprite.
+ * After initialization, the rect used will be the size of the image. The offset will be (0,0).
+ * Please pass parameters to the constructor to initialize the sprite, do not call this function yourself.
+ *
+ * @param {String} filename The path to an image file in local file system
+ * @param {cc.Rect} rect The rectangle assigned the content area from texture.
+ * @return {Boolean} true if the sprite is initialized properly, false otherwise.
+ */
+ initWithFile: function (filename, rect) {
+ cc.assert(filename, cc._LogInfos.Sprite_initWithFile);
+
+ var tex = cc.textureCache.getTextureForKey(filename);
+ if (!tex) {
+ tex = cc.textureCache.addImage(filename);
+ }
+
+ if (!tex.isLoaded()) {
+ this._loader.clear();
+ this._loader.once(tex, function () {
+ this.initWithFile(filename, rect);
+ this.dispatchEvent("load");
+ }, this);
+ return false;
+ }
+
+ if (!rect) {
+ var size = tex.getContentSize();
+ rect = cc.rect(0, 0, size.width, size.height);
+ }
+ return this.initWithTexture(tex, rect);
+ },
+
+ /**
+ * Initializes a sprite with a texture and a rect in points, optionally rotated.
+ * After initialization, the rect used will be the size of the texture, and the offset will be (0,0).
+ * Please pass parameters to the constructor to initialize the sprite, do not call this function yourself.
+ * @function
+ * @param {cc.Texture2D|HTMLImageElement|HTMLCanvasElement} texture A pointer to an existing CCTexture2D object. You can use a CCTexture2D object for many sprites.
+ * @param {cc.Rect} [rect] Only the contents inside rect of this texture will be applied for this sprite.
+ * @param {Boolean} [rotated] Whether or not the texture rectangle is rotated.
+ * @param {Boolean} [counterclockwise=true] Whether or not the texture rectangle rotation is counterclockwise (texture package is counterclockwise, spine is clockwise).
+ * @return {Boolean} true if the sprite is initialized properly, false otherwise.
+ */
+ initWithTexture: function (texture, rect, rotated, counterclockwise) {
+ var _t = this;
+ cc.assert(arguments.length !== 0, cc._LogInfos.CCSpriteBatchNode_initWithTexture);
+ this._loader.clear();
+
+ _t._textureLoaded = texture.isLoaded();
+ if (!_t._textureLoaded) {
+ this._loader.once(texture, function () {
+ this.initWithTexture(texture, rect, rotated, counterclockwise);
+ this.dispatchEvent("load");
+ }, this);
+ return false;
+ }
+
+ rotated = rotated || false;
+ texture = this._renderCmd._handleTextureForRotatedTexture(texture, rect, rotated, counterclockwise);
+
+ if (!cc.Node.prototype.init.call(_t))
+ return false;
+
+ _t._batchNode = null;
+ _t._recursiveDirty = false;
+ _t.dirty = false;
+ _t._opacityModifyRGB = true;
+
+ _t._blendFunc.src = cc.BLEND_SRC;
+ _t._blendFunc.dst = cc.BLEND_DST;
+
+ _t._flippedX = _t._flippedY = false;
+
+ // zwoptex default values
+ _t._offsetPosition.x = 0;
+ _t._offsetPosition.y = 0;
+ _t._hasChildren = false;
+
+ _t._rectRotated = rotated;
+ if (rect) {
+ _t._rect.x = rect.x;
+ _t._rect.y = rect.y;
+ _t._rect.width = rect.width;
+ _t._rect.height = rect.height;
+ }
+
+ if (!rect)
+ rect = cc.rect(0, 0, texture.width, texture.height);
+
+ this._renderCmd._checkTextureBoundary(texture, rect, rotated);
+
+ _t.setTexture(texture);
+ _t.setTextureRect(rect, rotated);
+
+ // by default use "Self Render".
+ // if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render"
+ _t.setBatchNode(null);
+ return true;
+ },
+
+ /**
+ * Updates the texture rect of the CCSprite in points.
+ * @function
+ * @param {cc.Rect} rect a rect of texture
+ * @param {Boolean} [rotated] Whether or not the texture is rotated
+ * @param {cc.Size} [untrimmedSize] The original pixels size of the texture
+ * @param {Boolean} [needConvert] contentScaleFactor switch
+ */
+ setTextureRect: function (rect, rotated, untrimmedSize, needConvert) {
+ var _t = this;
+ _t._rectRotated = rotated || false;
+ _t.setContentSize(untrimmedSize || rect);
+
+ _t.setVertexRect(rect);
+ _t._renderCmd._setTextureCoords(rect, needConvert);
+
+ var relativeOffsetX = _t._unflippedOffsetPositionFromCenter.x, relativeOffsetY = _t._unflippedOffsetPositionFromCenter.y;
+ if (_t._flippedX)
+ relativeOffsetX = -relativeOffsetX;
+ if (_t._flippedY)
+ relativeOffsetY = -relativeOffsetY;
+ var locRect = _t._rect;
+ _t._offsetPosition.x = relativeOffsetX + (_t._contentSize.width - locRect.width) / 2;
+ _t._offsetPosition.y = relativeOffsetY + (_t._contentSize.height - locRect.height) / 2;
+ },
+
+ // BatchNode methods
+
+ /**
+ * Add child to sprite (override cc.Node)
+ * @function
+ * @param {cc.Sprite} child
+ * @param {Number} localZOrder child's zOrder
+ * @param {number|String} [tag] child's tag
+ * @override
+ */
+ addChild: function (child, localZOrder, tag) {
+ cc.assert(child, cc._LogInfos.CCSpriteBatchNode_addChild_2);
+
+ if (localZOrder == null)
+ localZOrder = child._localZOrder;
+ if (tag == null)
+ tag = child.tag;
+
+ if (this._renderCmd._setBatchNodeForAddChild(child)) {
+ //cc.Node already sets isReorderChildDirty_ so this needs to be after batchNode check
+ cc.Node.prototype.addChild.call(this, child, localZOrder, tag);
+ this._hasChildren = true;
+ }
+ },
+
+ // Frames
+ /**
+ * Sets a new sprite frame to the sprite.
+ * @function
+ * @param {cc.SpriteFrame|String} newFrame
+ */
+ setSpriteFrame: function (newFrame) {
+ var _t = this;
+ if (typeof newFrame === 'string') {
+ newFrame = cc.spriteFrameCache.getSpriteFrame(newFrame);
+ cc.assert(newFrame, cc._LogInfos.Sprite_setSpriteFrame);
+ }
+ this._loader.clear();
+
+ this.setNodeDirty(true);
+
+ // update rect
+ var pNewTexture = newFrame.getTexture();
+ _t._textureLoaded = newFrame.textureLoaded();
+ this._loader.clear();
+ if (!_t._textureLoaded) {
+ this._loader.once(pNewTexture, function () {
+ this.setSpriteFrame(newFrame);
+ this.dispatchEvent("load");
+ }, this);
+ return false;
+ }
+
+ var frameOffset = newFrame.getOffset();
+ _t._unflippedOffsetPositionFromCenter.x = frameOffset.x;
+ _t._unflippedOffsetPositionFromCenter.y = frameOffset.y;
+
+ if (pNewTexture !== _t._texture) {
+ this._renderCmd._setTexture(pNewTexture);
+ _t.setColor(_t._realColor);
+ }
+ _t.setTextureRect(newFrame.getRect(), newFrame.isRotated(), newFrame.getOriginalSize());
+ },
+
+ /**
+ * Sets a new display frame to the sprite.
+ * @param {cc.SpriteFrame|String} newFrame
+ * @deprecated
+ */
+ setDisplayFrame: function (newFrame) {
+ cc.log(cc._LogInfos.Sprite_setDisplayFrame);
+ this.setSpriteFrame(newFrame);
+ },
+
+ /**
+ * Returns whether or not a cc.SpriteFrame is being displayed
+ * @function
+ * @param {cc.SpriteFrame} frame
+ * @return {Boolean}
+ */
+ isFrameDisplayed: function (frame) {
+ return this._renderCmd.isFrameDisplayed(frame);
+ },
+
+ /**
+ * Returns the current displayed frame.
+ * @deprecated since 3.4, please use getSpriteFrame instead
+ * @return {cc.SpriteFrame}
+ */
+ displayFrame: function () {
+ return this.getSpriteFrame();
+ },
+
+ /**
+ * Returns the current displayed frame.
+ * @return {cc.SpriteFrame}
+ */
+ getSpriteFrame: function () {
+ return new cc.SpriteFrame(this._texture,
+ cc.rectPointsToPixels(this._rect),
+ this._rectRotated,
+ cc.pointPointsToPixels(this._unflippedOffsetPositionFromCenter),
+ cc.sizePointsToPixels(this._contentSize));
+ },
+
+ /**
+ * Sets the batch node to sprite
+ * @function
+ * @param {cc.SpriteBatchNode|null} spriteBatchNode
+ * @example
+ * var batch = new cc.SpriteBatchNode("Images/grossini_dance_atlas.png", 15);
+ * var sprite = new cc.Sprite(batch.texture, cc.rect(0, 0, 57, 57));
+ * batch.addChild(sprite);
+ * layer.addChild(batch);
+ */
+ setBatchNode: function (spriteBatchNode) {
+ },
+
+ // CCTextureProtocol
+ /**
+ * Sets the texture of sprite
+ * @function
+ * @param {cc.Texture2D|String} texture
+ */
+ setTexture: function (texture) {
+ if (!texture)
+ return this._renderCmd._setTexture(null);
+
+ //CCSprite.cpp 327 and 338
+ var isFileName = (typeof texture === 'string');
+
+ if (isFileName)
+ texture = cc.textureCache.addImage(texture);
+
+ this._loader.clear();
+ if (!texture._textureLoaded) {
+ // wait for the load to be set again
+ this._loader.once(texture, function () {
+ this.setTexture(texture);
+ this.dispatchEvent("load");
+ }, this);
+ return false;
+ }
+
+ this._renderCmd._setTexture(texture);
+ if (isFileName)
+ this._changeRectWithTexture(texture);
+ this.setColor(this._realColor);
+ this._textureLoaded = true;
+ },
+
+ _changeRectWithTexture: function (texture) {
+ var contentSize = texture._contentSize;
+ var rect = cc.rect(
+ 0, 0,
+ contentSize.width, contentSize.height
+ );
+ this.setTextureRect(rect);
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.Sprite.CanvasRenderCmd(this);
+ else
+ return new cc.Sprite.WebGLRenderCmd(this);
+ }
+});
+
+/**
+ * Create a sprite with image path or frame name or texture or spriteFrame.
+ * @deprecated since v3.0, please use new construction instead
+ * @see cc.Sprite
+ * @param {String|cc.SpriteFrame|HTMLImageElement|cc.Texture2D} fileName The string which indicates a path to image file, e.g., "scene1/monster.png".
+ * @param {cc.Rect} rect Only the contents inside rect of pszFileName's texture will be applied for this sprite.
+ * @param {Boolean} [rotated] Whether or not the texture rectangle is rotated.
+ * @return {cc.Sprite} A valid sprite object
+ */
+cc.Sprite.create = function (fileName, rect, rotated) {
+ return new cc.Sprite(fileName, rect, rotated);
+};
+
+/**
+ * @deprecated since v3.0, please use new construction instead
+ * @see cc.Sprite
+ * @function
+ */
+cc.Sprite.createWithTexture = cc.Sprite.create;
+
+/**
+ * @deprecated since v3.0, please use new construction instead
+ * @see cc.Sprite
+ * @function
+ */
+cc.Sprite.createWithSpriteFrameName = cc.Sprite.create;
+
+/**
+ * @deprecated since v3.0, please use new construction instead
+ * @see cc.Sprite
+ * @function
+ */
+cc.Sprite.createWithSpriteFrame = cc.Sprite.create;
+/**
+ * cc.Sprite invalid index on the cc.SpriteBatchNode
+ * @constant
+ * @type {Number}
+ */
+cc.Sprite.INDEX_NOT_INITIALIZED = -1;
+
+cc.EventHelper.prototype.apply(cc.Sprite.prototype);
+
+cc.assert(cc.isFunction(cc._tmp.PrototypeSprite), cc._LogInfos.MissingFile, "SpritesPropertyDefine.js");
+cc._tmp.PrototypeSprite();
+delete cc._tmp.PrototypeSprite;
+
+(function () {
+ var manager = cc.Sprite.LoadManager = function () {
+ this.list = [];
+ };
+
+ manager.prototype.add = function (source, callback, target) {
+ if (!source || !source.addEventListener) return;
+ source.addEventListener('load', callback, target);
+ this.list.push({
+ source: source,
+ listener: callback,
+ target: target
+ });
+ };
+ manager.prototype.once = function (source, callback, target) {
+ if (!source || !source.addEventListener) return;
+ var tmpCallback = function (event) {
+ source.removeEventListener('load', tmpCallback, target);
+ callback.call(target, event);
+ };
+ source.addEventListener('load', tmpCallback, target);
+ this.list.push({
+ source: source,
+ listener: tmpCallback,
+ target: target
+ });
+ };
+ manager.prototype.clear = function () {
+ while (this.list.length > 0) {
+ var item = this.list.pop();
+ item.source.removeEventListener('load', item.listener, item.target);
+ }
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteBatchNode.js b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteBatchNode.js
new file mode 100644
index 0000000..3abd61f
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteBatchNode.js
@@ -0,0 +1,438 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+
+/**
+ *
+ * A cc.SpriteBatchNode can reference one and only one texture (one image file, one texture atlas).
+ * Only the cc.Sprites that are contained in that texture can be added to the cc.SpriteBatchNode.
+ * All cc.Sprites added to a cc.SpriteBatchNode are drawn in one WebGL draw call.
+ * If the cc.Sprites are not added to a cc.SpriteBatchNode then an WebGL draw call will be needed for each one, which is less efficient.
+ *
+ * Limitations:
+ * - The only object that is accepted as child (or grandchild, grand-grandchild, etc...) is cc.Sprite or any subclass of cc.Sprite.
+ * eg: particles, labels and layer can't be added to a cc.SpriteBatchNode.
+ * - Either all its children are Aliased or Antialiased. It can't be a mix.
+ * This is because "alias" is a property of the texture, and all the sprites share the same texture.
+ *
+ * @class
+ * @extends cc.Node
+ *
+ * @param {String|cc.Texture2D} fileImage
+ * @example
+ *
+ * // 1. create a SpriteBatchNode with image path
+ * var spriteBatchNode = new cc.SpriteBatchNode("res/animations/grossini.png");
+ *
+ * // 2. create a SpriteBatchNode with texture
+ * var texture = cc.textureCache.addImage("res/animations/grossini.png");
+ * var spriteBatchNode = new cc.SpriteBatchNode(texture);
+ *
+ * @property {cc.TextureAtlas} textureAtlas - The texture atlas
+ * @property {Array} descendants - <@readonly> Descendants of sprite batch node
+ */
+cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{
+ _blendFunc: null,
+ // all descendants: chlidren, gran children, etc...
+ _texture: null,
+ _className: "SpriteBatchNode",
+
+ ctor: function (fileImage) {
+ cc.Node.prototype.ctor.call(this);
+ this._blendFunc = new cc.BlendFunc(cc.BLEND_SRC, cc.BLEND_DST);
+
+ var texture2D;
+ if (cc.isString(fileImage)) {
+ texture2D = cc.textureCache.getTextureForKey(fileImage);
+ if (!texture2D)
+ texture2D = cc.textureCache.addImage(fileImage);
+ } else if (fileImage instanceof cc.Texture2D)
+ texture2D = fileImage;
+
+ texture2D && this.initWithTexture(texture2D);
+ },
+
+ /**
+ *
+ * Same as addChild
+ *
+ * @param {cc.Sprite} child
+ * @param {Number} z zOrder
+ * @param {Number} aTag
+ * @return {cc.SpriteBatchNode}
+ * @deprecated since v3.12
+ */
+ addSpriteWithoutQuad: function (child, z, aTag) {
+ this.addChild(child, z, aTag);
+ return this;
+ },
+
+ // property
+ /**
+ * Return null, no texture atlas is used any more
+ * @return {cc.TextureAtlas}
+ * @deprecated since v3.12
+ */
+ getTextureAtlas: function () {
+ return null;
+ },
+
+ /**
+ * TextureAtlas of cc.SpriteBatchNode setter
+ * @param {cc.TextureAtlas} textureAtlas
+ * @deprecated since v3.12
+ */
+ setTextureAtlas: function (textureAtlas) {
+ },
+
+ /**
+ * Return Descendants of cc.SpriteBatchNode
+ * @return {Array}
+ * @deprecated since v3.12
+ */
+ getDescendants: function () {
+ return this._children;
+ },
+
+ /**
+ *
+ * Initializes a cc.SpriteBatchNode with a file image (.png, .jpeg, .pvr, etc) and a capacity of children.
+ * The capacity will be increased in 33% in runtime if it run out of space.
+ * The file will be loaded using the TextureMgr.
+ * Please pass parameters to constructor to initialize the sprite batch node, do not call this function yourself.
+ *
+ * @param {String} fileImage
+ * @param {Number} capacity
+ * @return {Boolean}
+ */
+ initWithFile: function (fileImage, capacity) {
+ var texture2D = cc.textureCache.getTextureForKey(fileImage);
+ if (!texture2D)
+ texture2D = cc.textureCache.addImage(fileImage);
+ return this.initWithTexture(texture2D, capacity);
+ },
+
+ /**
+ *
+ * initializes a cc.SpriteBatchNode with a file image (.png, .jpeg, .pvr, etc) and a capacity of children.
+ * The capacity will be increased in 33% in runtime if it run out of space.
+ * The file will be loaded using the TextureMgr.
+ * Please pass parameters to constructor to initialize the sprite batch node, do not call this function yourself.
+ *
+ * @param {String} fileImage
+ * @param {Number} capacity
+ * @return {Boolean}
+ */
+ init: function (fileImage, capacity) {
+ var texture2D = cc.textureCache.getTextureForKey(fileImage);
+ if (!texture2D)
+ texture2D = cc.textureCache.addImage(fileImage);
+ return this.initWithTexture(texture2D, capacity);
+ },
+
+ /**
+ * Do nothing
+ * @deprecated since v3.12
+ */
+ increaseAtlasCapacity: function () {
+ },
+
+ /**
+ * Removes a child given a certain index. It will also cleanup the running actions depending on the cleanup parameter.
+ * @warning Removing a child from a cc.SpriteBatchNode is very slow
+ * @param {Number} index
+ * @param {Boolean} doCleanup
+ */
+ removeChildAtIndex: function (index, doCleanup) {
+ this.removeChild(this._children[index], doCleanup);
+ },
+
+ /**
+ * Do nothing
+ * @param {cc.Sprite} pobParent
+ * @param {Number} index
+ * @return {Number}
+ * @deprecated since v3.12
+ */
+ rebuildIndexInOrder: function (pobParent, index) {
+ return index;
+ },
+
+ /**
+ * Returns highest atlas index in child
+ * @param {cc.Sprite} sprite
+ * @return {Number}
+ * @deprecated since v3.12
+ */
+ highestAtlasIndexInChild: function (sprite) {
+ var children = sprite.children;
+ if (!children || children.length === 0)
+ return sprite.zIndex;
+ else
+ return this.highestAtlasIndexInChild(children[children.length - 1]);
+ },
+
+ /**
+ * Returns lowest atlas index in child
+ * @param {cc.Sprite} sprite
+ * @return {Number}
+ * @deprecated since v3.12
+ */
+ lowestAtlasIndexInChild: function (sprite) {
+ var children = sprite.children;
+ if (!children || children.length === 0)
+ return sprite.zIndex;
+ else
+ return this.lowestAtlasIndexInChild(children[children.length - 1]);
+ },
+
+ /**
+ * Returns index for child
+ * @param {cc.Sprite} sprite
+ * @return {Number}
+ * @deprecated since v3.12
+ */
+ atlasIndexForChild: function (sprite) {
+ return sprite.zIndex;
+ },
+
+ /**
+ * Sprites use this to start sortChildren, don't call this manually
+ * @param {Boolean} reorder
+ * @deprecated since v3.12
+ */
+ reorderBatch: function (reorder) {
+ this._reorderChildDirty = reorder;
+ },
+
+ /**
+ * Sets the source and destination blending function for the texture
+ * @param {Number | cc.BlendFunc} src
+ * @param {Number} dst
+ */
+ setBlendFunc: function (src, dst) {
+ if (dst === undefined)
+ this._blendFunc = src;
+ else
+ this._blendFunc = {src: src, dst: dst};
+ },
+
+ /**
+ * Returns the blending function used for the texture
+ * @return {cc.BlendFunc}
+ */
+ getBlendFunc: function () {
+ return new cc.BlendFunc(this._blendFunc.src, this._blendFunc.dst);
+ },
+
+ /**
+ *
+ * Updates a quad at a certain index into the texture atlas. The CCSprite won't be added into the children array.
+ * This method should be called only when you are dealing with very big AtlasSrite and when most of the cc.Sprite won't be updated.
+ * For example: a tile map (cc.TMXMap) or a label with lots of characters (BitmapFontAtlas)
+ *
+ * @function
+ * @param {cc.Sprite} sprite
+ * @param {Number} index
+ */
+ updateQuadFromSprite: function (sprite, index) {
+ cc.assert(sprite, cc._LogInfos.CCSpriteBatchNode_updateQuadFromSprite_2);
+ if (!(sprite instanceof cc.Sprite)) {
+ cc.log(cc._LogInfos.CCSpriteBatchNode_updateQuadFromSprite);
+ return;
+ }
+
+ //
+ // update the quad directly. Don't add the sprite to the scene graph
+ //
+ sprite.dirty = true;
+ // UpdateTransform updates the textureAtlas quad
+ sprite._renderCmd.transform(this._renderCmd, true);
+ },
+
+ /**
+ *
+ * Same as addChild(sprite, index)
+ *
+ * @function
+ * @param {cc.Sprite} sprite
+ * @param {Number} index
+ * @deprecated since v3.12
+ */
+ insertQuadFromSprite: function (sprite, index) {
+ this.addChild(sprite, index);
+ },
+
+ /**
+ * Same as addChild(sprite, index)
+ * @param {cc.Sprite} sprite The child sprite
+ * @param {Number} index The insert index
+ * @deprecated since v3.12
+ */
+ insertChild: function (sprite, index) {
+ this.addChild(sprite, index);
+ },
+
+ /**
+ * Add child at the end
+ * @function
+ * @param {cc.Sprite} sprite
+ */
+ appendChild: function (sprite) {
+ this.sortAllChildren();
+ var lastLocalZOrder = this._children[this._children.length - 1]._localZOrder;
+ this.addChild(sprite.lastLocalZOrder + 1);
+ },
+
+ /**
+ * Same as removeChild
+ * @function
+ * @param {cc.Sprite} sprite
+ * @param {Boolean} [cleanup=true] true if all running actions and callbacks on the child node will be cleanup, false otherwise.
+ * @deprecated since v3.12
+ */
+ removeSpriteFromAtlas: function (sprite, cleanup) {
+ this.removeChild(sprite, cleanup);
+ },
+
+ /**
+ * Set the texture property
+ * @function
+ * @param {cc.Texture2D} tex
+ * @return {Boolean}
+ */
+ initWithTexture: function (tex) {
+ this.setTexture(tex);
+ return true;
+ },
+
+ // CCTextureProtocol
+ /**
+ * Returns texture of the sprite batch node
+ * @function
+ * @return {cc.Texture2D}
+ */
+ getTexture: function () {
+ return this._texture;
+ },
+
+ /**
+ * Sets the texture of the sprite batch node.
+ * @function
+ * @param {cc.Texture2D} texture
+ */
+ setTexture: function (texture) {
+ this._texture = texture;
+
+ if (texture._textureLoaded) {
+ var i, children = this._children, len = children.length;
+ for (i = 0; i < len; ++i) {
+ children[i].setTexture(texture);
+ }
+ }
+ else {
+ texture.addEventListener("load", function () {
+ var i, children = this._children, len = children.length;
+ for (i = 0; i < len; ++i) {
+ children[i].setTexture(texture);
+ }
+ }, this);
+ }
+ },
+
+ setShaderProgram: function (newShaderProgram) {
+ this._renderCmd.setShaderProgram(newShaderProgram);
+ var i, children = this._children, len = children.length;
+ for (i = 0; i < len; ++i) {
+ children[i].setShaderProgram(newShaderProgram);
+ }
+ },
+
+ /**
+ * Add child to the sprite batch node (override addChild of cc.Node)
+ * @function
+ * @override
+ * @param {cc.Sprite} child
+ * @param {Number} [zOrder]
+ * @param {Number} [tag]
+ */
+ addChild: function (child, zOrder, tag) {
+ cc.assert(child !== undefined, cc._LogInfos.CCSpriteBatchNode_addChild_3);
+
+ if (!this._isValidChild(child))
+ return;
+
+ zOrder = (zOrder === undefined) ? child.zIndex : zOrder;
+ tag = (tag === undefined) ? child.tag : tag;
+ cc.Node.prototype.addChild.call(this, child, zOrder, tag);
+
+ // Apply shader
+ if (this._renderCmd._shaderProgram) {
+ child.shaderProgram = this._renderCmd._shaderProgram;
+ }
+ },
+
+ _isValidChild: function (child) {
+ if (!(child instanceof cc.Sprite)) {
+ cc.log(cc._LogInfos.Sprite_addChild_4);
+ return false;
+ }
+ if (child.texture !== this._texture) {
+ cc.log(cc._LogInfos.Sprite_addChild_5);
+ return false;
+ }
+ return true;
+ }
+});
+
+var _p = cc.SpriteBatchNode.prototype;
+
+// Override properties
+cc.defineGetterSetter(_p, "texture", _p.getTexture, _p.setTexture);
+cc.defineGetterSetter(_p, "shaderProgram", _p.getShaderProgram, _p.setShaderProgram);
+
+
+/**
+ *
+ * creates a cc.SpriteBatchNodeCanvas with a file image (.png, .jpg etc) with a default capacity of 29 children.
+ * The capacity will be increased in 33% in runtime if it run out of space.
+ * The file will be loaded using the TextureMgr.
+ *
+ * @deprecated since v3.0, please use new construction instead
+ * @see cc.SpriteBatchNode
+ * @param {String|cc.Texture2D} fileImage
+ * @return {cc.SpriteBatchNode}
+ */
+cc.SpriteBatchNode.create = function (fileImage) {
+ return new cc.SpriteBatchNode(fileImage);
+};
+
+/**
+ * @deprecated since v3.0, please use new construction instead
+ * @see cc.SpriteBatchNode
+ * @function
+ */
+cc.SpriteBatchNode.createWithTexture = cc.SpriteBatchNode.create;
diff --git a/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js
new file mode 100644
index 0000000..87da260
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js
@@ -0,0 +1,251 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ cc.Sprite.CanvasRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._needDraw = true;
+ this._textureCoord = {
+ renderX: 0, //the x of texture coordinate for render, when texture tinted, its value doesn't equal x.
+ renderY: 0, //the y of texture coordinate for render, when texture tinted, its value doesn't equal y.
+ x: 0, //the x of texture coordinate for node.
+ y: 0, //the y of texture coordinate for node.
+ width: 0,
+ height: 0,
+ validRect: false
+ };
+ this._blendFuncStr = "source-over";
+ this._colorized = false;
+ this._canUseDirtyRegion = true;
+ this._textureToRender = null;
+ };
+
+ var proto = cc.Sprite.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ proto.constructor = cc.Sprite.CanvasRenderCmd;
+ proto._spriteCmdCtor = cc.Sprite.CanvasRenderCmd;
+
+ proto.setDirtyRecursively = function (value) {
+ };
+
+ proto._setTexture = function (texture) {
+ var node = this._node;
+ if (node._texture !== texture) {
+ node._textureLoaded = texture ? texture._textureLoaded : false;
+ node._texture = texture;
+
+ var texSize = texture._contentSize;
+ var rect = cc.rect(0, 0, texSize.width, texSize.height);
+ node.setTextureRect(rect);
+ this._updateColor();
+ }
+ };
+
+ proto._setColorDirty = function () {
+ this.setDirtyFlag(cc.Node._dirtyFlags.colorDirty | cc.Node._dirtyFlags.opacityDirty);
+ };
+
+ proto.isFrameDisplayed = function (frame) { //TODO there maybe has a bug
+ var node = this._node;
+ if (frame.getTexture() !== node._texture)
+ return false;
+ return cc.rectEqualToRect(frame.getRect(), node._rect);
+ };
+
+ proto.updateBlendFunc = function (blendFunc) {
+ this._blendFuncStr = cc.Node.CanvasRenderCmd._getCompositeOperationByBlendFunc(blendFunc);
+ };
+
+ proto._setBatchNodeForAddChild = function (child) {
+ return true;
+ };
+
+ proto._handleTextureForRotatedTexture = function (texture, rect, rotated, counterclockwise) {
+ if (rotated && texture.isLoaded()) {
+ var tempElement = texture.getHtmlElementObj();
+ tempElement = cc.Sprite.CanvasRenderCmd._cutRotateImageToCanvas(tempElement, rect, counterclockwise);
+ var tempTexture = new cc.Texture2D();
+ tempTexture.initWithElement(tempElement);
+ tempTexture.handleLoadedTexture();
+ texture = tempTexture;
+ rect.x = rect.y = 0;
+ this._node._rect = cc.rect(0, 0, rect.width, rect.height);
+ }
+ return texture;
+ };
+
+ proto._checkTextureBoundary = function (texture, rect, rotated) {
+ if (texture && texture.url) {
+ var _x = rect.x + rect.width, _y = rect.y + rect.height;
+ if (_x > texture.width)
+ cc.error(cc._LogInfos.RectWidth, texture.url);
+ if (_y > texture.height)
+ cc.error(cc._LogInfos.RectHeight, texture.url);
+ }
+ };
+
+ proto.rendering = function (ctx, scaleX, scaleY) {
+ var node = this._node;
+ var locTextureCoord = this._textureCoord, alpha = (this._displayedOpacity / 255);
+ var texture = this._textureToRender || node._texture;
+
+ if ((texture && (locTextureCoord.width === 0 || locTextureCoord.height === 0 || !texture._textureLoaded)) || alpha === 0)
+ return;
+
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext();
+ var locX = node._offsetPosition.x, locHeight = node._rect.height, locWidth = node._rect.width,
+ locY = -node._offsetPosition.y - locHeight, image;
+
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+ wrapper.setCompositeOperation(this._blendFuncStr);
+ wrapper.setGlobalAlpha(alpha);
+
+ if (node._flippedX || node._flippedY)
+ wrapper.save();
+ if (node._flippedX) {
+ locX = -locX - locWidth;
+ context.scale(-1, 1);
+ }
+ if (node._flippedY) {
+ locY = node._offsetPosition.y;
+ context.scale(1, -1);
+ }
+
+ var sx, sy, sw, sh, x, y, w, h;
+ if (this._colorized) {
+ sx = 0;
+ sy = 0;
+ } else {
+ sx = locTextureCoord.renderX;
+ sy = locTextureCoord.renderY;
+ }
+ sw = locTextureCoord.width;
+ sh = locTextureCoord.height;
+
+ x = locX;
+ y = locY;
+ w = locWidth;
+ h = locHeight;
+
+ if (texture && texture._htmlElementObj) {
+ image = texture._htmlElementObj;
+ if (texture._pattern !== "") {
+ wrapper.setFillStyle(context.createPattern(image, texture._pattern));
+ context.fillRect(x, y, w, h);
+ } else {
+ context.drawImage(image,
+ sx, sy, sw, sh,
+ x, y, w, h);
+ }
+ } else {
+ var contentSize = node._contentSize;
+ if (locTextureCoord.validRect) {
+ var curColor = this._displayedColor;
+ wrapper.setFillStyle("rgba(" + curColor.r + "," + curColor.g + "," + curColor.b + ",1)");
+ context.fillRect(x, y, contentSize.width * scaleX, contentSize.height * scaleY);
+ }
+ }
+ if (node._flippedX || node._flippedY)
+ wrapper.restore();
+ cc.g_NumberOfDraws++;
+ };
+
+ proto._updateColor = function () {
+ var node = this._node;
+
+ var texture = node._texture, rect = this._textureCoord;
+ var dColor = this._displayedColor;
+
+ if (texture) {
+ if (dColor.r !== 255 || dColor.g !== 255 || dColor.b !== 255) {
+ this._textureToRender = texture._generateColorTexture(dColor.r, dColor.g, dColor.b, rect);
+ this._colorized = true;
+ } else if (texture) {
+ this._textureToRender = texture;
+ this._colorized = false;
+ }
+ }
+ };
+
+ proto._textureLoadedCallback = function (sender) {
+ var node = this;
+ if (node._textureLoaded)
+ return;
+
+ node._textureLoaded = true;
+ var locRect = node._rect, locRenderCmd = this._renderCmd;
+ if (!locRect) {
+ locRect = cc.rect(0, 0, sender.width, sender.height);
+ } else if (cc._rectEqualToZero(locRect)) {
+ locRect.width = sender.width;
+ locRect.height = sender.height;
+ }
+
+ node.texture = sender;
+ node.setTextureRect(locRect, node._rectRotated);
+
+ //set the texture's color after the it loaded
+ var locColor = locRenderCmd._displayedColor;
+ if (locColor.r !== 255 || locColor.g !== 255 || locColor.b !== 255)
+ locRenderCmd._updateColor();
+
+ // by default use "Self Render".
+ // if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render"
+ node.setBatchNode(node._batchNode);
+ node.dispatchEvent("load");
+ };
+
+ proto._setTextureCoords = function (rect, needConvert) {
+ if (needConvert === undefined)
+ needConvert = true;
+ var locTextureRect = this._textureCoord,
+ scaleFactor = needConvert ? cc.contentScaleFactor() : 1;
+ locTextureRect.renderX = locTextureRect.x = 0 | (rect.x * scaleFactor);
+ locTextureRect.renderY = locTextureRect.y = 0 | (rect.y * scaleFactor);
+ locTextureRect.width = 0 | (rect.width * scaleFactor);
+ locTextureRect.height = 0 | (rect.height * scaleFactor);
+ locTextureRect.validRect = !(locTextureRect.width === 0 || locTextureRect.height === 0 || locTextureRect.x < 0 || locTextureRect.y < 0);
+ };
+
+ cc.Sprite.CanvasRenderCmd._cutRotateImageToCanvas = function (texture, rect, counterclockwise) {
+ if (!texture)
+ return null;
+
+ if (!rect)
+ return texture;
+
+ counterclockwise = counterclockwise == null ? true : counterclockwise; // texture package is counterclockwise, spine is clockwise
+
+ var nCanvas = document.createElement("canvas");
+ nCanvas.width = rect.width;
+ nCanvas.height = rect.height;
+ var ctx = nCanvas.getContext("2d");
+ ctx.translate(nCanvas.width / 2, nCanvas.height / 2);
+ if (counterclockwise)
+ ctx.rotate(-1.5707963267948966);
+ else
+ ctx.rotate(1.5707963267948966);
+ ctx.drawImage(texture, rect.x, rect.y, rect.height, rect.width, -rect.height / 2, -rect.width / 2, rect.height, rect.width);
+ return nCanvas;
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteFrame.js b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteFrame.js
new file mode 100644
index 0000000..4879225
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteFrame.js
@@ -0,0 +1,420 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ *
+ * A cc.SpriteFrame has:
+ * - texture: A cc.Texture2D that will be used by the cc.Sprite
+ * - rectangle: A rectangle of the texture
+ *
+ * You can modify the frame of a cc.Sprite by doing:
+ *
+ * @class
+ * @extends cc.Class
+ *
+ * @param {String|cc.Texture2D} filename
+ * @param {cc.Rect} rect If parameters' length equal 2, rect in points, else rect in pixels
+ * @param {Boolean} [rotated] Whether the frame is rotated in the texture
+ * @param {cc.Point} [offset] The offset of the frame in the texture
+ * @param {cc.Size} [originalSize] The size of the frame in the texture
+ *
+ * @example
+ * // 1. Create a cc.SpriteFrame with image path
+ * var frame1 = new cc.SpriteFrame("res/grossini_dance.png",cc.rect(0,0,90,128));
+ * var frame2 = new cc.SpriteFrame("res/grossini_dance.png",cc.rect(0,0,90,128),false,0,cc.size(90,128));
+ *
+ * // 2. Create a cc.SpriteFrame with a texture, rect, rotated, offset and originalSize in pixels.
+ * var texture = cc.textureCache.addImage("res/grossini_dance.png");
+ * var frame1 = new cc.SpriteFrame(texture, cc.rect(0,0,90,128));
+ * var frame2 = new cc.SpriteFrame(texture, cc.rect(0,0,90,128),false,0,cc.size(90,128));
+ */
+cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{
+ _offset: null,
+ _originalSize: null,
+ _rectInPixels: null,
+ _rotated: false,
+ _rect: null,
+ _offsetInPixels: null,
+ _originalSizeInPixels: null,
+ _texture: null,
+ _textureFilename: "",
+ _textureLoaded: false,
+
+ ctor: function (filename, rect, rotated, offset, originalSize) {
+ this._offset = cc.p(0, 0);
+ this._offsetInPixels = cc.p(0, 0);
+ this._originalSize = cc.size(0, 0);
+ this._rotated = false;
+ this._originalSizeInPixels = cc.size(0, 0);
+ this._textureFilename = "";
+ this._texture = null;
+ this._textureLoaded = false;
+
+ if (filename !== undefined && rect !== undefined) {
+ if (rotated === undefined || offset === undefined || originalSize === undefined)
+ this.initWithTexture(filename, rect);
+ else
+ this.initWithTexture(filename, rect, rotated, offset, originalSize);
+ }
+ },
+
+ /**
+ * Returns whether the texture have been loaded
+ * @returns {boolean}
+ */
+ textureLoaded: function () {
+ return this._textureLoaded;
+ },
+
+ /**
+ * Add a event listener for texture loaded event.
+ * @param {Function} callback
+ * @param {Object} target
+ * @deprecated since 3.1, please use addEventListener instead
+ */
+ addLoadedEventListener: function (callback, target) {
+ this.addEventListener("load", callback, target);
+ },
+
+ /**
+ * Gets the rect of the frame in the texture
+ * @return {cc.Rect}
+ */
+ getRectInPixels: function () {
+ var locRectInPixels = this._rectInPixels;
+ return cc.rect(locRectInPixels.x, locRectInPixels.y, locRectInPixels.width, locRectInPixels.height);
+ },
+
+ /**
+ * Sets the rect of the frame in the texture
+ * @param {cc.Rect} rectInPixels
+ */
+ setRectInPixels: function (rectInPixels) {
+ if (!this._rectInPixels) {
+ this._rectInPixels = cc.rect(0, 0, 0, 0);
+ }
+ this._rectInPixels.x = rectInPixels.x;
+ this._rectInPixels.y = rectInPixels.y;
+ this._rectInPixels.width = rectInPixels.width;
+ this._rectInPixels.height = rectInPixels.height;
+ this._rect = cc.rectPixelsToPoints(rectInPixels);
+ },
+
+ /**
+ * Returns whether the sprite frame is rotated in the texture.
+ * @return {Boolean}
+ */
+ isRotated: function () {
+ return this._rotated;
+ },
+
+ /**
+ * Set whether the sprite frame is rotated in the texture.
+ * @param {Boolean} bRotated
+ */
+ setRotated: function (bRotated) {
+ this._rotated = bRotated;
+ },
+
+ /**
+ * Returns the rect of the sprite frame in the texture
+ * @return {cc.Rect}
+ */
+ getRect: function () {
+ var locRect = this._rect;
+ return cc.rect(locRect.x, locRect.y, locRect.width, locRect.height);
+ },
+
+ /**
+ * Sets the rect of the sprite frame in the texture
+ * @param {cc.Rect} rect
+ */
+ setRect: function (rect) {
+ if (!this._rect) {
+ this._rect = cc.rect(0, 0, 0, 0);
+ }
+ this._rect.x = rect.x;
+ this._rect.y = rect.y;
+ this._rect.width = rect.width;
+ this._rect.height = rect.height;
+ this._rectInPixels = cc.rectPointsToPixels(this._rect);
+ },
+
+ /**
+ * Returns the offset of the sprite frame in the texture in pixel
+ * @return {cc.Point}
+ */
+ getOffsetInPixels: function () {
+ return cc.p(this._offsetInPixels);
+ },
+
+ /**
+ * Sets the offset of the sprite frame in the texture in pixel
+ * @param {cc.Point} offsetInPixels
+ */
+ setOffsetInPixels: function (offsetInPixels) {
+ this._offsetInPixels.x = offsetInPixels.x;
+ this._offsetInPixels.y = offsetInPixels.y;
+ cc._pointPixelsToPointsOut(this._offsetInPixels, this._offset);
+ },
+
+ /**
+ * Returns the original size of the trimmed image
+ * @return {cc.Size}
+ */
+ getOriginalSizeInPixels: function () {
+ return cc.size(this._originalSizeInPixels);
+ },
+
+ /**
+ * Sets the original size of the trimmed image
+ * @param {cc.Size} sizeInPixels
+ */
+ setOriginalSizeInPixels: function (sizeInPixels) {
+ this._originalSizeInPixels.width = sizeInPixels.width;
+ this._originalSizeInPixels.height = sizeInPixels.height;
+ },
+
+ /**
+ * Returns the original size of the trimmed image
+ * @return {cc.Size}
+ */
+ getOriginalSize: function () {
+ return cc.size(this._originalSize);
+ },
+
+ /**
+ * Sets the original size of the trimmed image
+ * @param {cc.Size} sizeInPixels
+ */
+ setOriginalSize: function (sizeInPixels) {
+ this._originalSize.width = sizeInPixels.width;
+ this._originalSize.height = sizeInPixels.height;
+ },
+
+ /**
+ * Returns the texture of the frame
+ * @return {cc.Texture2D}
+ */
+ getTexture: function () {
+ if (this._texture)
+ return this._texture;
+ if (this._textureFilename !== "") {
+ var locTexture = cc.textureCache.addImage(this._textureFilename);
+ if (locTexture)
+ this._textureLoaded = locTexture.isLoaded();
+ return locTexture;
+ }
+ return null;
+ },
+
+ /**
+ * Sets the texture of the frame, the texture is retained automatically
+ * @param {cc.Texture2D} texture
+ */
+ setTexture: function (texture) {
+ if (this._texture !== texture) {
+ var locLoaded = texture.isLoaded();
+ this._textureLoaded = locLoaded;
+ this._texture = texture;
+ if (!locLoaded) {
+ texture.addEventListener("load", function (sender) {
+ this._textureLoaded = true;
+ if (this._rotated && cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
+ var tempElement = sender.getHtmlElementObj();
+ tempElement = cc.Sprite.CanvasRenderCmd._cutRotateImageToCanvas(tempElement, this.getRect());
+ var tempTexture = new cc.Texture2D();
+ tempTexture.initWithElement(tempElement);
+ tempTexture.handleLoadedTexture();
+ this.setTexture(tempTexture);
+
+ var rect = this.getRect();
+ this.setRect(cc.rect(0, 0, rect.width, rect.height));
+ }
+ var locRect = this._rect;
+ if (locRect.width === 0 && locRect.height === 0) {
+ var w = sender.width, h = sender.height;
+ this._rect.width = w;
+ this._rect.height = h;
+ this._rectInPixels = cc.rectPointsToPixels(this._rect);
+ this._originalSizeInPixels.width = this._rectInPixels.width;
+ this._originalSizeInPixels.height = this._rectInPixels.height;
+ this._originalSize.width = w;
+ this._originalSize.height = h;
+ }
+ //dispatch 'load' event of cc.SpriteFrame
+ this.dispatchEvent("load");
+ }, this);
+ }
+ }
+ },
+
+ /**
+ * Returns the offset of the frame in the texture
+ * @return {cc.Point}
+ */
+ getOffset: function () {
+ return cc.p(this._offset);
+ },
+
+ /**
+ * Sets the offset of the frame in the texture
+ * @param {cc.Point} offsets
+ */
+ setOffset: function (offsets) {
+ this._offset.x = offsets.x;
+ this._offset.y = offsets.y;
+ },
+
+ /**
+ * Clone the sprite frame
+ * @returns {SpriteFrame}
+ */
+ clone: function () {
+ var frame = new cc.SpriteFrame();
+ frame.initWithTexture(this._textureFilename, this._rectInPixels, this._rotated, this._offsetInPixels, this._originalSizeInPixels);
+ frame.setTexture(this._texture);
+ return frame;
+ },
+
+ /**
+ * Copy the sprite frame
+ * @return {cc.SpriteFrame}
+ */
+ copyWithZone: function () {
+ var copy = new cc.SpriteFrame();
+ copy.initWithTexture(this._textureFilename, this._rectInPixels, this._rotated, this._offsetInPixels, this._originalSizeInPixels);
+ copy.setTexture(this._texture);
+ return copy;
+ },
+
+ /**
+ * Copy the sprite frame
+ * @returns {cc.SpriteFrame}
+ */
+ copy: function () {
+ return this.copyWithZone();
+ },
+
+ /**
+ * Initializes SpriteFrame with Texture, rect, rotated, offset and originalSize in pixels.
+ * Please pass parameters to the constructor to initialize the sprite, do not call this function yourself.
+ * @param {String|cc.Texture2D} texture
+ * @param {cc.Rect} rect if parameters' length equal 2, rect in points, else rect in pixels
+ * @param {Boolean} [rotated=false]
+ * @param {cc.Point} [offset=cc.p(0,0)]
+ * @param {cc.Size} [originalSize=rect.size]
+ * @return {Boolean}
+ */
+ initWithTexture: function (texture, rect, rotated, offset, originalSize) {
+ if (arguments.length === 2)
+ rect = cc.rectPointsToPixels(rect);
+
+ offset = offset || cc.p(0, 0);
+ originalSize = originalSize || rect;
+ rotated = rotated || false;
+
+ if (typeof texture === 'string') {
+ this._texture = null;
+ this._textureFilename = texture;
+ } else if (texture instanceof cc.Texture2D) {
+ this.setTexture(texture);
+ }
+
+ texture = this.getTexture();
+
+ this._rectInPixels = rect;
+ this._rect = cc.rectPixelsToPoints(rect);
+
+ if (texture && texture.url && texture.isLoaded()) {
+ var _x, _y;
+ if (rotated) {
+ _x = rect.x + rect.height;
+ _y = rect.y + rect.width;
+ } else {
+ _x = rect.x + rect.width;
+ _y = rect.y + rect.height;
+ }
+ if (_x > texture.getPixelsWide()) {
+ cc.error(cc._LogInfos.RectWidth, texture.url);
+ }
+ if (_y > texture.getPixelsHigh()) {
+ cc.error(cc._LogInfos.RectHeight, texture.url);
+ }
+ }
+
+ this._offsetInPixels.x = offset.x;
+ this._offsetInPixels.y = offset.y;
+ cc._pointPixelsToPointsOut(offset, this._offset);
+ this._originalSizeInPixels.width = originalSize.width;
+ this._originalSizeInPixels.height = originalSize.height;
+ cc._sizePixelsToPointsOut(originalSize, this._originalSize);
+ this._rotated = rotated;
+ return true;
+ }
+});
+
+cc.EventHelper.prototype.apply(cc.SpriteFrame.prototype);
+
+/**
+ *
+ * Create a cc.SpriteFrame with a texture filename, rect, rotated, offset and originalSize in pixels.
+ * The originalSize is the size in pixels of the frame before being trimmed.
+ *
+ * @deprecated since v3.0, please use new construction instead
+ * @see cc.SpriteFrame
+ * @param {String|cc.Texture2D} filename
+ * @param {cc.Rect} rect if parameters' length equal 2, rect in points, else rect in pixels
+ * @param {Boolean} rotated
+ * @param {cc.Point} offset
+ * @param {cc.Size} originalSize
+ * @return {cc.SpriteFrame}
+ */
+cc.SpriteFrame.create = function (filename, rect, rotated, offset, originalSize) {
+ return new cc.SpriteFrame(filename, rect, rotated, offset, originalSize);
+};
+
+/**
+ * @deprecated since v3.0, please use new construction instead
+ * @see cc.SpriteFrame
+ * @function
+ */
+cc.SpriteFrame.createWithTexture = cc.SpriteFrame.create;
+
+cc.SpriteFrame._frameWithTextureForCanvas = function (texture, rect, rotated, offset, originalSize) {
+ var spriteFrame = new cc.SpriteFrame();
+ spriteFrame._texture = texture;
+ spriteFrame._rectInPixels = rect;
+ spriteFrame._rect = cc.rectPixelsToPoints(rect);
+ spriteFrame._offsetInPixels.x = offset.x;
+ spriteFrame._offsetInPixels.y = offset.y;
+ cc._pointPixelsToPointsOut(spriteFrame._offsetInPixels, spriteFrame._offset);
+ spriteFrame._originalSizeInPixels.width = originalSize.width;
+ spriteFrame._originalSizeInPixels.height = originalSize.height;
+ cc._sizePixelsToPointsOut(spriteFrame._originalSizeInPixels, spriteFrame._originalSize);
+ spriteFrame._rotated = rotated;
+ return spriteFrame;
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteFrameCache.js b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteFrameCache.js
new file mode 100644
index 0000000..7d38e89
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteFrameCache.js
@@ -0,0 +1,360 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ *
+ * cc.spriteFrameCache is a singleton that handles the loading of the sprite frames. It saves in a cache the sprite frames.
+ *
+ * example
+ * // add SpriteFrames to spriteFrameCache With File
+ * cc.spriteFrameCache.addSpriteFrames(s_grossiniPlist);
+ *
+ * @class
+ * @name cc.spriteFrameCache
+ */
+cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{
+ _CCNS_REG1: /^\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*$/,
+ _CCNS_REG2: /^\s*\{\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*,\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*\}\s*$/,
+
+ _spriteFrames: {},
+ _spriteFramesAliases: {},
+ _frameConfigCache: {},
+
+ _rectFromString: function (content) {
+ var result = this._CCNS_REG2.exec(content);
+ if (!result) return cc.rect(0, 0, 0, 0);
+ return cc.rect(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]), parseFloat(result[4]));
+ },
+
+ _pointFromString: function (content) {
+ var result = this._CCNS_REG1.exec(content);
+ if (!result) return cc.p(0, 0);
+ return cc.p(parseFloat(result[1]), parseFloat(result[2]));
+ },
+
+ _sizeFromString: function (content) {
+ var result = this._CCNS_REG1.exec(content);
+ if (!result) return cc.size(0, 0);
+ return cc.size(parseFloat(result[1]), parseFloat(result[2]));
+ },
+
+ _getFrameConfig: function (url) {
+ var dict = cc.loader.getRes(url);
+
+ cc.assert(dict, cc._LogInfos.spriteFrameCache__getFrameConfig_2, url);
+
+ cc.loader.release(url);//release it in loader
+ if (dict._inited) {
+ this._frameConfigCache[url] = dict;
+ return dict;
+ }
+ this._frameConfigCache[url] = this._parseFrameConfig(dict);
+ return this._frameConfigCache[url];
+ },
+
+ _getFrameConfigByJsonObject: function (url, jsonObject) {
+ cc.assert(jsonObject, cc._LogInfos.spriteFrameCache__getFrameConfig_2, url);
+ this._frameConfigCache[url] = this._parseFrameConfig(jsonObject);
+ return this._frameConfigCache[url];
+ },
+
+ _parseFrameConfig: function (dict) {
+ var tempFrames = dict["frames"], tempMeta = dict["metadata"] || dict["meta"];
+ var frames = {}, meta = {};
+ var format = 0;
+ if (tempMeta) {//init meta
+ var tmpFormat = tempMeta["format"];
+ format = (tmpFormat.length <= 1) ? parseInt(tmpFormat) : tmpFormat;
+ meta.image = tempMeta["textureFileName"] || tempMeta["textureFileName"] || tempMeta["image"];
+ }
+ for (var key in tempFrames) {
+ var frameDict = tempFrames[key];
+ if (!frameDict) continue;
+ var tempFrame = {};
+
+ if (format == 0) {
+ tempFrame.rect = cc.rect(frameDict["x"], frameDict["y"], frameDict["width"], frameDict["height"]);
+ tempFrame.rotated = false;
+ tempFrame.offset = cc.p(frameDict["offsetX"], frameDict["offsetY"]);
+ var ow = frameDict["originalWidth"];
+ var oh = frameDict["originalHeight"];
+ // check ow/oh
+ if (!ow || !oh) {
+ cc.log(cc._LogInfos.spriteFrameCache__getFrameConfig);
+ }
+ // Math.abs ow/oh
+ ow = Math.abs(ow);
+ oh = Math.abs(oh);
+ tempFrame.size = cc.size(ow, oh);
+ } else if (format == 1 || format == 2) {
+ tempFrame.rect = this._rectFromString(frameDict["frame"]);
+ tempFrame.rotated = frameDict["rotated"] || false;
+ tempFrame.offset = this._pointFromString(frameDict["offset"]);
+ tempFrame.size = this._sizeFromString(frameDict["sourceSize"]);
+ } else if (format == 3) {
+ // get values
+ var spriteSize = this._sizeFromString(frameDict["spriteSize"]);
+ var textureRect = this._rectFromString(frameDict["textureRect"]);
+ if (spriteSize) {
+ textureRect = cc.rect(textureRect.x, textureRect.y, spriteSize.width, spriteSize.height);
+ }
+ tempFrame.rect = textureRect;
+ tempFrame.rotated = frameDict["textureRotated"] || false; // == "true";
+ tempFrame.offset = this._pointFromString(frameDict["spriteOffset"]);
+ tempFrame.size = this._sizeFromString(frameDict["spriteSourceSize"]);
+ tempFrame.aliases = frameDict["aliases"];
+ } else {
+ var tmpFrame = frameDict["frame"], tmpSourceSize = frameDict["sourceSize"];
+ key = frameDict["filename"] || key;
+ tempFrame.rect = cc.rect(tmpFrame["x"], tmpFrame["y"], tmpFrame["w"], tmpFrame["h"]);
+ tempFrame.rotated = frameDict["rotated"] || false;
+ tempFrame.offset = cc.p(0, 0);
+ tempFrame.size = cc.size(tmpSourceSize["w"], tmpSourceSize["h"]);
+ }
+ frames[key] = tempFrame;
+ }
+ return {_inited: true, frames: frames, meta: meta};
+ },
+
+ // Adds multiple Sprite Frames from a json object. it uses for local web view app.
+ _addSpriteFramesByObject: function (url, jsonObject, texture) {
+ cc.assert(url, cc._LogInfos.spriteFrameCache_addSpriteFrames_2);
+ if (!jsonObject || !jsonObject["frames"])
+ return;
+
+ var frameConfig = this._frameConfigCache[url] || this._getFrameConfigByJsonObject(url, jsonObject);
+ //this._checkConflict(frameConfig); //TODO
+ this._createSpriteFrames(url, frameConfig, texture);
+ },
+
+ _createSpriteFrames: function (url, frameConfig, texture) {
+ var frames = frameConfig.frames, meta = frameConfig.meta;
+ if (!texture) {
+ var texturePath = cc.path.changeBasename(url, meta.image || ".png");
+ texture = cc.textureCache.addImage(texturePath);
+ } else if (texture instanceof cc.Texture2D) {
+ //do nothing
+ } else if (cc.isString(texture)) {//string
+ texture = cc.textureCache.addImage(texture);
+ } else {
+ cc.assert(0, cc._LogInfos.spriteFrameCache_addSpriteFrames_3);
+ }
+
+ //create sprite frames
+ var spAliases = this._spriteFramesAliases, spriteFrames = this._spriteFrames;
+ for (var key in frames) {
+ var frame = frames[key];
+ var spriteFrame = spriteFrames[key];
+ if (!spriteFrame) {
+ spriteFrame = new cc.SpriteFrame(texture, cc.rect(frame.rect), frame.rotated, frame.offset, frame.size);
+ var aliases = frame.aliases;
+ if (aliases) {//set aliases
+ for (var i = 0, li = aliases.length; i < li; i++) {
+ var alias = aliases[i];
+ if (spAliases[alias])
+ cc.log(cc._LogInfos.spriteFrameCache_addSpriteFrames, alias);
+ spAliases[alias] = key;
+ }
+ }
+
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS && spriteFrame.isRotated()) {
+ //clip to canvas
+ var locTexture = spriteFrame.getTexture();
+ if (locTexture.isLoaded()) {
+ var tempElement = spriteFrame.getTexture().getHtmlElementObj();
+ tempElement = cc.Sprite.CanvasRenderCmd._cutRotateImageToCanvas(tempElement, spriteFrame.getRectInPixels());
+ var tempTexture = new cc.Texture2D();
+ tempTexture.initWithElement(tempElement);
+ tempTexture.handleLoadedTexture();
+ spriteFrame.setTexture(tempTexture);
+ spriteFrame.setRotated(false);
+
+ var rect = spriteFrame._rect;
+ spriteFrame.setRect(cc.rect(0, 0, rect.width, rect.height));
+ }
+ }
+ spriteFrames[key] = spriteFrame;
+ }
+ }
+ },
+
+ /**
+ *
+ * Adds multiple Sprite Frames from a plist or json file.
+ * A texture will be loaded automatically. The texture name will composed by replacing the .plist or .json suffix with .png
+ * If you want to use another texture, you should use the addSpriteFrames:texture parameter.
+ *
+ * @param {String} url file path
+ * @param {HTMLImageElement|cc.Texture2D|string} [texture]
+ * @example
+ * // add SpriteFrames to SpriteFrameCache With File
+ * cc.spriteFrameCache.addSpriteFrames(s_grossiniPlist);
+ * cc.spriteFrameCache.addSpriteFrames(s_grossiniJson);
+ */
+ addSpriteFrames: function (url, texture) {
+ cc.assert(url, cc._LogInfos.spriteFrameCache_addSpriteFrames_2);
+
+ //Is it a SpriteFrame plist?
+ var dict = this._frameConfigCache[url] || cc.loader.getRes(url);
+ if (!dict || !dict["frames"])
+ return;
+
+ var frameConfig = this._frameConfigCache[url] || this._getFrameConfig(url);
+ //this._checkConflict(frameConfig); //TODO
+ this._createSpriteFrames(url, frameConfig, texture);
+ },
+
+ // Function to check if frames to add exists already, if so there may be name conflit that must be solved
+ _checkConflict: function (dictionary) {
+ var framesDict = dictionary["frames"];
+
+ for (var key in framesDict) {
+ if (this._spriteFrames[key]) {
+ cc.log(cc._LogInfos.spriteFrameCache__checkConflict, key);
+ }
+ }
+ },
+
+ /**
+ *
+ * Adds an sprite frame with a given name.
+ * If the name already exists, then the contents of the old name will be replaced with the new one.
+ *
+ * @param {cc.SpriteFrame} frame
+ * @param {String} frameName
+ */
+ addSpriteFrame: function (frame, frameName) {
+ this._spriteFrames[frameName] = frame;
+ },
+
+ /**
+ *
+ * Purges the dictionary of loaded sprite frames.
+ * Call this method if you receive the "Memory Warning".
+ * In the short term: it will free some resources preventing your app from being killed.
+ * In the medium term: it will allocate more resources.
+ * In the long term: it will be the same.
+ *
+ */
+ removeSpriteFrames: function () {
+ this._spriteFrames = {};
+ this._spriteFramesAliases = {};
+ },
+
+ /**
+ * Deletes an sprite frame from the sprite frame cache.
+ * @param {String} name
+ */
+ removeSpriteFrameByName: function (name) {
+ // explicit nil handling
+ if (!name) {
+ return;
+ }
+
+ // Is this an alias ?
+ if (this._spriteFramesAliases[name]) {
+ delete(this._spriteFramesAliases[name]);
+ }
+ if (this._spriteFrames[name]) {
+ delete(this._spriteFrames[name]);
+ }
+ // XXX. Since we don't know the .plist file that originated the frame, we must remove all .plist from the cache
+ },
+
+ /**
+ *
+ * Removes multiple Sprite Frames from a plist file.
+ * Sprite Frames stored in this file will be removed.
+ * It is convinient to call this method when a specific texture needs to be removed.
+ *
+ * @param {String} url Plist filename
+ */
+ removeSpriteFramesFromFile: function (url) {
+ var self = this, spriteFrames = self._spriteFrames,
+ aliases = self._spriteFramesAliases, cfg = self._frameConfigCache[url];
+ if (!cfg) return;
+ var frames = cfg.frames;
+ for (var key in frames) {
+ if (spriteFrames[key]) {
+ delete(spriteFrames[key]);
+ for (var alias in aliases) {//remove alias
+ if (aliases[alias] === key) delete aliases[alias];
+ }
+ }
+ }
+ },
+
+ /**
+ *
+ * Removes all Sprite Frames associated with the specified textures.
+ * It is convenient to call this method when a specific texture needs to be removed.
+ *
+ * @param {HTMLImageElement|HTMLCanvasElement|cc.Texture2D} texture
+ */
+ removeSpriteFramesFromTexture: function (texture) {
+ var self = this, spriteFrames = self._spriteFrames, aliases = self._spriteFramesAliases;
+ for (var key in spriteFrames) {
+ var frame = spriteFrames[key];
+ if (frame && (frame.getTexture() === texture)) {
+ delete(spriteFrames[key]);
+ for (var alias in aliases) {//remove alias
+ if (aliases[alias] === key) delete aliases[alias];
+ }
+ }
+ }
+ },
+
+ /**
+ *
+ * Returns an Sprite Frame that was previously added.
+ * If the name is not found it will return nil.
+ * You should retain the returned copy if you are going to use it.
+ *
+ * @param {String} name name of SpriteFrame
+ * @return {cc.SpriteFrame}
+ * @example
+ * //get a SpriteFrame by name
+ * var frame = cc.spriteFrameCache.getSpriteFrame("grossini_dance_01.png");
+ */
+ getSpriteFrame: function (name) {
+ var self = this, frame = self._spriteFrames[name];
+ if (!frame) {
+ // try alias dictionary
+ var key = self._spriteFramesAliases[name];
+ if (key) {
+ frame = self._spriteFrames[key.toString()];
+ if (!frame) delete self._spriteFramesAliases[name];
+ }
+ }
+ return frame;
+ },
+
+ _clear: function () {
+ this._spriteFrames = {};
+ this._spriteFramesAliases = {};
+ this._frameConfigCache = {};
+ }
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js
new file mode 100644
index 0000000..51ea502
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js
@@ -0,0 +1,332 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+//Sprite's WebGL render command
+(function () {
+
+ cc.Sprite.WebGLRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._needDraw = true;
+
+ this._vertices = [
+ {x: 0, y: 0, u: 0, v: 0}, // tl
+ {x: 0, y: 0, u: 0, v: 0}, // bl
+ {x: 0, y: 0, u: 0, v: 0}, // tr
+ {x: 0, y: 0, u: 0, v: 0} // br
+ ];
+ this._color = new Uint32Array(1);
+ this._dirty = false;
+ this._recursiveDirty = false;
+
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR);
+ };
+
+ var proto = cc.Sprite.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ proto.constructor = cc.Sprite.WebGLRenderCmd;
+ proto._spriteCmdCtor = cc.Sprite.WebGLRenderCmd;
+
+ proto.updateBlendFunc = function (blendFunc) {
+ };
+
+ proto.setDirtyFlag = function (dirtyFlag) {
+ cc.Node.WebGLRenderCmd.prototype.setDirtyFlag.call(this, dirtyFlag);
+ this._dirty = true;
+ };
+
+ proto.setDirtyRecursively = function (value) {
+ this._recursiveDirty = value;
+ this._dirty = value;
+ // recursively set dirty
+ var locChildren = this._node._children, child, l = locChildren ? locChildren.length : 0;
+ for (var i = 0; i < l; i++) {
+ child = locChildren[i];
+ (child instanceof cc.Sprite) && child._renderCmd.setDirtyRecursively(value);
+ }
+ };
+
+ proto._setBatchNodeForAddChild = function (child) {
+ var node = this._node;
+ if (node._batchNode) {
+ if (!(child instanceof cc.Sprite)) {
+ cc.log(cc._LogInfos.Sprite_addChild);
+ return false;
+ }
+ if (child.texture._webTextureObj !== node.textureAtlas.texture._webTextureObj)
+ cc.log(cc._LogInfos.Sprite_addChild_2);
+
+ //put it in descendants array of batch node
+ node._batchNode.appendChild(child);
+ if (!node._reorderChildDirty)
+ node._setReorderChildDirtyRecursively();
+ }
+ return true;
+ };
+
+ proto._handleTextureForRotatedTexture = function (texture) {
+ return texture;
+ };
+
+ proto.isFrameDisplayed = function (frame) {
+ var node = this._node;
+ return (cc.rectEqualToRect(frame.getRect(), node._rect) && frame.getTexture().getName() === node._texture.getName()
+ && cc.pointEqualToPoint(frame.getOffset(), node._unflippedOffsetPositionFromCenter));
+ };
+
+ proto._textureLoadedCallback = function (sender) {
+ if (this._textureLoaded)
+ return;
+
+ this._textureLoaded = true;
+ var locRect = this._rect;
+ if (!locRect) {
+ locRect = cc.rect(0, 0, sender.width, sender.height);
+ } else if (cc._rectEqualToZero(locRect)) {
+ locRect.width = sender.width;
+ locRect.height = sender.height;
+ }
+
+ this.texture = sender;
+ this.setTextureRect(locRect, this._rectRotated);
+
+ // by default use "Self Render".
+ // if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render"
+ this.setBatchNode(this._batchNode);
+ this.dispatchEvent("load");
+
+ // Force refresh the render command list
+ cc.renderer.childrenOrderDirty = true;
+ };
+
+ proto._setTextureCoords = function (rect, needConvert) {
+ if (needConvert === undefined)
+ needConvert = true;
+ if (needConvert)
+ rect = cc.rectPointsToPixels(rect);
+ var node = this._node;
+
+ var tex = node._batchNode ? node.textureAtlas.texture : node._texture;
+ var uvs = this._vertices;
+ if (!tex)
+ return;
+
+ var atlasWidth = tex.pixelsWidth;
+ var atlasHeight = tex.pixelsHeight;
+
+ var left, right, top, bottom, tempSwap;
+ if (node._rectRotated) {
+ if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) {
+ left = (2 * rect.x + 1) / (2 * atlasWidth);
+ right = left + (rect.height * 2 - 2) / (2 * atlasWidth);
+ top = (2 * rect.y + 1) / (2 * atlasHeight);
+ bottom = top + (rect.width * 2 - 2) / (2 * atlasHeight);
+ } else {
+ left = rect.x / atlasWidth;
+ right = (rect.x + rect.height) / atlasWidth;
+ top = rect.y / atlasHeight;
+ bottom = (rect.y + rect.width) / atlasHeight;
+ }
+
+ if (node._flippedX) {
+ tempSwap = top;
+ top = bottom;
+ bottom = tempSwap;
+ }
+
+ if (node._flippedY) {
+ tempSwap = left;
+ left = right;
+ right = tempSwap;
+ }
+
+ uvs[0].u = right; // tl
+ uvs[0].v = top; // tl
+ uvs[1].u = left; // bl
+ uvs[1].v = top; // bl
+ uvs[2].u = right; // tr
+ uvs[2].v = bottom; // tr
+ uvs[3].u = left; // br
+ uvs[3].v = bottom; // br
+ } else {
+ if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) {
+ left = (2 * rect.x + 1) / (2 * atlasWidth);
+ right = left + (rect.width * 2 - 2) / (2 * atlasWidth);
+ top = (2 * rect.y + 1) / (2 * atlasHeight);
+ bottom = top + (rect.height * 2 - 2) / (2 * atlasHeight);
+ } else {
+ left = rect.x / atlasWidth;
+ right = (rect.x + rect.width) / atlasWidth;
+ top = rect.y / atlasHeight;
+ bottom = (rect.y + rect.height) / atlasHeight;
+ }
+
+ if (node._flippedX) {
+ tempSwap = left;
+ left = right;
+ right = tempSwap;
+ }
+
+ if (node._flippedY) {
+ tempSwap = top;
+ top = bottom;
+ bottom = tempSwap;
+ }
+
+ uvs[0].u = left; // tl
+ uvs[0].v = top; // tl
+ uvs[1].u = left; // bl
+ uvs[1].v = bottom; // bl
+ uvs[2].u = right; // tr
+ uvs[2].v = top; // tr
+ uvs[3].u = right; // br
+ uvs[3].v = bottom; // br
+ }
+ };
+
+ proto._setColorDirty = function () {
+ };
+
+ proto._updateBlendFunc = function () {
+ if (this._batchNode) {
+ cc.log(cc._LogInfos.Sprite__updateBlendFunc);
+ return;
+ }
+
+ // it's possible to have an untextured sprite
+ var node = this._node,
+ blendFunc = node._blendFunc;
+ if (!node._texture || !node._texture.hasPremultipliedAlpha()) {
+ if (blendFunc.src === cc.ONE && blendFunc.dst === cc.BLEND_DST) {
+ blendFunc.src = cc.SRC_ALPHA;
+ }
+ node.opacityModifyRGB = false;
+ } else {
+ if (blendFunc.src === cc.SRC_ALPHA && blendFunc.dst === cc.BLEND_DST) {
+ blendFunc.src = cc.ONE;
+ }
+ node.opacityModifyRGB = true;
+ }
+ };
+
+ proto._setTexture = function (texture) {
+ var node = this._node;
+ if (node._texture !== texture) {
+ node._textureLoaded = texture ? texture._textureLoaded : false;
+ node._texture = texture;
+
+ // Update texture rect and blend func
+ if (texture) {
+ var texSize = texture._contentSize;
+ var rect = cc.rect(0, 0, texSize.width, texSize.height);
+ node.setTextureRect(rect);
+ this._updateBlendFunc();
+ }
+
+ if (node._textureLoaded) {
+ // Force refresh the render command list
+ cc.renderer.childrenOrderDirty = true;
+ }
+ }
+ };
+
+ proto._checkTextureBoundary = function (texture, rect, rotated) {
+ if (texture && texture.url) {
+ var _x, _y;
+ if (rotated) {
+ _x = rect.x + rect.height;
+ _y = rect.y + rect.width;
+ } else {
+ _x = rect.x + rect.width;
+ _y = rect.y + rect.height;
+ }
+ if (_x > texture.width) {
+ cc.error(cc._LogInfos.RectWidth, texture.url);
+ }
+ if (_y > texture.height) {
+ cc.error(cc._LogInfos.RectHeight, texture.url);
+ }
+ }
+ };
+
+ proto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
+
+ var node = this._node,
+ lx = node._offsetPosition.x, rx = lx + node._rect.width,
+ by = node._offsetPosition.y, ty = by + node._rect.height,
+ wt = this._worldTransform,
+ wtx = wt.tx, wty = wt.ty,
+ lxa = lx * wt.a, lxb = lx * wt.b, rxa = rx * wt.a, rxb = rx * wt.b,
+ tyc = ty * wt.c, tyd = ty * wt.d, byc = by * wt.c, byd = by * wt.d;
+
+ var vertices = this._vertices;
+ vertices[0].x = lxa + tyc + wtx; // tl
+ vertices[0].y = lxb + tyd + wty;
+ vertices[1].x = lxa + byc + wtx; // bl
+ vertices[1].y = lxb + byd + wty;
+ vertices[2].x = rxa + tyc + wtx; // tr
+ vertices[2].y = rxb + tyd + wty;
+ vertices[3].x = rxa + byc + wtx; // br
+ vertices[3].y = rxb + byd + wty;
+ };
+
+ proto.needDraw = function () {
+ var node = this._node, locTexture = node._texture;
+ return (this._needDraw && locTexture);
+ };
+
+ proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset) {
+ var node = this._node, locTexture = node._texture;
+ if (!(locTexture && locTexture._textureLoaded && node._rect.width && node._rect.height) || !this._displayedOpacity)
+ return 0;
+
+ // Fill in vertex data with quad information (4 vertices for sprite)
+ var opacity = this._displayedOpacity;
+ var r = this._displayedColor.r,
+ g = this._displayedColor.g,
+ b = this._displayedColor.b;
+ if (node._opacityModifyRGB) {
+ var a = opacity / 255;
+ r *= a;
+ g *= a;
+ b *= a;
+ }
+ this._color[0] = ((opacity << 24) | (b << 16) | (g << 8) | r);
+ var z = node._vertexZ;
+
+ var vertices = this._vertices;
+ var i, len = vertices.length, vertex, offset = vertexDataOffset;
+ for (i = 0; i < len; ++i) {
+ vertex = vertices[i];
+ f32buffer[offset] = vertex.x;
+ f32buffer[offset + 1] = vertex.y;
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = this._color[0];
+ f32buffer[offset + 4] = vertex.u;
+ f32buffer[offset + 5] = vertex.v;
+ offset += 6;
+ }
+
+ return len;
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/sprites/SpritesPropertyDefine.js b/frameworks/cocos2d-html5/cocos2d/core/sprites/SpritesPropertyDefine.js
new file mode 100644
index 0000000..20e8cc9
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/sprites/SpritesPropertyDefine.js
@@ -0,0 +1,67 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc._tmp.PrototypeSprite = function () {
+ var _p = cc.Sprite.prototype;
+
+ // Override properties
+ cc.defineGetterSetter(_p, "opacityModifyRGB", _p.isOpacityModifyRGB, _p.setOpacityModifyRGB);
+ cc.defineGetterSetter(_p, "opacity", _p.getOpacity, _p.setOpacity);
+ cc.defineGetterSetter(_p, "color", _p.getColor, _p.setColor);
+
+ // Extended properties
+ /** @expose */
+ _p.dirty;
+ /** @expose */
+ _p.flippedX;
+ cc.defineGetterSetter(_p, "flippedX", _p.isFlippedX, _p.setFlippedX);
+ /** @expose */
+ _p.flippedY;
+ cc.defineGetterSetter(_p, "flippedY", _p.isFlippedY, _p.setFlippedY);
+ /** @expose */
+ _p.offsetX;
+ cc.defineGetterSetter(_p, "offsetX", _p._getOffsetX);
+ /** @expose */
+ _p.offsetY;
+ cc.defineGetterSetter(_p, "offsetY", _p._getOffsetY);
+ /** @expose */
+ _p.atlasIndex;
+ /** @expose */
+ _p.texture;
+ cc.defineGetterSetter(_p, "texture", _p.getTexture, _p.setTexture);
+ /** @expose */
+ _p.textureRectRotated;
+ cc.defineGetterSetter(_p, "textureRectRotated", _p.isTextureRectRotated);
+ /** @expose */
+ _p.textureAtlas;
+ /** @expose */
+ _p.batchNode;
+ cc.defineGetterSetter(_p, "batchNode", _p.getBatchNode, _p.setBatchNode);
+ /** @expose */
+ _p.quad;
+ cc.defineGetterSetter(_p, "quad", _p.getQuad);
+
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/core/support/CCPointExtension.js b/frameworks/cocos2d-html5/cocos2d/core/support/CCPointExtension.js
new file mode 100644
index 0000000..3171a5f
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/support/CCPointExtension.js
@@ -0,0 +1,516 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.Point extensions based on Chipmunk's cpVect file.
+ * These extensions work both with cc.Point
+ *
+ * The "ccp" prefix means: "CoCos2d Point"
+ *
+ * //Examples:
+ * - cc.pAdd( cc.p(1,1), cc.p(2,2) ); // preferred cocos2d way
+ * - cc.pAdd( cc.p(1,1), cc.p(2,2) ); // also ok but more verbose
+ * - cc.pAdd( cc.cpv(1,1), cc.cpv(2,2) ); // mixing chipmunk and cocos2d (avoid)
+ */
+
+/**
+ * smallest such that 1.0+FLT_EPSILON != 1.0
+ * @constant
+ * @type Number
+ */
+cc.POINT_EPSILON = parseFloat('1.192092896e-07F');
+
+/**
+ * Returns opposite of point.
+ * @param {cc.Point} point
+ * @return {cc.Point}
+ */
+cc.pNeg = function (point) {
+ return cc.p(-point.x, -point.y);
+};
+
+/**
+ * Calculates sum of two points.
+ * @param {cc.Point} v1
+ * @param {cc.Point} v2
+ * @return {cc.Point}
+ */
+cc.pAdd = function (v1, v2) {
+ return cc.p(v1.x + v2.x, v1.y + v2.y);
+};
+
+/**
+ * Calculates difference of two points.
+ * @param {cc.Point} v1
+ * @param {cc.Point} v2
+ * @return {cc.Point}
+ */
+cc.pSub = function (v1, v2) {
+ return cc.p(v1.x - v2.x, v1.y - v2.y);
+};
+
+/**
+ * Returns point multiplied by given factor.
+ * @param {cc.Point} point
+ * @param {Number} floatVar
+ * @return {cc.Point}
+ */
+cc.pMult = function (point, floatVar) {
+ return cc.p(point.x * floatVar, point.y * floatVar);
+};
+
+/**
+ * Calculates midpoint between two points.
+ * @param {cc.Point} v1
+ * @param {cc.Point} v2
+ * @return {cc.Point}
+ */
+cc.pMidpoint = function (v1, v2) {
+ return cc.pMult(cc.pAdd(v1, v2), 0.5);
+};
+
+/**
+ * Calculates dot product of two points.
+ * @param {cc.Point} v1
+ * @param {cc.Point} v2
+ * @return {Number}
+ */
+cc.pDot = function (v1, v2) {
+ return v1.x * v2.x + v1.y * v2.y;
+};
+
+/**
+ * Calculates cross product of two points.
+ * @param {cc.Point} v1
+ * @param {cc.Point} v2
+ * @return {Number}
+ */
+cc.pCross = function (v1, v2) {
+ return v1.x * v2.y - v1.y * v2.x;
+};
+
+/**
+ * Calculates perpendicular of v, rotated 90 degrees counter-clockwise -- cross(v, perp(v)) >= 0
+ * @param {cc.Point} point
+ * @return {cc.Point}
+ */
+cc.pPerp = function (point) {
+ return cc.p(-point.y, point.x);
+};
+
+/**
+ * Calculates perpendicular of v, rotated 90 degrees clockwise -- cross(v, rperp(v)) <= 0
+ * @param {cc.Point} point
+ * @return {cc.Point}
+ */
+cc.pRPerp = function (point) {
+ return cc.p(point.y, -point.x);
+};
+
+/**
+ * Calculates the projection of v1 over v2.
+ * @param {cc.Point} v1
+ * @param {cc.Point} v2
+ * @return {cc.Point}
+ */
+cc.pProject = function (v1, v2) {
+ return cc.pMult(v2, cc.pDot(v1, v2) / cc.pDot(v2, v2));
+};
+
+/**
+ * Rotates two points.
+ * @param {cc.Point} v1
+ * @param {cc.Point} v2
+ * @return {cc.Point}
+ */
+cc.pRotate = function (v1, v2) {
+ return cc.p(v1.x * v2.x - v1.y * v2.y, v1.x * v2.y + v1.y * v2.x);
+};
+
+/**
+ * Unrotates two points.
+ * @param {cc.Point} v1
+ * @param {cc.Point} v2
+ * @return {cc.Point}
+ */
+cc.pUnrotate = function (v1, v2) {
+ return cc.p(v1.x * v2.x + v1.y * v2.y, v1.y * v2.x - v1.x * v2.y);
+};
+
+/**
+ * Calculates the square length of a cc.Point (not calling sqrt() )
+ * @param {cc.Point} v
+ *@return {Number}
+ */
+cc.pLengthSQ = function (v) {
+ return cc.pDot(v, v);
+};
+
+/**
+ * Calculates the square distance between two points (not calling sqrt() )
+ * @param {cc.Point} point1
+ * @param {cc.Point} point2
+ * @return {Number}
+ */
+cc.pDistanceSQ = function(point1, point2){
+ return cc.pLengthSQ(cc.pSub(point1,point2));
+};
+
+/**
+ * Calculates distance between point an origin
+ * @param {cc.Point} v
+ * @return {Number}
+ */
+cc.pLength = function (v) {
+ return Math.sqrt(cc.pLengthSQ(v));
+};
+
+/**
+ * Calculates the distance between two points
+ * @param {cc.Point} v1
+ * @param {cc.Point} v2
+ * @return {Number}
+ */
+cc.pDistance = function (v1, v2) {
+ return cc.pLength(cc.pSub(v1, v2));
+};
+
+/**
+ * Returns point multiplied to a length of 1.
+ * @param {cc.Point} v
+ * @return {cc.Point}
+ */
+cc.pNormalize = function (v) {
+ var n = cc.pLength(v);
+ return n === 0 ? cc.p(v) : cc.pMult(v, 1.0 / n);
+};
+
+/**
+ * Converts radians to a normalized vector.
+ * @param {Number} a
+ * @return {cc.Point}
+ */
+cc.pForAngle = function (a) {
+ return cc.p(Math.cos(a), Math.sin(a));
+};
+
+/**
+ * Converts a vector to radians.
+ * @param {cc.Point} v
+ * @return {Number}
+ */
+cc.pToAngle = function (v) {
+ return Math.atan2(v.y, v.x);
+};
+
+/**
+ * Clamp a value between from and to.
+ * @param {Number} value
+ * @param {Number} min_inclusive
+ * @param {Number} max_inclusive
+ * @return {Number}
+ */
+cc.clampf = function (value, min_inclusive, max_inclusive) {
+ if (min_inclusive > max_inclusive) {
+ var temp = min_inclusive;
+ min_inclusive = max_inclusive;
+ max_inclusive = temp;
+ }
+ return value < min_inclusive ? min_inclusive : value < max_inclusive ? value : max_inclusive;
+};
+
+/**
+ * Clamp a point between from and to.
+ * @param {Point} p
+ * @param {Number} min_inclusive
+ * @param {Number} max_inclusive
+ * @return {cc.Point}
+ */
+cc.pClamp = function (p, min_inclusive, max_inclusive) {
+ return cc.p(cc.clampf(p.x, min_inclusive.x, max_inclusive.x), cc.clampf(p.y, min_inclusive.y, max_inclusive.y));
+};
+
+/**
+ * Quickly convert cc.Size to a cc.Point
+ * @param {cc.Size} s
+ * @return {cc.Point}
+ */
+cc.pFromSize = function (s) {
+ return cc.p(s.width, s.height);
+};
+
+/**
+ * Run a math operation function on each point component
+ * Math.abs, Math.fllor, Math.ceil, Math.round.
+ * @param {cc.Point} p
+ * @param {Function} opFunc
+ * @return {cc.Point}
+ * @example
+ * //For example: let's try to take the floor of x,y
+ * var p = cc.pCompOp(cc.p(10,10),Math.abs);
+ */
+cc.pCompOp = function (p, opFunc) {
+ return cc.p(opFunc(p.x), opFunc(p.y));
+};
+
+/**
+ * Linear Interpolation between two points a and b
+ * alpha == 0 ? a
+ * alpha == 1 ? b
+ * otherwise a value between a..b
+ * @param {cc.Point} a
+ * @param {cc.Point} b
+ * @param {Number} alpha
+ * @return {cc.Point}
+ */
+cc.pLerp = function (a, b, alpha) {
+ return cc.pAdd(cc.pMult(a, 1 - alpha), cc.pMult(b, alpha));
+};
+
+/**
+ * @param {cc.Point} a
+ * @param {cc.Point} b
+ * @param {Number} variance
+ * @return {Boolean} if points have fuzzy equality which means equal with some degree of variance.
+ */
+cc.pFuzzyEqual = function (a, b, variance) {
+ if (a.x - variance <= b.x && b.x <= a.x + variance) {
+ if (a.y - variance <= b.y && b.y <= a.y + variance)
+ return true;
+ }
+ return false;
+};
+
+/**
+ * Multiplies a nd b components, a.x*b.x, a.y*b.y
+ * @param {cc.Point} a
+ * @param {cc.Point} b
+ * @return {cc.Point}
+ */
+cc.pCompMult = function (a, b) {
+ return cc.p(a.x * b.x, a.y * b.y);
+};
+
+/**
+ * @param {cc.Point} a
+ * @param {cc.Point} b
+ * @return {Number} the signed angle in radians between two vector directions
+ */
+cc.pAngleSigned = function (a, b) {
+ var a2 = cc.pNormalize(a);
+ var b2 = cc.pNormalize(b);
+ var angle = Math.atan2(a2.x * b2.y - a2.y * b2.x, cc.pDot(a2, b2));
+ if (Math.abs(angle) < cc.POINT_EPSILON)
+ return 0.0;
+ return angle;
+};
+
+/**
+ * @param {cc.Point} a
+ * @param {cc.Point} b
+ * @return {Number} the angle in radians between two vector directions
+ */
+cc.pAngle = function (a, b) {
+ var angle = Math.acos(cc.pDot(cc.pNormalize(a), cc.pNormalize(b)));
+ if (Math.abs(angle) < cc.POINT_EPSILON) return 0.0;
+ return angle;
+};
+
+/**
+ * Rotates a point counter clockwise by the angle around a pivot
+ * @param {cc.Point} v v is the point to rotate
+ * @param {cc.Point} pivot pivot is the pivot, naturally
+ * @param {Number} angle angle is the angle of rotation cw in radians
+ * @return {cc.Point} the rotated point
+ */
+cc.pRotateByAngle = function (v, pivot, angle) {
+ var r = cc.pSub(v, pivot);
+ var cosa = Math.cos(angle), sina = Math.sin(angle);
+ var t = r.x;
+ r.x = t * cosa - r.y * sina + pivot.x;
+ r.y = t * sina + r.y * cosa + pivot.y;
+ return r;
+};
+
+/**
+ * A general line-line intersection test
+ * indicating successful intersection of a line
+ * note that to truly test intersection for segments we have to make
+ * sure that s & t lie within [0..1] and for rays, make sure s & t > 0
+ * the hit point is p3 + t * (p4 - p3);
+ * the hit point also is p1 + s * (p2 - p1);
+ * @param {cc.Point} A A is the startpoint for the first line P1 = (p1 - p2).
+ * @param {cc.Point} B B is the endpoint for the first line P1 = (p1 - p2).
+ * @param {cc.Point} C C is the startpoint for the second line P2 = (p3 - p4).
+ * @param {cc.Point} D D is the endpoint for the second line P2 = (p3 - p4).
+ * @param {cc.Point} retP retP.x is the range for a hitpoint in P1 (pa = p1 + s*(p2 - p1)),
+ * retP.y is the range for a hitpoint in P3 (pa = p2 + t*(p4 - p3)).
+ * @return {Boolean}
+ */
+cc.pLineIntersect = function (A, B, C, D, retP) {
+ if ((A.x === B.x && A.y === B.y) || (C.x === D.x && C.y === D.y)) {
+ return false;
+ }
+ var BAx = B.x - A.x;
+ var BAy = B.y - A.y;
+ var DCx = D.x - C.x;
+ var DCy = D.y - C.y;
+ var ACx = A.x - C.x;
+ var ACy = A.y - C.y;
+
+ var denom = DCy * BAx - DCx * BAy;
+
+ retP.x = DCx * ACy - DCy * ACx;
+ retP.y = BAx * ACy - BAy * ACx;
+
+ if (denom === 0) {
+ if (retP.x === 0 || retP.y === 0) {
+ // Lines incident
+ return true;
+ }
+ // Lines parallel and not incident
+ return false;
+ }
+
+ retP.x = retP.x / denom;
+ retP.y = retP.y / denom;
+
+ return true;
+};
+
+/**
+ * ccpSegmentIntersect return YES if Segment A-B intersects with segment C-D.
+ * @param {cc.Point} A
+ * @param {cc.Point} B
+ * @param {cc.Point} C
+ * @param {cc.Point} D
+ * @return {Boolean}
+ */
+cc.pSegmentIntersect = function (A, B, C, D) {
+ var retP = cc.p(0, 0);
+ if (cc.pLineIntersect(A, B, C, D, retP))
+ if (retP.x >= 0.0 && retP.x <= 1.0 && retP.y >= 0.0 && retP.y <= 1.0)
+ return true;
+ return false;
+};
+
+/**
+ * ccpIntersectPoint return the intersection point of line A-B, C-D
+ * @param {cc.Point} A
+ * @param {cc.Point} B
+ * @param {cc.Point} C
+ * @param {cc.Point} D
+ * @return {cc.Point}
+ */
+cc.pIntersectPoint = function (A, B, C, D) {
+ var retP = cc.p(0, 0);
+
+ if (cc.pLineIntersect(A, B, C, D, retP)) {
+ // Point of intersection
+ var P = cc.p(0, 0);
+ P.x = A.x + retP.x * (B.x - A.x);
+ P.y = A.y + retP.x * (B.y - A.y);
+ return P;
+ }
+
+ return cc.p(0,0);
+};
+
+/**
+ * check to see if both points are equal
+ * @param {cc.Point} A A ccp a
+ * @param {cc.Point} B B ccp b to be compared
+ * @return {Boolean} the true if both ccp are same
+ */
+cc.pSameAs = function (A, B) {
+ if ((A != null) && (B != null)) {
+ return (A.x === B.x && A.y === B.y);
+ }
+ return false;
+};
+
+
+
+// High Performance In Place Operationrs ---------------------------------------
+
+/**
+ * sets the position of the point to 0
+ * @param {cc.Point} v
+ */
+cc.pZeroIn = function(v) {
+ v.x = 0;
+ v.y = 0;
+};
+
+/**
+ * copies the position of one point to another
+ * @param {cc.Point} v1
+ * @param {cc.Point} v2
+ */
+cc.pIn = function(v1, v2) {
+ v1.x = v2.x;
+ v1.y = v2.y;
+};
+
+/**
+ * multiplies the point with the given factor (inplace)
+ * @param {cc.Point} point
+ * @param {Number} floatVar
+ */
+cc.pMultIn = function(point, floatVar) {
+ point.x *= floatVar;
+ point.y *= floatVar;
+};
+
+/**
+ * subtracts one point from another (inplace)
+ * @param {cc.Point} v1
+ * @param {cc.Point} v2
+ */
+cc.pSubIn = function(v1, v2) {
+ v1.x -= v2.x;
+ v1.y -= v2.y;
+};
+
+/**
+ * adds one point to another (inplace)
+ * @param {cc.Point} v1
+ * @param {cc.Point} v2
+ */
+cc.pAddIn = function(v1, v2) {
+ v1.x += v2.x;
+ v1.y += v2.y;
+};
+
+/**
+ * normalizes the point (inplace)
+ * @param {cc.Point} v
+ */
+cc.pNormalizeIn = function(v) {
+ var n = Math.sqrt(v.x * v.x + v.y * v.y);
+ if (n !== 0)
+ cc.pMultIn(v, 1.0 / n);
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/core/support/CCVertex.js b/frameworks/cocos2d-html5/cocos2d/core/support/CCVertex.js
new file mode 100644
index 0000000..44b92f0
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/support/CCVertex.js
@@ -0,0 +1,170 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2009 Valentin Milea
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * converts a line to a polygon
+ * @param {Float32Array} points
+ * @param {Number} stroke
+ * @param {Float32Array} vertices
+ * @param {Number} offset
+ * @param {Number} nuPoints
+ */
+cc.vertexLineToPolygon = function (points, stroke, vertices, offset, nuPoints) {
+ nuPoints += offset;
+ if (nuPoints <= 1)
+ return;
+
+ stroke *= 0.5;
+ var idx;
+ var nuPointsMinus = nuPoints - 1;
+ for (var i = offset; i < nuPoints; i++) {
+ idx = i * 2;
+ var p1 = cc.p(points[i * 2], points[i * 2 + 1]);
+ var perpVector;
+
+ if (i === 0)
+ perpVector = cc.pPerp(cc.pNormalize(cc.pSub(p1, cc.p(points[(i + 1) * 2], points[(i + 1) * 2 + 1]))));
+ else if (i === nuPointsMinus)
+ perpVector = cc.pPerp(cc.pNormalize(cc.pSub(cc.p(points[(i - 1) * 2], points[(i - 1) * 2 + 1]), p1)));
+ else {
+ var p0 = cc.p(points[(i - 1) * 2], points[(i - 1) * 2 + 1]);
+ var p2 = cc.p(points[(i + 1) * 2], points[(i + 1) * 2 + 1]);
+
+ var p2p1 = cc.pNormalize(cc.pSub(p2, p1));
+ var p0p1 = cc.pNormalize(cc.pSub(p0, p1));
+
+ // Calculate angle between vectors
+ var angle = Math.acos(cc.pDot(p2p1, p0p1));
+
+ if (angle < cc.degreesToRadians(70))
+ perpVector = cc.pPerp(cc.pNormalize(cc.pMidpoint(p2p1, p0p1)));
+ else if (angle < cc.degreesToRadians(170))
+ perpVector = cc.pNormalize(cc.pMidpoint(p2p1, p0p1));
+ else
+ perpVector = cc.pPerp(cc.pNormalize(cc.pSub(p2, p0)));
+ }
+ perpVector = cc.pMult(perpVector, stroke);
+
+ vertices[idx * 2] = p1.x + perpVector.x;
+ vertices[idx * 2 + 1] = p1.y + perpVector.y;
+ vertices[(idx + 1) * 2] = p1.x - perpVector.x;
+ vertices[(idx + 1) * 2 + 1] = p1.y - perpVector.y;
+ }
+
+ // Validate vertexes
+ offset = (offset === 0) ? 0 : offset - 1;
+ for (i = offset; i < nuPointsMinus; i++) {
+ idx = i * 2;
+ var idx1 = idx + 2;
+
+ var v1 = cc.vertex2(vertices[idx * 2], vertices[idx * 2 + 1]);
+ var v2 = cc.vertex2(vertices[(idx + 1) * 2], vertices[(idx + 1) * 2 + 1]);
+ var v3 = cc.vertex2(vertices[idx1 * 2], vertices[idx1 * 2]);
+ var v4 = cc.vertex2(vertices[(idx1 + 1) * 2], vertices[(idx1 + 1) * 2 + 1]);
+
+ //BOOL fixVertex = !ccpLineIntersect(ccp(p1.x, p1.y), ccp(p4.x, p4.y), ccp(p2.x, p2.y), ccp(p3.x, p3.y), &s, &t);
+ var fixVertexResult = !cc.vertexLineIntersect(v1.x, v1.y, v4.x, v4.y, v2.x, v2.y, v3.x, v3.y);
+ if (!fixVertexResult.isSuccess)
+ if (fixVertexResult.value < 0.0 || fixVertexResult.value > 1.0)
+ fixVertexResult.isSuccess = true;
+
+ if (fixVertexResult.isSuccess) {
+ vertices[idx1 * 2] = v4.x;
+ vertices[idx1 * 2 + 1] = v4.y;
+ vertices[(idx1 + 1) * 2] = v3.x;
+ vertices[(idx1 + 1) * 2 + 1] = v3.y;
+ }
+ }
+};
+
+/**
+ * returns whether or not the line intersects
+ * @param {Number} Ax
+ * @param {Number} Ay
+ * @param {Number} Bx
+ * @param {Number} By
+ * @param {Number} Cx
+ * @param {Number} Cy
+ * @param {Number} Dx
+ * @param {Number} Dy
+ * @return {Object}
+ */
+cc.vertexLineIntersect = function (Ax, Ay, Bx, By, Cx, Cy, Dx, Dy) {
+ var distAB, theCos, theSin, newX;
+
+ // FAIL: Line undefined
+ if ((Ax === Bx && Ay === By) || (Cx === Dx && Cy === Dy))
+ return {isSuccess:false, value:0};
+
+ // Translate system to make A the origin
+ Bx -= Ax;
+ By -= Ay;
+ Cx -= Ax;
+ Cy -= Ay;
+ Dx -= Ax;
+ Dy -= Ay;
+
+ // Length of segment AB
+ distAB = Math.sqrt(Bx * Bx + By * By);
+
+ // Rotate the system so that point B is on the positive X axis.
+ theCos = Bx / distAB;
+ theSin = By / distAB;
+ newX = Cx * theCos + Cy * theSin;
+ Cy = Cy * theCos - Cx * theSin;
+ Cx = newX;
+ newX = Dx * theCos + Dy * theSin;
+ Dy = Dy * theCos - Dx * theSin;
+ Dx = newX;
+
+ // FAIL: Lines are parallel.
+ if (Cy === Dy) return {isSuccess:false, value:0};
+
+ // Discover the relative position of the intersection in the line AB
+ var t = (Dx + (Cx - Dx) * Dy / (Dy - Cy)) / distAB;
+
+ // Success.
+ return {isSuccess:true, value:t};
+};
+
+/**
+ * returns wheter or not polygon defined by vertex list is clockwise
+ * @param {Array} verts
+ * @return {Boolean}
+ */
+cc.vertexListIsClockwise = function(verts) {
+ for (var i = 0, len = verts.length; i < len; i++) {
+ var a = verts[i];
+ var b = verts[(i + 1) % len];
+ var c = verts[(i + 2) % len];
+
+ if (cc.pCross(cc.pSub(b, a), cc.pSub(c, b)) > 0)
+ return false;
+ }
+
+ return true;
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/core/support/TransformUtils.js b/frameworks/cocos2d-html5/cocos2d/core/support/TransformUtils.js
new file mode 100644
index 0000000..bb57c6f
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/support/TransformUtils.js
@@ -0,0 +1,62 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2009 Valentin Milea
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * convert an affine transform object to a kmMat4 object
+ * @param {cc.AffineTransform} trans
+ * @param {cc.kmMat4} mat
+ * @function
+ */
+cc.CGAffineToGL = function (trans, mat) {
+ // | m[0] m[4] m[8] m[12] | | m11 m21 m31 m41 | | a c 0 tx |
+ // | m[1] m[5] m[9] m[13] | | m12 m22 m32 m42 | | b d 0 ty |
+ // | m[2] m[6] m[10] m[14] | <=> | m13 m23 m33 m43 | <=> | 0 0 1 0 |
+ // | m[3] m[7] m[11] m[15] | | m14 m24 m34 m44 | | 0 0 0 1 |
+ mat[2] = mat[3] = mat[6] = mat[7] = mat[8] = mat[9] = mat[11] = mat[14] = 0.0;
+ mat[10] = mat[15] = 1.0;
+ mat[0] = trans.a;
+ mat[4] = trans.c;
+ mat[12] = trans.tx;
+ mat[1] = trans.b;
+ mat[5] = trans.d;
+ mat[13] = trans.ty;
+};
+
+/**
+ * Convert a kmMat4 object to an affine transform object
+ * @param {cc.kmMat4} mat
+ * @param {cc.AffineTransform} trans
+ * @function
+ */
+cc.GLToCGAffine = function (mat, trans) {
+ trans.a = mat[0];
+ trans.c = mat[4];
+ trans.tx = mat[12];
+ trans.b = mat[1];
+ trans.d = mat[5];
+ trans.ty = mat[13];
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/core/textures/CCTexture2D.js b/frameworks/cocos2d-html5/cocos2d/core/textures/CCTexture2D.js
new file mode 100644
index 0000000..b69d83c
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/textures/CCTexture2D.js
@@ -0,0 +1,622 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+//CONSTANTS:
+
+/**
+ * Horizontal center and vertical center.
+ * @constant
+ * @type Number
+ */
+cc.ALIGN_CENTER = 0x33;
+
+/**
+ * Horizontal center and vertical top.
+ * @constant
+ * @type Number
+ */
+cc.ALIGN_TOP = 0x13;
+
+/**
+ * Horizontal right and vertical top.
+ * @constant
+ * @type Number
+ */
+cc.ALIGN_TOP_RIGHT = 0x12;
+
+/**
+ * Horizontal right and vertical center.
+ * @constant
+ * @type Number
+ */
+cc.ALIGN_RIGHT = 0x32;
+
+/**
+ * Horizontal right and vertical bottom.
+ * @constant
+ * @type Number
+ */
+cc.ALIGN_BOTTOM_RIGHT = 0x22;
+
+/**
+ * Horizontal center and vertical bottom.
+ * @constant
+ * @type Number
+ */
+cc.ALIGN_BOTTOM = 0x23;
+
+/**
+ * Horizontal left and vertical bottom.
+ * @constant
+ * @type Number
+ */
+cc.ALIGN_BOTTOM_LEFT = 0x21;
+
+/**
+ * Horizontal left and vertical center.
+ * @constant
+ * @type Number
+ */
+cc.ALIGN_LEFT = 0x31;
+
+/**
+ * Horizontal left and vertical top.
+ * @constant
+ * @type Number
+ */
+cc.ALIGN_TOP_LEFT = 0x11;
+//----------------------Possible texture pixel formats----------------------------
+
+
+// By default PVR images are treated as if they don't have the alpha channel premultiplied
+cc.PVRHaveAlphaPremultiplied_ = false;
+
+//cc.Texture2DWebGL move to TextureWebGL.js
+
+cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
+
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
+
+ var proto = {
+ _contentSize: null,
+ _textureLoaded: false,
+ _htmlElementObj: null,
+ url: null,
+ _pattern: null,
+
+ ctor: function () {
+ this._contentSize = cc.size(0, 0);
+ this._textureLoaded = false;
+ this._htmlElementObj = null;
+ this._pattern = "";
+ this._pixelsWide = 0;
+ this._pixelsHigh = 0;
+ },
+
+ /**
+ * get width in pixels
+ * @return {Number}
+ */
+ getPixelsWide: function () {
+ return this._pixelsWide;
+ },
+
+ /**
+ * get height of in pixels
+ * @return {Number}
+ */
+ getPixelsHigh: function () {
+ return this._pixelsHigh;
+ },
+
+ /**
+ * get content size
+ * @returns {cc.Size}
+ */
+ getContentSize: function () {
+ var locScaleFactor = cc.contentScaleFactor();
+ return cc.size(this._contentSize.width / locScaleFactor, this._contentSize.height / locScaleFactor);
+ },
+
+ _getWidth: function () {
+ return this._contentSize.width / cc.contentScaleFactor();
+ },
+ _getHeight: function () {
+ return this._contentSize.height / cc.contentScaleFactor();
+ },
+
+ /**
+ * get content size in pixels
+ * @returns {cc.Size}
+ */
+ getContentSizeInPixels: function () {
+ return this._contentSize;
+ },
+
+ /**
+ * init with HTML element
+ * @param {HTMLImageElement|HTMLCanvasElement} element
+ */
+ initWithElement: function (element) {
+ if (!element)
+ return;
+ this._htmlElementObj = element;
+ this._pixelsWide = this._contentSize.width = element.width;
+ this._pixelsHigh = this._contentSize.height = element.height;
+ this._textureLoaded = true;
+ },
+
+ /**
+ * HTMLElement Object getter
+ * @return {HTMLImageElement|HTMLCanvasElement}
+ */
+ getHtmlElementObj: function () {
+ return this._htmlElementObj;
+ },
+
+ /**
+ * check whether texture is loaded
+ * @returns {boolean}
+ */
+ isLoaded: function () {
+ return this._textureLoaded;
+ },
+
+ /**
+ * handle loaded texture
+ */
+ handleLoadedTexture: function () {
+ var self = this;
+ if (!self._htmlElementObj) {
+ return;
+ }
+
+ var locElement = self._htmlElementObj;
+ self._pixelsWide = self._contentSize.width = locElement.width;
+ self._pixelsHigh = self._contentSize.height = locElement.height;
+
+ //dispatch load event to listener.
+ self.dispatchEvent("load");
+ },
+
+ /**
+ * description of cc.Texture2D
+ * @returns {string}
+ */
+ description: function () {
+ return "";
+ },
+
+ initWithData: function (data, pixelFormat, pixelsWide, pixelsHigh, contentSize) {
+ //support only in WebGl rendering mode
+ return false;
+ },
+
+ initWithImage: function (uiImage) {
+ //support only in WebGl rendering mode
+ return false;
+ },
+
+ initWithString: function (text, fontName, fontSize, dimensions, hAlignment, vAlignment) {
+ //support only in WebGl rendering mode
+ return false;
+ },
+
+ releaseTexture: function () {
+ this._htmlElementObj = null;
+ cc.loader.release(this.url);
+ },
+
+ getName: function () {
+ //support only in WebGl rendering mode
+ return null;
+ },
+
+ getMaxS: function () {
+ //support only in WebGl rendering mode
+ return 1;
+ },
+
+ setMaxS: function (maxS) {
+ //support only in WebGl rendering mode
+ },
+
+ getMaxT: function () {
+ return 1;
+ },
+
+ setMaxT: function (maxT) {
+ //support only in WebGl rendering mode
+ },
+
+ getPixelFormat: function () {
+ //support only in WebGl rendering mode
+ return null;
+ },
+
+ getShaderProgram: function () {
+ //support only in WebGl rendering mode
+ return null;
+ },
+
+ setShaderProgram: function (shaderProgram) {
+ //support only in WebGl rendering mode
+ },
+
+ hasPremultipliedAlpha: function () {
+ //support only in WebGl rendering mode
+ return false;
+ },
+
+ hasMipmaps: function () {
+ //support only in WebGl rendering mode
+ return false;
+ },
+
+ releaseData: function (data) {
+ //support only in WebGl rendering mode
+ data = null;
+ },
+
+ keepData: function (data, length) {
+ //support only in WebGl rendering mode
+ return data;
+ },
+
+ drawAtPoint: function (point) {
+ //support only in WebGl rendering mode
+ },
+
+ drawInRect: function (rect) {
+ //support only in WebGl rendering mode
+ },
+
+ /**
+ * init with ETC file
+ * @warning does not support on HTML5
+ */
+ initWithETCFile: function (file) {
+ cc.log(cc._LogInfos.Texture2D_initWithETCFile);
+ return false;
+ },
+
+ /**
+ * init with PVR file
+ * @warning does not support on HTML5
+ */
+ initWithPVRFile: function (file) {
+ cc.log(cc._LogInfos.Texture2D_initWithPVRFile);
+ return false;
+ },
+
+ /**
+ * init with PVRTC data
+ * @warning does not support on HTML5
+ */
+ initWithPVRTCData: function (data, level, bpp, hasAlpha, length, pixelFormat) {
+ cc.log(cc._LogInfos.Texture2D_initWithPVRTCData);
+ return false;
+ },
+
+ setTexParameters: function (texParams, magFilter, wrapS, wrapT) {
+ if (magFilter !== undefined)
+ texParams = {minFilter: texParams, magFilter: magFilter, wrapS: wrapS, wrapT: wrapT};
+
+ if (texParams.wrapS === cc.REPEAT && texParams.wrapT === cc.REPEAT) {
+ this._pattern = "repeat";
+ return;
+ }
+
+ if (texParams.wrapS === cc.REPEAT) {
+ this._pattern = "repeat-x";
+ return;
+ }
+
+ if (texParams.wrapT === cc.REPEAT) {
+ this._pattern = "repeat-y";
+ return;
+ }
+
+ this._pattern = "";
+ },
+
+ setAntiAliasTexParameters: function () {
+ //support only in WebGl rendering mode
+ },
+
+ setAliasTexParameters: function () {
+ //support only in WebGl rendering mode
+ },
+
+ generateMipmap: function () {
+ //support only in WebGl rendering mode
+ },
+
+ stringForFormat: function () {
+ //support only in WebGl rendering mode
+ return "";
+ },
+
+ bitsPerPixelForFormat: function (format) {
+ //support only in WebGl rendering mode
+ return -1;
+ },
+
+ /**
+ * add listener for loaded event
+ * @param {Function} callback
+ * @param {cc.Node} target
+ * @deprecated since 3.1, please use addEventListener instead
+ */
+ addLoadedEventListener: function (callback, target) {
+ this.addEventListener("load", callback, target);
+ },
+
+ /**
+ * remove listener from listeners by target
+ * @param {cc.Node} target
+ */
+ removeLoadedEventListener: function (target) {
+ this.removeEventTarget("load", target);
+ },
+
+ _generateColorTexture: function () {/*overide*/
+ },
+ _generateTextureCacheForColor: function () {
+ if (this.channelCache)
+ return this.channelCache;
+
+ var textureCache = [
+ document.createElement("canvas"),
+ document.createElement("canvas"),
+ document.createElement("canvas"),
+ document.createElement("canvas")
+ ];
+ //todo texture onload
+ renderToCache(this._htmlElementObj, textureCache);
+ return this.channelCache = textureCache;
+ },
+
+ //hack for gray effect
+ _grayElementObj: null,
+ _backupElement: null,
+ _isGray: false,
+ _switchToGray: function (toGray) {
+ if (!this._textureLoaded || this._isGray === toGray)
+ return;
+ this._isGray = toGray;
+ if (this._isGray) {
+ this._backupElement = this._htmlElementObj;
+ if (!this._grayElementObj)
+ this._grayElementObj = cc.Texture2D._generateGrayTexture(this._htmlElementObj);
+ this._htmlElementObj = this._grayElementObj;
+ } else {
+ if (this._backupElement !== null)
+ this._htmlElementObj = this._backupElement;
+ }
+ },
+
+ _generateGrayTexture: function() {
+ if(!this._textureLoaded)
+ return null;
+ var grayElement = cc.Texture2D._generateGrayTexture(this._htmlElementObj);
+ var newTexture = new cc.Texture2D();
+ newTexture.initWithElement(grayElement);
+ newTexture.handleLoadedTexture();
+ return newTexture;
+ },
+ };
+
+ var renderToCache = function (image, cache) {
+ var w = image.width;
+ var h = image.height;
+
+ cache[0].width = w;
+ cache[0].height = h;
+ cache[1].width = w;
+ cache[1].height = h;
+ cache[2].width = w;
+ cache[2].height = h;
+ cache[3].width = w;
+ cache[3].height = h;
+
+ var cacheCtx = cache[3].getContext("2d");
+ cacheCtx.drawImage(image, 0, 0);
+ var pixels = cacheCtx.getImageData(0, 0, w, h).data;
+
+ var ctx;
+ for (var rgbI = 0; rgbI < 4; rgbI++) {
+ ctx = cache[rgbI].getContext("2d");
+
+ var to = ctx.getImageData(0, 0, w, h);
+ var data = to.data;
+ for (var i = 0; i < pixels.length; i += 4) {
+ data[i] = (rgbI === 0) ? pixels[i] : 0;
+ data[i + 1] = (rgbI === 1) ? pixels[i + 1] : 0;
+ data[i + 2] = (rgbI === 2) ? pixels[i + 2] : 0;
+ data[i + 3] = pixels[i + 3];
+ }
+ ctx.putImageData(to, 0, 0);
+ }
+ image.onload = null;
+ };
+
+ //change color function
+ if (cc.sys._supportCanvasNewBlendModes) {
+ //multiply mode
+ //Primary afferent, Draw a new texture based on rect
+ proto._generateColorTexture = function (r, g, b, rect, canvas) {
+ var onlyCanvas = false;
+ if (canvas)
+ onlyCanvas = true;
+ else
+ canvas = document.createElement("canvas");
+ var textureImage = this._htmlElementObj;
+ if (!rect)
+ rect = cc.rect(0, 0, textureImage.width, textureImage.height);
+
+ canvas.width = rect.width;
+ canvas.height = rect.height;
+
+ var context = canvas.getContext("2d");
+ context.globalCompositeOperation = "source-over";
+ context.fillStyle = "rgb(" + (r | 0) + "," + (g | 0) + "," + (b | 0) + ")";
+ context.fillRect(0, 0, rect.width, rect.height);
+ context.globalCompositeOperation = "multiply";
+ context.drawImage(
+ textureImage,
+ rect.x, rect.y, rect.width, rect.height,
+ 0, 0, rect.width, rect.height
+ );
+ context.globalCompositeOperation = "destination-atop";
+ context.drawImage(
+ textureImage,
+ rect.x, rect.y, rect.width, rect.height,
+ 0, 0, rect.width, rect.height
+ );
+ if (onlyCanvas)
+ return canvas;
+ var newTexture = new cc.Texture2D();
+ newTexture.initWithElement(canvas);
+ newTexture.handleLoadedTexture();
+ return newTexture;
+ };
+ } else {
+ //Four color map overlay
+ proto._generateColorTexture = function (r, g, b, rect, canvas) {
+ var onlyCanvas = false;
+ if (canvas)
+ onlyCanvas = true;
+ else
+ canvas = document.createElement("canvas");
+
+ var textureImage = this._htmlElementObj;
+ if (!rect)
+ rect = cc.rect(0, 0, textureImage.width, textureImage.height);
+ var x, y, w, h;
+ x = rect.x; y = rect.y; w = rect.width; h = rect.height;
+ if (!w || !h)
+ return;
+
+ canvas.width = w;
+ canvas.height = h;
+
+ var context = canvas.getContext("2d");
+ var tintedImgCache = cc.textureCache.getTextureColors(this);
+ context.globalCompositeOperation = 'lighter';
+ context.drawImage(
+ tintedImgCache[3],
+ x, y, w, h,
+ 0, 0, w, h
+ );
+ if (r > 0) {
+ context.globalAlpha = r / 255;
+ context.drawImage(
+ tintedImgCache[0],
+ x, y, w, h,
+ 0, 0, w, h
+ );
+ }
+ if (g > 0) {
+ context.globalAlpha = g / 255;
+ context.drawImage(
+ tintedImgCache[1],
+ x, y, w, h,
+ 0, 0, w, h
+ );
+ }
+ if (b > 0) {
+ context.globalAlpha = b / 255;
+ context.drawImage(
+ tintedImgCache[2],
+ x, y, w, h,
+ 0, 0, w, h
+ );
+ }
+ if (onlyCanvas)
+ return canvas;
+
+ var newTexture = new cc.Texture2D();
+ newTexture.initWithElement(canvas);
+ newTexture.handleLoadedTexture();
+ return newTexture;
+ };
+ }
+
+ /**
+ *
+ * This class allows to easily create OpenGL or Canvas 2D textures from images, text or raw data.
+ * The created cc.Texture2D object will always have power-of-two dimensions.
+ * Depending on how you create the cc.Texture2D object, the actual image area of the texture might be smaller than the texture dimensions
+ * i.e. "contentSize" != (pixelsWide, pixelsHigh) and (maxS, maxT) != (1.0, 1.0).
+ * Be aware that the content of the generated textures will be upside-down!
+ * @name cc.Texture2D
+ * @class
+ * @extends cc.Class
+ *
+ * @property {WebGLTexture} name - <@readonly> WebGLTexture Object
+ * @property {Number} pixelFormat - <@readonly> Pixel format of the texture
+ * @property {Number} pixelsWidth - <@readonly> Width in pixels
+ * @property {Number} pixelsHeight - <@readonly> Height in pixels
+ * @property {Number} width - Content width in points
+ * @property {Number} height - Content height in points
+ * @property {cc.GLProgram} shaderProgram - The shader program used by drawAtPoint and drawInRect
+ * @property {Number} maxS - Texture max S
+ * @property {Number} maxT - Texture max T
+ */
+ cc.Texture2D = cc.Class.extend(/** @lends cc.Texture2D# */proto);
+
+ cc.Texture2D._generateGrayTexture = function (texture, rect, renderCanvas) {
+ if (texture === null)
+ return null;
+ renderCanvas = renderCanvas || document.createElement("canvas");
+ rect = rect || cc.rect(0, 0, texture.width, texture.height);
+ renderCanvas.width = rect.width;
+ renderCanvas.height = rect.height;
+
+ var context = renderCanvas.getContext("2d");
+ context.drawImage(texture, rect.x, rect.y, rect.width, rect.height, 0, 0, rect.width, rect.height);
+ var imgData = context.getImageData(0, 0, rect.width, rect.height);
+ var data = imgData.data;
+ for (var i = 0, len = data.length; i < len; i += 4) {
+ data[i] = data[i + 1] = data[i + 2] = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];
+ }
+ context.putImageData(imgData, 0, 0);
+ return renderCanvas;
+ };
+
+ } else if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ cc.assert(cc.isFunction(cc._tmp.WebGLTexture2D), cc._LogInfos.MissingFile, "TexturesWebGL.js");
+ cc._tmp.WebGLTexture2D();
+ delete cc._tmp.WebGLTexture2D;
+ }
+
+ cc.EventHelper.prototype.apply(cc.Texture2D.prototype);
+
+ cc.assert(cc.isFunction(cc._tmp.PrototypeTexture2D), cc._LogInfos.MissingFile, "TexturesPropertyDefine.js");
+ cc._tmp.PrototypeTexture2D();
+ delete cc._tmp.PrototypeTexture2D;
+});
diff --git a/frameworks/cocos2d-html5/cocos2d/core/textures/CCTextureAtlas.js b/frameworks/cocos2d-html5/cocos2d/core/textures/CCTextureAtlas.js
new file mode 100644
index 0000000..b996dc7
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/textures/CCTextureAtlas.js
@@ -0,0 +1,655 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * A class that implements a Texture Atlas.
+ * Supported features:
+ * The atlas file can be a PNG, JPG.
+ * Quads can be updated in runtime
+ * Quads can be added in runtime
+ * Quads can be removed in runtime
+ * Quads can be re-ordered in runtime
+ * The TextureAtlas capacity can be increased or decreased in runtime.
+ * @class
+ * @extends cc.Class
+ *
+ * @property {Boolean} dirty - Indicates whether or not the array buffer of the VBO needs to be updated.
+ * @property {Image} texture - Image texture for cc.TextureAtlas.
+ * @property {Number} capacity - <@readonly> Quantity of quads that can be stored with the current texture atlas size.
+ * @property {Number} totalQuads - <@readonly> Quantity of quads that are going to be drawn.
+ * @property {Array} quads - <@readonly> Quads that are going to be rendered
+ */
+cc.TextureAtlas = cc.Class.extend(/** @lends cc.TextureAtlas# */{ //WebGL only
+ dirty: false,
+ texture: null,
+
+ _indices: null,
+ //0: vertex 1: indices
+ _buffersVBO: null,
+ _capacity: 0,
+
+ _quads: null,
+ _quadsArrayBuffer: null,
+ _quadsWebBuffer: null,
+ _quadsReader: null,
+
+ /**
+ * Creates a TextureAtlas with an filename and with an initial capacity for Quads.
+ * The TextureAtlas capacity can be increased in runtime.
+ * Constructor of cc.TextureAtlas
+ * @param {String|cc.Texture2D} fileName
+ * @param {Number} capacity
+ * @example
+ * 1.
+ * //creates a TextureAtlas with filename
+ * var textureAtlas = new cc.TextureAtlas("res/hello.png", 3);
+ * 2.
+ * //creates a TextureAtlas with texture
+ * var texture = cc.textureCache.addImage("hello.png");
+ * var textureAtlas = new cc.TextureAtlas(texture, 3);
+ */
+ ctor: function (fileName, capacity) {
+ this._buffersVBO = [];
+
+ if (cc.isString(fileName)) {
+ this.initWithFile(fileName, capacity);
+ } else if (fileName instanceof cc.Texture2D) {
+ this.initWithTexture(fileName, capacity);
+ }
+ },
+
+ /**
+ * Quantity of quads that are going to be drawn.
+ * @return {Number}
+ */
+ getTotalQuads: function () {
+ //return this._quads.length;
+ return this._totalQuads;
+ },
+
+ /**
+ * Quantity of quads that can be stored with the current texture atlas size
+ * @return {Number}
+ */
+ getCapacity: function () {
+ return this._capacity;
+ },
+
+ /**
+ * Texture of the texture atlas
+ * @return {Image}
+ */
+ getTexture: function () {
+ return this.texture;
+ },
+
+ /**
+ * @param {Image} texture
+ */
+ setTexture: function (texture) {
+ this.texture = texture;
+ },
+
+ /**
+ * specify if the array buffer of the VBO needs to be updated
+ * @param {Boolean} dirty
+ */
+ setDirty: function (dirty) {
+ this.dirty = dirty;
+ },
+
+ /**
+ * whether or not the array buffer of the VBO needs to be updated
+ * @returns {boolean}
+ */
+ isDirty: function () {
+ return this.dirty;
+ },
+
+ /**
+ * Quads that are going to be rendered
+ * @return {Array}
+ */
+ getQuads: function () {
+ return this._quads;
+ },
+
+ /**
+ * @param {Array} quads
+ */
+ setQuads: function (quads) {
+ //TODO need re-binding
+ this._quads = quads;
+ },
+
+ _copyQuadsToTextureAtlas: function (quads, index) {
+ if (!quads)
+ return;
+
+ for (var i = 0; i < quads.length; i++)
+ this._setQuadToArray(quads[i], index + i);
+ },
+
+ _setQuadToArray: function (quad, index) {
+ var locQuads = this._quads;
+ if (!locQuads[index]) {
+ locQuads[index] = new cc.V3F_C4B_T2F_Quad(quad.tl, quad.bl, quad.tr, quad.br, this._quadsArrayBuffer, index * cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT);
+ return;
+ }
+ locQuads[index].bl = quad.bl;
+ locQuads[index].br = quad.br;
+ locQuads[index].tl = quad.tl;
+ locQuads[index].tr = quad.tr;
+ },
+
+ /**
+ * Description
+ * @return {String}
+ */
+ description: function () {
+ return '';
+ },
+
+ _setupIndices: function () {
+ if (this._capacity === 0)
+ return;
+ var locIndices = this._indices, locCapacity = this._capacity;
+ for (var i = 0; i < locCapacity; i++) {
+ if (cc.TEXTURE_ATLAS_USE_TRIANGLE_STRIP) {
+ locIndices[i * 6 + 0] = i * 4 + 0;
+ locIndices[i * 6 + 1] = i * 4 + 0;
+ locIndices[i * 6 + 2] = i * 4 + 2;
+ locIndices[i * 6 + 3] = i * 4 + 1;
+ locIndices[i * 6 + 4] = i * 4 + 3;
+ locIndices[i * 6 + 5] = i * 4 + 3;
+ } else {
+ locIndices[i * 6 + 0] = i * 4 + 0;
+ locIndices[i * 6 + 1] = i * 4 + 1;
+ locIndices[i * 6 + 2] = i * 4 + 2;
+
+ // inverted index. issue #179
+ locIndices[i * 6 + 3] = i * 4 + 3;
+ locIndices[i * 6 + 4] = i * 4 + 2;
+ locIndices[i * 6 + 5] = i * 4 + 1;
+ }
+ }
+ },
+
+ _setupVBO: function () {
+ var gl = cc._renderContext;
+ //create WebGLBuffer
+ this._buffersVBO[0] = gl.createBuffer();
+ this._buffersVBO[1] = gl.createBuffer();
+
+ this._quadsWebBuffer = gl.createBuffer();
+ this._mapBuffers();
+ },
+
+ _mapBuffers: function () {
+ var gl = cc._renderContext;
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._quadsWebBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this._quadsArrayBuffer, gl.DYNAMIC_DRAW);
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._buffersVBO[1]);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW);
+ },
+
+ /**
+ * Initializes a TextureAtlas with a filename and with a certain capacity for Quads.
+ * The TextureAtlas capacity can be increased in runtime.
+ * WARNING: Do not reinitialize the TextureAtlas because it will leak memory.
+ * @param {String} file
+ * @param {Number} capacity
+ * @return {Boolean}
+ * @example
+ * //example
+ * var textureAtlas = new cc.TextureAtlas();
+ * textureAtlas.initWithTexture("hello.png", 3);
+ */
+ initWithFile: function (file, capacity) {
+ // retained in property
+ var texture = cc.textureCache.addImage(file);
+ if (texture)
+ return this.initWithTexture(texture, capacity);
+ else {
+ cc.log(cc._LogInfos.TextureAtlas_initWithFile, file);
+ return false;
+ }
+ },
+
+ /**
+ * Initializes a TextureAtlas with a previously initialized Texture2D object, and
+ * with an initial capacity for Quads.
+ * The TextureAtlas capacity can be increased in runtime.
+ * WARNING: Do not reinitialize the TextureAtlas because it will leak memory
+ * @param {Image} texture
+ * @param {Number} capacity
+ * @return {Boolean}
+ * @example
+ * //example
+ * var texture = cc.textureCache.addImage("hello.png");
+ * var textureAtlas = new cc.TextureAtlas();
+ * textureAtlas.initWithTexture(texture, 3);
+ */
+ initWithTexture: function (texture, capacity) {
+ cc.assert(texture, cc._LogInfos.TextureAtlas_initWithTexture);
+
+ capacity = 0 | (capacity);
+ this._capacity = capacity;
+ this._totalQuads = 0;
+
+ // retained in property
+ this.texture = texture;
+
+ // Re-initialization is not allowed
+ this._quads = [];
+ this._indices = new Uint16Array(capacity * 6);
+ var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT;
+ this._quadsArrayBuffer = new ArrayBuffer(quadSize * capacity);
+ this._quadsReader = new Uint8Array(this._quadsArrayBuffer);
+
+ if (!( this._quads && this._indices) && capacity > 0)
+ return false;
+
+ var locQuads = this._quads;
+ for (var i = 0; i < capacity; i++)
+ locQuads[i] = new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._quadsArrayBuffer, i * quadSize);
+
+ this._setupIndices();
+ this._setupVBO();
+ this.dirty = true;
+ return true;
+ },
+
+ /**
+ * Updates a Quad (texture, vertex and color) at a certain index
+ * index must be between 0 and the atlas capacity - 1
+ * @param {cc.V3F_C4B_T2F_Quad} quad
+ * @param {Number} index
+ */
+ updateQuad: function (quad, index) {
+ cc.assert(quad, cc._LogInfos.TextureAtlas_updateQuad);
+ cc.assert(index >= 0 && index < this._capacity, cc._LogInfos.TextureAtlas_updateQuad_2);
+
+ this._totalQuads = Math.max(index + 1, this._totalQuads);
+ this._setQuadToArray(quad, index);
+ this.dirty = true;
+ },
+
+ /**
+ * Inserts a Quad (texture, vertex and color) at a certain index
+ * index must be between 0 and the atlas capacity - 1
+ * @param {cc.V3F_C4B_T2F_Quad} quad
+ * @param {Number} index
+ */
+ insertQuad: function (quad, index) {
+ cc.assert(index < this._capacity, cc._LogInfos.TextureAtlas_insertQuad_2);
+
+ this._totalQuads++;
+ if (this._totalQuads > this._capacity) {
+ cc.log(cc._LogInfos.TextureAtlas_insertQuad);
+ return;
+ }
+ var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT;
+ // issue #575. index can be > totalQuads
+ var remaining = (this._totalQuads - 1) - index;
+ var startOffset = index * quadSize;
+ var moveLength = remaining * quadSize;
+ this._quads[this._totalQuads - 1] = new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._quadsArrayBuffer, (this._totalQuads - 1) * quadSize);
+ this._quadsReader.set(this._quadsReader.subarray(startOffset, startOffset + moveLength), startOffset + quadSize);
+
+ this._setQuadToArray(quad, index);
+ this.dirty = true;
+ },
+
+ /**
+ *
+ * Inserts a c array of quads at a given index
+ * index must be between 0 and the atlas capacity - 1
+ * this method doesn't enlarge the array when amount + index > totalQuads
+ *
+ * @param {Array} quads
+ * @param {Number} index
+ * @param {Number} amount
+ */
+ insertQuads: function (quads, index, amount) {
+ amount = amount || quads.length;
+
+ cc.assert((index + amount) <= this._capacity, cc._LogInfos.TextureAtlas_insertQuads);
+
+ var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT;
+ this._totalQuads += amount;
+ if (this._totalQuads > this._capacity) {
+ cc.log(cc._LogInfos.TextureAtlas_insertQuad);
+ return;
+ }
+
+ // issue #575. index can be > totalQuads
+ var remaining = (this._totalQuads - 1) - index - amount;
+ var startOffset = index * quadSize;
+ var moveLength = remaining * quadSize;
+ var lastIndex = (this._totalQuads - 1) - amount;
+
+ var i;
+ for (i = 0; i < amount; i++)
+ this._quads[lastIndex + i] = new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._quadsArrayBuffer, (this._totalQuads - 1) * quadSize);
+ this._quadsReader.set(this._quadsReader.subarray(startOffset, startOffset + moveLength), startOffset + quadSize * amount);
+ for (i = 0; i < amount; i++)
+ this._setQuadToArray(quads[i], index + i);
+
+ this.dirty = true;
+ },
+
+ /**
+ * Removes the quad that is located at a certain index and inserts it at a new index
+ * This operation is faster than removing and inserting in a quad in 2 different steps
+ * @param {Number} fromIndex
+ * @param {Number} newIndex
+ */
+ insertQuadFromIndex: function (fromIndex, newIndex) {
+ if (fromIndex === newIndex)
+ return;
+
+ cc.assert(newIndex >= 0 || newIndex < this._totalQuads, cc._LogInfos.TextureAtlas_insertQuadFromIndex);
+
+ cc.assert(fromIndex >= 0 || fromIndex < this._totalQuads, cc._LogInfos.TextureAtlas_insertQuadFromIndex_2);
+
+ var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT;
+ var locQuadsReader = this._quadsReader;
+ var sourceArr = locQuadsReader.subarray(fromIndex * quadSize, quadSize);
+ var startOffset, moveLength;
+ if (fromIndex > newIndex) {
+ startOffset = newIndex * quadSize;
+ moveLength = (fromIndex - newIndex) * quadSize;
+ locQuadsReader.set(locQuadsReader.subarray(startOffset, startOffset + moveLength), startOffset + quadSize);
+ locQuadsReader.set(sourceArr, startOffset);
+ } else {
+ startOffset = (fromIndex + 1) * quadSize;
+ moveLength = (newIndex - fromIndex) * quadSize;
+ locQuadsReader.set(locQuadsReader.subarray(startOffset, startOffset + moveLength), startOffset - quadSize);
+ locQuadsReader.set(sourceArr, newIndex * quadSize);
+ }
+ this.dirty = true;
+ },
+
+ /**
+ * Removes a quad at a given index number.
+ * The capacity remains the same, but the total number of quads to be drawn is reduced in 1
+ * @param {Number} index
+ */
+ removeQuadAtIndex: function (index) {
+ cc.assert(index < this._totalQuads, cc._LogInfos.TextureAtlas_removeQuadAtIndex);
+
+ var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT;
+ this._totalQuads--;
+ this._quads.length = this._totalQuads;
+ if (index !== this._totalQuads) {
+ //move data
+ var startOffset = (index + 1) * quadSize;
+ var moveLength = (this._totalQuads - index) * quadSize;
+ this._quadsReader.set(this._quadsReader.subarray(startOffset, startOffset + moveLength), startOffset - quadSize);
+ }
+ this.dirty = true;
+ },
+
+ /**
+ * Removes a given number of quads at a given index
+ * @param {Number} index
+ * @param {Number} amount
+ */
+ removeQuadsAtIndex: function (index, amount) {
+ cc.assert(index + amount <= this._totalQuads, cc._LogInfos.TextureAtlas_removeQuadsAtIndex);
+
+ this._totalQuads -= amount;
+
+ if (index !== this._totalQuads) {
+ //move data
+ var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT;
+ var srcOffset = (index + amount) * quadSize;
+ var moveLength = (this._totalQuads - index) * quadSize;
+ var dstOffset = index * quadSize;
+ this._quadsReader.set(this._quadsReader.subarray(srcOffset, srcOffset + moveLength), dstOffset);
+ }
+ this.dirty = true;
+ },
+
+ /**
+ * Removes all Quads.
+ * The TextureAtlas capacity remains untouched. No memory is freed.
+ * The total number of quads to be drawn will be 0
+ */
+ removeAllQuads: function () {
+ this._quads.length = 0;
+ this._totalQuads = 0;
+ },
+
+ _setDirty: function (dirty) {
+ this.dirty = dirty;
+ },
+
+ /**
+ * Resize the capacity of the CCTextureAtlas.
+ * The new capacity can be lower or higher than the current one
+ * It returns YES if the resize was successful.
+ * If it fails to resize the capacity it will return NO with a new capacity of 0.
+ * no used for js
+ * @param {Number} newCapacity
+ * @return {Boolean}
+ */
+ resizeCapacity: function (newCapacity) {
+ if (newCapacity === this._capacity)
+ return true;
+
+ var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT;
+ var oldCapacity = this._capacity;
+ // update capacity and totolQuads
+ this._totalQuads = Math.min(this._totalQuads, newCapacity);
+ this._capacity = 0 | newCapacity;
+ var i, capacity = this._capacity, locTotalQuads = this._totalQuads;
+
+ if (this._quads === null) {
+ this._quads = [];
+ this._quadsArrayBuffer = new ArrayBuffer(quadSize * capacity);
+ this._quadsReader = new Uint8Array(this._quadsArrayBuffer);
+ for (i = 0; i < capacity; i++)
+ this._quads = new cc.V3F_C4B_T2F_Quad(null, null, null, null, this._quadsArrayBuffer, i * quadSize);
+ } else {
+ var newQuads, newArrayBuffer, quads = this._quads;
+ if (capacity > oldCapacity) {
+ newQuads = [];
+ newArrayBuffer = new ArrayBuffer(quadSize * capacity);
+ for (i = 0; i < locTotalQuads; i++) {
+ newQuads[i] = new cc.V3F_C4B_T2F_Quad(quads[i].tl, quads[i].bl, quads[i].tr, quads[i].br,
+ newArrayBuffer, i * quadSize);
+ }
+ for (; i < capacity; i++)
+ newQuads[i] = new cc.V3F_C4B_T2F_Quad(null, null, null, null, newArrayBuffer, i * quadSize);
+
+ this._quadsReader = new Uint8Array(newArrayBuffer);
+ this._quads = newQuads;
+ this._quadsArrayBuffer = newArrayBuffer;
+ } else {
+ var count = Math.max(locTotalQuads, capacity);
+ newQuads = [];
+ newArrayBuffer = new ArrayBuffer(quadSize * capacity);
+ for (i = 0; i < count; i++) {
+ newQuads[i] = new cc.V3F_C4B_T2F_Quad(quads[i].tl, quads[i].bl, quads[i].tr, quads[i].br,
+ newArrayBuffer, i * quadSize);
+ }
+ this._quadsReader = new Uint8Array(newArrayBuffer);
+ this._quads = newQuads;
+ this._quadsArrayBuffer = newArrayBuffer;
+ }
+ }
+
+ if (this._indices === null) {
+ this._indices = new Uint16Array(capacity * 6);
+ } else {
+ if (capacity > oldCapacity) {
+ var tempIndices = new Uint16Array(capacity * 6);
+ tempIndices.set(this._indices, 0);
+ this._indices = tempIndices;
+ } else {
+ this._indices = this._indices.subarray(0, capacity * 6);
+ }
+ }
+
+ this._setupIndices();
+ this._mapBuffers();
+ this.dirty = true;
+ return true;
+ },
+
+ /**
+ * Used internally by CCParticleBatchNode
+ * don't use this unless you know what you're doing
+ * @param {Number} amount
+ */
+ increaseTotalQuadsWith: function (amount) {
+ this._totalQuads += amount;
+ },
+
+ /**
+ * Moves an amount of quads from oldIndex at newIndex
+ * @param {Number} oldIndex
+ * @param {Number} amount
+ * @param {Number} newIndex
+ */
+ moveQuadsFromIndex: function (oldIndex, amount, newIndex) {
+ if (newIndex === undefined) {
+ newIndex = amount;
+ amount = this._totalQuads - oldIndex;
+
+ cc.assert((newIndex + (this._totalQuads - oldIndex)) <= this._capacity, cc._LogInfos.TextureAtlas_moveQuadsFromIndex);
+
+ if (amount === 0)
+ return;
+ } else {
+ cc.assert((newIndex + amount) <= this._totalQuads, cc._LogInfos.TextureAtlas_moveQuadsFromIndex_2);
+ cc.assert(oldIndex < this._totalQuads, cc._LogInfos.TextureAtlas_moveQuadsFromIndex_3);
+
+ if (oldIndex === newIndex)
+ return;
+ }
+
+ var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT;
+ var srcOffset = oldIndex * quadSize;
+ var srcLength = amount * quadSize;
+ var locQuadsReader = this._quadsReader;
+ var sourceArr = locQuadsReader.subarray(srcOffset, srcOffset + srcLength);
+ var dstOffset = newIndex * quadSize;
+ var moveLength, moveStart;
+ if (newIndex < oldIndex) {
+ moveLength = (oldIndex - newIndex) * quadSize;
+ moveStart = newIndex * quadSize;
+ locQuadsReader.set(locQuadsReader.subarray(moveStart, moveStart + moveLength), moveStart + srcLength)
+ } else {
+ moveLength = (newIndex - oldIndex) * quadSize;
+ moveStart = (oldIndex + amount) * quadSize;
+ locQuadsReader.set(locQuadsReader.subarray(moveStart, moveStart + moveLength), srcOffset);
+ }
+ locQuadsReader.set(sourceArr, dstOffset);
+ this.dirty = true;
+ },
+
+ /**
+ * Ensures that after a realloc quads are still empty
+ * Used internally by CCParticleBatchNode
+ * @param {Number} index
+ * @param {Number} amount
+ */
+ fillWithEmptyQuadsFromIndex: function (index, amount) {
+ var count = amount * cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT;
+ var clearReader = new Uint8Array(this._quadsArrayBuffer, index * cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT, count);
+ for (var i = 0; i < count; i++)
+ clearReader[i] = 0;
+ },
+
+ // TextureAtlas - Drawing
+
+ /**
+ * Draws all the Atlas's Quads
+ */
+ drawQuads: function () {
+ this.drawNumberOfQuads(this._totalQuads, 0);
+ },
+
+ _releaseBuffer: function () {
+ var gl = cc._renderContext;
+ if (this._buffersVBO) {
+ if (this._buffersVBO[0])
+ gl.deleteBuffer(this._buffersVBO[0]);
+ if (this._buffersVBO[1])
+ gl.deleteBuffer(this._buffersVBO[1])
+ }
+ if (this._quadsWebBuffer)
+ gl.deleteBuffer(this._quadsWebBuffer);
+ }
+});
+
+var _p = cc.TextureAtlas.prototype;
+
+// Extended properties
+/** @expose */
+_p.totalQuads;
+cc.defineGetterSetter(_p, "totalQuads", _p.getTotalQuads);
+/** @expose */
+_p.capacity;
+cc.defineGetterSetter(_p, "capacity", _p.getCapacity);
+/** @expose */
+_p.quads;
+cc.defineGetterSetter(_p, "quads", _p.getQuads, _p.setQuads);
+
+/**
+ * Creates a TextureAtlas with an filename and with an initial capacity for Quads.
+ * The TextureAtlas capacity can be increased in runtime.
+ * @deprecated since v3.0, please use new cc.TextureAtlas(fileName, capacity) instead
+ * @param {String|cc.Texture2D} fileName
+ * @param {Number} capacity
+ * @return {cc.TextureAtlas|Null}
+ */
+cc.TextureAtlas.create = function (fileName, capacity) {
+ return new cc.TextureAtlas(fileName, capacity);
+};
+
+/**
+ * @deprecated since v3.0, please use new cc.TextureAtlas(texture) instead
+ * @function
+ */
+cc.TextureAtlas.createWithTexture = cc.TextureAtlas.create;
+
+cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ cc.assert(cc.isFunction(cc._tmp.WebGLTextureAtlas), cc._LogInfos.MissingFile, "TexturesWebGL.js");
+ cc._tmp.WebGLTextureAtlas();
+ delete cc._tmp.WebGLTextureAtlas;
+ }
+});
+
+cc.assert(cc.isFunction(cc._tmp.PrototypeTextureAtlas), cc._LogInfos.MissingFile, "TexturesPropertyDefine.js");
+cc._tmp.PrototypeTextureAtlas();
+delete cc._tmp.PrototypeTextureAtlas;
diff --git a/frameworks/cocos2d-html5/cocos2d/core/textures/CCTextureCache.js b/frameworks/cocos2d-html5/cocos2d/core/textures/CCTextureCache.js
new file mode 100644
index 0000000..5e59c2f
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/textures/CCTextureCache.js
@@ -0,0 +1,385 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.textureCache is a singleton object, it's the global cache for cc.Texture2D
+ * @class
+ * @name cc.textureCache
+ */
+cc.textureCache = /** @lends cc.textureCache# */{
+ _textures: {},
+ _textureColorsCache: {},
+ _textureKeySeq: (0 | Math.random() * 1000),
+
+ _loadedTexturesBefore: {},
+
+ //handleLoadedTexture move to Canvas/WebGL
+
+ _initializingRenderer: function () {
+ var selPath;
+ //init texture from _loadedTexturesBefore
+ var locLoadedTexturesBefore = this._loadedTexturesBefore, locTextures = this._textures;
+ for (selPath in locLoadedTexturesBefore) {
+ var tex2d = locLoadedTexturesBefore[selPath];
+ tex2d.handleLoadedTexture();
+ locTextures[selPath] = tex2d;
+ }
+ this._loadedTexturesBefore = {};
+ },
+
+ /**
+ *
+ * Returns a Texture2D object given an PVR filename
+ * If the file image was not previously loaded, it will create a new CCTexture2D
+ * object and it will return it. Otherwise it will return a reference of a previously loaded image
+ * note: AddPVRTCImage does not support on HTML5
+ *
+ * @param {String} filename
+ * @return {cc.Texture2D}
+ */
+ addPVRTCImage: function (filename) {
+ cc.log(cc._LogInfos.textureCache_addPVRTCImage);
+ },
+
+ /**
+ *
+ * Returns a Texture2D object given an ETC filename
+ * If the file image was not previously loaded, it will create a new CCTexture2D
+ * object and it will return it. Otherwise it will return a reference of a previously loaded image
+ * note:addETCImage does not support on HTML5
+ *
+ * @param {String} filename
+ * @return {cc.Texture2D}
+ */
+ addETCImage: function (filename) {
+ cc.log(cc._LogInfos.textureCache_addETCImage);
+ },
+
+ /**
+ * Description
+ * @return {String}
+ */
+ description: function () {
+ return "";
+ },
+
+ /**
+ * Returns an already created texture. Returns null if the texture doesn't exist.
+ * @param {String} textureKeyName
+ * @return {cc.Texture2D|Null}
+ * @deprecated
+ * @example
+ * //example
+ * var key = cc.textureCache.textureForKey("hello.png");
+ */
+ textureForKey: function (textureKeyName) {
+ cc.log(cc._LogInfos.textureCache_textureForKey);
+ return this.getTextureForKey(textureKeyName);
+ },
+
+ /**
+ * Returns an already created texture. Returns null if the texture doesn't exist.
+ * @param {String} textureKeyName
+ * @return {cc.Texture2D|Null}
+ * @example
+ * //example
+ * var key = cc.textureCache.getTextureForKey("hello.png");
+ */
+ getTextureForKey: function (textureKeyName) {
+ return this._textures[textureKeyName] || this._textures[cc.loader._getAliase(textureKeyName)];
+ },
+
+ /**
+ * @param {Image} texture
+ * @return {String|Null}
+ * @example
+ * //example
+ * var key = cc.textureCache.getKeyByTexture(texture);
+ */
+ getKeyByTexture: function (texture) {
+ for (var key in this._textures) {
+ if (this._textures[key] === texture) {
+ return key;
+ }
+ }
+ return null;
+ },
+
+ _generalTextureKey: function (id) {
+ return "_textureKey_" + id;
+ },
+
+ /**
+ * @param {Image} texture
+ * @return {Array}
+ * @example
+ * //example
+ * var cacheTextureForColor = cc.textureCache.getTextureColors(texture);
+ */
+ getTextureColors: function (texture) {
+ var image = texture._htmlElementObj;
+ var key = this.getKeyByTexture(image);
+ if (!key) {
+ if (image instanceof HTMLImageElement)
+ key = image.src;
+ else
+ key = this._generalTextureKey(texture.__instanceId);
+ }
+
+ if (!this._textureColorsCache[key])
+ this._textureColorsCache[key] = texture._generateTextureCacheForColor();
+ return this._textureColorsCache[key];
+ },
+
+ /**
+ * Returns a Texture2D object given an PVR filename
+ * If the file image was not previously loaded, it will create a new Texture2D
+ * object and it will return it. Otherwise it will return a reference of a previously loaded image
+ * @param {String} path
+ * @return {cc.Texture2D}
+ */
+ addPVRImage: function (path) {
+ cc.log(cc._LogInfos.textureCache_addPVRImage);
+ },
+
+ /**
+ * Purges the dictionary of loaded textures.
+ * Call this method if you receive the "Memory Warning"
+ * In the short term: it will free some resources preventing your app from being killed
+ * In the medium term: it will allocate more resources
+ * In the long term: it will be the same
+ * @example
+ * //example
+ * cc.textureCache.removeAllTextures();
+ */
+ removeAllTextures: function () {
+ var locTextures = this._textures;
+ for (var selKey in locTextures) {
+ if (locTextures[selKey])
+ locTextures[selKey].releaseTexture();
+ }
+ this._textures = {};
+ },
+
+ /**
+ * Deletes a texture from the cache given a texture
+ * @param {Image} texture
+ * @example
+ * //example
+ * cc.textureCache.removeTexture(texture);
+ */
+ removeTexture: function (texture) {
+ if (!texture)
+ return;
+
+ var locTextures = this._textures;
+ for (var selKey in locTextures) {
+ if (locTextures[selKey] === texture) {
+ locTextures[selKey].releaseTexture();
+ delete(locTextures[selKey]);
+ }
+ }
+ },
+
+ /**
+ * Deletes a texture from the cache given a its key name
+ * @param {String} textureKeyName
+ * @example
+ * //example
+ * cc.textureCache.removeTexture("hello.png");
+ */
+ removeTextureForKey: function (textureKeyName) {
+ if (textureKeyName == null)
+ return;
+ var tex = this._textures[textureKeyName];
+ if (tex) {
+ tex.releaseTexture();
+ delete(this._textures[textureKeyName]);
+ }
+ },
+
+ //addImage move to Canvas/WebGL
+
+ /**
+ * Cache the image data
+ * @param {String} path
+ * @param {Image|HTMLImageElement|HTMLCanvasElement} texture
+ */
+ cacheImage: function (path, texture) {
+ if (texture instanceof cc.Texture2D) {
+ this._textures[path] = texture;
+ return;
+ }
+ var texture2d = new cc.Texture2D();
+ texture2d.initWithElement(texture);
+ texture2d.handleLoadedTexture();
+ this._textures[path] = texture2d;
+ },
+
+ /**
+ * Returns a Texture2D object given an UIImage image
+ * If the image was not previously loaded, it will create a new Texture2D object and it will return it.
+ * Otherwise it will return a reference of a previously loaded image
+ * The "key" parameter will be used as the "key" for the cache.
+ * If "key" is null, then a new texture will be created each time.
+ * @param {HTMLImageElement|HTMLCanvasElement} image
+ * @param {String} key
+ * @return {cc.Texture2D}
+ */
+ addUIImage: function (image, key) {
+ cc.assert(image, cc._LogInfos.textureCache_addUIImage_2);
+
+ if (key) {
+ if (this._textures[key])
+ return this._textures[key];
+ }
+
+ // prevents overloading the autorelease pool
+ var texture = new cc.Texture2D();
+ texture.initWithImage(image);
+ if (key != null)
+ this._textures[key] = texture;
+ else
+ cc.log(cc._LogInfos.textureCache_addUIImage);
+ return texture;
+ },
+
+ /**
+ * Output to cc.log the current contents of this TextureCache
+ * This will attempt to calculate the size of each texture, and the total texture memory in use.
+ */
+ dumpCachedTextureInfo: function () {
+ var count = 0;
+ var totalBytes = 0, locTextures = this._textures;
+
+ for (var key in locTextures) {
+ var selTexture = locTextures[key];
+ count++;
+ if (selTexture.getHtmlElementObj() instanceof HTMLImageElement)
+ cc.log(cc._LogInfos.textureCache_dumpCachedTextureInfo, key, selTexture.getHtmlElementObj().src, selTexture.getPixelsWide(), selTexture.getPixelsHigh());
+ else {
+ cc.log(cc._LogInfos.textureCache_dumpCachedTextureInfo_2, key, selTexture.getPixelsWide(), selTexture.getPixelsHigh());
+ }
+ totalBytes += selTexture.getPixelsWide() * selTexture.getPixelsHigh() * 4;
+ }
+
+ var locTextureColorsCache = this._textureColorsCache;
+ for (key in locTextureColorsCache) {
+ var selCanvasColorsArr = locTextureColorsCache[key];
+ for (var selCanvasKey in selCanvasColorsArr) {
+ var selCanvas = selCanvasColorsArr[selCanvasKey];
+ count++;
+ cc.log(cc._LogInfos.textureCache_dumpCachedTextureInfo_2, key, selCanvas.width, selCanvas.height);
+ totalBytes += selCanvas.width * selCanvas.height * 4;
+ }
+
+ }
+ cc.log(cc._LogInfos.textureCache_dumpCachedTextureInfo_3, count, totalBytes / 1024, (totalBytes / (1024.0 * 1024.0)).toFixed(2));
+ },
+
+ _clear: function () {
+ this._textures = {};
+ this._textureColorsCache = {};
+ this._textureKeySeq = (0 | Math.random() * 1000);
+ this._loadedTexturesBefore = {};
+ }
+};
+
+cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
+
+ var _p = cc.textureCache;
+
+ _p.handleLoadedTexture = function (url, img) {
+ var locTexs = this._textures;
+ //remove judge
+ var tex = locTexs[url];
+ if (!tex) {
+ tex = locTexs[url] = new cc.Texture2D();
+ tex.url = url;
+ }
+ tex.initWithElement(img);
+ tex.handleLoadedTexture();
+ return tex;
+ };
+
+ /**
+ * Returns a Texture2D object given an file image
+ * If the file image was not previously loaded, it will create a new Texture2D
+ * object and it will return it. It will use the filename as a key.
+ * Otherwise it will return a reference of a previously loaded image.
+ * Supported image extensions: .png, .jpg, .gif
+ * @param {String} url
+ * @param {Function} cb
+ * @param {Object} target
+ * @return {cc.Texture2D}
+ * @example
+ * //example
+ * cc.textureCache.addImage("hello.png");
+ */
+ _p.addImage = function (url, cb, target) {
+
+ cc.assert(url, cc._LogInfos.Texture2D_addImage);
+
+ var locTexs = this._textures;
+ //remove judge
+ var tex = locTexs[url] || locTexs[cc.loader._getAliase(url)];
+ if (tex) {
+ if (tex.isLoaded()) {
+ cb && cb.call(target, tex);
+ return tex;
+ }
+ else {
+ tex.addEventListener("load", function () {
+ cb && cb.call(target, tex);
+ }, target);
+ return tex;
+ }
+ }
+
+ tex = locTexs[url] = new cc.Texture2D();
+ tex.url = url;
+ var basePath = cc.loader.getBasePath ? cc.loader.getBasePath() : cc.loader.resPath;
+ cc.loader.loadImg(cc.path.join(basePath || "", url), function (err, img) {
+ if (err)
+ return cb && cb.call(target, err);
+
+ var texResult = cc.textureCache.handleLoadedTexture(url, img);
+ cb && cb.call(target, texResult);
+ });
+
+ return tex;
+ };
+
+ _p.addImageAsync = _p.addImage;
+ _p = null;
+
+ } else if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ cc.assert(cc.isFunction(cc._tmp.WebGLTextureCache), cc._LogInfos.MissingFile, "TexturesWebGL.js");
+ cc._tmp.WebGLTextureCache();
+ delete cc._tmp.WebGLTextureCache;
+ }
+});
diff --git a/frameworks/cocos2d-html5/cocos2d/core/textures/TexturesPropertyDefine.js b/frameworks/cocos2d-html5/cocos2d/core/textures/TexturesPropertyDefine.js
new file mode 100644
index 0000000..518a5f5
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/textures/TexturesPropertyDefine.js
@@ -0,0 +1,228 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc._tmp.PrototypeTexture2D = function () {
+
+ var _c = cc.Texture2D;
+
+ /**
+ *
+ * treats (or not) PVR files as if they have alpha premultiplied.
+ * Since it is impossible to know at runtime if the PVR images have the alpha channel premultiplied, it is
+ * possible load them as if they have (or not) the alpha channel premultiplied.
+ *
+ * By default it is disabled.
+ *
+ * @param haveAlphaPremultiplied
+ */
+ _c.PVRImagesHavePremultipliedAlpha = function (haveAlphaPremultiplied) {
+ cc.PVRHaveAlphaPremultiplied_ = haveAlphaPremultiplied;
+ };
+
+ /**
+ * 32-bit texture: RGBA8888
+ * @memberOf cc.Texture2D
+ * @name PIXEL_FORMAT_RGBA8888
+ * @static
+ * @constant
+ * @type {Number}
+ */
+ _c.PIXEL_FORMAT_RGBA8888 = 2;
+
+ /**
+ * 24-bit texture: RGBA888
+ * @memberOf cc.Texture2D
+ * @name PIXEL_FORMAT_RGB888
+ * @static
+ * @constant
+ * @type {Number}
+ */
+ _c.PIXEL_FORMAT_RGB888 = 3;
+
+ /**
+ * 16-bit texture without Alpha channel
+ * @memberOf cc.Texture2D
+ * @name PIXEL_FORMAT_RGB565
+ * @static
+ * @constant
+ * @type {Number}
+ */
+ _c.PIXEL_FORMAT_RGB565 = 4;
+
+ /**
+ * 8-bit textures used as masks
+ * @memberOf cc.Texture2D
+ * @name PIXEL_FORMAT_A8
+ * @static
+ * @constant
+ * @type {Number}
+ */
+ _c.PIXEL_FORMAT_A8 = 5;
+
+ /**
+ * 8-bit intensity texture
+ * @memberOf cc.Texture2D
+ * @name PIXEL_FORMAT_I8
+ * @static
+ * @constant
+ * @type {Number}
+ */
+ _c.PIXEL_FORMAT_I8 = 6;
+
+ /**
+ * 16-bit textures used as masks
+ * @memberOf cc.Texture2D
+ * @name PIXEL_FORMAT_AI88
+ * @static
+ * @constant
+ * @type {Number}
+ */
+ _c.PIXEL_FORMAT_AI88 = 7;
+
+ /**
+ * 16-bit textures: RGBA4444
+ * @memberOf cc.Texture2D
+ * @name PIXEL_FORMAT_RGBA4444
+ * @static
+ * @constant
+ * @type {Number}
+ */
+ _c.PIXEL_FORMAT_RGBA4444 = 8;
+
+ /**
+ * 16-bit textures: RGB5A1
+ * @memberOf cc.Texture2D
+ * @name PIXEL_FORMAT_RGB5A1
+ * @static
+ * @constant
+ * @type {Number}
+ */
+ _c.PIXEL_FORMAT_RGB5A1 = 7;
+
+ /**
+ * 4-bit PVRTC-compressed texture: PVRTC4
+ * @memberOf cc.Texture2D
+ * @name PIXEL_FORMAT_PVRTC4
+ * @static
+ * @constant
+ * @type {Number}
+ */
+ _c.PIXEL_FORMAT_PVRTC4 = 9;
+
+ /**
+ * 2-bit PVRTC-compressed texture: PVRTC2
+ * @memberOf cc.Texture2D
+ * @name PIXEL_FORMAT_PVRTC2
+ * @static
+ * @constant
+ * @type {Number}
+ */
+ _c.PIXEL_FORMAT_PVRTC2 = 10;
+
+ /**
+ * Default texture format: RGBA8888
+ * @memberOf cc.Texture2D
+ * @name PIXEL_FORMAT_DEFAULT
+ * @static
+ * @constant
+ * @type {Number}
+ */
+ _c.PIXEL_FORMAT_DEFAULT = _c.PIXEL_FORMAT_RGBA8888;
+
+ /**
+ * The default pixel format
+ * @memberOf cc.Texture2D
+ * @name PIXEL_FORMAT_PVRTC2
+ * @static
+ * @type {Number}
+ */
+ _c.defaultPixelFormat = _c.PIXEL_FORMAT_DEFAULT;
+
+ var _M = cc.Texture2D._M = {};
+ _M[_c.PIXEL_FORMAT_RGBA8888] = "RGBA8888";
+ _M[_c.PIXEL_FORMAT_RGB888] = "RGB888";
+ _M[_c.PIXEL_FORMAT_RGB565] = "RGB565";
+ _M[_c.PIXEL_FORMAT_A8] = "A8";
+ _M[_c.PIXEL_FORMAT_I8] = "I8";
+ _M[_c.PIXEL_FORMAT_AI88] = "AI88";
+ _M[_c.PIXEL_FORMAT_RGBA4444] = "RGBA4444";
+ _M[_c.PIXEL_FORMAT_RGB5A1] = "RGB5A1";
+ _M[_c.PIXEL_FORMAT_PVRTC4] = "PVRTC4";
+ _M[_c.PIXEL_FORMAT_PVRTC2] = "PVRTC2";
+
+ var _B = cc.Texture2D._B = {};
+ _B[_c.PIXEL_FORMAT_RGBA8888] = 32;
+ _B[_c.PIXEL_FORMAT_RGB888] = 24;
+ _B[_c.PIXEL_FORMAT_RGB565] = 16;
+ _B[_c.PIXEL_FORMAT_A8] = 8;
+ _B[_c.PIXEL_FORMAT_I8] = 8;
+ _B[_c.PIXEL_FORMAT_AI88] = 16;
+ _B[_c.PIXEL_FORMAT_RGBA4444] = 16;
+ _B[_c.PIXEL_FORMAT_RGB5A1] = 16;
+ _B[_c.PIXEL_FORMAT_PVRTC4] = 4;
+ _B[_c.PIXEL_FORMAT_PVRTC2] = 3;
+
+ var _p = cc.Texture2D.prototype;
+
+ // Extended properties
+ /** @expose */
+ _p.name;
+ cc.defineGetterSetter(_p, "name", _p.getName);
+ /** @expose */
+ _p.pixelFormat;
+ cc.defineGetterSetter(_p, "pixelFormat", _p.getPixelFormat);
+ /** @expose */
+ _p.pixelsWidth;
+ cc.defineGetterSetter(_p, "pixelsWidth", _p.getPixelsWide);
+ /** @expose */
+ _p.pixelsHeight;
+ cc.defineGetterSetter(_p, "pixelsHeight", _p.getPixelsHigh);
+ //cc.defineGetterSetter(_p, "size", _p.getContentSize, _p.setContentSize);
+ /** @expose */
+ _p.width;
+ cc.defineGetterSetter(_p, "width", _p._getWidth);
+ /** @expose */
+ _p.height;
+ cc.defineGetterSetter(_p, "height", _p._getHeight);
+};
+
+cc._tmp.PrototypeTextureAtlas = function () {
+
+ var _p = cc.TextureAtlas.prototype;
+
+ // Extended properties
+ /** @expose */
+ _p.totalQuads;
+ cc.defineGetterSetter(_p, "totalQuads", _p.getTotalQuads);
+ /** @expose */
+ _p.capacity;
+ cc.defineGetterSetter(_p, "capacity", _p.getCapacity);
+ /** @expose */
+ _p.quads;
+ cc.defineGetterSetter(_p, "quads", _p.getQuads, _p.setQuads);
+
+};
+
diff --git a/frameworks/cocos2d-html5/cocos2d/core/textures/TexturesWebGL.js b/frameworks/cocos2d-html5/cocos2d/core/textures/TexturesWebGL.js
new file mode 100644
index 0000000..2dfe145
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/textures/TexturesWebGL.js
@@ -0,0 +1,932 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc._tmp.WebGLTexture2D = function () {
+
+ /**
+ *
+ * This class allows to easily create OpenGL or Canvas 2D textures from images, text or raw data.
+ * The created cc.Texture2D object will always have power-of-two dimensions.
+ * Depending on how you create the cc.Texture2D object, the actual image area of the texture might be smaller than the texture dimensions
+ * i.e. "contentSize" != (pixelsWide, pixelsHigh) and (maxS, maxT) != (1.0, 1.0).
+ * Be aware that the content of the generated textures will be upside-down!
+ * @name cc.Texture2D
+ * @class
+ * @extends cc.Class
+ *
+ * @property {WebGLTexture} name - <@readonly> WebGLTexture Object
+ * @property {Number} pixelFormat - <@readonly> Pixel format of the texture
+ * @property {Number} pixelsWidth - <@readonly> Width in pixels
+ * @property {Number} pixelsHeight - <@readonly> Height in pixels
+ * @property {Number} width - Content width in points
+ * @property {Number} height - Content height in points
+ * @property {cc.GLProgram} shaderProgram - The shader program used by drawAtPoint and drawInRect
+ * @property {Number} maxS - Texture max S
+ * @property {Number} maxT - Texture max T
+ */
+ //Original : Texture2DWebGL
+ cc.Texture2D = cc.Class.extend(/** @lends cc.Texture2D# */{
+ // By default PVR images are treated as if they don't have the alpha channel premultiplied
+ _pVRHaveAlphaPremultiplied: true,
+ _pixelFormat: null,
+ _pixelsWide: 0,
+ _pixelsHigh: 0,
+ _name: "",
+ _contentSize: null,
+ maxS: 0,
+ maxT: 0,
+ _hasPremultipliedAlpha: false,
+ _hasMipmaps: false,
+
+ shaderProgram: null,
+
+ _textureLoaded: false,
+ _htmlElementObj: null,
+ _webTextureObj: null,
+
+ url: null,
+
+ /**
+ * constructor of cc.Texture2D
+ */
+ ctor: function () {
+ this._contentSize = cc.size(0, 0);
+ this._pixelFormat = cc.Texture2D.defaultPixelFormat;
+ },
+
+ /**
+ * release texture
+ */
+ releaseTexture: function () {
+ if (this._webTextureObj)
+ cc._renderContext.deleteTexture(this._webTextureObj);
+ this._htmlElementObj = null;
+ cc.loader.release(this.url);
+ },
+
+ /**
+ * pixel format of the texture
+ * @return {Number}
+ */
+ getPixelFormat: function () {
+ return this._pixelFormat;
+ },
+
+ /**
+ * width in pixels
+ * @return {Number}
+ */
+ getPixelsWide: function () {
+ return this._pixelsWide;
+ },
+
+ /**
+ * height in pixels
+ * @return {Number}
+ */
+ getPixelsHigh: function () {
+ return this._pixelsHigh;
+ },
+
+ /**
+ * get WebGLTexture Object
+ * @return {WebGLTexture}
+ */
+ getName: function () {
+ return this._webTextureObj;
+ },
+
+ /**
+ * content size
+ * @return {cc.Size}
+ */
+ getContentSize: function () {
+ return cc.size(this._contentSize.width / cc.contentScaleFactor(), this._contentSize.height / cc.contentScaleFactor());
+ },
+
+ _getWidth: function () {
+ return this._contentSize.width / cc.contentScaleFactor();
+ },
+ _getHeight: function () {
+ return this._contentSize.height / cc.contentScaleFactor();
+ },
+
+ /**
+ * get content size in pixels
+ * @return {cc.Size}
+ */
+ getContentSizeInPixels: function () {
+ return this._contentSize;
+ },
+
+ /**
+ * texture max S
+ * @return {Number}
+ */
+ getMaxS: function () {
+ return this.maxS;
+ },
+
+ /**
+ * set texture max S
+ * @param {Number} maxS
+ */
+ setMaxS: function (maxS) {
+ this.maxS = maxS;
+ },
+
+ /**
+ * get texture max T
+ * @return {Number}
+ */
+ getMaxT: function () {
+ return this.maxT;
+ },
+
+ /**
+ * set texture max T
+ * @param {Number} maxT
+ */
+ setMaxT: function (maxT) {
+ this.maxT = maxT;
+ },
+
+ /**
+ * return shader program used by drawAtPoint and drawInRect
+ * @return {cc.GLProgram}
+ */
+ getShaderProgram: function () {
+ return this.shaderProgram;
+ },
+
+ /**
+ * set shader program used by drawAtPoint and drawInRect
+ * @param {cc.GLProgram} shaderProgram
+ */
+ setShaderProgram: function (shaderProgram) {
+ this.shaderProgram = shaderProgram;
+ },
+
+ /**
+ * whether or not the texture has their Alpha premultiplied
+ * @return {Boolean}
+ */
+ hasPremultipliedAlpha: function () {
+ return this._hasPremultipliedAlpha;
+ },
+
+ /**
+ * whether or not use mipmap
+ * @return {Boolean}
+ */
+ hasMipmaps: function () {
+ return this._hasMipmaps;
+ },
+
+ /**
+ * description
+ * @return {string}
+ */
+ description: function () {
+ var _t = this;
+ return "";
+ },
+
+ /**
+ * These functions are needed to create mutable textures
+ * @param {Array} data
+ */
+ releaseData: function (data) {
+ data = null;
+ },
+
+ keepData: function (data, length) {
+ //The texture data mustn't be saved because it isn't a mutable texture.
+ return data;
+ },
+
+ /**
+ * Intializes with a texture2d with data
+ * @param {Array} data
+ * @param {Number} pixelFormat
+ * @param {Number} pixelsWide
+ * @param {Number} pixelsHigh
+ * @param {cc.Size} contentSize
+ * @return {Boolean}
+ */
+ initWithData: function (data, pixelFormat, pixelsWide, pixelsHigh, contentSize) {
+ var self = this, tex2d = cc.Texture2D;
+ var gl = cc._renderContext;
+ var format = gl.RGBA, type = gl.UNSIGNED_BYTE;
+
+ var bitsPerPixel = cc.Texture2D._B[pixelFormat];
+
+ var bytesPerRow = pixelsWide * bitsPerPixel / 8;
+ if (bytesPerRow % 8 === 0) {
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, 8);
+ } else if (bytesPerRow % 4 === 0) {
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4);
+ } else if (bytesPerRow % 2 === 0) {
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, 2);
+ } else {
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+ }
+
+ self._webTextureObj = gl.createTexture();
+ cc.glBindTexture2D(self);
+
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+
+ // Specify OpenGL texture image
+ switch (pixelFormat) {
+ case tex2d.PIXEL_FORMAT_RGBA8888:
+ format = gl.RGBA;
+ break;
+ case tex2d.PIXEL_FORMAT_RGB888:
+ format = gl.RGB;
+ break;
+ case tex2d.PIXEL_FORMAT_RGBA4444:
+ type = gl.UNSIGNED_SHORT_4_4_4_4;
+ break;
+ case tex2d.PIXEL_FORMAT_RGB5A1:
+ type = gl.UNSIGNED_SHORT_5_5_5_1;
+ break;
+ case tex2d.PIXEL_FORMAT_RGB565:
+ type = gl.UNSIGNED_SHORT_5_6_5;
+ break;
+ case tex2d.PIXEL_FORMAT_AI88:
+ format = gl.LUMINANCE_ALPHA;
+ break;
+ case tex2d.PIXEL_FORMAT_A8:
+ format = gl.ALPHA;
+ break;
+ case tex2d.PIXEL_FORMAT_I8:
+ format = gl.LUMINANCE;
+ break;
+ default:
+ cc.assert(0, cc._LogInfos.Texture2D_initWithData);
+ }
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, pixelsWide, pixelsHigh, 0, format, type, data);
+
+
+ self._contentSize.width = contentSize.width;
+ self._contentSize.height = contentSize.height;
+ self._pixelsWide = pixelsWide;
+ self._pixelsHigh = pixelsHigh;
+ self._pixelFormat = pixelFormat;
+ self.maxS = contentSize.width / pixelsWide;
+ self.maxT = contentSize.height / pixelsHigh;
+
+ self._hasPremultipliedAlpha = false;
+ self._hasMipmaps = false;
+ self.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE);
+
+ self._textureLoaded = true;
+
+ return true;
+ },
+
+ /**
+ Drawing extensions to make it easy to draw basic quads using a CCTexture2D object.
+ These functions require gl.TEXTURE_2D and both gl.VERTEX_ARRAY and gl.TEXTURE_COORD_ARRAY client states to be enabled.
+ */
+
+ /**
+ * draws a texture at a given point
+ * @param {cc.Point} point
+ */
+ drawAtPoint: function (point) {
+ var self = this;
+ var coordinates = [
+ 0.0, self.maxT,
+ self.maxS, self.maxT,
+ 0.0, 0.0,
+ self.maxS, 0.0],
+ gl = cc._renderContext;
+
+ var width = self._pixelsWide * self.maxS,
+ height = self._pixelsHigh * self.maxT;
+
+ var vertices = [
+ point.x, point.y, 0.0,
+ width + point.x, point.y, 0.0,
+ point.x, height + point.y, 0.0,
+ width + point.x, height + point.y, 0.0];
+
+ self._glProgramState.apply();
+ self._glProgramState._glprogram.setUniformsForBuiltins();
+
+ cc.glBindTexture2D(self);
+
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, gl.FLOAT, false, 0, vertices);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, coordinates);
+
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ },
+
+ /**
+ * draws a texture inside a rect
+ * @param {cc.Rect} rect
+ */
+ drawInRect: function (rect) {
+ var self = this;
+ var coordinates = [
+ 0.0, self.maxT,
+ self.maxS, self.maxT,
+ 0.0, 0.0,
+ self.maxS, 0.0];
+
+ var vertices = [rect.x, rect.y, /*0.0,*/
+ rect.x + rect.width, rect.y, /*0.0,*/
+ rect.x, rect.y + rect.height, /*0.0,*/
+ rect.x + rect.width, rect.y + rect.height /*0.0*/];
+
+ self._glProgramState.apply();
+ self._glProgramState._glprogram.setUniformsForBuiltins();
+
+ cc.glBindTexture2D(self);
+
+ var gl = cc._renderContext;
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, gl.FLOAT, false, 0, vertices);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, coordinates);
+
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ },
+
+ /**
+ Extensions to make it easy to create a CCTexture2D object from an image file.
+ Note that RGBA type textures will have their alpha premultiplied - use the blending mode (gl.ONE, gl.ONE_MINUS_SRC_ALPHA).
+ */
+
+ /**
+ * Initializes a texture from a UIImage object
+ * @param uiImage
+ * @return {Boolean}
+ */
+ initWithImage: function (uiImage) {
+ if (uiImage == null) {
+ cc.log(cc._LogInfos.Texture2D_initWithImage);
+ return false;
+ }
+
+ var imageWidth = uiImage.getWidth();
+ var imageHeight = uiImage.getHeight();
+
+ var maxTextureSize = cc.configuration.getMaxTextureSize();
+ if (imageWidth > maxTextureSize || imageHeight > maxTextureSize) {
+ cc.log(cc._LogInfos.Texture2D_initWithImage_2, imageWidth, imageHeight, maxTextureSize, maxTextureSize);
+ return false;
+ }
+ this._textureLoaded = true;
+
+ // always load premultiplied images
+ return this._initPremultipliedATextureWithImage(uiImage, imageWidth, imageHeight);
+ },
+
+ /**
+ * init with HTML element
+ * @param {HTMLImageElement|HTMLCanvasElement} element
+ */
+ initWithElement: function (element) {
+ if (!element)
+ return;
+ this._webTextureObj = cc._renderContext.createTexture();
+ this._htmlElementObj = element;
+ this._textureLoaded = true;
+ // Textures should be loaded with premultiplied alpha in order to avoid gray bleeding
+ // when semitransparent textures are interpolated (e.g. when scaled).
+ this._hasPremultipliedAlpha = true;
+ },
+
+ /**
+ * HTMLElement Object getter
+ * @return {HTMLElement}
+ */
+ getHtmlElementObj: function () {
+ return this._htmlElementObj;
+ },
+
+ /**
+ * whether texture is loaded
+ * @return {Boolean}
+ */
+ isLoaded: function () {
+ return this._textureLoaded;
+ },
+
+ /**
+ * handler of texture loaded event
+ * @param {Boolean} [premultiplied=false]
+ */
+ handleLoadedTexture: function (premultiplied) {
+ var self = this;
+ premultiplied =
+ (premultiplied !== undefined)
+ ? premultiplied
+ : self._hasPremultipliedAlpha;
+ // Not sure about this ! Some texture need to be updated even after loaded
+ if (!cc.game._rendererInitialized)
+ return;
+ if (!self._htmlElementObj)
+ return;
+ if (!self._htmlElementObj.width || !self._htmlElementObj.height)
+ return;
+
+ //upload image to buffer
+ var gl = cc._renderContext;
+
+ cc.glBindTexture2D(self);
+
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4);
+ if (premultiplied)
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
+
+ // Specify OpenGL texture image
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, self._htmlElementObj);
+
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+
+ self.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE);
+ cc.glBindTexture2D(null);
+ if (premultiplied)
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);
+
+ var pixelsWide = self._htmlElementObj.width;
+ var pixelsHigh = self._htmlElementObj.height;
+
+ self._pixelsWide = self._contentSize.width = pixelsWide;
+ self._pixelsHigh = self._contentSize.height = pixelsHigh;
+ self._pixelFormat = cc.Texture2D.PIXEL_FORMAT_RGBA8888;
+ self.maxS = 1;
+ self.maxT = 1;
+
+ self._hasPremultipliedAlpha = premultiplied;
+ self._hasMipmaps = false;
+ if (window.ENABLE_IMAEG_POOL) {
+ self._htmlElementObj = null;
+ }
+
+ //dispatch load event to listener.
+ self.dispatchEvent("load");
+ },
+
+ /**
+ Extensions to make it easy to create a cc.Texture2D object from a string of text.
+ Note that the generated textures are of type A8 - use the blending mode (gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA).
+ */
+ /**
+ * Initializes a texture from a string with dimensions, alignment, font name and font size (note: initWithString does not support on HTML5)
+ * @param {String} text
+ * @param {String | cc.FontDefinition} fontName or fontDefinition
+ * @param {Number} fontSize
+ * @param {cc.Size} dimensions
+ * @param {Number} hAlignment
+ * @param {Number} vAlignment
+ * @return {Boolean}
+ */
+ initWithString: function (text, fontName, fontSize, dimensions, hAlignment, vAlignment) {
+ cc.log(cc._LogInfos.Texture2D_initWithString);
+ return null;
+ },
+
+ /**
+ * Initializes a texture from a ETC file (note: initWithETCFile does not support on HTML5)
+ * @note Compatible to Cocos2d-x
+ * @param {String} file
+ * @return {Boolean}
+ */
+ initWithETCFile: function (file) {
+ cc.log(cc._LogInfos.Texture2D_initWithETCFile_2);
+ return false;
+ },
+
+ /**
+ * Initializes a texture from a PVR file
+ * @param {String} file
+ * @return {Boolean}
+ */
+ initWithPVRFile: function (file) {
+ cc.log(cc._LogInfos.Texture2D_initWithPVRFile_2);
+ return false;
+ },
+
+ /**
+ Extensions to make it easy to create a cc.Texture2D object from a PVRTC file
+ Note that the generated textures don't have their alpha premultiplied - use the blending mode (gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA).
+ */
+ /**
+ * Initializes a texture from a PVRTC buffer
+ * @note compatible to cocos2d-iphone interface.
+ * @param {Array} data
+ * @param {Number} level
+ * @param {Number} bpp
+ * @param {Boolean} hasAlpha
+ * @param {Number} length
+ * @param {Number} pixelFormat
+ * @return {Boolean}
+ */
+ initWithPVRTCData: function (data, level, bpp, hasAlpha, length, pixelFormat) {
+ cc.log(cc._LogInfos.Texture2D_initWithPVRTCData_2);
+ return false;
+ },
+
+ /**
+ * sets the min filter, mag filter, wrap s and wrap t texture parameters.
+ * If the texture size is NPOT (non power of 2), then in can only use gl.CLAMP_TO_EDGE in gl.TEXTURE_WRAP_{S,T}.
+ * @param {Object|Number} texParams texParams object or minFilter
+ * @param {Number} [magFilter]
+ * @param {Number} [wrapS]
+ * @param {Number} [wrapT]
+ */
+ setTexParameters: function (texParams, magFilter, wrapS, wrapT) {
+ var _t = this;
+ var gl = cc._renderContext;
+
+ if (magFilter !== undefined)
+ texParams = {minFilter: texParams, magFilter: magFilter, wrapS: wrapS, wrapT: wrapT};
+
+ cc.assert((_t._pixelsWide === cc.NextPOT(_t._pixelsWide) && _t._pixelsHigh === cc.NextPOT(_t._pixelsHigh)) ||
+ (texParams.wrapS === gl.CLAMP_TO_EDGE && texParams.wrapT === gl.CLAMP_TO_EDGE),
+ "WebGLRenderingContext.CLAMP_TO_EDGE should be used in NPOT textures");
+
+ cc.glBindTexture2D(_t);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texParams.minFilter);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texParams.magFilter);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texParams.wrapS);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texParams.wrapT);
+ },
+
+ /**
+ * sets antialias texture parameters:
+ * - GL_TEXTURE_MIN_FILTER = GL_NEAREST
+ * - GL_TEXTURE_MAG_FILTER = GL_NEAREST
+ */
+ setAntiAliasTexParameters: function () {
+ var gl = cc._renderContext;
+
+ cc.glBindTexture2D(this);
+ if (!this._hasMipmaps)
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ else
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ },
+
+ /**
+ * sets alias texture parameters:
+ * GL_TEXTURE_MIN_FILTER = GL_NEAREST
+ * GL_TEXTURE_MAG_FILTER = GL_NEAREST
+ */
+ setAliasTexParameters: function () {
+ var gl = cc._renderContext;
+
+ cc.glBindTexture2D(this);
+ if (!this._hasMipmaps)
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ else
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ },
+
+ /**
+ * Generates mipmap images for the texture.
+ * It only works if the texture size is POT (power of 2).
+ */
+ generateMipmap: function () {
+ var _t = this;
+ cc.assert(_t._pixelsWide === cc.NextPOT(_t._pixelsWide) && _t._pixelsHigh === cc.NextPOT(_t._pixelsHigh), "Mimpap texture only works in POT textures");
+
+ cc.glBindTexture2D(_t);
+ cc._renderContext.generateMipmap(cc._renderContext.TEXTURE_2D);
+ _t._hasMipmaps = true;
+ },
+
+ /**
+ * returns the pixel format.
+ * @return {String}
+ */
+ stringForFormat: function () {
+ return cc.Texture2D._M[this._pixelFormat];
+ },
+
+ /**
+ * returns the bits-per-pixel of the in-memory OpenGL texture
+ * @return {Number}
+ */
+ bitsPerPixelForFormat: function (format) {//TODO I want to delete the format argument, use this._pixelFormat
+ format = format || this._pixelFormat;
+ var value = cc.Texture2D._B[format];
+ if (value != null) return value;
+ cc.log(cc._LogInfos.Texture2D_bitsPerPixelForFormat, format);
+ return -1;
+ },
+
+ _initPremultipliedATextureWithImage: function (uiImage, width, height) {
+ var tex2d = cc.Texture2D;
+ var tempData = uiImage.getData();
+ var inPixel32 = null;
+ var inPixel8 = null;
+ var outPixel16 = null;
+ var hasAlpha = uiImage.hasAlpha();
+ var imageSize = cc.size(uiImage.getWidth(), uiImage.getHeight());
+ var pixelFormat = tex2d.defaultPixelFormat;
+ var bpp = uiImage.getBitsPerComponent();
+
+ // compute pixel format
+ if (!hasAlpha) {
+ if (bpp >= 8) {
+ pixelFormat = tex2d.PIXEL_FORMAT_RGB888;
+ } else {
+ cc.log(cc._LogInfos.Texture2D__initPremultipliedATextureWithImage);
+ pixelFormat = tex2d.PIXEL_FORMAT_RGB565;
+ }
+ }
+
+ // Repack the pixel data into the right format
+ var i, length = width * height;
+
+ if (pixelFormat === tex2d.PIXEL_FORMAT_RGB565) {
+ if (hasAlpha) {
+ // Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGGBBBBB"
+ tempData = new Uint16Array(width * height);
+ inPixel32 = uiImage.getData();
+
+ for (i = 0; i < length; ++i) {
+ tempData[i] =
+ ((((inPixel32[i] >> 0) & 0xFF) >> 3) << 11) | // R
+ ((((inPixel32[i] >> 8) & 0xFF) >> 2) << 5) | // G
+ ((((inPixel32[i] >> 16) & 0xFF) >> 3) << 0); // B
+ }
+ } else {
+ // Convert "RRRRRRRRRGGGGGGGGBBBBBBBB" to "RRRRRGGGGGGBBBBB"
+ tempData = new Uint16Array(width * height);
+ inPixel8 = uiImage.getData();
+
+ for (i = 0; i < length; ++i) {
+ tempData[i] =
+ (((inPixel8[i] & 0xFF) >> 3) << 11) | // R
+ (((inPixel8[i] & 0xFF) >> 2) << 5) | // G
+ (((inPixel8[i] & 0xFF) >> 3) << 0); // B
+ }
+ }
+ } else if (pixelFormat === tex2d.PIXEL_FORMAT_RGBA4444) {
+ // Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRGGGGBBBBAAAA"
+ tempData = new Uint16Array(width * height);
+ inPixel32 = uiImage.getData();
+
+ for (i = 0; i < length; ++i) {
+ tempData[i] =
+ ((((inPixel32[i] >> 0) & 0xFF) >> 4) << 12) | // R
+ ((((inPixel32[i] >> 8) & 0xFF) >> 4) << 8) | // G
+ ((((inPixel32[i] >> 16) & 0xFF) >> 4) << 4) | // B
+ ((((inPixel32[i] >> 24) & 0xFF) >> 4) << 0); // A
+ }
+ } else if (pixelFormat === tex2d.PIXEL_FORMAT_RGB5A1) {
+ // Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGBBBBBA"
+ tempData = new Uint16Array(width * height);
+ inPixel32 = uiImage.getData();
+
+ for (i = 0; i < length; ++i) {
+ tempData[i] =
+ ((((inPixel32[i] >> 0) & 0xFF) >> 3) << 11) | // R
+ ((((inPixel32[i] >> 8) & 0xFF) >> 3) << 6) | // G
+ ((((inPixel32[i] >> 16) & 0xFF) >> 3) << 1) | // B
+ ((((inPixel32[i] >> 24) & 0xFF) >> 7) << 0); // A
+ }
+ } else if (pixelFormat === tex2d.PIXEL_FORMAT_A8) {
+ // Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "AAAAAAAA"
+ tempData = new Uint8Array(width * height);
+ inPixel32 = uiImage.getData();
+
+ for (i = 0; i < length; ++i) {
+ tempData[i] = (inPixel32 >> 24) & 0xFF; // A
+ }
+ }
+
+ if (hasAlpha && pixelFormat === tex2d.PIXEL_FORMAT_RGB888) {
+ // Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRRRRGGGGGGGGBBBBBBBB"
+ inPixel32 = uiImage.getData();
+ tempData = new Uint8Array(width * height * 3);
+
+ for (i = 0; i < length; ++i) {
+ tempData[i * 3] = (inPixel32 >> 0) & 0xFF; // R
+ tempData[i * 3 + 1] = (inPixel32 >> 8) & 0xFF; // G
+ tempData[i * 3 + 2] = (inPixel32 >> 16) & 0xFF; // B
+ }
+ }
+
+ this.initWithData(tempData, pixelFormat, width, height, imageSize);
+
+ if (tempData != uiImage.getData())
+ tempData = null;
+
+ this._hasPremultipliedAlpha = uiImage.isPremultipliedAlpha();
+ return true;
+ },
+
+ /**
+ * add listener for loaded event
+ * @param {Function} callback
+ * @param {cc.Node} target
+ * @deprecated since 3.1, please use addEventListener instead
+ */
+ addLoadedEventListener: function (callback, target) {
+ this.addEventListener("load", callback, target);
+ },
+
+ /**
+ * remove listener from listeners by target
+ * @param {cc.Node} target
+ */
+ removeLoadedEventListener: function (target) {
+ this.removeEventTarget("load", target);
+ }
+ });
+};
+
+cc._tmp.WebGLTextureAtlas = function () {
+ var _p = cc.TextureAtlas.prototype;
+ _p._setupVBO = function () {
+ var _t = this;
+ var gl = cc._renderContext;
+ //create WebGLBuffer
+ _t._buffersVBO[0] = gl.createBuffer();
+ _t._buffersVBO[1] = gl.createBuffer();
+
+ _t._quadsWebBuffer = gl.createBuffer();
+ _t._mapBuffers();
+ };
+
+ _p._mapBuffers = function () {
+ var _t = this;
+ var gl = cc._renderContext;
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, _t._quadsWebBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, _t._quadsArrayBuffer, gl.DYNAMIC_DRAW);
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, _t._buffersVBO[1]);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, _t._indices, gl.STATIC_DRAW);
+
+ //cc.checkGLErrorDebug();
+ };
+
+ /**
+ * Draws n quads from an index (offset).
+ * n + start can't be greater than the capacity of the atlas
+ * @param {Number} n
+ * @param {Number} start
+ */
+ _p.drawNumberOfQuads = function (n, start) {
+ var _t = this;
+ start = start || 0;
+ if (0 === n || !_t.texture || !_t.texture.isLoaded())
+ return;
+
+ var gl = cc._renderContext;
+ cc.glBindTexture2D(_t.texture);
+
+ //
+ // Using VBO without VAO
+ //
+ //vertices
+ //gl.bindBuffer(gl.ARRAY_BUFFER, _t._buffersVBO[0]);
+ // XXX: update is done in draw... perhaps it should be done in a timer
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, _t._quadsWebBuffer);
+ if (_t.dirty) {
+ gl.bufferData(gl.ARRAY_BUFFER, _t._quadsArrayBuffer, gl.DYNAMIC_DRAW);
+ _t.dirty = false;
+ }
+
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS);
+
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 24, 0); // vertices
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, 12); // colors
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 24, 16); // tex coords
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, _t._buffersVBO[1]);
+
+ if (cc.TEXTURE_ATLAS_USE_TRIANGLE_STRIP)
+ gl.drawElements(gl.TRIANGLE_STRIP, n * 6, gl.UNSIGNED_SHORT, start * 6 * _t._indices.BYTES_PER_ELEMENT);
+ else
+ gl.drawElements(gl.TRIANGLES, n * 6, gl.UNSIGNED_SHORT, start * 6 * _t._indices.BYTES_PER_ELEMENT);
+
+ cc.g_NumberOfDraws++;
+ //cc.checkGLErrorDebug();
+ };
+};
+
+cc._tmp.WebGLTextureCache = function () {
+ var _p = cc.textureCache;
+
+ _p.handleLoadedTexture = function (url, img) {
+ var locTexs = this._textures, tex, ext;
+ //remove judge(webgl)
+ if (!cc.game._rendererInitialized) {
+ locTexs = this._loadedTexturesBefore;
+ }
+ tex = locTexs[url];
+ if (!tex) {
+ tex = locTexs[url] = new cc.Texture2D();
+ tex.url = url;
+ }
+ tex.initWithElement(img);
+ ext = cc.path.extname(url);
+ if (ext === ".png") {
+ tex.handleLoadedTexture(true);
+ }
+ else {
+ tex.handleLoadedTexture();
+ }
+ return tex;
+ };
+
+ /**
+ * Returns a Texture2D object given an file image
+ * If the file image was not previously loaded, it will create a new Texture2D
+ * object and it will return it. It will use the filename as a key.
+ * Otherwise it will return a reference of a previously loaded image.
+ * Supported image extensions: .png, .jpg, .gif
+ * @param {String} url
+ * @param {Function} cb
+ * @param {Object} target
+ * @return {cc.Texture2D}
+ * @example
+ * //example
+ * cc.textureCache.addImage("hello.png");
+ */
+ _p.addImage = function (url, cb, target) {
+ cc.assert(url, cc._LogInfos.Texture2D_addImage_2);
+
+ var locTexs = this._textures;
+ //remove judge(webgl)
+ if (!cc.game._rendererInitialized) {
+ locTexs = this._loadedTexturesBefore;
+ }
+ var tex = locTexs[url] || locTexs[cc.loader._getAliase(url)];
+ if (tex) {
+ if (tex.isLoaded()) {
+ cb && cb.call(target, tex);
+ return tex;
+ }
+ else {
+ tex.addEventListener("load", function () {
+ cb && cb.call(target, tex);
+ }, target);
+ return tex;
+ }
+ }
+
+ tex = locTexs[url] = new cc.Texture2D();
+ tex.url = url;
+ var basePath = cc.loader.getBasePath ? cc.loader.getBasePath() : cc.loader.resPath;
+ cc.loader.loadImg(cc.path.join(basePath || "", url), function (err, img) {
+ if (err)
+ return cb && cb.call(target, err);
+
+ var texResult = cc.textureCache.handleLoadedTexture(url, img);
+ cb && cb.call(target, texResult);
+ });
+
+ return tex;
+ };
+
+ _p.addImageAsync = _p.addImage;
+ _p = null;
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/core/utils/BinaryLoader.js b/frameworks/cocos2d-html5/cocos2d/core/utils/BinaryLoader.js
new file mode 100644
index 0000000..46b82b6
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/utils/BinaryLoader.js
@@ -0,0 +1,155 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+
+/**
+ * Load binary data by url.
+ * @function
+ * @param {String} url
+ * @param {Function} [cb]
+ */
+
+cc.loader.loadBinary = function (url, cb) {
+ var self = this;
+ var xhr = this.getXMLHttpRequest(),
+ errInfo = "load " + url + " failed!";
+ xhr.open("GET", url, true);
+ xhr.responseType = 'arraybuffer';
+ if (cc.loader.loadBinary._IEFilter) {
+ // IE-specific logic here
+ xhr.setRequestHeader("Accept-Charset", "x-user-defined");
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState === 4 && xhr.status === 200) {
+ var fileContents = cc._convertResponseBodyToText(xhr["responseBody"]);
+ cb(null, self._str2Uint8Array(fileContents));
+ } else cb(errInfo);
+ };
+ } else {
+ if (xhr.overrideMimeType) xhr.overrideMimeType("text\/plain; charset=x-user-defined");
+ xhr.onload = function () {
+ xhr.readyState === 4 && xhr.status === 200 ? cb(null, new Uint8Array(xhr.response)) : cb(errInfo);
+ };
+ }
+ xhr.send(null);
+};
+
+cc.loader.loadBinary._IEFilter = (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent) && window.IEBinaryToArray_ByteStr && window.IEBinaryToArray_ByteStr_Last);
+
+cc.loader._str2Uint8Array = function (strData) {
+ if (!strData)
+ return null;
+
+ var arrData = new Uint8Array(strData.length);
+ for (var i = 0; i < strData.length; i++) {
+ arrData[i] = strData.charCodeAt(i) & 0xff;
+ }
+ return arrData;
+};
+
+/**
+ * Load binary data by url synchronously
+ * @function
+ * @param {String} url
+ * @return {Uint8Array}
+ */
+cc.loader.loadBinarySync = function (url) {
+ var self = this;
+ var req = this.getXMLHttpRequest();
+ req.timeout = 0;
+ var errInfo = "load " + url + " failed!";
+ req.open('GET', url, false);
+ var arrayInfo = null;
+ if (cc.loader.loadBinary._IEFilter) {
+ req.setRequestHeader("Accept-Charset", "x-user-defined");
+ req.send(null);
+ if (req.status !== 200) {
+ cc.log(errInfo);
+ return null;
+ }
+
+ var fileContents = cc._convertResponseBodyToText(req["responseBody"]);
+ if (fileContents) {
+ arrayInfo = self._str2Uint8Array(fileContents);
+ }
+ } else {
+ if (req.overrideMimeType)
+ req.overrideMimeType('text\/plain; charset=x-user-defined');
+ req.send(null);
+ if (req.status !== 200) {
+ cc.log(errInfo);
+ return null;
+ }
+
+ arrayInfo = self._str2Uint8Array(req.responseText);
+ }
+ return arrayInfo;
+};
+
+//Compatibility with IE9
+window.Uint8Array = window.Uint8Array || window.Array;
+
+if (cc.loader.loadBinary._IEFilter) {
+ var IEBinaryToArray_ByteStr_Script =
+ "\r\n" +
+ //"\r\n";
+
+ // inject VBScript
+ //document.write(IEBinaryToArray_ByteStr_Script);
+ var myVBScript = document.createElement('script');
+ myVBScript.type = "text/vbscript";
+ myVBScript.textContent = IEBinaryToArray_ByteStr_Script;
+ document.body.appendChild(myVBScript);
+
+ // helper to convert from responseBody to a "responseText" like thing
+ cc._convertResponseBodyToText = function (binary) {
+ var byteMapping = {};
+ for (var i = 0; i < 256; i++) {
+ for (var j = 0; j < 256; j++) {
+ byteMapping[ String.fromCharCode(i + j * 256) ] =
+ String.fromCharCode(i) + String.fromCharCode(j);
+ }
+ }
+ var rawBytes = IEBinaryToArray_ByteStr(binary);
+ var lastChr = IEBinaryToArray_ByteStr_Last(binary);
+ return rawBytes.replace(/[\s\S]/g,
+ function (match) {
+ return byteMapping[match];
+ }) + lastChr;
+ };
+}
diff --git a/frameworks/cocos2d-html5/cocos2d/core/utils/CCProfiler.js b/frameworks/cocos2d-html5/cocos2d/core/utils/CCProfiler.js
new file mode 100644
index 0000000..94d0c41
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/utils/CCProfiler.js
@@ -0,0 +1,151 @@
+cc.profiler = (function () {
+ var _showFPS = false;
+ var _inited = false;
+ var _frames = 0, _frameRate = 0, _lastSPF = 0, _accumDt = 0;
+ var _afterVisitListener = null,
+ _FPSLabel = document.createElement('div'),
+ _SPFLabel = document.createElement('div'),
+ _drawsLabel = document.createElement('div'),
+ _fps = document.createElement('div');
+
+ var LEVEL_DET_FACTOR = 0.6, _levelDetCycle = 10;
+ var LEVELS = [0, 10, 20, 30];
+ var _fpsCount = [0, 0, 0, 0];
+ var _currLevel = 3, _analyseCount = 0, _totalFPS = 0;
+
+ _fps.id = 'fps';
+ _fps.style.position = 'absolute';
+ _fps.style.padding = '3px';
+ _fps.style.textAlign = 'left';
+ _fps.style.backgroundColor = 'rgb(0, 0, 34)';
+ _fps.style.bottom = cc.DIRECTOR_STATS_POSITION.y + '0px';
+ _fps.style.left = cc.DIRECTOR_STATS_POSITION.x + 'px';
+ _fps.style.width = '45px';
+ _fps.style.height = '80px';
+
+ var labels = [_drawsLabel, _SPFLabel, _FPSLabel];
+ for (var i = 0; i < 3; ++i) {
+ var style = labels[i].style;
+ style.color = 'rgb(0, 255, 255)';
+ style.font = 'bold 12px Helvetica, Arial';
+ style.lineHeight = '20px';
+ style.width = '100%';
+ _fps.appendChild(labels[i]);
+ }
+
+ var analyseFPS = function (fps) {
+ var lastId = LEVELS.length - 1, i = lastId, ratio, average = 0;
+ _analyseCount++;
+ _totalFPS += fps;
+
+ for (; i >= 0; i--) {
+ if (fps >= LEVELS[i]) {
+ _fpsCount[i]++;
+ break;
+ }
+ }
+
+ if (_analyseCount >= _levelDetCycle) {
+ average = _totalFPS / _levelDetCycle;
+ for (i = lastId; i > 0; i--) {
+ ratio = _fpsCount[i] / _levelDetCycle;
+ // Determined level
+ if (ratio >= LEVEL_DET_FACTOR && average >= LEVELS[i]) {
+ // Level changed
+ if (i != _currLevel) {
+ _currLevel = i;
+ profiler.onFrameRateChange && profiler.onFrameRateChange(average.toFixed(2));
+ }
+ break;
+ }
+ // If no level determined, that means the framerate is not stable
+ }
+
+ _changeCount = 0;
+ _analyseCount = 0;
+ _totalFPS = 0;
+ for (i = lastId; i > 0; i--) {
+ _fpsCount[i] = 0;
+ }
+ }
+ };
+
+ var afterVisit = function () {
+ _lastSPF = cc.director.getSecondsPerFrame();
+ _frames++;
+ _accumDt += cc.director.getDeltaTime();
+
+ if (_accumDt > cc.DIRECTOR_FPS_INTERVAL) {
+ _frameRate = _frames / _accumDt;
+ _frames = 0;
+ _accumDt = 0;
+
+ if (profiler.onFrameRateChange) {
+ analyseFPS(_frameRate);
+ }
+
+ if (_showFPS) {
+ var mode = cc._renderType === cc.game.RENDER_TYPE_CANVAS ? "\n canvas" : "\n webgl";
+ _SPFLabel.innerHTML = _lastSPF.toFixed(3);
+ _FPSLabel.innerHTML = _frameRate.toFixed(1).toString() + mode;
+ _drawsLabel.innerHTML = (0 | cc.g_NumberOfDraws).toString();
+ }
+ }
+ };
+
+ var profiler = {
+ onFrameRateChange: null,
+
+ getSecondsPerFrame: function () {
+ return _lastSPF;
+ },
+ getFrameRate: function () {
+ return _frameRate;
+ },
+
+ setProfileDuration: function (duration) {
+ if (!isNaN(duration) && duration > 0) {
+ _levelDetCycle = duration / cc.DIRECTOR_FPS_INTERVAL;
+ }
+ },
+
+ resumeProfiling: function () {
+ cc.eventManager.addListener(_afterVisitListener, 1);
+ },
+
+ stopProfiling: function () {
+ cc.eventManager.removeListener(_afterVisitListener);
+ },
+
+ isShowingStats: function () {
+ return _showFPS;
+ },
+
+ showStats: function () {
+ if (!_inited) {
+ this.init();
+ }
+
+ if (_fps.parentElement === null) {
+ cc.container.appendChild(_fps);
+ }
+ _showFPS = true;
+ },
+
+ hideStats: function () {
+ _showFPS = false;
+ if (_fps.parentElement === cc.container) {
+ cc.container.removeChild(_fps);
+ }
+ },
+
+ init: function () {
+ if (!_inited) {
+ _afterVisitListener = cc.eventManager.addCustomListener(cc.Director.EVENT_AFTER_VISIT, afterVisit);
+ _inited = true;
+ }
+ }
+ };
+
+ return profiler;
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/core/utils/CCSimplePool.js b/frameworks/cocos2d-html5/cocos2d/core/utils/CCSimplePool.js
new file mode 100644
index 0000000..30fa22c
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/core/utils/CCSimplePool.js
@@ -0,0 +1,74 @@
+/****************************************************************************
+ Copyright (c) 2016 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.SimplePool = function () {
+ this._pool = [];
+};
+cc.SimplePool.prototype = {
+ constructor: cc.SimplePool,
+
+ size: function () {
+ return this._pool.length;
+ },
+
+ put: function (obj) {
+ if (obj && this._pool.indexOf(obj) === -1) {
+ this._pool.unshift(obj);
+ }
+ },
+
+ get: function () {
+ var last = this._pool.length-1;
+ if (last < 0) {
+ return null;
+ }
+ else {
+ var obj = this._pool[last];
+ this._pool.length = last;
+ return obj;
+ }
+ },
+
+ find: function (finder, end) {
+ var found, i, obj, pool = this._pool, last = pool.length-1;
+ for (i = pool.length; i >= 0; --i) {
+ obj = pool[i];
+ found = finder(i, obj);
+ if (found) {
+ pool[i] = pool[last];
+ pool.length = last;
+ return obj;
+ }
+ }
+ if (end) {
+ var index = end();
+ if (index >= 0) {
+ pool[index] = pool[last];
+ pool.length = last;
+ return obj;
+ }
+ }
+ return null;
+ }
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/effects/CCGrabber.js b/frameworks/cocos2d-html5/cocos2d/effects/CCGrabber.js
new file mode 100644
index 0000000..2138025
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/effects/CCGrabber.js
@@ -0,0 +1,110 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * FBO class that grabs the the contents of the screen
+ * @class
+ * @extends cc.Class
+ */
+cc.Grabber = cc.Class.extend({
+ _FBO:null,
+ _oldFBO:null,
+ _oldClearColor:null,
+
+ _gl:null,
+
+ /**
+ * constructor of cc.Grabber
+ */
+ ctor:function () {
+ cc.sys._checkWebGLRenderMode();
+ this._gl = cc._renderContext;
+ this._oldClearColor = [0, 0, 0, 0];
+ this._oldFBO = null;
+ // generate FBO
+ this._FBO = this._gl.createFramebuffer();
+ },
+
+ /**
+ * grab
+ * @param {cc.Texture2D} texture
+ */
+ grab:function (texture) {
+ var locGL = this._gl;
+ this._oldFBO = locGL.getParameter(locGL.FRAMEBUFFER_BINDING);
+ // bind
+ locGL.bindFramebuffer(locGL.FRAMEBUFFER, this._FBO);
+ // associate texture with FBO
+ locGL.framebufferTexture2D(locGL.FRAMEBUFFER, locGL.COLOR_ATTACHMENT0, locGL.TEXTURE_2D, texture._webTextureObj, 0);
+
+ // check if it worked (probably worth doing :) )
+ var status = locGL.checkFramebufferStatus(locGL.FRAMEBUFFER);
+ if (status !== locGL.FRAMEBUFFER_COMPLETE)
+ cc.log("Frame Grabber: could not attach texture to frmaebuffer");
+ locGL.bindFramebuffer(locGL.FRAMEBUFFER, this._oldFBO);
+ },
+
+ /**
+ * should be invoked before drawing
+ * @param {cc.Texture2D} texture
+ */
+ beforeRender:function (texture) {
+ var locGL = this._gl;
+ this._oldFBO = locGL.getParameter(locGL.FRAMEBUFFER_BINDING);
+ locGL.bindFramebuffer(locGL.FRAMEBUFFER, this._FBO);
+
+ // save clear color
+ this._oldClearColor = locGL.getParameter(locGL.COLOR_CLEAR_VALUE);
+
+ // BUG XXX: doesn't work with RGB565.
+ locGL.clearColor(0, 0, 0, 0);
+
+ // BUG #631: To fix #631, uncomment the lines with #631
+ // Warning: But it CCGrabber won't work with 2 effects at the same time
+ // glClearColor(0.0f,0.0f,0.0f,1.0f); // #631
+
+ locGL.clear(locGL.COLOR_BUFFER_BIT | locGL.DEPTH_BUFFER_BIT);
+
+ // glColorMask(true, true, true, false); // #631
+ },
+
+ /**
+ * should be invoked after drawing
+ * @param {cc.Texture2D} texture
+ */
+ afterRender:function (texture) {
+ var locGL = this._gl;
+ locGL.bindFramebuffer(locGL.FRAMEBUFFER, this._oldFBO);
+ locGL.colorMask(true, true, true, true); // #631
+ },
+
+ /**
+ * delete FBO
+ */
+ destroy:function(){
+ this._gl.deleteFramebuffer(this._FBO);
+ }
+});
diff --git a/frameworks/cocos2d-html5/cocos2d/effects/CCGrid.js b/frameworks/cocos2d-html5/cocos2d/effects/CCGrid.js
new file mode 100644
index 0000000..361cba8
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/effects/CCGrid.js
@@ -0,0 +1,850 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2009 On-Core
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Base class for cc.Grid
+ * @class
+ * @extends cc.Class
+ */
+cc.GridBase = cc.Class.extend(/** @lends cc.GridBase# */{
+ _active: false,
+ _reuseGrid: 0,
+ _gridSize: null,
+ _gridRect: null,
+ _texture: null,
+ _step: null,
+ _grabber: null,
+ _isTextureFlipped: false,
+ _glProgramState: null,
+ _directorProjection: 0,
+
+ _dirty: false,
+
+ /**
+ * create one cc.GridBase Object
+ * Constructor of cc.GridBase
+ * @param {cc.Size} gridSize
+ * @param {cc.Texture2D} [texture=]
+ * @param {Boolean} [flipped=]
+ * @param {cc.Rect} rect
+ */
+ ctor: function (gridSize, texture, flipped, rect) {
+ cc.sys._checkWebGLRenderMode();
+ this._active = false;
+ this._reuseGrid = 0;
+ this._gridSize = null;
+ this._gridRect = new cc.rect();
+ this._texture = null;
+ this._step = cc.p(0, 0);
+ this._grabber = null;
+ this._isTextureFlipped = false;
+ this._glProgramState = null;
+ this._directorProjection = 0;
+ this._dirty = false;
+
+ if (gridSize !== undefined)
+ this.initWithSize(gridSize, texture, flipped, rect);
+ },
+
+ /**
+ * whether or not the grid is active
+ * @return {Boolean}
+ */
+ isActive: function () {
+ return this._active;
+ },
+
+ /**
+ * whether or not the grid is active
+ * @param {Number} active
+ */
+ setActive: function (active) {
+ this._active = active;
+ if (!active) {
+ var director = cc.director;
+ var proj = director.getProjection();
+ director.setProjection(proj);
+ }
+ },
+
+ /**
+ * get number of times that the grid will be reused
+ * @return {Number}
+ */
+ getReuseGrid: function () {
+ return this._reuseGrid;
+ },
+ /**
+ * set number of times that the grid will be reused
+ * @param reuseGrid
+ */
+ setReuseGrid: function (reuseGrid) {
+ this._reuseGrid = reuseGrid;
+ },
+
+ /**
+ * get size of the grid
+ * @return {cc.Size}
+ */
+ getGridSize: function () {
+ return cc.size(this._gridSize.width, this._gridSize.height);
+ },
+
+ /**
+ * set size of the grid
+ * @param {cc.Size} gridSize
+ */
+ setGridSize: function (gridSize) {
+ this._gridSize.width = parseInt(gridSize.width);
+ this._gridSize.height = parseInt(gridSize.height);
+ },
+
+ /**
+ * set rect of the grid
+ * @param {cc.Rect} rect
+ */
+ setGridRect: function (rect) {
+ this._gridRect = rect;
+ },
+
+ /**
+ * get rect of the grid
+ * @return {cc.Rect} rect
+ */
+ getGridRect: function () {
+ return this._gridRect;
+ },
+
+ /**
+ * get pixels between the grids
+ * @return {cc.Point}
+ */
+ getStep: function () {
+ return cc.p(this._step.x, this._step.y);
+ },
+
+ /**
+ * set pixels between the grids
+ * @param {cc.Point} step
+ */
+ setStep: function (step) {
+ this._step.x = step.x;
+ this._step.y = step.y;
+ },
+
+ /**
+ * get whether or not the texture is flipped
+ * @return {Boolean}
+ */
+ isTextureFlipped: function () {
+ return this._isTextureFlipped;
+ },
+
+ /**
+ * set whether or not the texture is flipped
+ * @param {Boolean} flipped
+ */
+ setTextureFlipped: function (flipped) {
+ if (this._isTextureFlipped !== flipped) {
+ this._isTextureFlipped = flipped;
+ this.calculateVertexPoints();
+ }
+ },
+
+ /**
+ *
+ * @param {cc.Size} gridSize
+ * @param {cc.Texture2D} [texture=]
+ * @param {Boolean} [flipped=false]
+ * @param {cc.Rect} [rect=]
+ * @returns {boolean}
+ */
+ initWithSize: function (gridSize, texture, flipped, rect) {
+ if (!texture) {
+ var director = cc.director;
+ var winSize = director.getWinSizeInPixels();
+
+ var POTWide = cc.NextPOT(winSize.width);
+ var POTHigh = cc.NextPOT(winSize.height);
+
+ var data = new Uint8Array(POTWide * POTHigh * 4);
+ if (!data) {
+ cc.log("cocos2d: CCGrid: not enough memory.");
+ return false;
+ }
+
+ texture = new cc.Texture2D();
+ // we only use rgba8888
+ texture.initWithData(data, cc.Texture2D.PIXEL_FORMAT_RGBA8888, POTWide, POTHigh, winSize);
+ if (!texture) {
+ cc.log("cocos2d: CCGrid: error creating texture");
+ return false;
+ }
+ }
+
+ flipped = flipped || false;
+
+ this._active = false;
+ this._reuseGrid = 0;
+ this._gridSize = gridSize;
+ this._texture = texture;
+ this._isTextureFlipped = flipped;
+ if (rect === undefined || cc._rectEqualToZero(rect)) {
+ var size = this._texture.getContentSize();
+ rect = new cc.rect(0, 0, size.width, size.height);
+ }
+
+ this._gridRect = rect;
+
+ this._step.x = this._gridRect.width / gridSize.width;
+ this._step.y = this._gridRect.height / gridSize.height;
+
+ this._grabber = new cc.Grabber();
+ if (!this._grabber)
+ return false;
+ this._grabber.grab(this._texture);
+ this._glProgramState = cc.GLProgramState.getOrCreateWithGLProgram(cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE));
+ this.calculateVertexPoints();
+ return true;
+ },
+
+ beforeDraw: function () {
+ // save projection
+ this._directorProjection = cc.director.getProjection();
+
+ //this.set2DProjection(); //TODO why?
+ var size = cc.director.getWinSizeInPixels();
+ gl.viewport(0, 0, size.width, size.height);
+ this._grabber.beforeRender(this._texture);
+ },
+
+ afterDraw: function (target) {
+ this._grabber.afterRender(this._texture);
+
+ // restore projection
+ //cc.director.setProjection(this._directorProjection);
+ cc.director.setViewport();
+
+ cc.glBindTexture2D(this._texture);
+ this.beforeBlit();
+ this.blit(target);
+ this.afterBlit();
+ },
+
+ beforeBlit: function () {
+ },
+
+ afterBlit: function () {
+ },
+
+ blit: function () {
+ cc.log("cc.GridBase.blit(): Shall be overridden in subclass.");
+ },
+
+ reuse: function () {
+ cc.log("cc.GridBase.reuse(): Shall be overridden in subclass.");
+ },
+
+ calculateVertexPoints: function () {
+ cc.log("cc.GridBase.calculateVertexPoints(): Shall be overridden in subclass.");
+ },
+
+ set2DProjection: function () {
+ var winSize = cc.director.getWinSizeInPixels();
+
+ var gl = cc._renderContext;
+ gl.viewport(0, 0, winSize.width, winSize.height);
+ cc.kmGLMatrixMode(cc.KM_GL_PROJECTION);
+ cc.kmGLLoadIdentity();
+
+ var orthoMatrix = cc.math.Matrix4.createOrthographicProjection(0, winSize.width, 0, winSize.height, -1, 1);
+ cc.kmGLMultMatrix(orthoMatrix);
+
+ cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
+ cc.kmGLLoadIdentity();
+ cc.setProjectionMatrixDirty()
+ }
+});
+
+/**
+ * create one cc.GridBase Object
+ * @deprecated
+ * @param {cc.Size} gridSize
+ * @param {cc.Texture2D} [texture=]
+ * @param {Boolean} [flipped=]
+ * @param {cc.Rect} [rect=]
+ * @return {cc.GridBase}
+ */
+cc.GridBase.create = function (gridSize, texture, flipped, rect) {
+ return new cc.GridBase(gridSize, texture, flipped, rect);
+};
+
+/**
+ * cc.Grid3D is a 3D grid implementation. Each vertex has 3 dimensions: x,y,z
+ * @class
+ * @extends cc.GridBase
+ */
+cc.Grid3D = cc.GridBase.extend(/** @lends cc.Grid3D# */{
+ _texCoordinates: null,
+ _vertices: null,
+ _originalVertices: null,
+ _indices: null,
+
+ _texCoordinateBuffer: null,
+ _verticesBuffer: null,
+ _indicesBuffer: null,
+
+ _needDepthTestForBlit: false,
+ _oldDepthTestValue: false,
+ _oldDepthWriteValue: false,
+
+ /**
+ * create one Grid3D object
+ * Constructor of cc.Grid3D
+ * @param {cc.Size} gridSize
+ * @param {cc.Texture2D} [texture=]
+ * @param {Boolean} [flipped=]
+ * @param {cc.Rect} [rect=]
+ */
+ ctor: function (gridSize, texture, flipped, rect) {
+ cc.GridBase.prototype.ctor.call(this);
+ this._texCoordinates = null;
+ this._vertices = null;
+ this._originalVertices = null;
+ this._indices = null;
+
+ this._texCoordinateBuffer = null;
+ this._verticesBuffer = null;
+ this._indicesBuffer = null;
+
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+
+ if (gridSize !== undefined)
+ this.initWithSize(gridSize, texture, flipped, rect);
+ },
+
+ /**
+ * returns the vertex at a given position
+ * It will be deprecated in future, please use getVertex instead.
+ * @param {cc.Point} pos
+ * @return {cc.Vertex3F}
+ */
+ vertex: function (pos) {
+ return this.getVertex(pos);
+ },
+
+ /**
+ * returns the vertex at a given position
+ * @param {cc.Point} pos
+ * @return {cc.Vertex3F}
+ */
+ getVertex: function (pos) {
+ if (pos.x !== (0 | pos.x) || pos.y !== (0 | pos.y))
+ cc.log("cc.Grid3D.vertex() : Numbers must be integers");
+ var index = 0 | ((pos.x * (this._gridSize.height + 1) + pos.y) * 3);
+ var locVertices = this._vertices;
+ return new cc.Vertex3F(locVertices[index], locVertices[index + 1], locVertices[index + 2]);
+ },
+
+ /**
+ * returns the original (non-transformed) vertex at a given position
+ * It will be deprecated in future, please use getOriginalVertex instead.
+ * @param {cc.Point} pos
+ * @return {cc.Vertex3F}
+ */
+ originalVertex: function (pos) {
+ return this.getOriginalVertex(pos);
+ },
+
+ /**
+ * returns the original (non-transformed) vertex at a given position
+ * @param {cc.Point} pos
+ * @return {cc.Vertex3F}
+ */
+ getOriginalVertex: function (pos) {
+ if (pos.x !== (0 | pos.x) || pos.y !== (0 | pos.y))
+ cc.log("cc.Grid3D.originalVertex() : Numbers must be integers");
+ var index = 0 | ((pos.x * (this._gridSize.height + 1) + pos.y) * 3);
+ var locOriginalVertices = this._originalVertices;
+ return new cc.Vertex3F(locOriginalVertices[index], locOriginalVertices[index + 1], locOriginalVertices[index + 2]);
+ },
+
+ /**
+ * sets a new vertex at a given position
+ * @param {cc.Point} pos
+ * @param {cc.Vertex3F} vertex
+ */
+ setVertex: function (pos, vertex) {
+ if (pos.x !== (0 | pos.x) || pos.y !== (0 | pos.y))
+ cc.log("cc.Grid3D.setVertex() : Numbers must be integers");
+ var index = 0 | ((pos.x * (this._gridSize.height + 1) + pos.y) * 3);
+ var vertArray = this._vertices;
+ vertArray[index] = vertex.x;
+ vertArray[index + 1] = vertex.y;
+ vertArray[index + 2] = vertex.z;
+ this._dirty = true;
+ },
+
+ beforeBlit: function () {
+ if (this._needDepthTestForBlit) {
+ var gl = cc._renderContext;
+ this._oldDepthTestValue = gl.isEnabled(gl.DEPTH_TEST);
+ this._oldDepthWriteValue = gl.getParameter(gl.DEPTH_WRITEMASK);
+ //CHECK_GL_ERROR_DEBUG();
+ gl.enable(gl.DEPTH_TEST);
+ gl.depthMask(true);
+ }
+ },
+
+ afterBlit: function () {
+ if (this._needDepthTestForBlit) {
+ var gl = cc._renderContext;
+ if (this._oldDepthTestValue)
+ gl.enable(gl.DEPTH_TEST);
+ else
+ gl.disable(gl.DEPTH_TEST);
+ gl.depthMask(this._oldDepthWriteValue);
+ }
+ },
+
+ blit: function (target) {
+ var n = this._gridSize.width * this._gridSize.height;
+
+ var wt = target._renderCmd._worldTransform;
+ this._matrix.mat[0] = wt.a;
+ this._matrix.mat[4] = wt.c;
+ this._matrix.mat[12] = wt.tx;
+ this._matrix.mat[1] = wt.b;
+ this._matrix.mat[5] = wt.d;
+ this._matrix.mat[13] = wt.ty;
+
+ this._glProgramState.apply(this._matrix);
+
+ var gl = cc._renderContext, locDirty = this._dirty;
+
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS);
+ //
+ // Attributes
+ //
+ // position
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer);
+ if (locDirty)
+ gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 0, 0);
+
+ // texCoords
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer);
+ if (locDirty)
+ gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, 0);
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer);
+ if (locDirty)
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW);
+ gl.drawElements(gl.TRIANGLES, n * 6, gl.UNSIGNED_SHORT, 0);
+ if (locDirty)
+ this._dirty = false;
+ cc.incrementGLDraws(1);
+ },
+
+ reuse: function () {
+ if (this._reuseGrid > 0) {
+ var locOriginalVertices = this._originalVertices, locVertices = this._vertices;
+ for (var i = 0, len = this._vertices.length; i < len; i++)
+ locOriginalVertices[i] = locVertices[i];
+ --this._reuseGrid;
+ }
+ },
+
+ calculateVertexPoints: function () {
+ var gl = cc._renderContext;
+
+ var width = this._texture.pixelsWidth;
+ var height = this._texture.pixelsHeight;
+ var imageH = this._texture.getContentSizeInPixels().height;
+ var locGridSize = this._gridSize;
+
+ var numOfPoints = (locGridSize.width + 1) * (locGridSize.height + 1);
+ this._vertices = new Float32Array(numOfPoints * 3);
+ this._texCoordinates = new Float32Array(numOfPoints * 2);
+ this._indices = new Uint16Array(locGridSize.width * locGridSize.height * 6);
+
+ if (this._verticesBuffer)
+ gl.deleteBuffer(this._verticesBuffer);
+ this._verticesBuffer = gl.createBuffer();
+ if (this._texCoordinateBuffer)
+ gl.deleteBuffer(this._texCoordinateBuffer);
+ this._texCoordinateBuffer = gl.createBuffer();
+ if (this._indicesBuffer)
+ gl.deleteBuffer(this._indicesBuffer);
+ this._indicesBuffer = gl.createBuffer();
+
+ var x, y, i, locIndices = this._indices, locTexCoordinates = this._texCoordinates;
+ var locIsTextureFlipped = this._isTextureFlipped, locVertices = this._vertices;
+ for (x = 0; x < locGridSize.width; ++x) {
+ for (y = 0; y < locGridSize.height; ++y) {
+ var idx = (y * locGridSize.width) + x;
+ var x1 = x * this._step.x + this._gridRect.x;
+ var x2 = x1 + this._step.x;
+ var y1 = y * this._step.y + this._gridRect.y;
+ var y2 = y1 + this._step.y;
+
+ var a = (x * (locGridSize.height + 1) + y);
+ var b = ((x + 1) * (locGridSize.height + 1) + y);
+ var c = ((x + 1) * (locGridSize.height + 1) + (y + 1));
+ var d = (x * (locGridSize.height + 1) + (y + 1));
+
+ locIndices[idx * 6] = a;
+ locIndices[idx * 6 + 1] = b;
+ locIndices[idx * 6 + 2] = d;
+ locIndices[idx * 6 + 3] = b;
+ locIndices[idx * 6 + 4] = c;
+ locIndices[idx * 6 + 5] = d;
+
+ var l1 = [a * 3, b * 3, c * 3, d * 3];
+ var e = {x: x1, y: y1, z: 0}; //new cc.Vertex3F(x1, y1, 0);
+ var f = {x: x2, y: y1, z: 0}; //new cc.Vertex3F(x2, y1, 0);
+ var g = {x: x2, y: y2, z: 0}; // new cc.Vertex3F(x2, y2, 0);
+ var h = {x: x1, y: y2, z: 0}; //new cc.Vertex3F(x1, y2, 0);
+
+ var l2 = [e, f, g, h];
+ var tex1 = [a * 2, b * 2, c * 2, d * 2];
+ var tex2 = [cc.p(x1, y1), cc.p(x2, y1), cc.p(x2, y2), cc.p(x1, y2)];
+ for (i = 0; i < 4; ++i) {
+ locVertices[l1[i]] = l2[i].x;
+ locVertices[l1[i] + 1] = l2[i].y;
+ locVertices[l1[i] + 2] = l2[i].z;
+ locTexCoordinates[tex1[i]] = tex2[i].x / width;
+ if (locIsTextureFlipped)
+ locTexCoordinates[tex1[i] + 1] = (imageH - tex2[i].y) / height;
+ else
+ locTexCoordinates[tex1[i] + 1] = tex2[i].y / height;
+ }
+ }
+ }
+ this._originalVertices = new Float32Array(this._vertices);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW);
+ this._dirty = true;
+ },
+
+ setNeedDepthTestForBlit: function (needDepthTest) {
+ this._needDepthTestForBlit = needDepthTest;
+ },
+
+ getNeedDepthTestForBlit: function () {
+ return this._needDepthTestForBlit;
+ }
+});
+
+/**
+ * create one Grid3D object
+ * @deprecated
+ * @param {cc.Size} gridSize
+ * @param {cc.Texture2D} [texture=]
+ * @param {Boolean} [flipped=]
+ * @return {cc.Grid3D}
+ */
+cc.Grid3D.create = function (gridSize, texture, flipped) {
+ return new cc.Grid3D(gridSize, texture, flipped);
+};
+
+/**
+ * cc.TiledGrid3D is a 3D grid implementation. It differs from Grid3D in that
+ * the tiles can be separated from the grid.
+ * @class
+ * @extends cc.GridBase
+ */
+cc.TiledGrid3D = cc.GridBase.extend(/** @lends cc.TiledGrid3D# */{
+ _texCoordinates: null,
+ _vertices: null,
+ _originalVertices: null,
+ _indices: null,
+
+ _texCoordinateBuffer: null,
+ _verticesBuffer: null,
+ _indicesBuffer: null,
+
+ /**
+ * create one TiledGrid3D object
+ * Constructor of cc.TiledGrid3D
+ * @param {cc.Size} gridSize
+ * @param {cc.Texture2D} [texture=]
+ * @param {Boolean} [flipped=]
+ */
+ ctor: function (gridSize, texture, flipped, rect) {
+ cc.GridBase.prototype.ctor.call(this);
+ this._texCoordinates = null;
+ this._vertices = null;
+ this._originalVertices = null;
+ this._indices = null;
+
+ this._texCoordinateBuffer = null;
+ this._verticesBuffer = null;
+ this._indicesBuffer = null;
+
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+
+ if (gridSize !== undefined)
+ this.initWithSize(gridSize, texture, flipped, rect);
+ },
+
+ /**
+ * returns the tile at the given position
+ * It will be deprecated in future, please use getTile instead.
+ * @param {cc.Point} pos
+ * @return {cc.Quad3}
+ */
+ tile: function (pos) {
+ return this.getTile(pos);
+ },
+
+ /**
+ * returns the tile at the given position
+ * @param {cc.Point} pos
+ * @return {cc.Quad3}
+ */
+ getTile: function (pos) {
+ if (pos.x !== (0 | pos.x) || pos.y !== (0 | pos.y))
+ cc.log("cc.TiledGrid3D.tile() : Numbers must be integers");
+
+ var idx = (this._gridSize.height * pos.x + pos.y) * 4 * 3;
+ var locVertices = this._vertices;
+ return new cc.Quad3(new cc.Vertex3F(locVertices[idx], locVertices[idx + 1], locVertices[idx + 2]),
+ new cc.Vertex3F(locVertices[idx + 3], locVertices[idx + 4], locVertices[idx + 5]),
+ new cc.Vertex3F(locVertices[idx + 6], locVertices[idx + 7], locVertices[idx + 8]),
+ new cc.Vertex3F(locVertices[idx + 9], locVertices[idx + 10], locVertices[idx + 11]));
+ },
+
+ /**
+ * returns the original tile (untransformed) at the given position
+ * @param {cc.Point} pos
+ * @return {cc.Quad3}
+ */
+ getOriginalTile: function (pos) {
+ if (pos.x !== (0 | pos.x) || pos.y !== (0 | pos.y))
+ cc.log("cc.TiledGrid3D.originalTile() : Numbers must be integers");
+
+ var idx = (this._gridSize.height * pos.x + pos.y) * 4 * 3;
+ var locOriginalVertices = this._originalVertices;
+ return new cc.Quad3(new cc.Vertex3F(locOriginalVertices[idx], locOriginalVertices[idx + 1], locOriginalVertices[idx + 2]),
+ new cc.Vertex3F(locOriginalVertices[idx + 3], locOriginalVertices[idx + 4], locOriginalVertices[idx + 5]),
+ new cc.Vertex3F(locOriginalVertices[idx + 6], locOriginalVertices[idx + 7], locOriginalVertices[idx + 8]),
+ new cc.Vertex3F(locOriginalVertices[idx + 9], locOriginalVertices[idx + 10], locOriginalVertices[idx + 11]));
+ },
+
+ /**
+ * returns the original tile (untransformed) at the given position.
+ * It will be deprecated in future, please use getOriginalTile instead.
+ * @param {cc.Point} pos
+ * @return {cc.Quad3}
+ */
+ originalTile: function (pos) {
+ return this.getOriginalTile(pos);
+ },
+
+ /**
+ * sets a new tile
+ * @param {cc.Point} pos
+ * @param {cc.Quad3} coords
+ */
+ setTile: function (pos, coords) {
+ if (pos.x !== (0 | pos.x) || pos.y !== (0 | pos.y))
+ cc.log("cc.TiledGrid3D.setTile() : Numbers must be integers");
+
+ var idx = (this._gridSize.height * pos.x + pos.y) * 12;
+ var locVertices = this._vertices;
+ locVertices[idx] = coords.bl.x;
+ locVertices[idx + 1] = coords.bl.y;
+ locVertices[idx + 2] = coords.bl.z;
+ locVertices[idx + 3] = coords.br.x;
+ locVertices[idx + 4] = coords.br.y;
+ locVertices[idx + 5] = coords.br.z;
+ locVertices[idx + 6] = coords.tl.x;
+ locVertices[idx + 7] = coords.tl.y;
+ locVertices[idx + 8] = coords.tl.z;
+ locVertices[idx + 9] = coords.tr.x;
+ locVertices[idx + 10] = coords.tr.y;
+ locVertices[idx + 11] = coords.tr.z;
+ this._dirty = true;
+ },
+
+ blit: function (target) {
+ var n = this._gridSize.width * this._gridSize.height;
+
+ var wt = target._renderCmd._worldTransform;
+ this._matrix.mat[0] = wt.a;
+ this._matrix.mat[4] = wt.c;
+ this._matrix.mat[12] = wt.tx;
+ this._matrix.mat[1] = wt.b;
+ this._matrix.mat[5] = wt.d;
+ this._matrix.mat[13] = wt.ty;
+
+ this._glProgramState.apply(this._matrix);
+
+ //
+ // Attributes
+ //
+ var gl = cc._renderContext, locDirty = this._dirty;
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS);
+
+ // position
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer);
+ if (locDirty)
+ gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 0, this._vertices);
+
+ // texCoords
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer);
+ if (locDirty)
+ gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, this._texCoordinates);
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer);
+ if (locDirty)
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW);
+ gl.drawElements(gl.TRIANGLES, n * 6, gl.UNSIGNED_SHORT, 0);
+ if (locDirty)
+ this._dirty = false;
+ cc.incrementGLDraws(1);
+ },
+
+ reuse: function () {
+ if (this._reuseGrid > 0) {
+ var locVertices = this._vertices, locOriginalVertices = this._originalVertices;
+ for (var i = 0; i < locVertices.length; i++)
+ locOriginalVertices[i] = locVertices[i];
+ --this._reuseGrid;
+ }
+ },
+
+ calculateVertexPoints: function () {
+ var width = this._texture.pixelsWidth;
+ var height = this._texture.pixelsHeight;
+ var imageH = this._texture.getContentSizeInPixels().height;
+ var locGridSize = this._gridSize;
+
+ var numQuads = locGridSize.width * locGridSize.height;
+ this._vertices = new Float32Array(numQuads * 12);
+ this._texCoordinates = new Float32Array(numQuads * 8);
+ this._indices = new Uint16Array(numQuads * 6);
+
+ var gl = cc._renderContext;
+ if (this._verticesBuffer)
+ gl.deleteBuffer(this._verticesBuffer);
+ this._verticesBuffer = gl.createBuffer();
+ if (this._texCoordinateBuffer)
+ gl.deleteBuffer(this._texCoordinateBuffer);
+ this._texCoordinateBuffer = gl.createBuffer();
+ if (this._indicesBuffer)
+ gl.deleteBuffer(this._indicesBuffer);
+ this._indicesBuffer = gl.createBuffer();
+
+ var x, y, i = 0;
+ var locStep = this._step, locVertices = this._vertices, locTexCoords = this._texCoordinates, locIsTextureFlipped = this._isTextureFlipped;
+ for (x = 0; x < locGridSize.width; x++) {
+ for (y = 0; y < locGridSize.height; y++) {
+ var x1 = x * locStep.x;
+ var x2 = x1 + locStep.x;
+ var y1 = y * locStep.y;
+ var y2 = y1 + locStep.y;
+
+ locVertices[i * 12] = x1;
+ locVertices[i * 12 + 1] = y1;
+ locVertices[i * 12 + 2] = 0;
+ locVertices[i * 12 + 3] = x2;
+ locVertices[i * 12 + 4] = y1;
+ locVertices[i * 12 + 5] = 0;
+ locVertices[i * 12 + 6] = x1;
+ locVertices[i * 12 + 7] = y2;
+ locVertices[i * 12 + 8] = 0;
+ locVertices[i * 12 + 9] = x2;
+ locVertices[i * 12 + 10] = y2;
+ locVertices[i * 12 + 11] = 0;
+
+ var newY1 = y1;
+ var newY2 = y2;
+
+ if (locIsTextureFlipped) {
+ newY1 = imageH - y1;
+ newY2 = imageH - y2;
+ }
+
+ locTexCoords[i * 8] = x1 / width;
+ locTexCoords[i * 8 + 1] = newY1 / height;
+ locTexCoords[i * 8 + 2] = x2 / width;
+ locTexCoords[i * 8 + 3] = newY1 / height;
+ locTexCoords[i * 8 + 4] = x1 / width;
+ locTexCoords[i * 8 + 5] = newY2 / height;
+ locTexCoords[i * 8 + 6] = x2 / width;
+ locTexCoords[i * 8 + 7] = newY2 / height;
+ i++;
+ }
+ }
+
+ var locIndices = this._indices;
+ for (x = 0; x < numQuads; x++) {
+ locIndices[x * 6 + 0] = (x * 4 + 0);
+ locIndices[x * 6 + 1] = (x * 4 + 1);
+ locIndices[x * 6 + 2] = (x * 4 + 2);
+
+ locIndices[x * 6 + 3] = (x * 4 + 1);
+ locIndices[x * 6 + 4] = (x * 4 + 2);
+ locIndices[x * 6 + 5] = (x * 4 + 3);
+ }
+ this._originalVertices = new Float32Array(this._vertices);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.DYNAMIC_DRAW);
+ this._dirty = true;
+ }
+});
+
+/**
+ * create one TiledGrid3D object
+ * @deprecated since v3.0, please use new cc.TiledGrid3D(gridSize, texture, flipped) instead
+ * @param {cc.Size} gridSize
+ * @param {cc.Texture2D} [texture=]
+ * @param {Boolean} [flipped=]
+ * @return {cc.TiledGrid3D}
+ */
+cc.TiledGrid3D.create = function (gridSize, texture, flipped) {
+ return new cc.TiledGrid3D(gridSize, texture, flipped);
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/SIMDPolyfill.js b/frameworks/cocos2d-html5/cocos2d/kazmath/SIMDPolyfill.js
new file mode 100644
index 0000000..7c65b0a
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/SIMDPolyfill.js
@@ -0,0 +1,78 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+(function(cc) {
+ var _useSIMD = false;
+
+ var mat4Proto = cc.math.Matrix4.prototype;
+ var mat4Inverse = mat4Proto.inverse;
+ var mat4IsIdentity = mat4Proto.isIdentity;
+ var mat4Transpose = mat4Proto.transpose;
+ var mat4Multiply = mat4Proto.multiply;
+ var mat4GetMat4MultiplyValue = mat4Proto.getMat4MultiplyValue;
+ var mat4AssignFrom = mat4Proto.assignFrom;
+ var mat4Equals = mat4Proto.equals;
+ var mat4LookAt = mat4Proto.lookAt;
+
+ var vec3Proto = cc.math.Vec3.prototype;
+ var vec3TransformCoord = vec3Proto.transformCoord;
+
+ function _isEnabledSIMD () {
+ return _useSIMD;
+ }
+
+ function _enableSIMD (enable) {
+ if(typeof(SIMD) === 'undefined')
+ return;
+
+ if (enable) {
+ mat4Proto.inverse = mat4Proto.inverseSIMD;
+ mat4Proto.isIdentity = mat4Proto.isIdentitySIMD;
+ mat4Proto.transpose = mat4Proto.transposeSIMD;
+ mat4Proto.multiply = mat4Proto.multiplySIMD;
+ mat4Proto.getMat4MultiplyValue = mat4Proto.getMat4MultiplyValueSIMD;
+ mat4Proto.assignFrom = mat4Proto.assignFromSIMD;
+ mat4Proto.equals = mat4Proto.equalsSIMD;
+ mat4Proto.lookAt = mat4Proto.lookAtSIMD;
+ vec3Proto.transformCoord = vec3Proto.transformCoordSIMD;
+ } else {
+ mat4Proto.inverse = mat4Inverse;
+ mat4Proto.isIdentity = mat4IsIdentity;
+ mat4Proto.transpose = mat4Transpose;
+ mat4Proto.multiply = mat4Multiply;
+ mat4Proto.getMat4MultiplyValue = mat4GetMat4MultiplyValue;
+ mat4Proto.assignFrom = mat4AssignFrom;
+ mat4Proto.equals = mat4Equals;
+ mat4Proto.lookAt = mat4LookAt;
+ vec3Proto.transformCoord = vec3TransformCoord;
+ }
+ _useSIMD = enable;
+ }
+
+ cc.defineGetterSetter(cc.sys, "useSIMD", _isEnabledSIMD, _enableSIMD);
+})(cc);
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/aabb.js b/frameworks/cocos2d-html5/cocos2d/kazmath/aabb.js
new file mode 100644
index 0000000..8c5dc5b
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/aabb.js
@@ -0,0 +1,78 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * A structure that represents an axis-aligned bounding box.
+ * cc.kmAABB => cc.math.AABB
+ */
+cc.math.AABB = function (min, max) {
+ /** The max corner of the box */
+ this.min = min || new cc.math.Vec3();
+ /** The min corner of the box */
+ this.max = max || new cc.math.Vec3();
+};
+
+/**
+ * Returns true if point is in the specified AABB, returns false otherwise.
+ * @param {cc.math.Vec3} point
+ * @returns {boolean}
+ */
+cc.math.AABB.prototype.containsPoint = function (point) {
+ return (point.x >= this.min.x && point.x <= this.max.x &&
+ point.y >= this.min.y && point.y <= this.max.y &&
+ point.z >= this.min.z && point.z <= this.max.z);
+};
+
+/**
+ * Returns true if point is in the specified AABB, returns
+ * false otherwise.
+ */
+cc.math.AABB.containsPoint = function (pPoint, pBox) {
+ return (pPoint.x >= pBox.min.x && pPoint.x <= pBox.max.x &&
+ pPoint.y >= pBox.min.y && pPoint.y <= pBox.max.y &&
+ pPoint.z >= pBox.min.z && pPoint.z <= pBox.max.z);
+};
+
+/**
+ * Assigns aabb to current AABB object
+ * @param {cc.math.AABB} aabb
+ */
+cc.math.AABB.prototype.assignFrom = function(aabb){
+ this.min.assignFrom(aabb.min);
+ this.max.assignFrom(aabb.max);
+};
+
+/**
+ * Assigns pIn to pOut, returns pOut.
+ */
+cc.math.AABB.assign = function (pOut, pIn) { //cc.kmAABBAssign
+ pOut.min.assignFrom(pIn.min);
+ pOut.max.assignFrom(pIn.max);
+ return pOut;
+};
+
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/gl/mat4stack.js b/frameworks/cocos2d-html5/cocos2d/kazmath/gl/mat4stack.js
new file mode 100644
index 0000000..cd33942
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/gl/mat4stack.js
@@ -0,0 +1,99 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+(function (cc) {
+ /**
+ * The stack of cc.math.Matrix4
+ * @param {cc.math.Matrix4} [top]
+ * @param {Array} [stack]
+ * @constructor
+ */
+ cc.math.Matrix4Stack = function (top, stack) {
+ this.top = top;
+ this.stack = stack || [];
+ this.lastUpdated = 0;
+ //this._matrixPool = []; // use pool in next version
+ };
+ cc.km_mat4_stack = cc.math.Matrix4Stack;
+ var proto = cc.math.Matrix4Stack.prototype;
+
+ proto.initialize = function () { //cc.km_mat4_stack_initialize
+ this.stack.length = 0;
+ this.top = null;
+ };
+
+ //for compatibility
+ cc.km_mat4_stack_push = function (stack, item) {
+ stack.stack.push(stack.top);
+ stack.top = new cc.math.Matrix4(item);
+ };
+
+ cc.km_mat4_stack_pop = function (stack, pOut) {
+ stack.top = stack.stack.pop();
+ };
+
+ cc.km_mat4_stack_release = function (stack) {
+ stack.stack = null;
+ stack.top = null;
+ };
+
+ proto.push = function (item) {
+ item = item || this.top;
+ this.stack.push(this.top);
+ this.top = new cc.math.Matrix4(item);
+ //this.top = this._getFromPool(item);
+ };
+
+ proto.pop = function () {
+ //this._putInPool(this.top);
+ this.top = this.stack.pop();
+ };
+
+ proto.release = function () {
+ this.stack = null;
+ this.top = null;
+ this._matrixPool = null;
+ };
+
+ proto._getFromPool = function (item) {
+ var pool = this._matrixPool;
+ if (pool.length === 0)
+ return new cc.math.Matrix4(item);
+ var ret = pool.pop();
+ ret.assignFrom(item);
+ return ret;
+ };
+
+ proto._putInPool = function (matrix) {
+ this._matrixPool.push(matrix);
+ };
+})(cc);
+
+
+
+
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/gl/matrix.js b/frameworks/cocos2d-html5/cocos2d/kazmath/gl/matrix.js
new file mode 100644
index 0000000..13c9798
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/gl/matrix.js
@@ -0,0 +1,168 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+(function (cc) {
+ cc.KM_GL_MODELVIEW = 0x1700;
+ cc.KM_GL_PROJECTION = 0x1701;
+ cc.KM_GL_TEXTURE = 0x1702;
+
+ cc.modelview_matrix_stack = new cc.math.Matrix4Stack();
+ cc.projection_matrix_stack = new cc.math.Matrix4Stack();
+ cc.texture_matrix_stack = new cc.math.Matrix4Stack();
+
+ cc.current_stack = null;
+ var initialized = false;
+
+ cc.lazyInitialize = function () {
+ if (!initialized) {
+ var identity = new cc.math.Matrix4(); //Temporary identity matrix
+
+ //Initialize all 3 stacks
+ cc.modelview_matrix_stack.initialize();
+ cc.projection_matrix_stack.initialize();
+ cc.texture_matrix_stack.initialize();
+
+ cc.current_stack = cc.modelview_matrix_stack;
+ cc.initialized = true;
+ identity.identity();
+
+ //Make sure that each stack has the identity matrix
+ cc.modelview_matrix_stack.push(identity);
+ cc.projection_matrix_stack.push(identity);
+ cc.texture_matrix_stack.push(identity);
+ }
+ };
+
+ cc.lazyInitialize();
+
+ cc.kmGLFreeAll = function () {
+ //Clear the matrix stacks
+ cc.modelview_matrix_stack.release();
+ cc.modelview_matrix_stack = null;
+ cc.projection_matrix_stack.release();
+ cc.projection_matrix_stack = null;
+ cc.texture_matrix_stack.release();
+ cc.texture_matrix_stack = null;
+
+ //Delete the matrices
+ cc.initialized = false; //Set to uninitialized
+ cc.current_stack = null; //Set the current stack to point nowhere
+ };
+
+ cc.kmGLPushMatrix = function () {
+ cc.current_stack.push(cc.current_stack.top);
+ };
+
+ cc.kmGLPushMatrixWitMat4 = function (saveMat) {
+ cc.current_stack.stack.push(cc.current_stack.top);
+ saveMat.assignFrom(cc.current_stack.top);
+ cc.current_stack.top = saveMat;
+ };
+
+ cc.kmGLPopMatrix = function () {
+ //No need to lazy initialize, you shouldn't be popping first anyway!
+ //cc.km_mat4_stack_pop(cc.current_stack, null);
+ cc.current_stack.top = cc.current_stack.stack.pop();
+ };
+
+ cc.kmGLMatrixMode = function (mode) {
+ //cc.lazyInitialize();
+ switch (mode) {
+ case cc.KM_GL_MODELVIEW:
+ cc.current_stack = cc.modelview_matrix_stack;
+ break;
+ case cc.KM_GL_PROJECTION:
+ cc.current_stack = cc.projection_matrix_stack;
+ break;
+ case cc.KM_GL_TEXTURE:
+ cc.current_stack = cc.texture_matrix_stack;
+ break;
+ default:
+ throw new Error("Invalid matrix mode specified"); //TODO: Proper error handling
+ break;
+ }
+ cc.current_stack.lastUpdated = cc.director.getTotalFrames();
+ };
+
+ cc.kmGLLoadIdentity = function () {
+ //cc.lazyInitialize();
+ cc.current_stack.top.identity(); //Replace the top matrix with the identity matrix
+ };
+
+ cc.kmGLLoadMatrix = function (pIn) {
+ //cc.lazyInitialize();
+ cc.current_stack.top.assignFrom(pIn);
+ };
+
+ cc.kmGLMultMatrix = function (pIn) {
+ //cc.lazyInitialize();
+ cc.current_stack.top.multiply(pIn);
+ };
+
+ var tempMatrix = new cc.math.Matrix4(); //an internal matrix
+ cc.kmGLTranslatef = function (x, y, z) {
+ //Create a rotation matrix using translation
+ var translation = cc.math.Matrix4.createByTranslation(x, y, z, tempMatrix);
+
+ //Multiply the rotation matrix by the current matrix
+ cc.current_stack.top.multiply(translation);
+ };
+
+ var tempVector3 = new cc.math.Vec3();
+ cc.kmGLRotatef = function (angle, x, y, z) {
+ tempVector3.fill(x, y, z);
+ //Create a rotation matrix using the axis and the angle
+ var rotation = cc.math.Matrix4.createByAxisAndAngle(tempVector3, cc.degreesToRadians(angle), tempMatrix);
+
+ //Multiply the rotation matrix by the current matrix
+ cc.current_stack.top.multiply(rotation);
+ };
+
+ cc.kmGLScalef = function (x, y, z) {
+ var scaling = cc.math.Matrix4.createByScale(x, y, z, tempMatrix);
+ cc.current_stack.top.multiply(scaling);
+ };
+
+ cc.kmGLGetMatrix = function (mode, pOut) {
+ //cc.lazyInitialize();
+ switch (mode) {
+ case cc.KM_GL_MODELVIEW:
+ pOut.assignFrom(cc.modelview_matrix_stack.top);
+ break;
+ case cc.KM_GL_PROJECTION:
+ pOut.assignFrom(cc.projection_matrix_stack.top);
+ break;
+ case cc.KM_GL_TEXTURE:
+ pOut.assignFrom(cc.texture_matrix_stack.top);
+ break;
+ default:
+ throw new Error("Invalid matrix mode specified"); //TODO: Proper error handling
+ break;
+ }
+ };
+})(cc);
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/mat3.js b/frameworks/cocos2d-html5/cocos2d/kazmath/mat3.js
new file mode 100644
index 0000000..d3023f0
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/mat3.js
@@ -0,0 +1,357 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+window.Uint16Array = window.Uint16Array || window.Array;
+window.Float32Array = window.Float32Array || window.Array;
+(function(cc){
+ /**
+ *
+ * A 3x3 matrix
+ *
+ * @class
+ * @param {cc.math.Matrix3} [mat3]
+ */
+ cc.math.Matrix3 = function(mat3) {
+ if (mat3 && mat3.mat) {
+ this.mat = new Float32Array(mat3.mat);
+ } else {
+ this.mat = new Float32Array(9);
+ }
+ };
+ cc.kmMat3 = cc.math.Matrix3;
+ var _p = cc.math.Matrix3.prototype;
+
+ /**
+ * Copy matrix.
+ * @fn fill
+ * @memberof cc.math.Matrix3
+ * @param {cc.math.Matrix3} mat3 Matrix to copy
+ * @return {cc.math.Matrix3} this
+ */
+ _p.fill = function(mat3) { //cc.kmMat3Fill
+ var mat = this.mat, matIn = mat3.mat;
+ mat[0] = matIn[0];
+ mat[1] = matIn[1];
+ mat[2] = matIn[2];
+ mat[3] = matIn[3];
+ mat[4] = matIn[4];
+ mat[5] = matIn[5];
+ mat[6] = matIn[6];
+ mat[7] = matIn[7];
+ mat[8] = matIn[8];
+ return this;
+ };
+
+ _p.adjugate = function(){ //= cc.kmMat3Adjugate
+ var mat = this.mat;
+ var m0 = mat[0], m1 = mat[1], m2 = mat[2], m3 = mat[3], m4 = mat[4],
+ m5 = mat[5], m6 = mat[6], m7 = mat[7], m8 = mat[8];
+ mat[0] = m4 * m8 - m5 * m7;
+ mat[1] = m2 * m7 - m1 * m8;
+ mat[2] = m1 * m5 - m2 * m4;
+ mat[3] = m5 * m6 - m3 * m8;
+ mat[4] = m0 * m8 - m2 * m6;
+ mat[5] = m2 * m3 - m0 * m5;
+ mat[6] = m3 * m7 - m4 * m6;
+
+ // XXX: pIn.mat[9] is invalid!
+ //mat[7] = m1 * m6 - pIn.mat[9] * m7;
+ mat[8] = m0 * m4 - m1 * m3;
+ return this;
+ };
+
+ /**
+ * Sets pOut to an identity matrix returns pOut
+ * @memberof cc.math.Matrix3
+ * @param {cc.math.Matrix3} pOut - A pointer to the matrix to set to identity
+ * @return {cc.math.Matrix3} this
+ */
+ _p.identity = function() { //cc.kmMat3Identity
+ var mat = this.mat;
+ mat[1] = mat[2] = mat[3] =
+ mat[5] = mat[6] = mat[7] = 0;
+ mat[0] = mat[4] = mat[8] = 1.0;
+ return this;
+ };
+
+ var tmpMatrix = new cc.math.Matrix3(); // internal matrix
+
+ _p.inverse = function(determinate){ //cc.kmMat3Inverse
+ if (determinate === 0.0)
+ return this;
+ tmpMatrix.assignFrom(this);
+ var detInv = 1.0 / determinate;
+ this.adjugate();
+ this.multiplyScalar(detInv);
+ return this;
+ };
+
+ _p.isIdentity = function(){ //= cc.kmMat3IsIdentity
+ var mat = this.mat;
+ return (mat[0] === 1 && mat[1] === 0 && mat[2] === 0
+ && mat[3] === 0 && mat[4] === 1 && mat[5] === 0
+ && mat[6] === 0 && mat[7] === 0 && mat[8] === 1);
+ };
+
+ _p.transpose = function(){ // cc.kmMat3Transpose
+ var mat = this.mat;
+ var m1 = mat[1], m2 = mat[2], m3 = mat[3], m5 = mat[5],
+ m6 = mat[6], m7 = mat[7];
+ // m0 = mat[0],m8 = mat[8], m4 = mat[4];
+ //mat[0] = m0;
+ //mat[8] = m8;
+ //mat[4] = m4
+ mat[1] = m3;
+ mat[2] = m6;
+ mat[3] = m1;
+ mat[5] = m7;
+ mat[6] = m2;
+ mat[7] = m5;
+ return this;
+ };
+
+ _p.determinant = function(){
+ var mat = this.mat;
+ /*
+ calculating the determinant following the rule of sarus,
+ | 0 3 6 | 0 3 |
+ m = | 1 4 7 | 1 4 |
+ | 2 5 8 | 2 5 |
+ now sum up the products of the diagonals going to the right (i.e. 0,4,8)
+ and subtract the products of the other diagonals (i.e. 2,4,6)
+ */
+ var output = mat[0] * mat[4] * mat[8] + mat[1] * mat[5] * mat[6] + mat[2] * mat[3] * mat[7];
+ output -= mat[2] * mat[4] * mat[6] + mat[0] * mat[5] * mat[7] + mat[1] * mat[3] * mat[8];
+ return output;
+ };
+
+ _p.multiply = function(mat3){
+ var m1 = this.mat, m2 = mat3.mat;
+ var a0 = m1[0], a1 = m1[1], a2 = m1[2], a3 = m1[3], a4 = m1[4], a5 = m1[5],
+ a6 = m1[6], a7 = m1[7], a8 = m1[8];
+ var b0 = m2[0], b1 = m2[1], b2 = m2[2], b3 = m2[3], b4 = m2[4], b5 = m2[5],
+ b6 = m2[6], b7 = m2[7], b8 = m2[8];
+
+ m1[0] = a0 * b0 + a3 * b1 + a6 * b2;
+ m1[1] = a1 * b0 + a4 * b1 + a7 * b2;
+ m1[2] = a2 * b0 + a5 * b1 + a8 * b2;
+
+ m1[3] = a2 * b0 + a5 * b1 + a8 * b2;
+ m1[4] = a1 * b3 + a4 * b4 + a7 * b5;
+ m1[5] = a2 * b3 + a5 * b4 + a8 * b5;
+
+ m1[6] = a0 * b6 + a3 * b7 + a6 * b8;
+ m1[7] = a1 * b6 + a4 * b7 + a7 * b8;
+ m1[8] = a2 * b6 + a5 * b7 + a8 * b8;
+ return this;
+ };
+
+ _p.multiplyScalar = function(factor) {
+ var mat = this.mat;
+ mat[0] *= factor;
+ mat[1] *= factor;
+ mat[2] *= factor;
+ mat[3] *= factor;
+ mat[4] *= factor;
+ mat[5] *= factor;
+ mat[6] *= factor;
+ mat[7] *= factor;
+ mat[8] *= factor;
+ return this;
+ };
+
+ cc.math.Matrix3.rotationAxisAngle = function(axis, radians) { //cc.kmMat3RotationAxisAngle
+ var rcos = Math.cos(radians), rsin = Math.sin(radians);
+ var retMat = new cc.math.Matrix3();
+ var mat = retMat.mat;
+
+ mat[0] = rcos + axis.x * axis.x * (1 - rcos);
+ mat[1] = axis.z * rsin + axis.y * axis.x * (1 - rcos);
+ mat[2] = -axis.y * rsin + axis.z * axis.x * (1 - rcos);
+
+ mat[3] = -axis.z * rsin + axis.x * axis.y * (1 - rcos);
+ mat[4] = rcos + axis.y * axis.y * (1 - rcos);
+ mat[5] = axis.x * rsin + axis.z * axis.y * (1 - rcos);
+
+ mat[6] = axis.y * rsin + axis.x * axis.z * (1 - rcos);
+ mat[7] = -axis.x * rsin + axis.y * axis.z * (1 - rcos);
+ mat[8] = rcos + axis.z * axis.z * (1 - rcos);
+
+ return retMat;
+ };
+
+ _p.assignFrom = function(matIn){ // cc.kmMat3Assign
+ if(this === matIn) {
+ cc.log("cc.math.Matrix3.assign(): current matrix equals matIn");
+ return this;
+ }
+ var mat = this.mat, m2 = matIn.mat;
+ mat[0] = m2[0];
+ mat[1] = m2[1];
+ mat[2] = m2[2];
+ mat[3] = m2[3];
+ mat[4] = m2[4];
+ mat[5] = m2[5];
+ mat[6] = m2[6];
+ mat[7] = m2[7];
+ mat[8] = m2[8];
+ return this;
+ };
+
+ _p.equals = function(mat3) {
+ if (this === mat3)
+ return true;
+ var EPSILON = cc.math.EPSILON,m1 = this.mat, m2 = mat3.mat;
+ for (var i = 0; i < 9; ++i) {
+ if (!(m1[i] + EPSILON > m2[i] && m1[i] - EPSILON < m2[i]))
+ return false;
+ }
+ return true;
+ };
+
+ cc.math.Matrix3.createByRotationX = function(radians) {
+ var retMat = new cc.math.Matrix3(), mat = retMat.mat;
+ mat[0] = 1.0;
+ mat[1] = 0.0;
+ mat[2] = 0.0;
+
+ mat[3] = 0.0;
+ mat[4] = Math.cos(radians);
+ mat[5] = Math.sin(radians);
+
+ mat[6] = 0.0;
+ mat[7] = -Math.sin(radians);
+ mat[8] = Math.cos(radians);
+ return retMat;
+ };
+
+ cc.math.Matrix3.createByRotationY = function(radians) {
+ /*
+ | cos(A) 0 sin(A) |
+ M = | 0 1 0 |
+ | -sin(A) 0 cos(A) |
+ */
+ var retMat = new cc.math.Matrix3(), mat = retMat.mat;
+ mat[0] = Math.cos(radians);
+ mat[1] = 0.0;
+ mat[2] = -Math.sin(radians);
+
+ mat[3] = 0.0;
+ mat[4] = 1.0;
+ mat[5] = 0.0;
+
+ mat[6] = Math.sin(radians);
+ mat[7] = 0.0;
+ mat[8] = Math.cos(radians);
+ return retMat;
+ };
+
+ cc.math.Matrix3.createByRotationZ = function(radians) {
+ /*
+ | cos(A) -sin(A) 0 |
+ M = | sin(A) cos(A) 0 |
+ | 0 0 1 |
+ */
+ var retMat = new cc.math.Matrix3(), mat = retMat.mat;
+ mat[0] = Math.cos(radians);
+ mat[1] = -Math.sin(radians);
+ mat[2] = 0.0;
+
+ mat[3] = Math.sin(radians);
+ mat[4] = Math.cos(radians);
+ mat[5] = 0.0;
+
+ mat[6] = 0.0;
+ mat[7] = 0.0;
+ mat[8] = 1.0;
+ return retMat;
+ };
+
+ cc.math.Matrix3.createByRotation = function(radians) {
+ /*
+ | cos(A) -sin(A) 0 |
+ M = | sin(A) cos(A) 0 |
+ | 0 0 1 |
+ */
+ var retMat = new cc.math.Matrix3(), mat = retMat.mat;
+ mat[0] = Math.cos(radians);
+ mat[1] = Math.sin(radians);
+ mat[2] = 0.0;
+
+ mat[3] = -Math.sin(radians);
+ mat[4] = Math.cos(radians);
+ mat[5] = 0.0;
+
+ mat[6] = 0.0;
+ mat[7] = 0.0;
+ mat[8] = 1.0;
+ return retMat;
+ };
+
+ cc.math.Matrix3.createByScale = function(x, y) {
+ var ret = new cc.math.Matrix3();
+ ret.identity();
+ ret.mat[0] = x;
+ ret.mat[4] = y;
+ return ret;
+ };
+
+ cc.math.Matrix3.createByTranslation = function(x, y){
+ var ret = new cc.math.Matrix3();
+ ret.identity();
+ ret.mat[6] = x;
+ ret.mat[7] = y;
+ return ret;
+ };
+
+ cc.math.Matrix3.createByQuaternion = function(quaternion) { //cc.kmMat3RotationQuaternion
+ if(!quaternion)
+ return null;
+
+ var ret = new cc.math.Matrix3(), mat = ret.mat;
+ // First row
+ mat[0] = 1.0 - 2.0 * (quaternion.y * quaternion.y + quaternion.z * quaternion.z);
+ mat[1] = 2.0 * (quaternion.x * quaternion.y - quaternion.w * quaternion.z);
+ mat[2] = 2.0 * (quaternion.x * quaternion.z + quaternion.w * quaternion.y);
+
+ // Second row
+ mat[3] = 2.0 * (quaternion.x * quaternion.y + quaternion.w * quaternion.z);
+ mat[4] = 1.0 - 2.0 * (quaternion.x * quaternion.x + quaternion.z * quaternion.z);
+ mat[5] = 2.0 * (quaternion.y * quaternion.z - quaternion.w * quaternion.x);
+
+ // Third row
+ mat[6] = 2.0 * (quaternion.x * quaternion.z - quaternion.w * quaternion.y);
+ mat[7] = 2.0 * (quaternion.y * quaternion.z + quaternion.w * quaternion.x);
+ mat[8] = 1.0 - 2.0 * (quaternion.x * quaternion.x + quaternion.y * quaternion.y);
+ return ret;
+ };
+
+ _p.rotationToAxisAngle = function() { //cc.kmMat3RotationToAxisAngle
+ return cc.math.Quaternion.rotationMatrix(this).toAxisAndAngle();
+ }
+})(cc);
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/mat4.js b/frameworks/cocos2d-html5/cocos2d/kazmath/mat4.js
new file mode 100644
index 0000000..35a56e1
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/mat4.js
@@ -0,0 +1,1011 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+(function(cc) {
+ /**
+ *
+ * A 4x4 matrix
+ *
+ * mat =
+ * | 0 4 8 12 |
+ * | 1 5 9 13 |
+ * | 2 6 10 14 |
+ * | 3 7 11 15 |
+ *
+ * @class
+ * @param {cc.math.Matrix4} [mat4]
+ */
+ cc.math.Matrix4 = function (mat4) {
+ if(mat4 && mat4.mat){
+ this.mat = new Float32Array(mat4.mat);
+ } else {
+ this.mat = new Float32Array(16);
+ }
+ };
+ cc.kmMat4 = cc.math.Matrix4;
+ var proto = cc.math.Matrix4.prototype;
+
+ /**
+ * Fills a cc.math.Matrix4 structure with the values from a 16 element array of floats
+ * @param {Array} scalarArr
+ */
+ proto.fill = function(scalarArr){ //cc.kmMat4Fill
+ var mat = this.mat;
+ for(var i = 0; i < 16; i++){
+ mat[i] = scalarArr[i];
+ }
+ return this;
+ };
+
+ /**
+ * Sets pOut to an identity matrix returns pOut
+ * @param pOut - A pointer to the matrix to set to identity
+ * @returns Returns pOut so that the call can be nested
+ */
+ cc.kmMat4Identity = function (pOut) {
+ var mat = pOut.mat;
+ mat[1] = mat[2] = mat[3] = mat[4] = mat[6] = mat[7]
+ = mat[8] = mat[9] = mat[11] = mat[12] = mat[13] = mat[14] = 0;
+ mat[0] = mat[5] = mat[10] = mat[15] = 1.0;
+ return pOut;
+ };
+
+ /**
+ * Sets matrix to identity value.
+ * @returns {cc.math.Matrix4}
+ */
+ proto.identity = function(){
+ var mat = this.mat;
+ mat[1] = mat[2] = mat[3] = mat[4] = mat[6] = mat[7]
+ = mat[8] = mat[9] = mat[11] = mat[12] = mat[13] = mat[14] = 0;
+ mat[0] = mat[5] = mat[10] = mat[15] = 1.0;
+ return this;
+ };
+
+ proto.get = function(row, col){
+ return this.mat[row + 4 * col];
+ };
+
+ proto.set = function(row, col, value){
+ this.mat[row + 4 * col] = value;
+ };
+
+ proto.swap = function(r1, c1, r2, c2) {
+/* var tmp = this.get(r1, c1);
+ this.set(r1, c1, this.get(r2, c2));
+ this.set(r2, c2, tmp);*/
+ var mat = this.mat, tmp = mat[r1 + 4 * c1];
+ mat[r1 + 4 * c1] = mat[r2 + 4 * c2];
+ mat[r2 + 4 * c2] = tmp;
+ };
+
+ //Returns an upper and a lower triangular matrix which are L and R in the Gauss algorithm
+ cc.math.Matrix4._gaussj = function (a, b) {
+ var i, icol = 0, irow = 0, j, k, l, ll, n = 4, m = 4, selElement;
+ var big, dumb, pivinv;
+ var indxc = [0, 0, 0, 0], indxr = [0, 0, 0, 0], ipiv = [0, 0, 0, 0];
+
+ /* for (j = 0; j < n; j++) {
+ ipiv[j] = 0;
+ }*/
+
+ for (i = 0; i < n; i++) {
+ big = 0.0;
+ for (j = 0; j < n; j++) {
+ if (ipiv[j] !== 1) {
+ for (k = 0; k < n; k++) {
+ if (ipiv[k] === 0) {
+ selElement = Math.abs(a.get(j, k));
+ if (selElement >= big) {
+ big = selElement;
+ irow = j;
+ icol = k;
+ }
+ }
+ }
+ }
+ }
+ ++(ipiv[icol]);
+ if (irow !== icol) {
+ for (l = 0; l < n; l++)
+ a.swap(irow, l, icol, l);
+ for (l = 0; l < m; l++)
+ b.swap(irow, l, icol, l);
+ }
+ indxr[i] = irow;
+ indxc[i] = icol;
+ if (a.get(icol, icol) === 0.0)
+ return false;
+
+ pivinv = 1.0 / a.get(icol, icol);
+ a.set(icol, icol, 1.0);
+ for (l = 0; l < n; l++)
+ a.set(icol, l, a.get(icol, l) * pivinv);
+
+ for (l = 0; l < m; l++)
+ b.set(icol, l, b.get(icol, l) * pivinv);
+
+ for (ll = 0; ll < n; ll++) {
+ if (ll !== icol) {
+ dumb = a.get(ll, icol);
+ a.set(ll, icol, 0.0);
+ for (l = 0; l < n; l++)
+ a.set(ll, l, a.get(ll, l) - a.get(icol, l) * dumb);
+
+ for (l = 0; l < m; l++)
+ b.set(ll, l, a.get(ll, l) - b.get(icol, l) * dumb);
+ }
+ }
+ }
+ // This is the end of the main loop over columns of the reduction. It only remains to unscram-
+ // ble the solution in view of the column interchanges. We do this by interchanging pairs of
+ // columns in the reverse order that the permutation was built up.
+ for (l = n - 1; l >= 0; l--) {
+ if (indxr[l] !== indxc[l]) {
+ for (k = 0; k < n; k++)
+ a.swap(k, indxr[l], k, indxc[l]);
+ }
+ }
+ return true;
+ };
+
+ var identityMatrix = new cc.math.Matrix4().identity();
+ /**
+ * Calculates the inverse of pM and stores the result in pOut.
+ * Please use matrix4's inverse function instead.
+ * @Return Returns NULL if there is no inverse, else pOut
+ */
+ cc.kmMat4Inverse = function (pOut, pM) {
+ var inv = new cc.math.Matrix4(pM);
+ var tmp = new cc.math.Matrix4(identityMatrix);
+ if (cc.math.Matrix4._gaussj(inv, tmp) === false)
+ return null;
+ pOut.assignFrom(inv);
+ return pOut;
+ };
+
+ /**
+ * Calculates the inverse of current matrix.
+ * @returns {cc.math.Matrix4} Returns null if there is no inverse, else returns a new inverse matrix object
+ */
+ proto.inverse = function(){ //cc.kmMat4Inverse
+ var inv = new cc.math.Matrix4(this);
+ var tmp = new cc.math.Matrix4(identityMatrix);
+ if (cc.math.Matrix4._gaussj(inv, tmp) === false)
+ return null;
+ return inv;
+ };
+
+ /**
+ * Returns true if current matrix is an identity matrix, false otherwise
+ */
+ proto.isIdentity = function () { // cc.kmMat4IsIdentity
+ var mat = this.mat;
+ return (mat[0] === 1 && mat[1] === 0 && mat[2] === 0 && mat[3] === 0
+ && mat[4] === 0 && mat[5] === 1 && mat[6] === 0 && mat[7] === 0
+ && mat[8] === 0 && mat[9] === 0 && mat[10] === 1 && mat[11] === 0
+ && mat[12] === 0 && mat[13] === 0 && mat[14] === 0 && mat[15] === 1);
+ };
+
+ /**
+ * transpose the current matrix
+ */
+ proto.transpose = function() { // cc.kmMat4Transpose
+ var mat = this.mat;
+ var m1 = mat[1], m2 = mat[2], m3 = mat[3],
+ m4 = mat[4], m6 = mat[6], m7 = mat[7],
+ m8 = mat[8], m9 = mat[9], m11 = mat[11],
+ m12 = mat[12], m13 = mat[13], m14 = mat[14];
+ mat[1] = m4;
+ mat[2] = m8;
+ mat[3] = m12;
+
+ mat[4] = m1;
+ mat[6] = m9;
+ mat[7] = m13;
+
+ mat[8] = m2;
+ mat[9] = m6;
+ mat[11] = m14;
+
+ mat[12] = m3;
+ mat[13] = m7;
+ mat[14] = m11;
+ return this;
+ };
+
+ /**
+ * Multiplies pM1 with pM2, stores the result in pOut, returns pOut
+ */
+ cc.kmMat4Multiply = function (pOut, pM1, pM2) {
+ // Cache the matrix values (makes for huge speed increases!)
+ var outArray = pOut.mat, mat1 = pM1.mat, mat2 = pM2.mat;
+ var a00 = mat1[0], a01 = mat1[1], a02 = mat1[2], a03 = mat1[3];
+ var a10 = mat1[4], a11 = mat1[5], a12 = mat1[6], a13 = mat1[7];
+ var a20 = mat1[8], a21 = mat1[9], a22 = mat1[10], a23 = mat1[11];
+ var a30 = mat1[12], a31 = mat1[13], a32 = mat1[14], a33 = mat1[15];
+
+ var b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], b03 = mat2[3];
+ var b10 = mat2[4], b11 = mat2[5], b12 = mat2[6], b13 = mat2[7];
+ var b20 = mat2[8], b21 = mat2[9], b22 = mat2[10], b23 = mat2[11];
+ var b30 = mat2[12], b31 = mat2[13], b32 = mat2[14], b33 = mat2[15];
+
+ outArray[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30;
+ outArray[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31;
+ outArray[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32;
+ outArray[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33;
+ outArray[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30;
+ outArray[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31;
+ outArray[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32;
+ outArray[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33;
+ outArray[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30;
+ outArray[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31;
+ outArray[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32;
+ outArray[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33;
+ outArray[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30;
+ outArray[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31;
+ outArray[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32;
+ outArray[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33;
+ return pOut;
+ };
+
+ /**
+ * current matrix multiplies with other matrix mat4
+ * @param {cc.math.Matrix4} mat4
+ * @returns {cc.math.Matrix4}
+ */
+ proto.multiply = function(mat4){
+ // Cache the matrix values (makes for huge speed increases!)
+ var mat = this.mat, mat2 = mat4.mat;
+ var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
+ var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
+ var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
+ var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
+
+ var b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], b03 = mat2[3];
+ var b10 = mat2[4], b11 = mat2[5], b12 = mat2[6], b13 = mat2[7];
+ var b20 = mat2[8], b21 = mat2[9], b22 = mat2[10], b23 = mat2[11];
+ var b30 = mat2[12], b31 = mat2[13], b32 = mat2[14], b33 = mat2[15];
+
+ mat[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30;
+ mat[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31;
+ mat[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32;
+ mat[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33;
+ mat[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30;
+ mat[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31;
+ mat[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32;
+ mat[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33;
+ mat[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30;
+ mat[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31;
+ mat[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32;
+ mat[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33;
+ mat[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30;
+ mat[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31;
+ mat[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32;
+ mat[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33;
+ return this;
+ };
+
+ cc.getMat4MultiplyValue = function (pM1, pM2) {
+ var m1 = pM1.mat, m2 = pM2.mat;
+ var mat = new Float32Array(16);
+
+ mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3];
+ mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3];
+ mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3];
+ mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3];
+
+ mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7];
+ mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7];
+ mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7];
+ mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7];
+
+ mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11];
+ mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11];
+ mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11];
+ mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11];
+
+ mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15];
+ mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15];
+ mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
+ mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];
+
+ return mat;
+ };
+
+ /**
+ * Assigns the value of pIn to pOut
+ */
+ cc.kmMat4Assign = function (pOut, pIn) {
+ if (pOut === pIn) {
+ cc.log("cc.kmMat4Assign(): pOut equals pIn");
+ return pOut;
+ }
+
+ var outArr = pOut.mat;
+ var inArr = pIn.mat;
+
+ outArr[0] = inArr[0];
+ outArr[1] = inArr[1];
+ outArr[2] = inArr[2];
+ outArr[3] = inArr[3];
+
+ outArr[4] = inArr[4];
+ outArr[5] = inArr[5];
+ outArr[6] = inArr[6];
+ outArr[7] = inArr[7];
+
+ outArr[8] = inArr[8];
+ outArr[9] = inArr[9];
+ outArr[10] = inArr[10];
+ outArr[11] = inArr[11];
+
+ outArr[12] = inArr[12];
+ outArr[13] = inArr[13];
+ outArr[14] = inArr[14];
+ outArr[15] = inArr[15];
+ return pOut;
+ };
+
+ /**
+ * Assigns the value of current matrix from mat4
+ * @param {cc.math.Matrix4} mat4
+ * @returns {cc.math.Matrix4}
+ */
+ proto.assignFrom = function(mat4) {
+ if (this === mat4) {
+ cc.log("cc.mat.Matrix4.assignFrom(): mat4 equals current matrix");
+ return this;
+ }
+ var outArr = this.mat, inArr = mat4.mat;
+
+ outArr[0] = inArr[0];
+ outArr[1] = inArr[1];
+ outArr[2] = inArr[2];
+ outArr[3] = inArr[3];
+
+ outArr[4] = inArr[4];
+ outArr[5] = inArr[5];
+ outArr[6] = inArr[6];
+ outArr[7] = inArr[7];
+
+ outArr[8] = inArr[8];
+ outArr[9] = inArr[9];
+ outArr[10] = inArr[10];
+ outArr[11] = inArr[11];
+
+ outArr[12] = inArr[12];
+ outArr[13] = inArr[13];
+ outArr[14] = inArr[14];
+ outArr[15] = inArr[15];
+ return this;
+ };
+
+ /**
+ * Returns true if current matrix equal mat4 (approximately)
+ * @param {cc.math.Matrix4} mat4
+ * @returns {boolean}
+ */
+ proto.equals = function(mat4) {
+ if (this === mat4) {
+ cc.log("cc.kmMat4AreEqual(): pMat1 and pMat2 are same object.");
+ return true;
+ }
+ var matA = this.mat, matB = mat4.mat, EPSILON = cc.math.EPSILON;
+ for (var i = 0; i < 16; i++) {
+ if (!(matA[i] + EPSILON > matB[i] && matA[i] - EPSILON < matB[i]))
+ return false;
+ }
+ return true;
+ };
+
+ /**
+ * Builds an X-axis rotation matrix and stores it in matrix, returns matrix, if matrix is null, create a new matrix
+ * @param {Number} radians
+ * @param {cc.math.Matrix4} [matrix]
+ * @returns {cc.math.Matrix4}
+ */
+ cc.math.Matrix4.createByRotationX = function(radians, matrix) { //cc.kmMat4RotationX
+ /*
+ | 1 0 0 0 |
+ M = | 0 cos(A) -sin(A) 0 |
+ | 0 sin(A) cos(A) 0 |
+ | 0 0 0 1 |
+ */
+ matrix = matrix || new cc.math.Matrix4();
+ var mat = matrix.mat;
+ mat[0] = 1.0;
+ mat[3] = mat[2] = mat[1] = 0.0;
+
+ mat[4] = 0.0;
+ mat[5] = Math.cos(radians);
+ mat[6] = Math.sin(radians);
+ mat[7] = 0.0;
+
+ mat[8] = 0.0;
+ mat[9] = -Math.sin(radians);
+ mat[10] = Math.cos(radians);
+ mat[11] = 0.0;
+
+ mat[14] = mat[13] = mat[12] = 0.0;
+ mat[15] = 1.0;
+ return matrix;
+ };
+
+ /**
+ * Builds a rotation matrix using the rotation around the Y-axis, The result is stored in matrix, matrix is returned.
+ * @param {Number} radians
+ * @param {cc.math.Matrix4} [matrix]
+ * @returns {*}
+ */
+ cc.math.Matrix4.createByRotationY = function(radians, matrix) { // cc.kmMat4RotationY
+ /*
+ | cos(A) 0 sin(A) 0 |
+ M = | 0 1 0 0 |
+ | -sin(A) 0 cos(A) 0 |
+ | 0 0 0 1 |
+ */
+ matrix = matrix || new cc.math.Matrix4();
+ var mat = matrix.mat;
+ mat[0] = Math.cos(radians);
+ mat[1] = 0.0;
+ mat[2] = -Math.sin(radians);
+ mat[3] = 0.0;
+
+ mat[7] = mat[6] = mat[4] = 0.0;
+ mat[5] = 1.0;
+
+ mat[8] = Math.sin(radians);
+ mat[9] = 0.0;
+ mat[10] = Math.cos(radians);
+ mat[11] = 0.0;
+
+ mat[14] = mat[13] = mat[12] = 0.0;
+ mat[15] = 1.0;
+ return matrix;
+ };
+
+ /**
+ * Builds a rotation matrix around the Z-axis. The resulting matrix is stored in matrix. matrix is returned.
+ * @param {Number} radians
+ * @param {cc.math.Matrix4} matrix
+ * @return {cc.math.Matrix4}
+ */
+ cc.math.Matrix4.createByRotationZ = function(radians, matrix){ // cc.kmMat4RotationZ
+ /*
+ | cos(A) -sin(A) 0 0 |
+ M = | sin(A) cos(A) 0 0 |
+ | 0 0 1 0 |
+ | 0 0 0 1 |
+ */
+ matrix = matrix || new cc.math.Matrix4();
+ var mat = matrix.mat;
+ mat[0] = Math.cos(radians);
+ mat[1] = Math.sin(radians);
+ mat[3] = mat[2] = 0.0;
+
+ mat[4] = -Math.sin(radians);
+ mat[5] = Math.cos(radians);
+ mat[7] = mat[6] = 0.0;
+
+ mat[11] = mat[9] = mat[8] = 0.0;
+ mat[10] = 1.0;
+
+ mat[14] = mat[13] = mat[12] = 0.0;
+ mat[15] = 1.0;
+
+ return matrix;
+ };
+
+ /**
+ * Builds a rotation matrix from pitch, yaw and roll. The resulting matrix is stored in parameter matrix and returns.
+ * @param {Number} pitch
+ * @param {Number} yaw
+ * @param {Number} roll
+ * @param {cc.math.Matrix4} [matrix] if matrix is undefined, creates a new matrix.
+ * @returns {cc.math.Matrix4}
+ */
+ cc.math.Matrix4.createByPitchYawRoll = function(pitch, yaw, roll, matrix) {
+ matrix = matrix || new cc.math.Matrix4();
+ var cr = Math.cos(pitch), sr = Math.sin(pitch);
+ var cp = Math.cos(yaw), sp = Math.sin(yaw);
+ var cy = Math.cos(roll), sy = Math.sin(roll);
+ var srsp = sr * sp, crsp = cr * sp;
+ var mat = matrix.mat;
+
+ mat[0] = cp * cy;
+ mat[4] = cp * sy;
+ mat[8] = -sp;
+
+ mat[1] = srsp * cy - cr * sy;
+ mat[5] = srsp * sy + cr * cy;
+ mat[9] = sr * cp;
+
+ mat[2] = crsp * cy + sr * sy;
+ mat[6] = crsp * sy - sr * cy;
+ mat[10] = cr * cp;
+
+ mat[3] = mat[7] = mat[11] = 0.0;
+ mat[15] = 1.0;
+ return matrix;
+ };
+
+ /**
+ * Builds a matrix by a quaternion.
+ * @param {cc.math.Quaternion} quaternion
+ * @param {cc.math.Matrix4} [matrix] if matrix is undefined, creates a new matrix.
+ * @returns {cc.math.Matrix4}
+ */
+ cc.math.Matrix4.createByQuaternion = function(quaternion, matrix) {
+ matrix = matrix || new cc.math.Matrix4();
+ var mat = matrix.mat;
+ mat[0] = 1.0 - 2.0 * (quaternion.y * quaternion.y + quaternion.z * quaternion.z );
+ mat[1] = 2.0 * (quaternion.x * quaternion.y + quaternion.z * quaternion.w);
+ mat[2] = 2.0 * (quaternion.x * quaternion.z - quaternion.y * quaternion.w);
+ mat[3] = 0.0;
+
+ // Second row
+ mat[4] = 2.0 * ( quaternion.x * quaternion.y - quaternion.z * quaternion.w );
+ mat[5] = 1.0 - 2.0 * ( quaternion.x * quaternion.x + quaternion.z * quaternion.z );
+ mat[6] = 2.0 * (quaternion.z * quaternion.y + quaternion.x * quaternion.w );
+ mat[7] = 0.0;
+
+ // Third row
+ mat[8] = 2.0 * ( quaternion.x * quaternion.z + quaternion.y * quaternion.w );
+ mat[9] = 2.0 * ( quaternion.y * quaternion.z - quaternion.x * quaternion.w );
+ mat[10] = 1.0 - 2.0 * ( quaternion.x * quaternion.x + quaternion.y * quaternion.y );
+ mat[11] = 0.0;
+
+ // Fourth row
+ mat[14] = mat[13] = mat[12] = 0;
+ mat[15] = 1.0;
+ return matrix;
+ };
+
+ /**
+ * Build a 4x4 OpenGL transformation matrix using a 3x3 rotation matrix, and a 3d vector representing a translation.
+ * @param {cc.math.Matrix3} rotation
+ * @param {cc.math.Vec3} translation
+ * @param {cc.math.Matrix4} [matrix] if matrix is undefined, creates a new matrix.
+ * @returns {cc.math.Matrix4}
+ */
+ cc.math.Matrix4.createByRotationTranslation = function(rotation, translation, matrix) {
+ matrix = matrix || new cc.math.Matrix4();
+ var mat = matrix.mat, rMat = rotation.mat;
+ mat[0] = rMat[0];
+ mat[1] = rMat[1];
+ mat[2] = rMat[2];
+ mat[3] = 0.0;
+
+ mat[4] = rMat[3];
+ mat[5] = rMat[4];
+ mat[6] = rMat[5];
+ mat[7] = 0.0;
+
+ mat[8] = rMat[6];
+ mat[9] = rMat[7];
+ mat[10] = rMat[8];
+ mat[11] = 0.0;
+
+ mat[12] = translation.x;
+ mat[13] = translation.y;
+ mat[14] = translation.z;
+ mat[15] = 1.0;
+ return matrix;
+ };
+
+ /**
+ * Builds a scaling matrix
+ * @param {Number} x
+ * @param {Number} y
+ * @param {Number} z
+ * @param {cc.math.Matrix4} [matrix] if matrix is undefined, creates a new matrix.
+ * @returns {cc.math.Matrix4}
+ */
+ cc.math.Matrix4.createByScale = function(x, y, z, matrix) { //cc.kmMat4Scaling
+ matrix = matrix || new cc.math.Matrix4();
+ var mat = matrix.mat;
+ mat[0] = x;
+ mat[5] = y;
+ mat[10] = z;
+ mat[15] = 1.0;
+ mat[1] = mat[2] = mat[3] = mat[4] = mat[6] = mat[7] =
+ mat[8] = mat[9] = mat[11] = mat[12] = mat[13] = mat[14] = 0;
+ return matrix;
+ };
+
+ /**
+ * Builds a translation matrix. All other elements in the matrix
+ * will be set to zero except for the diagonal which is set to 1.0
+ */
+ cc.kmMat4Translation = function (pOut, x, y, z) {
+ //FIXME: Write a test for this
+ pOut.mat[0] = pOut.mat[5] = pOut.mat[10] = pOut.mat[15] = 1.0;
+ pOut.mat[1] = pOut.mat[2] = pOut.mat[3] =
+ pOut.mat[4] = pOut.mat[6] = pOut.mat[7] =
+ pOut.mat[8] = pOut.mat[9] = pOut.mat[11] = 0.0;
+ pOut.mat[12] = x;
+ pOut.mat[13] = y;
+ pOut.mat[14] = z;
+ return pOut;
+ };
+
+ /**
+ * Builds a translation matrix.
+ * @param {Number} x
+ * @param {Number} y
+ * @param {Number} z
+ * @param {cc.math.Matrix4} [matrix] if matrix is undefined, creates a new matrix.
+ * @returns {cc.math.Matrix4}
+ */
+ cc.math.Matrix4.createByTranslation = function(x, y, z, matrix){ //cc.kmMat4Translation
+ matrix = matrix || new cc.math.Matrix4();
+ matrix.identity();
+ matrix.mat[12] = x;
+ matrix.mat[13] = y;
+ matrix.mat[14] = z;
+ return matrix;
+ };
+
+ /**
+ * Get the up vector from a matrix.
+ * @returns {cc.math.Vec3}
+ */
+ proto.getUpVec3 = function() {
+ var mat = this.mat;
+ var ret = new cc.math.Vec3(mat[4],mat[5], mat[6]);
+ return ret.normalize();
+ };
+
+ /**
+ * Extract the right vector from a 4x4 matrix.
+ * @returns {cc.math.Vec3}
+ */
+ proto.getRightVec3 = function(){
+ var mat = this.mat;
+ var ret = new cc.math.Vec3(mat[0],mat[1], mat[2]);
+ return ret.normalize();
+ };
+
+ /**
+ * Extract the forward vector from a 4x4 matrix.
+ * @returns {cc.math.Vec3}
+ */
+ proto.getForwardVec3 = function() {
+ var mat = this.mat;
+ var ret = new cc.math.Vec3(mat[8],mat[9], mat[10]);
+ return ret.normalize();
+ };
+
+ /**
+ * Creates a perspective projection matrix in the
+ * same way as gluPerspective
+ */
+ cc.kmMat4PerspectiveProjection = function (pOut, fovY, aspect, zNear, zFar) {
+ var r = cc.degreesToRadians(fovY / 2);
+ var deltaZ = zFar - zNear;
+ var s = Math.sin(r);
+
+ if (deltaZ === 0 || s === 0 || aspect === 0)
+ return null;
+
+ //cos(r) / sin(r) = cot(r)
+ var cotangent = Math.cos(r) / s;
+ pOut.identity();
+ pOut.mat[0] = cotangent / aspect;
+ pOut.mat[5] = cotangent;
+ pOut.mat[10] = -(zFar + zNear) / deltaZ;
+ pOut.mat[11] = -1;
+ pOut.mat[14] = -2 * zNear * zFar / deltaZ;
+ pOut.mat[15] = 0;
+
+ return pOut;
+ };
+
+ /**
+ * Creates a perspective projection matrix in the same way as gluPerspective
+ * @param {Number} fovY
+ * @param {Number} aspect
+ * @param {Number} zNear
+ * @param {Number} zFar
+ * @returns {cc.math.Matrix4|Null}
+ */
+ cc.math.Matrix4.createPerspectiveProjection = function(fovY, aspect, zNear, zFar){
+ var r = cc.degreesToRadians(fovY / 2), deltaZ = zFar - zNear;
+ var s = Math.sin(r);
+
+ if (deltaZ === 0 || s === 0 || aspect === 0)
+ return null;
+
+ //cos(r) / sin(r) = cot(r)
+ var cotangent = Math.cos(r) / s;
+ var matrix = new cc.math.Matrix4(), mat = matrix.mat;
+ matrix.identity();
+ mat[0] = cotangent / aspect;
+ mat[5] = cotangent;
+ mat[10] = -(zFar + zNear) / deltaZ;
+ mat[11] = -1;
+ mat[14] = -2 * zNear * zFar / deltaZ;
+ mat[15] = 0;
+ return matrix;
+ };
+
+ /** Creates an orthographic projection matrix like glOrtho */
+ cc.kmMat4OrthographicProjection = function (pOut, left, right, bottom, top, nearVal, farVal) {
+ pOut.identity();
+ pOut.mat[0] = 2 / (right - left);
+ pOut.mat[5] = 2 / (top - bottom);
+ pOut.mat[10] = -2 / (farVal - nearVal);
+ pOut.mat[12] = -((right + left) / (right - left));
+ pOut.mat[13] = -((top + bottom) / (top - bottom));
+ pOut.mat[14] = -((farVal + nearVal) / (farVal - nearVal));
+ return pOut;
+ };
+
+ /**
+ * Creates an orthographic projection matrix like glOrtho
+ * @param {Number} left
+ * @param {Number} right
+ * @param {Number} bottom
+ * @param {Number} top
+ * @param {Number} nearVal
+ * @param {Number} farVal
+ * @returns {cc.math.Matrix4}
+ */
+ cc.math.Matrix4.createOrthographicProjection = function (left, right, bottom, top, nearVal, farVal) {
+ var matrix = new cc.math.Matrix4(), mat = matrix.mat;
+ matrix.identity();
+ mat[0] = 2 / (right - left);
+ mat[5] = 2 / (top - bottom);
+ mat[10] = -2 / (farVal - nearVal);
+ mat[12] = -((right + left) / (right - left));
+ mat[13] = -((top + bottom) / (top - bottom));
+ mat[14] = -((farVal + nearVal) / (farVal - nearVal));
+ return matrix;
+ };
+
+ /**
+ * Builds a translation matrix in the same way as gluLookAt()
+ * the resulting matrix is stored in pOut. pOut is returned.
+ */
+ cc.kmMat4LookAt = function (pOut, pEye, pCenter, pUp) {
+ var f = new cc.math.Vec3(pCenter), up = new cc.math.Vec3(pUp);
+ f.subtract(pEye);
+ f.normalize();
+ up.normalize();
+
+ var s = new cc.math.Vec3(f);
+ s.cross(up);
+ s.normalize();
+
+ var u = new cc.math.Vec3(s);
+ u.cross(f);
+ s.normalize();
+
+ pOut.identity();
+
+ pOut.mat[0] = s.x;
+ pOut.mat[4] = s.y;
+ pOut.mat[8] = s.z;
+
+ pOut.mat[1] = u.x;
+ pOut.mat[5] = u.y;
+ pOut.mat[9] = u.z;
+
+ pOut.mat[2] = -f.x;
+ pOut.mat[6] = -f.y;
+ pOut.mat[10] = -f.z;
+
+ var translate = cc.math.Matrix4.createByTranslation(-pEye.x, -pEye.y, -pEye.z);
+ pOut.multiply(translate);
+ return pOut;
+ };
+
+ var tempMatrix = new cc.math.Matrix4(); // an internal matrix
+ proto.lookAt = function(eyeVec, centerVec, upVec) {
+ var f = new cc.math.Vec3(centerVec), up = new cc.math.Vec3(upVec), mat = this.mat;
+ f.subtract(eyeVec);
+ f.normalize();
+ up.normalize();
+
+ var s = new cc.math.Vec3(f);
+ s.cross(up);
+ s.normalize();
+
+ var u = new cc.math.Vec3(s);
+ u.cross(f);
+ s.normalize();
+
+ this.identity();
+ mat[0] = s.x;
+ mat[4] = s.y;
+ mat[8] = s.z;
+
+ mat[1] = u.x;
+ mat[5] = u.y;
+ mat[9] = u.z;
+
+ mat[2] = -f.x;
+ mat[6] = -f.y;
+ mat[10] = -f.z;
+
+ tempMatrix = cc.math.Matrix4.createByTranslation(-eyeVec.x, -eyeVec.y, -eyeVec.z, tempMatrix);
+ this.multiply(tempMatrix);
+ return this;
+ };
+
+ /**
+ * Build a rotation matrix from an axis and an angle. Result is stored in pOut.
+ * pOut is returned.
+ */
+ cc.kmMat4RotationAxisAngle = function (pOut, axis, radians) {
+ var rcos = Math.cos(radians), rsin = Math.sin(radians);
+
+ var normalizedAxis = new cc.math.Vec3(axis);
+ normalizedAxis.normalize();
+
+ pOut.mat[0] = rcos + normalizedAxis.x * normalizedAxis.x * (1 - rcos);
+ pOut.mat[1] = normalizedAxis.z * rsin + normalizedAxis.y * normalizedAxis.x * (1 - rcos);
+ pOut.mat[2] = -normalizedAxis.y * rsin + normalizedAxis.z * normalizedAxis.x * (1 - rcos);
+ pOut.mat[3] = 0.0;
+
+ pOut.mat[4] = -normalizedAxis.z * rsin + normalizedAxis.x * normalizedAxis.y * (1 - rcos);
+ pOut.mat[5] = rcos + normalizedAxis.y * normalizedAxis.y * (1 - rcos);
+ pOut.mat[6] = normalizedAxis.x * rsin + normalizedAxis.z * normalizedAxis.y * (1 - rcos);
+ pOut.mat[7] = 0.0;
+
+ pOut.mat[8] = normalizedAxis.y * rsin + normalizedAxis.x * normalizedAxis.z * (1 - rcos);
+ pOut.mat[9] = -normalizedAxis.x * rsin + normalizedAxis.y * normalizedAxis.z * (1 - rcos);
+ pOut.mat[10] = rcos + normalizedAxis.z * normalizedAxis.z * (1 - rcos);
+ pOut.mat[11] = 0.0;
+
+ pOut.mat[12] = 0.0;
+ pOut.mat[13] = 0.0;
+ pOut.mat[14] = 0.0;
+ pOut.mat[15] = 1.0;
+
+ return pOut;
+ };
+
+ /**
+ * Build a rotation matrix from an axis and an angle.
+ * @param {cc.math.Vec3} axis
+ * @param {Number} radians
+ * @param {cc.math.Matrix4} [matrix]
+ * @returns {cc.math.Matrix4}
+ */
+ cc.math.Matrix4.createByAxisAndAngle = function(axis, radians, matrix) {
+ matrix = matrix || new cc.math.Matrix4();
+ var mat = this.mat, rcos = Math.cos(radians), rsin = Math.sin(radians) ;
+
+ var normalizedAxis = new cc.math.Vec3(axis);
+ normalizedAxis.normalize();
+
+ mat[0] = rcos + normalizedAxis.x * normalizedAxis.x * (1 - rcos);
+ mat[1] = normalizedAxis.z * rsin + normalizedAxis.y * normalizedAxis.x * (1 - rcos);
+ mat[2] = -normalizedAxis.y * rsin + normalizedAxis.z * normalizedAxis.x * (1 - rcos);
+ mat[3] = 0.0;
+
+ mat[4] = -normalizedAxis.z * rsin + normalizedAxis.x * normalizedAxis.y * (1 - rcos);
+ mat[5] = rcos + normalizedAxis.y * normalizedAxis.y * (1 - rcos);
+ mat[6] = normalizedAxis.x * rsin + normalizedAxis.z * normalizedAxis.y * (1 - rcos);
+ mat[7] = 0.0;
+
+ mat[8] = normalizedAxis.y * rsin + normalizedAxis.x * normalizedAxis.z * (1 - rcos);
+ mat[9] = -normalizedAxis.x * rsin + normalizedAxis.y * normalizedAxis.z * (1 - rcos);
+ mat[10] = rcos + normalizedAxis.z * normalizedAxis.z * (1 - rcos);
+ mat[11] = 0.0;
+
+ mat[12] = mat[13] = mat[14] = 0.0;
+ mat[15] = 1.0;
+ return matrix;
+ };
+
+ /**
+ * Extract a 3x3 rotation matrix from the input 4x4 transformation.
+ * @returns {cc.math.Matrix3}
+ */
+ proto.extractRotation = function(){
+ var matrix = new cc.math.Matrix3(), mat4 = this.mat, mat3 = matrix.mat;
+ mat3[0] = mat4[0];
+ mat3[1] = mat4[1];
+ mat3[2] = mat4[2];
+
+ mat3[3] = mat4[4];
+ mat3[4] = mat4[5];
+ mat3[5] = mat4[6];
+
+ mat3[6] = mat4[8];
+ mat3[7] = mat4[9];
+ mat3[8] = mat4[10];
+ return matrix;
+ };
+
+ proto.extractPlane = function(planeType) {
+ var plane = new cc.math.Plane(), mat = this.mat;
+ switch (planeType) {
+ case cc.math.Plane.RIGHT:
+ plane.a = mat[3] - mat[0];
+ plane.b = mat[7] - mat[4];
+ plane.c = mat[11] - mat[8];
+ plane.d = mat[15] - mat[12];
+ break;
+ case cc.math.Plane.LEFT:
+ plane.a = mat[3] + mat[0];
+ plane.b = mat[7] + mat[4];
+ plane.c = mat[11] + mat[8];
+ plane.d = mat[15] + mat[12];
+ break;
+ case cc.math.Plane.BOTTOM:
+ plane.a = mat[3] + mat[1];
+ plane.b = mat[7] + mat[5];
+ plane.c = mat[11] + mat[9];
+ plane.d = mat[15] + mat[13];
+ break;
+ case cc.math.Plane.TOP:
+ plane.a = mat[3] - mat[1];
+ plane.b = mat[7] - mat[5];
+ plane.c = mat[11] - mat[9];
+ plane.d = mat[15] - mat[13];
+ break;
+ case cc.math.Plane.FAR:
+ plane.a = mat[3] - mat[2];
+ plane.b = mat[7] - mat[6];
+ plane.c = mat[11] - mat[10];
+ plane.d = mat[15] - mat[14];
+ break;
+ case cc.math.Plane.NEAR:
+ plane.a = mat[3] + mat[2];
+ plane.b = mat[7] + mat[6];
+ plane.c = mat[11] + mat[10];
+ plane.d = mat[15] + mat[14];
+ break;
+ default:
+ cc.log("cc.math.Matrix4.extractPlane: Invalid plane index");
+ break;
+ }
+
+ var t = Math.sqrt(plane.a * plane.a + plane.b * plane.b + plane.c * plane.c);
+ plane.a /= t;
+ plane.b /= t;
+ plane.c /= t;
+ plane.d /= t;
+ return plane;
+ };
+
+ /**
+ * Take the rotation from a 4x4 transformation matrix, and return it as an axis and an angle (in radians)
+ * @returns {*|{axis: cc.math.Vec3, angle: number}}
+ */
+ proto.toAxisAndAngle = function() {
+ /*Surely not this easy?*/
+ var rotation = this.extractRotation();
+ var temp = cc.math.Quaternion.rotationMatrix(rotation);
+ return temp.toAxisAndAngle();
+ };
+})(cc);
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/mat4SIMD.js b/frameworks/cocos2d-html5/cocos2d/kazmath/mat4SIMD.js
new file mode 100644
index 0000000..f716de7
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/mat4SIMD.js
@@ -0,0 +1,428 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+(function(cc) {
+ var proto = cc.math.Matrix4.prototype;
+
+ cc.kmMat4InverseSIMD = function (pOut, pM) {
+ pOut = pM.inverseSIMD();
+ return pOut;
+ };
+
+ proto.inverseSIMD = function(){
+ var inv = new cc.math.Matrix4();
+ var src = this.mat;
+ var dest = inv.mat;
+ var src0, src1, src2, src3;
+ var row0, row1, row2, row3;
+ var tmp1;
+ var minor0, minor1, minor2, minor3;
+ var det;
+
+ // Load the 4 rows
+ var src0 = SIMD.float32x4.load(src, 0);
+ var src1 = SIMD.float32x4.load(src, 4);
+ var src2 = SIMD.float32x4.load(src, 8);
+ var src3 = SIMD.float32x4.load(src, 12);
+
+ // Transpose the source matrix. Sort of. Not a true transpose operation
+
+ tmp1 = SIMD.float32x4.shuffle(src0, src1, 0, 1, 4, 5);
+ row1 = SIMD.float32x4.shuffle(src2, src3, 0, 1, 4, 5);
+ row0 = SIMD.float32x4.shuffle(tmp1, row1, 0, 2, 4, 6);
+ row1 = SIMD.float32x4.shuffle(row1, tmp1, 1, 3, 5, 7);
+
+ tmp1 = SIMD.float32x4.shuffle(src0, src1, 2, 3, 6, 7);
+ row3 = SIMD.float32x4.shuffle(src2, src3, 2, 3, 6, 7);
+ row2 = SIMD.float32x4.shuffle(tmp1, row3, 0, 2, 4, 6);
+ row3 = SIMD.float32x4.shuffle(row3, tmp1, 1, 3, 5, 7);
+
+ // ----
+ tmp1 = SIMD.float32x4.mul(row2, row3);
+ tmp1 = SIMD.float32x4.swizzle(tmp1, 1, 0, 3, 2); // 0xB1 = 10110001
+ minor0 = SIMD.float32x4.mul(row1, tmp1);
+ minor1 = SIMD.float32x4.mul(row0, tmp1);
+ tmp1 = SIMD.float32x4.swizzle(tmp1, 2, 3, 0, 1); // 0x4E = 01001110
+ minor0 = SIMD.float32x4.sub(SIMD.float32x4.mul(row1, tmp1), minor0);
+ minor1 = SIMD.float32x4.sub(SIMD.float32x4.mul(row0, tmp1), minor1);
+ minor1 = SIMD.float32x4.swizzle(minor1, 2, 3, 0, 1); // 0x4E = 01001110
+
+ // ----
+ tmp1 = SIMD.float32x4.mul(row1, row2);
+ tmp1 = SIMD.float32x4.swizzle(tmp1, 1, 0, 3, 2); // 0xB1 = 10110001
+ minor0 = SIMD.float32x4.add(SIMD.float32x4.mul(row3, tmp1), minor0);
+ minor3 = SIMD.float32x4.mul(row0, tmp1);
+ tmp1 = SIMD.float32x4.swizzle(tmp1, 2, 3, 0, 1); // 0x4E = 01001110
+ minor0 = SIMD.float32x4.sub(minor0, SIMD.float32x4.mul(row3, tmp1));
+ minor3 = SIMD.float32x4.sub(SIMD.float32x4.mul(row0, tmp1), minor3);
+ minor3 = SIMD.float32x4.swizzle(minor3, 2, 3, 0, 1); // 0x4E = 01001110
+
+ // ----
+ tmp1 = SIMD.float32x4.mul(SIMD.float32x4.swizzle(row1, 2, 3, 0, 1), row3); // 0x4E = 01001110
+ tmp1 = SIMD.float32x4.swizzle(tmp1, 1, 0, 3, 2); // 0xB1 = 10110001
+ row2 = SIMD.float32x4.swizzle(row2, 2, 3, 0, 1); // 0x4E = 01001110
+ minor0 = SIMD.float32x4.add(SIMD.float32x4.mul(row2, tmp1), minor0);
+ minor2 = SIMD.float32x4.mul(row0, tmp1);
+ tmp1 = SIMD.float32x4.swizzle(tmp1, 2, 3, 0, 1); // 0x4E = 01001110
+ minor0 = SIMD.float32x4.sub(minor0, SIMD.float32x4.mul(row2, tmp1));
+ minor2 = SIMD.float32x4.sub(SIMD.float32x4.mul(row0, tmp1), minor2);
+ minor2 = SIMD.float32x4.swizzle(minor2, 2, 3, 0, 1); // 0x4E = 01001110
+
+ // ----
+ tmp1 = SIMD.float32x4.mul(row0, row1);
+ tmp1 = SIMD.float32x4.swizzle(tmp1, 1, 0, 3, 2); // 0xB1 = 10110001
+ minor2 = SIMD.float32x4.add(SIMD.float32x4.mul(row3, tmp1), minor2);
+ minor3 = SIMD.float32x4.sub(SIMD.float32x4.mul(row2, tmp1), minor3);
+ tmp1 = SIMD.float32x4.swizzle(tmp1, 2, 3, 0, 1); // 0x4E = 01001110
+ minor2 = SIMD.float32x4.sub(SIMD.float32x4.mul(row3, tmp1), minor2);
+ minor3 = SIMD.float32x4.sub(minor3, SIMD.float32x4.mul(row2, tmp1));
+
+ // ----
+ tmp1 = SIMD.float32x4.mul(row0, row3);
+ tmp1 = SIMD.float32x4.swizzle(tmp1, 1, 0, 3, 2); // 0xB1 = 10110001
+ minor1 = SIMD.float32x4.sub(minor1, SIMD.float32x4.mul(row2, tmp1));
+ minor2 = SIMD.float32x4.add(SIMD.float32x4.mul(row1, tmp1), minor2);
+ tmp1 = SIMD.float32x4.swizzle(tmp1, 2, 3, 0, 1); // 0x4E = 01001110
+ minor1 = SIMD.float32x4.add(SIMD.float32x4.mul(row2, tmp1), minor1);
+ minor2 = SIMD.float32x4.sub(minor2, SIMD.float32x4.mul(row1, tmp1));
+
+ // ----
+ tmp1 = SIMD.float32x4.mul(row0, row2);
+ tmp1 = SIMD.float32x4.swizzle(tmp1, 1, 0, 3, 2); // 0xB1 = 10110001
+ minor1 = SIMD.float32x4.add(SIMD.float32x4.mul(row3, tmp1), minor1);
+ minor3 = SIMD.float32x4.sub(minor3, SIMD.float32x4.mul(row1, tmp1));
+ tmp1 = SIMD.float32x4.swizzle(tmp1, 2, 3, 0, 1); // 0x4E = 01001110
+ minor1 = SIMD.float32x4.sub(minor1, SIMD.float32x4.mul(row3, tmp1));
+ minor3 = SIMD.float32x4.add(SIMD.float32x4.mul(row1, tmp1), minor3);
+
+ // Compute determinant
+ det = SIMD.float32x4.mul(row0, minor0);
+ det = SIMD.float32x4.add(SIMD.float32x4.swizzle(det, 2, 3, 0, 1), det); // 0x4E = 01001110
+ det = SIMD.float32x4.add(SIMD.float32x4.swizzle(det, 1, 0, 3, 2), det); // 0xB1 = 10110001
+ tmp1 = SIMD.float32x4.reciprocalApproximation(det);
+ det = SIMD.float32x4.sub(SIMD.float32x4.add(tmp1, tmp1), SIMD.float32x4.mul(det, SIMD.float32x4.mul(tmp1, tmp1)));
+ det = SIMD.float32x4.swizzle(det, 0, 0, 0, 0);
+
+ // Compute final values by multiplying with 1/det
+ minor0 = SIMD.float32x4.mul(det, minor0);
+ minor1 = SIMD.float32x4.mul(det, minor1);
+ minor2 = SIMD.float32x4.mul(det, minor2);
+ minor3 = SIMD.float32x4.mul(det, minor3);
+
+ SIMD.float32x4.store(dest, 0, minor0);
+ SIMD.float32x4.store(dest, 4, minor1);
+ SIMD.float32x4.store(dest, 8, minor2);
+ SIMD.float32x4.store(dest, 12, minor3);
+
+ return inv;
+ };
+
+ var identityMatrix = new cc.math.Matrix4().identity();
+ proto.isIdentitySIMD = function () {
+ var inx4 = SIMD.float32x4.load(this.mat, 0);
+ var identityx4 = SIMD.float32x4.load(identityMatrix.mat, 0);
+ var ret = SIMD.float32x4.equal(inx4, identityx4);
+ if(ret.signMask === 0x00)
+ return false;
+
+ inx4 = SIMD.float32x4.load(this.mat, 4);
+ identityx4 = SIMD.float32x4.load(identityMatrix.mat, 4);
+ ret = SIMD.float32x4.equal(inx4, identityx4);
+ if(ret.signMask === 0x00)
+ return false;
+
+ inx4 = SIMD.float32x4.load(this.mat, 8);
+ identityx4 = SIMD.float32x4.load(identityMatrix.mat, 8);
+ ret = SIMD.float32x4.equal(inx4, identityx4);
+ if(ret.signMask === 0x00)
+ return false;
+
+ inx4 = SIMD.float32x4.load(this.mat, 12);
+ identityx4 = SIMD.float32x4.load(identityMatrix.mat, 12);
+ ret = SIMD.float32x4.equal(inx4, identityx4);
+ if(ret.signMask === 0x00)
+ return false;
+ return true;
+ };
+
+ proto.transposeSIMD = function () {
+ var outArr = this.mat, inArr = this.mat;
+ var src0 = SIMD.float32x4.load(inArr, 0);
+ var src1 = SIMD.float32x4.load(inArr, 4);
+ var src2 = SIMD.float32x4.load(inArr, 8);
+ var src3 = SIMD.float32x4.load(inArr, 12);
+ var dst0;
+ var dst1;
+ var dst2;
+ var dst3;
+ var tmp01;
+ var tmp23;
+
+ tmp01 = SIMD.float32x4.shuffle(src0, src1, 0, 1, 4, 5);
+ tmp23 = SIMD.float32x4.shuffle(src2, src3, 0, 1, 4, 5);
+ dst0 = SIMD.float32x4.shuffle(tmp01, tmp23, 0, 2, 4, 6);
+ dst1 = SIMD.float32x4.shuffle(tmp01, tmp23, 1, 3, 5, 7);
+
+ tmp01 = SIMD.float32x4.shuffle(src0, src1, 2, 3, 6, 7);
+ tmp23 = SIMD.float32x4.shuffle(src2, src3, 2, 3, 6, 7);
+ dst2 = SIMD.float32x4.shuffle(tmp01, tmp23, 0, 2, 4, 6);
+ dst3 = SIMD.float32x4.shuffle(tmp01, tmp23, 1, 3, 5, 7);
+
+ SIMD.float32x4.store(outArr, 0, dst0);
+ SIMD.float32x4.store(outArr, 4, dst1);
+ SIMD.float32x4.store(outArr, 8, dst2);
+ SIMD.float32x4.store(outArr, 12, dst3);
+ return this;
+ };
+
+ cc.kmMat4MultiplySIMD = function (pOut, pM1, pM2) {
+ pOut = new cc.math.Matrix4(pM1);
+ return pOut.multiplySIMD(pM2);
+ };
+
+ proto.multiplySIMD = function(mat4) {
+ var a = this.mat;
+ var b = mat4.mat;
+ var out = this.mat;
+
+ var a0 = SIMD.float32x4.load(a,0);
+ var a1 = SIMD.float32x4.load(a,4);
+ var a2 = SIMD.float32x4.load(a,8);
+ var a3 = SIMD.float32x4.load(a,12);
+ var b0 = SIMD.float32x4.load(b, 0);
+ SIMD.float32x4.store(out, 0, SIMD.float32x4.add(
+ SIMD.float32x4.mul(
+ SIMD.float32x4.swizzle(b0, 0, 0, 0, 0), a0),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b0, 1, 1, 1, 1), a1),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b0, 2, 2, 2, 2), a2),
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b0, 3, 3, 3, 3), a3)))));
+ var b1 = SIMD.float32x4.load(b, 4);
+ SIMD.float32x4.store(out, 4, SIMD.float32x4.add(
+ SIMD.float32x4.mul(
+ SIMD.float32x4.swizzle(b1, 0, 0, 0, 0), a0),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b1, 1, 1, 1, 1), a1),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b1, 2, 2, 2, 2), a2),
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b1, 3, 3, 3, 3), a3)))));
+ var b2 = SIMD.float32x4.load(b, 8);
+ SIMD.float32x4.store(out, 8, SIMD.float32x4.add(
+ SIMD.float32x4.mul(
+ SIMD.float32x4.swizzle(b2, 0, 0, 0, 0), a0),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b2, 1, 1, 1, 1), a1),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b2, 2, 2, 2, 2), a2),
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b2, 3, 3, 3, 3), a3)))));
+ var b3 = SIMD.float32x4.load(b, 12);
+ SIMD.float32x4.store(out, 12, SIMD.float32x4.add(
+ SIMD.float32x4.mul(
+ SIMD.float32x4.swizzle(b3, 0, 0, 0, 0), a0),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b3, 1, 1, 1, 1), a1),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b3, 2, 2, 2, 2), a2),
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b3, 3, 3, 3, 3), a3)))));
+
+ return this;
+ };
+
+ cc.getMat4MultiplyValueSIMD = function (pM1, pM2) {
+ var mat = new cc.math.Matrix4(pM1);
+ return mat.multiplySIMD(pM2);
+ };
+
+ cc.kmMat4AssignSIMD = function (pOut, pIn) {
+ if(pOut == pIn) {
+ cc.log("cc.kmMat4Assign(): pOut equals pIn");//TODO: ADD SIMD?
+ return pOut;
+ }
+
+ return pOut.assignFromSIMD(pIn);
+ };
+
+ proto.assignFromSIMD = function (mat4) {
+ if(this == mat4) {
+ cc.log("cc.mat.Matrix4.assignFrom(): mat4 equals current matrix");//TODO: ADD SIMD?
+ return this;
+ }
+
+ var outArr = this.mat;
+ var inArr = mat4.mat;
+
+ SIMD.float32x4.store(outArr, 0, SIMD.float32x4.load(inArr, 0));
+ SIMD.float32x4.store(outArr, 4, SIMD.float32x4.load(inArr, 4));
+ SIMD.float32x4.store(outArr, 8, SIMD.float32x4.load(inArr, 8));
+ SIMD.float32x4.store(outArr, 12, SIMD.float32x4.load(inArr, 12));
+
+ return this;
+ };
+
+ proto.equalsSIMD = function (mat4) {
+ if(this === mat4){
+ cc.log("cc.kmMat4AreEqual(): pMat1 and pMat2 are same object.");
+ return true;
+ }
+ var m10 = SIMD.float32x4.load(this.mat, 0);
+ var m20 = SIMD.float32x4.load(mat4.mat, 0);
+
+ var epsilon = SIMD.float32x4.splat(cc.math.EPSILON);
+
+ var ret = SIMD.float32x4.lessThanOrEqual(SIMD.float32x4.abs(SIMD.float32x4.sub(m10, m20)), epsilon);
+ if (ret.signMask === 0)
+ return false;
+
+ var m11 = SIMD.float32x4.load(this.mat, 4);
+ var m21 = SIMD.float32x4.load(mat4.mat, 4);
+ ret = SIMD.float32x4.lessThanOrEqual(SIMD.float32x4.abs(SIMD.float32x4.sub(m11, m21)), epsilon);
+ if (ret.signMask === 0)
+ return false;
+
+ var m12 = SIMD.float32x4.load(this.mat, 8);
+ var m22 = SIMD.float32x4.load(mat4.mat, 8);
+ ret = SIMD.float32x4.lessThanOrEqual(SIMD.float32x4.abs(SIMD.float32x4.sub(m12, m22)), epsilon);
+ if (ret.signMask === 0)
+ return false;
+
+ var m13 = SIMD.float32x4.load(this.mat, 12);
+ var m23 = SIMD.float32x4.load(mat4.mat, 12);
+ ret = SIMD.float32x4.lessThanOrEqual(SIMD.float32x4.abs(SIMD.float32x4.sub(m13, m23)), epsilon);
+ if (ret.signMask === 0)
+ return false;
+ return true;
+ };
+
+ cc.kmMat4LookAtSIMD = function (pOut, pEye, pCenter, pUp) {
+ return pOut.lookAtSIMD(pEye, pCenter, pUp);
+ };
+
+ proto.lookAtSIMD = function(eyeVec, centerVec, upVec) {
+ var out = this.mat;
+
+ var center = SIMD.float32x4(centerVec.x, centerVec.y, centerVec.z, 0.0);
+ var eye = SIMD.float32x4(eyeVec.x, eyeVec.y, eyeVec.z, 0.0);
+ var up = SIMD.float32x4(upVec.x, upVec.y, upVec.z, 0.0);
+
+ // cc.kmVec3Subtract(f, pCenter, pEye);
+ var f = SIMD.float32x4.sub(center, eye);
+ // cc.kmVec3Normalize(f, f);
+ var tmp = SIMD.float32x4.mul(f, f);
+ tmp = SIMD.float32x4.add(tmp, SIMD.float32x4.add(SIMD.float32x4.swizzle(tmp, 1, 2, 0, 3), SIMD.float32x4.swizzle(tmp, 2, 0, 1, 3)));
+ f = SIMD.float32x4.mul(f, SIMD.float32x4.reciprocalSqrtApproximation(tmp));
+
+ // cc.kmVec3Assign(up, pUp);
+ // cc.kmVec3Normalize(up, up);
+ tmp = SIMD.float32x4.mul(up, up);
+ tmp = SIMD.float32x4.add(tmp, SIMD.float32x4.add(SIMD.float32x4.swizzle(tmp, 1, 2, 0, 3), SIMD.float32x4.swizzle(tmp, 2, 0, 1, 3)));
+ up = SIMD.float32x4.mul(up, SIMD.float32x4.reciprocalSqrtApproximation(tmp));
+
+ // cc.kmVec3Cross(s, f, up);
+ var s = SIMD.float32x4.sub(SIMD.float32x4.mul(SIMD.float32x4.swizzle(f, 1, 2, 0, 3), SIMD.float32x4.swizzle(up, 2, 0, 1, 3)),
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(f, 2, 0, 1, 3), SIMD.float32x4.swizzle(up, 1, 2, 0, 3)));
+ // cc.kmVec3Normalize(s, s);
+ tmp = SIMD.float32x4.mul(s, s);
+ tmp = SIMD.float32x4.add(tmp, SIMD.float32x4.add(SIMD.float32x4.swizzle(tmp, 1, 2, 0, 3), SIMD.float32x4.swizzle(tmp, 2, 0, 1, 3)));
+ s = SIMD.float32x4.mul(s, SIMD.float32x4.reciprocalSqrtApproximation(tmp));
+
+ // cc.kmVec3Cross(u, s, f);
+ var u = SIMD.float32x4.sub(SIMD.float32x4.mul(SIMD.float32x4.swizzle(s, 1, 2, 0, 3), SIMD.float32x4.swizzle(f, 2, 0, 1, 3)),
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(s, 2, 0, 1, 3), SIMD.float32x4.swizzle(f, 1, 2, 0, 3)));
+ // cc.kmVec3Normalize(s, s);
+ tmp = SIMD.float32x4.mul(s, s);
+ tmp = SIMD.float32x4.add(tmp, SIMD.float32x4.add(SIMD.float32x4.swizzle(tmp, 1, 2, 0, 3), SIMD.float32x4.swizzle(tmp, 2, 0, 1, 3)));
+ s = SIMD.float32x4.mul(s, SIMD.float32x4.reciprocalSqrtApproximation(tmp));
+
+ //cc.kmMat4Identity(pOut);
+ //pOut.mat[0] = s.x;
+ //pOut.mat[4] = s.y;
+ //pOut.mat[8] = s.z;
+ //pOut.mat[1] = u.x;
+ //pOut.mat[5] = u.y;
+ //pOut.mat[9] = u.z;
+ //pOut.mat[2] = -f.x;
+ //pOut.mat[6] = -f.y;
+ //pOut.mat[10] = -f.z;
+ var zero = SIMD.float32x4.splat(0.0);
+ f = SIMD.float32x4.neg(f);
+ var tmp01 = SIMD.float32x4.shuffle(s, u, 0, 1, 4, 5);
+ var tmp23 = SIMD.float32x4.shuffle(f, zero, 0, 1, 4, 5);
+ var a0 = SIMD.float32x4.shuffle(tmp01, tmp23, 0, 2, 4, 6);
+ var a1 = SIMD.float32x4.shuffle(tmp01, tmp23, 1, 3, 5, 7);
+
+ var tmp01 = SIMD.float32x4.shuffle(s, u, 2, 3, 6, 7);
+ var tmp23 = SIMD.float32x4.shuffle(f, zero, 2, 3, 6, 7);
+ var a2 = SIMD.float32x4.shuffle(tmp01, tmp23, 0, 2, 4, 6);
+ var a3 = SIMD.float32x4(0.0, 0.0, 0.0, 1.0);
+
+ // cc.kmMat4Translation(translate, -pEye.x, -pEye.y, -pEye.z);
+ var b0 = SIMD.float32x4(1.0, 0.0, 0.0, 0.0);
+ var b1 = SIMD.float32x4(0.0, 1.0, 0.0, 0.0);
+ var b2 = SIMD.float32x4(0.0, 0.0, 1.0, 0.0);
+ var b3 = SIMD.float32x4.neg(eye);
+ b3 = SIMD.float32x4.withW(b3, 1.0);
+
+ // cc.kmMat4Multiply(pOut, pOut, translate);
+ SIMD.float32x4.store(out, 0, SIMD.float32x4.add(
+ SIMD.float32x4.mul(
+ SIMD.float32x4.swizzle(b0, 0, 0, 0, 0), a0),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b0, 1, 1, 1, 1), a1),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b0, 2, 2, 2, 2), a2),
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b0, 3, 3, 3, 3), a3)))));
+ SIMD.float32x4.store(out, 4, SIMD.float32x4.add(
+ SIMD.float32x4.mul(
+ SIMD.float32x4.swizzle(b1, 0, 0, 0, 0), a0),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b1, 1, 1, 1, 1), a1),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b1, 2, 2, 2, 2), a2),
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b1, 3, 3, 3, 3), a3)))));
+ SIMD.float32x4.store(out, 8, SIMD.float32x4.add(
+ SIMD.float32x4.mul(
+ SIMD.float32x4.swizzle(b2, 0, 0, 0, 0), a0),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b2, 1, 1, 1, 1), a1),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b2, 2, 2, 2, 2), a2),
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b2, 3, 3, 3, 3), a3)))));
+ SIMD.float32x4.store(out, 12, SIMD.float32x4.add(
+ SIMD.float32x4.mul(
+ SIMD.float32x4.swizzle(b3, 0, 0, 0, 0), a0),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b3, 1, 1, 1, 1), a1),
+ SIMD.float32x4.add(
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b3, 2, 2, 2, 2), a2),
+ SIMD.float32x4.mul(SIMD.float32x4.swizzle(b3, 3, 3, 3, 3), a3)))));
+ return this;
+ };
+
+
+})(cc);
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/plane.js b/frameworks/cocos2d-html5/cocos2d/kazmath/plane.js
new file mode 100644
index 0000000..db5f9dd
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/plane.js
@@ -0,0 +1,137 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @ignore
+ */
+(function(cc){
+ cc.math.Plane = function (a, b, c, d) {
+ if (a && b === undefined) {
+ this.a = a.a;
+ this.b = a.b;
+ this.c = a.c;
+ this.d = a.d;
+ } else {
+ this.a = a || 0;
+ this.b = b || 0;
+ this.c = c || 0;
+ this.d = d || 0;
+ }
+ };
+ cc.kmPlane = cc.math.Plane;
+ var proto = cc.math.Plane.prototype;
+
+ cc.math.Plane.LEFT = 0;
+
+ cc.math.Plane.RIGHT = 1;
+
+ cc.math.Plane.BOTTOM = 2;
+
+ cc.math.Plane.TOP = 3;
+
+ cc.math.Plane.NEAR = 4;
+
+ cc.math.Plane.FAR = 5;
+
+ cc.math.Plane.POINT_INFRONT_OF_PLANE = 0;
+
+ cc.math.Plane.POINT_BEHIND_PLANE = 1;
+
+ cc.math.Plane.POINT_ON_PLANE = 2;
+
+ proto.dot = function(vec4){ //cc.kmPlaneDot
+ return (this.a * vec4.x + this.b * vec4.y + this.c * vec4.z + this.d * vec4.w);
+ };
+
+ proto.dotCoord = function(vec3) { //=cc.kmPlaneDotCoord
+ return (this.a * vec3.x + this.b * vec3.y + this.c * vec3.z + this.d);
+ };
+
+ proto.dotNormal = function(vec3) { //=cc.kmPlaneDotNormal
+ return (this.a * vec3.x + this.b * vec3.y + this.c * vec3.z);
+ };
+
+ cc.math.Plane.fromPointNormal = function(vec3, normal) { //cc.kmPlaneFromPointNormal
+ /*
+ Planea = Nx
+ Planeb = Ny
+ Planec = Nz
+ Planned = −N⋅P
+ */
+ return new cc.math.Plane(normal.x, normal.y, normal.z, -normal.dot(vec3));
+ };
+
+ cc.math.Plane.fromPoints = function(vec1, vec2, vec3) { //cc.kmPlaneFromPoints
+ /*
+ v = (B − A) × (C − A)
+ n = 1⁄|v| v
+ Outa = nx
+ Outb = ny
+ Outc = nz
+ Outd = −n⋅A
+ */
+ var v1 = new cc.math.Vec3(vec2), v2 = new cc.math.Vec3(vec3), plane = new cc.math.Plane();
+ v1.subtract(vec1); //Create the vectors for the 2 sides of the triangle
+ v2.subtract(vec1);
+ v1.cross(v2); // Use the cross product to get the normal
+ v1.normalize(); //Normalize it and assign to pOut.m_N
+
+ plane.a = v1.x;
+ plane.b = v1.y;
+ plane.c = v1.z;
+ plane.d = v1.scale(-1.0).dot(vec1);
+ return plane;
+ };
+
+ proto.normalize = function(){ //cc.kmPlaneNormalize
+ var n = new cc.math.Vec3(this.a, this.b, this.c), l = 1.0 / n.length(); //Get 1/length
+ n.normalize(); //Normalize the vector and assign to pOut
+ this.a = n.x;
+ this.b = n.y;
+ this.c = n.z;
+ this.d = this.d * l; //Scale the D value and assign to pOut
+ return this;
+ };
+
+ proto.classifyPoint = function(vec3) {
+ // This function will determine if a point is on, in front of, or behind
+ // the plane. First we store the dot product of the plane and the point.
+ var distance = this.a * vec3.x + this.b * vec3.y + this.c * vec3.z + this.d;
+
+ // Simply put if the dot product is greater than 0 then it is infront of it.
+ // If it is less than 0 then it is behind it. And if it is 0 then it is on it.
+ if(distance > 0.001)
+ return cc.math.Plane.POINT_INFRONT_OF_PLANE;
+ if(distance < -0.001)
+ return cc.math.Plane.POINT_BEHIND_PLANE;
+ return cc.math.Plane.POINT_ON_PLANE;
+ };
+})(cc);
+
+
+
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/quaternion.js b/frameworks/cocos2d-html5/cocos2d/kazmath/quaternion.js
new file mode 100644
index 0000000..fcbd652
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/quaternion.js
@@ -0,0 +1,459 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+(function(cc) {
+ /**
+ * The Quaternion class
+ * @param {Number|cc.math.Quaternion} [x=0]
+ * @param {Number} [y=0]
+ * @param {Number} [z=0]
+ * @param {Number} [w=0]
+ * @constructor
+ */
+ cc.math.Quaternion = function (x, y, z, w) {
+ if (x && y === undefined) {
+ this.x = x.x;
+ this.y = x.y;
+ this.z = x.z;
+ this.w = x.w;
+ } else {
+ this.x = x || 0;
+ this.y = y || 0;
+ this.z = z || 0;
+ this.w = w || 0;
+ }
+ };
+ cc.kmQuaternion = cc.math.Quaternion;
+ var proto = cc.math.Quaternion.prototype;
+
+ /**
+ * Sets the conjugate of quaternion to self
+ * @param {cc.math.Quaternion} quaternion
+ */
+ proto.conjugate = function (quaternion) { //= cc.kmQuaternionConjugate
+ this.x = -quaternion.x;
+ this.y = -quaternion.y;
+ this.z = -quaternion.z;
+ this.w = quaternion.w;
+ return this;
+ };
+
+ /**
+ * Returns the dot product of the current quaternion and parameter quaternion
+ * @param quaternion
+ * @returns {number}
+ */
+ proto.dot = function(quaternion) { // = cc.kmQuaternionDot
+ // A dot B = B dot A = AtBt + AxBx + AyBy + AzBz
+ return (this.w * quaternion.w + this.x * quaternion.x + this.y * quaternion.y + this.z * quaternion.z);
+ };
+
+ /**
+ * Returns the exponential of the quaternion, this function doesn't implemented.
+ * @returns {cc.math.Quaternion}
+ */
+ proto.exponential = function(){ //=cc.kmQuaternionExp
+ return this;
+ };
+
+ /**
+ * Makes the current quaternion an identity quaternion
+ */
+ proto.identity = function(){ //=cc.kmQuaternionIdentity
+ this.x = 0.0;
+ this.y = 0.0;
+ this.z = 0.0;
+ this.w = 1.0;
+ return this;
+ };
+
+ /**
+ * Inverses the value of current Quaternion
+ */
+ proto.inverse = function(){ //=cc.kmQuaternionInverse
+ var len = this.length();
+ if (Math.abs(len) > cc.math.EPSILON) {
+ this.x = 0.0;
+ this.y = 0.0;
+ this.z = 0.0;
+ this.w = 0.0;
+ return this;
+ }
+
+ ///Get the conjugute and divide by the length
+ this.conjugate(this).scale(1.0 / len);
+ return this;
+ };
+
+ /**
+ * Returns true if the quaternion is an identity quaternion
+ * @returns {boolean}
+ */
+ proto.isIdentity = function(){ //=cc.kmQuaternionIsIdentity
+ return (this.x === 0.0 && this.y === 0.0 && this.z === 0.0 && this.w === 1.0);
+ };
+
+ /**
+ * Returns the length of the quaternion
+ * @returns {number}
+ */
+ proto.length = function() { //=cc.kmQuaternionLength
+ return Math.sqrt(this.lengthSq());
+ };
+
+ /**
+ * Returns the length of the quaternion squared (prevents a sqrt)
+ * @returns {number}
+ */
+ proto.lengthSq = function() { //=cc.kmQuaternionLengthSq
+ return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
+ };
+
+ /**
+ * Uses current quaternion multiplies other quaternion.
+ * @param {cc.math.Quaternion} quaternion
+ * @returns {cc.math.Quaternion}
+ */
+ proto.multiply = function(quaternion) { //cc.kmQuaternionMultiply
+ var x = this.x, y = this.y, z = this.z, w = this.w;
+ this.w = w * quaternion.w - x * quaternion.x - y * quaternion.y - z * quaternion.z;
+ this.x = w * quaternion.x + x * quaternion.w + y * quaternion.z - z * quaternion.y;
+ this.y = w * quaternion.y + y * quaternion.w + z * quaternion.x - x * quaternion.z;
+ this.z = w * quaternion.z + z * quaternion.w + x * quaternion.y - y * quaternion.x;
+ return this;
+ };
+
+ /**
+ * Normalizes a quaternion
+ * @returns {cc.math.Quaternion}
+ */
+ proto.normalize = function(){ //=cc.kmQuaternionNormalize
+ var length = this.length();
+ if (Math.abs(length) <= cc.math.EPSILON)
+ throw new Error("current quaternion is an invalid value");
+ this.scale(1.0 / length);
+ return this;
+ };
+
+ /**
+ * Rotates a quaternion around an axis and an angle
+ * @param {cc.math.Vec3} axis
+ * @param {Number} angle
+ */
+ proto.rotationAxis = function(axis, angle){ //cc.kmQuaternionRotationAxis
+ var rad = angle * 0.5, scale = Math.sin(rad);
+ this.w = Math.cos(rad);
+ this.x = axis.x * scale;
+ this.y = axis.y * scale;
+ this.z = axis.z * scale;
+ return this;
+ };
+
+ /**
+ * Creates a quaternion from a rotation matrix
+ * @param mat3
+ * @returns {*}
+ */
+ cc.math.Quaternion.rotationMatrix = function (mat3) { //cc.kmQuaternionRotationMatrix
+ if (!mat3)
+ return null;
+
+ var x, y, z, w;
+ var m4x4 = [], mat = mat3.mat, scale = 0.0;
+
+ /* 0 3 6
+ 1 4 7
+ 2 5 8
+
+ 0 1 2 3
+ 4 5 6 7
+ 8 9 10 11
+ 12 13 14 15*/
+ m4x4[0] = mat[0];
+ m4x4[1] = mat[3];
+ m4x4[2] = mat[6];
+ m4x4[4] = mat[1];
+ m4x4[5] = mat[4];
+ m4x4[6] = mat[7];
+ m4x4[8] = mat[2];
+ m4x4[9] = mat[5];
+ m4x4[10] = mat[8];
+ m4x4[15] = 1;
+ var pMatrix = m4x4[0];
+
+ var diagonal = pMatrix[0] + pMatrix[5] + pMatrix[10] + 1;
+ if (diagonal > cc.math.EPSILON) {
+ // Calculate the scale of the diagonal
+ scale = Math.sqrt(diagonal) * 2;
+
+ // Calculate the x, y, x and w of the quaternion through the respective equation
+ x = ( pMatrix[9] - pMatrix[6] ) / scale;
+ y = ( pMatrix[2] - pMatrix[8] ) / scale;
+ z = ( pMatrix[4] - pMatrix[1] ) / scale;
+ w = 0.25 * scale;
+ } else {
+ // If the first element of the diagonal is the greatest value
+ if (pMatrix[0] > pMatrix[5] && pMatrix[0] > pMatrix[10]) {
+ // Find the scale according to the first element, and double that value
+ scale = Math.sqrt(1.0 + pMatrix[0] - pMatrix[5] - pMatrix[10]) * 2.0;
+
+ // Calculate the x, y, x and w of the quaternion through the respective equation
+ x = 0.25 * scale;
+ y = (pMatrix[4] + pMatrix[1] ) / scale;
+ z = (pMatrix[2] + pMatrix[8] ) / scale;
+ w = (pMatrix[9] - pMatrix[6] ) / scale;
+ }
+ // Else if the second element of the diagonal is the greatest value
+ else if (pMatrix[5] > pMatrix[10]) {
+ // Find the scale according to the second element, and double that value
+ scale = Math.sqrt(1.0 + pMatrix[5] - pMatrix[0] - pMatrix[10]) * 2.0;
+
+ // Calculate the x, y, x and w of the quaternion through the respective equation
+ x = (pMatrix[4] + pMatrix[1] ) / scale;
+ y = 0.25 * scale;
+ z = (pMatrix[9] + pMatrix[6] ) / scale;
+ w = (pMatrix[2] - pMatrix[8] ) / scale;
+ } else {
+ // Else the third element of the diagonal is the greatest value
+
+ // Find the scale according to the third element, and double that value
+ scale = Math.sqrt(1.0 + pMatrix[10] - pMatrix[0] - pMatrix[5]) * 2.0;
+
+ // Calculate the x, y, x and w of the quaternion through the respective equation
+ x = (pMatrix[2] + pMatrix[8] ) / scale;
+ y = (pMatrix[9] + pMatrix[6] ) / scale;
+ z = 0.25 * scale;
+ w = (pMatrix[4] - pMatrix[1] ) / scale;
+ }
+ }
+ return new cc.math.Quaternion(x, y, z, w);
+ };
+
+ /**
+ * Create a quaternion from yaw, pitch and roll
+ * @param yaw
+ * @param pitch
+ * @param roll
+ * @returns {cc.math.Quaternion}
+ */
+ cc.math.Quaternion.rotationYawPitchRoll = function (yaw, pitch, roll) { //cc.kmQuaternionRotationYawPitchRoll
+ var ex, ey, ez; // temp half euler angles
+ var cr, cp, cy, sr, sp, sy, cpcy, spsy; // temp vars in roll,pitch yaw
+
+ ex = cc.degreesToRadians(pitch) / 2.0; // convert to rads and half them
+ ey = cc.degreesToRadians(yaw) / 2.0;
+ ez = cc.degreesToRadians(roll) / 2.0;
+
+ cr = Math.cos(ex);
+ cp = Math.cos(ey);
+ cy = Math.cos(ez);
+
+ sr = Math.sin(ex);
+ sp = Math.sin(ey);
+ sy = Math.sin(ez);
+
+ cpcy = cp * cy;
+ spsy = sp * sy;
+
+ var ret = new cc.math.Quaternion();
+ ret.w = cr * cpcy + sr * spsy;
+ ret.x = sr * cpcy - cr * spsy;
+ ret.y = cr * sp * cy + sr * cp * sy;
+ ret.z = cr * cp * sy - sr * sp * cy;
+ ret.normalize();
+ return ret;
+ };
+
+ /**
+ * Interpolate with other quaternions
+ * @param {cc.math.Quaternion} quaternion
+ * @param {Number} t
+ * @returns {cc.math.Quaternion}
+ */
+ proto.slerp = function(quaternion, t) { //=cc.kmQuaternionSlerp
+ if (this.x === quaternion.x && this.y === quaternion.y && this.z === quaternion.z && this.w === quaternion.w) {
+ return this;
+ }
+ var ct = this.dot(quaternion), theta = Math.acos(ct), st = Math.sqrt(1.0 - cc.math.square(ct));
+ var stt = Math.sin(t * theta) / st, somt = Math.sin((1.0 - t) * theta) / st;
+ var temp2 = new cc.math.Quaternion(quaternion);
+ this.scale(somt);
+ temp2.scale(stt);
+ this.add(temp2);
+ return this;
+ };
+
+ /**
+ * Get the axis and angle of rotation from a quaternion
+ * @returns {{axis: cc.math.Vec3, angle: number}}
+ */
+ proto.toAxisAndAngle = function(){ //=cc.kmQuaternionToAxisAngle
+ var tempAngle; // temp angle
+ var scale; // temp vars
+ var retAngle, retAxis = new cc.math.Vec3();
+
+ tempAngle = Math.acos(this.w);
+ scale = Math.sqrt(cc.math.square(this.x) + cc.math.square(this.y) + cc.math.square(this.z));
+
+ if (((scale > -cc.math.EPSILON) && scale < cc.math.EPSILON)
+ || (scale < 2 * Math.PI + cc.math.EPSILON && scale > 2 * Math.PI - cc.math.EPSILON)) { // angle is 0 or 360 so just simply set axis to 0,0,1 with angle 0
+ retAngle = 0.0;
+ retAxis.x = 0.0;
+ retAxis.y = 0.0;
+ retAxis.z = 1.0;
+ } else {
+ retAngle = tempAngle * 2.0; // angle in radians
+ retAxis.x = this.x / scale;
+ retAxis.y = this.y / scale;
+ retAxis.z = this.z / scale;
+ retAxis.normalize();
+ }
+ return {axis: retAxis, angle: retAngle};
+ };
+
+ /**
+ * Scale a quaternion
+ * @param {Number} scale
+ */
+ proto.scale = function(scale) { //cc.kmQuaternionScale
+ this.x *= scale;
+ this.y *= scale;
+ this.z *= scale;
+ this.w *= scale;
+ return this;
+ };
+
+ /**
+ * Assign current quaternion value from a quaternion.
+ * @param {cc.math.Quaternion} quaternion
+ * @returns {cc.math.Quaternion} current quaternion
+ */
+ proto.assignFrom = function(quaternion){ //=cc.kmQuaternionAssign
+ this.x = quaternion.x;
+ this.y = quaternion.y;
+ this.z = quaternion.z;
+ this.w = quaternion.w;
+ return this;
+ };
+
+ /**
+ * Adds other quaternion
+ * @param {cc.math.Quaternion} quaternion
+ * @returns {cc.math.Quaternion}
+ */
+ proto.add = function(quaternion) { //cc.kmQuaternionAdd
+ this.x += quaternion.x;
+ this.y += quaternion.y;
+ this.z += quaternion.z;
+ this.w += quaternion.w;
+ return this;
+ };
+
+ /**
+ *
+ * Adapted from the OGRE engine!
+ * Gets the shortest arc quaternion to rotate this vector to the destination vector.
+ * @remarks
+ * If you call this with a destination vector that is close to the inverse
+ * of this vector, we will rotate 180 degrees around the 'fallbackAxis'
+ * (if specified, or a generated axis if not) since in this case ANY axis of rotation is valid.
+ *
+ * @param {cc.math.Vec3} vec1
+ * @param {cc.math.Vec3} vec2
+ * @param {cc.math.Vec3} fallback
+ * @returns {cc.math.Quaternion}
+ */
+ cc.math.Quaternion.rotationBetweenVec3 = function(vec1, vec2, fallback) { //cc.kmQuaternionRotationBetweenVec3
+ var v1 = new cc.math.Vec3(vec1), v2 = new cc.math.Vec3(vec2);
+ v1.normalize();
+ v2.normalize();
+ var a = v1.dot(v2), quaternion = new cc.math.Quaternion();
+
+ if (a >= 1.0) {
+ quaternion.identity();
+ return quaternion;
+ }
+
+ if (a < (1e-6 - 1.0)) {
+ if (Math.abs(fallback.lengthSq()) < cc.math.EPSILON) {
+ quaternion.rotationAxis(fallback, Math.PI);
+ } else {
+ var axis = new cc.math.Vec3(1.0, 0.0, 0.0);
+ axis.cross(vec1);
+
+ //If axis is zero
+ if (Math.abs(axis.lengthSq()) < cc.math.EPSILON) {
+ axis.fill(0.0, 1.0, 0.0);
+ axis.cross(vec1);
+ }
+ axis.normalize();
+ quaternion.rotationAxis(axis, Math.PI);
+ }
+ } else {
+ var s = Math.sqrt((1 + a) * 2), invs = 1 / s;
+ v1.cross(v2);
+ quaternion.x = v1.x * invs;
+ quaternion.y = v1.y * invs;
+ quaternion.z = v1.z * invs;
+ quaternion.w = s * 0.5;
+ quaternion.normalize();
+ }
+ return quaternion;
+ };
+
+ /**
+ * Current quaternion multiplies a vec3
+ * @param {cc.math.Vec3} vec
+ * @returns {cc.math.Vec3}
+ */
+ proto.multiplyVec3 = function(vec){ //=cc.kmQuaternionMultiplyVec3
+ var x = this.x, y = this.y, z = this.z, retVec = new cc.math.Vec3(vec);
+ var uv = new cc.math.Vec3(x, y, z), uuv = new cc.math.Vec3(x, y, z);
+ uv.cross(vec);
+ uuv.cross(uv);
+ uv.scale((2.0 * q.w));
+ uuv.scale(2.0);
+
+ retVec.add(uv);
+ retVec.add(uuv);
+ return retVec;
+ };
+})(cc);
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/ray2.js b/frameworks/cocos2d-html5/cocos2d/kazmath/ray2.js
new file mode 100644
index 0000000..5a29794
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/ray2.js
@@ -0,0 +1,140 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+(function(cc){
+ cc.math.Ray2 = function (start, dir) { // = cc.kmRay2
+ this.start = start || new cc.math.Vec2();
+ this.dir = dir || new cc.math.Vec2();
+ };
+
+ cc.math.Ray2.prototype.fill = function (px, py, vx, vy) { // = cc.kmRay2Fill
+ this.start.x = px;
+ this.start.y = py;
+ this.dir.x = vx;
+ this.dir.y = vy;
+ };
+
+ cc.math.Ray2.prototype.intersectLineSegment = function (p1, p2, intersection) { // = cc.kmRay2IntersectLineSegment
+ var x1 = this.start.x, y1 = this.start.y;
+ var x2 = this.start.x + this.dir.x, y2 = this.start.y + this.dir.y;
+ var x3 = p1.x, y3 = p1.y;
+ var x4 = p2.x, y4 = p2.y;
+
+ var denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
+ var ua, x, y;
+ //If denom is zero, the lines are parallel
+ if (denom > -cc.math.EPSILON && denom < cc.math.EPSILON)
+ return false;
+
+ ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom;
+ //var ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom;
+
+ x = x1 + ua * (x2 - x1);
+ y = y1 + ua * (y2 - y1);
+
+ if (x < Math.min(p1.x, p2.x) - cc.math.EPSILON ||
+ x > Math.max(p1.x, p2.x) + cc.math.EPSILON ||
+ y < Math.min(p1.y, p2.y) - cc.math.EPSILON ||
+ y > Math.max(p1.y, p2.y) + cc.math.EPSILON) {
+ //Outside of line
+ //printf("Outside of line, %f %f (%f %f)(%f, %f)\n", x, y, p1.x, p1.y, p2.x, p2.y);
+ return false;
+ }
+
+ if (x < Math.min(x1, x2) - cc.math.EPSILON ||
+ x > Math.max(x1, x2) + cc.math.EPSILON ||
+ y < Math.min(y1, y2) - cc.math.EPSILON ||
+ y > Math.max(y1, y2) + cc.math.EPSILON) {
+ //printf("Outside of ray, %f %f (%f %f)(%f, %f)\n", x, y, x1, y1, x2, y2);
+ return false;
+ }
+
+ intersection.x = x;
+ intersection.y = y;
+ return true;
+ };
+
+ function calculate_line_normal(p1, p2, normalOut){
+ var tmp = new cc.math.Vec2(p2);
+ tmp.subtract(p1);
+
+ normalOut.x = -tmp.y;
+ normalOut.y = tmp.x;
+ normalOut.normalize();
+ //TODO: should check that the normal is pointing out of the triangle
+ }
+
+ cc.math.Ray2.prototype.intersectTriangle = function(p1, p2, p3, intersection, normal_out){
+ var intersect = new cc.math.Vec2(), final_intersect = new cc.math.Vec2();
+ var normal = new cc.math.Vec2(), distance = 10000.0, intersected = false;
+ var this_distance;
+
+ if(this.intersectLineSegment(p1, p2, intersect)) {
+ intersected = true;
+ this_distance = intersect.subtract(this.start).length();
+ if(this_distance < distance) {
+ final_intersect.x = intersect.x;
+ final_intersect.y = intersect.y;
+ distance = this_distance;
+ calculate_line_normal(p1, p2, normal);
+ }
+ }
+
+ if(this.intersectLineSegment(p2, p3, intersect)) {
+ intersected = true;
+ this_distance = intersect.subtract(this.start).length();
+ if(this_distance < distance) {
+ final_intersect.x = intersect.x;
+ final_intersect.y = intersect.y;
+ distance = this_distance;
+ calculate_line_normal(p2, p3, normal);
+ }
+ }
+
+ if(this.intersectLineSegment(p3, p1, intersect)) {
+ intersected = true;
+ this_distance = intersect.subtract(this.start).length();
+ if(this_distance < distance) {
+ final_intersect.x = intersect.x;
+ final_intersect.y = intersect.y;
+ distance = this_distance;
+ calculate_line_normal(p3, p1, normal);
+ }
+ }
+
+ if(intersected) {
+ intersection.x = final_intersect.x;
+ intersection.y = final_intersect.y;
+ if(normal_out) {
+ normal_out.x = normal.x;
+ normal_out.y = normal.y;
+ }
+ }
+ return intersected;
+ };
+})(cc);
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/base.js b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/base.js
new file mode 100644
index 0000000..d01857c
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/base.js
@@ -0,0 +1,139 @@
+// SIMD Kernel Benchmark Harness
+// Author: Peter Jensen
+
+function Benchmark (config) {
+ this.config = config;
+ this.initOk = true; // Initialize all properties used on a Benchmark object
+ this.cleanupOk = true;
+ this.useAutoIterations = true;
+ this.autoIterations = 0;
+ this.actualIterations = 0;
+ this.simdTime = 0;
+ this.nonSimdTime = 0;
+}
+
+function Benchmarks () {
+ this.benchmarks = [];
+}
+
+Benchmarks.prototype.add = function (benchmark) {
+ this.benchmarks.push (benchmark);
+ return this.benchmarks.length - 1;
+}
+
+Benchmarks.prototype.runOne = function (benchmark) {
+
+ function timeKernel(kernel, iterations) {
+ var start, stop;
+ start = Date.now();
+ kernel(iterations);
+ stop = Date.now();
+ return stop - start;
+ }
+
+ function computeIterations() {
+ var desiredRuntime = 1000; // milliseconds for longest running kernel
+ var testIterations = 10; // iterations used to determine time for desiredRuntime
+
+ // Make the slowest kernel run for at least 500ms
+ var simdTime = timeKernel(benchmark.config.kernelSimd, testIterations);
+ var nonSimdTime = timeKernel(benchmark.config.kernelNonSimd, testIterations);
+ var maxTime = simdTime > nonSimdTime ? simdTime : nonSimdTime;
+ while (maxTime < 500) {
+ testIterations *= 2;
+ simdTime = timeKernel(benchmark.config.kernelSimd, testIterations);
+ nonSimdTime = timeKernel(benchmark.config.kernelNonSimd, testIterations);
+ maxTime = simdTime > nonSimdTime ? simdTime : nonSimdTime;
+ }
+ maxTime = simdTime > nonSimdTime ? simdTime : nonSimdTime;
+
+ // Compute iteration count for 1 second run of slowest kernel
+ var iterations = Math.ceil(desiredRuntime * testIterations / maxTime);
+ return iterations;
+ }
+
+ // Initialize the kernels and check the correctness status
+ if (!benchmark.config.kernelInit()) {
+ benchmark.initOk = false;
+ return false;
+ }
+
+ // Determine how many iterations to use.
+ if (benchmark.useAutoIterations) {
+ benchmark.autoIterations = computeIterations();
+ benchmark.actualIterations = benchmark.autoIterations;
+ }
+ else {
+ benchmark.actualIterations = benchmark.config.kernelIterations;
+ }
+
+ // Run the SIMD kernel
+ benchmark.simdTime = timeKernel(benchmark.config.kernelSimd, benchmark.actualIterations);
+
+ // Run the non-SIMD kernel
+ benchmark.nonSimdTime = timeKernel(benchmark.config.kernelNonSimd, benchmark.actualIterations);
+
+ // Do the final sanity check
+ if (!benchmark.config.kernelCleanup()) {
+ benchmark.cleanupOk = false;
+ return false;
+ }
+
+ return true;
+}
+
+Benchmarks.prototype.report = function (benchmark, outputFunctions) {
+
+ function fillRight(str, width) {
+ str += ""; // make sure it's a string
+ while (str.length < width) {
+ str += " ";
+ }
+ return str;
+ }
+
+ function fillLeft(str, width) {
+ str += ""; // make sure it's a string
+ while (str.length < width) {
+ str = " " + str;
+ }
+ return str;
+ }
+
+ if (!benchmark.initOk) {
+ outputFunctions.notifyError(fillRight(benchmark.config.kernelName + ": ", 23) + "FAILED INIT");
+ return;
+ }
+ if (!benchmark.cleanupOk) {
+ outputFunctions.notifyError(fillRight(benchmark.config.kernelName + ": ", 23) + "FAILED CLEANUP");
+ return;
+ }
+
+ var ratio = benchmark.nonSimdTime / benchmark.simdTime;
+ ratio = ratio.toFixed(2);
+ outputFunctions.notifyResult(
+ fillRight(benchmark.config.kernelName + ": ", 23) +
+ "Iterations(" + fillLeft(benchmark.actualIterations, 10) + ")" +
+ ", SIMD(" + fillLeft(benchmark.simdTime + "ms)", 8) +
+ ", Non-SIMD(" + fillLeft(benchmark.nonSimdTime + "ms)", 8) +
+ ", Speedup(" + ratio + ")");
+ outputFunctions.timeData.labels.push(benchmark.config.kernelName);
+ outputFunctions.timeData.datasets[0].data.push(benchmark.simdTime);
+ outputFunctions.timeData.datasets[1].data.push(benchmark.nonSimdTime);
+ outputFunctions.speedupData.labels.push(benchmark.config.kernelName);
+ outputFunctions.speedupData.datasets[0].data.push(ratio);
+}
+
+Benchmarks.prototype.runAll = function (outputFunctions, useAutoIterations) {
+ if (typeof useAutoIterations === "undefined") {
+ useAutoIterations = false;
+ }
+ for (var i = 0, n = this.benchmarks.length; i < n; ++i) {
+ var benchmark = this.benchmarks[i];
+ benchmark.useAutoIterations = useAutoIterations;
+ this.runOne(benchmark);
+ this.report(benchmark, outputFunctions);
+ }
+}
+
+var benchmarks = new Benchmarks ();
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/index.html b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/index.html
new file mode 100644
index 0000000..8c9cb4f
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+ Kazmath SIMD benchmarks
+
+
+
+ Running benchmarks...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kernel-template.js b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kernel-template.js
new file mode 100644
index 0000000..d7c3775
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kernel-template.js
@@ -0,0 +1,64 @@
+// Kernel template
+// Author: Peter Jensen
+(function () {
+
+ // Kernel configuration
+ var kernelConfig = {
+ kernelName: "Test",
+ kernelInit: init,
+ kernelCleanup: cleanup,
+ kernelSimd: simd,
+ kernelNonSimd: nonSimd,
+ kernelIterations: 100000000
+ };
+
+ // Hook up to the harness
+ benchmarks.add (new Benchmark (kernelConfig));
+
+ // Kernel Initializer
+ function init () {
+ // Do initial sanity check and initialize data for the kernels.
+ // The sanity check should verify that the simd and nonSimd results
+ // are the same.
+ // It is recommended to do minimal object creation in the kernels
+ // themselves. If global data needs to be initialized, here would
+ // be the place to do it.
+ // If the sanity checks fails the kernels will not be executed
+ // Returns:
+ // true: First run (unoptimized) of the kernels passed
+ // false: First run (unoptimized) of the kernels failed
+ return simd (1) === nonSimd (1);
+ }
+
+ // Kernel Cleanup
+ function cleanup () {
+ // Do final sanity check and perform cleanup.
+ // This function is called when all the kernel iterations have been
+ // executed, so they should be in their final optimized version. The
+ // sanity check done during initialization will probably be of the
+ // initial unoptimized version.
+ // Returns:
+ // true: Last run (optimized) of the kernels passed
+ // false: last run (optimized) of the kernels failed
+ return simd (1) === nonSimd (1);
+ }
+
+ // SIMD version of the kernel
+ function simd (n) {
+ var s = 0;
+ for (var i = 0; i < n; ++i) {
+ s += i;
+ }
+ return s;
+ }
+
+ // Non SIMD version of the kernel
+ function nonSimd (n) {
+ var s = 0;
+ for (var i = 0; i < n; ++i) {
+ s += i;
+ }
+ return s;
+ }
+
+} ());
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4AreEqual.js b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4AreEqual.js
new file mode 100644
index 0000000..a3dee72
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4AreEqual.js
@@ -0,0 +1,77 @@
+// kmMat4AreEqual
+
+(function () {
+
+ // Kernel configuration
+ var kernelConfig = {
+ kernelName: "kmMat4AreEqual",
+ kernelInit: init,
+ kernelCleanup: cleanup,
+ kernelSimd: simd,
+ kernelNonSimd: nonSimd,
+ kernelIterations: 10000
+ };
+
+ // Hook up to the harness
+ benchmarks.add(new Benchmark(kernelConfig));
+
+ // Benchmark data, initialization and kernel functions
+ var T1 = new cc.kmMat4();
+ var T2 = new cc.kmMat4();
+ var T1x4 = new cc.kmMat4();
+ var T2x4 = new cc.kmMat4();
+ var areEqual, areEqualSIMD;
+
+ function equals(A, B) {
+ for (var i = 0; i < 16; ++i) {
+ if (A[i] != B[i])
+ return false;
+ }
+ return true;
+ }
+
+ function init() {
+ T1.mat[0] = 1.0;
+ T1.mat[5] = 1.0;
+ T1.mat[10] = 1.0;
+ T1.mat[15] = 1.0;
+
+ T2.mat[0] = 1.0;
+ T2.mat[5] = 1.0;
+ T2.mat[10] = 1.0;
+ T2.mat[15] = 1.0;
+
+ T1x4.mat[0] = 1.0;
+ T1x4.mat[5] = 1.0;
+ T1x4.mat[10] = 1.0;
+ T1x4.mat[15] = 1.0;
+
+ T2x4.mat[0] = 1.0;
+ T2x4.mat[5] = 1.0;
+ T2x4.mat[10] = 1.0;
+ T2x4.mat[15] = 1.0;
+
+ nonSimd(1);
+ simd(1);
+
+ return equals(T1.mat, T1x4.mat) && equals(T2.mat, T2x4.mat) && (areEqual === areEqualSIMD);
+
+ }
+
+ function cleanup() {
+ return init(); // Sanity checking before and after are the same
+ }
+
+ function nonSimd(n) {
+ for (var i = 0; i < n; i++) {
+ areEqual = T1.equals(T2);
+ }
+ }
+
+ function simd(n) {
+ for (var i = 0; i < n; i++) {
+ areEqualSIMD = T1x4.equalsSIMD(T2x4);
+ }
+ }
+
+} ());
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4Assign.js b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4Assign.js
new file mode 100644
index 0000000..e8e386f
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4Assign.js
@@ -0,0 +1,68 @@
+// kmMat4Assign
+
+(function () {
+
+ // Kernel configuration
+ var kernelConfig = {
+ kernelName: "kmMat4Assign",
+ kernelInit: init,
+ kernelCleanup: cleanup,
+ kernelSimd: simd,
+ kernelNonSimd: nonSimd,
+ kernelIterations: 10000
+ };
+
+ // Hook up to the harness
+ benchmarks.add(new Benchmark(kernelConfig));
+
+ // Benchmark data, initialization and kernel functions
+ var T1 = new cc.kmMat4();
+ var T2 = new cc.kmMat4();
+ var T1x4 = new cc.kmMat4();
+ var T2x4 = new cc.kmMat4();
+
+ function equals(A, B) {
+ for (var i = 0; i < 16; ++i) {
+ if (A[i] != B[i])
+ return false;
+ }
+ return true;
+ }
+
+ function init() {
+ T1.mat[0] = 1.0;
+ T1.mat[5] = 1.0;
+ T1.mat[10] = 1.0;
+ T1.mat[15] = 1.0;
+
+ T1x4.mat[0] = 1.0;
+ T1x4.mat[5] = 1.0;
+ T1x4.mat[10] = 1.0;
+ T1x4.mat[15] = 1.0;
+
+ nonSimd(1);
+ simd(1);
+
+ return equals(T1.mat, T1x4.mat) && equals(T2.mat, T2x4.mat);
+
+ }
+
+ function cleanup() {
+ return init(); // Sanity checking before and after are the same
+ }
+
+ function nonSimd(n) {
+ for (var i = 0; i < n; i++) {
+ //cc.kmMat4Assign(T2, T1);
+ T2.assignFrom(T1);
+ }
+ }
+
+ function simd(n) {
+ for (var i = 0; i < n; i++) {
+ //cc.kmMat4AssignSIMD(T2x4, T1x4);
+ T2x4.assignFromSIMD(T1x4);
+ }
+ }
+
+} ());
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4Inverse.js b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4Inverse.js
new file mode 100644
index 0000000..212dff1
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4Inverse.js
@@ -0,0 +1,116 @@
+// kmMat4Inverse
+
+(function () {
+
+ // Kernel configuration
+ var kernelConfig = {
+ kernelName: "kmMat4Inverse",
+ kernelInit: init,
+ kernelCleanup: cleanup,
+ kernelSimd: simd,
+ kernelNonSimd: nonSimd,
+ kernelIterations: 10000
+ };
+
+ // Hook up to the harness
+ benchmarks.add(new Benchmark(kernelConfig));
+
+ // Benchmark data, initialization and kernel functions
+ var src = new cc.kmMat4();
+ var dst = new cc.kmMat4();
+ var srcx4 = new cc.kmMat4();
+ var dstx4 = new cc.kmMat4();
+ var ident = new Float32Array(
+ [1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0,
+ 0,0,0,1]);
+
+ function equals(A, B) {
+ for (var i = 0; i < 16; ++i) {
+ if (Math.abs (A[i] - B[i]) > 5)
+ return false;
+ }
+ return true;
+ }
+
+ function initMatrix(matrix) {
+ // These values were chosen somewhat randomly, but they will at least yield a solution.
+ matrix [0] = 0; matrix[1] = 1; matrix[2] = 2; matrix[3] = 3;
+ matrix [4] = -1; matrix[5] = -2; matrix[6] = -3; matrix[7] = -4;
+ matrix [8] = 0; matrix[9] = 0; matrix[10] = 2; matrix[11] = 3;
+ matrix [12] = -1; matrix[13] = -2; matrix[14] = 0; matrix[15] = -4;
+ }
+
+ function mulMatrix(dst, op1, op2) {
+ for (var r = 0; r < 4; ++r) {
+ for (var c = 0; c < 4; ++c) {
+ var ri = 4*r;
+ dst[ri + c] = op1[ri]*op2[c] + op1[ri+1]*op2[c+4] + op1[ri+2]*op2[c+8] + op1[ri+3]*op2[c+12];
+ }
+ }
+ }
+
+ function printMatrix(matrix, str) {
+ print('--------matrix ' + str + '----------');
+ for (var r = 0; r < 4; ++r) {
+ var str = "";
+ var ri = r*4;
+ for (var c = 0; c < 4; ++c) {
+ var value = matrix[ri + c];
+ str += " " + value.toFixed(2);
+ }
+ print(str);
+ }
+ }
+
+ function checkMatrix(src, dst) {
+ // when multiplied with the src matrix it should yield the identity matrix
+ var tmp = new Float32Array(16);
+ mulMatrix(tmp, src, dst);
+ for (var i = 0; i < 16; ++i) {
+ if (Math.abs (tmp[i] - ident[i]) > 0.00001) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function init() {
+ initMatrix(src.mat);
+ // printMatrix(src);
+ nonSimd(1);
+ // printMatrix(dst);
+ if (!checkMatrix(src.mat, dst.mat)) {
+ return false;
+ }
+
+ initMatrix(srcx4.mat);
+ simd(1);
+ // printMatrix(dst);
+ if (!checkMatrix(srcx4.mat, dstx4.mat)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ function cleanup() {
+ return init(); // Sanity checking before and after are the same
+ }
+
+ function nonSimd(n) {
+ for (var i = 0; i < n; i++) {
+ //cc.kmMat4Inverse(dst, src);
+ dst = src.inverse();
+ }
+ }
+
+ function simd(n) {
+ for (var i = 0; i < n; i++) {
+ //cc.kmMat4InverseSIMD(dstx4, srcx4);
+ dstx4 = srcx4.inverseSIMD();
+ }
+ }
+
+} ());
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4IsIdentity.js b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4IsIdentity.js
new file mode 100644
index 0000000..9ab17ac
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4IsIdentity.js
@@ -0,0 +1,65 @@
+// kmMat4IsIdentity
+
+(function () {
+
+ // Kernel configuration
+ var kernelConfig = {
+ kernelName: "kmMat4IsIdentity",
+ kernelInit: init,
+ kernelCleanup: cleanup,
+ kernelSimd: simd,
+ kernelNonSimd: nonSimd,
+ kernelIterations: 10000
+ };
+
+ // Hook up to the harness
+ benchmarks.add(new Benchmark(kernelConfig));
+
+ // Benchmark data, initialization and kernel functions
+ var T1 = new cc.kmMat4();
+ var T1x4 = new cc.kmMat4();
+ var isIdentity, isIdentitySIMD;
+
+ function equals(A, B) {
+ for (var i = 0; i < 16; ++i) {
+ if (A[i] != B[i])
+ return false;
+ }
+ return true;
+ }
+
+ function init() {
+ T1.mat[0] = 1.0;
+ T1.mat[5] = 1.0;
+ T1.mat[10] = 1.0;
+ T1.mat[15] = 1.0;
+
+ T1x4.mat[0] = 1.0;
+ T1x4.mat[5] = 1.0;
+ T1x4.mat[10] = 1.0;
+ T1x4.mat[15] = 1.0;
+
+ nonSimd(1);
+ simd(1);
+
+ return equals(T1.mat, T1x4.mat) && (isIdentity === isIdentitySIMD);
+
+ }
+
+ function cleanup() {
+ return init(); // Sanity checking before and after are the same
+ }
+
+ function nonSimd(n) {
+ for (var i = 0; i < n; i++) {
+ isIdentity = T1.isIdentity();
+ }
+ }
+
+ function simd(n) {
+ for (var i = 0; i < n; i++) {
+ isIdentitySIMD = T1x4.isIdentitySIMD();
+ }
+ }
+
+} ());
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4LookAt.js b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4LookAt.js
new file mode 100644
index 0000000..1015ad1
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4LookAt.js
@@ -0,0 +1,94 @@
+// kmMat4LookAt
+
+(function () {
+
+ // Kernel configuration
+ var kernelConfig = {
+ kernelName: "kmMat4LookAt",
+ kernelInit: init,
+ kernelCleanup: cleanup,
+ kernelSimd: simd,
+ kernelNonSimd: nonSimd,
+ kernelIterations: 10000
+ };
+
+ // Hook up to the harness
+ benchmarks.add(new Benchmark(kernelConfig));
+
+ // Benchmark data, initialization and kernel functions
+ var eye = new cc.kmVec3(), center = new cc.kmVec3(), up = new cc.kmVec3();
+ var T1 = new cc.kmMat4();
+ var eye1 = new cc.kmVec3(), center1 = new cc.kmVec3(), up1 = new cc.kmVec3();
+ var T1x4 = new cc.kmMat4();
+
+ function printMatrix(matrix) {
+ print('--------matrix----------');
+ for (var r = 0; r < 4; ++r) {
+ var str = "";
+ var ri = r*4;
+ for (var c = 0; c < 4; ++c) {
+ var value = matrix[ri + c];
+ str += " " + value.toFixed(2);
+ }
+ print(str);
+ }
+ }
+
+ function equals(A, B) {
+ for (var i = 0; i < 16; ++i) {
+ if (Math.abs (A[i] - B[i]) > 0.001) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function init() {
+
+ eye.fill(0, 1, 2);
+ center.fill(2, 1, 0);
+ up.fill(1, 1, 1);
+
+ eye1.fill(0, 1, 2);
+ center1.fill(2, 1, 0);
+ up1.fill(1, 1, 1);
+ /*
+ eye1.data[0] = 0;
+ eye1.data[1] = 1;
+ eye1.data[2] = 2;
+
+ center1.data[0] = 2;
+ center1.data[1] = 1;
+ center1.data[2] = 0;
+
+ up1.data[0] = 1;
+ up1.data[1] = 1;
+ up1.data[2] = 1;
+ */
+ nonSimd(1);
+ //printMatrix(T1.mat);
+ simd(1);
+ //printMatrix(T1x4.mat);
+
+ return equals(T1.mat, T1x4.mat);
+ }
+
+ function cleanup() {
+ return init(); // Sanity checking before and after are the same
+ }
+
+ function nonSimd(n) {
+ for (var i = 0; i < n; i++) {
+ //cc.kmMat4LookAt(T1, eye, center, up);
+ T1.lookAt(eye, center, up);
+ }
+ }
+
+ function simd(n) {
+ for (var i = 0; i < n; i++) {
+ //cc.kmMat4LookAtSIMD(T1x4, eye1, center1, up1);
+ T1x4.lookAtSIMD(eye1, center1, up1);
+ }
+ }
+
+} ());
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4Multiply.js b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4Multiply.js
new file mode 100644
index 0000000..325b6f9
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4Multiply.js
@@ -0,0 +1,74 @@
+// kmMat4Multiply
+
+(function () {
+
+ // Kernel configuration
+ var kernelConfig = {
+ kernelName: "kmMat4Multiply",
+ kernelInit: init,
+ kernelCleanup: cleanup,
+ kernelSimd: simd,
+ kernelNonSimd: nonSimd,
+ kernelIterations: 10000
+ };
+
+ // Hook up to the harness
+ benchmarks.add(new Benchmark(kernelConfig));
+
+ // Benchmark data, initialization and kernel functions
+ var T1 = new cc.kmMat4();
+ var T2 = new cc.kmMat4();
+ var T1x4 = new cc.kmMat4();
+ var T2x4 = new cc.kmMat4();
+
+ function equals(A, B) {
+ for (var i = 0; i < 16; ++i) {
+ if (A[i] != B[i])
+ return false;
+ }
+ return true;
+ }
+
+ function init() {
+ T1.mat[0] = 1.0;
+ T1.mat[5] = 1.0;
+ T1.mat[10] = 1.0;
+ T1.mat[15] = 1.0;
+
+ T2.mat[0] = 1.0;
+ T2.mat[5] = 1.0;
+ T2.mat[10] = 1.0;
+ T2.mat[15] = 1.0;
+
+ T1x4.mat[0] = 1.0;
+ T1x4.mat[5] = 1.0;
+ T1x4.mat[10] = 1.0;
+ T1x4.mat[15] = 1.0;
+
+ T2x4.mat[0] = 1.0;
+ T2x4.mat[5] = 1.0;
+ T2x4.mat[10] = 1.0;
+ T2x4.mat[15] = 1.0;
+
+ nonSimd(1);
+ simd(1);
+ return equals(T1.mat, T1x4.mat) && equals(T2.mat, T2x4.mat);
+ }
+
+ function cleanup() {
+ return init(); // Sanity checking before and after are the same
+ }
+
+ function nonSimd(n) {
+ for (var i = 0; i < n; i++) {
+ T1.multiply(T2);
+ }
+ }
+
+ function simd(n) {
+ for (var i = 0; i < n; i++) {
+ T1x4.multiplySIMD(T2x4);
+ }
+ }
+
+} ());
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4Transpose.js b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4Transpose.js
new file mode 100644
index 0000000..cd1b776
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmMat4Transpose.js
@@ -0,0 +1,82 @@
+// kmMat4Transpose
+
+(function () {
+
+ // Kernel configuration
+ var kernelConfig = {
+ kernelName: "kmMat4Transpose",
+ kernelInit: init,
+ kernelCleanup: cleanup,
+ kernelSimd: simd,
+ kernelNonSimd: nonSimd,
+ kernelIterations: 10000
+ };
+
+ // Hook up to the harness
+ benchmarks.add(new Benchmark(kernelConfig));
+
+ // Benchmark data, initialization and kernel functions
+ var T1 = new cc.kmMat4();
+ var T2 = new cc.kmMat4();
+ var T1x4 = new cc.kmMat4();
+ var T2x4 = new cc.kmMat4();
+
+ function equals(A, B) {
+ for (var i = 0; i < 16; ++i) {
+ if (A[i] != B[i])
+ return false;
+ }
+ return true;
+ }
+
+ function printMatrix(matrix) {
+ print('--------matrix----------');
+ for (var r = 0; r < 4; ++r) {
+ var str = "";
+ var ri = r*4;
+ for (var c = 0; c < 4; ++c) {
+ var value = matrix[ri + c];
+ str += " " + value.toFixed(2);
+ }
+ print(str);
+ }
+ }
+
+ function init() {
+ T1.mat [0] = 0; T1.mat[1] = 1; T1.mat[2] = 2; T1.mat[3] = 3;
+ T1.mat [4] = -1; T1.mat[5] = -2; T1.mat[6] = -3; T1.mat[7] = -4;
+ T1.mat [8] = 0; T1.mat[9] = 0; T1.mat[10] = 2; T1.mat[11] = 3;
+ T1.mat [12] = -1; T1.mat[13] = -2; T1.mat[14] = 0; T1.mat[15] = -4;
+
+ T1x4.mat [0] = 0; T1x4.mat[1] = 1; T1x4.mat[2] = 2; T1x4.mat[3] = 3;
+ T1x4.mat [4] = -1; T1x4.mat[5] = -2; T1x4.mat[6] = -3; T1x4.mat[7] = -4;
+ T1x4.mat [8] = 0; T1x4.mat[9] = 0; T1x4.mat[10] = 2; T1x4.mat[11] = 3;
+ T1x4.mat [12] = -1; T1x4.mat[13] = -2; T1x4.mat[14] = 0; T1x4.mat[15] = -4;
+
+ nonSimd(1);
+ //printMatrix(T2.mat);
+ simd(1);
+ //printMatrix(T2x4.mat);
+ return equals(T1.mat, T1x4.mat) && equals(T2.mat, T2x4.mat);
+
+ }
+
+ function cleanup() {
+ return init(); // Sanity checking before and after are the same
+ }
+
+ function nonSimd(n) {
+ for (var i = 0; i < n; i++) {
+ T2 = T1.transpose();
+ //T1.transpose();
+ }
+ }
+
+ function simd(n) {
+ for (var i = 0; i < n; i++) {
+ T2x4 = T1x4.transposeSIMD();
+ //T1x4.transposeSIMD();
+ }
+ }
+
+} ());
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmVec3TransformCoord.js b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmVec3TransformCoord.js
new file mode 100644
index 0000000..541a926
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/kmVec3TransformCoord.js
@@ -0,0 +1,65 @@
+// kmVec3TransformCoord
+
+(function () {
+
+ // Kernel configuration
+ var kernelConfig = {
+ kernelName: "kmVec3TransformCoord",
+ kernelInit: init,
+ kernelCleanup: cleanup,
+ kernelSimd: simd,
+ kernelNonSimd: nonSimd,
+ kernelIterations: 10000
+ };
+
+ // Hook up to the harness
+ benchmarks.add(new Benchmark(kernelConfig));
+
+ // Benchmark data, initialization and kernel functions
+ var V = new cc.kmVec3();
+ var T = new cc.kmMat4();
+ var Out = new cc.kmVec3();
+ var Vx4 = new cc.kmVec3();
+ var Tx4 = new cc.kmMat4();
+ var Outx4 = new cc.kmVec3();
+
+ function init() {
+ T.mat[0] = 1.0;
+ T.mat[5] = 1.0;
+ T.mat[10] = 1.0;
+ T.mat[15] = 1.0;
+
+ V.fill(0.0, 1.0, 0.0);
+
+ Tx4.mat[0] = 1.0;
+ Tx4.mat[5] = 1.0;
+ Tx4.mat[10] = 1.0;
+ Tx4.mat[15] = 1.0;
+
+ Vx4.fill(0.0, 1.0, 0.0);
+
+ nonSimd(1);
+ simd(1);
+ //console.log(V);
+ //console.log(Vx4);
+ return V.equals(Vx4);
+
+ }
+
+ function cleanup() {
+ return init(); // Sanity checking before and after are the same
+ }
+
+ function nonSimd(n) {
+ for (var i = 0; i < n; i++) {
+ V.transformCoord(T);
+ }
+ }
+
+ function simd(n) {
+ for (var i = 0; i < n; i++) {
+ Vx4.transformCoordSIMD(Tx4);
+ }
+ }
+
+} ());
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/run.js b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/run.js
new file mode 100644
index 0000000..8441ae1
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/run.js
@@ -0,0 +1,40 @@
+"use strict"
+
+var cc = {};
+
+load ('base.js');
+
+load ('../utility.js');
+load ('../vec3.js');
+load ('../vec4.js');
+load ('../mat4.js');
+load ('../vec3SIMD.js');
+load ('../mat4SIMD.js');
+
+// load individual benchmarks
+load ('kernel-template.js');
+load ('kmMat4Multiply.js');
+load ('kmMat4Assign.js');
+load ('kmMat4AreEqual.js');
+load ('kmMat4Inverse.js');
+load ('kmMat4IsIdentity.js');
+load ('kmMat4Transpose.js');
+load ('kmMat4LookAt.js');
+load ('kmVec3TransformCoord.js');
+
+function printResult (str) {
+ print (str);
+}
+
+function printError (str) {
+ print (str);
+}
+
+function printScore (str) {
+ print (str);
+}
+
+benchmarks.runAll ({notifyResult: printResult,
+ notifyError: printError,
+ notifyScore: printScore},
+ true);
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/run_browser.js b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/run_browser.js
new file mode 100644
index 0000000..5d2d0cd
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/simd_benchmark/run_browser.js
@@ -0,0 +1,80 @@
+var echo = document.getElementById('echo');
+
+function printResult(str) {
+ console.log(str);
+ echo.innerHTML += str + ' ';
+}
+
+function printError(str) {
+ console.log(str);
+ echo.innerHTML += str + ' ';
+}
+
+function printScore(str) {
+ console.log(str);
+ echo.innerHTML += str + ' ';
+}
+
+var timeData = {
+ labels: [],
+ datasets: [
+ {
+ labels: 'Non-SIMD',
+ fillColor: "rgba(220,220,220,0.5)",
+ strokeColor: "rgba(220,220,220,0.8)",
+ highlightFill: "rgba(220,220,220,0.75)",
+ highlightStroke: "rgba(220,220,220,1)",
+ data: []
+ },
+ {
+ labels: 'SIMD',
+ fillColor: "rgba(151,187,205,0.5)",
+ strokeColor: "rgba(151,187,205,0.8)",
+ highlightFill: "rgba(151,187,205,0.75)",
+ highlightStroke: "rgba(151,187,205,1)",
+ data: []
+ }
+ ]
+};
+
+var speedupData ={
+ labels: [],
+ datasets: [
+ {
+ labels: 'SIMD',
+ fillColor: "rgba(151,187,205,0.5)",
+ strokeColor: "rgba(151,187,205,0.8)",
+ highlightFill: "rgba(151,187,205,0.75)",
+ highlightStroke: "rgba(151,187,205,1)",
+ data: []
+ }
+ ]
+};
+
+window.onload = function() {
+ if (typeof(SIMD) === 'undefined') {
+ var head = document.getElementById('head');
+ head.innerHTML = 'SIMD is not implemented in your browser, stops.';
+ return;
+ }
+ console.log('Running benchmarks.');
+ benchmarks.runAll({notifyResult: printResult,
+ notifyError: printError,
+ notifyScore: printScore,
+ timeData: timeData,
+ speedupData: speedupData}, true);
+ document.getElementById('head').innerHTML = 'Results';
+ document.getElementById('time').innerHTML = 'Time';
+ document.getElementById('speedup').innerHTML = 'Speedup';
+ var ctx1 = document.getElementById("canvasTime").getContext("2d");
+ window.Bar1 = new Chart(ctx1).Bar(timeData, {
+ scaleLabel: "<%=value%>ms",
+ responsive: true
+ });
+ var ctx2 = document.getElementById("canvasSpeedup").getContext("2d");
+ window.Bar2 = new Chart(ctx2).Bar(speedupData, {
+ scaleLabel: " <%=value%>",
+ responsive: true
+ });
+ console.log('Benchmarks completed.');
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/utility.js b/frameworks/cocos2d-html5/cocos2d/kazmath/utility.js
new file mode 100644
index 0000000..9cd3fb4
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/utility.js
@@ -0,0 +1,54 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * The main namespace of Cocos2d-html5's math library,
+ * all math core classes, functions, properties and constants are defined in this namespace
+ * @namespace
+ * @name cc.math
+ */
+cc.math = cc.math || {};
+
+//cc.kmPIOver180 = 0.017453; please use cc.RAD
+
+//cc.kmPIUnder180 = 57.295779; please use cc.DEG
+
+cc.math.EPSILON = 1.0 / 64.0; //cc.kmEpsilon
+
+/**
+ * Returns the square of s (e.g. s*s)
+ * @param {Number} s
+ */
+cc.math.square = function(s){
+ return s*s;
+};
+
+cc.math.almostEqual = function(lhs,rhs){
+ return (lhs + cc.math.EPSILON > rhs && lhs - cc.math.EPSILON < rhs);
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/vec2.js b/frameworks/cocos2d-html5/cocos2d/kazmath/vec2.js
new file mode 100644
index 0000000..a682bc4
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/vec2.js
@@ -0,0 +1,113 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+(function(cc){
+ cc.math.Vec2 = function (x, y) {
+ if(y === undefined){
+ this.x = x.x;
+ this.y = x.y;
+ }else{
+ this.x = x || 0;
+ this.y = y || 0;
+ }
+ };
+
+ var proto = cc.math.Vec2.prototype;
+ proto.fill = function(x, y){ // = cc.kmVec2Fill
+ this.x = x;
+ this.y = y;
+ };
+
+ proto.length = function(){ // = cc.kmVec2Length
+ return Math.sqrt(cc.math.square(this.x) + cc.math.square(this.y));
+ };
+
+ proto.lengthSq = function(){ // = cc.kmVec2LengthSq
+ return cc.math.square(this.x) + cc.math.square(this.y);
+ };
+
+ proto.normalize = function(){ // = cc.kmVec2Normalize
+ var l = 1.0 / this.length();
+ this.x *= l;
+ this.y *= l;
+ return this;
+ };
+
+ cc.math.Vec2.add = function (pOut, pV1, pV2) { // = cc.kmVec2Add
+ pOut.x = pV1.x + pV2.x;
+ pOut.y = pV1.y + pV2.y;
+ return pOut
+ };
+
+ proto.add = function(vec){ // = cc.kmVec2Add
+ this.x += vec.x;
+ this.y += vec.y;
+ return this;
+ };
+
+ proto.dot = function (vec) { //cc.kmVec2Dot
+ return this.x * vec.x + this.y * vec.y;
+ };
+
+ cc.math.Vec2.subtract = function (pOut, pV1, pV2) { // = cc.kmVec2Subtract
+ pOut.x = pV1.x - pV2.x;
+ pOut.y = pV1.y - pV2.y;
+ return pOut;
+ };
+
+ proto.subtract = function(vec){ // = cc.kmVec2Subtract
+ this.x -= vec.x;
+ this.y -= vec.y;
+ return this;
+ };
+
+ proto.transform = function (mat3) { // = cc.kmVec2Transform
+ var x = this.x, y = this.y;
+ this.x = x * mat3.mat[0] + y * mat3.mat[3] + mat3.mat[6];
+ this.y = x * mat3.mat[1] + y * mat3.mat[4] + mat3.mat[7];
+ return this;
+ };
+
+ cc.math.Vec2.scale = function (pOut, pIn, s) { // = cc.kmVec2Scale
+ pOut.x = pIn.x * s;
+ pOut.y = pIn.y * s;
+ return pOut;
+ };
+
+ proto.scale = function(s) { // = cc.kmVec2Scale
+ this.x *= s;
+ this.y *= s;
+ return this;
+ };
+
+ proto.equals = function (vec) { // = cc.kmVec2AreEqual
+ return (this.x < vec.x + cc.math.EPSILON && this.x > vec.x - cc.math.EPSILON) &&
+ (this.y < vec.y + cc.math.EPSILON && this.y > vec.y - cc.math.EPSILON);
+ };
+})(cc);
+
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/vec3.js b/frameworks/cocos2d-html5/cocos2d/kazmath/vec3.js
new file mode 100644
index 0000000..d9eafbe
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/vec3.js
@@ -0,0 +1,199 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+(function(cc) {
+ /**
+ * A 3d vector.
+ * @class
+ * @param {number} [x]
+ * @param {number} [y]
+ * @param {number} [z]
+ */
+
+ cc.math.Vec3 = cc.kmVec3 = function (x, y, z) {
+ if(x && y === undefined){
+ this.x = x.x;
+ this.y = x.y;
+ this.z = x.z;
+ } else {
+ this.x = x || 0;
+ this.y = y || 0;
+ this.z = z || 0;
+ }
+ };
+
+ cc.math.vec3 = function(x, y, z){
+ return new cc.math.Vec3(x, y, z);
+ };
+
+ var _p = cc.math.Vec3.prototype;
+
+ _p.fill = function (x, y, z) { // =cc.kmVec3Fill
+ if (x && y === undefined) {
+ this.x = x.x;
+ this.y = x.y;
+ this.z = x.z;
+ } else {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+ return this;
+ };
+
+ _p.length = function () { //=cc.kmVec3Length
+ return Math.sqrt(cc.math.square(this.x) + cc.math.square(this.y) + cc.math.square(this.z));
+ };
+
+ _p.lengthSq = function () { //=cc.kmVec3LengthSq
+ return cc.math.square(this.x) + cc.math.square(this.y) + cc.math.square(this.z)
+ };
+
+ _p.normalize = function () { //= cc.kmVec3Normalize
+ var l = 1.0 / this.length();
+ this.x *= l;
+ this.y *= l;
+ this.z *= l;
+ return this;
+ };
+
+ _p.cross = function (vec3) { //= cc.kmVec3Cross
+ var x = this.x, y = this.y, z = this.z;
+ this.x = (y * vec3.z) - (z * vec3.y);
+ this.y = (z * vec3.x) - (x * vec3.z);
+ this.z = (x * vec3.y) - (y * vec3.x);
+ return this;
+ };
+
+ _p.dot = function (vec) { //= cc.kmVec3Dot
+ return ( this.x * vec.x + this.y * vec.y + this.z * vec.z );
+ };
+
+ _p.add = function(vec){ //= cc.kmVec3Add
+ this.x += vec.x;
+ this.y += vec.y;
+ this.z += vec.z;
+ return this;
+ };
+
+ _p.subtract = function (vec) { // = cc.kmVec3Subtract
+ this.x -= vec.x;
+ this.y -= vec.y;
+ this.z -= vec.z;
+ return this;
+ };
+
+ _p.transform = function (mat4) { // = cc.kmVec3Transform
+ var x = this.x, y = this.y, z = this.z, mat = mat4.mat;
+ this.x = x * mat[0] + y * mat[4] + z * mat[8] + mat[12];
+ this.y = x * mat[1] + y * mat[5] + z * mat[9] + mat[13];
+ this.z = x * mat[2] + y * mat[6] + z * mat[10] + mat[14];
+ return this;
+ };
+
+ _p.transformNormal = function(mat4){
+ /*
+ a = (Vx, Vy, Vz, 0)
+ b = (a×M)T
+ Out = (bx, by, bz)
+ */
+ //Omits the translation, only scaling + rotating
+ var x = this.x, y = this.y, z = this.z, mat = mat4.mat;
+ this.x = x * mat[0] + y * mat[4] + z * mat[8];
+ this.y = x * mat[1] + y * mat[5] + z * mat[9];
+ this.z = x * mat[2] + y * mat[6] + z * mat[10];
+ return this;
+ };
+
+ _p.transformCoord = function(mat4){ // = cc.kmVec3TransformCoord
+ /*
+ a = (Vx, Vy, Vz, 1)
+ b = (a×M)T
+ Out = 1⁄bw(bx, by, bz)
+ */
+ var v = new cc.math.Vec4(this.x, this.y, this.z, 1.0);
+ v.transform(mat4);
+ this.x = v.x / v.w;
+ this.y = v.y / v.w;
+ this.z = v.z / v.w;
+ return this;
+ };
+
+ _p.scale = function(scale){ // = cc.kmVec3Scale
+ this.x *= scale;
+ this.y *= scale;
+ this.z *= scale;
+ return this;
+ };
+
+ _p.equals = function(vec){ // = cc.kmVec3AreEqual
+ var EPSILON = cc.math.EPSILON;
+ return (this.x < (vec.x + EPSILON) && this.x > (vec.x - EPSILON)) &&
+ (this.y < (vec.y + EPSILON) && this.y > (vec.y - EPSILON)) &&
+ (this.z < (vec.z + EPSILON) && this.z > (vec.z - EPSILON));
+ };
+
+ _p.inverseTransform = function(mat4){ //= cc.kmVec3InverseTransform
+ var mat = mat4.mat;
+ var v1 = new cc.math.Vec3(this.x - mat[12], this.y - mat[13], this.z - mat[14]);
+ this.x = v1.x * mat[0] + v1.y * mat[1] + v1.z * mat[2];
+ this.y = v1.x * mat[4] + v1.y * mat[5] + v1.z * mat[6];
+ this.z = v1.x * mat[8] + v1.y * mat[9] + v1.z * mat[10];
+ return this;
+ };
+
+ _p.inverseTransformNormal = function(mat4){ // = cc.kmVec3InverseTransformNormal
+ var x = this.x, y = this.y, z = this.z, mat = mat4.mat;
+ this.x = x * mat[0] + y * mat[1] + z * mat[2];
+ this.y = x * mat[4] + y * mat[5] + z * mat[6];
+ this.z = x * mat[8] + y * mat[9] + z * mat[10];
+ return this;
+ };
+
+ _p.assignFrom = function(vec){
+ if(!vec)
+ return this;
+ this.x = vec.x;
+ this.y = vec.y;
+ this.z = vec.z;
+ return this;
+ };
+
+ cc.math.Vec3.zero = function(vec){ // = cc.kmVec3Zero
+ vec.x = vec.y = vec.z = 0.0;
+ return vec;
+ };
+
+ _p.toTypeArray = function(){ //cc.kmVec3ToTypeArray
+ var tyArr = new Float32Array(3);
+ tyArr[0] = this.x;
+ tyArr[1] = this.y;
+ tyArr[2] = this.z;
+ return tyArr;
+ };
+})(cc);
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/vec3SIMD.js b/frameworks/cocos2d-html5/cocos2d/kazmath/vec3SIMD.js
new file mode 100644
index 0000000..0bf4ff4
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/vec3SIMD.js
@@ -0,0 +1,51 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ (function(cc) {
+ var proto = cc.math.Vec3.prototype;
+
+ proto.transformCoordSIMD = function(mat4){
+ var vec = SIMD.float32x4(this.x, this.y, this.z, 0.0);
+ var mat0 = SIMD.float32x4.load(mat4.mat, 0);
+ var mat1 = SIMD.float32x4.load(mat4.mat, 4);
+ var mat2 = SIMD.float32x4.load(mat4.mat, 8);
+ var mat3 = SIMD.float32x4.load(mat4.mat, 12);
+
+ //cc.kmVec4Transform(v, inV,pM);
+ var out = SIMD.float32x4.add(
+ SIMD.float32x4.add(SIMD.float32x4.mul(mat0, SIMD.float32x4.swizzle(vec, 0, 0, 0, 0)),
+ SIMD.float32x4.mul(mat1, SIMD.float32x4.swizzle(vec, 1, 1, 1, 1))),
+ SIMD.float32x4.add(SIMD.float32x4.mul(mat2, SIMD.float32x4.swizzle(vec, 2, 2, 2, 2)),
+ mat3));
+
+ out = SIMD.float32x4.div(out, SIMD.float32x4.swizzle(out, 3, 3, 3, 3));
+ this.fill(out);
+
+ return this;
+ };
+})(cc);
diff --git a/frameworks/cocos2d-html5/cocos2d/kazmath/vec4.js b/frameworks/cocos2d-html5/cocos2d/kazmath/vec4.js
new file mode 100644
index 0000000..fb2e376
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/kazmath/vec4.js
@@ -0,0 +1,158 @@
+/**
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008, Luke Benstead.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+(function(cc) {
+ cc.math.Vec4 = function (x, y, z, w) {
+ if (x && y === undefined) {
+ this.x = x.x;
+ this.y = x.y;
+ this.z = x.z;
+ this.w = x.w;
+ } else {
+ this.x = x || 0;
+ this.y = y || 0;
+ this.z = z || 0;
+ this.w = w || 0;
+ }
+ };
+ cc.kmVec4 = cc.math.Vec4;
+ var proto = cc.math.Vec4.prototype;
+
+ proto.fill = function (x, y, z, w) { //=cc.kmVec4Fill
+ if (x && y === undefined) {
+ this.x = x.x;
+ this.y = x.y;
+ this.z = x.z;
+ this.w = x.w;
+ } else {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.w = w;
+ }
+ };
+
+ proto.add = function(vec) { //cc.kmVec4Add
+ if(!vec)
+ return this;
+ this.x += vec.x;
+ this.y += vec.y;
+ this.z += vec.z;
+ this.w += vec.w;
+ return this;
+ };
+
+ proto.dot = function(vec){ //cc.kmVec4Dot
+ return ( this.x * vec.x + this.y * vec.y + this.z * vec.z + this.w * vec.w );
+ };
+
+ proto.length = function(){ //=cc.kmVec4Length
+ return Math.sqrt(cc.math.square(this.x) + cc.math.square(this.y) + cc.math.square(this.z) + cc.math.square(this.w));
+ };
+
+ proto.lengthSq = function(){ //=cc.kmVec4LengthSq
+ return cc.math.square(this.x) + cc.math.square(this.y) + cc.math.square(this.z) + cc.math.square(this.w);
+ };
+
+ proto.lerp = function(vec, t){ //= cc.kmVec4Lerp
+ //not implemented
+ return this;
+ };
+
+ proto.normalize = function() { // cc.kmVec4Normalize
+ var l = 1.0 / this.length();
+ this.x *= l;
+ this.y *= l;
+ this.z *= l;
+ this.w *= l;
+ return this;
+ };
+
+ proto.scale = function(scale){ //= cc.kmVec4Scale
+ /// Scales a vector to the required length. This performs a Normalize before multiplying by S.
+ this.normalize();
+ this.x *= scale;
+ this.y *= scale;
+ this.z *= scale;
+ this.w *= scale;
+ return this;
+ };
+
+ proto.subtract = function(vec) {
+ this.x -= vec.x;
+ this.y -= vec.y;
+ this.z -= vec.z;
+ this.w -= vec.w;
+ };
+
+ proto.transform = function(mat4) {
+ var x = this.x, y = this.y, z = this.z, w = this.w, mat = mat4.mat;
+ this.x = x * mat[0] + y * mat[4] + z * mat[8] + w * mat[12];
+ this.y = x * mat[1] + y * mat[5] + z * mat[9] + w * mat[13];
+ this.z = x * mat[2] + y * mat[6] + z * mat[10] + w * mat[14];
+ this.w = x * mat[3] + y * mat[7] + z * mat[11] + w * mat[15];
+ return this;
+ };
+
+ cc.math.Vec4.transformArray = function(vecArray, mat4){
+ var retArray = [];
+ for (var i = 0; i < vecArray.length; i++) {
+ var selVec = new cc.math.Vec4(vecArray[i]);
+ selVec.transform(mat4);
+ retArray.push(selVec);
+ }
+ return retArray;
+ };
+
+ proto.equals = function(vec){ //=cc.kmVec4AreEqual
+ var EPSILON = cc.math.EPSILON;
+ return (this.x < vec.x + EPSILON && this.x > vec.x - EPSILON) &&
+ (this.y < vec.y + EPSILON && this.y > vec.y - EPSILON) &&
+ (this.z < vec.z + EPSILON && this.z > vec.z - EPSILON) &&
+ (this.w < vec.w + EPSILON && this.w > vec.w - EPSILON);
+ };
+
+ proto.assignFrom = function(vec) { //= cc.kmVec4Assign
+ this.x = vec.x;
+ this.y = vec.y;
+ this.z = vec.z;
+ this.w = vec.w;
+ return this;
+ };
+
+ proto.toTypeArray = function(){ //cc.kmVec4ToTypeArray
+ var tyArr = new Float32Array(4);
+ tyArr[0] = this.x;
+ tyArr[1] = this.y;
+ tyArr[2] = this.z;
+ tyArr[3] = this.w;
+ return tyArr;
+ };
+})(cc);
+
+
diff --git a/frameworks/cocos2d-html5/cocos2d/labels/CCLabelAtlas.js b/frameworks/cocos2d-html5/cocos2d/labels/CCLabelAtlas.js
new file mode 100644
index 0000000..c5cd816
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/labels/CCLabelAtlas.js
@@ -0,0 +1,224 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * using image file to print text label on the screen, might be a bit slower than cc.Label, similar to cc.LabelBMFont
+ * @class
+ * @extends cc.LabelBMFont
+ *
+ * @property {String} string - Content string of label
+ *
+ * @param {String} strText
+ * @param {String} charMapFile charMapFile or fntFile
+ * @param {Number} [itemWidth=0]
+ * @param {Number} [itemHeight=0]
+ * @param {Number} [startCharMap=""]
+ * @example
+ * //creates the cc.LabelAtlas with a string, a char map file(the atlas), the width and height of each element and the starting char of the atlas
+ * var myLabel = new cc.LabelAtlas('Text to display', 'CharMapfile.png', 12, 20, ' ')
+ *
+ * //creates the cc.LabelAtlas with a string, a fnt file
+ * var myLabel = new cc.LabelAtlas('Text to display', 'CharMapFile.plist‘);
+ */
+cc.LabelAtlas = cc.LabelBMFont.extend(/** @lends cc.LabelBMFont# */{
+ _className: "LabelAtlas",
+
+ /**
+ *
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * Create a label atlas.
+ * It accepts two groups of parameters:
+ * a) string, fntFile
+ * b) label, textureFilename, width, height, startChar
+ *
+ * @param {String} strText
+ * @param {String} charMapFile charMapFile or fntFile
+ * @param {Number} [itemWidth=0]
+ * @param {Number} [itemHeight=0]
+ * @param {Number} [startCharMap=""]
+ */
+ ctor: function (strText, charMapFile, itemWidth, itemHeight, startCharMap) {
+ cc.SpriteBatchNode.prototype.ctor.call(this);
+ this._imageOffset = cc.p(0, 0);
+ this._cascadeColorEnabled = true;
+ this._cascadeOpacityEnabled = true;
+
+ charMapFile && cc.LabelAtlas.prototype.initWithString.call(this, strText, charMapFile, itemWidth, itemHeight, startCharMap);
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ return new cc.LabelBMFont.WebGLRenderCmd(this);
+ else
+ return new cc.LabelBMFont.CanvasRenderCmd(this);
+ },
+
+ _createFntConfig: function (texture, itemWidth, itemHeight, startCharMap) {
+ var fnt = {};
+ fnt.commonHeight = itemHeight;
+
+ var fontDefDictionary = fnt.fontDefDictionary = {};
+
+ var textureWidth = texture.pixelsWidth;
+ var textureHeight = texture.pixelsHeight;
+
+ var startCharCode = startCharMap.charCodeAt(0);
+ var i = 0;
+ for (var col = itemHeight; col <= textureHeight; col += itemHeight) {
+ for (var row = 0; row < textureWidth; row += itemWidth) {
+ fontDefDictionary[startCharCode+i] = {
+ rect: {x: row, y: col - itemHeight, width:itemWidth, height: itemHeight },
+ xOffset: 0,
+ yOffset: 0,
+ xAdvance: itemWidth
+ };
+ ++i;
+ }
+ }
+
+ fnt.kerningDict = {};
+
+ return fnt;
+ },
+
+ /**
+ *
+ * initializes the cc.LabelAtlas with a string, a char map file(the atlas),
+ * the width and height of each element and the starting char of the atlas
+ * It accepts two groups of parameters:
+ * a) string, fntFile
+ * b) label, textureFilename, width, height, startChar
+ *
+ * @param {String} strText
+ * @param {String|cc.Texture2D} charMapFile charMapFile or fntFile or texture file
+ * @param {Number} [itemWidth=0]
+ * @param {Number} [itemHeight=0]
+ * @param {Number} [startCharMap=""]
+ * @return {Boolean} returns true on success
+ */
+ initWithString: function (strText, charMapFile, itemWidth, itemHeight, startCharMap) {
+ var label = strText + "", textureFilename, width, height, startChar;
+ var self = this, theString = label || "";
+ this._initialString = theString;
+ self._string = theString;
+
+ if (itemWidth === undefined) {
+ var dict = cc.loader.getRes(charMapFile);
+ if (parseInt(dict["version"], 10) !== 1) {
+ cc.log("cc.LabelAtlas.initWithString(): Unsupported version. Upgrade cocos2d version");
+ return false;
+ }
+
+ textureFilename = cc.path.changeBasename(charMapFile, dict["textureFilename"]);
+ var locScaleFactor = cc.contentScaleFactor();
+ width = parseInt(dict["itemWidth"], 10) / locScaleFactor;
+ height = parseInt(dict["itemHeight"], 10) / locScaleFactor;
+ startChar = String.fromCharCode(parseInt(dict["firstChar"], 10));
+ } else {
+ textureFilename = charMapFile;
+ width = itemWidth || 0;
+ height = itemHeight || 0;
+ startChar = startCharMap || " ";
+ }
+
+ var texture;
+ if (charMapFile) {
+ self._fntFile = "dummy_fnt_file:" + textureFilename;
+ var spriteFrameBaseName = textureFilename;
+ var spriteFrame = cc.spriteFrameCache.getSpriteFrame(spriteFrameBaseName) || cc.spriteFrameCache.getSpriteFrame(cc.path.basename(spriteFrameBaseName));
+ if(spriteFrame) {
+ texture = spriteFrame.getTexture();
+ this._spriteFrame = spriteFrame;
+ } else {
+ texture = cc.textureCache.addImage(textureFilename);
+ }
+
+ var newConf = this._createFntConfig(texture, width, height, startChar);
+ newConf.atlasName = textureFilename;
+ self._config = newConf;
+
+ var locIsLoaded = texture.isLoaded();
+ self._textureLoaded = locIsLoaded;
+ if (!locIsLoaded) {
+ texture.addEventListener("load", function (sender) {
+ var self1 = this;
+ self1._textureLoaded = true;
+ //reset the LabelBMFont
+ self1.initWithTexture(sender, self1._initialString.length);
+ self1.setString(self1._initialString, true);
+ self1.dispatchEvent("load");
+ }, self);
+ }
+ } else {
+ texture = new cc.Texture2D();
+ var image = new Image();
+ texture.initWithElement(image);
+ self._textureLoaded = false;
+ }
+
+ if (self.initWithTexture(texture, theString.length)) {
+ self._alignment = cc.TEXT_ALIGNMENT_LEFT;
+ self._imageOffset = cc.p(0, 0);
+ self._width = -1;
+
+ self._realOpacity = 255;
+ self._realColor = cc.color(255, 255, 255, 255);
+
+ self._contentSize.width = 0;
+ self._contentSize.height = 0;
+
+ self.setString(theString, true);
+ return true;
+ }
+ return false;
+ },
+
+ setFntFile: function () {
+ cc.warn("setFntFile doesn't support with LabelAtlas.");
+ }
+
+});
+
+/**
+ *
+ * Please use new cc.LabelAtlas instead.
+ * Create a label atlas.
+ * It accepts two groups of parameters:
+ * a) string, fntFile
+ * b) label, textureFilename, width, height, startChar
+ *
+ * @deprecated since v3.0 please use new cc.LabelAtlas
+ * @param {String} strText
+ * @param {String} charMapFile charMapFile or fntFile
+ * @param {Number} [itemWidth=0]
+ * @param {Number} [itemHeight=0]
+ * @param {Number} [startCharMap=""]
+ * @return {cc.LabelAtlas} returns the LabelAtlas object on success
+ */
+cc.LabelAtlas.create = function (strText, charMapFile, itemWidth, itemHeight, startCharMap) {
+ return new cc.LabelAtlas(strText, charMapFile, itemWidth, itemHeight, startCharMap);
+};
+
diff --git a/frameworks/cocos2d-html5/cocos2d/labels/CCLabelAtlasCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/labels/CCLabelAtlasCanvasRenderCmd.js
new file mode 100644
index 0000000..890c98b
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/labels/CCLabelAtlasCanvasRenderCmd.js
@@ -0,0 +1,110 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function(){
+ cc.LabelAtlas.CanvasRenderCmd = function(renderableObject){
+ cc.AtlasNode.CanvasRenderCmd.call(this, renderableObject);
+ this._needDraw = false;
+ };
+
+ var proto = cc.LabelAtlas.CanvasRenderCmd.prototype = Object.create(cc.AtlasNode.CanvasRenderCmd.prototype);
+ proto.constructor = cc.LabelAtlas.CanvasRenderCmd;
+
+ proto.setCascade = function(){
+ var node = this._node;
+ node._cascadeOpacityEnabled = true;
+ node._cascadeColorEnabled = false;
+ };
+
+ proto.updateAtlasValues = function(){
+ var node = this._node;
+ var locString = node._string || "";
+ var n = locString.length;
+ var texture = this._textureToRender;
+ var locItemWidth = node._itemWidth , locItemHeight = node._itemHeight; //needn't multiply cc.contentScaleFactor(), because sprite's draw will do this
+
+ for (var i = 0, cr = -1; i < n; i++) {
+ var a = locString.charCodeAt(i) - node._mapStartChar.charCodeAt(0);
+ var row = parseInt(a % node._itemsPerRow, 10);
+ var col = parseInt(a / node._itemsPerRow, 10);
+ if(row < 0 || col < 0)
+ continue;
+ var rect = cc.rect(row * locItemWidth, col * locItemHeight, locItemWidth, locItemHeight);
+ var textureContent = texture._contentSize;
+ if(rect.x < 0 || rect.y < 0 || rect.x + rect.width > textureContent.width || rect.y + rect.height > textureContent.height)
+ continue;
+
+ cr++;
+ var c = locString.charCodeAt(i);
+ var fontChar = node.getChildByTag(i);
+ if (!fontChar) {
+ fontChar = new cc.Sprite();
+ if (c === 32) {
+ fontChar.init();
+ fontChar.setTextureRect(cc.rect(0, 0, 10, 10), false, cc.size(0, 0));
+ } else
+ fontChar.initWithTexture(texture, rect);
+
+ cc.Node.prototype.addChild.call(node, fontChar, 0, i);
+ } else {
+ if (c === 32) {
+ fontChar.init();
+ fontChar.setTextureRect(cc.rect(0, 0, 10, 10), false, cc.size(0, 0));
+ } else {
+ // reusing fonts
+ fontChar.initWithTexture(texture, rect);
+ // restore to default in case they were modified
+ fontChar.visible = true;
+ }
+ }
+ fontChar.setPosition(cr * locItemWidth + locItemWidth / 2, locItemHeight / 2);
+ }
+ this.updateContentSize(i, cr+1);
+ };
+
+ proto.updateContentSize = function(i, cr){
+ var node = this._node,
+ contentSize = node._contentSize;
+ if(i !== cr && i*node._itemWidth === contentSize.width && node._itemHeight === contentSize.height){
+ node.setContentSize(cr * node._itemWidth, node._itemHeight);
+ }
+ };
+
+ proto.setString = function(label){
+ var node = this._node;
+ if (node._children) {
+ var locChildren = node._children;
+ var len = locChildren.length;
+ for (var i = 0; i < len; i++) {
+ var child = locChildren[i];
+ if (child && !child._lateChild)
+ child.visible = false;
+ }
+ }
+ };
+
+ proto._addChild = function(){
+ child._lateChild = true;
+ };
+})();
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/labels/CCLabelAtlasWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/labels/CCLabelAtlasWebGLRenderCmd.js
new file mode 100644
index 0000000..5edf6c5
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/labels/CCLabelAtlasWebGLRenderCmd.js
@@ -0,0 +1,170 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ cc.LabelAtlas.WebGLRenderCmd = function (renderable) {
+ cc.AtlasNode.WebGLRenderCmd.call(this, renderable);
+ this._needDraw = true;
+ };
+
+ var proto = cc.LabelAtlas.WebGLRenderCmd.prototype = Object.create(cc.AtlasNode.WebGLRenderCmd.prototype);
+ proto.constructor = cc.LabelAtlas.WebGLRenderCmd;
+
+ proto._updateColor = function () {
+ if (this._colorF32Array) {
+ var locDisplayedColor = this._displayedColor;
+ var a = this._displayedOpacity / 255;
+ if (this._node._opacityModifyRGB) {
+ this._colorF32Array[0] = locDisplayedColor.r * a / 255;
+ this._colorF32Array[1] = locDisplayedColor.g * a / 255;
+ this._colorF32Array[2] = locDisplayedColor.b * a / 255;
+ this._colorF32Array[3] = a;
+ }
+ else {
+ this._colorF32Array[0] = locDisplayedColor.r / 255;
+ this._colorF32Array[1] = locDisplayedColor.g / 255;
+ this._colorF32Array[2] = locDisplayedColor.b / 255;
+ this._colorF32Array[3] = a;
+ }
+ }
+ };
+
+ proto.setCascade = function () {
+ var node = this._node;
+ node._cascadeOpacityEnabled = true;
+ node._cascadeColorEnabled = true;
+ };
+
+ proto.rendering = function (ctx) {
+ cc.AtlasNode.WebGLRenderCmd.prototype.rendering.call(this, ctx);
+ if (cc.LABELATLAS_DEBUG_DRAW) {
+ var node = this._node;
+ var s = node.getContentSize();
+ var locRect = node.getBoundingBoxToWorld();
+ var posX = locRect.x,
+ posY = locRect.y;
+ s.width = locRect.width;
+ s.height = locRect.height;
+ var vertices = [cc.p(posX, posY), cc.p(posX + s.width, posY),
+ cc.p(s.width + posX, s.height + posY), cc.p(posX, posY + s.height)];
+ cc._drawingUtil.drawPoly(vertices, 4, true);
+ }
+ };
+
+ proto.updateAtlasValues = function () {
+ var node = this._node;
+ var locString = node._string;
+ var n = locString.length;
+ var locTextureAtlas = this._textureAtlas;
+
+ var texture = locTextureAtlas.texture;
+ var textureWide = texture.pixelsWidth;
+ var textureHigh = texture.pixelsHeight;
+ var itemWidthInPixels = node._itemWidth;
+ var itemHeightInPixels = node._itemHeight;
+ if (!node._ignoreContentScaleFactor) {
+ itemWidthInPixels = node._itemWidth * cc.contentScaleFactor();
+ itemHeightInPixels = node._itemHeight * cc.contentScaleFactor();
+ }
+ if (n > locTextureAtlas.getCapacity())
+ cc.log("cc.LabelAtlas._updateAtlasValues(): Invalid String length");
+ var quads = locTextureAtlas.quads;
+ var locItemWidth = node._itemWidth;
+ var locItemHeight = node._itemHeight;
+ for (var i = 0, cr = -1; i < n; i++) {
+ var a = locString.charCodeAt(i) - node._mapStartChar.charCodeAt(0);
+ var row = a % node._itemsPerRow;
+ var col = 0 | (a / node._itemsPerRow);
+ if (row < 0 || col < 0)
+ continue;
+ if (row * locItemWidth + locItemWidth > textureWide || col * locItemHeight + locItemHeight > textureHigh)
+ continue;
+
+ cr++;
+ var left, right, top, bottom;
+ if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) {
+ // Issue #938. Don't use texStepX & texStepY
+ left = (2 * row * itemWidthInPixels + 1) / (2 * textureWide);
+ right = left + (itemWidthInPixels * 2 - 2) / (2 * textureWide);
+ top = (2 * col * itemHeightInPixels + 1) / (2 * textureHigh);
+ bottom = top + (itemHeightInPixels * 2 - 2) / (2 * textureHigh);
+ } else {
+ left = row * itemWidthInPixels / textureWide;
+ right = left + itemWidthInPixels / textureWide;
+ top = col * itemHeightInPixels / textureHigh;
+ bottom = top + itemHeightInPixels / textureHigh;
+ }
+ var quad = quads[i];
+ var locQuadTL = quad.tl, locQuadTR = quad.tr, locQuadBL = quad.bl, locQuadBR = quad.br;
+ locQuadTL.texCoords.u = left;
+ locQuadTL.texCoords.v = top;
+ locQuadTR.texCoords.u = right;
+ locQuadTR.texCoords.v = top;
+ locQuadBL.texCoords.u = left;
+ locQuadBL.texCoords.v = bottom;
+ locQuadBR.texCoords.u = right;
+ locQuadBR.texCoords.v = bottom;
+
+ locQuadBL.vertices.x = (cr * locItemWidth);
+ locQuadBL.vertices.y = 0;
+ locQuadBL.vertices.z = 0.0;
+ locQuadBR.vertices.x = (cr * locItemWidth + locItemWidth);
+ locQuadBR.vertices.y = 0;
+ locQuadBR.vertices.z = 0.0;
+ locQuadTL.vertices.x = cr * locItemWidth;
+ locQuadTL.vertices.y = node._itemHeight;
+ locQuadTL.vertices.z = 0.0;
+ locQuadTR.vertices.x = cr * locItemWidth + locItemWidth;
+ locQuadTR.vertices.y = node._itemHeight;
+ locQuadTR.vertices.z = 0.0;
+ }
+
+ this._updateColor();
+
+ this.updateContentSize(i, cr + 1);
+ if (n > 0) {
+ locTextureAtlas.dirty = true;
+ var totalQuads = locTextureAtlas.totalQuads;
+ if (n > totalQuads)
+ locTextureAtlas.increaseTotalQuadsWith(n - totalQuads);
+ }
+ };
+
+ proto.updateContentSize = function (i, cr) {
+ var node = this._node,
+ contentSize = node._contentSize;
+ if (i !== cr && i * node._itemWidth === contentSize.width && node._itemHeight === contentSize.height) {
+ node.setContentSize(cr * node._itemWidth, node._itemHeight);
+ }
+ };
+
+ proto.setString = function (label) {
+ var len = label.length;
+ if (len > this._textureAtlas.totalQuads)
+ this._textureAtlas.resizeCapacity(len);
+ };
+
+ proto._addChild = function () {
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/labels/CCLabelBMFont.js b/frameworks/cocos2d-html5/cocos2d/labels/CCLabelBMFont.js
new file mode 100644
index 0000000..388f0e8
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/labels/CCLabelBMFont.js
@@ -0,0 +1,1022 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+ Use any of these editors to generate BMFonts:
+ http://glyphdesigner.71squared.com/ (Commercial, Mac OS X)
+ http://www.n4te.com/hiero/hiero.jnlp (Free, Java)
+ http://slick.cokeandcode.com/demos/hiero.jnlp (Free, Java)
+ http://www.angelcode.com/products/bmfont/ (Free, Windows only)
+ ****************************************************************************/
+
+/**
+ * cc.LabelBMFont is a subclass of cc.SpriteBatchNode.
+ *
+ * Features:
+ *
- Treats each character like a cc.Sprite. This means that each individual character can be:
+ * - rotated
+ * - scaled
+ * - translated
+ * - tinted
+ * - change the opacity
+ * - It can be used as part of a menu item.
+ * - anchorPoint can be used to align the "label"
+ * - Supports AngelCode text format
+ *
+ * Limitations:
+ * - All inner characters are using an anchorPoint of (0.5, 0.5) and it is not recommend to change it
+ * because it might affect the rendering
+ *
+ * cc.LabelBMFont implements the protocol cc.LabelProtocol, like cc.Label and cc.LabelAtlas.
+ * cc.LabelBMFont has the flexibility of cc.Label, the speed of cc.LabelAtlas and all the features of cc.Sprite.
+ * If in doubt, use cc.LabelBMFont instead of cc.LabelAtlas / cc.Label.
+ *
+ * Supported editors:
+ * http://glyphdesigner.71squared.com/ (Commercial, Mac OS X)
+ * http://www.n4te.com/hiero/hiero.jnlp (Free, Java)
+ * http://slick.cokeandcode.com/demos/hiero.jnlp (Free, Java)
+ * http://www.angelcode.com/products/bmfont/ (Free, Windows only)
+ * @class
+ * @extends cc.SpriteBatchNode
+ *
+ * @property {String} string - Content string of label
+ * @property {Number} textAlign - Horizontal Alignment of label, cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT
+ * @property {Number} boundingWidth - Width of the bounding box of label, the real content width is limited by boundingWidth
+ *
+ * @param {String} str
+ * @param {String} fntFile
+ * @param {Number} [width=-1]
+ * @param {Number} [alignment=cc.TEXT_ALIGNMENT_LEFT]
+ * @param {cc.Point} [imageOffset=cc.p(0,0)]
+ *
+ * @example
+ * // Example 01
+ * var label1 = new cc.LabelBMFont("Test case", "test.fnt");
+ *
+ * // Example 02
+ * var label2 = new cc.LabelBMFont("test case", "test.fnt", 200, cc.TEXT_ALIGNMENT_LEFT);
+ *
+ * // Example 03
+ * var label3 = new cc.LabelBMFont("This is a \n test case", "test.fnt", 200, cc.TEXT_ALIGNMENT_LEFT, cc.p(0,0));
+ */
+cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{
+ //property string is Getter and Setter.
+ //property textAlign is Getter and Setter.
+ //property boundingWidth is Getter and Setter.
+ _opacityModifyRGB: false,
+
+ _string: "",
+ _config: null,
+
+ // name of fntFile
+ _fntFile: "",
+
+ // initial string without line breaks
+ _initialString: "",
+
+ // alignment of all lines
+ _alignment: cc.TEXT_ALIGNMENT_CENTER,
+
+ // max width until a line break is added
+ _width: -1,
+ _lineBreakWithoutSpaces: false,
+ _imageOffset: null,
+
+ _textureLoaded: false,
+ _className: "LabelBMFont",
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ return new cc.LabelBMFont.WebGLRenderCmd(this);
+ else
+ return new cc.LabelBMFont.CanvasRenderCmd(this);
+ },
+
+ _setString: function (newString, needUpdateLabel) {
+ if (!needUpdateLabel) {
+ this._string = newString;
+ } else {
+ this._initialString = newString;
+ }
+
+ var locChildren = this._children;
+ if (locChildren) {
+ for (var i = 0; i < locChildren.length; i++) {
+ var selNode = locChildren[i];
+ if (selNode)
+ selNode.setVisible(false);
+ }
+ }
+ if (this._textureLoaded) {
+ if(this._string && this._string.length > 0) {
+ this.createFontChars();
+ }
+ if (needUpdateLabel)
+ this.updateLabel();
+ }
+ },
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * creates a bitmap font atlas with an initial string and the FNT file.
+ * @param {String} str
+ * @param {String} fntFile
+ * @param {Number} [width=-1]
+ * @param {Number} [alignment=cc.TEXT_ALIGNMENT_LEFT]
+ * @param {cc.Point} [imageOffset=cc.p(0,0)]
+ */
+ ctor: function (str, fntFile, width, alignment, imageOffset) {
+ cc.SpriteBatchNode.prototype.ctor.call(this);
+ this._imageOffset = cc.p(0, 0);
+ this._cascadeColorEnabled = true;
+ this._cascadeOpacityEnabled = true;
+ this.initWithString(str, fntFile, width, alignment, imageOffset);
+ },
+
+ /**
+ * return texture is loaded
+ * @returns {boolean}
+ */
+ textureLoaded: function () {
+ return this._textureLoaded;
+ },
+
+ /**
+ * add texture loaded event listener.
+ * Will execute the callback in the loaded.
+ * @param {Function} callback
+ * @param {Object} target
+ * @deprecated since 3.1, please use addEventListener instead
+ */
+ addLoadedEventListener: function (callback, target) {
+ this.addEventListener("load", callback, target);
+ },
+
+ /**
+ * Conforms to cc.RGBAProtocol protocol.
+ * @return {Boolean}
+ */
+ isOpacityModifyRGB: function () {
+ return this._opacityModifyRGB;
+ },
+
+ /**
+ * Set whether to support cc.RGBAProtocol protocol
+ * @param {Boolean} opacityModifyRGB
+ */
+ setOpacityModifyRGB: function (opacityModifyRGB) {
+ this._opacityModifyRGB = opacityModifyRGB;
+ var locChildren = this._children;
+ if (locChildren) {
+ for (var i = 0; i < locChildren.length; i++) {
+ var node = locChildren[i];
+ if (node)
+ node.opacityModifyRGB = this._opacityModifyRGB;
+ }
+ }
+ },
+
+ _changeTextureColor: function () {
+ this._renderCmd._changeTextureColor();
+ },
+
+ /**
+ * Initialization of the node, please do not call this function by yourself, you should pass the parameters to constructor to initialize it
.
+ */
+ init: function () {
+ return this.initWithString(null, null, null, null, null);
+ },
+
+ /**
+ * init a bitmap font atlas with an initial string and the FNT file
+ * @param {String} str
+ * @param {String} fntFile
+ * @param {Number} [width=-1]
+ * @param {Number} [alignment=cc.TEXT_ALIGNMENT_LEFT]
+ * @param {cc.Point} [imageOffset=cc.p(0,0)]
+ * @return {Boolean}
+ */
+ initWithString: function (str, fntFile, width, alignment, imageOffset) {
+ var self = this, theString = str || "";
+
+ if (self._config)
+ cc.log("cc.LabelBMFont.initWithString(): re-init is no longer supported");
+
+ var texture;
+ if (fntFile) {
+ var newConf = cc.loader.getRes(fntFile);
+ if (!newConf) {
+ newConf = cc.FntFrameCache[fntFile] || cc.FntFrameCache[cc.path.basename(fntFile)];
+ if(!newConf) {
+ cc.log("cc.LabelBMFont.initWithString(): Impossible to create font. Please check file");
+ return false;
+ }
+ }
+
+ self._config = newConf;
+ self._fntFile = fntFile;
+ var spriteFrameBaseName = newConf.atlasName;
+ var spriteFrame = cc.spriteFrameCache.getSpriteFrame(spriteFrameBaseName) || cc.spriteFrameCache.getSpriteFrame(cc.path.basename(spriteFrameBaseName));
+ if(spriteFrame) {
+ texture = spriteFrame.getTexture();
+ this._spriteFrame = spriteFrame;
+ } else {
+ texture = cc.textureCache.addImage(newConf.atlasName);
+ }
+ var locIsLoaded = texture.isLoaded();
+ self._textureLoaded = locIsLoaded;
+ if (!locIsLoaded) {
+ texture.addEventListener("load", function (sender) {
+ var self1 = this;
+ self1._textureLoaded = true;
+ //reset the LabelBMFont
+ self1.initWithTexture(sender, self1._initialString.length);
+ self1.setString(self1._initialString, true);
+ self1.dispatchEvent("load");
+ }, self);
+ }
+ } else {
+ texture = new cc.Texture2D();
+ var image = new Image();
+ texture.initWithElement(image);
+ self._textureLoaded = false;
+ }
+
+ if (self.initWithTexture(texture, theString.length)) {
+ self._alignment = alignment || cc.TEXT_ALIGNMENT_LEFT;
+ self._imageOffset = imageOffset || cc.p(0, 0);
+ self._width = (width === undefined) ? -1 : width;
+
+ self._realOpacity = 255;
+ self._realColor = cc.color(255, 255, 255, 255);
+
+ self._contentSize.width = 0;
+ self._contentSize.height = 0;
+
+ self.setAnchorPoint(0.5, 0.5);
+
+ self.setString(theString, true);
+
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * updates the font chars based on the string to render
+ */
+ createFontChars: function () {
+ var locStr = this._string;
+ var stringLen = locStr ? locStr.length : 0;
+
+ var self = this;
+ var cmd = this._renderCmd;
+ var locTexture = cmd._texture || this._texture;
+
+ var nextFontPositionX = 0;
+
+ var tmpSize = cc.size(0, 0);
+
+ var longestLine = 0;
+
+ var quantityOfLines = 1;
+
+
+ var i, locCfg = self._config, locKerningDict = locCfg.kerningDict,
+ locCommonH = locCfg.commonHeight, locFontDict = locCfg.fontDefDictionary;
+ for (i = 0; i < stringLen - 1; i++) {
+ if (locStr.charCodeAt(i) === 10) quantityOfLines++;
+ }
+
+ var totalHeight = locCommonH * quantityOfLines;
+ var nextFontPositionY = -(locCommonH - locCommonH * quantityOfLines);
+
+ var prev = -1;
+ var fontDef;
+ for (i = 0; i < stringLen; i++) {
+ var key = locStr.charCodeAt(i);
+ if (key === 0) continue;
+
+ if (key === 10) {
+ //new line
+ nextFontPositionX = 0;
+ nextFontPositionY -= locCfg.commonHeight;
+ continue;
+ }
+
+ var kerningAmount = locKerningDict[(prev << 16) | (key & 0xffff)] || 0;
+ fontDef = locFontDict[key];
+ if (!fontDef) {
+ cc.log("cocos2d: LabelBMFont: character not found " + locStr[i]);
+
+ fontDef = {
+ rect: {
+ x: 0,
+ y: 0,
+ width: 0,
+ height: 0
+ },
+ xOffset: 0,
+ yOffset: 0,
+ xAdvance: 0
+ };
+ }
+
+ var rect = cc.rect(fontDef.rect.x, fontDef.rect.y, fontDef.rect.width, fontDef.rect.height);
+ rect = cc.rectPixelsToPoints(rect);
+ rect.x += self._imageOffset.x;
+ rect.y += self._imageOffset.y;
+
+ var isRotated = false;
+ if(this._spriteFrame) {
+ var textureWidth = locTexture.width;
+ var spriteFrameRect = this._spriteFrame._rect;
+ if(!this._spriteFrame._rotated) {
+ rect.x = rect.x + spriteFrameRect.x;
+ rect.y = rect.y + spriteFrameRect.y;
+ } else {
+ isRotated = true;
+ var originalX = rect.x;
+ rect.x = rect.y + spriteFrameRect.x;
+ rect.y = originalX + spriteFrameRect.y;
+ }
+ }
+
+ var fontChar = self.getChildByTag(i);
+
+ if (!fontChar) {
+ fontChar = new cc.Sprite();
+ fontChar.initWithTexture(locTexture, rect, isRotated);
+ fontChar._newTextureWhenChangeColor = true;
+ this.addChild(fontChar, 0, i);
+ } else {
+ cmd._updateCharTexture(fontChar, rect, key, isRotated);
+ }
+
+ // Apply label properties
+ fontChar.opacityModifyRGB = this._opacityModifyRGB;
+ cmd._updateCharColorAndOpacity(fontChar);
+
+ var yOffset = locCfg.commonHeight - fontDef.yOffset;
+ var fontPos = cc.p(nextFontPositionX + fontDef.xOffset + fontDef.rect.width * 0.5 + kerningAmount,
+ nextFontPositionY + yOffset - rect.height * 0.5 * cc.contentScaleFactor());
+ fontChar.setPosition(cc.pointPixelsToPoints(fontPos));
+
+ // update kerning
+ nextFontPositionX += fontDef.xAdvance + kerningAmount;
+ prev = key;
+
+ if (longestLine < nextFontPositionX)
+ longestLine = nextFontPositionX;
+ }
+
+ //If the last character processed has an xAdvance which is less that the width of the characters image, then we need
+ // to adjust the width of the string to take this into account, or the character will overlap the end of the bounding box
+ if (fontDef && fontDef.xAdvance < fontDef.rect.width)
+ tmpSize.width = longestLine - fontDef.xAdvance + fontDef.rect.width;
+ else
+ tmpSize.width = longestLine;
+ tmpSize.height = totalHeight;
+ self.setContentSize(cc.sizePixelsToPoints(tmpSize));
+ },
+
+ /**
+ * Update String.
+ * Only update this label display string.
+ * @param {Boolean} fromUpdate
+ */
+ updateString: function (fromUpdate) {
+ var self = this;
+ var locChildren = self._children;
+ if (locChildren) {
+ var length = locChildren.length;
+ for (var i = 0, li = length; i < li; i++) {
+ var node = locChildren[i];
+ if (node) node.visible = false;
+ }
+ }
+ if (self._config) {
+ if(self._string && self._string.length > 0) {
+ self.createFontChars();
+ }
+ }
+
+ if (!fromUpdate)
+ self.updateLabel();
+ },
+
+ /**
+ * Gets the text of this label
+ * @return {String}
+ */
+ getString: function () {
+ return this._initialString;
+ },
+
+ /**
+ * Set the text
+ * @param {String} newString
+ * @param {Boolean|null} needUpdateLabel
+ */
+ setString: function (newString, needUpdateLabel) {
+ newString = String(newString);
+ if (needUpdateLabel === undefined)
+ needUpdateLabel = true;
+ if (newString === undefined || typeof newString !== 'string')
+ newString = newString + "";
+
+ this._initialString = newString;
+ this._setString(newString, needUpdateLabel);
+ },
+
+ _setStringForSetter: function (newString) {
+ this.setString(newString, false);
+ },
+
+ /**
+ * Set the text.
+ * Change this Label display string.
+ * @deprecated since v3.0 please use .setString
+ * @param label
+ */
+ setCString: function (label) {
+ this.setString(label, true);
+ },
+
+ // calc the text all with in a line
+ _getCharsWidth: function (startIndex, endIndex) {
+ if (endIndex <= 0) {
+ return 0;
+ }
+ var curTextFirstSprite = this.getChildByTag(startIndex);
+ var curTextLastSprite = this.getChildByTag(startIndex + endIndex);
+ return this._getLetterPosXLeft(curTextLastSprite) - this._getLetterPosXLeft(curTextFirstSprite);
+ },
+
+ _checkWarp: function (strArr, i, maxWidth, initStringWrapNum) {
+ var self = this;
+ var text = strArr[i];
+ var curLength = 0;
+ for (var strArrIndex = 0; strArrIndex < i; strArrIndex++) {
+ curLength += strArr[strArrIndex].length;
+ }
+
+ curLength = curLength + i - initStringWrapNum; // add the wrap line num
+
+ var allWidth = self._getCharsWidth(curLength, strArr[i].length - 1);
+
+ if (allWidth > maxWidth && text.length > 1) {
+ var fuzzyLen = text.length * ( maxWidth / allWidth ) | 0;
+ var tmpText = text.substr(fuzzyLen);
+ var width = allWidth - this._getCharsWidth(curLength + fuzzyLen, tmpText.length - 1);
+ var sLine;
+ var pushNum = 0;
+
+ //Increased while cycle maximum ceiling. default 100 time
+ var checkWhile = 0;
+
+ //Exceeded the size
+ while (width > maxWidth && checkWhile++ < 100) {
+ fuzzyLen *= maxWidth / width;
+ fuzzyLen = fuzzyLen | 0;
+ tmpText = text.substr(fuzzyLen);
+ width = allWidth - this._getCharsWidth(curLength + fuzzyLen, tmpText.length - 1);
+ }
+
+ checkWhile = 0;
+
+ //Find the truncation point
+ while (width < maxWidth && checkWhile++ < 100) {
+ if (tmpText) {
+ var exec = cc.LabelTTF._wordRex.exec(tmpText);
+ pushNum = exec ? exec[0].length : 1;
+ sLine = tmpText;
+ }
+ if (self._lineBreakWithoutSpaces) {
+ pushNum = 0;
+ }
+ fuzzyLen = fuzzyLen + pushNum;
+ tmpText = text.substr(fuzzyLen);
+ width = allWidth - this._getCharsWidth(curLength + fuzzyLen, tmpText.length - 1);
+ }
+
+ fuzzyLen -= pushNum;
+ if (fuzzyLen === 0) {
+ fuzzyLen = 1;
+ sLine = sLine.substr(1);
+ }
+
+ var sText = text.substr(0, fuzzyLen), result;
+
+ //symbol in the first
+ if (cc.LabelTTF.wrapInspection) {
+ if (cc.LabelTTF._symbolRex.test(sLine || tmpText)) {
+ result = cc.LabelTTF._lastWordRex.exec(sText);
+ pushNum = result ? result[0].length : 0;
+ if (self._lineBreakWithoutSpaces) {
+ pushNum = 0;
+ }
+ fuzzyLen -= pushNum;
+
+ sLine = text.substr(fuzzyLen);
+ sText = text.substr(0, fuzzyLen);
+ }
+ }
+
+ //To judge whether a English words are truncated
+ if (cc.LabelTTF._firsrEnglish.test(sLine)) {
+ result = cc.LabelTTF._lastEnglish.exec(sText);
+ if (result && sText !== result[0]) {
+ pushNum = result[0].length;
+ if (self._lineBreakWithoutSpaces) {
+ pushNum = 0;
+ }
+ fuzzyLen -= pushNum;
+ sLine = text.substr(fuzzyLen);
+ sText = text.substr(0, fuzzyLen);
+ }
+ }
+ strArr[i] = sLine || tmpText;
+ strArr.splice(i, 0, sText);
+ }
+ },
+
+ /**
+ * Update Label.
+ * Update this Label display string and more...
+ */
+ updateLabel: function () {
+ var self = this;
+ self.string = self._initialString;
+
+ var i, j, characterSprite;
+ // process string
+ // Step 1: Make multiline
+ if (self._width > 0) {
+ var stringArr = self.string.split('\n');
+ var wrapString = "";
+ var newWrapNum = 0;
+ var oldArrLength = 0;
+ for (i = 0; i < stringArr.length; i++) {
+ oldArrLength = stringArr.length;
+ this._checkWarp(stringArr, i, self._width * this._scaleX, newWrapNum);
+ if (oldArrLength < stringArr.length) {
+ newWrapNum++;
+ }
+ if (i > 0) {
+ wrapString += "\n";
+ }
+ wrapString += stringArr[i];
+ }
+ wrapString = wrapString + String.fromCharCode(0);
+ self._setString(wrapString, false);
+ }
+ // Step 2: Make alignment
+ if (self._alignment !== cc.TEXT_ALIGNMENT_LEFT) {
+ i = 0;
+
+ var lineNumber = 0;
+ var strlen = self._string.length;
+ var last_line = [];
+
+ for (var ctr = 0; ctr < strlen; ctr++) {
+ if (self._string[ctr].charCodeAt(0) === 10 || self._string[ctr].charCodeAt(0) === 0) {
+ var lineWidth = 0;
+ var line_length = last_line.length;
+ // if last line is empty we must just increase lineNumber and work with next line
+ if (line_length === 0) {
+ lineNumber++;
+ continue;
+ }
+ var index = i + line_length - 1 + lineNumber;
+ if (index < 0) continue;
+
+ var lastChar = self.getChildByTag(index);
+ if (lastChar == null)
+ continue;
+ lineWidth = lastChar.getPositionX() + lastChar._getWidth() / 2;
+
+ var shift = 0;
+ switch (self._alignment) {
+ case cc.TEXT_ALIGNMENT_CENTER:
+ shift = self.width / 2 - lineWidth / 2;
+ break;
+ case cc.TEXT_ALIGNMENT_RIGHT:
+ shift = self.width - lineWidth;
+ break;
+ default:
+ break;
+ }
+
+ if (shift !== 0) {
+ for (j = 0; j < line_length; j++) {
+ index = i + j + lineNumber;
+ if (index < 0) continue;
+ characterSprite = self.getChildByTag(index);
+ if (characterSprite)
+ characterSprite.x += shift;
+ }
+ }
+
+ i += line_length;
+ lineNumber++;
+
+ last_line.length = 0;
+ continue;
+ }
+ last_line.push(self._string[i]);
+ }
+ }
+ },
+
+ /**
+ * Set text alignment.
+ * @param {Number} alignment
+ */
+ setAlignment: function (alignment) {
+ this._alignment = alignment;
+ this.updateLabel();
+ },
+
+ _getAlignment: function () {
+ return this._alignment;
+ },
+
+ /**
+ * Set the bounding width.
+ * max with display width. The exceeding string will be wrapping.
+ * @param {Number} width
+ */
+ setBoundingWidth: function (width) {
+ this._width = width;
+ this.updateLabel();
+ },
+
+ _getBoundingWidth: function () {
+ return this._width;
+ },
+
+ /**
+ * Set the param to change English word warp according to whether the space.
+ * default is false.
+ * @param {Boolean} breakWithoutSpace
+ */
+ setLineBreakWithoutSpace: function (breakWithoutSpace) {
+ this._lineBreakWithoutSpaces = breakWithoutSpace;
+ this.updateLabel();
+ },
+
+ /**
+ * Set scale.
+ * Input a number, will be decrease or increase the font size.
+ * @param {Number} scale
+ * @param {Number} [scaleY=null] default is scale
+ */
+ setScale: function (scale, scaleY) {
+ cc.Node.prototype.setScale.call(this, scale, scaleY);
+ this.updateLabel();
+ },
+
+ /**
+ * Set scale of x.
+ * Input a number, will be decrease or increase the font size.
+ * Horizontal scale.
+ * @param {Number} scaleX
+ */
+ setScaleX: function (scaleX) {
+ cc.Node.prototype.setScaleX.call(this, scaleX);
+ this.updateLabel();
+ },
+
+ /**
+ * Set scale of x.
+ * Input a number, will be decrease or increase the font size.
+ * Longitudinal scale.
+ * @param {Number} scaleY
+ */
+ setScaleY: function (scaleY) {
+ cc.Node.prototype.setScaleY.call(this, scaleY);
+ this.updateLabel();
+ },
+
+ /**
+ * set fnt file path.
+ * Change the fnt file path.
+ * @param {String} fntFile
+ */
+ setFntFile: function (fntFile) {
+ var self = this;
+ if (fntFile != null && fntFile !== self._fntFile) {
+ var newConf = cc.loader.getRes(fntFile);
+
+ if (!newConf) {
+ cc.log("cc.LabelBMFont.setFntFile() : Impossible to create font. Please check file");
+ return;
+ }
+
+ self._fntFile = fntFile;
+ self._config = newConf;
+
+ var texture = cc.textureCache.addImage(newConf.atlasName);
+ var locIsLoaded = texture.isLoaded();
+ self._textureLoaded = locIsLoaded;
+ if (!locIsLoaded) {
+ texture.addEventListener("load", function (sender) {
+ var self1 = this;
+ self1._textureLoaded = true;
+ self1.setTexture(sender);
+ if(self1._string && self1._string.length > 0) {
+ self1.createFontChars();
+ }
+
+ self1._changeTextureColor();
+ self1.updateLabel();
+
+ self1.dispatchEvent("load");
+ }, self);
+ } else {
+ self.setTexture(texture);
+ if(self._string && self._string.length > 0) {
+ self.createFontChars();
+ }
+ }
+ }
+ },
+
+ /**
+ * Return the fnt file path.
+ * @return {String}
+ */
+ getFntFile: function () {
+ return this._fntFile;
+ },
+
+ setTexture: function (texture) {
+ this._texture = texture;
+ this._renderCmd.setTexture(texture);
+ },
+
+ /**
+ * Set the AnchorPoint of the labelBMFont.
+ * In order to change the location of label.
+ * @override
+ * @param {cc.Point|Number} point The anchor point of labelBMFont or The anchor point.x of labelBMFont.
+ * @param {Number} [y] The anchor point.y of labelBMFont.
+ */
+ setAnchorPoint: function (point, y) {
+ cc.Node.prototype.setAnchorPoint.call(this, point, y);
+ this.updateLabel();
+ },
+
+ _setAnchorX: function (x) {
+ cc.Node.prototype._setAnchorX.call(this, x);
+ this.updateLabel();
+ },
+
+ _setAnchorY: function (y) {
+ cc.Node.prototype._setAnchorY.call(this, y);
+ this.updateLabel();
+ },
+
+ _atlasNameFromFntFile: function (fntFile) {
+ },
+
+ _kerningAmountForFirst: function (first, second) {
+ var ret = 0;
+ var key = (first << 16) | (second & 0xffff);
+ if (this._configuration.kerningDictionary) {
+ var element = this._configuration.kerningDictionary[key.toString()];
+ if (element)
+ ret = element.amount;
+ }
+ return ret;
+ },
+
+ _getLetterPosXLeft: function (sp) {
+ return sp.getPositionX() * this._scaleX - (sp._getWidth() * this._scaleX * sp._getAnchorX());
+ },
+
+ _getLetterPosXRight: function (sp) {
+ return sp.getPositionX() * this._scaleX + (sp._getWidth() * this._scaleX * sp._getAnchorX());
+ },
+
+ //Checking whether the character is a whitespace
+ _isspace_unicode: function (ch) {
+ ch = ch.charCodeAt(0);
+ return ((ch >= 9 && ch <= 13) || ch === 32 || ch === 133 || ch === 160 || ch === 5760
+ || (ch >= 8192 && ch <= 8202) || ch === 8232 || ch === 8233 || ch === 8239
+ || ch === 8287 || ch === 12288);
+ },
+
+ _utf8_trim_ws: function (str) {
+ var len = str.length;
+
+ if (len <= 0)
+ return;
+
+ var last_index = len - 1;
+
+ // Only start trimming if the last character is whitespace..
+ if (this._isspace_unicode(str[last_index])) {
+ for (var i = last_index - 1; i >= 0; --i) {
+ if (this._isspace_unicode(str[i])) {
+ last_index = i;
+ }
+ else {
+ break;
+ }
+ }
+ this._utf8_trim_from(str, last_index);
+ }
+ },
+
+ //Trims str st str=[0, index) after the operation.
+ //Return value: the trimmed string.
+ _utf8_trim_from: function (str, index) {
+ var len = str.length;
+ if (index >= len || index < 0)
+ return;
+ str.splice(index, len);
+ }
+});
+
+(function () {
+ var p = cc.LabelBMFont.prototype;
+ cc.EventHelper.prototype.apply(p);
+
+ /** @expose */
+ p.string;
+ cc.defineGetterSetter(p, "string", p.getString, p._setStringForSetter);
+ /** @expose */
+ p.boundingWidth;
+ cc.defineGetterSetter(p, "boundingWidth", p._getBoundingWidth, p.setBoundingWidth);
+ /** @expose */
+ p.textAlign;
+ cc.defineGetterSetter(p, "textAlign", p._getAlignment, p.setAlignment);
+
+ // Override properties
+ cc.defineGetterSetter(p, "texture", p.getTexture, p.setTexture);
+})();
+
+/**
+ * creates a bitmap font atlas with an initial string and the FNT file
+ * @deprecated since v3.0 please use new cc.LabelBMFont
+ * @param {String} str
+ * @param {String} fntFile
+ * @param {Number} [width=-1]
+ * @param {Number} [alignment=cc.TEXT_ALIGNMENT_LEFT]
+ * @param {cc.Point} [imageOffset=cc.p(0,0)]
+ * @return {cc.LabelBMFont|Null}
+ */
+cc.LabelBMFont.create = function (str, fntFile, width, alignment, imageOffset) {
+ return new cc.LabelBMFont(str, fntFile, width, alignment, imageOffset);
+};
+
+cc.FntFrameCache = {};
+
+var _fntLoader = {
+ FNT_HEAD: /fntframes [^\n]*(\n|$)/gi,
+ FNT_FRAME_NAME: /fntframe [^\n]*(\n|$)/gi,
+ INFO_EXP: /info [^\n]*(\n|$)/gi,
+ COMMON_EXP: /common [^\n]*(\n|$)/gi,
+ PAGE_EXP: /page [^\n]*(\n|$)/gi,
+ CHAR_EXP: /char [^\n]*(\n|$)/gi,
+ KERNING_EXP: /kerning [^\n]*(\n|$)/gi,
+ ITEM_EXP: /\w+=[^ \r\n]+/gi,
+ INT_EXP: /^[\-]?\d+$/,
+
+ _parseStrToObj: function (str) {
+ var arr = str.match(this.ITEM_EXP);
+ var obj = {};
+ if (arr) {
+ for (var i = 0, li = arr.length; i < li; i++) {
+ var tempStr = arr[i];
+ var index = tempStr.indexOf("=");
+ var key = tempStr.substring(0, index);
+ var value = tempStr.substring(index + 1);
+ if (value.match(this.INT_EXP)) value = parseInt(value);
+ else if (value[0] === '"') value = value.substring(1, value.length - 1);
+ obj[key] = value;
+ }
+ }
+ return obj;
+ },
+
+ _parseFntContent: function (fnt, fntStr, url, useAtlas) {
+ var self = this;
+ //common
+ var commonObj = self._parseStrToObj(fntStr.match(self.COMMON_EXP)[0]);
+ fnt.commonHeight = commonObj["lineHeight"];
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ var texSize = cc.configuration.getMaxTextureSize();
+ if (commonObj["scaleW"] > texSize.width || commonObj["scaleH"] > texSize.height)
+ cc.log("cc.LabelBMFont._parseCommonArguments(): page can't be larger than supported");
+ }
+ if (commonObj["pages"] !== 1) cc.log("cc.LabelBMFont._parseCommonArguments(): only supports 1 page");
+
+ //page
+ var pageObj = self._parseStrToObj(fntStr.match(self.PAGE_EXP)[0]);
+ if (pageObj["id"] !== 0) cc.log("cc.LabelBMFont._parseImageFileName() : file could not be found");
+ if(!useAtlas) {
+ fnt.atlasName = cc.path.changeBasename(url, pageObj["file"]);
+ } else {
+ fnt.atlasName = cc.path.join(cc.path.dirname(useAtlas.path) + pageObj["file"]);
+ }
+
+ //char
+ var charLines = fntStr.match(self.CHAR_EXP);
+ var fontDefDictionary = fnt.fontDefDictionary = {};
+ for (var i = 0, li = charLines.length; i < li; i++) {
+ var charObj = self._parseStrToObj(charLines[i]);
+ var charId = charObj["id"];
+ fontDefDictionary[charId] = {
+ rect: {x: charObj["x"], y: charObj["y"], width: charObj["width"], height: charObj["height"]},
+ xOffset: charObj["xoffset"],
+ yOffset: charObj["yoffset"],
+ xAdvance: charObj["xadvance"]
+ };
+ }
+
+ //kerning
+ var kerningDict = fnt.kerningDict = {};
+ var kerningLines = fntStr.match(self.KERNING_EXP);
+ if (kerningLines) {
+ for (var i = 0, li = kerningLines.length; i < li; i++) {
+ var kerningObj = self._parseStrToObj(kerningLines[i]);
+ kerningDict[(kerningObj["first"] << 16) | (kerningObj["second"] & 0xffff)] = kerningObj["amount"];
+ }
+ }
+
+ return fnt;
+ },
+
+ /**
+ * Parse Fnt string.
+ * @param fntStr
+ * @param url
+ * @returns {{}}
+ */
+ parseFnt: function (fntStr, url) {
+ var self = this, fnt = {};
+ var headString = fntStr.match(self.FNT_HEAD);
+ if(headString) {
+ var headObj = self._parseStrToObj(headString[0]);
+ if(headObj && headObj.count) {
+ fntStr = fntStr.substr(headString[0].length);
+ var fntFrames = fntStr.split("----");
+ for(var i = 0; i < headObj.count; ++i) {
+ var contentString = fntFrames[i];
+ var frameNameStr = contentString.match(self.FNT_FRAME_NAME);
+ if(frameNameStr) {
+ var frameName = self._parseStrToObj(frameNameStr[0]);
+ if(frameName && frameName.name) {
+ fnt = {};
+ var realFntPathKey = cc.path.join(cc.path.dirname(url), frameName.name);
+ cc.FntFrameCache[realFntPathKey] = this._parseFntContent(fnt, contentString.substr(frameNameStr[0].length), url, {path: frameName.name});
+ }
+ }
+ }
+ }
+ } else {
+ fnt = this._parseFntContent(fnt, fntStr, url);
+ }
+ return fnt;
+ },
+
+ /**
+ * load the fnt
+ * @param realUrl
+ * @param url
+ * @param res
+ * @param cb
+ */
+ load: function (realUrl, url, res, cb) {
+ var self = this;
+ cc.loader.loadTxt(realUrl, function (err, txt) {
+ if (err) return cb(err);
+ cb(null, self.parseFnt(txt, url));
+ });
+ }
+};
+cc.loader.register(["fnt"], _fntLoader);
diff --git a/frameworks/cocos2d-html5/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js
new file mode 100644
index 0000000..5861daa
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js
@@ -0,0 +1,101 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+ Use any of these editors to generate BMFonts:
+ http://glyphdesigner.71squared.com/ (Commercial, Mac OS X)
+ http://www.n4te.com/hiero/hiero.jnlp (Free, Java)
+ http://slick.cokeandcode.com/demos/hiero.jnlp (Free, Java)
+ http://www.angelcode.com/products/bmfont/ (Free, Windows only)
+ ****************************************************************************/
+
+(function () {
+ cc.LabelBMFont.CanvasRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ };
+
+ var proto = cc.LabelBMFont.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ proto.constructor = cc.LabelBMFont.CanvasRenderCmd;
+
+ proto._updateCharTexture = function (fontChar, rect, key) {
+ if (key === 32) {
+ fontChar.setTextureRect(rect, false, cc.size(0, 0));
+ } else {
+ // updating previous sprite
+ fontChar.setTextureRect(rect, false);
+ // restore to default in case they were modified
+ fontChar.visible = true;
+ }
+ };
+
+ proto._updateCharColorAndOpacity = function (fontChar) {
+ // Color MUST be set before opacity, since opacity might change color if OpacityModifyRGB is on
+ fontChar._displayedColor = this._displayedColor;
+ fontChar._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty);
+ fontChar._displayedOpacity = this._displayedOpacity;
+ fontChar._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty);
+ };
+
+ proto.setTexture = function (texture) {
+ var node = this._node;
+ var locChildren = node._children;
+ var locDisplayedColor = this._displayedColor;
+ for (var i = 0; i < locChildren.length; i++) {
+ var selChild = locChildren[i];
+ var cm = selChild._renderCmd;
+ var childDColor = cm._displayedColor;
+ if (node._texture !== cm._texture && (childDColor.r !== locDisplayedColor.r ||
+ childDColor.g !== locDisplayedColor.g || childDColor.b !== locDisplayedColor.b))
+ continue;
+ selChild.texture = texture;
+ }
+ node._texture = texture;
+ };
+
+ proto._changeTextureColor = function () {
+ var node = this._node;
+ var texture = node._texture,
+ contentSize = texture.getContentSize();
+
+ var oTexture = node._texture,
+ oElement = oTexture.getHtmlElementObj();
+ var disColor = this._displayedColor;
+ var textureRect = cc.rect(0, 0, oElement.width, oElement.height);
+ if (texture && contentSize.width > 0) {
+ if (!oElement)
+ return;
+ var textureToRender = oTexture._generateColorTexture(disColor.r, disColor.g, disColor.b, textureRect);
+ node.setTexture(textureToRender);
+ }
+ };
+
+ proto._updateChildrenDisplayedOpacity = function (locChild) {
+ cc.Node.prototype.updateDisplayedOpacity.call(locChild, this._displayedOpacity);
+ };
+
+ proto._updateChildrenDisplayedColor = function (locChild) {
+ cc.Node.prototype.updateDisplayedColor.call(locChild, this._displayedColor);
+ };
+
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js
new file mode 100644
index 0000000..09e18a5
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js
@@ -0,0 +1,57 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+ Use any of these editors to generate BMFonts:
+ http://glyphdesigner.71squared.com/ (Commercial, Mac OS X)
+ http://www.n4te.com/hiero/hiero.jnlp (Free, Java)
+ http://slick.cokeandcode.com/demos/hiero.jnlp (Free, Java)
+ http://www.angelcode.com/products/bmfont/ (Free, Windows only)
+ ****************************************************************************/
+
+(function () {
+ cc.LabelBMFont.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ };
+
+ var proto = cc.LabelBMFont.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ proto.constructor = cc.LabelBMFont.WebGLRenderCmd;
+
+ proto.setTexture = function (texture) {
+ this._node.setOpacityModifyRGB(this._node._texture.hasPremultipliedAlpha());
+ };
+
+ proto._updateCharTexture = function(fontChar, rect, key, isRotated){
+ // updating previous sprite
+ fontChar.setTextureRect(rect, isRotated);
+ // restore to default in case they were modified
+ fontChar.visible = true;
+ };
+
+ proto._changeTextureColor = function () {
+ };
+
+ proto._updateCharColorAndOpacity = function () {
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/menus/CCMenu.js b/frameworks/cocos2d-html5/cocos2d/menus/CCMenu.js
new file mode 100644
index 0000000..e3edd73
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/menus/CCMenu.js
@@ -0,0 +1,608 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.MENU_STATE_WAITING = 0;
+/**
+ * @constant
+ * @type Number
+ */
+cc.MENU_STATE_TRACKING_TOUCH = 1;
+/**
+ * @constant
+ * @type Number
+ */
+cc.MENU_HANDLER_PRIORITY = -128;
+/**
+ * @constant
+ * @type Number
+ */
+cc.DEFAULT_PADDING = 5;
+
+/**
+ * Features and Limitation:
+ * - You can add MenuItem objects in runtime using addChild:
+ * - But the only accepted children are MenuItem objects
+ * @class
+ * @extends cc.Layer
+ * @param {...cc.MenuItem|null} menuItems
+ * @example
+ * var layer = new cc.Menu(menuitem1, menuitem2, menuitem3);
+ */
+cc.Menu = cc.Layer.extend(/** @lends cc.Menu# */{
+ enabled: false,
+
+ _selectedItem: null,
+ _state: -1,
+ _touchListener: null,
+ _className: "Menu",
+
+ /**
+ * Constructor of cc.Menu override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {...cc.MenuItem|null} menuItems
+ */
+ ctor: function (menuItems) {
+ cc.Layer.prototype.ctor.call(this);
+ this._color = cc.color.WHITE;
+ this.enabled = false;
+ this._opacity = 255;
+ this._selectedItem = null;
+ this._state = -1;
+
+ this._touchListener = cc.EventListener.create({
+ event: cc.EventListener.TOUCH_ONE_BY_ONE,
+ swallowTouches: true,
+ onTouchBegan: this._onTouchBegan,
+ onTouchMoved: this._onTouchMoved,
+ onTouchEnded: this._onTouchEnded,
+ onTouchCancelled: this._onTouchCancelled
+ });
+
+ var argc = arguments.length, items;
+ if (menuItems instanceof Array) {
+ items = menuItems;
+ }
+ else if (argc === 0) {
+ items = [];
+ }
+ else if (argc > 0) {
+ items = [];
+ for (var i = 0; i < argc; i++) {
+ if (arguments[i])
+ items.push(arguments[i]);
+ }
+ }
+ this.initWithArray(items);
+ },
+ /**
+ *
+ * Event callback that is invoked every time when CCMenu enters the 'stage'.
+ * If the CCMenu enters the 'stage' with a transition, this event is called when the transition starts.
+ * During onEnter you can't access a "sister/brother" node.
+ * If you override onEnter, you must call its parent's onEnter function with this._super().
+ *
+ */
+ onEnter: function () {
+ var locListener = this._touchListener;
+ if (!locListener._isRegistered())
+ cc.eventManager.addListener(locListener, this);
+ cc.Node.prototype.onEnter.call(this);
+ },
+
+ /**
+ * return whether or not the menu will receive events
+ * @return {Boolean}
+ */
+ isEnabled: function () {
+ return this.enabled;
+ },
+
+ /**
+ * set whether or not the menu will receive events
+ * @param {Boolean} enabled
+ */
+ setEnabled: function (enabled) {
+ this.enabled = enabled;
+ },
+
+ /**
+ * initializes a cc.Menu with it's items
+ * @param {Array} args
+ * @return {Boolean}
+ */
+ initWithItems: function (args) {
+ var pArray = [];
+ if (args) {
+ for (var i = 0; i < args.length; i++) {
+ if (args[i])
+ pArray.push(args[i]);
+ }
+ }
+
+ return this.initWithArray(pArray);
+ },
+
+ /**
+ * initializes a cc.Menu with a Array of cc.MenuItem objects
+ * @param {Array} arrayOfItems array Of cc.MenuItem Items
+ * @return {Boolean}
+ */
+ initWithArray: function (arrayOfItems) {
+ if (cc.Layer.prototype.init.call(this)) {
+ this.enabled = true;
+
+ // menu in the center of the screen
+ var winSize = cc.winSize;
+ this.setPosition(winSize.width / 2, winSize.height / 2);
+ this.setContentSize(winSize);
+ this.setAnchorPoint(0.5, 0.5);
+ this.ignoreAnchorPointForPosition(true);
+
+ if (arrayOfItems) {
+ for (var i = 0; i < arrayOfItems.length; i++)
+ this.addChild(arrayOfItems[i], i);
+ }
+
+ this._selectedItem = null;
+ this._state = cc.MENU_STATE_WAITING;
+
+ // enable cascade color and opacity on menus
+ this.cascadeColor = true;
+ this.cascadeOpacity = true;
+
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * add a child for cc.Menu
+ * @param {cc.Node} child
+ * @param {Number|Null} [zOrder=] zOrder for the child
+ * @param {Number|Null} [tag=] tag for the child
+ */
+ addChild: function (child, zOrder, tag) {
+ if (!(child instanceof cc.MenuItem))
+ throw new Error("cc.Menu.addChild() : Menu only supports MenuItem objects as children");
+ cc.Layer.prototype.addChild.call(this, child, zOrder, tag);
+ },
+
+ updateAlign: function () {
+ switch (this._align) {
+ case 'vertically':
+ this.alignItemsVertically();
+ break;
+ case 'horizontally':
+ this.alignItemsHorizontally();
+ break;
+ }
+ },
+
+ /**
+ * align items vertically with default padding
+ */
+ alignItemsVertically: function () {
+ this.alignItemsVerticallyWithPadding(cc.DEFAULT_PADDING);
+ },
+
+ /**
+ * align items vertically with specified padding
+ * @param {Number} padding
+ */
+ alignItemsVerticallyWithPadding: function (padding) {
+ this._align = 'vertically';
+ var height = -padding, locChildren = this._children, len, i, locScaleY, locHeight, locChild;
+ if (locChildren && locChildren.length > 0) {
+ for (i = 0, len = locChildren.length; i < len; i++)
+ height += locChildren[i].height * locChildren[i].scaleY + padding;
+
+ var y = height / 2.0;
+
+ for (i = 0, len = locChildren.length; i < len; i++) {
+ locChild = locChildren[i];
+ locHeight = locChild.height;
+ locScaleY = locChild.scaleY;
+ locChild.setPosition(0, y - locHeight * locScaleY / 2);
+ y -= locHeight * locScaleY + padding;
+ }
+ }
+ },
+
+ /**
+ * align items horizontally with default padding
+ */
+ alignItemsHorizontally: function () {
+ this.alignItemsHorizontallyWithPadding(cc.DEFAULT_PADDING);
+ },
+
+ /**
+ * align items horizontally with specified padding
+ * @param {Number} padding
+ */
+ alignItemsHorizontallyWithPadding: function (padding) {
+ this._align = 'horizontally';
+ var width = -padding, locChildren = this._children, i, len, locScaleX, locWidth, locChild;
+ if (locChildren && locChildren.length > 0) {
+ for (i = 0, len = locChildren.length; i < len; i++)
+ width += locChildren[i].width * locChildren[i].scaleX + padding;
+
+ var x = -width / 2.0;
+
+ for (i = 0, len = locChildren.length; i < len; i++) {
+ locChild = locChildren[i];
+ locScaleX = locChild.scaleX;
+ locWidth = locChildren[i].width;
+ locChild.setPosition(x + locWidth * locScaleX / 2, 0);
+ x += locWidth * locScaleX + padding;
+ }
+ }
+ },
+
+ /**
+ * align items in columns
+ * @example
+ * // Example
+ * menu.alignItemsInColumns(3,2,3)// this will create 3 columns, with 3 items for first column, 2 items for second and 3 for third
+ *
+ * menu.alignItemsInColumns(3,3)//this creates 2 columns, each have 3 items
+ */
+ alignItemsInColumns: function (/*Multiple Arguments*/) {
+ if ((arguments.length > 0) && (arguments[arguments.length - 1] == null))
+ cc.log("parameters should not be ending with null in Javascript");
+
+ var i, rows = [];
+ for (i = 0; i < arguments.length; i++) {
+ rows.push(arguments[i]);
+ }
+ var height = -5;
+ var row = 0;
+ var rowHeight = 0;
+ var columnsOccupied = 0;
+ var rowColumns, tmp, len;
+ var locChildren = this._children;
+ if (locChildren && locChildren.length > 0) {
+ for (i = 0, len = locChildren.length; i < len; i++) {
+ if (row >= rows.length)
+ continue;
+
+ rowColumns = rows[row];
+ // can not have zero columns on a row
+ if (!rowColumns)
+ continue;
+
+ tmp = locChildren[i].height;
+ rowHeight = ((rowHeight >= tmp || isNaN(tmp)) ? rowHeight : tmp);
+
+ ++columnsOccupied;
+ if (columnsOccupied >= rowColumns) {
+ height += rowHeight + 5;
+
+ columnsOccupied = 0;
+ rowHeight = 0;
+ ++row;
+ }
+ }
+ }
+ // check if too many rows/columns for available menu items
+ //cc.assert(!columnsOccupied, ""); //?
+ var winSize = cc.director.getWinSize();
+
+ row = 0;
+ rowHeight = 0;
+ rowColumns = 0;
+ var w = 0.0;
+ var x = 0.0;
+ var y = (height / 2);
+
+ if (locChildren && locChildren.length > 0) {
+ for (i = 0, len = locChildren.length; i < len; i++) {
+ var child = locChildren[i];
+ if (rowColumns === 0) {
+ rowColumns = rows[row];
+ w = winSize.width / (1 + rowColumns);
+ x = w;
+ }
+
+ tmp = child._getHeight();
+ rowHeight = ((rowHeight >= tmp || isNaN(tmp)) ? rowHeight : tmp);
+ child.setPosition(x - winSize.width / 2, y - tmp / 2);
+
+ x += w;
+ ++columnsOccupied;
+
+ if (columnsOccupied >= rowColumns) {
+ y -= rowHeight + 5;
+ columnsOccupied = 0;
+ rowColumns = 0;
+ rowHeight = 0;
+ ++row;
+ }
+ }
+ }
+ },
+ /**
+ * align menu items in rows
+ * @param {Number}
+ * @example
+ * // Example
+ * menu.alignItemsInRows(5,3)//this will align items to 2 rows, first row with 5 items, second row with 3
+ *
+ * menu.alignItemsInRows(4,4,4,4)//this creates 4 rows each have 4 items
+ */
+ alignItemsInRows: function (/*Multiple arguments*/) {
+ if ((arguments.length > 0) && (arguments[arguments.length - 1] == null))
+ cc.log("parameters should not be ending with null in Javascript");
+ var i, columns = [];
+ for (i = 0; i < arguments.length; i++) {
+ columns.push(arguments[i]);
+ }
+ var columnWidths = [];
+ var columnHeights = [];
+
+ var width = -10;
+ var columnHeight = -5;
+ var column = 0;
+ var columnWidth = 0;
+ var rowsOccupied = 0;
+ var columnRows, child, len, tmp;
+
+ var locChildren = this._children;
+ if (locChildren && locChildren.length > 0) {
+ for (i = 0, len = locChildren.length; i < len; i++) {
+ child = locChildren[i];
+ // check if too many menu items for the amount of rows/columns
+ if (column >= columns.length)
+ continue;
+
+ columnRows = columns[column];
+ // can't have zero rows on a column
+ if (!columnRows)
+ continue;
+
+ // columnWidth = fmaxf(columnWidth, [item contentSize].width);
+ tmp = child.width;
+ columnWidth = ((columnWidth >= tmp || isNaN(tmp)) ? columnWidth : tmp);
+
+ columnHeight += (child.height + 5);
+ ++rowsOccupied;
+
+ if (rowsOccupied >= columnRows) {
+ columnWidths.push(columnWidth);
+ columnHeights.push(columnHeight);
+ width += columnWidth + 10;
+
+ rowsOccupied = 0;
+ columnWidth = 0;
+ columnHeight = -5;
+ ++column;
+ }
+ }
+ }
+ // check if too many rows/columns for available menu items.
+ //cc.assert(!rowsOccupied, "");
+ var winSize = cc.director.getWinSize();
+
+ column = 0;
+ columnWidth = 0;
+ columnRows = 0;
+ var x = -width / 2;
+ var y = 0.0;
+
+ if (locChildren && locChildren.length > 0) {
+ for (i = 0, len = locChildren.length; i < len; i++) {
+ child = locChildren[i];
+ if (columnRows === 0) {
+ columnRows = columns[column];
+ y = columnHeights[column];
+ }
+
+ // columnWidth = fmaxf(columnWidth, [item contentSize].width);
+ tmp = child._getWidth();
+ columnWidth = ((columnWidth >= tmp || isNaN(tmp)) ? columnWidth : tmp);
+
+ child.setPosition(x + columnWidths[column] / 2, y - winSize.height / 2);
+
+ y -= child.height + 10;
+ ++rowsOccupied;
+
+ if (rowsOccupied >= columnRows) {
+ x += columnWidth + 5;
+ rowsOccupied = 0;
+ columnRows = 0;
+ columnWidth = 0;
+ ++column;
+ }
+ }
+ }
+ },
+
+ /**
+ * remove a child from cc.Menu
+ * @param {cc.Node} child the child you want to remove
+ * @param {boolean} cleanup whether to cleanup
+ */
+ removeChild: function (child, cleanup) {
+ if (child == null)
+ return;
+ if (!(child instanceof cc.MenuItem)) {
+ cc.log("cc.Menu.removeChild():Menu only supports MenuItem objects as children");
+ return;
+ }
+
+ if (this._selectedItem === child)
+ this._selectedItem = null;
+ cc.Node.prototype.removeChild.call(this, child, cleanup);
+ },
+
+ _onTouchBegan: function (touch, event) {
+ var target = event.getCurrentTarget();
+ if (target._state !== cc.MENU_STATE_WAITING || !target._visible || !target.enabled)
+ return false;
+
+ for (var c = target.parent; c != null; c = c.parent) {
+ if (!c.isVisible())
+ return false;
+ }
+
+ target._selectedItem = target._itemForTouch(touch);
+ if (target._selectedItem) {
+ target._state = cc.MENU_STATE_TRACKING_TOUCH;
+ target._selectedItem.selected();
+ target._selectedItem.setNodeDirty();
+ return true;
+ }
+ return false;
+ },
+
+ _onTouchEnded: function (touch, event) {
+ var target = event.getCurrentTarget();
+ if (target._state !== cc.MENU_STATE_TRACKING_TOUCH) {
+ cc.log("cc.Menu.onTouchEnded(): invalid state");
+ return;
+ }
+ if (target._selectedItem) {
+ target._selectedItem.unselected();
+ target._selectedItem.setNodeDirty();
+ target._selectedItem.activate();
+ }
+ target._state = cc.MENU_STATE_WAITING;
+ },
+
+ _onTouchCancelled: function (touch, event) {
+ var target = event.getCurrentTarget();
+ if (target._state !== cc.MENU_STATE_TRACKING_TOUCH) {
+ cc.log("cc.Menu.onTouchCancelled(): invalid state");
+ return;
+ }
+ if (target._selectedItem) {
+ target._selectedItem.unselected();
+ target._selectedItem.setNodeDirty();
+ }
+ target._state = cc.MENU_STATE_WAITING;
+ },
+
+ _onTouchMoved: function (touch, event) {
+ var target = event.getCurrentTarget();
+ if (target._state !== cc.MENU_STATE_TRACKING_TOUCH) {
+ cc.log("cc.Menu.onTouchMoved(): invalid state");
+ return;
+ }
+ var currentItem = target._itemForTouch(touch);
+ if (currentItem !== target._selectedItem) {
+ if (target._selectedItem) {
+ target._selectedItem.unselected();
+ target._selectedItem.setNodeDirty();
+ }
+ target._selectedItem = currentItem;
+ if (target._selectedItem) {
+ target._selectedItem.selected();
+ target._selectedItem.setNodeDirty();
+ }
+ }
+ },
+
+ /**
+ *
+ * callback that is called every time the cc.Menu leaves the 'stage'.
+ * If the cc.Menu leaves the 'stage' with a transition, this callback is called when the transition finishes.
+ * During onExit you can't access a sibling node.
+ * If you override onExit, you shall call its parent's onExit with this._super().
+ *
+ */
+ onExit: function () {
+ if (this._state === cc.MENU_STATE_TRACKING_TOUCH) {
+ if (this._selectedItem) {
+ this._selectedItem.unselected();
+ this._selectedItem = null;
+ }
+ this._state = cc.MENU_STATE_WAITING;
+ }
+ cc.Node.prototype.onExit.call(this);
+ },
+ /**
+ * only use for jsbinding
+ * @param value
+ */
+ setOpacityModifyRGB: function (value) {
+ },
+ /**
+ * only use for jsbinding
+ * @returns {boolean}
+ */
+ isOpacityModifyRGB: function () {
+ return false;
+ },
+
+ _itemForTouch: function (touch) {
+ var touchLocation = touch.getLocation();
+ var itemChildren = this._children, locItemChild;
+ if (itemChildren && itemChildren.length > 0) {
+ for (var i = itemChildren.length - 1; i >= 0; i--) {
+ locItemChild = itemChildren[i];
+ if (locItemChild.isVisible() && locItemChild.isEnabled()) {
+ var local = locItemChild.convertToNodeSpace(touchLocation);
+ var r = locItemChild.rect();
+ r.x = 0;
+ r.y = 0;
+ if (cc.rectContainsPoint(r, local))
+ return locItemChild;
+ }
+ }
+ }
+ return null;
+ }
+});
+
+var _p = cc.Menu.prototype;
+
+// Extended properties
+/** @expose */
+_p.enabled;
+
+/**
+ * create a new menu
+ * @deprecated since v3.0, please use new cc.Menu(menuitem1, menuitem2, menuitem3) to create a new menu
+ * @param {...cc.MenuItem|null} menuItems
+ * todo: need to use new
+ * @return {cc.Menu}
+ */
+cc.Menu.create = function (menuItems) {
+ var argc = arguments.length;
+ if ((argc > 0) && (arguments[argc - 1] == null))
+ cc.log("parameters should not be ending with null in Javascript");
+
+ var ret;
+ if (argc === 0)
+ ret = new cc.Menu();
+ else if (argc === 1)
+ ret = new cc.Menu(menuItems);
+ else
+ ret = new cc.Menu(Array.prototype.slice.call(arguments, 0));
+ return ret;
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/menus/CCMenuItem.js b/frameworks/cocos2d-html5/cocos2d/menus/CCMenuItem.js
new file mode 100644
index 0000000..de25bee
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/menus/CCMenuItem.js
@@ -0,0 +1,1371 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc._globalFontSize = cc.ITEM_SIZE;
+cc._globalFontName = "Arial";
+cc._globalFontNameRelease = false;
+
+/**
+ * Subclass cc.MenuItem (or any subclass) to create your custom cc.MenuItem objects.
+ * @class
+ * @extends cc.Node
+ * @param {function|String} callback
+ * @param {cc.Node} target
+ */
+cc.MenuItem = cc.Node.extend(/** @lends cc.MenuItem# */{
+ _enabled: false,
+ _target: null,
+ _callback: null,
+ _isSelected: false,
+ _className: "MenuItem",
+
+ /**
+ * Constructor of cc.MenuItem
+ * @param {function|String} callback
+ * @param {cc.Node} target
+ */
+ ctor: function (callback, target) {
+ var nodeP = cc.Node.prototype;
+ nodeP.ctor.call(this);
+ this._target = null;
+ this._callback = null;
+ this._isSelected = false;
+ this._enabled = false;
+
+ nodeP.setAnchorPoint.call(this, 0.5, 0.5);
+ this._target = target || null;
+ this._callback = callback || null;
+ if (this._callback) {
+ this._enabled = true;
+ }
+ },
+
+ /**
+ * return whether MenuItem is selected
+ * @return {Boolean}
+ */
+ isSelected: function () {
+ return this._isSelected;
+ },
+ /**
+ * only use for jsbinding
+ * @param value
+ */
+ setOpacityModifyRGB: function (value) {
+ },
+ /**
+ * only use for jsbinding
+ * @returns {boolean}
+ */
+ isOpacityModifyRGB: function () {
+ return false;
+ },
+
+ /**
+ * set the target/selector of the menu item
+ * @param {function|String} selector
+ * @param {cc.Node} rec
+ * @deprecated since v3.0
+ */
+ setTarget: function (selector, rec) {
+ this._target = rec;
+ this._callback = selector;
+ },
+
+ /**
+ * return whether MenuItem is Enabled
+ * @return {Boolean}
+ */
+ isEnabled: function () {
+ return this._enabled;
+ },
+
+ /**
+ * set enable value of MenuItem
+ * @param {Boolean} enable
+ */
+ setEnabled: function (enable) {
+ this._enabled = enable;
+ },
+
+ /**
+ * initializes a cc.MenuItem with callback
+ * @param {function|String} callback
+ * @param {cc.Node} target
+ * @return {Boolean}
+ */
+ initWithCallback: function (callback, target) {
+ this.anchorX = 0.5;
+ this.anchorY = 0.5;
+ this._target = target;
+ this._callback = callback;
+ this._enabled = true;
+ this._isSelected = false;
+ return true;
+ },
+
+ /**
+ * return rect value of cc.MenuItem
+ * @return {cc.Rect}
+ */
+ rect: function () {
+ var locPosition = this._position, locContentSize = this._contentSize, locAnchorPoint = this._anchorPoint;
+ return cc.rect(locPosition.x - locContentSize.width * locAnchorPoint.x,
+ locPosition.y - locContentSize.height * locAnchorPoint.y,
+ locContentSize.width, locContentSize.height);
+ },
+
+ /**
+ * set the cc.MenuItem selected same as setIsSelected(true)
+ */
+ selected: function () {
+ this._isSelected = true;
+ },
+
+ /**
+ * set the cc.MenuItem unselected same as setIsSelected(false)
+ */
+ unselected: function () {
+ this._isSelected = false;
+ },
+
+ /**
+ * set the callback to the menu item
+ * @param {function|String} callback
+ * @param {cc.Node} target
+ */
+ setCallback: function (callback, target) {
+ this._target = target;
+ this._callback = callback;
+ },
+
+ /**
+ * call the selector with target
+ */
+ activate: function () {
+ if (this._enabled) {
+ var locTarget = this._target, locCallback = this._callback;
+ if (!locCallback)
+ return;
+ if (locTarget && cc.isString(locCallback)) {
+ locTarget[locCallback](this);
+ } else if (locTarget && cc.isFunction(locCallback)) {
+ locCallback.call(locTarget, this);
+ } else
+ locCallback(this);
+ }
+ }
+});
+
+var _p = cc.MenuItem.prototype;
+
+// Extended properties
+/** @expose */
+_p.enabled;
+cc.defineGetterSetter(_p, "enabled", _p.isEnabled, _p.setEnabled);
+
+/**
+ * creates an empty menu item with target and callback
+ * Not recommended to use the base class, should use more defined menu item classes
+ * @deprecated since v3.0, please use new cc.MenuItem(callback,target) instead
+ * @param {function|String} callback callback
+ * @param {cc.Node} target
+ * @return {cc.MenuItem}
+ */
+cc.MenuItem.create = function (callback, target) {
+ return new cc.MenuItem(callback, target);
+};
+
+/**
+ * Any cc.Node that supports the cc.LabelProtocol protocol can be added.
+ * Supported nodes:
+ * - cc.BitmapFontAtlas
+ * - cc.LabelAtlas
+ * - cc.LabelTTF
+ * @class
+ * @extends cc.MenuItem
+ * @param {cc.Node} label
+ * @param {function|String} selector
+ * @param {cc.Node} target
+ * @example
+ * var menuitemLabel = new cc.MenuItemLabel(label,selector,target);
+ *
+ * @property {String} string - Content string of label item
+ * @property {cc.Node} label - Label of label item
+ * @property {cc.Color} disabledColor - Color of label when it's disabled
+ */
+cc.MenuItemLabel = cc.MenuItem.extend(/** @lends cc.MenuItemLabel# */{
+ _disabledColor: null,
+ _label: null,
+ _originalScale: 0,
+ _colorBackup: null,
+
+ /**
+ * Constructor of cc.MenuItemLabel
+ * @param {cc.Node} label
+ * @param {function|String} selector
+ * @param {cc.Node} target
+ */
+ ctor: function (label, selector, target) {
+ cc.MenuItem.prototype.ctor.call(this, selector, target);
+ this._disabledColor = null;
+ this._label = null;
+ this._colorBackup = null;
+
+ if (label) {
+ this._originalScale = 1.0;
+ this._colorBackup = cc.color.WHITE;
+ this._disabledColor = cc.color(126, 126, 126);
+ this.setLabel(label);
+
+ if (label.textureLoaded && !label.textureLoaded()) {
+ label.addEventListener("load", function (sender) {
+ this.width = sender.width;
+ this.height = sender.height;
+ if (this.parent instanceof cc.Menu) {
+ this.parent.updateAlign();
+ }
+ }, this);
+ }
+
+ this.setCascadeColorEnabled(true);
+ this.setCascadeOpacityEnabled(true);
+ }
+ },
+
+ /**
+ * return the disable color for this cc.MenuItemLabel
+ * @return {cc.Color}
+ */
+ getDisabledColor: function () {
+ return this._disabledColor;
+ },
+
+ /**
+ * set the disable color for this cc.MenuItemLabel
+ * @param {cc.Color} color
+ */
+ setDisabledColor: function (color) {
+ this._disabledColor = color;
+ },
+
+ /**
+ * return label of cc.MenuItemLabel
+ * @return {cc.Node}
+ */
+ getLabel: function () {
+ return this._label;
+ },
+
+ /**
+ * set a label for cc.MenuItemLabel
+ * @param {cc.Node} label
+ */
+ setLabel: function (label) {
+ if (label) {
+ this.addChild(label);
+ label.anchorX = 0;
+ label.anchorY = 0;
+ this.width = label.width;
+ this.height = label.height;
+ label.setCascadeColorEnabled(true);
+ }
+
+ if (this._label) {
+ this.removeChild(this._label, true);
+ }
+
+ this._label = label;
+ },
+
+ /**
+ * set enable value to cc.MenuItemLabel
+ * @param {Boolean} enabled
+ */
+ setEnabled: function (enabled) {
+ if (this._enabled !== enabled) {
+ if (!enabled) {
+ this._colorBackup = this.color;
+ this.setColor(this._disabledColor);
+ } else {
+ this.setColor(this._colorBackup);
+ }
+ }
+ cc.MenuItem.prototype.setEnabled.call(this, enabled);
+ },
+
+ /**
+ * initializes a cc.MenuItemLabel with a label
+ * @param {cc.Node} label
+ * @param {function|String} selector
+ * @param {cc.Node} target
+ * @return {Boolean}
+ */
+ initWithLabel: function (label, selector, target) {
+ this.initWithCallback(selector, target);
+ this._originalScale = 1.0;
+ this._colorBackup = cc.color.WHITE;
+ this._disabledColor = cc.color(126, 126, 126);
+ this.setLabel(label);
+
+ this.setCascadeColorEnabled(true);
+ this.setCascadeOpacityEnabled(true);
+
+ return true;
+ },
+
+ /**
+ * set the string for cc.MenuItemLabel
+ * @param {String} label
+ */
+ setString: function (label) {
+ this._label.string = label;
+ this.width = this._label.width;
+ this.height = this._label.height;
+ },
+ /**
+ * return the string of cc.MenuItemLabel
+ * @returns {String}
+ */
+ getString: function () {
+ return this._label.string;
+ },
+
+ /**
+ * activate the menu item
+ */
+ activate: function () {
+ if (this._enabled) {
+ this.stopAllActions();
+ this.scale = this._originalScale;
+ cc.MenuItem.prototype.activate.call(this);
+ }
+ },
+
+ /**
+ * menu item is selected (runs callback)
+ */
+ selected: function () {
+ if (this._enabled) {
+ cc.MenuItem.prototype.selected.call(this);
+
+ var action = this.getActionByTag(cc.ZOOM_ACTION_TAG);
+ if (action)
+ this.stopAction(action);
+ else
+ this._originalScale = this.scale;
+
+ var zoomAction = cc.scaleTo(0.1, this._originalScale * 1.2);
+ zoomAction.setTag(cc.ZOOM_ACTION_TAG);
+ this.runAction(zoomAction);
+ }
+ },
+
+ /**
+ * menu item goes back to unselected state
+ */
+ unselected: function () {
+ if (this._enabled) {
+ cc.MenuItem.prototype.unselected.call(this);
+ this.stopActionByTag(cc.ZOOM_ACTION_TAG);
+ var zoomAction = cc.scaleTo(0.1, this._originalScale);
+ zoomAction.setTag(cc.ZOOM_ACTION_TAG);
+ this.runAction(zoomAction);
+ }
+ }
+});
+
+var _p = cc.MenuItemLabel.prototype;
+
+// Extended properties
+/** @expose */
+_p.string;
+cc.defineGetterSetter(_p, "string", _p.getString, _p.setString);
+/** @expose */
+_p.disabledColor;
+cc.defineGetterSetter(_p, "disabledColor", _p.getDisabledColor, _p.setDisabledColor);
+/** @expose */
+_p.label;
+cc.defineGetterSetter(_p, "label", _p.getLabel, _p.setLabel);
+
+
+/**
+ * @deprecated since v3.0 ,please use new cc.MenuItemLabel(label,selector,target) instead
+ * @param {cc.Node} label
+ * @param {function|String|Null} [selector=]
+ * @param {cc.Node|Null} [target=]
+ * @return {cc.MenuItemLabel}
+ */
+cc.MenuItemLabel.create = function (label, selector, target) {
+ return new cc.MenuItemLabel(label, selector, target);
+};
+
+/**
+ * Helper class that creates a MenuItemLabel class with a LabelAtlas
+ * @class
+ * @extends cc.MenuItemLabel
+ * @param {String} value
+ * @param {String} charMapFile
+ * @param {Number} itemWidth
+ * @param {Number} itemHeight
+ * @param {String} startCharMap a single character
+ * @param {function|String|Null} callback
+ * @param {cc.Node|Null} target
+ * @example
+ * var menuItem = new cc.MenuItemAtlasFont(param1,param2...);
+ */
+cc.MenuItemAtlasFont = cc.MenuItemLabel.extend(/** @lends cc.MenuItemAtlasFont# */{
+
+ /**
+ * the contructor of cc.MenuItemAtlasFont
+ * @param {String} value
+ * @param {String} charMapFile
+ * @param {Number} itemWidth
+ * @param {Number} itemHeight
+ * @param {String} startCharMap a single character
+ * @param {function|String|Null} callback
+ * @param {cc.Node|Null} target
+ */
+ ctor: function (value, charMapFile, itemWidth, itemHeight, startCharMap, callback, target) {
+ var label;
+ if (value && value.length > 0) {
+ label = new cc.LabelAtlas(value, charMapFile, itemWidth, itemHeight, startCharMap);
+ }
+
+ cc.MenuItemLabel.prototype.ctor.call(this, label, callback, target);
+ },
+
+ /**
+ * initializes a cc.MenuItemAtlasFont with string
+ * @param {String} value
+ * @param {String} charMapFile
+ * @param {Number} itemWidth
+ * @param {Number} itemHeight
+ * @param {String} startCharMap a single character
+ * @param {function|String|Null} callback
+ * @param {cc.Node|Null} target
+ * @return {Boolean}
+ */
+ initWithString: function (value, charMapFile, itemWidth, itemHeight, startCharMap, callback, target) {
+ if (!value || value.length === 0)
+ throw new Error("cc.MenuItemAtlasFont.initWithString(): value should be non-null and its length should be greater than 0");
+
+ var label = new cc.LabelAtlas();
+ label.initWithString(value, charMapFile, itemWidth, itemHeight, startCharMap);
+ if (this.initWithLabel(label, callback, target)) {
+ // do something ?
+ }
+ return true;
+ }
+});
+
+/**
+ * create menu item from string with font
+ * @deprecated since v3.0 ,please use new cc.MenuItemAtlasFont() instead.
+ * @param {String} value the text to display
+ * @param {String} charMapFile the character map file
+ * @param {Number} itemWidth
+ * @param {Number} itemHeight
+ * @param {String} startCharMap a single character
+ * @param {function|String|Null} [callback=null]
+ * @param {cc.Node|Null} [target=]
+ * @return {cc.MenuItemAtlasFont}
+ */
+cc.MenuItemAtlasFont.create = function (value, charMapFile, itemWidth, itemHeight, startCharMap, callback, target) {
+ return new cc.MenuItemAtlasFont(value, charMapFile, itemWidth, itemHeight, startCharMap, callback, target);
+};
+
+/**
+ * Helper class that creates a CCMenuItemLabel class with a Label
+ * @class
+ * @extends cc.MenuItemLabel
+ * @param {String} value text for the menu item
+ * @param {function|String} callback
+ * @param {cc.Node} target
+ * @example
+ * var menuItem = new cc.MenuItemFont(value, callback, target);
+ *
+ * @property {Number} fontSize - Font size of font item
+ * @property {String} fontName - Font name of font item
+ */
+cc.MenuItemFont = cc.MenuItemLabel.extend(/** @lends cc.MenuItemFont# */{
+ _fontSize: null,
+ _fontName: null,
+
+ /**
+ * Constructor of cc.MenuItemFont
+ * @param {String} value text for the menu item
+ * @param {function|String} callback
+ * @param {cc.Node} target
+ */
+ ctor: function (value, callback, target) {
+ var label;
+ if (value && value.length > 0) {
+ this._fontName = cc._globalFontName;
+ this._fontSize = cc._globalFontSize;
+ label = new cc.LabelTTF(value, this._fontName, this._fontSize);
+ }
+ else {
+ this._fontSize = 0;
+ this._fontName = "";
+ }
+
+ cc.MenuItemLabel.prototype.ctor.call(this, label, callback, target);
+ },
+
+ /**
+ * initializes cc.MenuItemFont with string
+ * @param {String} value text for the menu item
+ * @param {function|String} callback
+ * @param {cc.Node} target
+ * @return {Boolean}
+ */
+ initWithString: function (value, callback, target) {
+ if (!value || value.length === 0)
+ throw new Error("Value should be non-null and its length should be greater than 0");
+
+ this._fontName = cc._globalFontName;
+ this._fontSize = cc._globalFontSize;
+
+ var label = new cc.LabelTTF(value, this._fontName, this._fontSize);
+ if (this.initWithLabel(label, callback, target)) {
+ // do something ?
+ }
+ return true;
+ },
+
+ /**
+ * set the font size for cc.MenuItemFont
+ * @param {Number} s
+ */
+ setFontSize: function (s) {
+ this._fontSize = s;
+ this._recreateLabel();
+ },
+
+ /**
+ *return the font size of cc.MenuItemFont
+ * @return {Number}
+ */
+ getFontSize: function () {
+ return this._fontSize;
+ },
+
+ /**
+ * set the font name for cc.MenuItemFont
+ * @param {String} name
+ */
+ setFontName: function (name) {
+ this._fontName = name;
+ this._recreateLabel();
+ },
+
+ /**
+ * return the font name for cc.MenuItemFont
+ * @return {String}
+ */
+ getFontName: function () {
+ return this._fontName;
+ },
+
+ _recreateLabel: function () {
+ var label = new cc.LabelTTF(this._label.string, this._fontName, this._fontSize);
+ this.setLabel(label);
+ }
+});
+
+/**
+ * a shared function to set the fontSize for menuitem font
+ * @param {Number} fontSize
+ */
+cc.MenuItemFont.setFontSize = function (fontSize) {
+ cc._globalFontSize = fontSize;
+};
+
+/**
+ * a shared function to get the font size for menuitem font
+ * @return {Number}
+ */
+cc.MenuItemFont.fontSize = function () {
+ return cc._globalFontSize;
+};
+
+/**
+ * a shared function to set the fontsize for menuitem font
+ * @param name
+ */
+cc.MenuItemFont.setFontName = function (name) {
+ if (cc._globalFontNameRelease) {
+ cc._globalFontName = '';
+ }
+ cc._globalFontName = name;
+ cc._globalFontNameRelease = true;
+};
+
+var _p = cc.MenuItemFont.prototype;
+
+// Extended properties
+/** @expose */
+_p.fontSize;
+cc.defineGetterSetter(_p, "fontSize", _p.getFontSize, _p.setFontSize);
+/** @expose */
+_p.fontName;
+cc.defineGetterSetter(_p, "fontName", _p.getFontName, _p.setFontName);
+
+
+/**
+ * a shared function to get the font name for menuitem font
+ * @return {String}
+ */
+cc.MenuItemFont.fontName = function () {
+ return cc._globalFontName;
+};
+
+/**
+ * create a menu item from string
+ * @deprecated since v3.0, please use new construction instead
+ * @param {String} value the text to display
+ * @param {String|function|Null} callback the callback to run, either in function name or pass in the actual function
+ * @param {cc.Node|Null} target the target to run callback
+ * @return {cc.MenuItemFont}
+ */
+cc.MenuItemFont.create = function (value, callback, target) {
+ return new cc.MenuItemFont(value, callback, target);
+};
+
+
+/**
+ * CCMenuItemSprite accepts CCNode objects as items.
+ * The images has 3 different states:
+ * - unselected image
+ * - selected image
+ * - disabled image
+ * @class
+ * @extends cc.MenuItem
+ * @param {Image|Null} normalSprite normal state image
+ * @param {Image|Null} selectedSprite selected state image
+ * @param {Image|cc.Node|Null} three disabled state image OR target node
+ * @param {String|function|cc.Node|Null} four callback function name in string or actual function, OR target Node
+ * @param {String|function|Null} five callback function name in string or actual function
+ *
+ * @example
+ * var item = new cc.MenuItemSprite(normalImage)//create a menu item from a sprite with no functionality
+ * var item = new cc.MenuItemSprite(normalImage, selectedImage)//create a menu Item, nothing will happen when clicked
+ * var item = new cc.MenuItemSprite(normalImage, SelectedImage, disabledImage)//same above, but with disabled state image
+ * var item = new cc.MenuItemSprite(normalImage, SelectedImage, 'callback', targetNode)//create a menu item, when clicked runs targetNode.callback()
+ * var item = new cc.MenuItemSprite(normalImage, SelectedImage, disabledImage, targetNode.callback, targetNode)
+ * //same as above, but with disabled image, and passing in callback function
+ *
+ * @property {cc.Sprite} normalImage - Sprite in normal state
+ * @property {cc.Sprite} selectedImage - Sprite in selected state
+ * @property {cc.Sprite} disabledImage - Sprite in disabled state
+ */
+cc.MenuItemSprite = cc.MenuItem.extend(/** @lends cc.MenuItemSprite# */{
+ _normalImage: null,
+ _selectedImage: null,
+ _disabledImage: null,
+
+ /**
+ * Constructor of cc.MenuItemSprite
+ * @param {Image|Null} normalSprite normal state image
+ * @param {Image|Null} selectedSprite selected state image
+ * @param {Image|cc.Node|Null} three disabled state image OR target node
+ * @param {String|function|cc.Node|Null} four callback function name in string or actual function, OR target Node
+ * @param {String|function|Null} five callback function name in string or actual function
+ */
+ ctor: function (normalSprite, selectedSprite, three, four, five) {
+ cc.MenuItem.prototype.ctor.call(this);
+ this._normalImage = null;
+ this._selectedImage = null;
+ this._disabledImage = null;
+ this._loader = new cc.Sprite.LoadManager();
+
+ if (normalSprite !== undefined) {
+ //normalSprite = normalSprite;
+ selectedSprite = selectedSprite || null;
+ var disabledImage, target, callback;
+ //when you send 4 arguments, five is undefined
+ if (five !== undefined) {
+ disabledImage = three;
+ callback = four;
+ target = five;
+ } else if (four !== undefined && cc.isFunction(four)) {
+ disabledImage = three;
+ callback = four;
+ } else if (four !== undefined && cc.isFunction(three)) {
+ target = four;
+ callback = three;
+ disabledImage = null;
+ } else if (three === undefined) {
+ disabledImage = null;
+ }
+
+ this._loader.clear();
+ if (normalSprite.textureLoaded && !normalSprite.textureLoaded()) {
+ this._loader.once(normalSprite, function () {
+ this.initWithNormalSprite(normalSprite, selectedSprite, disabledImage, callback, target);
+ }, this);
+ return false;
+ }
+
+ this.initWithNormalSprite(normalSprite, selectedSprite, disabledImage, callback, target);
+ return true;
+ }
+ },
+
+ /**
+ * return the normal status image(cc.Sprite)
+ * @return {cc.Sprite}
+ */
+ getNormalImage: function () {
+ return this._normalImage;
+ },
+
+ /**
+ * set the normal status image(cc.Sprite)
+ * @param {cc.Sprite} normalImage
+ */
+ setNormalImage: function (normalImage) {
+ if (this._normalImage === normalImage) {
+ return;
+ }
+ if (normalImage) {
+ this.addChild(normalImage, 0, cc.NORMAL_TAG);
+ normalImage.anchorX = 0;
+ normalImage.anchorY = 0;
+ }
+ if (this._normalImage) {
+ this.removeChild(this._normalImage, true);
+ }
+
+ this._normalImage = normalImage;
+ if(!this._normalImage)
+ return;
+
+ this.width = this._normalImage.width;
+ this.height = this._normalImage.height;
+ this._updateImagesVisibility();
+
+ if (normalImage.textureLoaded && !normalImage.textureLoaded()) {
+ normalImage.addEventListener("load", function (sender) {
+ this.width = sender.width;
+ this.height = sender.height;
+ if (this.parent instanceof cc.Menu) {
+ this.parent.updateAlign();
+ }
+ }, this);
+ }
+ },
+
+ /**
+ * return the selected status image(cc.Sprite) of cc.MenuItemSprite
+ * @return {cc.Sprite}
+ */
+ getSelectedImage: function () {
+ return this._selectedImage;
+ },
+
+ /**
+ * set the selected status image(cc.Sprite)
+ * @param {cc.Sprite} selectedImage
+ */
+ setSelectedImage: function (selectedImage) {
+ if (this._selectedImage === selectedImage)
+ return;
+
+ if (selectedImage) {
+ this.addChild(selectedImage, 0, cc.SELECTED_TAG);
+ selectedImage.anchorX = 0;
+ selectedImage.anchorY = 0;
+ }
+
+ if (this._selectedImage) {
+ this.removeChild(this._selectedImage, true);
+ }
+
+ this._selectedImage = selectedImage;
+ this._updateImagesVisibility();
+ },
+
+ /**
+ * return the disabled status of cc.MenuItemSprite
+ * @return {cc.Sprite}
+ */
+ getDisabledImage: function () {
+ return this._disabledImage;
+ },
+
+ /**
+ * set the disabled status image(cc.Sprite)
+ * @param {cc.Sprite} disabledImage
+ */
+ setDisabledImage: function (disabledImage) {
+ if (this._disabledImage === disabledImage)
+ return;
+
+ if (disabledImage) {
+ this.addChild(disabledImage, 0, cc.DISABLE_TAG);
+ disabledImage.anchorX = 0;
+ disabledImage.anchorY = 0;
+ }
+
+ if (this._disabledImage)
+ this.removeChild(this._disabledImage, true);
+
+ this._disabledImage = disabledImage;
+ this._updateImagesVisibility();
+ },
+
+ /**
+ * initializes cc.MenuItemSprite with a cc.Sprite
+ * @param {cc.Node} normalSprite
+ * @param {cc.Node} selectedSprite
+ * @param {cc.Node} disabledSprite
+ * @param {function|String} callback
+ * @param {cc.Node} target
+ * @return {Boolean}
+ */
+ initWithNormalSprite: function (normalSprite, selectedSprite, disabledSprite, callback, target) {
+ this._loader.clear();
+ if (normalSprite.textureLoaded && !normalSprite.textureLoaded()) {
+ this._loader.once(normalSprite, function () {
+ this.initWithNormalSprite(normalSprite, selectedSprite, disabledSprite, callback, target);
+ }, this);
+ return false;
+ }
+ this.initWithCallback(callback, target);
+ this.setNormalImage(normalSprite);
+ this.setSelectedImage(selectedSprite);
+ this.setDisabledImage(disabledSprite);
+ var locNormalImage = this._normalImage;
+ if (locNormalImage) {
+ this.width = locNormalImage.width;
+ this.height = locNormalImage.height;
+ }
+ this.setCascadeColorEnabled(true);
+ this.setCascadeOpacityEnabled(true);
+ return true;
+ },
+
+ /**
+ * menu item is selected (runs callback)
+ */
+ selected: function () {
+ cc.MenuItem.prototype.selected.call(this);
+ if (this._normalImage) {
+ if (this._disabledImage)
+ this._disabledImage.visible = false;
+
+ if (this._selectedImage) {
+ this._normalImage.visible = false;
+ this._selectedImage.visible = true;
+ } else
+ this._normalImage.visible = true;
+ }
+ },
+
+ /**
+ * menu item goes back to unselected state
+ */
+ unselected: function () {
+ cc.MenuItem.prototype.unselected.call(this);
+ if (this._normalImage) {
+ this._normalImage.visible = true;
+
+ if (this._selectedImage)
+ this._selectedImage.visible = false;
+
+ if (this._disabledImage)
+ this._disabledImage.visible = false;
+ }
+ },
+
+ /**
+ * set cc.MenuItemSprite enable to receive the touch event
+ * @param {Boolean} bEnabled
+ */
+ setEnabled: function (bEnabled) {
+ if (this._enabled !== bEnabled) {
+ cc.MenuItem.prototype.setEnabled.call(this, bEnabled);
+ this._updateImagesVisibility();
+ }
+ },
+
+ _updateImagesVisibility: function () {
+ var locNormalImage = this._normalImage, locSelImage = this._selectedImage, locDisImage = this._disabledImage;
+ if (this._enabled) {
+ if (locNormalImage)
+ locNormalImage.visible = true;
+ if (locSelImage)
+ locSelImage.visible = false;
+ if (locDisImage)
+ locDisImage.visible = false;
+ } else {
+ if (locDisImage) {
+ if (locNormalImage)
+ locNormalImage.visible = false;
+ if (locSelImage)
+ locSelImage.visible = false;
+ if (locDisImage)
+ locDisImage.visible = true;
+ } else {
+ if (locNormalImage)
+ locNormalImage.visible = true;
+ if (locSelImage)
+ locSelImage.visible = false;
+ }
+ }
+ }
+});
+
+var _p = cc.MenuItemSprite.prototype;
+
+// Extended properties
+/** @expose */
+_p.normalImage;
+cc.defineGetterSetter(_p, "normalImage", _p.getNormalImage, _p.setNormalImage);
+/** @expose */
+_p.selectedImage;
+cc.defineGetterSetter(_p, "selectedImage", _p.getSelectedImage, _p.setSelectedImage);
+/** @expose */
+_p.disabledImage;
+cc.defineGetterSetter(_p, "disabledImage", _p.getDisabledImage, _p.setDisabledImage);
+
+/**
+ * create a menu item from sprite
+ * @deprecated since v3.0 please use new cc.MenuItemSprite(normalSprite, selectedSprite, three, four, five) instead
+ * @param {Image} normalSprite normal state image
+ * @param {Image|Null} selectedSprite selected state image
+ * @param {Image|cc.Node|Null} three disabled state image OR target node
+ * @param {String|function|cc.Node|Null} four callback function name in string or actual function, OR target Node
+ * @param {String|function|Null} five callback function name in string or actual function
+ * @return {cc.MenuItemSprite}
+ */
+cc.MenuItemSprite.create = function (normalSprite, selectedSprite, three, four, five) {
+ return new cc.MenuItemSprite(normalSprite, selectedSprite, three, four, five || undefined);
+};
+
+/**
+ * cc.MenuItemImage accepts images as items.
+ * The images has 3 different states:
+ * - unselected image
+ * - selected image
+ * - disabled image
+ *
+ * For best results try that all images are of the same size
+ * @class
+ * @extends cc.MenuItemSprite
+ * @param {string|null} normalImage
+ * @param {string|null} selectedImage
+ * @param {string|null} disabledImage
+ * @param {function|string|null} callback
+ * @param {cc.Node|null} target
+ * @example
+ * var menuItem = new cc.MenuItemImage(normalImage, selectedImage, three, four, five);
+ */
+cc.MenuItemImage = cc.MenuItemSprite.extend(/** @lends cc.MenuItemImage# */{
+
+ /**
+ * Constructor of cc.MenuItemImage
+ * @param {string|null} normalImage
+ * @param {string|null} selectedImage
+ * @param {string|null} disabledImage
+ * @param {function|string|null} callback
+ * @param {cc.Node|null} target
+ */
+ ctor: function (normalImage, selectedImage, three, four, five) {
+ var normalSprite = null,
+ selectedSprite = null,
+ disabledSprite = null,
+ callback = null,
+ target = null;
+
+ if (normalImage === undefined || normalImage === null) {
+ cc.MenuItemSprite.prototype.ctor.call(this);
+ }
+ else {
+ normalSprite = new cc.Sprite(normalImage);
+ selectedImage &&
+ (selectedSprite = new cc.Sprite(selectedImage));
+
+ if (four === undefined) {
+ callback = three;
+ }
+ else if (five === undefined) {
+ callback = three;
+ target = four;
+ }
+ else if (five) {
+ disabledSprite = new cc.Sprite(three);
+ callback = four;
+ target = five;
+ }
+ cc.MenuItemSprite.prototype.ctor.call(this, normalSprite, selectedSprite, disabledSprite, callback, target);
+ }
+ },
+
+ /**
+ * sets the sprite frame for the normal image
+ * @param {cc.SpriteFrame} frame
+ */
+ setNormalSpriteFrame: function (frame) {
+ this.setNormalImage(new cc.Sprite(frame));
+ },
+
+ /**
+ * sets the sprite frame for the selected image
+ * @param {cc.SpriteFrame} frame
+ */
+ setSelectedSpriteFrame: function (frame) {
+ this.setSelectedImage(new cc.Sprite(frame));
+ },
+
+ /**
+ * sets the sprite frame for the disabled image
+ * @param {cc.SpriteFrame} frame
+ */
+ setDisabledSpriteFrame: function (frame) {
+ this.setDisabledImage(new cc.Sprite(frame));
+ },
+
+ /**
+ * initializes a cc.MenuItemImage
+ * @param {string|null} normalImage
+ * @param {string|null} selectedImage
+ * @param {string|null} disabledImage
+ * @param {function|string|null} callback
+ * @param {cc.Node|null} target
+ * @returns {boolean}
+ */
+ initWithNormalImage: function (normalImage, selectedImage, disabledImage, callback, target) {
+ var normalSprite = null;
+ var selectedSprite = null;
+ var disabledSprite = null;
+
+ if (normalImage) {
+ normalSprite = new cc.Sprite(normalImage);
+ }
+ if (selectedImage) {
+ selectedSprite = new cc.Sprite(selectedImage);
+ }
+ if (disabledImage) {
+ disabledSprite = new cc.Sprite(disabledImage);
+ }
+ return this.initWithNormalSprite(normalSprite, selectedSprite, disabledSprite, callback, target);
+ }
+});
+
+/**
+ * creates a new menu item image
+ * @deprecated since v3.0, please use new cc.MenuItemImage(normalImage, selectedImage, three, four, five) instead.
+ * @param {String} normalImage file name for normal state
+ * @param {String} selectedImage image for selected state
+ * @param {String|cc.Node} three Disabled image OR callback function
+ * @param {String|function|Null} [four] callback function, either name in string or pass the whole function OR the target
+ * @param {cc.Node|String|function|Null} [five] cc.Node target to run callback when clicked
+ * @return {cc.MenuItemImage}
+ */
+cc.MenuItemImage.create = function (normalImage, selectedImage, three, four, five) {
+ return new cc.MenuItemImage(normalImage, selectedImage, three, four, five);
+};
+
+
+/**
+ * A simple container class that "toggles" it's inner items
+ * The inner items can be any MenuItem
+ * @class
+ * @extends cc.MenuItem
+ *
+ * @property {Array} subItems - Sub items
+ * @property {Number} selectedIndex - Index of selected sub item
+ *
+ *@example
+ * // Example
+ * //create a toggle item with 2 menu items (which you can then toggle between them later)
+ * var toggler = new cc.MenuItemToggle( new cc.MenuItemFont("On"), new cc.MenuItemFont("Off"), this.callback, this)
+ * //Note: the first param is the target, the second is the callback function, afterwards, you can pass in any number of menuitems
+ *
+ * //if you pass only 1 variable, then it must be a cc.MenuItem
+ * var notYetToggler = new cc.MenuItemToggle(cc.MenuItemFont("On"));//it is useless right now, until you add more stuff to it
+ * notYetToggler.addSubItem(new cc.MenuItemFont("Off"));
+ * //this is useful for constructing a toggler without a callback function (you wish to control the behavior from somewhere else)
+ */
+cc.MenuItemToggle = cc.MenuItem.extend(/** @lends cc.MenuItemToggle# */{
+ subItems: null,
+
+ _selectedIndex: 0,
+ _opacity: null,
+ _color: null,
+
+ /**
+ * Constructor of cc.MenuItemToggle
+ */
+ ctor: function (/*Multiple arguments follow*/) {
+
+ cc.MenuItem.prototype.ctor.call(this);
+ this._selectedIndex = 0;
+ this.subItems = [];
+ this._opacity = 0;
+ this._color = cc.color.WHITE;
+
+ if(arguments.length > 0)
+ this.initWithItems(Array.prototype.slice.apply(arguments));
+
+ },
+
+ /**
+ * return the opacity of cc.MenuItemToggle
+ * @return {Number}
+ */
+ getOpacity: function () {
+ return this._opacity;
+ },
+
+ /**
+ * set the opacity for cc.MenuItemToggle
+ * @param {Number} opacity
+ */
+ setOpacity: function (opacity) {
+ this._opacity = opacity;
+ if (this.subItems && this.subItems.length > 0) {
+ for (var it = 0; it < this.subItems.length; it++) {
+ this.subItems[it].opacity = opacity;
+ }
+ }
+ this._color.a = opacity;
+ },
+
+ /**
+ * return the color of cc.MenuItemToggle
+ * @return {cc.Color}
+ */
+ getColor: function () {
+ var locColor = this._color;
+ return cc.color(locColor.r, locColor.g, locColor.b, locColor.a);
+ },
+
+ /**
+ * set the color for cc.MenuItemToggle
+ * @param {cc.Color} Color
+ */
+ setColor: function (color) {
+ var locColor = this._color;
+ locColor.r = color.r;
+ locColor.g = color.g;
+ locColor.b = color.b;
+
+ if (this.subItems && this.subItems.length > 0) {
+ for (var it = 0; it < this.subItems.length; it++) {
+ this.subItems[it].setColor(color);
+ }
+ }
+
+ if (color.a !== undefined && !color.a_undefined) {
+ this.setOpacity(color.a);
+ }
+ },
+
+ /**
+ * return the index of selected
+ * @return {Number}
+ */
+ getSelectedIndex: function () {
+ return this._selectedIndex;
+ },
+
+ /**
+ * set the seleceted index for cc.MenuItemToggle
+ * @param {Number} SelectedIndex
+ */
+ setSelectedIndex: function (SelectedIndex) {
+ if (SelectedIndex !== this._selectedIndex) {
+ this._selectedIndex = SelectedIndex;
+ var currItem = this.getChildByTag(cc.CURRENT_ITEM);
+ if (currItem)
+ currItem.removeFromParent(false);
+
+ var item = this.subItems[this._selectedIndex];
+ this.addChild(item, 0, cc.CURRENT_ITEM);
+ var w = item.width, h = item.height;
+ this.width = w;
+ this.height = h;
+ item.setPosition(w / 2, h / 2);
+ }
+ },
+
+ /**
+ * similar to get children,return the sumItem array.
+ * @return {Array}
+ */
+ getSubItems: function () {
+ return this.subItems;
+ },
+
+ /**
+ * set the subitem for cc.MenuItemToggle
+ * @param {cc.MenuItem} subItems
+ */
+ setSubItems: function (subItems) {
+ this.subItems = subItems;
+ },
+
+ /**
+ * initializes a cc.MenuItemToggle with items
+ * @param {...cc.MenuItem} array the rest in the array are cc.MenuItems
+ * @param {function|String} secondTolast the second item in the args array is the callback
+ * @param {cc.Node} last the first item in the args array is a target
+ * @return {Boolean}
+ */
+ initWithItems: function (args) {
+ var l = args.length;
+ // passing callback.
+ if (cc.isFunction(args[args.length - 2])) {
+ this.initWithCallback(args[args.length - 2], args[args.length - 1]);
+ l = l - 2;
+ } else if (cc.isFunction(args[args.length - 1])) {
+ this.initWithCallback(args[args.length - 1], null);
+ l = l - 1;
+ } else {
+ this.initWithCallback(null, null);
+ }
+
+ var locSubItems = this.subItems;
+ locSubItems.length = 0;
+ for (var i = 0; i < l; i++) {
+ if (args[i])
+ locSubItems.push(args[i]);
+ }
+ this._selectedIndex = cc.UINT_MAX;
+ this.setSelectedIndex(0);
+
+ this.setCascadeColorEnabled(true);
+ this.setCascadeOpacityEnabled(true);
+
+ return true;
+ },
+
+ /**
+ * add the subitem for cc.MenuItemToggle
+ * @param {cc.MenuItem} item
+ */
+ addSubItem: function (item) {
+ this.subItems.push(item);
+ },
+
+ /**
+ * activate the menu item
+ */
+ activate: function () {
+ // update index
+ if (this._enabled) {
+ var newIndex = (this._selectedIndex + 1) % this.subItems.length;
+ this.setSelectedIndex(newIndex);
+ }
+ cc.MenuItem.prototype.activate.call(this);
+ },
+
+ /**
+ * menu item is selected (runs callback)
+ */
+ selected: function () {
+ cc.MenuItem.prototype.selected.call(this);
+ this.subItems[this._selectedIndex].selected();
+ },
+
+ /**
+ * menu item goes back to unselected state
+ */
+ unselected: function () {
+ cc.MenuItem.prototype.unselected.call(this);
+ this.subItems[this._selectedIndex].unselected();
+ },
+
+ /**
+ * set the enable status for cc.MenuItemToggle
+ * @param {Boolean} enabled
+ */
+ setEnabled: function (enabled) {
+ if (this._enabled !== enabled) {
+ cc.MenuItem.prototype.setEnabled.call(this, enabled);
+ var locItems = this.subItems;
+ if (locItems && locItems.length > 0) {
+ for (var it = 0; it < locItems.length; it++)
+ locItems[it].enabled = enabled;
+ }
+ }
+ },
+
+ /**
+ * returns the selected item (deprecated in -x, please use getSelectedItem instead.)
+ * @return {cc.MenuItem}
+ */
+ selectedItem: function () {
+ return this.subItems[this._selectedIndex];
+ },
+
+ /**
+ * returns the selected item.
+ * @return {cc.MenuItem}
+ */
+ getSelectedItem: function() {
+ return this.subItems[this._selectedIndex];
+ },
+
+ /**
+ * *
+ * Event callback that is invoked every time when cc.MenuItemToggle enters the 'stage'.
+ * If the cc.MenuItemToggle enters the 'stage' with a transition, this event is called when the transition starts.
+ * During onEnter you can't access a "sister/brother" node.
+ * If you override onEnter, you must call its parent's onEnter function with this._super().
+ *
+ */
+ onEnter: function () {
+ cc.Node.prototype.onEnter.call(this);
+ this.setSelectedIndex(this._selectedIndex);
+ }
+});
+
+var _p = cc.MenuItemToggle.prototype;
+
+// Extended properties
+/** @expose */
+_p.selectedIndex;
+cc.defineGetterSetter(_p, "selectedIndex", _p.getSelectedIndex, _p.setSelectedIndex);
+
+
+/**
+ * create a simple container class that "toggles" it's inner items
+ * The inner items can be any MenuItem
+ * @deprecated since v3.0 please use new cc.MenuItemToggle(params) instead
+ * @return {cc.MenuItemToggle}
+ */
+cc.MenuItemToggle.create = function (/*Multiple arguments follow*/) {
+ if ((arguments.length > 0) && (arguments[arguments.length - 1] == null))
+ cc.log("parameters should not be ending with null in Javascript");
+ var ret = new cc.MenuItemToggle();
+ ret.initWithItems(Array.prototype.slice.apply(arguments));
+ return ret;
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/motion-streak/CCMotionStreak.js b/frameworks/cocos2d-html5/cocos2d/motion-streak/CCMotionStreak.js
new file mode 100644
index 0000000..1583934
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/motion-streak/CCMotionStreak.js
@@ -0,0 +1,533 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2008-2009 Jason Booth
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.MotionStreak manages a Ribbon based on it's motion in absolute space.
+ * You construct it with a fadeTime, minimum segment size, texture path, texture
+ * length and color. The fadeTime controls how long it takes each vertex in
+ * the streak to fade out, the minimum segment size it how many pixels the
+ * streak will move before adding a new ribbon segment, and the texture
+ * length is the how many pixels the texture is stretched across. The texture
+ * is vertically aligned along the streak segment.
+ * @class
+ * @extends cc.Node
+ *
+ * @property {cc.Texture2D} texture - Texture used for the motion streak.
+ * @property {Boolean} fastMode - Indicate whether use fast mode.
+ * @property {Boolean} startingPositionInitialized - Indicate whether starting position initialized.
+ * @example
+ * //example
+ * new cc.MotionStreak(2, 3, 32, cc.color.GREEN, s_streak);
+ */
+cc.MotionStreak = cc.Node.extend(/** @lends cc.MotionStreak# */{
+ texture: null,
+ fastMode: false,
+ startingPositionInitialized: false,
+
+ _blendFunc: null,
+
+ _stroke: 0,
+ _fadeDelta: 0,
+ _minSeg: 0,
+
+ _maxPoints: 0,
+ _nuPoints: 0,
+ _previousNuPoints: 0,
+
+ /* Pointers */
+ _pointVertexes: null,
+ _pointState: null,
+
+ // webgl
+ _vertices: null,
+ _colorPointer: null,
+ _texCoords: null,
+
+ _verticesBuffer: null,
+ _colorPointerBuffer: null,
+ _texCoordsBuffer: null,
+ _className: "MotionStreak",
+
+ /**
+ * creates and initializes a motion streak with fade in seconds, minimum segments, stroke's width, color, texture filename or texture
+ * Constructor of cc.MotionStreak
+ * @param {Number} fade time to fade
+ * @param {Number} minSeg minimum segment size
+ * @param {Number} stroke stroke's width
+ * @param {Number} color
+ * @param {string|cc.Texture2D} texture texture filename or texture
+ */
+ ctor: function (fade, minSeg, stroke, color, texture) {
+ cc.Node.prototype.ctor.call(this);
+ this._positionR = cc.p(0, 0);
+ this._blendFunc = new cc.BlendFunc(cc.SRC_ALPHA, cc.ONE_MINUS_SRC_ALPHA);
+
+ this.fastMode = false;
+ this.startingPositionInitialized = false;
+
+ this.texture = null;
+
+ this._stroke = 0;
+ this._fadeDelta = 0;
+ this._minSeg = 0;
+
+ this._maxPoints = 0;
+ this._nuPoints = 0;
+ this._previousNuPoints = 0;
+
+ /** Pointers */
+ this._pointVertexes = null;
+ this._pointState = null;
+
+ // webgl
+ this._vertices = null;
+ this._colorPointer = null;
+ this._texCoords = null;
+
+ this._verticesBuffer = null;
+ this._colorPointerBuffer = null;
+ this._texCoordsBuffer = null;
+
+ if (texture !== undefined)
+ this.initWithFade(fade, minSeg, stroke, color, texture);
+ },
+
+ /**
+ * Gets the texture.
+ * @return {cc.Texture2D}
+ */
+ getTexture: function () {
+ return this.texture;
+ },
+
+ /**
+ * Set the texture.
+ * @param {cc.Texture2D} texture
+ */
+ setTexture: function (texture) {
+ if (this.texture !== texture)
+ this.texture = texture;
+ },
+
+ /**
+ * Gets the blend func.
+ * @return {cc.BlendFunc}
+ */
+ getBlendFunc: function () {
+ return this._blendFunc;
+ },
+
+ /**
+ * Set the blend func.
+ * @param {Number} src
+ * @param {Number} dst
+ */
+ setBlendFunc: function (src, dst) {
+ if (dst === undefined) {
+ this._blendFunc = src;
+ } else {
+ this._blendFunc.src = src;
+ this._blendFunc.dst = dst;
+ }
+ },
+
+ /**
+ * Gets opacity.
+ * @warning cc.MotionStreak.getOpacity has not been supported.
+ * @returns {number}
+ */
+ getOpacity: function () {
+ cc.log("cc.MotionStreak.getOpacity has not been supported.");
+ return 0;
+ },
+
+ /**
+ * Set opacity.
+ * @warning cc.MotionStreak.setOpacity has not been supported.
+ * @param opacity
+ */
+ setOpacity: function (opacity) {
+ cc.log("cc.MotionStreak.setOpacity has not been supported.");
+ },
+
+ /**
+ * set opacity modify RGB.
+ * @warning cc.MotionStreak.setOpacityModifyRGB has not been supported.
+ * @param value
+ */
+ setOpacityModifyRGB: function (value) {
+ },
+
+ /**
+ * Checking OpacityModifyRGB.
+ * @returns {boolean}
+ */
+ isOpacityModifyRGB: function () {
+ return false;
+ },
+
+ /**
+ * Checking fast mode.
+ * @returns {boolean}
+ */
+ isFastMode: function () {
+ return this.fastMode;
+ },
+
+ /**
+ * set fast mode
+ * @param {Boolean} fastMode
+ */
+ setFastMode: function (fastMode) {
+ this.fastMode = fastMode;
+ },
+
+ /**
+ * Checking starting position initialized.
+ * @returns {boolean}
+ */
+ isStartingPositionInitialized: function () {
+ return this.startingPositionInitialized;
+ },
+
+ /**
+ * Set Starting Position Initialized.
+ * @param {Boolean} startingPositionInitialized
+ */
+ setStartingPositionInitialized: function (startingPositionInitialized) {
+ this.startingPositionInitialized = startingPositionInitialized;
+ },
+
+ /**
+ * Get stroke.
+ * @returns {Number} stroke
+ */
+ getStroke: function () {
+ return this._stroke;
+ },
+
+ /**
+ * Set stroke.
+ * @param {Number} stroke
+ */
+ setStroke: function (stroke) {
+ this._stroke = stroke;
+ },
+
+ /**
+ * initializes a motion streak with fade in seconds, minimum segments, stroke's width, color and texture filename or texture
+ * @param {Number} fade time to fade
+ * @param {Number} minSeg minimum segment size
+ * @param {Number} stroke stroke's width
+ * @param {Number} color
+ * @param {string|cc.Texture2D} texture texture filename or texture
+ * @return {Boolean}
+ */
+ initWithFade: function (fade, minSeg, stroke, color, texture) {
+ if (!texture)
+ throw new Error("cc.MotionStreak.initWithFade(): Invalid filename or texture");
+
+ if (cc.isString(texture))
+ texture = cc.textureCache.addImage(texture);
+
+ cc.Node.prototype.setPosition.call(this, cc.p(0, 0));
+ this.anchorX = 0;
+ this.anchorY = 0;
+ this.ignoreAnchor = true;
+ this.startingPositionInitialized = false;
+
+ this.fastMode = true;
+ this._minSeg = (minSeg === -1.0) ? (stroke / 5.0) : minSeg;
+ this._minSeg *= this._minSeg;
+
+ this._stroke = stroke;
+ this._fadeDelta = 1.0 / fade;
+
+ var locMaxPoints = (0 | (fade * 60)) + 2;
+ this._maxPoints = locMaxPoints;
+ this._nuPoints = 0;
+ this._pointState = new Float32Array(locMaxPoints);
+ this._pointVertexes = new Float32Array(locMaxPoints * 2);
+
+ this._vertices = new Float32Array(locMaxPoints * 4);
+ this._texCoords = new Float32Array(locMaxPoints * 4);
+ this._colorPointer = new Uint8Array(locMaxPoints * 8);
+
+ this._verticesBuffer = gl.createBuffer();
+ this._texCoordsBuffer = gl.createBuffer();
+ this._colorPointerBuffer = gl.createBuffer();
+
+ // Set blend mode
+ this._blendFunc.src = gl.SRC_ALPHA;
+ this._blendFunc.dst = gl.ONE_MINUS_SRC_ALPHA;
+
+ this.texture = texture;
+ this.color = color;
+ this.scheduleUpdate();
+
+ //bind buffer
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordsBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this._texCoords, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._colorPointerBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this._colorPointer, gl.DYNAMIC_DRAW);
+
+ return true;
+ },
+
+ /**
+ * color used for the tint
+ * @param {cc.Color} color
+ */
+ tintWithColor: function (color) {
+ this.color = color;
+
+ // Fast assignation
+ var locColorPointer = this._colorPointer;
+ for (var i = 0, len = this._nuPoints * 2; i < len; i++) {
+ locColorPointer[i * 4] = color.r;
+ locColorPointer[i * 4 + 1] = color.g;
+ locColorPointer[i * 4 + 2] = color.b;
+ }
+ },
+
+ /**
+ * Remove all living segments of the ribbon
+ */
+ reset: function () {
+ this._nuPoints = 0;
+ },
+
+ /**
+ * Set the position.
+ *
+ * @param {cc.Point|Number} position
+ * @param {Number} [yValue=undefined] If not exists, the first parameter must be cc.Point.
+ */
+ setPosition: function (position, yValue) {
+ this.startingPositionInitialized = true;
+ if (yValue === undefined) {
+ this._positionR.x = position.x;
+ this._positionR.y = position.y;
+ } else {
+ this._positionR.x = position;
+ this._positionR.y = yValue;
+ }
+ },
+
+ /**
+ * Gets the position.x
+ * @return {Number}
+ */
+ getPositionX: function () {
+ return this._positionR.x;
+ },
+
+ /**
+ * Set the position.x
+ * @param {Number} x
+ */
+ setPositionX: function (x) {
+ this._positionR.x = x;
+ if (!this.startingPositionInitialized)
+ this.startingPositionInitialized = true;
+ },
+
+ /**
+ * Gets the position.y
+ * @return {Number}
+ */
+ getPositionY: function () {
+ return this._positionR.y;
+ },
+
+ /**
+ * Set the position.y
+ * @param {Number} y
+ */
+ setPositionY: function (y) {
+ this._positionR.y = y;
+ if (!this.startingPositionInitialized)
+ this.startingPositionInitialized = true;
+ },
+
+ /**
+ * schedules the "update" method.
+ * It will use the order number 0. This method will be called every frame.
+ * Scheduled methods with a lower order value will be called before the ones that have a higher order value.
+ * Only one "update" method could be scheduled per node.
+ * @param {Number} delta
+ */
+ update: function (delta) {
+ if (!this.startingPositionInitialized)
+ return;
+
+ //TODO update the color (need move to render cmd)
+ this._renderCmd._updateDisplayColor();
+
+ delta *= this._fadeDelta;
+
+ var i, newIdx, newIdx2, i2;
+ var mov = 0;
+
+ // Update current points
+ var locNuPoints = this._nuPoints;
+ var locPointState = this._pointState, locPointVertexes = this._pointVertexes, locVertices = this._vertices;
+ var locColorPointer = this._colorPointer;
+
+ for (i = 0; i < locNuPoints; i++) {
+ locPointState[i] -= delta;
+
+ if (locPointState[i] <= 0)
+ mov++;
+ else {
+ newIdx = i - mov;
+ if (mov > 0) {
+ // Move data
+ locPointState[newIdx] = locPointState[i];
+ // Move point
+ locPointVertexes[newIdx * 2] = locPointVertexes[i * 2];
+ locPointVertexes[newIdx * 2 + 1] = locPointVertexes[i * 2 + 1];
+
+ // Move vertices
+ i2 = i * 2;
+ newIdx2 = newIdx * 2;
+ locVertices[newIdx2 * 2] = locVertices[i2 * 2];
+ locVertices[newIdx2 * 2 + 1] = locVertices[i2 * 2 + 1];
+ locVertices[(newIdx2 + 1) * 2] = locVertices[(i2 + 1) * 2];
+ locVertices[(newIdx2 + 1) * 2 + 1] = locVertices[(i2 + 1) * 2 + 1];
+
+ // Move color
+ i2 *= 4;
+ newIdx2 *= 4;
+ locColorPointer[newIdx2 + 0] = locColorPointer[i2 + 0];
+ locColorPointer[newIdx2 + 1] = locColorPointer[i2 + 1];
+ locColorPointer[newIdx2 + 2] = locColorPointer[i2 + 2];
+ locColorPointer[newIdx2 + 4] = locColorPointer[i2 + 4];
+ locColorPointer[newIdx2 + 5] = locColorPointer[i2 + 5];
+ locColorPointer[newIdx2 + 6] = locColorPointer[i2 + 6];
+ } else
+ newIdx2 = newIdx * 8;
+
+ var op = locPointState[newIdx] * 255.0;
+ locColorPointer[newIdx2 + 3] = op;
+ locColorPointer[newIdx2 + 7] = op;
+ }
+ }
+ locNuPoints -= mov;
+
+ // Append new point
+ var appendNewPoint = true;
+ if (locNuPoints >= this._maxPoints)
+ appendNewPoint = false;
+ else if (locNuPoints > 0) {
+ var a1 = cc.pDistanceSQ(cc.p(locPointVertexes[(locNuPoints - 1) * 2], locPointVertexes[(locNuPoints - 1) * 2 + 1]),
+ this._positionR) < this._minSeg;
+ var a2 = (locNuPoints === 1) ? false : (cc.pDistanceSQ(
+ cc.p(locPointVertexes[(locNuPoints - 2) * 2], locPointVertexes[(locNuPoints - 2) * 2 + 1]), this._positionR) < (this._minSeg * 2.0));
+ if (a1 || a2)
+ appendNewPoint = false;
+ }
+
+ if (appendNewPoint) {
+ locPointVertexes[locNuPoints * 2] = this._positionR.x;
+ locPointVertexes[locNuPoints * 2 + 1] = this._positionR.y;
+ locPointState[locNuPoints] = 1.0;
+
+ // Color assignment
+ var offset = locNuPoints * 8;
+
+ var locDisplayedColor = this.getDisplayedColor();
+ locColorPointer[offset] = locDisplayedColor.r;
+ locColorPointer[offset + 1] = locDisplayedColor.g;
+ locColorPointer[offset + 2] = locDisplayedColor.b;
+ //*((ccColor3B*)(m_pColorPointer + offset+4)) = this._color;
+ locColorPointer[offset + 4] = locDisplayedColor.r;
+ locColorPointer[offset + 5] = locDisplayedColor.g;
+ locColorPointer[offset + 6] = locDisplayedColor.b;
+
+ // Opacity
+ locColorPointer[offset + 3] = 255;
+ locColorPointer[offset + 7] = 255;
+
+ // Generate polygon
+ if (locNuPoints > 0 && this.fastMode) {
+ if (locNuPoints > 1)
+ cc.vertexLineToPolygon(locPointVertexes, this._stroke, this._vertices, locNuPoints, 1);
+ else
+ cc.vertexLineToPolygon(locPointVertexes, this._stroke, this._vertices, 0, 2);
+ }
+ locNuPoints++;
+ }
+
+ if (!this.fastMode)
+ cc.vertexLineToPolygon(locPointVertexes, this._stroke, this._vertices, 0, locNuPoints);
+
+ // Updated Tex Coords only if they are different than previous step
+ if (locNuPoints && this._previousNuPoints !== locNuPoints) {
+ var texDelta = 1.0 / locNuPoints;
+ var locTexCoords = this._texCoords;
+ for (i = 0; i < locNuPoints; i++) {
+ locTexCoords[i * 4] = 0;
+ locTexCoords[i * 4 + 1] = texDelta * i;
+
+ locTexCoords[(i * 2 + 1) * 2] = 1;
+ locTexCoords[(i * 2 + 1) * 2 + 1] = texDelta * i;
+ }
+
+ this._previousNuPoints = locNuPoints;
+ }
+
+ this._nuPoints = locNuPoints;
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ return new cc.MotionStreak.WebGLRenderCmd(this);
+ else
+ return null; //MotionStreak doesn't support Canvas mode
+ }
+});
+
+/**
+ * Please use new cc.MotionStreak instead.
+ * Creates and initializes a motion streak with fade in seconds, minimum segments, stroke's width, color, texture filename or texture
+ * @deprecated since v3.0 please use new cc.MotionStreak instead.
+ * @param {Number} fade time to fade
+ * @param {Number} minSeg minimum segment size
+ * @param {Number} stroke stroke's width
+ * @param {Number} color
+ * @param {string|cc.Texture2D} texture texture filename or texture
+ * @return {cc.MotionStreak}
+ * @example
+ * //example
+ * new cc.MotionStreak(2, 3, 32, cc.color.GREEN, s_streak);
+ */
+cc.MotionStreak.create = function (fade, minSeg, stroke, color, texture) {
+ return new cc.MotionStreak(fade, minSeg, stroke, color, texture);
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js
new file mode 100644
index 0000000..a7d793a
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js
@@ -0,0 +1,79 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.MotionStreak.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR);
+};
+
+cc.MotionStreak.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+cc.MotionStreak.WebGLRenderCmd.prototype.constructor = cc.Sprite.WebGLRenderCmd;
+
+cc.MotionStreak.WebGLRenderCmd.prototype.rendering = function (ctx) {
+ var node = this._node;
+ if (node._nuPoints <= 1)
+ return;
+
+ if (node.texture && node.texture.isLoaded()) {
+ ctx = ctx || cc._renderContext;
+
+ var wt = this._worldTransform;
+ this._matrix.mat[0] = wt.a;
+ this._matrix.mat[4] = wt.c;
+ this._matrix.mat[12] = wt.tx;
+ this._matrix.mat[1] = wt.b;
+ this._matrix.mat[5] = wt.d;
+ this._matrix.mat[13] = wt.ty;
+
+ this._glProgramState.apply(this._matrix);
+ cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
+
+ cc.glBindTexture2D(node.texture);
+
+ ctx.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ ctx.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
+ ctx.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS);
+
+ //position
+ ctx.bindBuffer(ctx.ARRAY_BUFFER, node._verticesBuffer);
+ ctx.bufferData(ctx.ARRAY_BUFFER, node._vertices, ctx.DYNAMIC_DRAW);
+ ctx.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, ctx.FLOAT, false, 0, 0);
+
+ //texcoords
+ ctx.bindBuffer(ctx.ARRAY_BUFFER, node._texCoordsBuffer);
+ ctx.bufferData(ctx.ARRAY_BUFFER, node._texCoords, ctx.DYNAMIC_DRAW);
+ ctx.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, ctx.FLOAT, false, 0, 0);
+
+ //colors
+ ctx.bindBuffer(ctx.ARRAY_BUFFER, node._colorPointerBuffer);
+ ctx.bufferData(ctx.ARRAY_BUFFER, node._colorPointer, ctx.DYNAMIC_DRAW);
+ ctx.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, ctx.UNSIGNED_BYTE, true, 0, 0);
+
+ ctx.drawArrays(ctx.TRIANGLE_STRIP, 0, node._nuPoints * 2);
+ cc.g_NumberOfDraws++;
+ }
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/node-grid/CCNodeGrid.js b/frameworks/cocos2d-html5/cocos2d/node-grid/CCNodeGrid.js
new file mode 100644
index 0000000..684b388
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/node-grid/CCNodeGrid.js
@@ -0,0 +1,110 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * NodeGrid class is a class serves as a decorator of cc.Node,
+ * Grid node can run grid actions over all its children (WebGL only)
+ *
+ * @type {Class}
+ *
+ * @property {cc.GridBase} grid - Grid object that is used when applying effects
+ * @property {cc.Node} target - <@writeonly>Target
+ */
+cc.NodeGrid = cc.Node.extend(/** @lends cc.NodeGrid# */{
+ grid: null,
+ _target: null,
+ _gridRect:null,
+
+ ctor: function (rect) {
+ cc.Node.prototype.ctor.call(this);
+ if(rect === undefined) rect = cc.rect();
+ this._gridRect = rect;
+ },
+ /**
+ * Gets the grid object.
+ * @returns {cc.GridBase}
+ */
+ getGrid: function () {
+ return this.grid;
+ },
+
+ /**
+ * Set the grid object.
+ * @param {cc.GridBase} grid
+ */
+ setGrid: function (grid) {
+ this.grid = grid;
+ },
+
+ /**
+ * @brief Set the effect grid rect.
+ * @param {cc.Rect} rect
+ */
+ setGridRect: function (rect) {
+ this._gridRect = rect;
+ },
+ /**
+ * @brief Get the effect grid rect.
+ * @return {cc.Rect} rect.
+ */
+ getGridRect: function () {
+ return this._gridRect;
+ },
+
+ /**
+ * Set the target
+ * @param {cc.Node} target
+ */
+ setTarget: function (target) {
+ this._target = target;
+ },
+
+ _createRenderCmd: function(){
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ return new cc.NodeGrid.WebGLRenderCmd(this);
+ else
+ return new cc.Node.CanvasRenderCmd(this); // cc.NodeGrid doesn't support Canvas mode.
+ }
+});
+
+var _p = cc.NodeGrid.prototype;
+// Extended property
+/** @expose */
+_p.grid;
+/** @expose */
+_p.target;
+cc.defineGetterSetter(_p, "target", null, _p.setTarget);
+
+
+/**
+ * Creates a NodeGrid.
+ * Implementation cc.NodeGrid
+ * @deprecated since v3.0 please new cc.NodeGrid instead.
+ * @return {cc.NodeGrid}
+ */
+cc.NodeGrid.create = function () {
+ return new cc.NodeGrid();
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/node-grid/CCNodeGridWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/node-grid/CCNodeGridWebGLRenderCmd.js
new file mode 100644
index 0000000..9288a0f
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/node-grid/CCNodeGridWebGLRenderCmd.js
@@ -0,0 +1,98 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ cc.NodeGrid.WebGLRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._needDraw = false;
+ this._gridBeginCommand = new cc.CustomRenderCmd(this, this.onGridBeginDraw);
+ this._gridEndCommand = new cc.CustomRenderCmd(this, this.onGridEndDraw);
+ };
+
+ var proto = cc.NodeGrid.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ proto.constructor = cc.NodeGrid.WebGLRenderCmd;
+
+ proto.visit = function (parentCmd) {
+ var node = this._node;
+ // quick return if not visible
+ if (!node._visible)
+ return;
+
+ parentCmd = parentCmd || this.getParentRenderCmd();
+ if (parentCmd)
+ this._curLevel = parentCmd._curLevel + 1;
+
+ var currentStack = cc.current_stack;
+ currentStack.stack.push(currentStack.top);
+ this._syncStatus(parentCmd);
+ currentStack.top = this._stackMatrix;
+
+ /*var beforeProjectionType = cc.director.PROJECTION_DEFAULT;
+ if (locGrid && locGrid._active) {
+ //var backMatrix = new cc.kmMat4();
+ //cc.kmMat4Assign(backMatrix, this._stackMatrix);
+
+ beforeProjectionType = cc.director.getProjection();
+ //locGrid.set2DProjection();
+
+ //reset this._stackMatrix to current_stack.top
+ //cc.kmMat4Assign(currentStack.top, backMatrix);
+ }*/
+ cc.renderer.pushRenderCommand(this._gridBeginCommand);
+
+ if (node._target)
+ node._target.visit();
+
+ var locChildren = node._children;
+ if (locChildren && locChildren.length > 0) {
+ var childLen = locChildren.length;
+ node.sortAllChildren();
+ // draw children
+ for (var i = 0; i < childLen; i++) {
+ var child = locChildren[i];
+ child && child.visit();
+ }
+ }
+
+ //if (locGrid && locGrid._active) {
+ //cc.director.setProjection(beforeProjectionType);
+ //}
+ cc.renderer.pushRenderCommand(this._gridEndCommand);
+
+ this._dirtyFlag = 0;
+ currentStack.top = currentStack.stack.pop();
+ };
+
+ proto.onGridBeginDraw = function () {
+ var locGrid = this._node.grid;
+ if (locGrid && locGrid._active)
+ locGrid.beforeDraw();
+ };
+
+ proto.onGridEndDraw = function () {
+ var locGrid = this._node.grid;
+ if (locGrid && locGrid._active)
+ locGrid.afterDraw(this._node);
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/parallax/CCParallaxNode.js b/frameworks/cocos2d-html5/cocos2d/parallax/CCParallaxNode.js
new file mode 100644
index 0000000..7efc9cf
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/parallax/CCParallaxNode.js
@@ -0,0 +1,252 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Parallax Object.
+ * Parallax required attributes are stored.
+ * @class
+ * @extends cc.Class
+ */
+cc.PointObject = cc.Class.extend(/** @lends cc.PointObject# */{
+ _ratio:null,
+ _offset:null,
+ _child:null,
+
+ ctor: function(ratio, offset){
+ this.initWithCCPoint(ratio, offset);
+ },
+
+ /**
+ * Gets the ratio.
+ * @return {cc.Point} Not point, this is ratio.
+ */
+ getRatio:function () {
+ return this._ratio;
+ },
+
+ /**
+ * Set the ratio.
+ * @param {cc.Point} value
+ */
+ setRatio:function (value) {
+ this._ratio = value;
+ },
+
+ /**
+ * Gets the offset.
+ * @return {cc.Point}
+ */
+ getOffset:function () {
+ return this._offset;
+ },
+
+ /**
+ * Set the offset.
+ * @param {cc.Point} value
+ */
+ setOffset:function (value) {
+ this._offset = value;
+ },
+
+ /**
+ * Gets the child.
+ * @return {cc.Node}
+ */
+ getChild:function () {
+ return this._child;
+ },
+
+ /**
+ * Set the child.
+ * @param {cc.Node} value
+ */
+ setChild:function (value) {
+ this._child = value;
+ },
+
+ /**
+ * initializes cc.PointObject
+ * @param {cc.Point} ratio Not point, this is a ratio.
+ * @param {cc.Point} offset
+ * @return {Boolean}
+ */
+ initWithCCPoint:function (ratio, offset) {
+ this._ratio = ratio;
+ this._offset = offset;
+ this._child = null;
+ return true;
+ }
+});
+
+/**
+ * Create a object to stored parallax data.
+ * @param {cc.Point} ratio
+ * @param {cc.Point} offset
+ * @return {cc.PointObject}
+ * @deprecated since v3.0 please use new cc.PointObject() instead.
+ */
+cc.PointObject.create = function (ratio, offset) {
+ return new cc.PointObject(ratio, offset);
+};
+
+/**
+ * cc.ParallaxNode: A node that simulates a parallax scroller
+ * The children will be moved faster / slower than the parent according the the parallax ratio.
+ * @class
+ * @extends cc.Node
+ *
+ * @property {Array} parallaxArray - Parallax nodes array
+ */
+cc.ParallaxNode = cc.Node.extend(/** @lends cc.ParallaxNode# */{
+ parallaxArray:null,
+
+ _lastPosition:null,
+ _className:"ParallaxNode",
+
+ /**
+ * Gets the parallax array.
+ * @return {Array}
+ */
+ getParallaxArray:function () {
+ return this.parallaxArray;
+ },
+
+ /**
+ * Set parallax array.
+ * @param {Array} value
+ */
+ setParallaxArray:function (value) {
+ this.parallaxArray = value;
+ },
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor:function () {
+ cc.Node.prototype.ctor.call(this);
+ this.parallaxArray = [];
+ this._lastPosition = cc.p(-100, -100);
+ },
+
+ /**
+ * Adds a child to the container with a z-order, a parallax ratio and a position offset
+ * It returns self, so you can chain several addChilds.
+ * @param {cc.Node} child
+ * @param {Number} z
+ * @param {cc.Point} ratio
+ * @param {cc.Point} offset
+ * @example
+ * //example
+ * voidNode.addChild(background, -1, cc.p(0.4, 0.5), cc.p(0,0));
+ */
+ addChild:function (child, z, ratio, offset) {
+ if (arguments.length === 3) {
+ cc.log("ParallaxNode: use addChild(child, z, ratio, offset) instead");
+ return;
+ }
+ if(!child)
+ throw new Error("cc.ParallaxNode.addChild(): child should be non-null");
+ var obj = new cc.PointObject(ratio, offset);
+ obj.setChild(child);
+ this.parallaxArray.push(obj);
+
+ child.setPosition(this._position.x * ratio.x + offset.x, this._position.y * ratio.y + offset.y);
+
+ cc.Node.prototype.addChild.call(this, child, z, child.tag);
+ },
+
+ /**
+ * Remove Child
+ * @param {cc.Node} child
+ * @param {Boolean} cleanup
+ * @example
+ * //example
+ * voidNode.removeChild(background,true);
+ */
+ removeChild:function (child, cleanup) {
+ var locParallaxArray = this.parallaxArray;
+ for (var i = 0; i < locParallaxArray.length; i++) {
+ var point = locParallaxArray[i];
+ if (point.getChild() === child) {
+ locParallaxArray.splice(i, 1);
+ break;
+ }
+ }
+ cc.Node.prototype.removeChild.call(this, child, cleanup);
+ },
+
+ /**
+ * Remove all children with cleanup
+ * @param {Boolean} [cleanup=true]
+ */
+ removeAllChildren:function (cleanup) {
+ this.parallaxArray.length = 0;
+ cc.Node.prototype.removeAllChildren.call(this, cleanup);
+ },
+
+ _updateParallaxPosition: function(){
+ var pos = this._absolutePosition();
+ if (!cc.pointEqualToPoint(pos, this._lastPosition)) {
+ var locParallaxArray = this.parallaxArray;
+ for (var i = 0, len = locParallaxArray.length; i < len; i++) {
+ var point = locParallaxArray[i];
+ var child = point.getChild();
+ child.setPosition(-pos.x + pos.x * point.getRatio().x + point.getOffset().x,
+ -pos.y + pos.y * point.getRatio().y + point.getOffset().y);
+ }
+ this._lastPosition = pos;
+ }
+ },
+
+ _absolutePosition:function () {
+ var ret = this._position;
+ var cn = this;
+ while (cn.parent !== null) {
+ cn = cn.parent;
+ ret = cc.pAdd(ret, cn.getPosition());
+ }
+ return ret;
+ },
+
+ _createRenderCmd: function(){
+ if(cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.ParallaxNode.CanvasRenderCmd(this);
+ else
+ return new cc.ParallaxNode.WebGLRenderCmd(this);
+ }
+});
+
+/**
+ * Create new parallax node.
+ * @deprecated since v3.0 please use new cc.ParallaxNode() instead.
+ * @return {cc.ParallaxNode}
+ * @example
+ * //example
+ * var voidNode = new cc.ParallaxNode();
+ */
+cc.ParallaxNode.create = function () {
+ return new cc.ParallaxNode();
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/parallax/CCParallaxNodeRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/parallax/CCParallaxNodeRenderCmd.js
new file mode 100644
index 0000000..2f5031c
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/parallax/CCParallaxNodeRenderCmd.js
@@ -0,0 +1,69 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+//TODO find a way to simple these code.
+
+(function () {
+ cc.ParallaxNode.CanvasRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._needDraw = false;
+ };
+
+ var proto = cc.ParallaxNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ proto.constructor = cc.ParallaxNode.CanvasRenderCmd;
+
+ proto.updateStatus = function () {
+ this._node._updateParallaxPosition();
+ this.originUpdateStatus();
+ };
+
+ proto._syncStatus = function (parentCmd) {
+ this._node._updateParallaxPosition();
+ this._originSyncStatus(parentCmd);
+ };
+})();
+
+cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
+ if (cc._renderType !== cc.game.RENDER_TYPE_WEBGL)
+ return;
+
+ cc.ParallaxNode.WebGLRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._needDraw = false;
+ };
+
+ var proto = cc.ParallaxNode.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ proto.constructor = cc.ParallaxNode.WebGLRenderCmd;
+
+ proto.updateStatus = function () {
+ this._node._updateParallaxPosition();
+ this.originUpdateStatus();
+ };
+
+ proto._syncStatus = function (parentCmd) {
+ this._node._updateParallaxPosition();
+ this._originSyncStatus(parentCmd);
+ };
+});
+
diff --git a/frameworks/cocos2d-html5/cocos2d/particle/CCPNGReader.js b/frameworks/cocos2d-html5/cocos2d/particle/CCPNGReader.js
new file mode 100644
index 0000000..20667a2
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/particle/CCPNGReader.js
@@ -0,0 +1,330 @@
+/****************************************************************************
+ Copyright (c) 2011 Devon Govett
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * A png file reader
+ * @name cc.tiffReader
+ */
+cc.PNGReader = cc.Class.extend({
+ ctor:function(data){
+ var chunkSize, colors, delayDen, delayNum, frame, i, index, key, section, ccshort, text, _i, _j, _ref;
+ this.data = data;
+ this.pos = 8;
+ this.palette = [];
+ this.imgData = [];
+ this.transparency = {};
+ this.animation = null;
+ this.text = {};
+ frame = null;
+ while (true) {
+ chunkSize = this.readUInt32();
+ section = ((function() {
+ var _i, _results;
+ _results = [];
+ for (i = _i = 0; _i < 4; i = ++_i) {
+ _results.push(String.fromCharCode(this.data[this.pos++]));
+ }
+ return _results;
+ }).call(this)).join('');
+ switch (section) {
+ case 'IHDR':
+ this.width = this.readUInt32();
+ this.height = this.readUInt32();
+ this.bits = this.data[this.pos++];
+ this.colorType = this.data[this.pos++];
+ this.compressionMethod = this.data[this.pos++];
+ this.filterMethod = this.data[this.pos++];
+ this.interlaceMethod = this.data[this.pos++];
+ break;
+ case 'acTL':
+ this.animation = {
+ numFrames: this.readUInt32(),
+ numPlays: this.readUInt32() || Infinity,
+ frames: []
+ };
+ break;
+ case 'PLTE':
+ this.palette = this.read(chunkSize);
+ break;
+ case 'fcTL':
+ if (frame) {
+ this.animation.frames.push(frame);
+ }
+ this.pos += 4;
+ frame = {
+ width: this.readUInt32(),
+ height: this.readUInt32(),
+ xOffset: this.readUInt32(),
+ yOffset: this.readUInt32()
+ };
+ delayNum = this.readUInt16();
+ delayDen = this.readUInt16() || 100;
+ frame.delay = 1000 * delayNum / delayDen;
+ frame.disposeOp = this.data[this.pos++];
+ frame.blendOp = this.data[this.pos++];
+ frame.data = [];
+ break;
+ case 'IDAT':
+ case 'fdAT':
+ if (section === 'fdAT') {
+ this.pos += 4;
+ chunkSize -= 4;
+ }
+ data = (frame != null ? frame.data : void 0) || this.imgData;
+ for (i = _i = 0; 0 <= chunkSize ? _i < chunkSize : _i > chunkSize; i = 0 <= chunkSize ? ++_i : --_i) {
+ data.push(this.data[this.pos++]);
+ }
+ break;
+ case 'tRNS':
+ this.transparency = {};
+ switch (this.colorType) {
+ case 3:
+ this.transparency.indexed = this.read(chunkSize);
+ ccshort = 255 - this.transparency.indexed.length;
+ if (ccshort > 0) {
+ for (i = _j = 0; 0 <= ccshort ? _j < ccshort : _j > ccshort; i = 0 <= ccshort ? ++_j : --_j) {
+ this.transparency.indexed.push(255);
+ }
+ }
+ break;
+ case 0:
+ this.transparency.grayscale = this.read(chunkSize)[0];
+ break;
+ case 2:
+ this.transparency.rgb = this.read(chunkSize);
+ }
+ break;
+ case 'tEXt':
+ text = this.read(chunkSize);
+ index = text.indexOf(0);
+ key = String.fromCharCode.apply(String, text.slice(0, index));
+ this.text[key] = String.fromCharCode.apply(String, text.slice(index + 1));
+ break;
+ case 'IEND':
+ if (frame) {
+ this.animation.frames.push(frame);
+ }
+ this.colors = (function() {
+ switch (this.colorType) {
+ case 0:
+ case 3:
+ case 4:
+ return 1;
+ case 2:
+ case 6:
+ return 3;
+ }
+ }).call(this);
+ this.hasAlphaChannel = (_ref = this.colorType) === 4 || _ref === 6;
+ colors = this.colors + (this.hasAlphaChannel ? 1 : 0);
+ this.pixelBitlength = this.bits * colors;
+ this.colorSpace = (function() {
+ switch (this.colors) {
+ case 1:
+ return 'DeviceGray';
+ case 3:
+ return 'DeviceRGB';
+ }
+ }).call(this);
+ if(Uint8Array != Array)
+ this.imgData = new Uint8Array(this.imgData);
+ return;
+ default:
+ this.pos += chunkSize;
+ }
+ this.pos += 4;
+ if (this.pos > this.data.length) {
+ throw new Error("Incomplete or corrupt PNG file");
+ }
+ }
+ },
+ read:function(bytes){
+ var i, _i, _results;
+ _results = [];
+ for (i = _i = 0; 0 <= bytes ? _i < bytes : _i > bytes; i = 0 <= bytes ? ++_i : --_i) {
+ _results.push(this.data[this.pos++]);
+ }
+ return _results;
+ },
+ readUInt32:function(){
+ var b1, b2, b3, b4;
+ b1 = this.data[this.pos++] << 24;
+ b2 = this.data[this.pos++] << 16;
+ b3 = this.data[this.pos++] << 8;
+ b4 = this.data[this.pos++];
+ return b1 | b2 | b3 | b4;
+ },
+ readUInt16:function(){
+ var b1, b2;
+ b1 = this.data[this.pos++] << 8;
+ b2 = this.data[this.pos++];
+ return b1 | b2;
+ },
+ decodePixels:function(data){
+ var ccbyte, c, col, i, left, length, p, pa, paeth, pb, pc, pixelBytes, pixels, pos, row, scanlineLength, upper, upperLeft, _i, _j, _k, _l, _m;
+ if (data == null) {
+ data = this.imgData;
+ }
+ if (data.length === 0) {
+ return new Uint8Array(0);
+ }
+ var inflate = new Zlib.Inflate(data,{index:0, verify:false});
+ data = inflate.decompress();
+
+ pixelBytes = this.pixelBitlength / 8;
+ scanlineLength = pixelBytes * this.width;
+ pixels = new Uint8Array(scanlineLength * this.height);
+ length = data.length;
+ row = 0;
+ pos = 0;
+ c = 0;
+ while (pos < length) {
+ switch (data[pos++]) {
+ case 0:
+ for (i = _i = 0; _i < scanlineLength; i = _i += 1) {
+ pixels[c++] = data[pos++];
+ }
+ break;
+ case 1:
+ for (i = _j = 0; _j < scanlineLength; i = _j += 1) {
+ ccbyte = data[pos++];
+ left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
+ pixels[c++] = (ccbyte + left) % 256;
+ }
+ break;
+ case 2:
+ for (i = _k = 0; _k < scanlineLength; i = _k += 1) {
+ ccbyte = data[pos++];
+ col = (i - (i % pixelBytes)) / pixelBytes;
+ upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
+ pixels[c++] = (upper + ccbyte) % 256;
+ }
+ break;
+ case 3:
+ for (i = _l = 0; _l < scanlineLength; i = _l += 1) {
+ ccbyte = data[pos++];
+ col = (i - (i % pixelBytes)) / pixelBytes;
+ left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
+ upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
+ pixels[c++] = (ccbyte + Math.floor((left + upper) / 2)) % 256;
+ }
+ break;
+ case 4:
+ for (i = _m = 0; _m < scanlineLength; i = _m += 1) {
+ ccbyte = data[pos++];
+ col = (i - (i % pixelBytes)) / pixelBytes;
+ left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
+ if (row === 0) {
+ upper = upperLeft = 0;
+ } else {
+ upper = pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
+ upperLeft = col && pixels[(row - 1) * scanlineLength + (col - 1) * pixelBytes + (i % pixelBytes)];
+ }
+ p = left + upper - upperLeft;
+ pa = Math.abs(p - left);
+ pb = Math.abs(p - upper);
+ pc = Math.abs(p - upperLeft);
+ if (pa <= pb && pa <= pc) {
+ paeth = left;
+ } else if (pb <= pc) {
+ paeth = upper;
+ } else {
+ paeth = upperLeft;
+ }
+ pixels[c++] = (ccbyte + paeth) % 256;
+ }
+ break;
+ default:
+ throw new Error("Invalid filter algorithm: " + data[pos - 1]);
+ }
+ row++;
+ }
+ return pixels;
+ },
+ copyToImageData:function(imageData,pixels){
+ var alpha, colors, data, i, input, j, k, length, palette, v, _ref;
+ colors = this.colors;
+ palette = null;
+ alpha = this.hasAlphaChannel;
+ if (this.palette.length) {
+ palette = (_ref = this._decodedPalette) != null ? _ref : this._decodedPalette = this.decodePalette();
+ colors = 4;
+ alpha = true;
+ }
+ data = imageData.data || imageData;
+ length = data.length;
+ input = palette || pixels;
+ i = j = 0;
+ if (colors === 1) {
+ while (i < length) {
+ k = palette ? pixels[i / 4] * 4 : j;
+ v = input[k++];
+ data[i++] = v;
+ data[i++] = v;
+ data[i++] = v;
+ data[i++] = alpha ? input[k++] : 255;
+ j = k;
+ }
+ } else {
+ while (i < length) {
+ k = palette ? pixels[i / 4] * 4 : j;
+ data[i++] = input[k++];
+ data[i++] = input[k++];
+ data[i++] = input[k++];
+ data[i++] = alpha ? input[k++] : 255;
+ j = k;
+ }
+ }
+ },
+ decodePalette:function(){
+ var c, i, palette, pos, ret, transparency, _i, _ref, _ref1;
+ palette = this.palette;
+ transparency = this.transparency.indexed || [];
+ ret = new Uint8Array((transparency.length || 0) + palette.length);
+ pos = 0;
+ c = 0;
+ for (i = _i = 0, _ref = palette.length; _i < _ref; i = _i += 3) {
+ ret[pos++] = palette[i];
+ ret[pos++] = palette[i + 1];
+ ret[pos++] = palette[i + 2];
+ ret[pos++] = (_ref1 = transparency[c++]) != null ? _ref1 : 255;
+ }
+ return ret;
+ },
+ render: function (canvas) {
+ var ctx, data;
+ canvas.width = this.width;
+ canvas.height = this.height;
+ ctx = canvas.getContext("2d");
+ data = ctx.createImageData(this.width, this.height);
+ this.copyToImageData(data, this.decodePixels());
+ return ctx.putImageData(data, 0, 0);
+
+ }
+});
+
diff --git a/frameworks/cocos2d-html5/cocos2d/particle/CCParticleBatchNode.js b/frameworks/cocos2d-html5/cocos2d/particle/CCParticleBatchNode.js
new file mode 100644
index 0000000..53c381f
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/particle/CCParticleBatchNode.js
@@ -0,0 +1,538 @@
+/**
+ * Copyright (c) 2008-2010 Ricardo Quesada
+ * Copyright (c) 2011-2012 cocos2d-x.org
+ * Copyright (c) 2013-2014 Chukong Technologies Inc.
+ * Copyright (C) 2009 Matt Oswald
+ * Copyright (c) 2011 Marco Tillemans
+ *
+ * http://www.cocos2d-x.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+/**
+ * paticle default capacity
+ * @constant
+ * @type Number
+ */
+cc.PARTICLE_DEFAULT_CAPACITY = 500;
+
+/**
+ *
+ * cc.ParticleBatchNode is like a batch node: if it contains children, it will draw them in 1 single OpenGL call
+ * (often known as "batch draw").
+ *
+ * A cc.ParticleBatchNode can reference one and only one texture (one image file, one texture atlas).
+ * Only the cc.ParticleSystems that are contained in that texture can be added to the cc.SpriteBatchNode.
+ * All cc.ParticleSystems added to a cc.SpriteBatchNode are drawn in one OpenGL ES draw call.
+ * If the cc.ParticleSystems are not added to a cc.ParticleBatchNode then an OpenGL ES draw call will be needed for each one, which is less efficient.
+ *
+ * Limitations:
+ * - At the moment only cc.ParticleSystem is supported
+ * - All systems need to be drawn with the same parameters, blend function, aliasing, texture
+ *
+ * Most efficient usage
+ * - Initialize the ParticleBatchNode with the texture and enough capacity for all the particle systems
+ * - Initialize all particle systems and add them as child to the batch node
+ *
+ * @class
+ * @extends cc.ParticleSystem
+ * @param {String|cc.Texture2D} fileImage
+ * @param {Number} capacity
+ *
+ * @property {cc.Texture2D|HTMLImageElement|HTMLCanvasElement} texture - The used texture
+ * @property {cc.TextureAtlas} textureAtlas - The texture atlas used for drawing the quads
+ *
+ * @example
+ * 1.
+ * //Create a cc.ParticleBatchNode with image path and capacity
+ * var particleBatchNode = new cc.ParticleBatchNode("res/grossini_dance.png",30);
+ *
+ * 2.
+ * //Create a cc.ParticleBatchNode with a texture and capacity
+ * var texture = cc.TextureCache.getInstance().addImage("res/grossini_dance.png");
+ * var particleBatchNode = new cc.ParticleBatchNode(texture, 30);
+ */
+cc.ParticleBatchNode = cc.Node.extend(/** @lends cc.ParticleBatchNode# */{
+ textureAtlas: null,
+ //the blend function used for drawing the quads
+ _blendFunc: null,
+ _className: "ParticleBatchNode",
+
+ /**
+ * initializes the particle system with the name of a file on disk (for a list of supported formats look at the cc.Texture2D class), a capacity of particles
+ * Constructor of cc.ParticleBatchNode
+ * @param {String|cc.Texture2D} fileImage
+ * @param {Number} capacity
+ * @example
+ * 1.
+ * //Create a cc.ParticleBatchNode with image path and capacity
+ * var particleBatchNode = new cc.ParticleBatchNode("res/grossini_dance.png",30);
+ *
+ * 2.
+ * //Create a cc.ParticleBatchNode with a texture and capacity
+ * var texture = cc.TextureCache.getInstance().addImage("res/grossini_dance.png");
+ * var particleBatchNode = new cc.ParticleBatchNode(texture, 30);
+ */
+ ctor: function (fileImage, capacity) {
+ cc.Node.prototype.ctor.call(this);
+ this._blendFunc = {src: cc.BLEND_SRC, dst: cc.BLEND_DST};
+ if (cc.isString(fileImage)) {
+ this.init(fileImage, capacity);
+ } else if (fileImage instanceof cc.Texture2D) {
+ this.initWithTexture(fileImage, capacity);
+ }
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.ParticleBatchNode.CanvasRenderCmd(this);
+ else
+ return new cc.ParticleBatchNode.WebGLRenderCmd(this);
+ },
+
+ /**
+ * initializes the particle system with cc.Texture2D, a capacity of particles
+ * @param {cc.Texture2D|HTMLImageElement|HTMLCanvasElement} texture
+ * @param {Number} capacity
+ * @return {Boolean}
+ */
+ initWithTexture: function (texture, capacity) {
+ this.textureAtlas = new cc.TextureAtlas();
+ this.textureAtlas.initWithTexture(texture, capacity);
+
+ // no lazy alloc in this node
+ this._children.length = 0;
+
+ this._renderCmd._initWithTexture();
+ return true;
+ },
+
+ /**
+ * initializes the particle system with the name of a file on disk (for a list of supported formats look at the cc.Texture2D class), a capacity of particles
+ * @param {String} fileImage
+ * @param {Number} capacity
+ * @return {Boolean}
+ */
+ initWithFile: function (fileImage, capacity) {
+ var tex = cc.textureCache.addImage(fileImage);
+ return this.initWithTexture(tex, capacity);
+ },
+
+ /**
+ * initializes the particle system with the name of a file on disk (for a list of supported formats look at the cc.Texture2D class), a capacity of particles
+ * @param {String} fileImage
+ * @param {Number} capacity
+ * @return {Boolean}
+ */
+ init: function (fileImage, capacity) {
+ var tex = cc.textureCache.addImage(fileImage);
+ return this.initWithTexture(tex, capacity);
+ },
+
+ visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
+
+ cmd.visit(parentCmd);
+ cc.renderer.pushRenderCommand(cmd);
+ cmd._dirtyFlag = 0;
+ },
+
+ /**
+ * Add a child into the cc.ParticleBatchNode
+ * @param {cc.ParticleSystem} child
+ * @param {Number} zOrder
+ * @param {Number} tag
+ */
+ addChild: function (child, zOrder, tag) {
+ if (!child)
+ throw new Error("cc.ParticleBatchNode.addChild() : child should be non-null");
+ if (!(child instanceof cc.ParticleSystem))
+ throw new Error("cc.ParticleBatchNode.addChild() : only supports cc.ParticleSystem as children");
+ zOrder = (zOrder == null) ? child.zIndex : zOrder;
+ tag = (tag == null) ? child.tag : tag;
+
+ if (child.getTexture() !== this.textureAtlas.texture)
+ throw new Error("cc.ParticleSystem.addChild() : the child is not using the same texture id");
+
+ // If this is the 1st children, then copy blending function
+ var childBlendFunc = child.getBlendFunc();
+ if (this._children.length === 0)
+ this.setBlendFunc(childBlendFunc);
+ else {
+ if ((childBlendFunc.src !== this._blendFunc.src) || (childBlendFunc.dst !== this._blendFunc.dst)) {
+ cc.log("cc.ParticleSystem.addChild() : Can't add a ParticleSystem that uses a different blending function");
+ return;
+ }
+ }
+
+ //no lazy sorting, so don't call super addChild, call helper instead
+ var pos = this._addChildHelper(child, zOrder, tag);
+
+ //get new atlasIndex
+ var atlasIndex = 0;
+
+ if (pos !== 0) {
+ var p = this._children[pos - 1];
+ atlasIndex = p.getAtlasIndex() + p.getTotalParticles();
+ } else
+ atlasIndex = 0;
+
+ this.insertChild(child, atlasIndex);
+
+ // update quad info
+ child.setBatchNode(this);
+ },
+
+ /**
+ * Inserts a child into the cc.ParticleBatchNode
+ * @param {cc.ParticleSystem} pSystem
+ * @param {Number} index
+ */
+ insertChild: function (pSystem, index) {
+ var totalParticles = pSystem.getTotalParticles();
+ var locTextureAtlas = this.textureAtlas;
+ var totalQuads = locTextureAtlas.totalQuads;
+ pSystem.setAtlasIndex(index);
+ if (totalQuads + totalParticles > locTextureAtlas.getCapacity()) {
+ this._increaseAtlasCapacityTo(totalQuads + totalParticles);
+ // after a realloc empty quads of textureAtlas can be filled with gibberish (realloc doesn't perform calloc), insert empty quads to prevent it
+ locTextureAtlas.fillWithEmptyQuadsFromIndex(locTextureAtlas.getCapacity() - totalParticles, totalParticles);
+ }
+
+ // make room for quads, not necessary for last child
+ if (pSystem.getAtlasIndex() + totalParticles !== totalQuads)
+ locTextureAtlas.moveQuadsFromIndex(index, index + totalParticles);
+
+ // increase totalParticles here for new particles, update method of particlesystem will fill the quads
+ locTextureAtlas.increaseTotalQuadsWith(totalParticles);
+ this._updateAllAtlasIndexes();
+ },
+
+ /**
+ * @param {cc.ParticleSystem} child
+ * @param {Boolean} cleanup
+ */
+ removeChild: function (child, cleanup) {
+ // explicit nil handling
+ if (child == null)
+ return;
+
+ if (!(child instanceof cc.ParticleSystem))
+ throw new Error("cc.ParticleBatchNode.removeChild(): only supports cc.ParticleSystem as children");
+ if (this._children.indexOf(child) === -1) {
+ cc.log("cc.ParticleBatchNode.removeChild(): doesn't contain the sprite. Can't remove it");
+ return;
+ }
+
+ cc.Node.prototype.removeChild.call(this, child, cleanup);
+
+ var locTextureAtlas = this.textureAtlas;
+ // remove child helper
+ locTextureAtlas.removeQuadsAtIndex(child.getAtlasIndex(), child.getTotalParticles());
+
+ // after memmove of data, empty the quads at the end of array
+ locTextureAtlas.fillWithEmptyQuadsFromIndex(locTextureAtlas.totalQuads, child.getTotalParticles());
+
+ // paticle could be reused for self rendering
+ child.setBatchNode(null);
+
+ this._updateAllAtlasIndexes();
+ },
+
+ /**
+ * Reorder will be done in this function, no "lazy" reorder to particles
+ * @param {cc.ParticleSystem} child
+ * @param {Number} zOrder
+ */
+ reorderChild: function (child, zOrder) {
+ if (!child)
+ throw new Error("cc.ParticleBatchNode.reorderChild(): child should be non-null");
+ if (!(child instanceof cc.ParticleSystem))
+ throw new Error("cc.ParticleBatchNode.reorderChild(): only supports cc.QuadParticleSystems as children");
+ if (this._children.indexOf(child) === -1) {
+ cc.log("cc.ParticleBatchNode.reorderChild(): Child doesn't belong to batch");
+ return;
+ }
+
+ // no reordering if only 1 child
+ if (this._children.length > 1) {
+ var getIndexes = this._getCurrentIndex(child, zOrder);
+
+ if (getIndexes.oldIndex !== getIndexes.newIndex) {
+ // reorder m_pChildren.array
+ this._children.splice(getIndexes.oldIndex, 1)
+ this._children.splice(getIndexes.newIndex, 0, child);
+
+ // save old altasIndex
+ var oldAtlasIndex = child.getAtlasIndex();
+
+ // update atlas index
+ this._updateAllAtlasIndexes();
+
+ // Find new AtlasIndex
+ var newAtlasIndex = 0;
+ var locChildren = this._children;
+ for (var i = 0; i < locChildren.length; i++) {
+ var pNode = locChildren[i];
+ if (pNode === child) {
+ newAtlasIndex = child.getAtlasIndex();
+ break;
+ }
+ }
+
+ // reorder textureAtlas quads
+ this.textureAtlas.moveQuadsFromIndex(oldAtlasIndex, child.getTotalParticles(), newAtlasIndex);
+
+ child.updateWithNoTime();
+ }
+ }
+ child._setLocalZOrder(zOrder);
+ },
+
+ /**
+ * @param {Number} index
+ * @param {Boolean} doCleanup
+ */
+ removeChildAtIndex: function (index, doCleanup) {
+ this.removeChild(this._children[i], doCleanup);
+ },
+
+ /**
+ * @param {Boolean} [doCleanup=true]
+ */
+ removeAllChildren: function (doCleanup) {
+ var locChildren = this._children;
+ for (var i = 0; i < locChildren.length; i++) {
+ locChildren[i].setBatchNode(null);
+ }
+ cc.Node.prototype.removeAllChildren.call(this, doCleanup);
+ this.textureAtlas.removeAllQuads();
+ },
+
+ /**
+ * disables a particle by inserting a 0'd quad into the texture atlas
+ * @param {Number} particleIndex
+ */
+ disableParticle: function (particleIndex) {
+ var quad = this.textureAtlas.quads[particleIndex];
+ quad.br.vertices.x = quad.br.vertices.y = quad.tr.vertices.x = quad.tr.vertices.y =
+ quad.tl.vertices.x = quad.tl.vertices.y = quad.bl.vertices.x = quad.bl.vertices.y = 0.0;
+ this.textureAtlas._setDirty(true);
+ },
+
+ /**
+ * returns the used texture
+ * @return {cc.Texture2D}
+ */
+ getTexture: function () {
+ return this.textureAtlas.texture;
+ },
+
+ /**
+ * sets a new texture. it will be retained
+ * @param {cc.Texture2D} texture
+ */
+ setTexture: function (texture) {
+ this.textureAtlas.texture = texture;
+
+ // If the new texture has No premultiplied alpha, AND the blendFunc hasn't been changed, then update it
+ var locBlendFunc = this._blendFunc;
+ if (texture && !texture.hasPremultipliedAlpha() && ( locBlendFunc.src === cc.BLEND_SRC && locBlendFunc.dst === cc.BLEND_DST )) {
+ locBlendFunc.src = cc.SRC_ALPHA;
+ locBlendFunc.dst = cc.ONE_MINUS_SRC_ALPHA;
+ }
+ },
+
+ /**
+ * set the blending function used for the texture
+ * @param {Number|Object} src
+ * @param {Number} dst
+ */
+ setBlendFunc: function (src, dst) {
+ if (dst === undefined) {
+ this._blendFunc.src = src.src;
+ this._blendFunc.dst = src.dst;
+ } else {
+ this._blendFunc.src = src;
+ this._blendFunc.src = dst;
+ }
+ },
+
+ /**
+ * returns the blending function used for the texture
+ * @return {cc.BlendFunc}
+ */
+ getBlendFunc: function () {
+ return new cc.BlendFunc(this._blendFunc.src, this._blendFunc.dst);
+ },
+
+ _updateAllAtlasIndexes: function () {
+ var index = 0;
+ var locChildren = this._children;
+ for (var i = 0; i < locChildren.length; i++) {
+ var child = locChildren[i];
+ child.setAtlasIndex(index);
+ index += child.getTotalParticles();
+ }
+ },
+
+ _increaseAtlasCapacityTo: function (quantity) {
+ cc.log("cocos2d: cc.ParticleBatchNode: resizing TextureAtlas capacity from [" + this.textureAtlas.getCapacity()
+ + "] to [" + quantity + "].");
+
+ if (!this.textureAtlas.resizeCapacity(quantity)) {
+ // serious problems
+ cc.log("cc.ParticleBatchNode._increaseAtlasCapacityTo() : WARNING: Not enough memory to resize the atlas");
+ }
+ },
+
+ _searchNewPositionInChildrenForZ: function (z) {
+ var locChildren = this._children;
+ var count = locChildren.length;
+ for (var i = 0; i < count; i++) {
+ if (locChildren[i].zIndex > z)
+ return i;
+ }
+ return count;
+ },
+
+ _getCurrentIndex: function (child, z) {
+ var foundCurrentIdx = false;
+ var foundNewIdx = false;
+
+ var newIndex = 0;
+ var oldIndex = 0;
+
+ var minusOne = 0, locChildren = this._children;
+ var count = locChildren.length;
+ for (var i = 0; i < count; i++) {
+ var pNode = locChildren[i];
+ // new index
+ if (pNode.zIndex > z && !foundNewIdx) {
+ newIndex = i;
+ foundNewIdx = true;
+
+ if (foundCurrentIdx && foundNewIdx)
+ break;
+ }
+ // current index
+ if (child === pNode) {
+ oldIndex = i;
+ foundCurrentIdx = true;
+ if (!foundNewIdx)
+ minusOne = -1;
+ if (foundCurrentIdx && foundNewIdx)
+ break;
+ }
+ }
+ if (!foundNewIdx)
+ newIndex = count;
+ newIndex += minusOne;
+ return {newIndex: newIndex, oldIndex: oldIndex};
+ },
+
+ //
+ //
+ // don't use lazy sorting, reordering the particle systems quads afterwards would be too complex
+ // XXX research whether lazy sorting + freeing current quads and calloc a new block with size of capacity would be faster
+ // XXX or possibly using vertexZ for reordering, that would be fastest
+ // this helper is almost equivalent to CCNode's addChild, but doesn't make use of the lazy sorting
+ //
+ // @param {cc.ParticleSystem} child
+ // @param {Number} z
+ // @param {Number} aTag
+ // @return {Number}
+ // @private
+ //
+ _addChildHelper: function (child, z, aTag) {
+ if (!child)
+ throw new Error("cc.ParticleBatchNode._addChildHelper(): child should be non-null");
+ if (child.parent) {
+ cc.log("cc.ParticleBatchNode._addChildHelper(): child already added. It can't be added again");
+ return null;
+ }
+
+
+ if (!this._children)
+ this._children = [];
+
+ //don't use a lazy insert
+ var pos = this._searchNewPositionInChildrenForZ(z);
+
+ this._children.splice(pos, 0, child);
+ child.tag = aTag;
+ child._setLocalZOrder(z);
+ child.parent = this;
+ if (this._running) {
+ child._performRecursive(cc.Node._stateCallbackType.onEnter);
+ child._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
+ }
+ return pos;
+ },
+
+ _updateBlendFunc: function () {
+ if (!this.textureAtlas.texture.hasPremultipliedAlpha()) {
+ this._blendFunc.src = cc.SRC_ALPHA;
+ this._blendFunc.dst = cc.ONE_MINUS_SRC_ALPHA;
+ }
+ },
+
+ /**
+ * return the texture atlas used for drawing the quads
+ * @return {cc.TextureAtlas}
+ */
+ getTextureAtlas: function () {
+ return this.textureAtlas;
+ },
+
+ /**
+ * set the texture atlas used for drawing the quads
+ * @param {cc.TextureAtlas} textureAtlas
+ */
+ setTextureAtlas: function (textureAtlas) {
+ this.textureAtlas = textureAtlas;
+ }
+});
+
+var _p = cc.ParticleBatchNode.prototype;
+
+// Extended properties
+/** @expose */
+_p.texture;
+cc.defineGetterSetter(_p, "texture", _p.getTexture, _p.setTexture);
+
+
+/**
+ * initializes the particle system with the name of a file on disk (for a list of supported formats look at the cc.Texture2D class), a capacity of particles
+ * @deprecated since v3.0 please use new cc.ParticleBatchNode(filename, capacity) instead.
+ * @param {String|cc.Texture2D} fileImage
+ * @param {Number} capacity
+ * @return {cc.ParticleBatchNode}
+ */
+cc.ParticleBatchNode.create = function (fileImage, capacity) {
+ return new cc.ParticleBatchNode(fileImage, capacity);
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/particle/CCParticleBatchNodeCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/particle/CCParticleBatchNodeCanvasRenderCmd.js
new file mode 100644
index 0000000..6e0990d
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/particle/CCParticleBatchNodeCanvasRenderCmd.js
@@ -0,0 +1,39 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ /**
+ * cc.ParticleBatchNode's rendering objects of Canvas
+ */
+ cc.ParticleBatchNode.CanvasRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._needDraw = false;
+ };
+
+ var proto = cc.ParticleBatchNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ proto.constructor = cc.ParticleBatchNode.CanvasRenderCmd;
+
+ proto._initWithTexture = function () {
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js
new file mode 100644
index 0000000..765e755
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js
@@ -0,0 +1,60 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ /**
+ * cc.ParticleBatchNode's rendering objects of WebGL
+ */
+ cc.ParticleBatchNode.WebGLRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._needDraw = true;
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+ };
+
+ var proto = cc.ParticleBatchNode.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ proto.constructor = cc.ParticleBatchNode.WebGLRenderCmd;
+
+ proto.rendering = function (ctx) {
+ var _t = this._node;
+ if (_t.textureAtlas.totalQuads === 0)
+ return;
+
+ var wt = this._worldTransform;
+ this._matrix.mat[0] = wt.a;
+ this._matrix.mat[4] = wt.c;
+ this._matrix.mat[12] = wt.tx;
+ this._matrix.mat[1] = wt.b;
+ this._matrix.mat[5] = wt.d;
+ this._matrix.mat[13] = wt.ty;
+
+ this._glProgramState.apply(this._matrix);
+ cc.glBlendFuncForParticle(_t._blendFunc.src, _t._blendFunc.dst);
+ _t.textureAtlas.drawQuads();
+ };
+
+ proto._initWithTexture = function () {
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR);
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/particle/CCParticleExamples.js b/frameworks/cocos2d-html5/cocos2d/particle/CCParticleExamples.js
new file mode 100644
index 0000000..7c89bb3
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/particle/CCParticleExamples.js
@@ -0,0 +1,1006 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * A fire particle system
+ * @class
+ * @extends cc.ParticleSystem
+ *
+ * @example
+ * var emitter = new cc.ParticleFire();
+ */
+cc.ParticleFire = cc.ParticleSystem.extend(/** @lends cc.ParticleFire# */{
+ /**
+ * The cc.ParticleFire's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleFire()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor:function () {
+ cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 300 : 150);
+ },
+
+ /**
+ * initialize a fire particle system with number Of Particles
+ * @param {Number} numberOfParticles
+ * @return {Boolean}
+ */
+ initWithTotalParticles:function (numberOfParticles) {
+ if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) {
+ // duration
+ this.setDuration(cc.ParticleSystem.DURATION_INFINITY);
+
+ // Gravity Mode
+ this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY);
+
+
+ // Gravity Mode: gravity
+ this.setGravity(cc.p(0, 0));
+
+ // Gravity Mode: radial acceleration
+ this.setRadialAccel(0);
+ this.setRadialAccelVar(0);
+
+ // Gravity Mode: speed of particles
+ this.setSpeed(60);
+ this.setSpeedVar(20);
+
+ // starting angle
+ this.setAngle(90);
+ this.setAngleVar(10);
+
+ // emitter position
+ var winSize = cc.director.getWinSize();
+ this.setPosition(winSize.width / 2, 60);
+ this.setPosVar(cc.p(40, 20));
+
+ // life of particles
+ this.setLife(3);
+ this.setLifeVar(0.25);
+
+
+ // size, in pixels
+ this.setStartSize(54.0);
+ this.setStartSizeVar(10.0);
+ this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE);
+
+ // emits per frame
+ this.setEmissionRate(this.getTotalParticles() / this.getLife());
+
+ // color of particles
+ this.setStartColor(cc.color(194,64,31,255));
+ this.setStartColorVar(cc.color(0,0,0,0));
+ this.setEndColor(cc.color(0,0,0,255));
+ this.setEndColorVar(cc.color(0,0,0,0));
+
+ // additive
+ this.setBlendAdditive(true);
+ return true;
+ }
+ return false;
+ }
+});
+
+/**
+ * Create a fire particle system
+ * @deprecated since v3.0 please use new cc.ParticleFire() instead
+ * @return {cc.ParticleFire}
+ */
+cc.ParticleFire.create = function () {
+ return new cc.ParticleFire();
+};
+
+/**
+ * A fireworks particle system
+ * @class
+ * @extends cc.ParticleSystem
+ *
+ * @example
+ * var emitter = new cc.ParticleFireworks();
+ */
+cc.ParticleFireworks = cc.ParticleSystem.extend(/** @lends cc.ParticleFireworks# */{
+ /**
+ * The cc.ParticleFireworks's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleFireworks()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor:function () {
+ cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 1500 : 150);
+ },
+
+ /**
+ * initialize a fireworks particle system with number Of Particles
+ * @param {Number} numberOfParticles
+ * @return {Boolean}
+ */
+ initWithTotalParticles:function (numberOfParticles) {
+ if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) {
+ // duration
+ this.setDuration(cc.ParticleSystem.DURATION_INFINITY);
+
+ // Gravity Mode
+ this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY);
+
+ // Gravity Mode: gravity
+ this.setGravity(cc.p(0, -90));
+
+ // Gravity Mode: radial
+ this.setRadialAccel(0);
+ this.setRadialAccelVar(0);
+
+ // Gravity Mode: speed of particles
+ this.setSpeed(180);
+ this.setSpeedVar(50);
+
+ // emitter position
+ var winSize = cc.director.getWinSize();
+ this.setPosition(winSize.width / 2, winSize.height / 2);
+
+ // angle
+ this.setAngle(90);
+ this.setAngleVar(20);
+
+ // life of particles
+ this.setLife(3.5);
+ this.setLifeVar(1);
+
+ // emits per frame
+ this.setEmissionRate(this.getTotalParticles() / this.getLife());
+
+ // color of particles
+ this.setStartColor(cc.color(128,128,128,255));
+ this.setStartColorVar(cc.color(128,128,128,255));
+ this.setEndColor(cc.color(26,26,26,51));
+ this.setEndColorVar(cc.color(26,26,26,51));
+
+ // size, in pixels
+ this.setStartSize(8.0);
+ this.setStartSizeVar(2.0);
+ this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE);
+
+ // additive
+ this.setBlendAdditive(false);
+ return true;
+ }
+ return false;
+ }
+});
+
+/**
+ * Create a fireworks particle system
+ * @deprecated since v3.0 please use new cc.ParticleFireworks() instead.
+ * @return {cc.ParticleFireworks}
+ */
+cc.ParticleFireworks.create = function () {
+ return new cc.ParticleFireworks();
+};
+
+/**
+ * A sun particle system
+ * @class
+ * @extends cc.ParticleSystem
+ *
+ * @example
+ * var emitter = new cc.ParticleSun();
+ */
+cc.ParticleSun = cc.ParticleSystem.extend(/** @lends cc.ParticleSun# */{
+ /**
+ * The cc.ParticleSun's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleSun()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor:function () {
+ cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 350 : 150);
+ },
+
+ /**
+ * initialize a sun particle system with number Of Particles
+ * @param {Number} numberOfParticles
+ * @return {Boolean}
+ */
+ initWithTotalParticles:function (numberOfParticles) {
+ if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) {
+ // additive
+ this.setBlendAdditive(true);
+
+ // duration
+ this.setDuration(cc.ParticleSystem.DURATION_INFINITY);
+
+ // Gravity Mode
+ this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY);
+
+ // Gravity Mode: gravity
+ this.setGravity(cc.p(0, 0));
+
+ // Gravity mode: radial acceleration
+ this.setRadialAccel(0);
+ this.setRadialAccelVar(0);
+
+ // Gravity mode: speed of particles
+ this.setSpeed(20);
+ this.setSpeedVar(5);
+
+ // angle
+ this.setAngle(90);
+ this.setAngleVar(360);
+
+ // emitter position
+ var winSize = cc.director.getWinSize();
+ this.setPosition(winSize.width / 2, winSize.height / 2);
+ this.setPosVar(cc.p(0,0));
+
+ // life of particles
+ this.setLife(1);
+ this.setLifeVar(0.5);
+
+ // size, in pixels
+ this.setStartSize(30.0);
+ this.setStartSizeVar(10.0);
+ this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE);
+
+ // emits per seconds
+ this.setEmissionRate(this.getTotalParticles() / this.getLife());
+
+ // color of particles
+ this.setStartColor(cc.color(194, 64, 31, 255));
+ this.setStartColorVar(cc.color(0, 0, 0, 0));
+ this.setEndColor(cc.color(0, 0, 0, 255));
+ this.setEndColorVar(cc.color(0, 0, 0, 0));
+
+ return true;
+ }
+ return false;
+ }
+});
+
+/**
+ * Create a sun particle system
+ * @deprecated since v3.0 please use new cc.ParticleSun() instead.
+ * @return {cc.ParticleSun}
+ */
+cc.ParticleSun.create = function () {
+ return new cc.ParticleSun();
+};
+
+//! @brief A particle system
+/**
+ * A galaxy particle system
+ * @class
+ * @extends cc.ParticleSystem
+ *
+ * @example
+ * var emitter = new cc.ParticleGalaxy();
+ */
+cc.ParticleGalaxy = cc.ParticleSystem.extend(/** @lends cc.ParticleGalaxy# */{
+ /**
+ * The cc.ParticleGalaxy's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleGalaxy()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor:function () {
+ cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 200 : 100);
+ },
+
+ /**
+ * initialize a galaxy particle system with number Of Particles
+ * @param {Number} numberOfParticles
+ * @return {Boolean}
+ */
+ initWithTotalParticles:function (numberOfParticles) {
+ if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) {
+ // duration
+ this.setDuration(cc.ParticleSystem.DURATION_INFINITY);
+
+ // Gravity Mode
+ this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY);
+
+ // Gravity Mode: gravity
+ this.setGravity(cc.p(0, 0));
+
+ // Gravity Mode: speed of particles
+ this.setSpeed(60);
+ this.setSpeedVar(10);
+
+ // Gravity Mode: radial
+ this.setRadialAccel(-80);
+ this.setRadialAccelVar(0);
+
+ // Gravity Mode: tangential
+ this.setTangentialAccel(80);
+ this.setTangentialAccelVar(0);
+
+ // angle
+ this.setAngle(90);
+ this.setAngleVar(360);
+
+ // emitter position
+ var winSize = cc.director.getWinSize();
+ this.setPosition(winSize.width / 2, winSize.height / 2);
+ this.setPosVar(cc.p(0,0));
+
+ // life of particles
+ this.setLife(4);
+ this.setLifeVar(1);
+
+ // size, in pixels
+ this.setStartSize(37.0);
+ this.setStartSizeVar(10.0);
+ this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE);
+
+ // emits per second
+ this.setEmissionRate(this.getTotalParticles() / this.getLife());
+
+ // color of particles
+ this.setStartColor(cc.color(31, 64, 194, 255));
+ this.setStartColorVar(cc.color(0, 0, 0, 0));
+ this.setEndColor(cc.color(0, 0, 0, 255));
+ this.setEndColorVar(cc.color(0, 0, 0, 0));
+
+ // additive
+ this.setBlendAdditive(true);
+ return true;
+ }
+ return false;
+ }
+});
+/**
+ * Create a galaxy particle system
+ * @deprecated since v3.0 please use new cc.OarticleGalaxy() instead.
+ * @return {cc.ParticleGalaxy}
+ */
+cc.ParticleGalaxy.create = function () {
+ return new cc.ParticleGalaxy();
+};
+
+/**
+ * A flower particle system
+ * @class
+ * @extends cc.ParticleSystem
+ *
+ * @example
+ * var emitter = new cc.ParticleFlower();
+ */
+cc.ParticleFlower = cc.ParticleSystem.extend(/** @lends cc.ParticleFlower# */{
+ /**
+ * The cc.ParticleFlower's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleFlower()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor : function () {
+ cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 250 : 100);
+ },
+
+ /**
+ * initialize a flower particle system with number Of Particles
+ * @param {Number} numberOfParticles
+ * @return {Boolean}
+ */
+ initWithTotalParticles:function (numberOfParticles) {
+ if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) {
+ // duration
+ this.setDuration(cc.ParticleSystem.DURATION_INFINITY);
+
+ // Gravity Mode
+ this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY);
+
+ // Gravity Mode: gravity
+ this.setGravity(cc.p(0, 0));
+
+ // Gravity Mode: speed of particles
+ this.setSpeed(80);
+ this.setSpeedVar(10);
+
+ // Gravity Mode: radial
+ this.setRadialAccel(-60);
+ this.setRadialAccelVar(0);
+
+ // Gravity Mode: tangential
+ this.setTangentialAccel(15);
+ this.setTangentialAccelVar(0);
+
+ // angle
+ this.setAngle(90);
+ this.setAngleVar(360);
+
+ // emitter position
+ var winSize = cc.director.getWinSize();
+ this.setPosition(winSize.width / 2, winSize.height / 2);
+ this.setPosVar(cc.p(0,0));
+
+ // life of particles
+ this.setLife(4);
+ this.setLifeVar(1);
+
+ // size, in pixels
+ this.setStartSize(30.0);
+ this.setStartSizeVar(10.0);
+ this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE);
+
+ // emits per second
+ this.setEmissionRate(this.getTotalParticles() / this.getLife());
+
+ // color of particles
+ this.setStartColor(cc.color(128, 128, 128, 255));
+ this.setStartColorVar(cc.color(128, 128, 128, 128));
+ this.setEndColor(cc.color(0, 0, 0, 255));
+ this.setEndColorVar(cc.color(0, 0, 0, 0));
+
+ // additive
+ this.setBlendAdditive(true);
+ return true;
+ }
+ return false;
+ }
+});
+
+/**
+ * Create a flower particle system
+ * @deprecated since v3.0 please use new cc.ParticleFlower() instead.
+ * @return {cc.ParticleFlower}
+ */
+cc.ParticleFlower.create = function () {
+ return new cc.ParticleFlower();
+};
+
+//! @brief A meteor particle system
+/**
+ * A meteor particle system
+ * @class
+ * @extends cc.ParticleSystem
+ *
+ * @example
+ * var emitter = new cc.ParticleMeteor();
+ */
+cc.ParticleMeteor = cc.ParticleSystem.extend(/** @lends cc.ParticleMeteor# */{
+ /**
+ * The cc.ParticleMeteor's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleMeteor()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor:function () {
+ cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 150 : 100);
+ },
+
+ /**
+ * initialize a meteor particle system with number Of Particles
+ * @param {Number} numberOfParticles
+ * @return {Boolean}
+ */
+ initWithTotalParticles:function (numberOfParticles) {
+ if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) {
+ // duration
+ this.setDuration(cc.ParticleSystem.DURATION_INFINITY);
+
+ // Gravity Mode
+ this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY);
+
+ // Gravity Mode: gravity
+ this.setGravity(cc.p(-200, 200));
+
+ // Gravity Mode: speed of particles
+ this.setSpeed(15);
+ this.setSpeedVar(5);
+
+ // Gravity Mode: radial
+ this.setRadialAccel(0);
+ this.setRadialAccelVar(0);
+
+ // Gravity Mode: tangential
+ this.setTangentialAccel(0);
+ this.setTangentialAccelVar(0);
+
+ // angle
+ this.setAngle(90);
+ this.setAngleVar(360);
+
+ // emitter position
+ var winSize = cc.director.getWinSize();
+ this.setPosition(winSize.width / 2, winSize.height / 2);
+ this.setPosVar(cc.p(0,0));
+
+ // life of particles
+ this.setLife(2);
+ this.setLifeVar(1);
+
+ // size, in pixels
+ this.setStartSize(60.0);
+ this.setStartSizeVar(10.0);
+ this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE);
+
+ // emits per second
+ this.setEmissionRate(this.getTotalParticles() / this.getLife());
+
+ // color of particles
+ this.setStartColor(cc.color(51, 102, 179));
+ this.setStartColorVar(cc.color(0, 0, 51, 26));
+ this.setEndColor(cc.color(0, 0, 0, 255));
+ this.setEndColorVar(cc.color(0, 0, 0, 0));
+
+ // additive
+ this.setBlendAdditive(true);
+ return true;
+ }
+ return false;
+ }
+});
+
+/**
+ * Create a meteor particle system
+ * @deprecated since v3.0 please use new cc.ParticleMeteor() instead.
+ * @return {cc.ParticleMeteor}
+ */
+cc.ParticleMeteor.create = function () {
+ return new cc.ParticleMeteor();
+};
+
+/**
+ * A spiral particle system
+ * @class
+ * @extends cc.ParticleSystem
+ *
+ * @example
+ * var emitter = new cc.ParticleSpiral();
+ */
+cc.ParticleSpiral = cc.ParticleSystem.extend(/** @lends cc.ParticleSpiral# */{
+
+ /**
+ * The cc.ParticleSpiral's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleSpiral()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor:function() {
+ cc.ParticleSystem.prototype.ctor.call(this,(cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 500 : 100);
+ },
+
+ /**
+ * initialize a spiral particle system with number Of Particles
+ * @param {Number} numberOfParticles
+ * @return {Boolean}
+ */
+ initWithTotalParticles:function (numberOfParticles) {
+ if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) {
+ // duration
+ this.setDuration(cc.ParticleSystem.DURATION_INFINITY);
+
+ // Gravity Mode
+ this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY);
+
+ // Gravity Mode: gravity
+ this.setGravity(cc.p(0, 0));
+
+ // Gravity Mode: speed of particles
+ this.setSpeed(150);
+ this.setSpeedVar(0);
+
+ // Gravity Mode: radial
+ this.setRadialAccel(-380);
+ this.setRadialAccelVar(0);
+
+ // Gravity Mode: tangential
+ this.setTangentialAccel(45);
+ this.setTangentialAccelVar(0);
+
+ // angle
+ this.setAngle(90);
+ this.setAngleVar(0);
+
+ // emitter position
+ var winSize = cc.director.getWinSize();
+ this.setPosition(winSize.width / 2, winSize.height / 2);
+ this.setPosVar(cc.p(0,0));
+
+ // life of particles
+ this.setLife(12);
+ this.setLifeVar(0);
+
+ // size, in pixels
+ this.setStartSize(20.0);
+ this.setStartSizeVar(0.0);
+ this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE);
+
+ // emits per second
+ this.setEmissionRate(this.getTotalParticles() / this.getLife());
+
+ // color of particles
+ this.setStartColor(cc.color(128,128,128,255));
+ this.setStartColorVar(cc.color(128,128,128,0));
+ this.setEndColor(cc.color(128,128,128,255));
+ this.setEndColorVar(cc.color(128,128,128,0));
+
+ // additive
+ this.setBlendAdditive(false);
+ return true;
+ }
+ return false;
+ }
+});
+
+/**
+ * Create a spiral particle system
+ * @deprecated since v3.0 please use new cc.ParticleSpiral() instead.
+ * @return {cc.ParticleSpiral}
+ */
+cc.ParticleSpiral.create = function () {
+ return new cc.ParticleSpiral();
+};
+
+/**
+ * An explosion particle system
+ * @class
+ * @extends cc.ParticleSystem
+ *
+ * @example
+ * var emitter = new cc.ParticleExplosion();
+ */
+cc.ParticleExplosion = cc.ParticleSystem.extend(/** @lends cc.ParticleExplosion# */{
+ /**
+ * The cc.ParticleExplosion's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleExplosion()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor:function () {
+ cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 700 : 300);
+ },
+
+ /**
+ * initialize an explosion particle system with number Of Particles
+ * @param {Number} numberOfParticles
+ * @return {Boolean}
+ */
+ initWithTotalParticles:function (numberOfParticles) {
+ if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) {
+ // duration
+ this.setDuration(0.1);
+
+ this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY);
+
+ // Gravity Mode: gravity
+ this.setGravity(cc.p(0, 0));
+
+ // Gravity Mode: speed of particles
+ this.setSpeed(70);
+ this.setSpeedVar(40);
+
+ // Gravity Mode: radial
+ this.setRadialAccel(0);
+ this.setRadialAccelVar(0);
+
+ // Gravity Mode: tangential
+ this.setTangentialAccel(0);
+ this.setTangentialAccelVar(0);
+
+ // angle
+ this.setAngle(90);
+ this.setAngleVar(360);
+
+ // emitter position
+ var winSize = cc.director.getWinSize();
+ this.setPosition(winSize.width / 2, winSize.height / 2);
+ this.setPosVar(cc.p(0,0));
+
+ // life of particles
+ this.setLife(5.0);
+ this.setLifeVar(2);
+
+ // size, in pixels
+ this.setStartSize(15.0);
+ this.setStartSizeVar(10.0);
+ this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE);
+
+ // emits per second
+ this.setEmissionRate(this.getTotalParticles() / this.getDuration());
+
+ // color of particles
+ this.setStartColor(cc.color(179, 26, 51, 255));
+ this.setStartColorVar(cc.color(128, 128, 128, 0));
+ this.setEndColor(cc.color(128, 128, 128, 0));
+ this.setEndColorVar(cc.color(128, 128, 128, 0));
+
+ // additive
+ this.setBlendAdditive(false);
+ return true;
+ }
+ return false;
+ }
+});
+
+/**
+ * Create an explosion particle system
+ * @deprecated since v3.0 please use new cc.ParticleExplosion() instead.
+ * @return {cc.ParticleExplosion}
+ */
+cc.ParticleExplosion.create = function () {
+ return new cc.ParticleExplosion();
+};
+
+/**
+ * A smoke particle system
+ * @class
+ * @extends cc.ParticleSystem
+ *
+ * @example
+ * var emitter = new cc.ParticleSmoke();
+ */
+cc.ParticleSmoke = cc.ParticleSystem.extend(/** @lends cc.ParticleSmoke# */{
+
+ /**
+ * The cc.ParticleSmoke's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleSmoke()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor:function () {
+ cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 200 : 100);
+ },
+
+ /**
+ * initialize a smoke particle system with number Of Particles
+ * @param {Number} numberOfParticles
+ * @return {Boolean}
+ */
+ initWithTotalParticles:function (numberOfParticles) {
+ if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) {
+ // duration
+ this.setDuration(cc.ParticleSystem.DURATION_INFINITY);
+
+ // Emitter mode: Gravity Mode
+ this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY);
+
+ // Gravity Mode: gravity
+ this.setGravity(cc.p(0, 0));
+
+ // Gravity Mode: radial acceleration
+ this.setRadialAccel(0);
+ this.setRadialAccelVar(0);
+
+ // Gravity Mode: speed of particles
+ this.setSpeed(25);
+ this.setSpeedVar(10);
+
+ // angle
+ this.setAngle(90);
+ this.setAngleVar(5);
+
+ // emitter position
+ var winSize = cc.director.getWinSize();
+ this.setPosition(winSize.width / 2, 0);
+ this.setPosVar(cc.p(20, 0));
+
+ // life of particles
+ this.setLife(4);
+ this.setLifeVar(1);
+
+ // size, in pixels
+ this.setStartSize(60.0);
+ this.setStartSizeVar(10.0);
+ this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE);
+
+ // emits per frame
+ this.setEmissionRate(this.getTotalParticles() / this.getLife());
+
+ // color of particles
+ this.setStartColor(cc.color(204, 204, 204, 255));
+ this.setStartColorVar(cc.color(5, 5, 5, 0));
+ this.setEndColor(cc.color(0, 0, 0, 255));
+ this.setEndColorVar(cc.color(0, 0, 0, 0));
+
+ // additive
+ this.setBlendAdditive(false);
+ return true;
+ }
+ return false;
+ }
+});
+
+/**
+ * Create a smoke particle system
+ * @deprecated since v3.0 please use new cc.ParticleSmoke() instead.
+ * @return {cc.ParticleSmoke}
+ */
+cc.ParticleSmoke.create = function () {
+ return new cc.ParticleSmoke();
+};
+
+/**
+ * A snow particle system
+ * @class
+ * @extends cc.ParticleSystem
+ *
+ * @example
+ * var emitter = new cc.ParticleSnow();
+ */
+cc.ParticleSnow = cc.ParticleSystem.extend(/** @lends cc.ParticleSnow# */{
+
+ /**
+ * The cc.ParticleSnow's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleSnow()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor:function () {
+ cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 700 : 250);
+ },
+
+ /**
+ * initialize a snow particle system with number Of Particles
+ * @param {Number} numberOfParticles
+ * @return {Boolean}
+ */
+ initWithTotalParticles:function (numberOfParticles) {
+ if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) {
+ // duration
+ this.setDuration(cc.ParticleSystem.DURATION_INFINITY);
+
+ // set gravity mode.
+ this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY);
+
+ // Gravity Mode: gravity
+ this.setGravity(cc.p(0, -1));
+
+ // Gravity Mode: speed of particles
+ this.setSpeed(5);
+ this.setSpeedVar(1);
+
+ // Gravity Mode: radial
+ this.setRadialAccel(0);
+ this.setRadialAccelVar(1);
+
+ // Gravity mode: tangential
+ this.setTangentialAccel(0);
+ this.setTangentialAccelVar(1);
+
+ // emitter position
+ var winSize = cc.director.getWinSize();
+ this.setPosition(winSize.width / 2, winSize.height + 10);
+ this.setPosVar(cc.p(winSize.width / 2, 0));
+
+ // angle
+ this.setAngle(-90);
+ this.setAngleVar(5);
+
+ // life of particles
+ this.setLife(45);
+ this.setLifeVar(15);
+
+ // size, in pixels
+ this.setStartSize(10.0);
+ this.setStartSizeVar(5.0);
+ this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE);
+
+ // emits per second
+ this.setEmissionRate(10);
+
+ // color of particles
+ this.setStartColor(cc.color(255, 255, 255, 255));
+ this.setStartColorVar(cc.color(0, 0, 0, 0));
+ this.setEndColor(cc.color(255, 255, 255, 0));
+ this.setEndColorVar(cc.color(0, 0, 0, 0));
+
+ // additive
+ this.setBlendAdditive(false);
+ return true;
+ }
+ return false;
+ }
+});
+
+/**
+ * Create a snow particle system
+ * @deprecated since v3.0 please use new cc.ParticleSnow() instead.
+ * @return {cc.ParticleSnow}
+ */
+cc.ParticleSnow.create = function () {
+ return new cc.ParticleSnow();
+};
+
+//! @brief A rain particle system
+/**
+ * A rain particle system
+ * @class
+ * @extends cc.ParticleSystem
+ *
+ * @example
+ * var emitter = new cc.ParticleRain();
+ */
+cc.ParticleRain = cc.ParticleSystem.extend(/** @lends cc.ParticleRain# */{
+
+ /**
+ * The cc.ParticleRain's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleRain()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor:function () {
+ cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 1000 : 300);
+ },
+
+ /**
+ * initialize a rain particle system with number Of Particles
+ * @param {Number} numberOfParticles
+ * @return {Boolean}
+ */
+ initWithTotalParticles:function (numberOfParticles) {
+ if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) {
+ // duration
+ this.setDuration(cc.ParticleSystem.DURATION_INFINITY);
+
+ this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY);
+
+ // Gravity Mode: gravity
+ this.setGravity(cc.p(10, -10));
+
+ // Gravity Mode: radial
+ this.setRadialAccel(0);
+ this.setRadialAccelVar(1);
+
+ // Gravity Mode: tangential
+ this.setTangentialAccel(0);
+ this.setTangentialAccelVar(1);
+
+ // Gravity Mode: speed of particles
+ this.setSpeed(130);
+ this.setSpeedVar(30);
+
+ // angle
+ this.setAngle(-90);
+ this.setAngleVar(5);
+
+
+ // emitter position
+ var winSize = cc.director.getWinSize();
+ this.setPosition(winSize.width / 2, winSize.height);
+ this.setPosVar(cc.p(winSize.width / 2, 0));
+
+ // life of particles
+ this.setLife(4.5);
+ this.setLifeVar(0);
+
+ // size, in pixels
+ this.setStartSize(4.0);
+ this.setStartSizeVar(2.0);
+ this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE);
+
+ // emits per second
+ this.setEmissionRate(20);
+
+ // color of particles
+ this.setStartColor(cc.color(179, 204, 255, 255));
+ this.setStartColorVar(cc.color(0, 0, 0, 0));
+ this.setEndColor(cc.color(179, 204, 255, 128));
+ this.setEndColorVar(cc.color(0, 0, 0, 0));
+
+ // additive
+ this.setBlendAdditive(false);
+ return true;
+ }
+ return false;
+ }
+});
+
+/**
+ * Create a rain particle system
+ * @deprecated since v3.0 please use cc.ParticleRain() instead.
+ * @return {cc.ParticleRain}
+ */
+cc.ParticleRain.create = function () {
+ return new cc.ParticleRain();
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/particle/CCParticleSystem.js b/frameworks/cocos2d-html5/cocos2d/particle/CCParticleSystem.js
new file mode 100644
index 0000000..7a18fa4
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/particle/CCParticleSystem.js
@@ -0,0 +1,2318 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+// ideas taken from:
+// . The ocean spray in your face [Jeff Lander]
+// http://www.double.co.nz/dust/col0798.pdf
+// . Building an Advanced Particle System [John van der Burg]
+// http://www.gamasutra.com/features/20000623/vanderburg_01.htm
+// . LOVE game engine
+// http://love2d.org/
+//
+//
+// Radius mode support, from 71 squared
+// http://particledesigner.71squared.com/
+//
+// IMPORTANT: Particle Designer is supported by cocos2d, but
+// 'Radius Mode' in Particle Designer uses a fixed emit rate of 30 hz. Since that can't be guarateed in cocos2d,
+// cocos2d uses a another approach, but the results are almost identical.
+//
+
+
+// tCCPositionType
+// possible types of particle positions
+
+
+/**
+ * Structure that contains the values of each particle
+ * @Class
+ * @Construct
+ * @param {cc.Point} [pos=cc.p(0,0)] Position of particle
+ * @param {cc.Point} [startPos=cc.p(0,0)]
+ * @param {cc.Color} [color= cc.color(0, 0, 0, 255)]
+ * @param {cc.Color} [deltaColor=cc.color(0, 0, 0, 255)]
+ * @param {cc.Size} [size=0]
+ * @param {cc.Size} [deltaSize=0]
+ * @param {Number} [rotation=0]
+ * @param {Number} [deltaRotation=0]
+ * @param {Number} [timeToLive=0]
+ * @param {Number} [atlasIndex=0]
+ * @param {cc.Particle.ModeA} [modeA=]
+ * @param {cc.Particle.ModeA} [modeB=]
+ */
+cc.Particle = function (pos, startPos, color, deltaColor, size, deltaSize, rotation, deltaRotation, timeToLive, atlasIndex, modeA, modeB) {
+ this.pos = pos ? pos : cc.p(0, 0);
+ this.startPos = startPos ? startPos : cc.p(0, 0);
+ this.color = color ? color : {r: 0, g: 0, b: 0, a: 255};
+ this.deltaColor = deltaColor ? deltaColor : {r: 0, g: 0, b: 0, a: 255};
+ this.size = size || 0;
+ this.deltaSize = deltaSize || 0;
+ this.rotation = rotation || 0;
+ this.deltaRotation = deltaRotation || 0;
+ this.timeToLive = timeToLive || 0;
+ this.atlasIndex = atlasIndex || 0;
+ this.modeA = modeA ? modeA : new cc.Particle.ModeA();
+ this.modeB = modeB ? modeB : new cc.Particle.ModeB();
+ this.isChangeColor = false;
+ this.drawPos = cc.p(0, 0);
+};
+
+/**
+ * Mode A: gravity, direction, radial accel, tangential accel
+ * @Class
+ * @Construct
+ * @param {cc.Point} dir direction of particle
+ * @param {Number} radialAccel
+ * @param {Number} tangentialAccel
+ */
+cc.Particle.ModeA = function (dir, radialAccel, tangentialAccel) {
+ this.dir = dir ? dir : cc.p(0, 0);
+ this.radialAccel = radialAccel || 0;
+ this.tangentialAccel = tangentialAccel || 0;
+};
+
+/**
+ * Mode B: radius mode
+ * @Class
+ * @Construct
+ * @param {Number} angle
+ * @param {Number} degreesPerSecond
+ * @param {Number} radius
+ * @param {Number} deltaRadius
+ */
+cc.Particle.ModeB = function (angle, degreesPerSecond, radius, deltaRadius) {
+ this.angle = angle || 0;
+ this.degreesPerSecond = degreesPerSecond || 0;
+ this.radius = radius || 0;
+ this.deltaRadius = deltaRadius || 0;
+};
+
+/**
+ * Array of Point instances used to optimize particle updates
+ */
+cc.Particle.TemporaryPoints = [
+ cc.p(),
+ cc.p(),
+ cc.p(),
+ cc.p()
+];
+
+/**
+ *
+ * Particle System base class.
+ * Attributes of a Particle System:
+ * - emission rate of the particles
+ * - Gravity Mode (Mode A):
+ * - gravity
+ * - direction
+ * - speed +- variance
+ * - tangential acceleration +- variance
+ * - radial acceleration +- variance
+ * - Radius Mode (Mode B):
+ * - startRadius +- variance
+ * - endRadius +- variance
+ * - rotate +- variance
+ * - Properties common to all modes:
+ * - life +- life variance
+ * - start spin +- variance
+ * - end spin +- variance
+ * - start size +- variance
+ * - end size +- variance
+ * - start color +- variance
+ * - end color +- variance
+ * - life +- variance
+ * - blending function
+ * - texture
+ *
+ * cocos2d also supports particles generated by Particle Designer (http://particledesigner.71squared.com/).
+ * 'Radius Mode' in Particle Designer uses a fixed emit rate of 30 hz. Since that can't be guarateed in cocos2d,
+ * cocos2d uses a another approach, but the results are almost identical.
+ * cocos2d supports all the variables used by Particle Designer plus a bit more:
+ * - spinning particles (supported when using ParticleSystem)
+ * - tangential acceleration (Gravity mode)
+ * - radial acceleration (Gravity mode)
+ * - radius direction (Radius mode) (Particle Designer supports outwards to inwards direction only)
+ * It is possible to customize any of the above mentioned properties in runtime. Example:
+ *
+ * @class
+ * @extends cc.Node
+ *
+ * @property {Boolean} opacityModifyRGB - Indicate whether the alpha value modify color.
+ * @property {cc.SpriteBatchNode} batchNode - Weak reference to the sprite batch node.
+ * @property {Boolean} active - <@readonly> Indicate whether the particle system is activated.
+ * @property {Number} shapeType - ShapeType of ParticleSystem : cc.ParticleSystem.BALL_SHAPE | cc.ParticleSystem.STAR_SHAPE.
+ * @property {Number} atlasIndex - Index of system in batch node array.
+ * @property {Number} particleCount - Current quantity of particles that are being simulated.
+ * @property {Number} duration - How many seconds the emitter wil run. -1 means 'forever'
+ * @property {cc.Point} sourcePos - Source position of the emitter.
+ * @property {cc.Point} posVar - Variation of source position.
+ * @property {Number} life - Life of each particle setter.
+ * @property {Number} lifeVar - Variation of life.
+ * @property {Number} angle - Angle of each particle setter.
+ * @property {Number} angleVar - Variation of angle of each particle setter.
+ * @property {Number} startSize - Start size in pixels of each particle.
+ * @property {Number} startSizeVar - Variation of start size in pixels.
+ * @property {Number} endSize - End size in pixels of each particle.
+ * @property {Number} endSizeVar - Variation of end size in pixels.
+ * @property {Number} startSpin - Start angle of each particle.
+ * @property {Number} startSpinVar - Variation of start angle.
+ * @property {Number} endSpin - End angle of each particle.
+ * @property {Number} endSpinVar - Variation of end angle.
+ * @property {cc.Point} gravity - Gravity of the emitter.
+ * @property {cc.Point} speed - Speed of the emitter.
+ * @property {cc.Point} speedVar - Variation of the speed.
+ * @property {Number} tangentialAccel - Tangential acceleration of each particle. Only available in 'Gravity' mode.
+ * @property {Number} tangentialAccelVar - Variation of the tangential acceleration.
+ * @property {Number} tangentialAccel - Radial acceleration of each particle. Only available in 'Gravity' mode.
+ * @property {Number} tangentialAccelVar - Variation of the radial acceleration.
+ * @property {Boolean} rotationIsDir - Indicate whether the rotation of each particle equals to its direction. Only available in 'Gravity' mode.
+ * @property {Number} startRadius - Starting radius of the particles. Only available in 'Radius' mode.
+ * @property {Number} startRadiusVar - Variation of the starting radius.
+ * @property {Number} endRadius - Ending radius of the particles. Only available in 'Radius' mode.
+ * @property {Number} endRadiusVar - Variation of the ending radius.
+ * @property {Number} rotatePerS - Number of degress to rotate a particle around the source pos per second. Only available in 'Radius' mode.
+ * @property {Number} rotatePerSVar - Variation of the degress to rotate a particle around the source pos per second.
+ * @property {cc.Color} startColor - Start color of each particle.
+ * @property {cc.Color} startColorVar - Variation of the start color.
+ * @property {cc.Color} endColor - Ending color of each particle.
+ * @property {cc.Color} endColorVar - Variation of the end color.
+ * @property {Number} emissionRate - Emission rate of the particles.
+ * @property {Number} emitterMode - Emitter modes: CCParticleSystem.MODE_GRAVITY: uses gravity, speed, radial and tangential acceleration; CCParticleSystem.MODE_RADIUS: uses radius movement + rotation.
+ * @property {Number} positionType - Particles movement type: cc.ParticleSystem.TYPE_FREE | cc.ParticleSystem.TYPE_GROUPED.
+ * @property {Number} totalParticles - Maximum particles of the system.
+ * @property {Boolean} autoRemoveOnFinish - Indicate whether the node will be auto-removed when it has no particles left.
+ * @property {cc.Texture2D|HTMLImageElement|HTMLCanvasElement} texture - Texture of Particle System.
+ *
+ * @example
+ * emitter.radialAccel = 15;
+ * emitter.startSpin = 0;
+ */
+cc.ParticleSystem = cc.Node.extend(/** @lends cc.ParticleSystem# */{
+ _className: "ParticleSystem",
+ //***********variables*************
+ _plistFile: "",
+ //! time elapsed since the start of the system (in seconds)
+ _elapsed: 0,
+ _dontTint: false,
+
+ // Different modes
+ //! Mode A:Gravity + Tangential Accel + Radial Accel
+ modeA: null,
+ //! Mode B: circular movement (gravity, radial accel and tangential accel don't are not used in this mode)
+ modeB: null,
+
+ //private POINTZERO for ParticleSystem
+ _pointZeroForParticle: cc.p(0, 0),
+
+ //! Array of particles
+ _particles: null,
+
+ // color modulate
+ // BOOL colorModulate;
+
+ //! How many particles can be emitted per second
+ _emitCounter: 0,
+ //! particle idx
+ _particleIdx: 0,
+
+ _batchNode: null,
+ atlasIndex: 0,
+
+ //true if scaled or rotated
+ _transformSystemDirty: false,
+ _allocatedParticles: 0,
+
+ _isActive: false,
+ particleCount: 0,
+ duration: 0,
+ _sourcePosition: null,
+ _posVar: null,
+ life: 0,
+ lifeVar: 0,
+ angle: 0,
+ angleVar: 0,
+ startSize: 0,
+ startSizeVar: 0,
+ endSize: 0,
+ endSizeVar: 0,
+ _startColor: null,
+ _startColorVar: null,
+ _endColor: null,
+ _endColorVar: null,
+ startSpin: 0,
+ startSpinVar: 0,
+ endSpin: 0,
+ endSpinVar: 0,
+ emissionRate: 0,
+ _totalParticles: 0,
+ _texture: null,
+ _blendFunc: null,
+ _opacityModifyRGB: false,
+ positionType: null,
+ autoRemoveOnFinish: false,
+ emitterMode: 0,
+
+ _textureLoaded: null,
+
+ /**
+ * return the string found by key in dict.
+ * This plist files can be create manually or with Particle Designer:
+ * http://particledesigner.71squared.com/
+ *
+ * Constructor of cc.ParticleSystem
+ * @param {String|Number} plistFile
+ */
+ ctor: function (plistFile) {
+ cc.Node.prototype.ctor.call(this);
+ this.emitterMode = cc.ParticleSystem.MODE_GRAVITY;
+ this.modeA = new cc.ParticleSystem.ModeA();
+ this.modeB = new cc.ParticleSystem.ModeB();
+ this._blendFunc = {src: cc.BLEND_SRC, dst: cc.BLEND_DST};
+
+ this._particles = [];
+ this._sourcePosition = cc.p(0, 0);
+ this._posVar = cc.p(0, 0);
+
+ this._startColor = cc.color(255, 255, 255, 255);
+ this._startColorVar = cc.color(255, 255, 255, 255);
+ this._endColor = cc.color(255, 255, 255, 255);
+ this._endColorVar = cc.color(255, 255, 255, 255);
+
+ this._plistFile = "";
+ this._elapsed = 0;
+ this._dontTint = false;
+ this._pointZeroForParticle = cc.p(0, 0);
+ this._emitCounter = 0;
+ this._particleIdx = 0;
+ this._batchNode = null;
+ this.atlasIndex = 0;
+
+ this._transformSystemDirty = false;
+ this._allocatedParticles = 0;
+ this._isActive = false;
+ this.particleCount = 0;
+ this.duration = 0;
+ this.life = 0;
+ this.lifeVar = 0;
+ this.angle = 0;
+ this.angleVar = 0;
+ this.startSize = 0;
+ this.startSizeVar = 0;
+ this.endSize = 0;
+ this.endSizeVar = 0;
+
+ this.startSpin = 0;
+ this.startSpinVar = 0;
+ this.endSpin = 0;
+ this.endSpinVar = 0;
+ this.emissionRate = 0;
+ this._totalParticles = 0;
+ this._texture = null;
+ this._opacityModifyRGB = false;
+ this.positionType = cc.ParticleSystem.TYPE_FREE;
+ this.autoRemoveOnFinish = false;
+
+ this._textureLoaded = true;
+
+ if (!plistFile || cc.isNumber(plistFile)) {
+ var ton = plistFile || 100;
+ this.setDrawMode(cc.ParticleSystem.TEXTURE_MODE);
+ this.initWithTotalParticles(ton);
+ } else if (cc.isString(plistFile)) {
+ this.initWithFile(plistFile);
+ } else if (cc.isObject(plistFile)) {
+ this.initWithDictionary(plistFile, "");
+ }
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.ParticleSystem.CanvasRenderCmd(this);
+ else
+ return new cc.ParticleSystem.WebGLRenderCmd(this);
+ },
+
+ /**
+ * This is a hack function for performance, it's only available on Canvas mode.
+ * It's very expensive to change color on Canvas mode, so if set it to true, particle system will ignore the changing color operation.
+ * @param {boolean} ignore
+ */
+ ignoreColor: function (ignore) {
+ this._dontTint = ignore;
+ },
+
+ /**
+ * initializes the texture with a rectangle measured Points
+ * pointRect should be in Texture coordinates, not pixel coordinates
+ *
+ * @param {cc.Rect} pointRect
+ */
+ initTexCoordsWithRect: function (pointRect) {
+ this._renderCmd.initTexCoordsWithRect(pointRect);
+ },
+
+ /**
+ * return weak reference to the cc.SpriteBatchNode that renders the cc.Sprite
+ * @return {cc.ParticleBatchNode}
+ */
+ getBatchNode: function () {
+ return this._batchNode;
+ },
+
+ /**
+ * set weak reference to the cc.SpriteBatchNode that renders the cc.Sprite
+ * @param {cc.ParticleBatchNode} batchNode
+ */
+ setBatchNode: function (batchNode) {
+ this._renderCmd.setBatchNode(batchNode);
+ },
+
+ /**
+ * return index of system in batch node array
+ * @return {Number}
+ */
+ getAtlasIndex: function () {
+ return this.atlasIndex;
+ },
+
+ /**
+ * set index of system in batch node array
+ * @param {Number} atlasIndex
+ */
+ setAtlasIndex: function (atlasIndex) {
+ this.atlasIndex = atlasIndex;
+ },
+
+ /**
+ * Return DrawMode of ParticleSystem (Canvas Mode only)
+ * @return {Number}
+ */
+ getDrawMode: function () {
+ return this._renderCmd.getDrawMode();
+ },
+
+ /**
+ * DrawMode of ParticleSystem setter (Canvas Mode only)
+ * @param {Number} drawMode
+ */
+ setDrawMode: function (drawMode) {
+ this._renderCmd.setDrawMode(drawMode);
+ },
+
+ /**
+ * Return ShapeType of ParticleSystem (Canvas Mode only)
+ * @return {Number}
+ */
+ getShapeType: function () {
+ return this._renderCmd.getShapeType();
+ },
+
+ /**
+ * ShapeType of ParticleSystem setter (Canvas Mode only)
+ * @param {Number} shapeType
+ */
+ setShapeType: function (shapeType) {
+ this._renderCmd.setShapeType(shapeType);
+ },
+
+ /**
+ * Return ParticleSystem is active
+ * @return {Boolean}
+ */
+ isActive: function () {
+ return this._isActive;
+ },
+
+ /**
+ * Quantity of particles that are being simulated at the moment
+ * @return {Number}
+ */
+ getParticleCount: function () {
+ return this.particleCount;
+ },
+
+ /**
+ * Quantity of particles setter
+ * @param {Number} particleCount
+ */
+ setParticleCount: function (particleCount) {
+ this.particleCount = particleCount;
+ },
+
+ /**
+ * How many seconds the emitter wil run. -1 means 'forever'
+ * @return {Number}
+ */
+ getDuration: function () {
+ return this.duration;
+ },
+
+ /**
+ * set run seconds of the emitter
+ * @param {Number} duration
+ */
+ setDuration: function (duration) {
+ this.duration = duration;
+ },
+
+ /**
+ * Return sourcePosition of the emitter
+ * @return {cc.Point | Object}
+ */
+ getSourcePosition: function () {
+ return {x: this._sourcePosition.x, y: this._sourcePosition.y};
+ },
+
+ /**
+ * sourcePosition of the emitter setter
+ * @param sourcePosition
+ */
+ setSourcePosition: function (sourcePosition) {
+ this._sourcePosition.x = sourcePosition.x;
+ this._sourcePosition.y = sourcePosition.y;
+ },
+
+ /**
+ * Return Position variance of the emitter
+ * @return {cc.Point | Object}
+ */
+ getPosVar: function () {
+ return {x: this._posVar.x, y: this._posVar.y};
+ },
+
+ /**
+ * Position variance of the emitter setter
+ * @param {cc.Point} posVar
+ */
+ setPosVar: function (posVar) {
+ this._posVar.x = posVar.x;
+ this._posVar.y = posVar.y;
+ },
+
+ /**
+ * Return life of each particle
+ * @return {Number}
+ */
+ getLife: function () {
+ return this.life;
+ },
+
+ /**
+ * life of each particle setter
+ * @param {Number} life
+ */
+ setLife: function (life) {
+ this.life = life;
+ },
+
+ /**
+ * Return life variance of each particle
+ * @return {Number}
+ */
+ getLifeVar: function () {
+ return this.lifeVar;
+ },
+
+ /**
+ * life variance of each particle setter
+ * @param {Number} lifeVar
+ */
+ setLifeVar: function (lifeVar) {
+ this.lifeVar = lifeVar;
+ },
+
+ /**
+ * Return angle of each particle
+ * @return {Number}
+ */
+ getAngle: function () {
+ return this.angle;
+ },
+
+ /**
+ * angle of each particle setter
+ * @param {Number} angle
+ */
+ setAngle: function (angle) {
+ this.angle = angle;
+ },
+
+ /**
+ * Return angle variance of each particle
+ * @return {Number}
+ */
+ getAngleVar: function () {
+ return this.angleVar;
+ },
+
+ /**
+ * angle variance of each particle setter
+ * @param angleVar
+ */
+ setAngleVar: function (angleVar) {
+ this.angleVar = angleVar;
+ },
+
+ // mode A
+ /**
+ * Return Gravity of emitter
+ * @return {cc.Point}
+ */
+ getGravity: function () {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.getGravity() : Particle Mode should be Gravity");
+ var locGravity = this.modeA.gravity;
+ return cc.p(locGravity.x, locGravity.y);
+ },
+
+ /**
+ * Gravity of emitter setter
+ * @param {cc.Point} gravity
+ */
+ setGravity: function (gravity) {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.setGravity() : Particle Mode should be Gravity");
+ this.modeA.gravity = gravity;
+ },
+
+ /**
+ * Return Speed of each particle
+ * @return {Number}
+ */
+ getSpeed: function () {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.getSpeed() : Particle Mode should be Gravity");
+ return this.modeA.speed;
+ },
+
+ /**
+ * Speed of each particle setter
+ * @param {Number} speed
+ */
+ setSpeed: function (speed) {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.setSpeed() : Particle Mode should be Gravity");
+ this.modeA.speed = speed;
+ },
+
+ /**
+ * return speed variance of each particle. Only available in 'Gravity' mode.
+ * @return {Number}
+ */
+ getSpeedVar: function () {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.getSpeedVar() : Particle Mode should be Gravity");
+ return this.modeA.speedVar;
+ },
+
+ /**
+ * speed variance of each particle setter. Only available in 'Gravity' mode.
+ * @param {Number} speedVar
+ */
+ setSpeedVar: function (speedVar) {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.setSpeedVar() : Particle Mode should be Gravity");
+ this.modeA.speedVar = speedVar;
+ },
+
+ /**
+ * Return tangential acceleration of each particle. Only available in 'Gravity' mode.
+ * @return {Number}
+ */
+ getTangentialAccel: function () {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.getTangentialAccel() : Particle Mode should be Gravity");
+ return this.modeA.tangentialAccel;
+ },
+
+ /**
+ * Tangential acceleration of each particle setter. Only available in 'Gravity' mode.
+ * @param {Number} tangentialAccel
+ */
+ setTangentialAccel: function (tangentialAccel) {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.setTangentialAccel() : Particle Mode should be Gravity");
+ this.modeA.tangentialAccel = tangentialAccel;
+ },
+
+ /**
+ * Return tangential acceleration variance of each particle. Only available in 'Gravity' mode.
+ * @return {Number}
+ */
+ getTangentialAccelVar: function () {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.getTangentialAccelVar() : Particle Mode should be Gravity");
+ return this.modeA.tangentialAccelVar;
+ },
+
+ /**
+ * tangential acceleration variance of each particle setter. Only available in 'Gravity' mode.
+ * @param {Number} tangentialAccelVar
+ */
+ setTangentialAccelVar: function (tangentialAccelVar) {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.setTangentialAccelVar() : Particle Mode should be Gravity");
+ this.modeA.tangentialAccelVar = tangentialAccelVar;
+ },
+
+ /**
+ * Return radial acceleration of each particle. Only available in 'Gravity' mode.
+ * @return {Number}
+ */
+ getRadialAccel: function () {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.getRadialAccel() : Particle Mode should be Gravity");
+ return this.modeA.radialAccel;
+ },
+
+ /**
+ * radial acceleration of each particle setter. Only available in 'Gravity' mode.
+ * @param {Number} radialAccel
+ */
+ setRadialAccel: function (radialAccel) {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.setRadialAccel() : Particle Mode should be Gravity");
+ this.modeA.radialAccel = radialAccel;
+ },
+
+ /**
+ * Return radial acceleration variance of each particle. Only available in 'Gravity' mode.
+ * @return {Number}
+ */
+ getRadialAccelVar: function () {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.getRadialAccelVar() : Particle Mode should be Gravity");
+ return this.modeA.radialAccelVar;
+ },
+
+ /**
+ * radial acceleration variance of each particle setter. Only available in 'Gravity' mode.
+ * @param {Number} radialAccelVar
+ */
+ setRadialAccelVar: function (radialAccelVar) {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.setRadialAccelVar() : Particle Mode should be Gravity");
+ this.modeA.radialAccelVar = radialAccelVar;
+ },
+
+ /**
+ * get the rotation of each particle to its direction Only available in 'Gravity' mode.
+ * @returns {boolean}
+ */
+ getRotationIsDir: function () {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.getRotationIsDir() : Particle Mode should be Gravity");
+ return this.modeA.rotationIsDir;
+ },
+
+ /**
+ * set the rotation of each particle to its direction Only available in 'Gravity' mode.
+ * @param {boolean} t
+ */
+ setRotationIsDir: function (t) {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_GRAVITY)
+ cc.log("cc.ParticleBatchNode.setRotationIsDir() : Particle Mode should be Gravity");
+ this.modeA.rotationIsDir = t;
+ },
+
+ // mode B
+ /**
+ * Return starting radius of the particles. Only available in 'Radius' mode.
+ * @return {Number}
+ */
+ getStartRadius: function () {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_RADIUS)
+ cc.log("cc.ParticleBatchNode.getStartRadius() : Particle Mode should be Radius");
+ return this.modeB.startRadius;
+ },
+
+ /**
+ * starting radius of the particles setter. Only available in 'Radius' mode.
+ * @param {Number} startRadius
+ */
+ setStartRadius: function (startRadius) {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_RADIUS)
+ cc.log("cc.ParticleBatchNode.setStartRadius() : Particle Mode should be Radius");
+ this.modeB.startRadius = startRadius;
+ },
+
+ /**
+ * Return starting radius variance of the particles. Only available in 'Radius' mode.
+ * @return {Number}
+ */
+ getStartRadiusVar: function () {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_RADIUS)
+ cc.log("cc.ParticleBatchNode.getStartRadiusVar() : Particle Mode should be Radius");
+ return this.modeB.startRadiusVar;
+ },
+
+ /**
+ * starting radius variance of the particles setter. Only available in 'Radius' mode.
+ * @param {Number} startRadiusVar
+ */
+ setStartRadiusVar: function (startRadiusVar) {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_RADIUS)
+ cc.log("cc.ParticleBatchNode.setStartRadiusVar() : Particle Mode should be Radius");
+ this.modeB.startRadiusVar = startRadiusVar;
+ },
+
+ /**
+ * Return ending radius of the particles. Only available in 'Radius' mode.
+ * @return {Number}
+ */
+ getEndRadius: function () {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_RADIUS)
+ cc.log("cc.ParticleBatchNode.getEndRadius() : Particle Mode should be Radius");
+ return this.modeB.endRadius;
+ },
+
+ /**
+ * ending radius of the particles setter. Only available in 'Radius' mode.
+ * @param {Number} endRadius
+ */
+ setEndRadius: function (endRadius) {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_RADIUS)
+ cc.log("cc.ParticleBatchNode.setEndRadius() : Particle Mode should be Radius");
+ this.modeB.endRadius = endRadius;
+ },
+
+ /**
+ * Return ending radius variance of the particles. Only available in 'Radius' mode.
+ * @return {Number}
+ */
+ getEndRadiusVar: function () {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_RADIUS)
+ cc.log("cc.ParticleBatchNode.getEndRadiusVar() : Particle Mode should be Radius");
+ return this.modeB.endRadiusVar;
+ },
+
+ /**
+ * ending radius variance of the particles setter. Only available in 'Radius' mode.
+ * @param endRadiusVar
+ */
+ setEndRadiusVar: function (endRadiusVar) {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_RADIUS)
+ cc.log("cc.ParticleBatchNode.setEndRadiusVar() : Particle Mode should be Radius");
+ this.modeB.endRadiusVar = endRadiusVar;
+ },
+
+ /**
+ * get Number of degress to rotate a particle around the source pos per second. Only available in 'Radius' mode.
+ * @return {Number}
+ */
+ getRotatePerSecond: function () {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_RADIUS)
+ cc.log("cc.ParticleBatchNode.getRotatePerSecond() : Particle Mode should be Radius");
+ return this.modeB.rotatePerSecond;
+ },
+
+ /**
+ * set Number of degress to rotate a particle around the source pos per second. Only available in 'Radius' mode.
+ * @param {Number} degrees
+ */
+ setRotatePerSecond: function (degrees) {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_RADIUS)
+ cc.log("cc.ParticleBatchNode.setRotatePerSecond() : Particle Mode should be Radius");
+ this.modeB.rotatePerSecond = degrees;
+ },
+
+ /**
+ * Return Variance in degrees for rotatePerSecond. Only available in 'Radius' mode.
+ * @return {Number}
+ */
+ getRotatePerSecondVar: function () {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_RADIUS)
+ cc.log("cc.ParticleBatchNode.getRotatePerSecondVar() : Particle Mode should be Radius");
+ return this.modeB.rotatePerSecondVar;
+ },
+
+ /**
+ * Variance in degrees for rotatePerSecond setter. Only available in 'Radius' mode.
+ * @param degrees
+ */
+ setRotatePerSecondVar: function (degrees) {
+ if (this.emitterMode !== cc.ParticleSystem.MODE_RADIUS)
+ cc.log("cc.ParticleBatchNode.setRotatePerSecondVar() : Particle Mode should be Radius");
+ this.modeB.rotatePerSecondVar = degrees;
+ },
+ //////////////////////////////////////////////////////////////////////////
+
+ //don't use a transform matrix, this is faster
+ setScale: function (scale, scaleY) {
+ this._transformSystemDirty = true;
+ cc.Node.prototype.setScale.call(this, scale, scaleY);
+ },
+
+ setRotation: function (newRotation) {
+ this._transformSystemDirty = true;
+ cc.Node.prototype.setRotation.call(this, newRotation);
+ },
+
+ setScaleX: function (newScaleX) {
+ this._transformSystemDirty = true;
+ cc.Node.prototype.setScaleX.call(this, newScaleX);
+ },
+
+ setScaleY: function (newScaleY) {
+ this._transformSystemDirty = true;
+ cc.Node.prototype.setScaleY.call(this, newScaleY);
+ },
+
+ /**
+ * get start size in pixels of each particle
+ * @return {Number}
+ */
+ getStartSize: function () {
+ return this.startSize;
+ },
+
+ /**
+ * set start size in pixels of each particle
+ * @param {Number} startSize
+ */
+ setStartSize: function (startSize) {
+ this.startSize = startSize;
+ },
+
+ /**
+ * get size variance in pixels of each particle
+ * @return {Number}
+ */
+ getStartSizeVar: function () {
+ return this.startSizeVar;
+ },
+
+ /**
+ * set size variance in pixels of each particle
+ * @param {Number} startSizeVar
+ */
+ setStartSizeVar: function (startSizeVar) {
+ this.startSizeVar = startSizeVar;
+ },
+
+ /**
+ * get end size in pixels of each particle
+ * @return {Number}
+ */
+ getEndSize: function () {
+ return this.endSize;
+ },
+
+ /**
+ * set end size in pixels of each particle
+ * @param endSize
+ */
+ setEndSize: function (endSize) {
+ this.endSize = endSize;
+ },
+
+ /**
+ * get end size variance in pixels of each particle
+ * @return {Number}
+ */
+ getEndSizeVar: function () {
+ return this.endSizeVar;
+ },
+
+ /**
+ * set end size variance in pixels of each particle
+ * @param {Number} endSizeVar
+ */
+ setEndSizeVar: function (endSizeVar) {
+ this.endSizeVar = endSizeVar;
+ },
+
+ /**
+ * set start color of each particle
+ * @return {cc.Color}
+ */
+ getStartColor: function () {
+ return cc.color(this._startColor.r, this._startColor.g, this._startColor.b, this._startColor.a);
+ },
+
+ /**
+ * get start color of each particle
+ * @param {cc.Color} startColor
+ */
+ setStartColor: function (startColor) {
+ this._startColor.r = startColor.r;
+ this._startColor.g = startColor.g;
+ this._startColor.b = startColor.b;
+ this._startColor.a = startColor.a;
+ },
+
+ /**
+ * get start color variance of each particle
+ * @return {cc.Color}
+ */
+ getStartColorVar: function () {
+ return cc.color(this._startColorVar.r, this._startColorVar.g, this._startColorVar.b, this._startColorVar.a);
+ },
+
+ /**
+ * set start color variance of each particle
+ * @param {cc.Color} startColorVar
+ */
+ setStartColorVar: function (startColorVar) {
+ this._startColorVar.r = startColorVar.r;
+ this._startColorVar.g = startColorVar.g;
+ this._startColorVar.b = startColorVar.b;
+ this._startColorVar.a = startColorVar.a;
+ },
+
+ /**
+ * get end color and end color variation of each particle
+ * @return {cc.Color}
+ */
+ getEndColor: function () {
+ return cc.color(this._endColor.r, this._endColor.g, this._endColor.b, this._endColor.a);
+ },
+
+ /**
+ * set end color and end color variation of each particle
+ * @param {cc.Color} endColor
+ */
+ setEndColor: function (endColor) {
+ this._endColor.r = endColor.r;
+ this._endColor.g = endColor.g;
+ this._endColor.b = endColor.b;
+ this._endColor.a = endColor.a;
+ },
+
+ /**
+ * get end color variance of each particle
+ * @return {cc.Color}
+ */
+ getEndColorVar: function () {
+ return cc.color(this._endColorVar.r, this._endColorVar.g, this._endColorVar.b, this._endColorVar.a);
+ },
+
+ /**
+ * set end color variance of each particle
+ * @param {cc.Color} endColorVar
+ */
+ setEndColorVar: function (endColorVar) {
+ this._endColorVar.r = endColorVar.r;
+ this._endColorVar.g = endColorVar.g;
+ this._endColorVar.b = endColorVar.b;
+ this._endColorVar.a = endColorVar.a;
+ },
+
+ /**
+ * get initial angle of each particle
+ * @return {Number}
+ */
+ getStartSpin: function () {
+ return this.startSpin;
+ },
+
+ /**
+ * set initial angle of each particle
+ * @param {Number} startSpin
+ */
+ setStartSpin: function (startSpin) {
+ this.startSpin = startSpin;
+ },
+
+ /**
+ * get initial angle variance of each particle
+ * @return {Number}
+ */
+ getStartSpinVar: function () {
+ return this.startSpinVar;
+ },
+
+ /**
+ * set initial angle variance of each particle
+ * @param {Number} startSpinVar
+ */
+ setStartSpinVar: function (startSpinVar) {
+ this.startSpinVar = startSpinVar;
+ },
+
+ /**
+ * get end angle of each particle
+ * @return {Number}
+ */
+ getEndSpin: function () {
+ return this.endSpin;
+ },
+
+ /**
+ * set end angle of each particle
+ * @param {Number} endSpin
+ */
+ setEndSpin: function (endSpin) {
+ this.endSpin = endSpin;
+ },
+
+ /**
+ * get end angle variance of each particle
+ * @return {Number}
+ */
+ getEndSpinVar: function () {
+ return this.endSpinVar;
+ },
+
+ /**
+ * set end angle variance of each particle
+ * @param {Number} endSpinVar
+ */
+ setEndSpinVar: function (endSpinVar) {
+ this.endSpinVar = endSpinVar;
+ },
+
+ /**
+ * get emission rate of the particles
+ * @return {Number}
+ */
+ getEmissionRate: function () {
+ return this.emissionRate;
+ },
+
+ /**
+ * set emission rate of the particles
+ * @param {Number} emissionRate
+ */
+ setEmissionRate: function (emissionRate) {
+ this.emissionRate = emissionRate;
+ },
+
+ /**
+ * get maximum particles of the system
+ * @return {Number}
+ */
+ getTotalParticles: function () {
+ return this._totalParticles;
+ },
+
+ /**
+ * set maximum particles of the system
+ * @param {Number} tp totalParticles
+ */
+ setTotalParticles: function (tp) {
+ this._renderCmd.setTotalParticles(tp);
+ },
+
+ /**
+ * get Texture of Particle System
+ * @return {cc.Texture2D}
+ */
+ getTexture: function () {
+ return this._texture;
+ },
+
+ /**
+ * set Texture of Particle System
+ * @param {cc.Texture2D } texture
+ */
+ setTexture: function (texture) {
+ if (!texture)
+ return;
+
+ if (texture.isLoaded()) {
+ this.setTextureWithRect(texture, cc.rect(0, 0, texture.width, texture.height));
+ } else {
+ this._textureLoaded = false;
+ texture.addEventListener("load", function (sender) {
+ this._textureLoaded = true;
+ this.setTextureWithRect(sender, cc.rect(0, 0, sender.width, sender.height));
+ }, this);
+ }
+ },
+
+ /** conforms to CocosNodeTexture protocol */
+ /**
+ * get BlendFunc of Particle System
+ * @return {cc.BlendFunc}
+ */
+ getBlendFunc: function () {
+ return this._blendFunc;
+ },
+
+ /**
+ * set BlendFunc of Particle System
+ * @param {Number} src
+ * @param {Number} dst
+ */
+ setBlendFunc: function (src, dst) {
+ if (dst === undefined) {
+ if (this._blendFunc !== src) {
+ this._blendFunc = src;
+ this._updateBlendFunc();
+ }
+ } else {
+ if (this._blendFunc.src !== src || this._blendFunc.dst !== dst) {
+ this._blendFunc = {src: src, dst: dst};
+ this._updateBlendFunc();
+ }
+ }
+ },
+
+ /**
+ * does the alpha value modify color getter
+ * @return {Boolean}
+ */
+ isOpacityModifyRGB: function () {
+ return this._opacityModifyRGB;
+ },
+
+ /**
+ * does the alpha value modify color setter
+ * @param newValue
+ */
+ setOpacityModifyRGB: function (newValue) {
+ this._opacityModifyRGB = newValue;
+ },
+
+ /**
+ * whether or not the particles are using blend additive.
+ * If enabled, the following blending function will be used.
+ *
+ * @return {Boolean}
+ * @example
+ * source blend function = GL_SRC_ALPHA;
+ * dest blend function = GL_ONE;
+ */
+ isBlendAdditive: function () {
+ return (( this._blendFunc.src === cc.SRC_ALPHA && this._blendFunc.dst === cc.ONE) || (this._blendFunc.src === cc.ONE && this._blendFunc.dst === cc.ONE));
+ },
+
+ /**
+ * whether or not the particles are using blend additive.
+ * If enabled, the following blending function will be used.
+ *
+ * @param {Boolean} isBlendAdditive
+ */
+ setBlendAdditive: function (isBlendAdditive) {
+ var locBlendFunc = this._blendFunc;
+ if (isBlendAdditive) {
+ locBlendFunc.src = cc.SRC_ALPHA;
+ locBlendFunc.dst = cc.ONE;
+ } else {
+ this._renderCmd._setBlendAdditive();
+ }
+ },
+
+ /**
+ * get particles movement type: Free or Grouped
+ * @return {Number}
+ */
+ getPositionType: function () {
+ return this.positionType;
+ },
+
+ /**
+ * set particles movement type: Free or Grouped
+ * @param {Number} positionType
+ */
+ setPositionType: function (positionType) {
+ this.positionType = positionType;
+ },
+
+ /**
+ * return whether or not the node will be auto-removed when it has no particles left.
+ * By default it is false.
+ *
+ * @return {Boolean}
+ */
+ isAutoRemoveOnFinish: function () {
+ return this.autoRemoveOnFinish;
+ },
+
+ /**
+ * set whether or not the node will be auto-removed when it has no particles left.
+ * By default it is false.
+ *
+ * @param {Boolean} isAutoRemoveOnFinish
+ */
+ setAutoRemoveOnFinish: function (isAutoRemoveOnFinish) {
+ this.autoRemoveOnFinish = isAutoRemoveOnFinish;
+ },
+
+ /**
+ * return kind of emitter modes
+ * @return {Number}
+ */
+ getEmitterMode: function () {
+ return this.emitterMode;
+ },
+
+ /**
+ * Switch between different kind of emitter modes:
+ * - CCParticleSystem.MODE_GRAVITY: uses gravity, speed, radial and tangential acceleration
+ * - CCParticleSystem.MODE_RADIUS: uses radius movement + rotation
+ *
+ * @param {Number} emitterMode
+ */
+ setEmitterMode: function (emitterMode) {
+ this.emitterMode = emitterMode;
+ },
+
+ /**
+ * initializes a cc.ParticleSystem
+ */
+ init: function () {
+ return this.initWithTotalParticles(150);
+ },
+
+ /**
+ *
+ * initializes a CCParticleSystem from a plist file.
+ * This plist files can be creted manually or with Particle Designer:
+ * http://particledesigner.71squared.com/
+ *
+ * @param {String} plistFile
+ * @return {boolean}
+ */
+ initWithFile: function (plistFile) {
+ this._plistFile = plistFile;
+ var dict = cc.loader.getRes(plistFile);
+ if (!dict) {
+ cc.log("cc.ParticleSystem.initWithFile(): Particles: file not found");
+ return false;
+ }
+
+ // XXX compute path from a path, should define a function somewhere to do it
+ return this.initWithDictionary(dict, "");
+ },
+
+ /**
+ * return bounding box of particle system in world space
+ * @return {cc.Rect}
+ */
+ getBoundingBoxToWorld: function () {
+ return cc.rect(0, 0, cc._canvas.width, cc._canvas.height);
+ },
+
+ /**
+ * initializes a particle system from a NSDictionary and the path from where to load the png
+ * @param {object} dictionary
+ * @param {String} dirname
+ * @return {Boolean}
+ */
+ initWithDictionary: function (dictionary, dirname) {
+ var ret = false;
+ var buffer = null;
+ var image = null;
+ var locValueForKey = this._valueForKey;
+
+ var maxParticles = parseInt(locValueForKey("maxParticles", dictionary));
+ // self, not super
+ if (this.initWithTotalParticles(maxParticles)) {
+ // angle
+ this.angle = parseFloat(locValueForKey("angle", dictionary));
+ this.angleVar = parseFloat(locValueForKey("angleVariance", dictionary));
+
+ // duration
+ this.duration = parseFloat(locValueForKey("duration", dictionary));
+
+ // blend function
+ this._blendFunc.src = parseInt(locValueForKey("blendFuncSource", dictionary));
+ this._blendFunc.dst = parseInt(locValueForKey("blendFuncDestination", dictionary));
+
+ // color
+ var locStartColor = this._startColor;
+ locStartColor.r = parseFloat(locValueForKey("startColorRed", dictionary)) * 255;
+ locStartColor.g = parseFloat(locValueForKey("startColorGreen", dictionary)) * 255;
+ locStartColor.b = parseFloat(locValueForKey("startColorBlue", dictionary)) * 255;
+ locStartColor.a = parseFloat(locValueForKey("startColorAlpha", dictionary)) * 255;
+
+ var locStartColorVar = this._startColorVar;
+ locStartColorVar.r = parseFloat(locValueForKey("startColorVarianceRed", dictionary)) * 255;
+ locStartColorVar.g = parseFloat(locValueForKey("startColorVarianceGreen", dictionary)) * 255;
+ locStartColorVar.b = parseFloat(locValueForKey("startColorVarianceBlue", dictionary)) * 255;
+ locStartColorVar.a = parseFloat(locValueForKey("startColorVarianceAlpha", dictionary)) * 255;
+
+ var locEndColor = this._endColor;
+ locEndColor.r = parseFloat(locValueForKey("finishColorRed", dictionary)) * 255;
+ locEndColor.g = parseFloat(locValueForKey("finishColorGreen", dictionary)) * 255;
+ locEndColor.b = parseFloat(locValueForKey("finishColorBlue", dictionary)) * 255;
+ locEndColor.a = parseFloat(locValueForKey("finishColorAlpha", dictionary)) * 255;
+
+ var locEndColorVar = this._endColorVar;
+ locEndColorVar.r = parseFloat(locValueForKey("finishColorVarianceRed", dictionary)) * 255;
+ locEndColorVar.g = parseFloat(locValueForKey("finishColorVarianceGreen", dictionary)) * 255;
+ locEndColorVar.b = parseFloat(locValueForKey("finishColorVarianceBlue", dictionary)) * 255;
+ locEndColorVar.a = parseFloat(locValueForKey("finishColorVarianceAlpha", dictionary)) * 255;
+
+ // particle size
+ this.startSize = parseFloat(locValueForKey("startParticleSize", dictionary));
+ this.startSizeVar = parseFloat(locValueForKey("startParticleSizeVariance", dictionary));
+ this.endSize = parseFloat(locValueForKey("finishParticleSize", dictionary));
+ this.endSizeVar = parseFloat(locValueForKey("finishParticleSizeVariance", dictionary));
+
+ // position
+ this.setPosition(parseFloat(locValueForKey("sourcePositionx", dictionary)),
+ parseFloat(locValueForKey("sourcePositiony", dictionary)));
+ this._posVar.x = parseFloat(locValueForKey("sourcePositionVariancex", dictionary));
+ this._posVar.y = parseFloat(locValueForKey("sourcePositionVariancey", dictionary));
+
+ // Spinning
+ this.startSpin = parseFloat(locValueForKey("rotationStart", dictionary));
+ this.startSpinVar = parseFloat(locValueForKey("rotationStartVariance", dictionary));
+ this.endSpin = parseFloat(locValueForKey("rotationEnd", dictionary));
+ this.endSpinVar = parseFloat(locValueForKey("rotationEndVariance", dictionary));
+
+ this.emitterMode = parseInt(locValueForKey("emitterType", dictionary));
+
+ // Mode A: Gravity + tangential accel + radial accel
+ if (this.emitterMode === cc.ParticleSystem.MODE_GRAVITY) {
+ var locModeA = this.modeA;
+ // gravity
+ locModeA.gravity.x = parseFloat(locValueForKey("gravityx", dictionary));
+ locModeA.gravity.y = parseFloat(locValueForKey("gravityy", dictionary));
+
+ // speed
+ locModeA.speed = parseFloat(locValueForKey("speed", dictionary));
+ locModeA.speedVar = parseFloat(locValueForKey("speedVariance", dictionary));
+
+ // radial acceleration
+ var pszTmp = locValueForKey("radialAcceleration", dictionary);
+ locModeA.radialAccel = (pszTmp) ? parseFloat(pszTmp) : 0;
+
+ pszTmp = locValueForKey("radialAccelVariance", dictionary);
+ locModeA.radialAccelVar = (pszTmp) ? parseFloat(pszTmp) : 0;
+
+ // tangential acceleration
+ pszTmp = locValueForKey("tangentialAcceleration", dictionary);
+ locModeA.tangentialAccel = (pszTmp) ? parseFloat(pszTmp) : 0;
+
+ pszTmp = locValueForKey("tangentialAccelVariance", dictionary);
+ locModeA.tangentialAccelVar = (pszTmp) ? parseFloat(pszTmp) : 0;
+
+ // rotation is dir
+ var locRotationIsDir = locValueForKey("rotationIsDir", dictionary);
+ if (locRotationIsDir !== null) {
+ locRotationIsDir = locRotationIsDir.toString().toLowerCase();
+ locModeA.rotationIsDir = (locRotationIsDir === "true" || locRotationIsDir === "1");
+ }
+ else {
+ locModeA.rotationIsDir = false;
+ }
+ } else if (this.emitterMode === cc.ParticleSystem.MODE_RADIUS) {
+ // or Mode B: radius movement
+ var locModeB = this.modeB;
+ locModeB.startRadius = parseFloat(locValueForKey("maxRadius", dictionary));
+ locModeB.startRadiusVar = parseFloat(locValueForKey("maxRadiusVariance", dictionary));
+ locModeB.endRadius = parseFloat(locValueForKey("minRadius", dictionary));
+ locModeB.endRadiusVar = 0;
+ locModeB.rotatePerSecond = parseFloat(locValueForKey("rotatePerSecond", dictionary));
+ locModeB.rotatePerSecondVar = parseFloat(locValueForKey("rotatePerSecondVariance", dictionary));
+ } else {
+ cc.log("cc.ParticleSystem.initWithDictionary(): Invalid emitterType in config file");
+ return false;
+ }
+
+ // life span
+ this.life = parseFloat(locValueForKey("particleLifespan", dictionary));
+ this.lifeVar = parseFloat(locValueForKey("particleLifespanVariance", dictionary));
+
+ // emission Rate
+ this.emissionRate = this._totalParticles / this.life;
+
+ //don't get the internal texture if a batchNode is used
+ if (!this._batchNode) {
+ // Set a compatible default for the alpha transfer
+ this._opacityModifyRGB = false;
+
+ // texture
+ // Try to get the texture from the cache
+ var textureName = locValueForKey("textureFileName", dictionary);
+ var imgPath = cc.path.changeBasename(this._plistFile, textureName);
+ var tex = cc.textureCache.getTextureForKey(imgPath);
+
+ if (tex) {
+ this.setTexture(tex);
+ } else {
+ var textureData = locValueForKey("textureImageData", dictionary);
+
+ if (!textureData || textureData.length === 0) {
+ tex = cc.textureCache.addImage(imgPath);
+ if (!tex)
+ return false;
+ this.setTexture(tex);
+ } else {
+ buffer = cc.unzipBase64AsArray(textureData, 1);
+ if (!buffer) {
+ cc.log("cc.ParticleSystem: error decoding or ungzipping textureImageData");
+ return false;
+ }
+
+ var imageFormat = cc.getImageFormatByData(buffer);
+
+ if (imageFormat !== cc.FMT_TIFF && imageFormat !== cc.FMT_PNG) {
+ cc.log("cc.ParticleSystem: unknown image format with Data");
+ return false;
+ }
+
+ var canvasObj = document.createElement("canvas");
+ if (imageFormat === cc.FMT_PNG) {
+ var myPngObj = new cc.PNGReader(buffer);
+ myPngObj.render(canvasObj);
+ } else {
+ var myTIFFObj = cc.tiffReader;
+ myTIFFObj.parseTIFF(buffer, canvasObj);
+ }
+
+ cc.textureCache.cacheImage(imgPath, canvasObj);
+
+ var addTexture = cc.textureCache.getTextureForKey(imgPath);
+ if (!addTexture)
+ cc.log("cc.ParticleSystem.initWithDictionary() : error loading the texture");
+ this.setTexture(addTexture);
+ }
+ }
+ }
+ ret = true;
+ }
+ return ret;
+ },
+
+ /**
+ * Initializes a system with a fixed number of particles
+ * @param {Number} numberOfParticles
+ * @return {Boolean}
+ */
+ initWithTotalParticles: function (numberOfParticles) {
+ this._totalParticles = numberOfParticles;
+
+ var i, locParticles = this._particles;
+ locParticles.length = 0;
+ for (i = 0; i < numberOfParticles; i++) {
+ locParticles[i] = new cc.Particle();
+ }
+
+ if (!locParticles) {
+ cc.log("Particle system: not enough memory");
+ return false;
+ }
+ this._allocatedParticles = numberOfParticles;
+
+ if (this._batchNode)
+ for (i = 0; i < this._totalParticles; i++)
+ locParticles[i].atlasIndex = i;
+
+ // default, active
+ this._isActive = true;
+
+ // default blend function
+ this._blendFunc.src = cc.BLEND_SRC;
+ this._blendFunc.dst = cc.BLEND_DST;
+
+ // default movement type;
+ this.positionType = cc.ParticleSystem.TYPE_FREE;
+
+ // by default be in mode A:
+ this.emitterMode = cc.ParticleSystem.MODE_GRAVITY;
+
+ // default: modulate
+ // XXX: not used
+ // colorModulate = YES;
+ this.autoRemoveOnFinish = false;
+
+ //for batchNode
+ this._transformSystemDirty = false;
+
+ // udpate after action in run!
+ this.scheduleUpdateWithPriority(1);
+ this._renderCmd._initWithTotalParticles(numberOfParticles);
+ return true;
+ },
+
+ /**
+ * Unschedules the "update" method.
+ * @function
+ * @see scheduleUpdate();
+ */
+ destroyParticleSystem: function () {
+ this.unscheduleUpdate();
+ },
+
+ /**
+ * Add a particle to the emitter
+ * @return {Boolean}
+ */
+ addParticle: function () {
+ if (this.isFull())
+ return false;
+
+ var particle = this._renderCmd.addParticle();
+ this.initParticle(particle);
+ ++this.particleCount;
+ return true;
+ },
+
+ /**
+ * Initializes a particle
+ * @param {cc.Particle} particle
+ */
+ initParticle: function (particle) {
+ var locRandomMinus11 = cc.randomMinus1To1;
+ // timeToLive
+ // no negative life. prevent division by 0
+ particle.timeToLive = this.life + this.lifeVar * locRandomMinus11();
+ particle.timeToLive = Math.max(0, particle.timeToLive);
+
+ // position
+ particle.pos.x = this._sourcePosition.x + this._posVar.x * locRandomMinus11();
+ particle.pos.y = this._sourcePosition.y + this._posVar.y * locRandomMinus11();
+
+ // Color
+ var start, end;
+ var locStartColor = this._startColor, locStartColorVar = this._startColorVar;
+ var locEndColor = this._endColor, locEndColorVar = this._endColorVar;
+ start = {
+ r: cc.clampf(locStartColor.r + locStartColorVar.r * locRandomMinus11(), 0, 255),
+ g: cc.clampf(locStartColor.g + locStartColorVar.g * locRandomMinus11(), 0, 255),
+ b: cc.clampf(locStartColor.b + locStartColorVar.b * locRandomMinus11(), 0, 255),
+ a: cc.clampf(locStartColor.a + locStartColorVar.a * locRandomMinus11(), 0, 255)
+ };
+ end = {
+ r: cc.clampf(locEndColor.r + locEndColorVar.r * locRandomMinus11(), 0, 255),
+ g: cc.clampf(locEndColor.g + locEndColorVar.g * locRandomMinus11(), 0, 255),
+ b: cc.clampf(locEndColor.b + locEndColorVar.b * locRandomMinus11(), 0, 255),
+ a: cc.clampf(locEndColor.a + locEndColorVar.a * locRandomMinus11(), 0, 255)
+ };
+
+ particle.color = start;
+ var locParticleDeltaColor = particle.deltaColor, locParticleTimeToLive = particle.timeToLive;
+ locParticleDeltaColor.r = (end.r - start.r) / locParticleTimeToLive;
+ locParticleDeltaColor.g = (end.g - start.g) / locParticleTimeToLive;
+ locParticleDeltaColor.b = (end.b - start.b) / locParticleTimeToLive;
+ locParticleDeltaColor.a = (end.a - start.a) / locParticleTimeToLive;
+
+ // size
+ var startS = this.startSize + this.startSizeVar * locRandomMinus11();
+ startS = Math.max(0, startS); // No negative value
+
+ particle.size = startS;
+ if (this.endSize === cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE) {
+ particle.deltaSize = 0;
+ } else {
+ var endS = this.endSize + this.endSizeVar * locRandomMinus11();
+ endS = Math.max(0, endS); // No negative values
+ particle.deltaSize = (endS - startS) / locParticleTimeToLive;
+ }
+
+ // rotation
+ var startA = this.startSpin + this.startSpinVar * locRandomMinus11();
+ var endA = this.endSpin + this.endSpinVar * locRandomMinus11();
+ particle.rotation = startA;
+ particle.deltaRotation = (endA - startA) / locParticleTimeToLive;
+
+ // position
+ if (this.positionType === cc.ParticleSystem.TYPE_FREE)
+ particle.startPos = this.convertToWorldSpace(this._pointZeroForParticle);
+ else if (this.positionType === cc.ParticleSystem.TYPE_RELATIVE) {
+ particle.startPos.x = this._position.x;
+ particle.startPos.y = this._position.y;
+ }
+
+ // direction
+ var a = cc.degreesToRadians(this.angle + this.angleVar * locRandomMinus11());
+
+ // Mode Gravity: A
+ if (this.emitterMode === cc.ParticleSystem.MODE_GRAVITY) {
+ var locModeA = this.modeA, locParticleModeA = particle.modeA;
+ var s = locModeA.speed + locModeA.speedVar * locRandomMinus11();
+
+ // direction
+ locParticleModeA.dir.x = Math.cos(a);
+ locParticleModeA.dir.y = Math.sin(a);
+ cc.pMultIn(locParticleModeA.dir, s);
+
+ // radial accel
+ locParticleModeA.radialAccel = locModeA.radialAccel + locModeA.radialAccelVar * locRandomMinus11();
+
+ // tangential accel
+ locParticleModeA.tangentialAccel = locModeA.tangentialAccel + locModeA.tangentialAccelVar * locRandomMinus11();
+
+ // rotation is dir
+ if (locModeA.rotationIsDir)
+ particle.rotation = -cc.radiansToDegrees(cc.pToAngle(locParticleModeA.dir));
+ } else {
+ // Mode Radius: B
+ var locModeB = this.modeB, locParitlceModeB = particle.modeB;
+
+ // Set the default diameter of the particle from the source position
+ var startRadius = locModeB.startRadius + locModeB.startRadiusVar * locRandomMinus11();
+ var endRadius = locModeB.endRadius + locModeB.endRadiusVar * locRandomMinus11();
+
+ locParitlceModeB.radius = startRadius;
+ locParitlceModeB.deltaRadius = (locModeB.endRadius === cc.ParticleSystem.START_RADIUS_EQUAL_TO_END_RADIUS) ? 0 : (endRadius - startRadius) / locParticleTimeToLive;
+
+ locParitlceModeB.angle = a;
+ locParitlceModeB.degreesPerSecond = cc.degreesToRadians(locModeB.rotatePerSecond + locModeB.rotatePerSecondVar * locRandomMinus11());
+ }
+ },
+
+ /**
+ * stop emitting particles. Running particles will continue to run until they die
+ */
+ stopSystem: function () {
+ this._isActive = false;
+ this._elapsed = this.duration;
+ this._emitCounter = 0;
+ },
+
+ /**
+ * Kill all living particles.
+ */
+ resetSystem: function () {
+ this._isActive = true;
+ this._elapsed = 0;
+ var locParticles = this._particles;
+ for (this._particleIdx = 0; this._particleIdx < this.particleCount; ++this._particleIdx)
+ locParticles[this._particleIdx].timeToLive = 0;
+ },
+
+ /**
+ * whether or not the system is full
+ * @return {Boolean}
+ */
+ isFull: function () {
+ return (this.particleCount >= this._totalParticles);
+ },
+
+ /**
+ * should be overridden by subclasses
+ * @param {cc.Particle} particle
+ * @param {cc.Point} newPosition
+ */
+ updateQuadWithParticle: function (particle, newPosition) {
+ this._renderCmd.updateQuadWithParticle(particle, newPosition);
+ },
+
+ /**
+ * should be overridden by subclasses
+ */
+ postStep: function () {
+ this._renderCmd.postStep();
+ },
+
+ /**
+ * update emitter's status
+ * @override
+ * @param {Number} dt delta time
+ */
+ update:function (dt) {
+ if (this._isActive && this.emissionRate) {
+ var rate = 1.0 / this.emissionRate;
+ //issue #1201, prevent bursts of particles, due to too high emitCounter
+ if (this.particleCount < this._totalParticles)
+ this._emitCounter += dt;
+
+ while ((this.particleCount < this._totalParticles) && (this._emitCounter > rate)) {
+ this.addParticle();
+ this._emitCounter -= rate;
+ }
+
+ this._elapsed += dt;
+ if (this.duration !== -1 && this.duration < this._elapsed)
+ this.stopSystem();
+ }
+ this._particleIdx = 0;
+
+ var currentPosition = cc.Particle.TemporaryPoints[0];
+ if (this.positionType === cc.ParticleSystem.TYPE_FREE) {
+ cc.pIn(currentPosition, this.convertToWorldSpace(this._pointZeroForParticle));
+ } else if (this.positionType === cc.ParticleSystem.TYPE_RELATIVE) {
+ currentPosition.x = this._position.x;
+ currentPosition.y = this._position.y;
+ }
+
+ if (this._visible) {
+ // Used to reduce memory allocation / creation within the loop
+ var tpa = cc.Particle.TemporaryPoints[1],
+ tpb = cc.Particle.TemporaryPoints[2],
+ tpc = cc.Particle.TemporaryPoints[3];
+
+ var locParticles = this._particles;
+ while (this._particleIdx < this.particleCount) {
+
+ // Reset the working particles
+ cc.pZeroIn(tpa);
+ cc.pZeroIn(tpb);
+ cc.pZeroIn(tpc);
+
+ var selParticle = locParticles[this._particleIdx];
+
+ // life
+ selParticle.timeToLive -= dt;
+
+ if (selParticle.timeToLive > 0) {
+ // Mode A: gravity, direction, tangential accel & radial accel
+ if (this.emitterMode === cc.ParticleSystem.MODE_GRAVITY) {
+
+ var tmp = tpc, radial = tpa, tangential = tpb;
+
+ // radial acceleration
+ if (selParticle.pos.x || selParticle.pos.y) {
+ cc.pIn(radial, selParticle.pos);
+ cc.pNormalizeIn(radial);
+ } else {
+ cc.pZeroIn(radial);
+ }
+
+ cc.pIn(tangential, radial);
+ cc.pMultIn(radial, selParticle.modeA.radialAccel);
+
+ // tangential acceleration
+ var newy = tangential.x;
+ tangential.x = -tangential.y;
+ tangential.y = newy;
+
+ cc.pMultIn(tangential, selParticle.modeA.tangentialAccel);
+
+ cc.pIn(tmp, radial);
+ cc.pAddIn(tmp, tangential);
+ cc.pAddIn(tmp, this.modeA.gravity);
+ cc.pMultIn(tmp, dt);
+ cc.pAddIn(selParticle.modeA.dir, tmp);
+
+
+ cc.pIn(tmp, selParticle.modeA.dir);
+ cc.pMultIn(tmp, dt);
+ cc.pAddIn(selParticle.pos, tmp);
+ } else {
+ // Mode B: radius movement
+ var selModeB = selParticle.modeB;
+ // Update the angle and radius of the particle.
+ selModeB.angle += selModeB.degreesPerSecond * dt;
+ selModeB.radius += selModeB.deltaRadius * dt;
+
+ selParticle.pos.x = -Math.cos(selModeB.angle) * selModeB.radius;
+ selParticle.pos.y = -Math.sin(selModeB.angle) * selModeB.radius;
+ }
+
+ // color
+ this._renderCmd._updateDeltaColor(selParticle, dt);
+
+ // size
+ selParticle.size += (selParticle.deltaSize * dt);
+ selParticle.size = Math.max(0, selParticle.size);
+
+ // angle
+ selParticle.rotation += (selParticle.deltaRotation * dt);
+
+ //
+ // update values in quad
+ //
+ var newPos = tpa;
+ if (this.positionType === cc.ParticleSystem.TYPE_FREE || this.positionType === cc.ParticleSystem.TYPE_RELATIVE) {
+ var diff = tpb;
+ cc.pIn(diff, currentPosition);
+ cc.pSubIn(diff, selParticle.startPos);
+
+ cc.pIn(newPos, selParticle.pos);
+ cc.pSubIn(newPos, diff);
+ } else {
+ cc.pIn(newPos, selParticle.pos);
+ }
+
+ // translate newPos to correct position, since matrix transform isn't performed in batchnode
+ // don't update the particle with the new position information, it will interfere with the radius and tangential calculations
+ if (this._batchNode) {
+ newPos.x += this._position.x;
+ newPos.y += this._position.y;
+ }
+ this._renderCmd.updateParticlePosition(selParticle, newPos);
+
+ // update particle counter
+ ++this._particleIdx;
+ } else {
+ // life < 0
+ var currentIndex = selParticle.atlasIndex;
+ if (this._particleIdx !== this.particleCount - 1) {
+ var deadParticle = locParticles[this._particleIdx];
+ locParticles[this._particleIdx] = locParticles[this.particleCount - 1];
+ locParticles[this.particleCount - 1] = deadParticle;
+ }
+ if (this._batchNode) {
+ //disable the switched particle
+ this._batchNode.disableParticle(this.atlasIndex + currentIndex);
+ //switch indexes
+ locParticles[this.particleCount - 1].atlasIndex = currentIndex;
+ }
+
+ --this.particleCount;
+ if (this.particleCount === 0 && this.autoRemoveOnFinish) {
+ this.unscheduleUpdate();
+ this._parent.removeChild(this, true);
+ return;
+ }
+ }
+ }
+ this._transformSystemDirty = false;
+ }
+
+ if (!this._batchNode)
+ this.postStep();
+ },
+
+ /**
+ * update emitter's status (dt = 0)
+ */
+ updateWithNoTime: function () {
+ this.update(0);
+ },
+
+ //
+ // return the string found by key in dict.
+ // @param {string} key
+ // @param {object} dict
+ // @return {String} "" if not found; return the string if found.
+ // @private
+ //
+ _valueForKey: function (key, dict) {
+ if (dict) {
+ var pString = dict[key];
+ return pString != null ? pString : "";
+ }
+ return "";
+ },
+
+ _updateBlendFunc: function () {
+ if (this._batchNode) {
+ cc.log("Can't change blending functions when the particle is being batched");
+ return;
+ }
+
+ var locTexture = this._texture;
+ if (locTexture && locTexture instanceof cc.Texture2D) {
+ this._opacityModifyRGB = false;
+ var locBlendFunc = this._blendFunc;
+ if (locBlendFunc.src === cc.BLEND_SRC && locBlendFunc.dst === cc.BLEND_DST) {
+ if (locTexture.hasPremultipliedAlpha()) {
+ this._opacityModifyRGB = true;
+ } else {
+ locBlendFunc.src = cc.SRC_ALPHA;
+ locBlendFunc.dst = cc.ONE_MINUS_SRC_ALPHA;
+ }
+ }
+ }
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ *
+ * @return {cc.ParticleSystem}
+ */
+ clone: function () {
+ var retParticle = new cc.ParticleSystem();
+
+ // self, not super
+ if (retParticle.initWithTotalParticles(this.getTotalParticles())) {
+ // angle
+ retParticle.setAngle(this.getAngle());
+ retParticle.setAngleVar(this.getAngleVar());
+
+ // duration
+ retParticle.setDuration(this.getDuration());
+
+ // blend function
+ var blend = this.getBlendFunc();
+ retParticle.setBlendFunc(blend.src, blend.dst);
+
+ // color
+ retParticle.setStartColor(this.getStartColor());
+
+ retParticle.setStartColorVar(this.getStartColorVar());
+
+ retParticle.setEndColor(this.getEndColor());
+
+ retParticle.setEndColorVar(this.getEndColorVar());
+
+ // this size
+ retParticle.setStartSize(this.getStartSize());
+ retParticle.setStartSizeVar(this.getStartSizeVar());
+ retParticle.setEndSize(this.getEndSize());
+ retParticle.setEndSizeVar(this.getEndSizeVar());
+
+ // position
+ retParticle.setPosition(cc.p(this.x, this.y));
+ retParticle.setPosVar(cc.p(this.getPosVar().x, this.getPosVar().y));
+
+ retParticle.setPositionType(this.getPositionType());
+
+ // Spinning
+ retParticle.setStartSpin(this.getStartSpin() || 0);
+ retParticle.setStartSpinVar(this.getStartSpinVar() || 0);
+ retParticle.setEndSpin(this.getEndSpin() || 0);
+ retParticle.setEndSpinVar(this.getEndSpinVar() || 0);
+
+ retParticle.setEmitterMode(this.getEmitterMode());
+
+ // Mode A: Gravity + tangential accel + radial accel
+ if (this.getEmitterMode() === cc.ParticleSystem.MODE_GRAVITY) {
+ // gravity
+ var gra = this.getGravity();
+ retParticle.setGravity(cc.p(gra.x, gra.y));
+
+ // speed
+ retParticle.setSpeed(this.getSpeed());
+ retParticle.setSpeedVar(this.getSpeedVar());
+
+ // radial acceleration
+ retParticle.setRadialAccel(this.getRadialAccel());
+ retParticle.setRadialAccelVar(this.getRadialAccelVar());
+
+ // tangential acceleration
+ retParticle.setTangentialAccel(this.getTangentialAccel());
+ retParticle.setTangentialAccelVar(this.getTangentialAccelVar());
+
+ } else if (this.getEmitterMode() === cc.ParticleSystem.MODE_RADIUS) {
+ // or Mode B: radius movement
+ retParticle.setStartRadius(this.getStartRadius());
+ retParticle.setStartRadiusVar(this.getStartRadiusVar());
+ retParticle.setEndRadius(this.getEndRadius());
+ retParticle.setEndRadiusVar(this.getEndRadiusVar());
+
+ retParticle.setRotatePerSecond(this.getRotatePerSecond());
+ retParticle.setRotatePerSecondVar(this.getRotatePerSecondVar());
+ }
+
+ // life span
+ retParticle.setLife(this.getLife());
+ retParticle.setLifeVar(this.getLifeVar());
+
+ // emission Rate
+ retParticle.setEmissionRate(this.getEmissionRate());
+
+ //don't get the internal texture if a batchNode is used
+ if (!this.getBatchNode()) {
+ // Set a compatible default for the alpha transfer
+ retParticle.setOpacityModifyRGB(this.isOpacityModifyRGB());
+ // texture
+ var texture = this.getTexture();
+ if (texture) {
+ var size = texture.getContentSize();
+ retParticle.setTextureWithRect(texture, cc.rect(0, 0, size.width, size.height));
+ }
+ }
+ }
+ return retParticle;
+ },
+
+ /**
+ * Sets a new CCSpriteFrame as particle.
+ * WARNING: this method is experimental. Use setTextureWithRect instead.
+ *
+ * @param {cc.SpriteFrame} spriteFrame
+ */
+ setDisplayFrame: function (spriteFrame) {
+ if (!spriteFrame)
+ return;
+
+ var locOffset = spriteFrame.getOffsetInPixels();
+ if (locOffset.x !== 0 || locOffset.y !== 0)
+ cc.log("cc.ParticleSystem.setDisplayFrame(): QuadParticle only supports SpriteFrames with no offsets");
+
+ // update texture before updating texture rect
+ var texture = spriteFrame.getTexture(), locTexture = this._texture;
+ if (locTexture !== texture)
+ this.setTexture(texture);
+ },
+
+ /**
+ * Sets a new texture with a rect. The rect is in Points.
+ * @param {cc.Texture2D} texture
+ * @param {cc.Rect} rect
+ */
+ setTextureWithRect: function (texture, rect) {
+ var locTexture = this._texture;
+ if (locTexture !== texture) {
+ this._texture = texture;
+ this._updateBlendFunc();
+ }
+ this.initTexCoordsWithRect(rect);
+ },
+
+ /**
+ * listen the event that coming to foreground on Android (An empty function for native)
+ * @param {cc.Class} obj
+ */
+ listenBackToForeground: function (obj) {
+ //do nothing
+ }
+});
+
+var _p = cc.ParticleSystem.prototype;
+
+// Extended properties
+/** @expose */
+_p.opacityModifyRGB;
+cc.defineGetterSetter(_p, "opacityModifyRGB", _p.isOpacityModifyRGB, _p.setOpacityModifyRGB);
+/** @expose */
+_p.batchNode;
+cc.defineGetterSetter(_p, "batchNode", _p.getBatchNode, _p.setBatchNode);
+/** @expose */
+_p.drawMode;
+cc.defineGetterSetter(_p, "drawMode", _p.getDrawMode, _p.setDrawMode);
+/** @expose */
+_p.shapeType;
+cc.defineGetterSetter(_p, "shapeType", _p.getShapeType, _p.setShapeType);
+/** @expose */
+_p.active;
+cc.defineGetterSetter(_p, "active", _p.isActive);
+/** @expose */
+_p.sourcePos;
+cc.defineGetterSetter(_p, "sourcePos", _p.getSourcePosition, _p.setSourcePosition);
+/** @expose */
+_p.posVar;
+cc.defineGetterSetter(_p, "posVar", _p.getPosVar, _p.setPosVar);
+/** @expose */
+_p.gravity;
+cc.defineGetterSetter(_p, "gravity", _p.getGravity, _p.setGravity);
+/** @expose */
+_p.speed;
+cc.defineGetterSetter(_p, "speed", _p.getSpeed, _p.setSpeed);
+/** @expose */
+_p.speedVar;
+cc.defineGetterSetter(_p, "speedVar", _p.getSpeedVar, _p.setSpeedVar);
+/** @expose */
+_p.tangentialAccel;
+cc.defineGetterSetter(_p, "tangentialAccel", _p.getTangentialAccel, _p.setTangentialAccel);
+/** @expose */
+_p.tangentialAccelVar;
+cc.defineGetterSetter(_p, "tangentialAccelVar", _p.getTangentialAccelVar, _p.setTangentialAccelVar);
+/** @expose */
+_p.radialAccel;
+cc.defineGetterSetter(_p, "radialAccel", _p.getRadialAccel, _p.setRadialAccel);
+/** @expose */
+_p.radialAccelVar;
+cc.defineGetterSetter(_p, "radialAccelVar", _p.getRadialAccelVar, _p.setRadialAccelVar);
+/** @expose */
+_p.rotationIsDir;
+cc.defineGetterSetter(_p, "rotationIsDir", _p.getRotationIsDir, _p.setRotationIsDir);
+/** @expose */
+_p.startRadius;
+cc.defineGetterSetter(_p, "startRadius", _p.getStartRadius, _p.setStartRadius);
+/** @expose */
+_p.startRadiusVar;
+cc.defineGetterSetter(_p, "startRadiusVar", _p.getStartRadiusVar, _p.setStartRadiusVar);
+/** @expose */
+_p.endRadius;
+cc.defineGetterSetter(_p, "endRadius", _p.getEndRadius, _p.setEndRadius);
+/** @expose */
+_p.endRadiusVar;
+cc.defineGetterSetter(_p, "endRadiusVar", _p.getEndRadiusVar, _p.setEndRadiusVar);
+/** @expose */
+_p.rotatePerS;
+cc.defineGetterSetter(_p, "rotatePerS", _p.getRotatePerSecond, _p.setRotatePerSecond);
+/** @expose */
+_p.rotatePerSVar;
+cc.defineGetterSetter(_p, "rotatePerSVar", _p.getRotatePerSecondVar, _p.setRotatePerSecondVar);
+/** @expose */
+_p.startColor;
+cc.defineGetterSetter(_p, "startColor", _p.getStartColor, _p.setStartColor);
+/** @expose */
+_p.startColorVar;
+cc.defineGetterSetter(_p, "startColorVar", _p.getStartColorVar, _p.setStartColorVar);
+/** @expose */
+_p.endColor;
+cc.defineGetterSetter(_p, "endColor", _p.getEndColor, _p.setEndColor);
+/** @expose */
+_p.endColorVar;
+cc.defineGetterSetter(_p, "endColorVar", _p.getEndColorVar, _p.setEndColorVar);
+/** @expose */
+_p.totalParticles;
+cc.defineGetterSetter(_p, "totalParticles", _p.getTotalParticles, _p.setTotalParticles);
+/** @expose */
+_p.texture;
+cc.defineGetterSetter(_p, "texture", _p.getTexture, _p.setTexture);
+
+
+/**
+ * return the string found by key in dict.
+ * This plist files can be create manually or with Particle Designer:
+ * http://particledesigner.71squared.com/
+ *
+ * @deprecated since v3.0 please use new cc.ParticleSysytem(plistFile) instead.
+ * @param {String|Number} plistFile
+ * @return {cc.ParticleSystem}
+ */
+cc.ParticleSystem.create = function (plistFile) {
+ return new cc.ParticleSystem(plistFile);
+};
+
+/**
+ * return the string found by key in dict.
+ * This plist files can be create manually or with Particle Designer:
+ * http://particledesigner.71squared.com/
+ *
+ * @deprecated since v3.0 please use new cc.ParticleSysytem(plistFile) instead.
+ * @function
+ * @param {String|Number} plistFile
+ * @return {cc.ParticleSystem}
+ */
+cc.ParticleSystem.createWithTotalParticles = cc.ParticleSystem.create;
+
+// Different modes
+/**
+ * Mode A:Gravity + Tangential Accel + Radial Accel
+ * @Class
+ * @Construct
+ * @param {cc.Point} [gravity=] Gravity value.
+ * @param {Number} [speed=0] speed of each particle.
+ * @param {Number} [speedVar=0] speed variance of each particle.
+ * @param {Number} [tangentialAccel=0] tangential acceleration of each particle.
+ * @param {Number} [tangentialAccelVar=0] tangential acceleration variance of each particle.
+ * @param {Number} [radialAccel=0] radial acceleration of each particle.
+ * @param {Number} [radialAccelVar=0] radial acceleration variance of each particle.
+ * @param {boolean} [rotationIsDir=false]
+ */
+cc.ParticleSystem.ModeA = function (gravity, speed, speedVar, tangentialAccel, tangentialAccelVar, radialAccel, radialAccelVar, rotationIsDir) {
+ /** Gravity value. Only available in 'Gravity' mode. */
+ this.gravity = gravity ? gravity : cc.p(0, 0);
+ /** speed of each particle. Only available in 'Gravity' mode. */
+ this.speed = speed || 0;
+ /** speed variance of each particle. Only available in 'Gravity' mode. */
+ this.speedVar = speedVar || 0;
+ /** tangential acceleration of each particle. Only available in 'Gravity' mode. */
+ this.tangentialAccel = tangentialAccel || 0;
+ /** tangential acceleration variance of each particle. Only available in 'Gravity' mode. */
+ this.tangentialAccelVar = tangentialAccelVar || 0;
+ /** radial acceleration of each particle. Only available in 'Gravity' mode. */
+ this.radialAccel = radialAccel || 0;
+ /** radial acceleration variance of each particle. Only available in 'Gravity' mode. */
+ this.radialAccelVar = radialAccelVar || 0;
+ /** set the rotation of each particle to its direction Only available in 'Gravity' mode. */
+ this.rotationIsDir = rotationIsDir || false;
+};
+
+/**
+ * Mode B: circular movement (gravity, radial accel and tangential accel don't are not used in this mode)
+ * @Class
+ * @Construct
+ * @param {Number} [startRadius=0] The starting radius of the particles.
+ * @param {Number} [startRadiusVar=0] The starting radius variance of the particles.
+ * @param {Number} [endRadius=0] The ending radius of the particles.
+ * @param {Number} [endRadiusVar=0] The ending radius variance of the particles.
+ * @param {Number} [rotatePerSecond=0] Number of degrees to rotate a particle around the source pos per second.
+ * @param {Number} [rotatePerSecondVar=0] Variance in degrees for rotatePerSecond.
+ */
+cc.ParticleSystem.ModeB = function (startRadius, startRadiusVar, endRadius, endRadiusVar, rotatePerSecond, rotatePerSecondVar) {
+ /** The starting radius of the particles. Only available in 'Radius' mode. */
+ this.startRadius = startRadius || 0;
+ /** The starting radius variance of the particles. Only available in 'Radius' mode. */
+ this.startRadiusVar = startRadiusVar || 0;
+ /** The ending radius of the particles. Only available in 'Radius' mode. */
+ this.endRadius = endRadius || 0;
+ /** The ending radius variance of the particles. Only available in 'Radius' mode. */
+ this.endRadiusVar = endRadiusVar || 0;
+ /** Number of degress to rotate a particle around the source pos per second. Only available in 'Radius' mode. */
+ this.rotatePerSecond = rotatePerSecond || 0;
+ /** Variance in degrees for rotatePerSecond. Only available in 'Radius' mode. */
+ this.rotatePerSecondVar = rotatePerSecondVar || 0;
+};
+
+/**
+ * Shape Mode of Particle Draw
+ * @constant
+ * @type Number
+ */
+cc.ParticleSystem.SHAPE_MODE = 0;
+
+/**
+ * Texture Mode of Particle Draw
+ * @constant
+ * @type Number
+ */
+cc.ParticleSystem.TEXTURE_MODE = 1;
+
+/**
+ * Star Shape for ShapeMode of Particle
+ * @constant
+ * @type Number
+ */
+cc.ParticleSystem.STAR_SHAPE = 0;
+
+/**
+ * Ball Shape for ShapeMode of Particle
+ * @constant
+ * @type Number
+ */
+cc.ParticleSystem.BALL_SHAPE = 1;
+
+/**
+ * The Particle emitter lives forever
+ * @constant
+ * @type Number
+ */
+cc.ParticleSystem.DURATION_INFINITY = -1;
+
+/**
+ * The starting size of the particle is equal to the ending size
+ * @constant
+ * @type Number
+ */
+cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE = -1;
+
+/**
+ * The starting radius of the particle is equal to the ending radius
+ * @constant
+ * @type Number
+ */
+cc.ParticleSystem.START_RADIUS_EQUAL_TO_END_RADIUS = -1;
+
+/**
+ * Gravity mode (A mode)
+ * @constant
+ * @type Number
+ */
+cc.ParticleSystem.MODE_GRAVITY = 0;
+
+/**
+ * Radius mode (B mode)
+ * @constant
+ * @type Number
+ */
+cc.ParticleSystem.MODE_RADIUS = 1;
+
+/**
+ * Living particles are attached to the world and are unaffected by emitter repositioning.
+ * @constant
+ * @type Number
+ */
+cc.ParticleSystem.TYPE_FREE = 0;
+
+/**
+ * Living particles are attached to the world but will follow the emitter repositioning.
+ * Use case: Attach an emitter to an sprite, and you want that the emitter follows the sprite.
+ * @constant
+ * @type Number
+ */
+cc.ParticleSystem.TYPE_RELATIVE = 1;
+
+/**
+ * Living particles are attached to the emitter and are translated along with it.
+ * @constant
+ * @type Number
+ */
+cc.ParticleSystem.TYPE_GROUPED = 2;
diff --git a/frameworks/cocos2d-html5/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js
new file mode 100644
index 0000000..5f602e9
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js
@@ -0,0 +1,206 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * ParticleSystem's canvas render command
+ */
+(function () {
+ cc.ParticleSystem.CanvasRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._needDraw = true;
+
+ this._drawMode = cc.ParticleSystem.TEXTURE_MODE;
+ this._shapeType = cc.ParticleSystem.BALL_SHAPE;
+
+ this._pointRect = cc.rect(0, 0, 0, 0);
+ this._tintCache = null;
+ };
+ var proto = cc.ParticleSystem.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ proto.constructor = cc.ParticleSystem.CanvasRenderCmd;
+
+ proto.getDrawMode = function () {
+ return this._drawMode;
+ };
+
+ proto.setDrawMode = function (drawMode) {
+ this._drawMode = drawMode;
+ };
+
+ proto.getShapeType = function () {
+ return this._shapeType;
+ };
+
+ proto.setShapeType = function (shapeType) {
+ this._shapeType = shapeType;
+ };
+
+ proto.setBatchNode = function (batchNode) {
+ if (this._batchNode !== batchNode) {
+ this._node._batchNode = batchNode;
+ }
+ };
+
+ proto.updateQuadWithParticle = function (particle, newPosition) {
+ //do nothing
+ };
+
+ proto.updateParticlePosition = function (particle, position) {
+ cc.pIn(particle.drawPos, position);
+ };
+
+ proto.rendering = function (ctx, scaleX, scaleY) {
+ //TODO: need refactor rendering for performance
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext(),
+ node = this._node, pointRect = this._pointRect;
+
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+ wrapper.save();
+ if (node.isBlendAdditive())
+ context.globalCompositeOperation = 'lighter';
+ else
+ context.globalCompositeOperation = 'source-over';
+
+ var i, particle, lpx, alpha;
+ var particleCount = this._node.particleCount, particles = this._node._particles;
+ if (node.drawMode !== cc.ParticleSystem.SHAPE_MODE && node._texture) {
+ // Delay drawing until the texture is fully loaded by the browser
+ if (!node._texture._textureLoaded) {
+ wrapper.restore();
+ return;
+ }
+ var element = node._texture.getHtmlElementObj();
+ if (!element.width || !element.height) {
+ wrapper.restore();
+ return;
+ }
+
+ var drawElement = element;
+ for (i = 0; i < particleCount; i++) {
+ particle = particles[i];
+ lpx = (0 | (particle.size * 0.5));
+
+ alpha = particle.color.a / 255;
+ if (alpha === 0) continue;
+ context.globalAlpha = alpha;
+
+ context.save();
+ context.translate((0 | particle.drawPos.x), -(0 | particle.drawPos.y));
+
+ var size = Math.floor(particle.size / 4) * 4;
+ var w = pointRect.width;
+ var h = pointRect.height;
+
+ context.scale(Math.max((1 / w) * size, 0.000001), Math.max((1 / h) * size, 0.000001));
+ if (particle.rotation)
+ context.rotate(cc.degreesToRadians(particle.rotation));
+
+ drawElement = particle.isChangeColor ? this._changeTextureColor(node._texture, particle.color, this._pointRect) : element;
+ context.drawImage(drawElement, -(0 | (w / 2)), -(0 | (h / 2)));
+ context.restore();
+ }
+ } else {
+ var drawTool = cc._drawingUtil;
+ for (i = 0; i < particleCount; i++) {
+ particle = particles[i];
+ lpx = (0 | (particle.size * 0.5));
+ alpha = particle.color.a / 255;
+ if (alpha === 0) continue;
+ context.globalAlpha = alpha;
+
+ context.save();
+ context.translate(0 | particle.drawPos.x, -(0 | particle.drawPos.y));
+ if (node.shapeType === cc.ParticleSystem.STAR_SHAPE) {
+ if (particle.rotation)
+ context.rotate(cc.degreesToRadians(particle.rotation));
+ drawTool.drawStar(wrapper, lpx, particle.color);
+ } else
+ drawTool.drawColorBall(wrapper, lpx, particle.color);
+ context.restore();
+ }
+ }
+ wrapper.restore();
+ cc.g_NumberOfDraws++;
+ };
+
+ proto._changeTextureColor = function (texture, color, rect) {
+ if (!this._tintCache) {
+ this._tintCache = document.createElement("canvas");
+ }
+ var tintCache = this._tintCache;
+ var textureContentSize = texture.getContentSize();
+ tintCache.width = textureContentSize.width;
+ tintCache.height = textureContentSize.height;
+ return texture._generateColorTexture(color.r, color.g, color.b, rect, tintCache);
+ };
+
+ proto.initTexCoordsWithRect = function (pointRect) {
+ this._pointRect = pointRect;
+ };
+
+ proto.setTotalParticles = function (tp) {
+ //cc.assert(tp <= this._allocatedParticles, "Particle: resizing particle array only supported for quads");
+ this._node._totalParticles = (tp < 200) ? tp : 200;
+ };
+
+ proto.addParticle = function () {
+ var node = this._node,
+ particles = node._particles,
+ particle;
+ if (node.particleCount < particles.length) {
+ particle = particles[node.particleCount];
+ } else {
+ particle = new cc.Particle();
+ particles.push(particle);
+ }
+ return particle;
+ };
+
+ proto._setupVBO = function () {
+ };
+ proto._allocMemory = function () {
+ return true;
+ };
+
+ proto.postStep = function () {
+ };
+
+ proto._setBlendAdditive = function () {
+ var locBlendFunc = this._node._blendFunc;
+ locBlendFunc.src = cc.BLEND_SRC;
+ locBlendFunc.dst = cc.BLEND_DST;
+ };
+
+ proto._initWithTotalParticles = function (totalParticles) {
+ };
+ proto._updateDeltaColor = function (selParticle, dt) {
+ if (!this._node._dontTint) {
+ var deltaColor = selParticle.deltaColor;
+ selParticle.color.r += deltaColor.r * dt;
+ selParticle.color.g += deltaColor.g * dt;
+ selParticle.color.b += deltaColor.b * dt;
+ selParticle.color.a += deltaColor.a * dt;
+ selParticle.isChangeColor = deltaColor.r !== 0 || deltaColor.g !== 0 || deltaColor.b !== 0;
+ }
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js
new file mode 100644
index 0000000..54b1236
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js
@@ -0,0 +1,420 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ /**
+ * ParticleSystem's WebGL render command
+ */
+ cc.ParticleSystem.WebGLRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._needDraw = true;
+
+ this._matrix = null;
+
+ this._buffersVBO = [0, 0];
+ this._quads = [];
+ this._indices = [];
+ this._quadsArrayBuffer = null;
+ };
+ var proto = cc.ParticleSystem.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ proto.constructor = cc.ParticleSystem.WebGLRenderCmd;
+
+ proto.getDrawMode = function () {
+ };
+ proto.setDrawMode = function (drawMode) {
+ };
+ proto.getShapeType = function () {
+ };
+ proto.setShapeType = function (shapeType) {
+ };
+
+ proto.setBatchNode = function (batchNode) {
+ var node = this._node;
+ if (node._batchNode !== batchNode) {
+ var oldBatch = node._batchNode;
+ node._batchNode = batchNode; //weak reference
+
+ if (batchNode) {
+ var locParticles = node._particles;
+ for (var i = 0; i < node._totalParticles; i++)
+ locParticles[i].atlasIndex = i;
+ }
+
+ // NEW: is self render ?
+ if (!batchNode) {
+ this._allocMemory();
+ this.initIndices(node._totalParticles);
+ node.setTexture(oldBatch.getTexture());
+ this._setupVBO();
+
+ } else if (!oldBatch) {
+ // OLD: was it self render cleanup ?
+ // copy current state to batch
+ node._batchNode.textureAtlas._copyQuadsToTextureAtlas(this._quads, node.atlasIndex);
+
+ //delete buffer
+ cc._renderContext.deleteBuffer(this._buffersVBO[1]); //where is re-bindBuffer code?
+ }
+ }
+ };
+
+ proto.initIndices = function (totalParticles) {
+ var locIndices = this._indices;
+ for (var i = 0, len = totalParticles; i < len; ++i) {
+ var i6 = i * 6;
+ var i4 = i * 4;
+ locIndices[i6 + 0] = i4 + 0;
+ locIndices[i6 + 1] = i4 + 1;
+ locIndices[i6 + 2] = i4 + 2;
+
+ locIndices[i6 + 5] = i4 + 1;
+ locIndices[i6 + 4] = i4 + 2;
+ locIndices[i6 + 3] = i4 + 3;
+ }
+ };
+
+ proto.isDifferentTexture = function (texture1, texture2) {
+ return (texture1 === texture2);
+ };
+
+ proto.updateParticlePosition = function (particle, position) {
+ // IMPORTANT: newPos may not be used as a reference here! (as it is just the temporary tpa point)
+ // the implementation of updateQuadWithParticle must use
+ // the x and y values directly
+ this.updateQuadWithParticle(particle, position);
+ };
+
+ proto.updateQuadWithParticle = function (particle, newPosition) {
+ var quad = null, node = this._node;
+ if (node._batchNode) {
+ var batchQuads = node._batchNode.textureAtlas.quads;
+ quad = batchQuads[node.atlasIndex + particle.atlasIndex];
+ node._batchNode.textureAtlas.dirty = true;
+ } else
+ quad = this._quads[node._particleIdx];
+
+ var r, g, b, a;
+ if (node._opacityModifyRGB) {
+ r = 0 | (particle.color.r * particle.color.a / 255);
+ g = 0 | (particle.color.g * particle.color.a / 255);
+ b = 0 | (particle.color.b * particle.color.a / 255);
+ } else {
+ r = 0 | (particle.color.r );
+ g = 0 | (particle.color.g );
+ b = 0 | (particle.color.b );
+ }
+ a = 0 | (particle.color.a );
+
+ var blColors = quad.bl.colors, brColors = quad.br.colors, tlColors = quad.tl.colors, trColors = quad.tr.colors;
+ blColors.r = brColors.r = tlColors.r = trColors.r = r;
+ blColors.g = brColors.g = tlColors.g = trColors.g = g;
+ blColors.b = brColors.b = tlColors.b = trColors.b = b;
+ blColors.a = brColors.a = tlColors.a = trColors.a = a;
+
+ // vertices
+ var size_2 = particle.size / 2;
+ if (particle.rotation) {
+ var x1 = -size_2, y1 = -size_2;
+
+ var x2 = size_2, y2 = size_2;
+ var x = newPosition.x, y = newPosition.y;
+
+ var rad = -cc.degreesToRadians(particle.rotation);
+ var cr = Math.cos(rad), sr = Math.sin(rad);
+ var ax = x1 * cr - y1 * sr + x;
+ var ay = x1 * sr + y1 * cr + y;
+ var bx = x2 * cr - y1 * sr + x;
+ var by = x2 * sr + y1 * cr + y;
+ var cx = x2 * cr - y2 * sr + x;
+ var cy = x2 * sr + y2 * cr + y;
+ var dx = x1 * cr - y2 * sr + x;
+ var dy = x1 * sr + y2 * cr + y;
+
+ // bottom-left
+ quad.bl.vertices.x = ax;
+ quad.bl.vertices.y = ay;
+
+ // bottom-right vertex:
+ quad.br.vertices.x = bx;
+ quad.br.vertices.y = by;
+
+ // top-left vertex:
+ quad.tl.vertices.x = dx;
+ quad.tl.vertices.y = dy;
+
+ // top-right vertex:
+ quad.tr.vertices.x = cx;
+ quad.tr.vertices.y = cy;
+ } else {
+ // bottom-left vertex:
+ quad.bl.vertices.x = newPosition.x - size_2;
+ quad.bl.vertices.y = newPosition.y - size_2;
+
+ // bottom-right vertex:
+ quad.br.vertices.x = newPosition.x + size_2;
+ quad.br.vertices.y = newPosition.y - size_2;
+
+ // top-left vertex:
+ quad.tl.vertices.x = newPosition.x - size_2;
+ quad.tl.vertices.y = newPosition.y + size_2;
+
+ // top-right vertex:
+ quad.tr.vertices.x = newPosition.x + size_2;
+ quad.tr.vertices.y = newPosition.y + size_2;
+ }
+ };
+
+ proto.rendering = function (ctx) {
+ var node = this._node;
+ if (!node._texture)
+ return;
+
+ var gl = ctx || cc._renderContext;
+
+ if (!this._matrix) {
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+ }
+ var wt = this._worldTransform;
+ this._matrix.mat[0] = wt.a;
+ this._matrix.mat[4] = wt.c;
+ this._matrix.mat[12] = wt.tx;
+ this._matrix.mat[1] = wt.b;
+ this._matrix.mat[5] = wt.d;
+ this._matrix.mat[13] = wt.ty;
+
+ this._glProgramState.apply(this._matrix);
+
+ cc.glBindTexture2D(node._texture);
+ cc.glBlendFuncForParticle(node._blendFunc.src, node._blendFunc.dst);
+
+ //
+ // Using VBO without VAO
+ //
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._buffersVBO[0]);
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 24, 0); // vertices
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, 12); // colors
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 24, 16); // tex coords
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._buffersVBO[1]);
+ gl.drawElements(gl.TRIANGLES, node._particleIdx * 6, gl.UNSIGNED_SHORT, 0);
+ };
+
+ proto.initTexCoordsWithRect = function (pointRect) {
+ var node = this._node;
+ var texture = node.texture;
+ var scaleFactor = cc.contentScaleFactor();
+ // convert to pixels coords
+ var rect = cc.rect(
+ pointRect.x * scaleFactor,
+ pointRect.y * scaleFactor,
+ pointRect.width * scaleFactor,
+ pointRect.height * scaleFactor);
+
+ var wide = pointRect.width;
+ var high = pointRect.height;
+
+ if (texture) {
+ wide = texture.pixelsWidth;
+ high = texture.pixelsHeight;
+ }
+
+ var left, bottom, right, top;
+ if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) {
+ left = (rect.x * 2 + 1) / (wide * 2);
+ bottom = (rect.y * 2 + 1) / (high * 2);
+ right = left + (rect.width * 2 - 2) / (wide * 2);
+ top = bottom + (rect.height * 2 - 2) / (high * 2);
+ } else {
+ left = rect.x / wide;
+ bottom = rect.y / high;
+ right = left + rect.width / wide;
+ top = bottom + rect.height / high;
+ }
+
+ // Important. Texture in cocos2d are inverted, so the Y component should be inverted
+ var temp = top;
+ top = bottom;
+ bottom = temp;
+
+ var quads;
+ var start = 0, end = 0;
+ if (node._batchNode) {
+ quads = node._batchNode.textureAtlas.quads;
+ start = node.atlasIndex;
+ end = node.atlasIndex + node._totalParticles;
+ } else {
+ quads = this._quads;
+ start = 0;
+ end = node._totalParticles;
+ }
+
+ for (var i = start; i < end; i++) {
+ if (!quads[i])
+ quads[i] = cc.V3F_C4B_T2F_QuadZero();
+
+ // bottom-left vertex:
+ var selQuad = quads[i];
+ selQuad.bl.texCoords.u = left;
+ selQuad.bl.texCoords.v = bottom;
+ // bottom-right vertex:
+ selQuad.br.texCoords.u = right;
+ selQuad.br.texCoords.v = bottom;
+ // top-left vertex:
+ selQuad.tl.texCoords.u = left;
+ selQuad.tl.texCoords.v = top;
+ // top-right vertex:
+ selQuad.tr.texCoords.u = right;
+ selQuad.tr.texCoords.v = top;
+ }
+ };
+
+ proto.setTotalParticles = function (tp) {
+ var node = this._node;
+ // If we are setting the total numer of particles to a number higher
+ // than what is allocated, we need to allocate new arrays
+ if (tp > node._allocatedParticles) {
+ var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT;
+ // Allocate new memory
+ this._indices = new Uint16Array(tp * 6);
+ var locQuadsArrayBuffer = new ArrayBuffer(tp * quadSize);
+ //TODO need fix
+ // Assign pointers
+ var locParticles = node._particles;
+ locParticles.length = 0;
+ var locQuads = this._quads;
+ locQuads.length = 0;
+ for (var j = 0; j < tp; j++) {
+ locParticles[j] = new cc.Particle();
+ locQuads[j] = new cc.V3F_C4B_T2F_Quad(null, null, null, null, locQuadsArrayBuffer, j * quadSize);
+ }
+ node._allocatedParticles = tp;
+ node._totalParticles = tp;
+
+ // Init particles
+ if (node._batchNode) {
+ for (var i = 0; i < tp; i++)
+ locParticles[i].atlasIndex = i;
+ }
+
+ this._quadsArrayBuffer = locQuadsArrayBuffer;
+ this.initIndices(tp);
+ this._setupVBO();
+
+ //set the texture coord
+ if (node._texture) {
+ this.initTexCoordsWithRect(cc.rect(0, 0, node._texture.width, node._texture.height));
+ }
+ } else
+ node._totalParticles = tp;
+ node.resetSystem();
+ };
+
+ proto.addParticle = function () {
+ var node = this._node,
+ particles = node._particles;
+ return particles[node.particleCount];
+ };
+
+ proto._setupVBO = function () {
+ var node = this;
+ var gl = cc._renderContext;
+
+ //gl.deleteBuffer(this._buffersVBO[0]);
+ this._buffersVBO[0] = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._buffersVBO[0]);
+ gl.bufferData(gl.ARRAY_BUFFER, this._quadsArrayBuffer, gl.DYNAMIC_DRAW);
+
+ this._buffersVBO[1] = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._buffersVBO[1]);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW);
+
+ //cc.checkGLErrorDebug();
+ };
+
+ proto._allocMemory = function () {
+ var node = this._node;
+ //cc.assert((!this._quads && !this._indices), "Memory already allocated");
+ if (node._batchNode) {
+ cc.log("cc.ParticleSystem._allocMemory(): Memory should not be allocated when not using batchNode");
+ return false;
+ }
+
+ var quadSize = cc.V3F_C4B_T2F_Quad.BYTES_PER_ELEMENT;
+ var totalParticles = node._totalParticles;
+ var locQuads = this._quads;
+ locQuads.length = 0;
+ this._indices = new Uint16Array(totalParticles * 6);
+ var locQuadsArrayBuffer = new ArrayBuffer(quadSize * totalParticles);
+
+ for (var i = 0; i < totalParticles; i++)
+ locQuads[i] = new cc.V3F_C4B_T2F_Quad(null, null, null, null, locQuadsArrayBuffer, i * quadSize);
+ if (!locQuads || !this._indices) {
+ cc.log("cocos2d: Particle system: not enough memory");
+ return false;
+ }
+ this._quadsArrayBuffer = locQuadsArrayBuffer;
+ return true;
+ };
+
+ proto.postStep = function () {
+ var gl = cc._renderContext;
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._buffersVBO[0]);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, this._quadsArrayBuffer);
+ };
+
+ proto._setBlendAdditive = function () {
+ var locBlendFunc = this._node._blendFunc;
+ if (this._texture && !this._texture.hasPremultipliedAlpha()) {
+ locBlendFunc.src = cc.SRC_ALPHA;
+ locBlendFunc.dst = cc.ONE_MINUS_SRC_ALPHA;
+ } else {
+ locBlendFunc.src = cc.BLEND_SRC;
+ locBlendFunc.dst = cc.BLEND_DST;
+ }
+ };
+
+ proto._initWithTotalParticles = function (totalParticles) {
+ // allocating data space
+ if (!this._allocMemory())
+ return false;
+
+ this.initIndices(totalParticles);
+ this._setupVBO();
+
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR);
+ };
+
+ proto._updateDeltaColor = function (selParticle, dt) {
+ selParticle.color.r += selParticle.deltaColor.r * dt;
+ selParticle.color.g += selParticle.deltaColor.g * dt;
+ selParticle.color.b += selParticle.deltaColor.b * dt;
+ selParticle.color.a += selParticle.deltaColor.a * dt;
+ selParticle.isChangeColor = true;
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/particle/CCTIFFReader.js b/frameworks/cocos2d-html5/cocos2d/particle/CCTIFFReader.js
new file mode 100644
index 0000000..1854865
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/particle/CCTIFFReader.js
@@ -0,0 +1,692 @@
+/****************************************************************************
+ Copyright (c) 2011 Gordon P. Hemsley
+ http://gphemsley.org/
+
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.tiffReader is a singleton object, it's a tiff file reader, it can parse byte array to draw into a canvas
+ * @class
+ * @name cc.tiffReader
+ */
+cc.tiffReader = /** @lends cc.tiffReader# */{
+ _littleEndian: false,
+ _tiffData: null,
+ _fileDirectories: [],
+
+ getUint8: function (offset) {
+ return this._tiffData[offset];
+ },
+
+ getUint16: function (offset) {
+ if (this._littleEndian)
+ return (this._tiffData[offset + 1] << 8) | (this._tiffData[offset]);
+ else
+ return (this._tiffData[offset] << 8) | (this._tiffData[offset + 1]);
+ },
+
+ getUint32: function (offset) {
+ var a = this._tiffData;
+ if (this._littleEndian)
+ return (a[offset + 3] << 24) | (a[offset + 2] << 16) | (a[offset + 1] << 8) | (a[offset]);
+ else
+ return (a[offset] << 24) | (a[offset + 1] << 16) | (a[offset + 2] << 8) | (a[offset + 3]);
+ },
+
+ checkLittleEndian: function () {
+ var BOM = this.getUint16(0);
+
+ if (BOM === 0x4949) {
+ this.littleEndian = true;
+ } else if (BOM === 0x4D4D) {
+ this.littleEndian = false;
+ } else {
+ console.log(BOM);
+ throw TypeError("Invalid byte order value.");
+ }
+
+ return this.littleEndian;
+ },
+
+ hasTowel: function () {
+ // Check for towel.
+ if (this.getUint16(2) !== 42) {
+ throw RangeError("You forgot your towel!");
+ return false;
+ }
+
+ return true;
+ },
+
+ getFieldTypeName: function (fieldType) {
+ var typeNames = this.fieldTypeNames;
+ if (fieldType in typeNames) {
+ return typeNames[fieldType];
+ }
+ return null;
+ },
+
+ getFieldTagName: function (fieldTag) {
+ var tagNames = this.fieldTagNames;
+
+ if (fieldTag in tagNames) {
+ return tagNames[fieldTag];
+ } else {
+ console.log("Unknown Field Tag:", fieldTag);
+ return "Tag" + fieldTag;
+ }
+ },
+
+ getFieldTypeLength: function (fieldTypeName) {
+ if (['BYTE', 'ASCII', 'SBYTE', 'UNDEFINED'].indexOf(fieldTypeName) !== -1) {
+ return 1;
+ } else if (['SHORT', 'SSHORT'].indexOf(fieldTypeName) !== -1) {
+ return 2;
+ } else if (['LONG', 'SLONG', 'FLOAT'].indexOf(fieldTypeName) !== -1) {
+ return 4;
+ } else if (['RATIONAL', 'SRATIONAL', 'DOUBLE'].indexOf(fieldTypeName) !== -1) {
+ return 8;
+ }
+ return null;
+ },
+
+ getFieldValues: function (fieldTagName, fieldTypeName, typeCount, valueOffset) {
+ var fieldValues = [];
+ var fieldTypeLength = this.getFieldTypeLength(fieldTypeName);
+ var fieldValueSize = fieldTypeLength * typeCount;
+
+ if (fieldValueSize <= 4) {
+ // The value is stored at the big end of the valueOffset.
+ if (this.littleEndian === false)
+ fieldValues.push(valueOffset >>> ((4 - fieldTypeLength) * 8));
+ else
+ fieldValues.push(valueOffset);
+ } else {
+ for (var i = 0; i < typeCount; i++) {
+ var indexOffset = fieldTypeLength * i;
+ if (fieldTypeLength >= 8) {
+ if (['RATIONAL', 'SRATIONAL'].indexOf(fieldTypeName) !== -1) {
+ // Numerator
+ fieldValues.push(this.getUint32(valueOffset + indexOffset));
+ // Denominator
+ fieldValues.push(this.getUint32(valueOffset + indexOffset + 4));
+ } else {
+ cc.log("Can't handle this field type or size");
+ }
+ } else {
+ fieldValues.push(this.getBytes(fieldTypeLength, valueOffset + indexOffset));
+ }
+ }
+ }
+
+ if (fieldTypeName === 'ASCII') {
+ fieldValues.forEach(function (e, i, a) {
+ a[i] = String.fromCharCode(e);
+ });
+ }
+ return fieldValues;
+ },
+
+ getBytes: function (numBytes, offset) {
+ if (numBytes <= 0) {
+ cc.log("No bytes requested");
+ } else if (numBytes <= 1) {
+ return this.getUint8(offset);
+ } else if (numBytes <= 2) {
+ return this.getUint16(offset);
+ } else if (numBytes <= 3) {
+ return this.getUint32(offset) >>> 8;
+ } else if (numBytes <= 4) {
+ return this.getUint32(offset);
+ } else {
+ cc.log("Too many bytes requested");
+ }
+ },
+
+ getBits: function (numBits, byteOffset, bitOffset) {
+ bitOffset = bitOffset || 0;
+ var extraBytes = Math.floor(bitOffset / 8);
+ var newByteOffset = byteOffset + extraBytes;
+ var totalBits = bitOffset + numBits;
+ var shiftRight = 32 - numBits;
+ var shiftLeft,rawBits;
+
+ if (totalBits <= 0) {
+ console.log("No bits requested");
+ } else if (totalBits <= 8) {
+ shiftLeft = 24 + bitOffset;
+ rawBits = this.getUint8(newByteOffset);
+ } else if (totalBits <= 16) {
+ shiftLeft = 16 + bitOffset;
+ rawBits = this.getUint16(newByteOffset);
+ } else if (totalBits <= 32) {
+ shiftLeft = bitOffset;
+ rawBits = this.getUint32(newByteOffset);
+ } else {
+ console.log( "Too many bits requested" );
+ }
+
+ return {
+ 'bits': ((rawBits << shiftLeft) >>> shiftRight),
+ 'byteOffset': newByteOffset + Math.floor(totalBits / 8),
+ 'bitOffset': totalBits % 8
+ };
+ },
+
+ parseFileDirectory: function (byteOffset) {
+ var numDirEntries = this.getUint16(byteOffset);
+ var tiffFields = [];
+
+ for (var i = byteOffset + 2, entryCount = 0; entryCount < numDirEntries; i += 12, entryCount++) {
+ var fieldTag = this.getUint16(i);
+ var fieldType = this.getUint16(i + 2);
+ var typeCount = this.getUint32(i + 4);
+ var valueOffset = this.getUint32(i + 8);
+
+ var fieldTagName = this.getFieldTagName(fieldTag);
+ var fieldTypeName = this.getFieldTypeName(fieldType);
+ var fieldValues = this.getFieldValues(fieldTagName, fieldTypeName, typeCount, valueOffset);
+
+ tiffFields[fieldTagName] = { type: fieldTypeName, values: fieldValues };
+ }
+
+ this._fileDirectories.push(tiffFields);
+
+ var nextIFDByteOffset = this.getUint32(i);
+ if (nextIFDByteOffset !== 0x00000000) {
+ this.parseFileDirectory(nextIFDByteOffset);
+ }
+ },
+
+ clampColorSample: function(colorSample, bitsPerSample) {
+ var multiplier = Math.pow(2, 8 - bitsPerSample);
+
+ return Math.floor((colorSample * multiplier) + (multiplier - 1));
+ },
+
+ /**
+ * @function
+ * @param {Array} tiffData
+ * @param {HTMLCanvasElement} canvas
+ * @returns {*}
+ */
+ parseTIFF: function (tiffData, canvas) {
+ canvas = canvas || document.createElement('canvas');
+
+ this._tiffData = tiffData;
+ this.canvas = canvas;
+
+ this.checkLittleEndian();
+
+ if (!this.hasTowel()) {
+ return;
+ }
+
+ var firstIFDByteOffset = this.getUint32(4);
+
+ this._fileDirectories.length = 0;
+ this.parseFileDirectory(firstIFDByteOffset);
+
+ var fileDirectory = this._fileDirectories[0];
+
+ var imageWidth = fileDirectory['ImageWidth'].values[0];
+ var imageLength = fileDirectory['ImageLength'].values[0];
+
+ this.canvas.width = imageWidth;
+ this.canvas.height = imageLength;
+
+ var strips = [];
+
+ var compression = (fileDirectory['Compression']) ? fileDirectory['Compression'].values[0] : 1;
+
+ var samplesPerPixel = fileDirectory['SamplesPerPixel'].values[0];
+
+ var sampleProperties = [];
+
+ var bitsPerPixel = 0;
+ var hasBytesPerPixel = false;
+
+ fileDirectory['BitsPerSample'].values.forEach(function (bitsPerSample, i, bitsPerSampleValues) {
+ sampleProperties[i] = {
+ bitsPerSample: bitsPerSample,
+ hasBytesPerSample: false,
+ bytesPerSample: undefined
+ };
+
+ if ((bitsPerSample % 8) === 0) {
+ sampleProperties[i].hasBytesPerSample = true;
+ sampleProperties[i].bytesPerSample = bitsPerSample / 8;
+ }
+
+ bitsPerPixel += bitsPerSample;
+ }, this);
+
+ if ((bitsPerPixel % 8) === 0) {
+ hasBytesPerPixel = true;
+ var bytesPerPixel = bitsPerPixel / 8;
+ }
+
+ var stripOffsetValues = fileDirectory['StripOffsets'].values;
+ var numStripOffsetValues = stripOffsetValues.length;
+
+ // StripByteCounts is supposed to be required, but see if we can recover anyway.
+ if (fileDirectory['StripByteCounts']) {
+ var stripByteCountValues = fileDirectory['StripByteCounts'].values;
+ } else {
+ cc.log("Missing StripByteCounts!");
+
+ // Infer StripByteCounts, if possible.
+ if (numStripOffsetValues === 1) {
+ var stripByteCountValues = [Math.ceil((imageWidth * imageLength * bitsPerPixel) / 8)];
+ } else {
+ throw Error("Cannot recover from missing StripByteCounts");
+ }
+ }
+
+ // Loop through strips and decompress as necessary.
+ for (var i = 0; i < numStripOffsetValues; i++) {
+ var stripOffset = stripOffsetValues[i];
+ strips[i] = [];
+
+ var stripByteCount = stripByteCountValues[i];
+
+ // Loop through pixels.
+ for (var byteOffset = 0, bitOffset = 0, jIncrement = 1, getHeader = true, pixel = [], numBytes = 0, sample = 0, currentSample = 0;
+ byteOffset < stripByteCount; byteOffset += jIncrement) {
+ // Decompress strip.
+ switch (compression) {
+ // Uncompressed
+ case 1:
+ // Loop through samples (sub-pixels).
+ for (var m = 0, pixel = []; m < samplesPerPixel; m++) {
+ if (sampleProperties[m].hasBytesPerSample) {
+ // XXX: This is wrong!
+ var sampleOffset = sampleProperties[m].bytesPerSample * m;
+ pixel.push(this.getBytes(sampleProperties[m].bytesPerSample, stripOffset + byteOffset + sampleOffset));
+ } else {
+ var sampleInfo = this.getBits(sampleProperties[m].bitsPerSample, stripOffset + byteOffset, bitOffset);
+ pixel.push(sampleInfo.bits);
+ byteOffset = sampleInfo.byteOffset - stripOffset;
+ bitOffset = sampleInfo.bitOffset;
+
+ throw RangeError("Cannot handle sub-byte bits per sample");
+ }
+ }
+
+ strips[i].push(pixel);
+
+ if (hasBytesPerPixel) {
+ jIncrement = bytesPerPixel;
+ } else {
+ jIncrement = 0;
+ throw RangeError("Cannot handle sub-byte bits per pixel");
+ }
+ break;
+
+ // CITT Group 3 1-Dimensional Modified Huffman run-length encoding
+ case 2:
+ // XXX: Use PDF.js code?
+ break;
+
+ // Group 3 Fax
+ case 3:
+ // XXX: Use PDF.js code?
+ break;
+
+ // Group 4 Fax
+ case 4:
+ // XXX: Use PDF.js code?
+ break;
+
+ // LZW
+ case 5:
+ // XXX: Use PDF.js code?
+ break;
+
+ // Old-style JPEG (TIFF 6.0)
+ case 6:
+ // XXX: Use PDF.js code?
+ break;
+
+ // New-style JPEG (TIFF Specification Supplement 2)
+ case 7:
+ // XXX: Use PDF.js code?
+ break;
+
+ // PackBits
+ case 32773:
+ // Are we ready for a new block?
+ if (getHeader) {
+ getHeader = false;
+
+ var blockLength = 1;
+ var iterations = 1;
+
+ // The header byte is signed.
+ var header = this.getInt8(stripOffset + byteOffset);
+
+ if ((header >= 0) && (header <= 127)) { // Normal pixels.
+ blockLength = header + 1;
+ } else if ((header >= -127) && (header <= -1)) { // Collapsed pixels.
+ iterations = -header + 1;
+ } else /*if (header === -128)*/ { // Placeholder byte?
+ getHeader = true;
+ }
+ } else {
+ var currentByte = this.getUint8(stripOffset + byteOffset);
+
+ // Duplicate bytes, if necessary.
+ for (var m = 0; m < iterations; m++) {
+ if (sampleProperties[sample].hasBytesPerSample) {
+ // We're reading one byte at a time, so we need to handle multi-byte samples.
+ currentSample = (currentSample << (8 * numBytes)) | currentByte;
+ numBytes++;
+
+ // Is our sample complete?
+ if (numBytes === sampleProperties[sample].bytesPerSample) {
+ pixel.push(currentSample);
+ currentSample = numBytes = 0;
+ sample++;
+ }
+ } else {
+ throw RangeError("Cannot handle sub-byte bits per sample");
+ }
+
+ // Is our pixel complete?
+ if (sample === samplesPerPixel) {
+ strips[i].push(pixel);
+ pixel = [];
+ sample = 0;
+ }
+ }
+
+ blockLength--;
+
+ // Is our block complete?
+ if (blockLength === 0) {
+ getHeader = true;
+ }
+ }
+
+ jIncrement = 1;
+ break;
+
+ // Unknown compression algorithm
+ default:
+ // Do not attempt to parse the image data.
+ break;
+ }
+ }
+ }
+
+ if (canvas.getContext) {
+ var ctx = this.canvas.getContext("2d");
+
+ // Set a default fill style.
+ ctx.fillStyle = "rgba(255, 255, 255, 0)";
+
+ // If RowsPerStrip is missing, the whole image is in one strip.
+ var rowsPerStrip = fileDirectory['RowsPerStrip'] ? fileDirectory['RowsPerStrip'].values[0] : imageLength;
+
+ var numStrips = strips.length;
+
+ var imageLengthModRowsPerStrip = imageLength % rowsPerStrip;
+ var rowsInLastStrip = (imageLengthModRowsPerStrip === 0) ? rowsPerStrip : imageLengthModRowsPerStrip;
+
+ var numRowsInStrip = rowsPerStrip;
+ var numRowsInPreviousStrip = 0;
+
+ var photometricInterpretation = fileDirectory['PhotometricInterpretation'].values[0];
+
+ var extraSamplesValues = [];
+ var numExtraSamples = 0;
+
+ if (fileDirectory['ExtraSamples']) {
+ extraSamplesValues = fileDirectory['ExtraSamples'].values;
+ numExtraSamples = extraSamplesValues.length;
+ }
+
+ if (fileDirectory['ColorMap']) {
+ var colorMapValues = fileDirectory['ColorMap'].values;
+ var colorMapSampleSize = Math.pow(2, sampleProperties[0].bitsPerSample);
+ }
+
+ // Loop through the strips in the image.
+ for (var i = 0; i < numStrips; i++) {
+ // The last strip may be short.
+ if ((i + 1) === numStrips) {
+ numRowsInStrip = rowsInLastStrip;
+ }
+
+ var numPixels = strips[i].length;
+ var yPadding = numRowsInPreviousStrip * i;
+
+ // Loop through the rows in the strip.
+ for (var y = 0, j = 0; y < numRowsInStrip, j < numPixels; y++) {
+ // Loop through the pixels in the row.
+ for (var x = 0; x < imageWidth; x++, j++) {
+ var pixelSamples = strips[i][j];
+
+ var red = 0;
+ var green = 0;
+ var blue = 0;
+ var opacity = 1.0;
+
+ if (numExtraSamples > 0) {
+ for (var k = 0; k < numExtraSamples; k++) {
+ if (extraSamplesValues[k] === 1 || extraSamplesValues[k] === 2) {
+ // Clamp opacity to the range [0,1].
+ opacity = pixelSamples[3 + k] / 256;
+
+ break;
+ }
+ }
+ }
+
+ switch (photometricInterpretation) {
+ // Bilevel or Grayscale
+ // WhiteIsZero
+ case 0:
+ if (sampleProperties[0].hasBytesPerSample) {
+ var invertValue = Math.pow(0x10, sampleProperties[0].bytesPerSample * 2);
+ }
+
+ // Invert samples.
+ pixelSamples.forEach(function (sample, index, samples) {
+ samples[index] = invertValue - sample;
+ });
+
+ // Bilevel or Grayscale
+ // BlackIsZero
+ case 1:
+ red = green = blue = this.clampColorSample(pixelSamples[0], sampleProperties[0].bitsPerSample);
+ break;
+
+ // RGB Full Color
+ case 2:
+ red = this.clampColorSample(pixelSamples[0], sampleProperties[0].bitsPerSample);
+ green = this.clampColorSample(pixelSamples[1], sampleProperties[1].bitsPerSample);
+ blue = this.clampColorSample(pixelSamples[2], sampleProperties[2].bitsPerSample);
+ break;
+
+ // RGB Color Palette
+ case 3:
+ if (colorMapValues === undefined) {
+ throw Error("Palette image missing color map");
+ }
+
+ var colorMapIndex = pixelSamples[0];
+
+ red = this.clampColorSample(colorMapValues[colorMapIndex], 16);
+ green = this.clampColorSample(colorMapValues[colorMapSampleSize + colorMapIndex], 16);
+ blue = this.clampColorSample(colorMapValues[(2 * colorMapSampleSize) + colorMapIndex], 16);
+ break;
+
+ // Unknown Photometric Interpretation
+ default:
+ throw RangeError('Unknown Photometric Interpretation:', photometricInterpretation);
+ break;
+ }
+
+ ctx.fillStyle = "rgba(" + red + ", " + green + ", " + blue + ", " + opacity + ")";
+ ctx.fillRect(x, yPadding + y, 1, 1);
+ }
+ }
+
+ numRowsInPreviousStrip = numRowsInStrip;
+ }
+ }
+
+ return this.canvas;
+ },
+
+ // See: http://www.digitizationguidelines.gov/guidelines/TIFF_Metadata_Final.pdf
+ // See: http://www.digitalpreservation.gov/formats/content/tiff_tags.shtml
+ fieldTagNames: {
+ // TIFF Baseline
+ 0x013B: 'Artist',
+ 0x0102: 'BitsPerSample',
+ 0x0109: 'CellLength',
+ 0x0108: 'CellWidth',
+ 0x0140: 'ColorMap',
+ 0x0103: 'Compression',
+ 0x8298: 'Copyright',
+ 0x0132: 'DateTime',
+ 0x0152: 'ExtraSamples',
+ 0x010A: 'FillOrder',
+ 0x0121: 'FreeByteCounts',
+ 0x0120: 'FreeOffsets',
+ 0x0123: 'GrayResponseCurve',
+ 0x0122: 'GrayResponseUnit',
+ 0x013C: 'HostComputer',
+ 0x010E: 'ImageDescription',
+ 0x0101: 'ImageLength',
+ 0x0100: 'ImageWidth',
+ 0x010F: 'Make',
+ 0x0119: 'MaxSampleValue',
+ 0x0118: 'MinSampleValue',
+ 0x0110: 'Model',
+ 0x00FE: 'NewSubfileType',
+ 0x0112: 'Orientation',
+ 0x0106: 'PhotometricInterpretation',
+ 0x011C: 'PlanarConfiguration',
+ 0x0128: 'ResolutionUnit',
+ 0x0116: 'RowsPerStrip',
+ 0x0115: 'SamplesPerPixel',
+ 0x0131: 'Software',
+ 0x0117: 'StripByteCounts',
+ 0x0111: 'StripOffsets',
+ 0x00FF: 'SubfileType',
+ 0x0107: 'Threshholding',
+ 0x011A: 'XResolution',
+ 0x011B: 'YResolution',
+
+ // TIFF Extended
+ 0x0146: 'BadFaxLines',
+ 0x0147: 'CleanFaxData',
+ 0x0157: 'ClipPath',
+ 0x0148: 'ConsecutiveBadFaxLines',
+ 0x01B1: 'Decode',
+ 0x01B2: 'DefaultImageColor',
+ 0x010D: 'DocumentName',
+ 0x0150: 'DotRange',
+ 0x0141: 'HalftoneHints',
+ 0x015A: 'Indexed',
+ 0x015B: 'JPEGTables',
+ 0x011D: 'PageName',
+ 0x0129: 'PageNumber',
+ 0x013D: 'Predictor',
+ 0x013F: 'PrimaryChromaticities',
+ 0x0214: 'ReferenceBlackWhite',
+ 0x0153: 'SampleFormat',
+ 0x022F: 'StripRowCounts',
+ 0x014A: 'SubIFDs',
+ 0x0124: 'T4Options',
+ 0x0125: 'T6Options',
+ 0x0145: 'TileByteCounts',
+ 0x0143: 'TileLength',
+ 0x0144: 'TileOffsets',
+ 0x0142: 'TileWidth',
+ 0x012D: 'TransferFunction',
+ 0x013E: 'WhitePoint',
+ 0x0158: 'XClipPathUnits',
+ 0x011E: 'XPosition',
+ 0x0211: 'YCbCrCoefficients',
+ 0x0213: 'YCbCrPositioning',
+ 0x0212: 'YCbCrSubSampling',
+ 0x0159: 'YClipPathUnits',
+ 0x011F: 'YPosition',
+
+ // EXIF
+ 0x9202: 'ApertureValue',
+ 0xA001: 'ColorSpace',
+ 0x9004: 'DateTimeDigitized',
+ 0x9003: 'DateTimeOriginal',
+ 0x8769: 'Exif IFD',
+ 0x9000: 'ExifVersion',
+ 0x829A: 'ExposureTime',
+ 0xA300: 'FileSource',
+ 0x9209: 'Flash',
+ 0xA000: 'FlashpixVersion',
+ 0x829D: 'FNumber',
+ 0xA420: 'ImageUniqueID',
+ 0x9208: 'LightSource',
+ 0x927C: 'MakerNote',
+ 0x9201: 'ShutterSpeedValue',
+ 0x9286: 'UserComment',
+
+ // IPTC
+ 0x83BB: 'IPTC',
+
+ // ICC
+ 0x8773: 'ICC Profile',
+
+ // XMP
+ 0x02BC: 'XMP',
+
+ // GDAL
+ 0xA480: 'GDAL_METADATA',
+ 0xA481: 'GDAL_NODATA',
+
+ // Photoshop
+ 0x8649: 'Photoshop'
+ },
+
+ fieldTypeNames: {
+ 0x0001: 'BYTE',
+ 0x0002: 'ASCII',
+ 0x0003: 'SHORT',
+ 0x0004: 'LONG',
+ 0x0005: 'RATIONAL',
+ 0x0006: 'SBYTE',
+ 0x0007: 'UNDEFINED',
+ 0x0008: 'SSHORT',
+ 0x0009: 'SLONG',
+ 0x000A: 'SRATIONAL',
+ 0x000B: 'FLOAT',
+ 0x000C: 'DOUBLE'
+ }
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsDebugNode.js b/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsDebugNode.js
new file mode 100644
index 0000000..003bfe3
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsDebugNode.js
@@ -0,0 +1,212 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2012 Scott Lembcke and Howling Moon Software
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/*
+ IMPORTANT - READ ME!
+
+ This file sets pokes around in the private API a lot to provide efficient
+ debug rendering given nothing more than reference to a Chipmunk space.
+ It is not recommended to write rendering code like this in your own games
+ as the private API may change with little or no warning.
+ */
+
+/**
+ * Converts an array of numbers into an array of vectors(x,y)
+ * @function
+ * @param {Array} verts
+ * @return {Array}
+ */
+cc.__convertVerts = function (verts) {
+ var ret = [];
+ for (var i = 0; i < verts.length / 2; i++) {
+ ret[i] = {x:verts[i * 2], y:verts[i * 2 + 1]};
+ }
+ return ret;
+};
+
+/**
+ * color for body
+ * @function
+ * @param {cp.Body} body
+ * @return {cc.color}
+ */
+cc.ColorForBody = function (body) {
+ if (body.isRogue() || body.isSleeping()) {
+ return cc.color(128, 128, 128, 128);
+ } else if (body.nodeIdleTime > body.space.sleepTimeThreshold) {
+ return cc.color(84, 84, 84, 128);
+ } else {
+ return cc.color(255, 0, 0, 128);
+ }
+};
+
+/**
+ * draw shape
+ * @param {cp.Shape} shape
+ * @param renderer
+ */
+cc.DrawShape = function (shape, renderer) {
+ var body = shape.body;
+ var color = cc.ColorForBody(body);
+ switch (shape.collisionCode) {
+ case cp.CircleShape.prototype.collisionCode:
+ this.drawDot(shape.tc, Math.max(shape.r, 1.0), color);
+ this.drawSegment(shape.tc, cp.v.add(shape.tc, cp.v.mult(body.rot, shape.r)), 1.0, color);
+ break;
+ case cp.SegmentShape.prototype.collisionCode:
+ this.drawSegment(shape.ta, shape.tb, Math.max(shape.r, 2.0), color);
+ break;
+ case cp.PolyShape.prototype.collisionCode:
+ var line = cc.color(color.r, color.g, color.b, cc.lerp(color.a, 255, 0.5));
+ this.drawPoly(cc.__convertVerts(shape.tVerts), color, 1.0, line);
+ break;
+ default:
+ cc.log("cc.DrawShape(): Bad assertion in DrawShape()");
+ break;
+ }
+};
+
+/**
+ * draw constraint
+ * @param {cp.Constraint} constraint
+ * @param renderer
+ */
+cc.DrawConstraint = function (constraint, renderer) {
+ var body_a = constraint.a;
+ var body_b = constraint.b;
+ var a, b;
+
+ if (constraint instanceof cp.PinJoint) {
+ a = body_a.local2World(constraint.anchr1);
+ b = body_b.local2World(constraint.anchr2);
+ this.drawDot(a, 3.0, cc.CONSTRAINT_COLOR);
+ this.drawDot(b, 3.0, cc.CONSTRAINT_COLOR);
+ this.drawSegment(a, b, 1.0, cc.CONSTRAINT_COLOR);
+ } else if (constraint instanceof cp.SlideJoint) {
+ a = body_a.local2World(constraint.anchr1);
+ b = body_b.local2World(constraint.anchr2);
+
+ this.drawDot(a, 3.0, cc.CONSTRAINT_COLOR);
+ this.drawDot(b, 3.0, cc.CONSTRAINT_COLOR);
+ this.drawSegment(a, b, 1.0, cc.CONSTRAINT_COLOR);
+ } else if (constraint instanceof cp.PivotJoint) {
+ a = body_a.local2World(constraint.anchr1);
+ b = body_b.local2World(constraint.anchr2);
+ this.drawDot(a, 3.0, cc.CONSTRAINT_COLOR);
+ this.drawDot(b, 3.0, cc.CONSTRAINT_COLOR);
+ } else if (constraint instanceof cp.GrooveJoint) {
+ a = body_a.local2World(constraint.grv_a);
+ b = body_a.local2World(constraint.grv_b);
+ var c = body_b.local2World(constraint.anchr2);
+
+ this.drawDot(c, 3.0, cc.CONSTRAINT_COLOR);
+ this.drawSegment(a, b, 1.0, cc.CONSTRAINT_COLOR);
+ } else if (constraint instanceof cp.DampedSpring) {
+ // TODO
+ } else {
+ //printf("Cannot draw constraint\n");
+ }
+};
+
+/**
+ * @constant
+ * @type {cc.color}
+ */
+cc.CONSTRAINT_COLOR = cc.color(0, 255, 0, 128);
+
+
+/**
+ * A Node that draws the components of a physics engine.
+ * Supported physics engines:
+ * - Chipmunk
+ * - Objective-Chipmunk
+ *
+ * @class
+ * @extends cc.DrawNode
+ *
+ * @property {cp.Space} space Physic world space
+ */
+cc.PhysicsDebugNode = cc.DrawNode.extend({
+ _space:null,
+ _className:"PhysicsDebugNode",
+
+ /**
+ * constructor of cc.PhysicsDebugNode
+ * @param {cp.Space} space
+ */
+ ctor: function (space) {
+ cc.DrawNode.prototype.ctor.call(this);
+ this._space = space;
+ },
+
+ /**
+ * get space
+ * @returns {cp.Space}
+ */
+ getSpace:function () {
+ return this._space;
+ },
+
+ /**
+ * set space
+ * @param {cp.Space} space
+ */
+ setSpace:function (space) {
+ this._space = space;
+ },
+
+ /**
+ * draw
+ * @param {object} context
+ */
+ draw:function (context) {
+ if (!this._space)
+ return;
+
+ this._space.eachShape(cc.DrawShape.bind(this));
+ this._space.eachConstraint(cc.DrawConstraint.bind(this));
+ cc.DrawNode.prototype.draw.call(this);
+ this.clear();
+ },
+
+ _createRenderCmd: function(){
+ if(cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.PhysicsDebugNode.CanvasRenderCmd(this);
+ else
+ return new cc.PhysicsDebugNode.WebGLRenderCmd(this);
+ }
+});
+
+/**
+ * Create a debug node for a regular Chipmunk space.
+ * @deprecated since v3.0, please use new cc.PhysicsDebugNode(space)
+ * @param {cp.Space} space
+ * @return {cc.PhysicsDebugNode}
+ */
+cc.PhysicsDebugNode.create = function (space) {
+ return new cc.PhysicsDebugNode(space);
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsDebugNodeCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsDebugNodeCanvasRenderCmd.js
new file mode 100644
index 0000000..1adf9a3
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsDebugNodeCanvasRenderCmd.js
@@ -0,0 +1,52 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.PhysicsDebugNode's rendering objects of Canvas
+ */
+(function () {
+ cc.PhysicsDebugNode.CanvasRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._buffer = renderableObject._buffer;
+ this._needDraw = true;
+ };
+
+ var proto = cc.PhysicsDebugNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ proto.constructor = cc.PhysicsDebugNode.CanvasRenderCmd;
+
+ proto.rendering = function (ctx, scaleX, scaleY) {
+ var node = this._node;
+ if (!node._space)
+ return;
+ node._space.eachShape(cc.DrawShape.bind(node));
+ node._space.eachConstraint(cc.DrawConstraint.bind(node));
+ cc.DrawNode.CanvasRenderCmd.prototype.rendering.call(this, ctx, scaleX, scaleY);
+ node.clear();
+ };
+
+ proto._drawDot = cc.DrawNode.CanvasRenderCmd.prototype._drawDot;
+ proto._drawSegment = cc.DrawNode.CanvasRenderCmd.prototype._drawSegment;
+ proto._drawPoly = cc.DrawNode.CanvasRenderCmd.prototype._drawPoly;
+
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js
new file mode 100644
index 0000000..0b8a185
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js
@@ -0,0 +1,62 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.PhysicsDebugNode's rendering objects of WebGL
+ */
+(function () {
+ cc.PhysicsDebugNode.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+ };
+
+ cc.PhysicsDebugNode.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ cc.PhysicsDebugNode.WebGLRenderCmd.prototype.constructor = cc.PhysicsDebugNode.WebGLRenderCmd;
+
+ cc.PhysicsDebugNode.WebGLRenderCmd.prototype.rendering = function (ctx) {
+ var node = this._node;
+ if (!node._space)
+ return;
+
+ node._space.eachShape(cc.DrawShape.bind(node));
+ node._space.eachConstraint(cc.DrawConstraint.bind(node));
+
+ var wt = this._worldTransform;
+ this._matrix.mat[0] = wt.a;
+ this._matrix.mat[4] = wt.c;
+ this._matrix.mat[12] = wt.tx;
+ this._matrix.mat[1] = wt.b;
+ this._matrix.mat[5] = wt.d;
+ this._matrix.mat[13] = wt.ty;
+
+ //cc.DrawNode.prototype.draw.call(node);
+ cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
+ this._glProgramState.apply(this._matrix);
+ node._render();
+
+ node.clear();
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsSprite.js b/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsSprite.js
new file mode 100644
index 0000000..dde3546
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsSprite.js
@@ -0,0 +1,442 @@
+/**
+ * Copyright (c) 2012 Scott Lembcke and Howling Moon Software
+ * Copyright (c) 2008-2010 Ricardo Quesada
+ * Copyright (c) 2011-2012 cocos2d-x.org
+ * Copyright (c) 2013-2014 Chukong Technologies Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/** A CCSprite subclass that is bound to a physics body.
+ It works with:
+ - Chipmunk: Preprocessor macro CC_ENABLE_CHIPMUNK_INTEGRATION should be defined
+ - Objective-Chipmunk: Preprocessor macro CC_ENABLE_CHIPMUNK_INTEGRATION should be defined
+ - Box2d: Preprocessor macro CC_ENABLE_BOX2D_INTEGRATION should be defined
+
+ Features and Limitations:
+ - Scale and Skew properties are ignored.
+ - Position and rotation are going to updated from the physics body
+ - If you update the rotation or position manually, the physics body will be updated
+ - You can't eble both Chipmunk support and Box2d support at the same time. Only one can be enabled at compile time
+ */
+(function () {
+ var box2dAPI = {
+ _ignoreBodyRotation: false,
+ _body: null,
+ _PTMRatio: 32,
+ _rotation: 1,
+ /**
+ * Create a PhysicsSprite with filename and rect
+ * Constructor of cc.PhysicsSprite for Box2d
+ * @param {String|cc.Texture2D|cc.SpriteFrame} fileName
+ * @param {cc.Rect} rect
+ * @example
+ *
+ * 1.Create a sprite with image path and rect
+ * var physicsSprite1 = new cc.PhysicsSprite("res/HelloHTML5World.png");
+ * var physicsSprite2 = new cc.PhysicsSprite("res/HelloHTML5World.png",cc.rect(0,0,480,320));
+ *
+ * 2.Create a sprite with a sprite frame name. Must add "#" before fame name.
+ * var physicsSprite = new cc.PhysicsSprite('#grossini_dance_01.png');
+ *
+ * 3.Create a sprite with a sprite frame
+ * var spriteFrame = cc.spriteFrameCache.getSpriteFrame("grossini_dance_01.png");
+ * var physicsSprite = new cc.PhysicsSprite(spriteFrame);
+ *
+ * 4.Creates a sprite with an existing texture contained in a CCTexture2D object
+ * After creation, the rect will be the size of the texture, and the offset will be (0,0).
+ * var texture = cc.textureCache.addImage("HelloHTML5World.png");
+ * var physicsSprite1 = new cc.PhysicsSprite(texture);
+ * var physicsSprite2 = new cc.PhysicsSprite(texture, cc.rect(0,0,480,320));
+ *
+ */
+ ctor: function (fileName, rect) {
+ cc.Sprite.prototype.ctor.call(this);
+
+ if (fileName === undefined) {
+ cc.PhysicsSprite.prototype.init.call(this);
+ } else if (cc.isString(fileName)) {
+ if (fileName[0] === "#") {
+ //init with a sprite frame name
+ var frameName = fileName.substr(1, fileName.length - 1);
+ var spriteFrame = cc.spriteFrameCache.getSpriteFrame(frameName);
+ this.initWithSpriteFrame(spriteFrame);
+ } else {
+ //init with filename and rect
+ this.init(fileName, rect);
+ }
+ } else if (cc.isObject(fileName)) {
+ if (fileName instanceof cc.Texture2D) {
+ //init with texture and rect
+ this.initWithTexture(fileName, rect);
+ } else if (fileName instanceof cc.SpriteFrame) {
+ //init with a sprite frame
+ this.initWithSpriteFrame(fileName);
+ }
+ }
+ //this._transformCmd = new cc.PhysicsSpriteTransformCmdCanvas(this);
+ //cc.rendererCanvas.pushRenderCommand(this._transformCmd);
+ },
+
+ //visit: function(){
+ // cc.Sprite.prototype.visit.call(this);
+ // cc.rendererCanvas.pushRenderCommand(this._transformCmd);
+ //},
+
+ /**
+ * set body
+ * @param {Box2D.Dynamics.b2Body} body
+ */
+ setBody: function (body) {
+ this._body = body;
+ },
+
+ /**
+ * get body
+ * @return {Box2D.Dynamics.b2Body}
+ */
+ getBody: function () {
+ return this._body;
+ },
+
+ /**
+ * set PTM ratio
+ * @param {Number} r
+ */
+ setPTMRatio: function (r) {
+ this._PTMRatio = r;
+ },
+
+ /**
+ * get PTM ration
+ * @return {Number}
+ */
+ getPTMRatio: function () {
+ return this._PTMRatio;
+ },
+
+ /**
+ * get position
+ * @return {cc.Point}
+ */
+ getPosition: function () {
+ var pos = this._body.GetPosition();
+ var locPTMRatio = this._PTMRatio;
+ return cc.p(pos.x * locPTMRatio, pos.y * locPTMRatio);
+ },
+
+ /**
+ * set position
+ * @param {cc.Point} p
+ */
+ setPosition: function (p) {
+ var angle = this._body.GetAngle();
+ var locPTMRatio = this._PTMRatio;
+ this._body.setTransform(Box2D.b2Vec2(p.x / locPTMRatio, p.y / locPTMRatio), angle);
+ this.setNodeDirty();
+ },
+
+ /**
+ * get rotation
+ * @return {Number}
+ */
+ getRotation: function () {
+ return (this._ignoreBodyRotation ? cc.radiansToDegrees(this._rotationRadians) : cc.radiansToDegrees(this._body.GetAngle()));
+ },
+
+ /**
+ * set rotation
+ * @param {Number} r
+ */
+ setRotation: function (r) {
+ if (this._ignoreBodyRotation) {
+ this._rotation = r;
+ } else {
+ var locBody = this._body;
+ var p = locBody.GetPosition();
+ locBody.SetTransform(p, cc.degreesToRadians(r));
+ }
+ this.setNodeDirty();
+ },
+
+ _syncPosition: function () {
+ var locPosition = this._position,
+ pos = this._body.GetPosition(),
+ x = pos.x * this._PTMRatio,
+ y = pos.y * this._PTMRatio;
+ if (locPosition.x !== pos.x || locPosition.y !== pos.y) {
+ cc.Sprite.prototype.setPosition.call(this, x, y);
+ }
+ },
+ _syncRotation: function () {
+ this._rotationRadians = this._body.GetAngle();
+ var a = cc.radiansToDegrees(this._rotationRadians);
+ if (this._rotationX !== a) {
+ cc.Sprite.prototype.setRotation.call(this, a);
+ }
+ },
+
+ /**
+ * set whether to ingore body's rotation
+ * @param {Boolean} b
+ */
+ setIgnoreBodyRotation: function (b) {
+ this._ignoreBodyRotation = b;
+ }
+ };
+
+ var chipmunkAPI = {
+ _ignoreBodyRotation: false,
+ _body: null, //physics body
+ _rotation: 1,
+
+ /**
+ * Create a PhysicsSprite with filename and rect
+ * Constructor of cc.PhysicsSprite for chipmunk
+ * @param {String|cc.Texture2D|cc.SpriteFrame} fileName
+ * @param {cc.Rect} rect
+ * @example
+ *
+ * 1.Create a sprite with image path and rect
+ * var physicsSprite1 = new cc.PhysicsSprite("res/HelloHTML5World.png");
+ * var physicsSprite2 = new cc.PhysicsSprite("res/HelloHTML5World.png",cc.rect(0,0,480,320));
+ *
+ * 2.Create a sprite with a sprite frame name. Must add "#" before frame name.
+ * var physicsSprite = new cc.PhysicsSprite('#grossini_dance_01.png');
+ *
+ * 3.Create a sprite with a sprite frame
+ * var spriteFrame = cc.spriteFrameCache.getSpriteFrame("grossini_dance_01.png");
+ * var physicsSprite = new cc.PhysicsSprite(spriteFrame);
+ *
+ * 4.Creates a sprite with an exsiting texture contained in a CCTexture2D object
+ * After creation, the rect will be the size of the texture, and the offset will be (0,0).
+ * var texture = cc.textureCache.addImage("HelloHTML5World.png");
+ * var physicsSprite1 = new cc.PhysicsSprite(texture);
+ * var physicsSprite2 = new cc.PhysicsSprite(texture, cc.rect(0,0,480,320));
+ *
+ */
+ ctor: function (fileName, rect) {
+ cc.Sprite.prototype.ctor.call(this);
+
+ if (fileName === undefined) {
+ cc.PhysicsSprite.prototype.init.call(this);
+ } else if (cc.isString(fileName)) {
+ if (fileName[0] === "#") {
+ //init with a sprite frame name
+ var frameName = fileName.substr(1, fileName.length - 1);
+ var spriteFrame = cc.spriteFrameCache.getSpriteFrame(frameName);
+ this.initWithSpriteFrame(spriteFrame);
+ } else {
+ //init with filename and rect
+ this.init(fileName, rect);
+ }
+ } else if (cc.isObject(fileName)) {
+ if (fileName instanceof cc.Texture2D) {
+ //init with texture and rect
+ this.initWithTexture(fileName, rect);
+ } else if (fileName instanceof cc.SpriteFrame) {
+ //init with a sprite frame
+ this.initWithSpriteFrame(fileName);
+ }
+ }
+
+ cc.renderer.pushRenderCommand(this._renderCmd);
+ },
+
+ visit: function () {
+ cc.renderer.pushRenderCommand(this._renderCmd);
+ cc.Sprite.prototype.visit.call(this);
+ },
+
+ /**
+ * set body
+ * @param {cp.Body} body
+ */
+ setBody: function (body) {
+ this._body = body;
+ },
+
+ /**
+ * get body
+ * @returns {cp.Body}
+ */
+ getBody: function () {
+ return this._body;
+ },
+
+ /**
+ * get position
+ * @return {cc.Point}
+ */
+ getPosition: function () {
+ var locBody = this._body;
+ return {x: locBody.p.x, y: locBody.p.y};
+ },
+
+ /**
+ * get position x
+ * @return {Number}
+ */
+ getPositionX: function () {
+ return this._body.p.x;
+ },
+
+ /**
+ * get position y
+ * @return {Number}
+ */
+ getPositionY: function () {
+ return this._body.p.y;
+ },
+
+ /**
+ * set position
+ * @param {cc.Point|Number}newPosOrxValue
+ * @param {Number}yValue
+ */
+ setPosition: function (newPosOrxValue, yValue) {
+ if (yValue === undefined) {
+ this._body.p.x = newPosOrxValue.x;
+ this._body.p.y = newPosOrxValue.y;
+ } else {
+ this._body.p.x = newPosOrxValue;
+ this._body.p.y = yValue;
+ }
+ },
+
+ /**
+ * set position x
+ * @param {Number} xValue
+ */
+ setPositionX: function (xValue) {
+ this._body.p.x = xValue;
+ },
+
+ /**
+ * set position y
+ * @param {Number} yValue
+ */
+ setPositionY: function (yValue) {
+ this._body.p.y = yValue;
+ },
+
+ _syncPosition: function () {
+ var locPosition = this._position, locBody = this._body;
+ if (locPosition.x !== locBody.p.x || locPosition.y !== locBody.p.y) {
+ cc.Sprite.prototype.setPosition.call(this, locBody.p.x, locBody.p.y);
+ }
+ },
+
+ /**
+ * get rotation
+ * @return {Number}
+ */
+ getRotation: function () {
+ return this._ignoreBodyRotation ? this._rotationX : -cc.radiansToDegrees(this._body.a);
+ },
+
+ /**
+ * set rotation
+ * @param {Number} r
+ */
+ setRotation: function (r) {
+ if (this._ignoreBodyRotation) {
+ cc.Sprite.prototype.setRotation.call(this, r);
+ } else {
+ this._body.a = -cc.degreesToRadians(r);
+ }
+ },
+ _syncRotation: function () {
+ var a = -cc.radiansToDegrees(this._body.a);
+ if (this._rotationX !== a) {
+ cc.Sprite.prototype.setRotation.call(this, a);
+ }
+ },
+
+ /**
+ * get the affine transform matrix of node to parent coordinate frame
+ * @return {cc.AffineTransform}
+ */
+ getNodeToParentTransform: function () {
+ return this._renderCmd.getNodeToParentTransform();
+ },
+
+ /**
+ * whether dirty
+ * @return {Boolean}
+ */
+ isDirty: function () {
+ return !this._body.isSleeping();
+ },
+ setDirty: function () {
+ },
+
+ /**
+ * set whether to ignore rotation of body
+ * @param {Boolean} b
+ */
+ setIgnoreBodyRotation: function (b) {
+ this._ignoreBodyRotation = b;
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.PhysicsSprite.CanvasRenderCmd(this);
+ else
+ return new cc.PhysicsSprite.WebGLRenderCmd(this);
+ }
+ };
+ /**
+ * @class
+ */
+ cc.PhysicsSprite = cc.Sprite.extend(chipmunkAPI);
+ cc.PhysicsSprite._className = "PhysicsSprite";
+ var _p = cc.PhysicsSprite.prototype;
+ // Extended properties
+ /** @expose */
+ _p.body;
+ cc.defineGetterSetter(_p, "body", _p.getBody, _p.setBody);
+ /** @expose */
+ _p.dirty;
+ cc.defineGetterSetter(_p, "dirty", _p.isDirty, _p.setDirty);
+
+
+ /**
+ * Create a PhysicsSprite with filename and rect
+ * @deprecated since v3.0, please use new cc.PhysicsSprite(fileName, rect) instead
+ * @param {String|cc.Texture2D|cc.SpriteFrame} fileName
+ * @param {cc.Rect} rect
+ * @return {cc.PhysicsSprite}
+ */
+ cc.PhysicsSprite.create = function (fileName, rect) {
+ return new cc.PhysicsSprite(fileName, rect);
+ };
+
+ /**
+ * @deprecated since v3.0, please use new cc.PhysicsSprite(spriteFrameName) instead
+ * @type {Function}
+ */
+ cc.PhysicsSprite.createWithSpriteFrameName = cc.PhysicsSprite.create;
+
+ /**
+ * @deprecated since v3.0, please use new cc.PhysicsSprite(spriteFrame) instead
+ * @type {Function}
+ */
+ cc.PhysicsSprite.createWithSpriteFrame = cc.PhysicsSprite.create;
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsSpriteCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsSpriteCanvasRenderCmd.js
new file mode 100644
index 0000000..09279e6
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsSpriteCanvasRenderCmd.js
@@ -0,0 +1,50 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.PhysicsSprite's rendering objects of Canvas
+ */
+(function () {
+ cc.PhysicsSprite.CanvasRenderCmd = function (renderableObject) {
+ this._spriteCmdCtor(renderableObject);
+ this._needDraw = true;
+ };
+
+ var proto = cc.PhysicsSprite.CanvasRenderCmd.prototype = Object.create(cc.Sprite.CanvasRenderCmd.prototype);
+ proto.constructor = cc.PhysicsSprite.CanvasRenderCmd;
+
+ proto.rendering = function (ctx, scaleX, scaleY) {
+ // This is a special class
+ // Sprite can not obtain sign
+ // So here must to calculate of each frame
+ var node = this._node;
+ node._syncPosition();
+ if (!node._ignoreBodyRotation)
+ node._syncRotation();
+ this.transform(this.getParentRenderCmd());
+
+ cc.Sprite.CanvasRenderCmd.prototype.rendering.call(this, ctx, scaleX, scaleY);
+ };
+
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js
new file mode 100644
index 0000000..25fc120
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js
@@ -0,0 +1,51 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.PhysicsSprite's rendering objects of WebGL
+ */
+(function () {
+ cc.PhysicsSprite.WebGLRenderCmd = function (renderableObject) {
+ this._spriteCmdCtor(renderableObject);
+ this._needDraw = true;
+ };
+
+ var proto = cc.PhysicsSprite.WebGLRenderCmd.prototype = Object.create(cc.Sprite.WebGLRenderCmd.prototype);
+ proto.constructor = cc.PhysicsSprite.WebGLRenderCmd;
+
+ proto.spUploadData = cc.Sprite.WebGLRenderCmd.prototype.uploadData;
+
+ proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset) {
+ // This is a special class
+ // Sprite can not obtain sign
+ // So here must to calculate of each frame
+ var node = this._node;
+ node._syncPosition();
+ if (!node._ignoreBodyRotation)
+ node._syncRotation();
+ this.transform(this.getParentRenderCmd(), true);
+
+ return this.spUploadData(f32buffer, ui32buffer, vertexDataOffset);
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/progress-timer/CCActionProgressTimer.js b/frameworks/cocos2d-html5/cocos2d/progress-timer/CCActionProgressTimer.js
new file mode 100644
index 0000000..026af89
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/progress-timer/CCActionProgressTimer.js
@@ -0,0 +1,227 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (C) 2010 Lam Pham
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Progress to percentage
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} duration duration in seconds
+ * @param {Number} percent
+ * @example
+ * var to = new cc.ProgressTo(2, 100);
+ */
+cc.ProgressTo = cc.ActionInterval.extend(/** @lends cc.ProgressTo# */{
+ _to:0,
+ _from:0,
+
+ /**
+ * Creates a ProgressTo action with a duration and a percent
+ * Constructor of cc.ProgressTo
+ * @param {Number} duration duration in seconds
+ * @param {Number} percent
+ */
+ ctor: function(duration, percent){
+ cc.ActionInterval.prototype.ctor.call(this);
+ this._to = 0;
+ this._from = 0;
+
+ percent !== undefined && this.initWithDuration(duration, percent);
+ },
+
+ /** Initializes with a duration and a percent
+ * @param {Number} duration duration in seconds
+ * @param {Number} percent
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, percent) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ this._to = percent;
+ return true;
+ }
+ return false;
+ },
+ /**
+ * return a new cc.ProgressTo, all the configuration is the same as the original
+ * @returns {cc.ProgressTo}
+ */
+ clone:function(){
+ var action = new cc.ProgressTo();
+ action.initWithDuration(this._duration, this._to);
+ return action;
+ },
+ /**
+ * reverse hasn't been supported
+ * @returns {null}
+ */
+ reverse: function(){
+ cc.log("cc.ProgressTo.reverse(): reverse hasn't been supported.");
+ return null;
+ },
+
+ /**
+ * start with a target
+ * @param {cc.Node} target
+ */
+ startWithTarget:function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ this._from = target.percentage;
+ },
+
+ /**
+ * custom update
+ * @param {Number} time time in seconds
+ */
+ update:function (time) {
+ if (this.target instanceof cc.ProgressTimer)
+ this.target.percentage = this._from + (this._to - this._from) * time;
+ }
+});
+
+/**
+ * Creates and initializes with a duration and a percent
+ * @function
+ * @param {Number} duration duration in seconds
+ * @param {Number} percent
+ * @return {cc.ProgressTo}
+ * @example
+ * // example
+ * var to = cc.progressTo(2, 100);
+ */
+cc.progressTo = function (duration, percent) {
+ return new cc.ProgressTo(duration, percent);
+};
+/**
+ * Please use cc.progressTo instead
+ * Creates and initializes with a duration and a percent
+ * @static
+ * @deprecated since v3.0,please use cc.progressTo instead.
+ * @param {Number} duration duration in seconds
+ * @param {Number} percent
+ * @return {cc.ProgressTo}
+ */
+cc.ProgressTo.create = cc.progressTo;
+
+/**
+ * Progress from a percentage to another percentage
+ * @class
+ * @extends cc.ActionInterval
+ * @param {Number} duration duration in seconds
+ * @param {Number} fromPercentage
+ * @param {Number} toPercentage
+ * @example
+ * var fromTo = new cc.ProgressFromTo(2, 100.0, 0.0);
+ */
+cc.ProgressFromTo = cc.ActionInterval.extend(/** @lends cc.ProgressFromTo# */{
+ _to:0,
+ _from:0,
+
+ /**
+ * Creates and initializes the action with a duration, a "from" percentage and a "to" percentage
+ * Constructor of cc.ProgressFromTo
+ * @param {Number} duration duration in seconds
+ * @param {Number} fromPercentage
+ * @param {Number} toPercentage
+ */
+ ctor:function(duration, fromPercentage, toPercentage){
+ cc.ActionInterval.prototype.ctor.call(this);
+ this._to = 0;
+ this._from = 0;
+
+ toPercentage !== undefined && this.initWithDuration(duration, fromPercentage, toPercentage);
+ },
+
+ /** Initializes the action with a duration, a "from" percentage and a "to" percentage
+ * @param {Number} duration duration in seconds
+ * @param {Number} fromPercentage
+ * @param {Number} toPercentage
+ * @return {Boolean}
+ */
+ initWithDuration:function (duration, fromPercentage, toPercentage) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ this._to = toPercentage;
+ this._from = fromPercentage;
+ return true;
+ }
+ return false;
+ },
+ /**
+ * return a new cc.ProgressTo, all the configuration is the same as the original
+ * @returns {cc.ProgressFromTo}
+ */
+ clone:function(){
+ var action = new cc.ProgressFromTo();
+ action.initWithDuration(this._duration, this._from, this._to);
+ return action;
+ },
+
+ /**
+ * @return {cc.ActionInterval}
+ */
+ reverse:function () {
+ return cc.progressFromTo(this._duration, this._to, this._from);
+ },
+
+ /**
+ * start with a target
+ * @param {cc.Node} target
+ */
+ startWithTarget:function (target) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, target);
+ },
+
+ /**
+ * @param {Number} time time in seconds
+ */
+ update:function (time) {
+ if (this.target instanceof cc.ProgressTimer)
+ this.target.percentage = this._from + (this._to - this._from) * time;
+ }
+});
+
+/** Creates and initializes the action with a duration, a "from" percentage and a "to" percentage
+ * @function
+ * @param {Number} duration duration in seconds
+ * @param {Number} fromPercentage
+ * @param {Number} toPercentage
+ * @return {cc.ProgressFromTo}
+ * @example
+ * // example
+ * var fromTo = cc.progressFromTo(2, 100.0, 0.0);
+ */
+cc.progressFromTo = function (duration, fromPercentage, toPercentage) {
+ return new cc.ProgressFromTo(duration, fromPercentage, toPercentage);
+};
+/**
+ * Creates and initializes the action with a duration, a "from" percentage and a "to" percentage
+ * @static
+ * @deprecated since v3.0,please use cc.ProgressFromTo(duration, fromPercentage, toPercentage) instead.
+ * @param {Number} duration duration in seconds
+ * @param {Number} fromPercentage
+ * @param {Number} toPercentage
+ * @return {cc.ProgressFromTo}
+ */
+cc.ProgressFromTo.create = cc.progressFromTo;
diff --git a/frameworks/cocos2d-html5/cocos2d/progress-timer/CCProgressTimer.js b/frameworks/cocos2d-html5/cocos2d/progress-timer/CCProgressTimer.js
new file mode 100644
index 0000000..abeeb16
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/progress-timer/CCProgressTimer.js
@@ -0,0 +1,363 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2010 Lam Pham
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.Progresstimer is a subclass of cc.Node.
+ * It renders the inner sprite according to the percentage.
+ * The progress can be Radial, Horizontal or vertical.
+ * @class
+ * @extends cc.Node
+ *
+ * @property {cc.Point} midPoint - Midpoint is used to modify the progress start position.
+ * If you're using radials type then the midpoint changes the center point
+ * If you're using bar type the the midpoint changes the bar growth
+ * it expands from the center but clamps to the sprites edge so:
+ * you want a left to right then set the midpoint all the way to cc.p(0,y)
+ * you want a right to left then set the midpoint all the way to cc.p(1,y)
+ * you want a bottom to top then set the midpoint all the way to cc.p(x,0)
+ * you want a top to bottom then set the midpoint all the way to cc.p(x,1)
+ * @property {cc.Point} barChangeRate - This allows the bar type to move the component at a specific rate.
+ * @property {enum} type - Type of the progress timer: cc.ProgressTimer.TYPE_RADIAL|cc.ProgressTimer.TYPE_BAR.
+ * @property {Number} percentage - Percentage to change progress, from 0 to 100.
+ * @property {cc.Sprite} sprite - The sprite to show the progress percentage.
+ * @property {Boolean} reverseDir - Indicate whether the direction is reversed.
+ *
+ */
+cc.ProgressTimer = cc.Node.extend(/** @lends cc.ProgressTimer# */{
+ _type:null,
+ _percentage:0.0,
+ _sprite:null,
+
+ _midPoint:null,
+ _barChangeRate:null,
+ _reverseDirection:false,
+ _className:"ProgressTimer",
+
+ /**
+ * constructor of cc.cc.ProgressTimer
+ * @function
+ * @param {cc.Sprite} sprite
+ */
+ ctor: function(sprite){
+ cc.Node.prototype.ctor.call(this);
+
+ this._type = cc.ProgressTimer.TYPE_RADIAL;
+ this._percentage = 0.0;
+ this._midPoint = cc.p(0, 0);
+ this._barChangeRate = cc.p(0, 0);
+ this._reverseDirection = false;
+ this._sprite = null;
+
+ sprite && this.initWithSprite(sprite);
+ },
+
+ onEnter: function () {
+ this._super();
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ this._renderCmd.initCmd();
+ this._renderCmd._updateProgress();
+ }
+ },
+
+ cleanup: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ this._renderCmd.releaseData();
+ }
+ this._super();
+ },
+
+ /**
+ * Midpoint is used to modify the progress start position.
+ * If you're using radials type then the midpoint changes the center point
+ * If you're using bar type the the midpoint changes the bar growth
+ * it expands from the center but clamps to the sprites edge so:
+ * you want a left to right then set the midpoint all the way to cc.p(0,y)
+ * you want a right to left then set the midpoint all the way to cc.p(1,y)
+ * you want a bottom to top then set the midpoint all the way to cc.p(x,0)
+ * you want a top to bottom then set the midpoint all the way to cc.p(x,1)
+ * @return {cc.Point}
+ */
+ getMidpoint:function () {
+ return cc.p(this._midPoint.x, this._midPoint.y);
+ },
+
+ /**
+ * Midpoint setter
+ * @param {cc.Point} mpoint
+ */
+ setMidpoint:function (mpoint) {
+ this._midPoint = cc.pClamp(mpoint, cc.p(0, 0), cc.p(1, 1));
+ },
+
+ /**
+ * This allows the bar type to move the component at a specific rate
+ * Set the component to 0 to make sure it stays at 100%.
+ * For example you want a left to right bar but not have the height stay 100%
+ * Set the rate to be cc.p(0,1); and set the midpoint to = cc.p(0,.5f);
+ * @return {cc.Point}
+ */
+ getBarChangeRate:function () {
+ return cc.p(this._barChangeRate.x, this._barChangeRate.y);
+ },
+
+ /**
+ * @param {cc.Point} barChangeRate
+ */
+ setBarChangeRate:function (barChangeRate) {
+ this._barChangeRate = cc.pClamp(barChangeRate, cc.p(0, 0), cc.p(1, 1));
+ },
+
+ /**
+ * Change the percentage to change progress
+ * @return {cc.ProgressTimer.TYPE_RADIAL|cc.ProgressTimer.TYPE_BAR}
+ */
+ getType:function () {
+ return this._type;
+ },
+
+ /**
+ * Percentages are from 0 to 100
+ * @return {Number}
+ */
+ getPercentage:function () {
+ return this._percentage;
+ },
+
+ /**
+ * The image to show the progress percentage, retain
+ * @return {cc.Sprite}
+ */
+ getSprite:function () {
+ return this._sprite;
+ },
+
+ /**
+ * from 0-100
+ * @param {Number} percentage
+ */
+ setPercentage:function (percentage) {
+ if (this._percentage !== percentage) {
+ this._percentage = cc.clampf(percentage, 0, 100);
+ this._renderCmd._updateProgress();
+ }
+ },
+ /**
+ * only use for jsbinding
+ * @param bValue
+ */
+ setOpacityModifyRGB:function (bValue) {
+ },
+ /**
+ * only use for jsbinding
+ * @returns {boolean}
+ */
+ isOpacityModifyRGB:function () {
+ return false;
+ },
+ /**
+ * return if reverse direction
+ * @returns {boolean}
+ */
+ isReverseDirection:function () {
+ return this._reverseDirection;
+ },
+
+ /**
+ * set color of sprite
+ * @param {cc.Color} color
+ */
+ setColor:function (color) {
+ this._sprite.color = color;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty);
+ },
+
+ /**
+ * set opacity of sprite
+ * @param {Number} opacity
+ */
+ setOpacity:function (opacity) {
+ this._sprite.opacity = opacity;
+ //this._renderCmd._updateColor();
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty);
+ },
+
+ /**
+ * return color of sprite
+ * @return {cc.Color}
+ */
+ getColor:function () {
+ return this._sprite.color;
+ },
+
+ /**
+ * return Opacity of sprite
+ * @return {Number}
+ */
+ getOpacity:function () {
+ return this._sprite.opacity;
+ },
+
+ /**
+ * set reverse cc.ProgressTimer
+ * @function
+ * @param {Boolean} reverse
+ */
+ setReverseProgress: function(reverse){
+ if (this._reverseDirection !== reverse){
+ this._reverseDirection = reverse;
+ this._renderCmd.resetVertexData();
+ }
+ },
+
+ /**
+ * set sprite for cc.ProgressTimer
+ * @function
+ * @param {cc.Sprite} sprite
+ */
+ setSprite: function(sprite){
+ if (this._sprite !== sprite) {
+ this._sprite = sprite;
+ if(sprite) {
+ this.setContentSize(sprite.width, sprite.height);
+ sprite.ignoreAnchorPointForPosition(true);
+ }
+ else {
+ this.setContentSize(0,0);
+ }
+ this._renderCmd.resetVertexData();
+ }
+ },
+
+ /**
+ * set Progress type of cc.ProgressTimer
+ * @function
+ * @param {cc.ProgressTimer.TYPE_RADIAL|cc.ProgressTimer.TYPE_BAR} type
+ */
+ setType: function(type){
+ if (type !== this._type){
+ this._type = type;
+ this._renderCmd.resetVertexData();
+ }
+ },
+
+ /**
+ * Reverse Progress setter
+ * @function
+ * @param {Boolean} reverse
+ */
+ setReverseDirection: function(reverse){
+ if (this._reverseDirection !== reverse){
+ this._reverseDirection = reverse;
+ this._renderCmd.resetVertexData();
+ }
+ },
+
+ /**
+ * Initializes a progress timer with the sprite as the shape the timer goes through
+ * @function
+ * @param {cc.Sprite} sprite
+ * @return {Boolean}
+ */
+ initWithSprite: function(sprite){
+ this.percentage = 0;
+ this.setAnchorPoint(0.5,0.5);
+
+ this._type = cc.ProgressTimer.TYPE_RADIAL;
+ this._reverseDirection = false;
+ this.midPoint = cc.p(0.5, 0.5);
+ this.barChangeRate = cc.p(1, 1);
+ this.setSprite(sprite);
+ this._renderCmd.resetVertexData();
+ return true;
+ },
+
+ _createRenderCmd: function(){
+ if(cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.ProgressTimer.CanvasRenderCmd(this);
+ else
+ return new cc.ProgressTimer.WebGLRenderCmd(this);
+ }
+});
+
+// Extended properties
+var _p = cc.ProgressTimer.prototype;
+
+/** @expose */
+_p.midPoint;
+cc.defineGetterSetter(_p, "midPoint", _p.getMidpoint, _p.setMidpoint);
+/** @expose */
+_p.barChangeRate;
+cc.defineGetterSetter(_p, "barChangeRate", _p.getBarChangeRate, _p.setBarChangeRate);
+/** @expose */
+_p.type;
+cc.defineGetterSetter(_p, "type", _p.getType, _p.setType);
+/** @expose */
+_p.percentage;
+cc.defineGetterSetter(_p, "percentage", _p.getPercentage, _p.setPercentage);
+/** @expose */
+_p.sprite;
+cc.defineGetterSetter(_p, "sprite", _p.getSprite, _p.setSprite);
+/** @expose */
+_p.reverseDir;
+cc.defineGetterSetter(_p, "reverseDir", _p.isReverseDirection, _p.setReverseDirection);
+
+
+/**
+ * create a progress timer object with image file name that renders the inner sprite according to the percentage
+ * @deprecated since v3.0,please use new cc.ProgressTimer(sprite) instead.
+ * @param {cc.Sprite} sprite
+ * @return {cc.ProgressTimer}
+ */
+cc.ProgressTimer.create = function (sprite) {
+ return new cc.ProgressTimer(sprite);
+};
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.ProgressTimer.TEXTURE_COORDS_COUNT = 4;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.ProgressTimer.TEXTURE_COORDS = 0x4b;
+
+/**
+ * Radial Counter-Clockwise
+ * @type Number
+ * @constant
+ */
+cc.ProgressTimer.TYPE_RADIAL = 0;
+
+/**
+ * Bar
+ * @type Number
+ * @constant
+ */
+cc.ProgressTimer.TYPE_BAR = 1;
diff --git a/frameworks/cocos2d-html5/cocos2d/progress-timer/CCProgressTimerCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/progress-timer/CCProgressTimerCanvasRenderCmd.js
new file mode 100644
index 0000000..4dc2a71
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/progress-timer/CCProgressTimerCanvasRenderCmd.js
@@ -0,0 +1,286 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.ProgressTimer's rendering objects of Canvas
+ */
+(function () {
+ cc.ProgressTimer.CanvasRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+
+ this._PI180 = Math.PI / 180;
+ this._barRect = cc.rect(0, 0, 0, 0);
+ this._origin = cc.p(0, 0);
+ this._radius = 0;
+ this._startAngle = 270;
+ this._endAngle = 270;
+ this._counterClockWise = false;
+ this._canUseDirtyRegion = true;
+ };
+
+ var proto = cc.ProgressTimer.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ proto.constructor = cc.ProgressTimer.CanvasRenderCmd;
+
+ proto.rendering = function (ctx, scaleX, scaleY) {
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext(), node = this._node, locSprite = node._sprite;
+ var locTextureCoord = locSprite._renderCmd._textureCoord, alpha = locSprite._renderCmd._displayedOpacity / 255;
+
+ if (locTextureCoord.width === 0 || locTextureCoord.height === 0)
+ return;
+ if (!locSprite._texture || !locTextureCoord.validRect || alpha === 0)
+ return;
+
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+ wrapper.setCompositeOperation(locSprite._blendFuncStr);
+ wrapper.setGlobalAlpha(alpha);
+
+ var locRect = locSprite._rect, locOffsetPosition = locSprite._offsetPosition;
+ var locX = locOffsetPosition.x,
+ locY = -locOffsetPosition.y - locRect.height,
+ locWidth = locRect.width,
+ locHeight = locRect.height;
+
+ wrapper.save();
+ if (locSprite._flippedX) {
+ locX = -locX - locWidth;
+ context.scale(-1, 1);
+ }
+ if (locSprite._flippedY) {
+ locY = locOffsetPosition.y;
+ context.scale(1, -1);
+ }
+
+ //clip
+ if (node._type === cc.ProgressTimer.TYPE_BAR) {
+ var locBarRect = this._barRect;
+ context.beginPath();
+ context.rect(locBarRect.x, locBarRect.y, locBarRect.width, locBarRect.height);
+ context.clip();
+ context.closePath();
+ } else if (node._type === cc.ProgressTimer.TYPE_RADIAL) {
+ var locOriginX = this._origin.x;
+ var locOriginY = this._origin.y;
+ context.beginPath();
+ context.arc(locOriginX, locOriginY, this._radius, this._PI180 * this._startAngle, this._PI180 * this._endAngle, this._counterClockWise);
+ context.lineTo(locOriginX, locOriginY);
+ context.clip();
+ context.closePath();
+ }
+
+ //draw sprite
+ var texture = locSprite._renderCmd._textureToRender || locSprite._texture;
+ var image = texture.getHtmlElementObj();
+ if (locSprite._renderCmd._colorized) {
+ context.drawImage(image,
+ 0, 0, locTextureCoord.width, locTextureCoord.height,
+ locX, locY, locWidth, locHeight);
+ } else {
+ context.drawImage(image,
+ locTextureCoord.renderX, locTextureCoord.renderY, locTextureCoord.width, locTextureCoord.height,
+ locX, locY, locWidth, locHeight);
+ }
+ wrapper.restore();
+ cc.g_NumberOfDraws++;
+ };
+
+ proto.releaseData = function () {
+ };
+
+ proto.resetVertexData = function () {
+ };
+
+ proto._updateProgress = function () {
+ this.setDirtyFlag(cc.Node._dirtyFlags.contentDirty);
+ var node = this._node;
+ var locSprite = node._sprite;
+ var sw = locSprite.width, sh = locSprite.height;
+ var locMidPoint = node._midPoint;
+
+ if (node._type === cc.ProgressTimer.TYPE_RADIAL) {
+ this._radius = Math.round(Math.sqrt(sw * sw + sh * sh));
+ var locStartAngle, locEndAngle, locCounterClockWise = false, locOrigin = this._origin;
+ locOrigin.x = sw * locMidPoint.x;
+ locOrigin.y = -sh * locMidPoint.y;
+
+ if (node._reverseDirection) {
+ locEndAngle = 270;
+ locStartAngle = 270 - 3.6 * node._percentage;
+ } else {
+ locStartAngle = -90;
+ locEndAngle = -90 + 3.6 * node._percentage;
+ }
+
+ if (locSprite._flippedX) {
+ locOrigin.x -= sw * (node._midPoint.x * 2);
+ locStartAngle = -locStartAngle;
+ locEndAngle = -locEndAngle;
+ locStartAngle -= 180;
+ locEndAngle -= 180;
+ locCounterClockWise = !locCounterClockWise;
+ }
+ if (locSprite._flippedY) {
+ locOrigin.y += sh * (node._midPoint.y * 2);
+ locCounterClockWise = !locCounterClockWise;
+ locStartAngle = -locStartAngle;
+ locEndAngle = -locEndAngle;
+ }
+
+ this._startAngle = locStartAngle;
+ this._endAngle = locEndAngle;
+ this._counterClockWise = locCounterClockWise;
+ } else {
+ var locBarChangeRate = node._barChangeRate;
+ var percentageF = node._percentage / 100;
+ var locBarRect = this._barRect;
+
+ var drewSize = cc.size((sw * (1 - locBarChangeRate.x)), (sh * (1 - locBarChangeRate.y)));
+ var drawingSize = cc.size((sw - drewSize.width) * percentageF, (sh - drewSize.height) * percentageF);
+ var currentDrawSize = cc.size(drewSize.width + drawingSize.width, drewSize.height + drawingSize.height);
+
+ var startPoint = cc.p(sw * locMidPoint.x, sh * locMidPoint.y);
+
+ var needToLeft = startPoint.x - currentDrawSize.width / 2;
+ if ((locMidPoint.x > 0.5) && (currentDrawSize.width / 2 >= sw - startPoint.x))
+ needToLeft = sw - currentDrawSize.width;
+
+ var needToTop = startPoint.y - currentDrawSize.height / 2;
+ if ((locMidPoint.y > 0.5) && (currentDrawSize.height / 2 >= sh - startPoint.y))
+ needToTop = sh - currentDrawSize.height;
+
+ //left pos
+ locBarRect.x = 0;
+ var flipXNeed = 1;
+ if (locSprite._flippedX) {
+ locBarRect.x -= currentDrawSize.width;
+ flipXNeed = -1;
+ }
+
+ if (needToLeft > 0)
+ locBarRect.x += needToLeft * flipXNeed;
+
+ //right pos
+ locBarRect.y = 0;
+ var flipYNeed = 1;
+ if (locSprite._flippedY) {
+ locBarRect.y += currentDrawSize.height;
+ flipYNeed = -1;
+ }
+
+ if (needToTop > 0)
+ locBarRect.y -= needToTop * flipYNeed;
+
+ //clip width and clip height
+ locBarRect.width = currentDrawSize.width;
+ locBarRect.height = -currentDrawSize.height;
+ }
+ };
+
+ proto._syncStatus = function (parentCmd) {
+ var node = this._node;
+ if (!node._sprite)
+ return;
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ var parentNode = parentCmd ? parentCmd._node : null;
+
+ if (parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & flags.colorDirty))
+ locFlag |= flags.colorDirty;
+
+ if (parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & flags.opacityDirty))
+ locFlag |= flags.opacityDirty;
+
+ if (parentCmd && (parentCmd._dirtyFlag & flags.transformDirty))
+ locFlag |= flags.transformDirty;
+
+ this._dirtyFlag = locFlag;
+
+ var spriteCmd = node._sprite._renderCmd;
+ var spriteFlag = spriteCmd._dirtyFlag;
+
+ var colorDirty = spriteFlag & flags.colorDirty,
+ opacityDirty = spriteFlag & flags.opacityDirty;
+
+ if (colorDirty) {
+ spriteCmd._syncDisplayColor();
+ spriteCmd._dirtyFlag &= ~flags.colorDirty;
+ this._dirtyFlag &= ~flags.colorDirty;
+ }
+
+ if (opacityDirty) {
+ spriteCmd._syncDisplayOpacity();
+ spriteCmd._dirtyFlag &= ~flags.opacityDirty;
+ this._dirtyFlag &= ~flags.opacityDirty;
+ }
+
+ if (colorDirty || opacityDirty) {
+ spriteCmd._updateColor();
+ }
+
+ if (locFlag & flags.transformDirty) {
+ //update the transform
+ this.transform(parentCmd);
+ }
+
+ if (locFlag & flags.orderDirty) {
+ this._dirtyFlag &= ~flags.orderDirty;
+ }
+ };
+
+ proto.updateStatus = function () {
+ var node = this._node;
+ if (!node._sprite)
+ return;
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ var spriteCmd = node._sprite._renderCmd;
+ var spriteFlag = spriteCmd._dirtyFlag;
+
+ var colorDirty = spriteFlag & flags.colorDirty,
+ opacityDirty = spriteFlag & flags.opacityDirty;
+
+ if (colorDirty) {
+ spriteCmd._updateDisplayColor();
+ spriteCmd._dirtyFlag = spriteCmd._dirtyFlag & flags.colorDirty ^ spriteCmd._dirtyFlag;
+ this._dirtyFlag = this._dirtyFlag & flags.colorDirty ^ this._dirtyFlag;
+ }
+
+ if (opacityDirty) {
+ spriteCmd._updateDisplayOpacity();
+ spriteCmd._dirtyFlag = spriteCmd._dirtyFlag & flags.opacityDirty ^ spriteCmd._dirtyFlag;
+ this._dirtyFlag = this._dirtyFlag & flags.opacityDirty ^ this._dirtyFlag;
+ }
+
+ if (colorDirty || opacityDirty) {
+ spriteCmd._updateColor();
+ }
+
+ if (locFlag & flags.transformDirty) {
+ //update the transform
+ this.transform(this.getParentRenderCmd(), true);
+ }
+ if(locFlag & flags.contentDirty) {
+ this._notifyRegionStatus && this._notifyRegionStatus(cc.Node.CanvasRenderCmd.RegionStatus.Dirty);
+ }
+ this._dirtyFlag = 0;
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js
new file mode 100644
index 0000000..8a89913
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js
@@ -0,0 +1,542 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.ProgressTimer's rendering objects of WebGL
+ */
+(function () {
+ var MAX_VERTEX_COUNT = 8;
+
+ cc.ProgressTimer.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+ this._progressDirty = true;
+
+ this._bl = cc.p();
+ this._tr = cc.p();
+ this._transformUpdating = false;
+
+ this.initCmd();
+ };
+
+ var proto = cc.ProgressTimer.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ proto.constructor = cc.ProgressTimer.WebGLRenderCmd;
+
+ proto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
+ var sp = this._node._sprite;
+ sp._renderCmd.transform(this, recursive);
+
+ var lx = sp._offsetPosition.x, rx = lx + sp._rect.width,
+ by = sp._offsetPosition.y, ty = by + sp._rect.height,
+ wt = this._worldTransform;
+ this._bl.x = lx * wt.a + by * wt.c + wt.tx;
+ this._bl.y = lx * wt.b + by * wt.d + wt.ty;
+ this._tr.x = rx * wt.a + ty * wt.c + wt.tx;
+ this._tr.y = rx * wt.b + ty * wt.d + wt.ty;
+
+ this._transformUpdating = true;
+ this._updateProgressData();
+ this._transformUpdating = false;
+ };
+
+ proto.rendering = function (ctx) {
+ var node = this._node;
+ var context = ctx || cc._renderContext;
+ if (this._vertexDataCount === 0 || !node._sprite)
+ return;
+
+ this._glProgramState.apply();
+ this._shaderProgram._updateProjectionUniform();
+
+ var blendFunc = node._sprite._blendFunc;
+ cc.glBlendFunc(blendFunc.src, blendFunc.dst);
+ cc.glBindTexture2D(node._sprite.texture);
+ context.bindBuffer(context.ARRAY_BUFFER, this._vertexWebGLBuffer);
+
+ context.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ context.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
+ context.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS);
+
+ if (this._vertexDataDirty) {
+ context.bufferSubData(context.ARRAY_BUFFER, 0, this._float32View);
+ this._vertexDataDirty = false;
+ }
+ var locVertexDataLen = cc.V3F_C4B_T2F.BYTES_PER_ELEMENT;
+ context.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, context.FLOAT, false, locVertexDataLen, 0);
+ context.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, context.UNSIGNED_BYTE, true, locVertexDataLen, 12);
+ context.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, context.FLOAT, false, locVertexDataLen, 16);
+
+ if (node._type === cc.ProgressTimer.TYPE_RADIAL)
+ context.drawArrays(context.TRIANGLE_FAN, 0, this._vertexDataCount);
+ else if (node._type === cc.ProgressTimer.TYPE_BAR) {
+ if (!node._reverseDirection)
+ context.drawArrays(context.TRIANGLE_STRIP, 0, this._vertexDataCount);
+ else {
+ context.drawArrays(context.TRIANGLE_STRIP, 0, this._vertexDataCount / 2);
+ context.drawArrays(context.TRIANGLE_STRIP, 4, this._vertexDataCount / 2);
+ // 2 draw calls
+ cc.g_NumberOfDraws++;
+ }
+ }
+ cc.g_NumberOfDraws++;
+ };
+
+ proto._syncStatus = function (parentCmd) {
+ var node = this._node;
+ if (!node._sprite)
+ return;
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ var parentNode = parentCmd ? parentCmd._node : null;
+
+ if (parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & flags.colorDirty))
+ locFlag |= flags.colorDirty;
+ if (parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & flags.opacityDirty))
+ locFlag |= flags.opacityDirty;
+ if (parentCmd && (parentCmd._dirtyFlag & flags.transformDirty))
+ locFlag |= flags.transformDirty;
+ this._dirtyFlag = locFlag;
+
+ var spriteCmd = node._sprite._renderCmd;
+ var spriteFlag = spriteCmd._dirtyFlag;
+
+ var colorDirty = (locFlag | spriteFlag) & flags.colorDirty,
+ opacityDirty = (locFlag | spriteFlag) & flags.opacityDirty;
+
+ if (colorDirty) {
+ spriteCmd._syncDisplayColor();
+ spriteCmd._dirtyFlag &= ~flags.colorDirty;
+ this._dirtyFlag &= ~flags.colorDirty;
+ }
+
+ if (opacityDirty) {
+ spriteCmd._syncDisplayOpacity();
+ spriteCmd._dirtyFlag &= ~flags.opacityDirty;
+ this._dirtyFlag &= ~flags.opacityDirty;
+ }
+
+ if (colorDirty || opacityDirty) {
+ this._updateColor();
+ }
+
+ if (locFlag & flags.transformDirty) {
+ //update the transform
+ this.transform(parentCmd);
+ }
+
+ if (locFlag & flags.textureDirty) {
+ this._updateProgressData();
+ this._dirtyFlag &= ~flags.textureDirty;
+ }
+
+ spriteCmd._dirtyFlag = 0;
+ };
+
+ proto.updateStatus = function () {
+ var node = this._node;
+ if (!node._sprite)
+ return;
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ var spriteCmd = node._sprite._renderCmd;
+ var spriteFlag = spriteCmd._dirtyFlag;
+
+ var colorDirty = (locFlag | spriteFlag) & flags.colorDirty,
+ opacityDirty = (locFlag | spriteFlag) & flags.opacityDirty;
+
+ if (colorDirty) {
+ spriteCmd._updateDisplayColor();
+ spriteCmd._dirtyFlag = spriteCmd._dirtyFlag & flags.colorDirty ^ spriteCmd._dirtyFlag;
+ this._dirtyFlag = this._dirtyFlag & flags.colorDirty ^ this._dirtyFlag;
+ }
+
+ if (opacityDirty) {
+ spriteCmd._updateDisplayOpacity();
+ spriteCmd._dirtyFlag = spriteCmd._dirtyFlag & flags.opacityDirty ^ spriteCmd._dirtyFlag;
+ this._dirtyFlag = this._dirtyFlag & flags.opacityDirty ^ this._dirtyFlag;
+ }
+
+ if (colorDirty || opacityDirty) {
+ this._updateColor();
+ }
+
+ if (locFlag & flags.transformDirty) {
+ //update the transform
+ this.transform(this.getParentRenderCmd(), true);
+ }
+
+ if (locFlag & flags.orderDirty) {
+ this._dirtyFlag = this._dirtyFlag & flags.orderDirty ^ this._dirtyFlag;
+ }
+
+ if (locFlag & flags.textureDirty) {
+ this._updateProgressData();
+ this._dirtyFlag = this._dirtyFlag & flags.textureDirty ^ this._dirtyFlag;
+ }
+ };
+
+ proto.releaseData = function () {
+ if (this._vertexData) {
+ //release all previous information
+ var webglBuffer = this._vertexWebGLBuffer;
+ setTimeout(function () {
+ cc._renderContext.deleteBuffer(webglBuffer);
+ }, 0.1);
+ this._vertexWebGLBuffer = null;
+ this._vertexData = null;
+ this._float32View = null;
+ this._vertexArrayBuffer = null;
+ this._vertexDataCount = 0;
+ }
+ };
+
+ proto.initCmd = function () {
+ if (!this._vertexData) {
+ this._vertexWebGLBuffer = cc._renderContext.createBuffer();
+
+ var vertexDataLen = cc.V3F_C4B_T2F.BYTES_PER_ELEMENT;
+ this._vertexArrayBuffer = new ArrayBuffer(MAX_VERTEX_COUNT * vertexDataLen);
+ this._float32View = new Float32Array(this._vertexArrayBuffer);
+ this._vertexData = [];
+ for (var i = 0; i < MAX_VERTEX_COUNT; i++) {
+ this._vertexData[i] = new cc.V3F_C4B_T2F(null, null, null, this._vertexArrayBuffer, i * vertexDataLen);
+ }
+
+ // Init buffer data
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexWebGLBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this._float32View, gl.DYNAMIC_DRAW);
+
+ this._vertexDataCount = 0;
+ this._vertexDataDirty = true;
+
+ //shader program
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR);
+ }
+ };
+
+ proto.resetVertexData = function () {
+ this._vertexDataCount = 0;
+ };
+
+ proto._updateProgressData = function () {
+ var node = this._node;
+ var locType = node._type;
+ if (locType === cc.ProgressTimer.TYPE_RADIAL)
+ this._updateRadial();
+ else if (locType === cc.ProgressTimer.TYPE_BAR)
+ this._updateBar();
+ this._vertexDataDirty = true;
+ };
+
+ proto._updateProgress = function () {
+ this.setDirtyFlag(cc.Node._dirtyFlags.textureDirty);
+ };
+
+ /**
+ *
+ * Update does the work of mapping the texture onto the triangles for the bar
+ * It now doesn't occur the cost of free/alloc data every update cycle.
+ * It also only changes the percentage point but no other points if they have not been modified.
+ *
+ * It now deals with flipped texture. If you run into this problem, just use the
+ * sprite property and enable the methods flipX, flipY.
+ *
+ * @private
+ */
+ proto._updateBar = function () {
+ var node = this._node;
+ if (!node._sprite)
+ return;
+
+ var i, alpha = node._percentage / 100.0;
+ var locBarChangeRate = node._barChangeRate;
+ var alphaOffset = cc.pMult(cc.p((1.0 - locBarChangeRate.x) + alpha * locBarChangeRate.x,
+ (1.0 - locBarChangeRate.y) + alpha * locBarChangeRate.y), 0.5);
+ var min = cc.pSub(node._midPoint, alphaOffset), max = cc.pAdd(node._midPoint, alphaOffset);
+
+ if (min.x < 0) {
+ max.x += -min.x;
+ min.x = 0;
+ }
+
+ if (max.x > 1) {
+ min.x -= max.x - 1;
+ max.x = 1;
+ }
+
+ if (min.y < 0) {
+ max.y += -min.y;
+ min.y = 0;
+ }
+
+ if (max.y > 1) {
+ min.y -= max.y - 1;
+ max.y = 1;
+ }
+
+ var locVertexData;
+ if (!this._reverseDirection) {
+ if (!this._vertexDataCount) {
+ this._vertexDataCount = 4;
+ }
+ locVertexData = this._vertexData;
+ // TOPLEFT
+ this._textureCoordFromAlphaPoint(locVertexData[0].texCoords, min.x, max.y);
+ this._vertexFromAlphaPoint(locVertexData[0].vertices, min.x, max.y);
+
+ // BOTLEFT
+ this._textureCoordFromAlphaPoint(locVertexData[1].texCoords, min.x, min.y);
+ this._vertexFromAlphaPoint(locVertexData[1].vertices, min.x, min.y);
+
+ // TOPRIGHT
+ this._textureCoordFromAlphaPoint(locVertexData[2].texCoords, max.x, max.y);
+ this._vertexFromAlphaPoint(locVertexData[2].vertices, max.x, max.y);
+
+ // BOTRIGHT
+ this._textureCoordFromAlphaPoint(locVertexData[3].texCoords, max.x, min.y);
+ this._vertexFromAlphaPoint(locVertexData[3].vertices, max.x, min.y);
+ } else {
+ locVertexData = this._vertexData;
+ if (!this._vertexDataCount) {
+ this._vertexDataCount = 8;
+ // TOPLEFT 1
+ this._textureCoordFromAlphaPoint(locVertexData[0].texCoords, 0, 1);
+ this._vertexFromAlphaPoint(locVertexData[0].vertices, 0, 1);
+
+ // BOTLEFT 1
+ this._textureCoordFromAlphaPoint(locVertexData[1].texCoords, 0, 0);
+ this._vertexFromAlphaPoint(locVertexData[1].vertices, 0, 0);
+
+ // TOPRIGHT 2
+ this._textureCoordFromAlphaPoint(locVertexData[6].texCoords, 1, 1);
+ this._vertexFromAlphaPoint(locVertexData[6].vertices, 1, 1);
+
+ // BOTRIGHT 2
+ this._textureCoordFromAlphaPoint(locVertexData[7].texCoords, 1, 0);
+ this._vertexFromAlphaPoint(locVertexData[7].vertices, 1, 0);
+ }
+
+ // TOPRIGHT 1
+ this._textureCoordFromAlphaPoint(locVertexData[2].texCoords, min.x, max.y);
+ this._vertexFromAlphaPoint(locVertexData[2].vertices, min.x, max.y);
+
+ // BOTRIGHT 1
+ this._textureCoordFromAlphaPoint(locVertexData[3].texCoords, min.x, min.y);
+ this._vertexFromAlphaPoint(locVertexData[3].vertices, min.x, min.y);
+
+ // TOPLEFT 2
+ this._textureCoordFromAlphaPoint(locVertexData[4].texCoords, max.x, max.y);
+ this._vertexFromAlphaPoint(locVertexData[4].vertices, max.x, max.y);
+
+ // BOTLEFT 2
+ this._textureCoordFromAlphaPoint(locVertexData[5].texCoords, max.x, min.y);
+ this._vertexFromAlphaPoint(locVertexData[5].vertices, max.x, min.y);
+ }
+ this._updateColor();
+ };
+
+ /**
+ *
+ * Update does the work of mapping the texture onto the triangles
+ * It now doesn't occur the cost of free/alloc data every update cycle.
+ * It also only changes the percentage point but no other points if they have not been modified.
+ *
+ * It now deals with flipped texture. If you run into this problem, just use the
+ * sprite property and enable the methods flipX, flipY.
+ *
+ * @private
+ */
+ proto._updateRadial = function () {
+ var node = this._node;
+ if (!node._sprite)
+ return;
+
+ var i, locMidPoint = node._midPoint;
+ var alpha = node._percentage / 100;
+ var angle = 2 * (cc.PI) * ( node._reverseDirection ? alpha : 1.0 - alpha);
+
+ // We find the vector to do a hit detection based on the percentage
+ // We know the first vector is the one @ 12 o'clock (top,mid) so we rotate
+ // from that by the progress angle around the m_tMidpoint pivot
+ var topMid = cc.p(locMidPoint.x, 1);
+ var percentagePt = cc.pRotateByAngle(topMid, locMidPoint, angle);
+
+ var index = 0;
+ var hit;
+
+ if (alpha === 0) {
+ // More efficient since we don't always need to check intersection
+ // If the alpha is zero then the hit point is top mid and the index is 0.
+ hit = topMid;
+ index = 0;
+ } else if (alpha === 1) {
+ // More efficient since we don't always need to check intersection
+ // If the alpha is one then the hit point is top mid and the index is 4.
+ hit = topMid;
+ index = 4;
+ } else {
+ // We run a for loop checking the edges of the texture to find the
+ // intersection point
+ // We loop through five points since the top is split in half
+
+ var min_t = cc.FLT_MAX;
+ var locProTextCoordsCount = cc.ProgressTimer.TEXTURE_COORDS_COUNT;
+ for (i = 0; i <= locProTextCoordsCount; ++i) {
+ var pIndex = (i + (locProTextCoordsCount - 1)) % locProTextCoordsCount;
+
+ var edgePtA = this._boundaryTexCoord(i % locProTextCoordsCount);
+ var edgePtB = this._boundaryTexCoord(pIndex);
+
+ // Remember that the top edge is split in half for the 12 o'clock position
+ // Let's deal with that here by finding the correct endpoints
+ if (i === 0)
+ edgePtB = cc.pLerp(edgePtA, edgePtB, 1 - locMidPoint.x);
+ else if (i === 4)
+ edgePtA = cc.pLerp(edgePtA, edgePtB, 1 - locMidPoint.x);
+
+ // retPoint are returned by ccpLineIntersect
+ var retPoint = cc.p(0, 0);
+ if (cc.pLineIntersect(edgePtA, edgePtB, locMidPoint, percentagePt, retPoint)) {
+ // Since our hit test is on rays we have to deal with the top edge
+ // being in split in half so we have to test as a segment
+ if ((i === 0 || i === 4)) {
+ // s represents the point between edgePtA--edgePtB
+ if (!(0 <= retPoint.x && retPoint.x <= 1))
+ continue;
+ }
+ // As long as our t isn't negative we are at least finding a
+ // correct hitpoint from m_tMidpoint to percentagePt.
+ if (retPoint.y >= 0) {
+ // Because the percentage line and all the texture edges are
+ // rays we should only account for the shortest intersection
+ if (retPoint.y < min_t) {
+ min_t = retPoint.y;
+ index = i;
+ }
+ }
+ }
+ }
+
+ // Now that we have the minimum magnitude we can use that to find our intersection
+ hit = cc.pAdd(locMidPoint, cc.pMult(cc.pSub(percentagePt, locMidPoint), min_t));
+ }
+
+ // The size of the vertex data is the index from the hitpoint
+ // the 3 is for the m_tMidpoint, 12 o'clock point and hitpoint position.
+ var sameIndexCount = true;
+ if (this._vertexDataCount !== index + 3) {
+ sameIndexCount = false;
+ this._vertexDataCount = index + 3;
+ }
+
+ this._updateColor();
+
+ var locVertexData = this._vertexData;
+ if (this._transformUpdating || !sameIndexCount) {
+ // First we populate the array with the m_tMidpoint, then all
+ // vertices/texcoords/colors of the 12 'o clock start and edges and the hitpoint
+ this._textureCoordFromAlphaPoint(locVertexData[0].texCoords, locMidPoint.x, locMidPoint.y);
+ this._vertexFromAlphaPoint(locVertexData[0].vertices, locMidPoint.x, locMidPoint.y);
+
+ this._textureCoordFromAlphaPoint(locVertexData[1].texCoords, topMid.x, topMid.y);
+ this._vertexFromAlphaPoint(locVertexData[1].vertices, topMid.x, topMid.y);
+
+ for (i = 0; i < index; i++) {
+ var alphaPoint = this._boundaryTexCoord(i);
+ this._textureCoordFromAlphaPoint(locVertexData[i + 2].texCoords, alphaPoint.x, alphaPoint.y);
+ this._vertexFromAlphaPoint(locVertexData[i + 2].vertices, alphaPoint.x, alphaPoint.y);
+ }
+ }
+
+ // hitpoint will go last
+ this._textureCoordFromAlphaPoint(locVertexData[this._vertexDataCount - 1].texCoords, hit.x, hit.y);
+ this._vertexFromAlphaPoint(locVertexData[this._vertexDataCount - 1].vertices, hit.x, hit.y);
+ };
+
+ proto._boundaryTexCoord = function (index) {
+ if (index < cc.ProgressTimer.TEXTURE_COORDS_COUNT) {
+ var locProTextCoords = cc.ProgressTimer.TEXTURE_COORDS;
+ if (this._node._reverseDirection)
+ return cc.p((locProTextCoords >> (7 - (index << 1))) & 1, (locProTextCoords >> (7 - ((index << 1) + 1))) & 1);
+ else
+ return cc.p((locProTextCoords >> ((index << 1) + 1)) & 1, (locProTextCoords >> (index << 1)) & 1);
+ }
+ return cc.p(0, 0);
+ };
+
+ proto._textureCoordFromAlphaPoint = function (coords, ax, ay) {
+ var locSprite = this._node._sprite;
+ if (!locSprite) {
+ coords.u = 0;
+ coords.v = 0;
+ return;
+ }
+ var uvs = locSprite._renderCmd._vertices,
+ bl = uvs[1],
+ tr = uvs[2];
+ var min = cc.p(bl.u, bl.v);
+ var max = cc.p(tr.u, tr.v);
+
+ // Fix bug #1303 so that progress timer handles sprite frame texture rotation
+ if (locSprite.textureRectRotated) {
+ var temp = ax;
+ ax = ay;
+ ay = temp;
+ }
+ coords.u = min.x * (1 - ax) + max.x * ax;
+ coords.v = min.y * (1 - ay) + max.y * ay;
+ };
+
+ proto._vertexFromAlphaPoint = function (vertex, ax, ay) {
+ vertex.x = this._bl.x * (1 - ax) + this._tr.x * ax;
+ vertex.y = this._bl.y * (1 - ay) + this._tr.y * ay;
+ vertex.z = this._node._vertexZ;
+ };
+
+ proto._updateColor = function () {
+ var sp = this._node._sprite;
+ if (!this._vertexDataCount || !sp)
+ return;
+
+ var color = this._displayedColor;
+ var spColor = sp._renderCmd._displayedColor;
+ var r = spColor.r;
+ var g = spColor.g;
+ var b = spColor.b;
+ var a = sp._renderCmd._displayedOpacity / 255;
+ if (sp._opacityModifyRGB) {
+ r *= a;
+ g *= a;
+ b *= a;
+ }
+ color.r = r;
+ color.g = g;
+ color.b = b;
+ color.a = sp._renderCmd._displayedOpacity;
+ var locVertexData = this._vertexData;
+ for (var i = 0, len = this._vertexDataCount; i < len; ++i) {
+ locVertexData[i].colors = color;
+ }
+ this._vertexDataDirty = true;
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/render-texture/CCRenderTexture.js b/frameworks/cocos2d-html5/cocos2d/render-texture/CCRenderTexture.js
new file mode 100644
index 0000000..5cc00ae
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/render-texture/CCRenderTexture.js
@@ -0,0 +1,425 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2009 Jason Booth
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * enum for jpg
+ * @constant
+ * @type Number
+ */
+cc.IMAGE_FORMAT_JPEG = 0;
+/**
+ * enum for png
+ * @constant
+ * @type Number
+ */
+cc.IMAGE_FORMAT_PNG = 1;
+/**
+ * enum for raw
+ * @constant
+ * @type Number
+ */
+cc.IMAGE_FORMAT_RAWDATA = 9;
+
+/**
+ * @param {Number} x
+ * @return {Number}
+ * Constructor
+ */
+cc.NextPOT = function (x) {
+ x = x - 1;
+ x = x | (x >> 1);
+ x = x | (x >> 2);
+ x = x | (x >> 4);
+ x = x | (x >> 8);
+ x = x | (x >> 16);
+ return x + 1;
+};
+
+/**
+ * cc.RenderTexture is a generic rendering target. To render things into it,
+ * simply construct a render target, call begin on it, call visit on any cocos
+ * scenes or objects to render them, and call end. For convenience, render texture
+ * adds a sprite as it's display child with the results, so you can simply add
+ * the render texture to your scene and treat it like any other CocosNode.
+ * There are also functions for saving the render texture to disk in PNG or JPG format.
+ * @class
+ * @extends cc.Node
+ *
+ * @property {cc.Sprite} sprite - The sprite.
+ * @property {cc.Sprite} clearFlags - Code for "auto" update.
+ * @property {Number} clearDepthVal - Clear depth value.
+ * @property {Boolean} autoDraw - Indicate auto draw mode activate or not.
+ * @property {Number} clearStencilVal - Clear stencil value.
+ * @property {cc.Color} clearColorVal - Clear color value, valid only when "autoDraw" is true.
+ */
+cc.RenderTexture = cc.Node.extend(/** @lends cc.RenderTexture# */{
+ sprite: null,
+
+ //
+ // Code for "auto" update
+ // Valid flags: GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT.
+ // They can be OR'ed. Valid when "autoDraw is YES.
+ // @public
+ //
+ clearFlags: 0,
+
+ clearDepthVal: 0,
+ autoDraw: false,
+
+ _texture: null,
+ _pixelFormat: 0,
+
+ clearStencilVal: 0,
+ _clearColor: null,
+
+ _className: "RenderTexture",
+
+ /**
+ * creates a RenderTexture object with width and height in Points and a pixel format, only RGB and RGBA formats are valid
+ * Constructor of cc.RenderTexture for Canvas
+ * @param {Number} width
+ * @param {Number} height
+ * @param {cc.IMAGE_FORMAT_JPEG|cc.IMAGE_FORMAT_PNG|cc.IMAGE_FORMAT_RAWDATA} format
+ * @param {Number} depthStencilFormat
+ * @example
+ * // Example
+ * var rt = new cc.RenderTexture(width, height, format, depthStencilFormat)
+ * @function
+ */
+ ctor: function (width, height, format, depthStencilFormat) {
+ cc.Node.prototype.ctor.call(this);
+ this._cascadeColorEnabled = true;
+ this._cascadeOpacityEnabled = true;
+ this._pixelFormat = cc.Texture2D.PIXEL_FORMAT_RGBA8888;
+ this._clearColor = new cc.Color(0, 0, 0, 255);
+
+ if (width !== undefined && height !== undefined) {
+ format = format || cc.Texture2D.PIXEL_FORMAT_RGBA8888;
+ depthStencilFormat = depthStencilFormat || 0;
+ this.initWithWidthAndHeight(width, height, format, depthStencilFormat);
+ }
+ this.setAnchorPoint(0, 0);
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.RenderTexture.CanvasRenderCmd(this);
+ else
+ return new cc.RenderTexture.WebGLRenderCmd(this);
+ },
+
+ visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
+
+ var renderer = cc.renderer;
+
+ cmd.visit(parentCmd);
+ renderer.pushRenderCommand(cmd);
+ this.sprite.visit(this);
+ cmd._dirtyFlag = 0;
+ },
+
+ /**
+ * Clear RenderTexture.
+ * @function
+ */
+ cleanup: function () {
+ cc.Node.prototype.onExit.call(this);
+ this._renderCmd.cleanup();
+ },
+
+ /**
+ * Gets the sprite
+ * @return {cc.Sprite}
+ */
+ getSprite: function () {
+ return this.sprite;
+ },
+
+ /**
+ * Set the sprite
+ * @param {cc.Sprite} sprite
+ */
+ setSprite: function (sprite) {
+ this.sprite = sprite;
+ },
+
+ /**
+ * Used for grab part of screen to a texture.
+ * @param {cc.Point} rtBegin
+ * @param {cc.Rect} fullRect
+ * @param {cc.Rect} fullViewport
+ */
+ setVirtualViewport: function (rtBegin, fullRect, fullViewport) {
+ this._renderCmd.setVirtualViewport(rtBegin, fullRect, fullViewport);
+ },
+
+ /**
+ * Initializes the instance of cc.RenderTexture
+ * @function
+ * @param {Number} width
+ * @param {Number} height
+ * @param {cc.IMAGE_FORMAT_JPEG|cc.IMAGE_FORMAT_PNG|cc.IMAGE_FORMAT_RAWDATA} [format]
+ * @param {Number} [depthStencilFormat]
+ * @return {Boolean}
+ */
+ initWithWidthAndHeight: function (width, height, format, depthStencilFormat) {
+ return this._renderCmd.initWithWidthAndHeight(width, height, format, depthStencilFormat);
+ },
+
+ /**
+ * starts grabbing
+ * @function
+ */
+ begin: function () {
+ cc.renderer._turnToCacheMode(this.__instanceId);
+ this._renderCmd.begin();
+ },
+ /**
+ * starts rendering to the texture while clearing the texture first.
+ * This is more efficient then calling -clear first and then -begin
+ * @param {Number} r red 0-255
+ * @param {Number} g green 0-255
+ * @param {Number} b blue 0-255
+ * @param {Number} a alpha 0-255 0 is transparent
+ * @param {Number} [depthValue=]
+ * @param {Number} [stencilValue=]
+ */
+ beginWithClear: function (r, g, b, a, depthValue, stencilValue) {
+ //todo: only for WebGL?
+ var gl = cc._renderContext;
+ depthValue = depthValue || gl.COLOR_BUFFER_BIT;
+ stencilValue = stencilValue || (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ this._beginWithClear(r, g, b, a, depthValue, stencilValue, (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ },
+
+ _beginWithClear: function (r, g, b, a, depthValue, stencilValue, flags) {
+ this.begin();
+ this._renderCmd._beginWithClear(r, g, b, a, depthValue, stencilValue, flags);
+ },
+
+ /**
+ * ends grabbing
+ * @function
+ */
+ end: function () {
+ this._renderCmd.end();
+ },
+
+ /**
+ * clears the texture with a color
+ * @param {Number|cc.Rect} r red 0-255
+ * @param {Number} g green 0-255
+ * @param {Number} b blue 0-255
+ * @param {Number} a alpha 0-255
+ */
+ clear: function (r, g, b, a) {
+ this.beginWithClear(r, g, b, a);
+ this.end();
+ },
+
+ /**
+ * clears the texture with rect.
+ * @function
+ * @param {number} x
+ * @param {number} y
+ * @param {number} width
+ * @param {number} height
+ */
+ clearRect: function (x, y, width, height) {
+ this._renderCmd.clearRect(x, y, width, height);
+ },
+
+ /**
+ * clears the texture with a specified depth value
+ * @function
+ * @param {Number} depthValue
+ */
+ clearDepth: function (depthValue) {
+ this._renderCmd.clearDepth(depthValue);
+ },
+
+ /**
+ * clears the texture with a specified stencil value
+ * @function
+ * @param {Number} stencilValue
+ */
+ clearStencil: function (stencilValue) {
+ this._renderCmd.clearStencil(stencilValue);
+ },
+
+ /**
+ * Valid flags: GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT. They can be OR'ed. Valid when "autoDraw is YES.
+ * @return {Number}
+ */
+ getClearFlags: function () {
+ return this.clearFlags;
+ },
+
+ /**
+ * Set the clearFlags
+ * @param {Number} clearFlags
+ */
+ setClearFlags: function (clearFlags) {
+ this.clearFlags = clearFlags;
+ },
+
+ /**
+ * Clear color value. Valid only when "autoDraw" is true.
+ * @function
+ * @return {cc.Color}
+ */
+ getClearColor: function () {
+ return this._clearColor;
+ },
+
+ /**
+ * Set the clear color value. Valid only when "autoDraw" is true.
+ * @function
+ * @param {cc.Color} clearColor The clear color
+ */
+ setClearColor: function (clearColor) {
+ var locClearColor = this._clearColor;
+ locClearColor.r = clearColor.r;
+ locClearColor.g = clearColor.g;
+ locClearColor.b = clearColor.b;
+ locClearColor.a = clearColor.a;
+ this._renderCmd.updateClearColor(clearColor);
+ },
+
+ /**
+ * Value for clearDepth. Valid only when autoDraw is true.
+ * @return {Number}
+ */
+ getClearDepth: function () {
+ return this.clearDepthVal;
+ },
+
+ /**
+ * Set value for clearDepth. Valid only when autoDraw is true.
+ * @param {Number} clearDepth
+ */
+ setClearDepth: function (clearDepth) {
+ this.clearDepthVal = clearDepth;
+ },
+
+ /**
+ * Value for clear Stencil. Valid only when autoDraw is true
+ * @return {Number}
+ */
+ getClearStencil: function () {
+ return this.clearStencilVal;
+ },
+
+ /**
+ * Set value for clear Stencil. Valid only when autoDraw is true
+ * @return {Number}
+ */
+ setClearStencil: function (clearStencil) {
+ this.clearStencilVal = clearStencil;
+ },
+
+ /**
+ * When enabled, it will render its children into the texture automatically. Disabled by default for compatibility reasons.
+ * Will be enabled in the future.
+ * @return {Boolean}
+ */
+ isAutoDraw: function () {
+ return this.autoDraw;
+ },
+
+ /**
+ * When enabled, it will render its children into the texture automatically. Disabled by default for compatibility reasons.
+ * Will be enabled in the future.
+ * @return {Boolean}
+ */
+ setAutoDraw: function (autoDraw) {
+ this.autoDraw = autoDraw;
+ },
+
+ //---- some stub functions for jsb
+ /**
+ * saves the texture into a file using JPEG format. The file will be saved in the Documents folder.
+ * Returns YES if the operation is successful.
+ * (doesn't support in HTML5)
+ * @param {Number} filePath
+ * @param {Number} format
+ */
+ saveToFile: function (filePath, format) {
+ cc.log("saveToFile isn't supported on Cocos2d-Html5");
+ },
+
+ /**
+ * creates a new CCImage from with the texture's data. Caller is responsible for releasing it by calling delete.
+ * @return {*}
+ */
+ newCCImage: function (flipImage) {
+ cc.log("saveToFile isn't supported on cocos2d-html5");
+ return null;
+ },
+
+ /**
+ * Listen "come to background" message, and save render texture. It only has effect on Android.
+ * @param {cc.Class} obj
+ */
+ listenToBackground: function (obj) {
+ },
+
+ /**
+ * Listen "come to foreground" message and restore the frame buffer object. It only has effect on Android.
+ * @param {cc.Class} obj
+ */
+ listenToForeground: function (obj) {
+ }
+});
+
+var _p = cc.RenderTexture.prototype;
+// Extended
+/** @expose */
+_p.clearColorVal;
+cc.defineGetterSetter(_p, "clearColorVal", _p.getClearColor, _p.setClearColor);
+
+
+/**
+ * creates a RenderTexture object with width and height in Points and a pixel format, only RGB and RGBA formats are valid
+ * @deprecated since v3.0 please use new cc.RenderTexture() instead.
+ * @param {Number} width
+ * @param {Number} height
+ * @param {cc.IMAGE_FORMAT_JPEG|cc.IMAGE_FORMAT_PNG|cc.IMAGE_FORMAT_RAWDATA} format
+ * @param {Number} depthStencilFormat
+ * @return {cc.RenderTexture}
+ */
+cc.RenderTexture.create = function (width, height, format, depthStencilFormat) {
+ return new cc.RenderTexture(width, height, format, depthStencilFormat);
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/render-texture/CCRenderTextureCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/render-texture/CCRenderTextureCanvasRenderCmd.js
new file mode 100644
index 0000000..c55f9e7
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/render-texture/CCRenderTextureCanvasRenderCmd.js
@@ -0,0 +1,105 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ cc.RenderTexture.CanvasRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = false;
+ this._clearColorStr = "rgba(255,255,255,1)";
+
+ this._cacheCanvas = document.createElement('canvas');
+ this._cacheContext = new cc.CanvasContextWrapper(this._cacheCanvas.getContext('2d'));
+ };
+
+ var proto = cc.RenderTexture.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ proto.constructor = cc.RenderTexture.CanvasRenderCmd;
+
+ proto.cleanup = function () {
+ this._cacheContext = null;
+ this._cacheCanvas = null;
+ };
+
+ proto.clearStencil = function (stencilValue) {
+ };
+
+ proto.setVirtualViewport = function (rtBegin, fullRect, fullViewport) {
+ };
+
+ proto.updateClearColor = function (clearColor) {
+ this._clearColorStr = "rgba(" + (0 | clearColor.r) + "," + (0 | clearColor.g) + "," + (0 | clearColor.b) + "," + clearColor.a / 255 + ")";
+ };
+
+ proto.initWithWidthAndHeight = function (width, height, format, depthStencilFormat) {
+ var node = this._node;
+ var locCacheCanvas = this._cacheCanvas, locScaleFactor = cc.contentScaleFactor();
+ locCacheCanvas.width = 0 | (width * locScaleFactor);
+ locCacheCanvas.height = 0 | (height * locScaleFactor);
+
+ var texture = new cc.Texture2D();
+ texture.initWithElement(locCacheCanvas);
+ texture.handleLoadedTexture();
+
+ var locSprite = node.sprite = new cc.Sprite(texture);
+ locSprite.setBlendFunc(cc.ONE, cc.ONE_MINUS_SRC_ALPHA);
+ // Disabled by default.
+ node.autoDraw = false;
+ // add sprite for backward compatibility
+ node.addChild(locSprite);
+ return true;
+ };
+
+ proto.begin = function () {
+ };
+
+ proto._beginWithClear = function (r, g, b, a, depthValue, stencilValue, flags) {
+ r = r || 0;
+ g = g || 0;
+ b = b || 0;
+ a = isNaN(a) ? 255 : a;
+
+ var context = this._cacheContext.getContext();
+ var locCanvas = this._cacheCanvas;
+ context.setTransform(1, 0, 0, 1, 0, 0);
+ this._cacheContext.setFillStyle("rgba(" + (0 | r) + "," + (0 | g) + "," + (0 | b) + "," + a / 255 + ")");
+ context.clearRect(0, 0, locCanvas.width, locCanvas.height);
+ context.fillRect(0, 0, locCanvas.width, locCanvas.height);
+ };
+
+ proto.end = function () {
+ var node = this._node;
+
+ var scale = cc.contentScaleFactor();
+ cc.renderer._renderingToCacheCanvas(this._cacheContext, node.__instanceId, scale, scale);
+ var spriteRenderCmd = node.sprite._renderCmd;
+ spriteRenderCmd._notifyRegionStatus && spriteRenderCmd._notifyRegionStatus(cc.Node.CanvasRenderCmd.RegionStatus.Dirty);
+ };
+
+ proto.clearRect = function (x, y, width, height) {
+ this._cacheContext.clearRect(x, y, width, -height);
+ };
+
+ proto.clearDepth = function (depthValue) {
+ cc.log("clearDepth isn't supported on Cocos2d-Html5");
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/render-texture/CCRenderTextureWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/render-texture/CCRenderTextureWebGLRenderCmd.js
new file mode 100644
index 0000000..9abe91f
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/render-texture/CCRenderTextureWebGLRenderCmd.js
@@ -0,0 +1,366 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ cc.RenderTexture.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+
+ this._fBO = null;
+ this._oldFBO = null;
+ this._textureCopy = null;
+ this._depthRenderBuffer = null;
+
+ this._rtTextureRect = new cc.Rect();
+ this._fullRect = new cc.Rect();
+ this._fullViewport = new cc.Rect();
+ };
+
+ var proto = cc.RenderTexture.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ proto.constructor = cc.RenderTexture.WebGLRenderCmd;
+
+ proto.setVirtualViewport = function (rtBegin, fullRect, fullViewport) {
+ this._rtTextureRect.x = rtBegin.x;
+ this._rtTextureRect.y = rtBegin.y;
+
+ this._fullRect = fullRect;
+ this._fullViewport = fullViewport;
+ };
+
+ proto.needDraw = function () {
+ return this._needDraw && this._node.autoDraw;
+ };
+
+ proto.rendering = function (ctx) {
+ var gl = ctx || cc._renderContext;
+ var node = this._node;
+ if (node.autoDraw) {
+ node.begin();
+
+ var locClearFlags = node.clearFlags;
+ if (locClearFlags) {
+ var oldClearColor = [0.0, 0.0, 0.0, 0.0];
+ var oldDepthClearValue = 0.0;
+ var oldStencilClearValue = 0;
+
+ // backup and set
+ if (locClearFlags & gl.COLOR_BUFFER_BIT) {
+ oldClearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE);
+ gl.clearColor(node._clearColor.r / 255, node._clearColor.g / 255, node._clearColor.b / 255, node._clearColor.a / 255);
+ }
+
+ if (locClearFlags & gl.DEPTH_BUFFER_BIT) {
+ oldDepthClearValue = gl.getParameter(gl.DEPTH_CLEAR_VALUE);
+ gl.clearDepth(node.clearDepthVal);
+ }
+
+ if (locClearFlags & gl.STENCIL_BUFFER_BIT) {
+ oldStencilClearValue = gl.getParameter(gl.STENCIL_CLEAR_VALUE);
+ gl.clearStencil(node.clearStencilVal);
+ }
+
+ // clear
+ gl.clear(locClearFlags);
+
+ // restore
+ if (locClearFlags & gl.COLOR_BUFFER_BIT)
+ gl.clearColor(oldClearColor[0], oldClearColor[1], oldClearColor[2], oldClearColor[3]);
+
+ if (locClearFlags & gl.DEPTH_BUFFER_BIT)
+ gl.clearDepth(oldDepthClearValue);
+
+ if (locClearFlags & gl.STENCIL_BUFFER_BIT)
+ gl.clearStencil(oldStencilClearValue);
+ }
+
+ //! make sure all children are drawn
+ node.sortAllChildren();
+ var locChildren = node._children;
+ for (var i = 0; i < locChildren.length; i++) {
+ var getChild = locChildren[i];
+ if (getChild !== node.sprite) {
+ getChild.visit(node.sprite); //TODO it's very Strange
+ }
+ }
+ node.end();
+ }
+ };
+
+ proto.clearStencil = function (stencilValue) {
+ var gl = cc._renderContext;
+ // save old stencil value
+ var stencilClearValue = gl.getParameter(gl.STENCIL_CLEAR_VALUE);
+
+ gl.clearStencil(stencilValue);
+ gl.clear(gl.STENCIL_BUFFER_BIT);
+
+ // restore clear color
+ gl.clearStencil(stencilClearValue);
+ };
+
+ proto.cleanup = function () {
+ var node = this._node;
+ //node.sprite = null;
+ this._textureCopy = null;
+
+ var gl = cc._renderContext;
+ gl.deleteFramebuffer(this._fBO);
+ if (this._depthRenderBuffer)
+ gl.deleteRenderbuffer(this._depthRenderBuffer);
+ };
+
+ proto.updateClearColor = function (clearColor) {
+ };
+
+ proto.initWithWidthAndHeight = function (width, height, format, depthStencilFormat) {
+ var node = this._node;
+ if (format === cc.Texture2D.PIXEL_FORMAT_A8)
+ cc.log("cc.RenderTexture._initWithWidthAndHeightForWebGL() : only RGB and RGBA formats are valid for a render texture;");
+
+ var gl = cc._renderContext, locScaleFactor = cc.contentScaleFactor();
+ this._fullRect = new cc.Rect(0, 0, width, height);
+ this._fullViewport = new cc.Rect(0, 0, width, height);
+
+ width = 0 | (width * locScaleFactor);
+ height = 0 | (height * locScaleFactor);
+
+ this._oldFBO = gl.getParameter(gl.FRAMEBUFFER_BINDING);
+
+ // textures must be power of two squared
+ var powW, powH;
+
+ if (cc.configuration.supportsNPOT()) {
+ powW = width;
+ powH = height;
+ } else {
+ powW = cc.NextPOT(width);
+ powH = cc.NextPOT(height);
+ }
+
+ //void *data = malloc(powW * powH * 4);
+ var dataLen = powW * powH * 4;
+ var data = new Uint8Array(dataLen);
+ //memset(data, 0, (int)(powW * powH * 4));
+ for (var i = 0; i < powW * powH * 4; i++)
+ data[i] = 0;
+
+ this._pixelFormat = format;
+
+ var locTexture = node._texture = new cc.Texture2D();
+ if (!node._texture)
+ return false;
+
+ locTexture.initWithData(data, node._pixelFormat, powW, powH, cc.size(width, height));
+ //free( data );
+
+ var oldRBO = gl.getParameter(gl.RENDERBUFFER_BINDING);
+
+ if (cc.configuration.checkForGLExtension("GL_QCOM")) {
+ this._textureCopy = new cc.Texture2D();
+ if (!this._textureCopy)
+ return false;
+ this._textureCopy.initWithData(data, node._pixelFormat, powW, powH, cc.size(width, height));
+ }
+
+ // generate FBO
+ this._fBO = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this._fBO);
+
+ // associate texture with FBO
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, locTexture._webTextureObj, 0);
+
+ if (depthStencilFormat !== 0) {
+ //create and attach depth buffer
+ this._depthRenderBuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, this._depthRenderBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, depthStencilFormat, powW, powH);
+ if (depthStencilFormat === gl.DEPTH_STENCIL)
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this._depthRenderBuffer);
+ else if (depthStencilFormat === gl.STENCIL_INDEX || depthStencilFormat === gl.STENCIL_INDEX8)
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, this._depthRenderBuffer);
+ else if (depthStencilFormat === gl.DEPTH_COMPONENT16)
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this._depthRenderBuffer);
+ }
+
+ // check if it worked (probably worth doing :) )
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE)
+ cc.log("Could not attach texture to the framebuffer");
+
+ locTexture.setAliasTexParameters();
+
+ var locSprite = node.sprite = new cc.Sprite(locTexture);
+ locSprite.scaleY = -1;
+ locSprite.setBlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, oldRBO);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this._oldFBO);
+
+ // Disabled by default.
+ node.autoDraw = false;
+
+ // add sprite for backward compatibility
+ node.addChild(locSprite);
+ return true;
+ };
+
+ proto.begin = function () {
+ var node = this._node;
+ // Save the current matrix
+ cc.kmGLMatrixMode(cc.KM_GL_PROJECTION);
+ cc.kmGLPushMatrix();
+ cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
+ cc.kmGLPushMatrix();
+
+ var gl = cc._renderContext;
+
+ var director = cc.director;
+ director.setProjection(director.getProjection());
+
+ var texSize = node._texture.getContentSizeInPixels();
+
+ // Calculate the adjustment ratios based on the old and new projections
+ var size = cc.director.getWinSizeInPixels();
+ var widthRatio = size.width / texSize.width;
+ var heightRatio = size.height / texSize.height;
+
+ var orthoMatrix = cc.math.Matrix4.createOrthographicProjection(-1.0 / widthRatio, 1.0 / widthRatio,
+ -1.0 / heightRatio, 1.0 / heightRatio, -1, 1);
+ cc.kmGLMultMatrix(orthoMatrix);
+
+ //calculate viewport
+ var viewport = new cc.Rect(0, 0, 0, 0);
+ viewport.width = this._fullViewport.width;
+ viewport.height = this._fullViewport.height;
+ var viewPortRectWidthRatio = viewport.width / this._fullRect.width;
+ var viewPortRectHeightRatio = viewport.height / this._fullRect.height;
+ viewport.x = (this._fullRect.x - this._rtTextureRect.x) * viewPortRectWidthRatio;
+ viewport.y = (this._fullRect.y - this._rtTextureRect.y) * viewPortRectHeightRatio;
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+
+ this._oldFBO = gl.getParameter(gl.FRAMEBUFFER_BINDING);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this._fBO);//Will direct drawing to the frame buffer created above
+
+ /* Certain Qualcomm Adreno gpu's will retain data in memory after a frame buffer switch which corrupts the render to the texture.
+ * The solution is to clear the frame buffer before rendering to the texture. However, calling glClear has the unintended result of clearing the current texture.
+ * Create a temporary texture to overcome this. At the end of CCRenderTexture::begin(), switch the attached texture to the second one, call glClear,
+ * and then switch back to the original texture. This solution is unnecessary for other devices as they don't have the same issue with switching frame buffers.
+ */
+ if (cc.configuration.checkForGLExtension("GL_QCOM")) {
+ // -- bind a temporary texture so we can clear the render buffer without losing our texture
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this._textureCopy._webTextureObj, 0);
+ //cc.checkGLErrorDebug();
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, node._texture._webTextureObj, 0);
+ }
+ };
+
+ proto._beginWithClear = function (r, g, b, a, depthValue, stencilValue, flags) {
+ r = r / 255;
+ g = g / 255;
+ b = b / 255;
+ a = a / 255;
+
+ var gl = cc._renderContext;
+
+ // save clear color
+ var clearColor = [0.0, 0.0, 0.0, 0.0];
+ var depthClearValue = 0.0;
+ var stencilClearValue = 0;
+
+ if (flags & gl.COLOR_BUFFER_BIT) {
+ clearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE);
+ gl.clearColor(r, g, b, a);
+ }
+
+ if (flags & gl.DEPTH_BUFFER_BIT) {
+ depthClearValue = gl.getParameter(gl.DEPTH_CLEAR_VALUE);
+ gl.clearDepth(depthValue);
+ }
+
+ if (flags & gl.STENCIL_BUFFER_BIT) {
+ stencilClearValue = gl.getParameter(gl.STENCIL_CLEAR_VALUE);
+ gl.clearStencil(stencilValue);
+ }
+
+ gl.clear(flags);
+
+ // restore
+ if (flags & gl.COLOR_BUFFER_BIT)
+ gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
+
+ if (flags & gl.DEPTH_BUFFER_BIT)
+ gl.clearDepth(depthClearValue);
+
+ if (flags & gl.STENCIL_BUFFER_BIT)
+ gl.clearStencil(stencilClearValue);
+ };
+
+ proto.end = function () {
+ var node = this._node;
+ cc.renderer._renderingToBuffer(node.__instanceId);
+
+ var gl = cc._renderContext;
+ var director = cc.director;
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this._oldFBO);
+
+ //restore viewport
+ director.setViewport();
+ cc.kmGLMatrixMode(cc.KM_GL_PROJECTION);
+ cc.kmGLPopMatrix();
+ cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
+ cc.kmGLPopMatrix();
+
+ /* var size = director.getWinSizeInPixels();
+
+ // restore viewport
+ gl.viewport(0, 0, size.width * cc.contentScaleFactor(), size.height * cc.contentScaleFactor());
+
+ // special viewport for 3d projection + retina display
+ if (director.getProjection() == cc.Director.PROJECTION_3D && cc.contentScaleFactor() != 1) {
+ gl.viewport((-size.width / 2), (-size.height / 2), (size.width * cc.contentScaleFactor()), (size.height * cc.contentScaleFactor()));
+ }
+
+ director.setProjection(director.getProjection());*/
+ };
+
+ proto.clearRect = function (x, y, width, height) {
+ //TODO need to implement
+ };
+
+ proto.clearDepth = function (depthValue) {
+ var node = this._node;
+ node.begin();
+
+ var gl = cc._renderContext;
+ //! save old depth value
+ var depthClearValue = gl.getParameter(gl.DEPTH_CLEAR_VALUE);
+
+ gl.clearDepth(depthValue);
+ gl.clear(gl.DEPTH_BUFFER_BIT);
+
+ // restore clear color
+ gl.clearDepth(depthClearValue);
+ node.end();
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/shaders/CCGLProgram.js b/frameworks/cocos2d-html5/cocos2d/shaders/CCGLProgram.js
new file mode 100644
index 0000000..0cf9f47
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/shaders/CCGLProgram.js
@@ -0,0 +1,902 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright 2011 Jeff Lamarche
+ Copyright 2012 Goffredo Marocchi
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Class that implements a WebGL program
+ * @class
+ * @extends cc.Class
+ */
+cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{
+ _glContext: null,
+ _programObj: null,
+ _vertShader: null,
+ _fragShader: null,
+ _uniforms: null,
+ _hashForUniforms: null,
+ _usesTime: false,
+ _projectionUpdated: -1,
+
+ // Uniform cache
+ _updateUniform: function (name) {
+ if (!name)
+ return false;
+
+ var updated = false;
+ var element = this._hashForUniforms[name];
+ var args;
+ if (Array.isArray(arguments[1])) {
+ args = arguments[1];
+ } else {
+ args = new Array(arguments.length - 1);
+ for (var i = 1; i < arguments.length; i += 1) {
+ args[i - 1] = arguments[i];
+ }
+ }
+
+ if (!element || element.length !== args.length) {
+ this._hashForUniforms[name] = [].concat(args);
+ updated = true;
+ } else {
+ for (var i = 0; i < args.length; i += 1) {
+ // Array and Typed Array inner values could be changed, so we must update them
+ if (args[i] !== element[i] || typeof args[i] === 'object') {
+ element[i] = args[i];
+ updated = true;
+ }
+ }
+ }
+
+ return updated;
+ },
+
+ _description: function () {
+ return "";
+ },
+
+ _compileShader: function (shader, type, source) {
+ if (!source || !shader)
+ return false;
+
+ var preStr = cc.GLProgram._isHighpSupported() ? "precision highp float;\n" : "precision mediump float;\n";
+ source = preStr
+ + "uniform mat4 CC_PMatrix; \n"
+ + "uniform mat4 CC_MVMatrix; \n"
+ + "uniform mat4 CC_MVPMatrix; \n"
+ + "uniform vec4 CC_Time; \n"
+ + "uniform vec4 CC_SinTime; \n"
+ + "uniform vec4 CC_CosTime; \n"
+ + "uniform vec4 CC_Random01; \n"
+ + "uniform sampler2D CC_Texture0; \n"
+ + "//CC INCLUDES END \n" + source;
+
+ this._glContext.shaderSource(shader, source);
+ this._glContext.compileShader(shader);
+ var status = this._glContext.getShaderParameter(shader, this._glContext.COMPILE_STATUS);
+
+ if (!status) {
+ cc.log("cocos2d: ERROR: Failed to compile shader:\n" + this._glContext.getShaderSource(shader));
+ if (type === this._glContext.VERTEX_SHADER)
+ cc.log("cocos2d: \n" + this.vertexShaderLog());
+ else
+ cc.log("cocos2d: \n" + this.fragmentShaderLog());
+ }
+ return ( status === true );
+ },
+
+ /**
+ * Create a cc.GLProgram object
+ * @param {String} vShaderFileName
+ * @param {String} fShaderFileName
+ * @returns {cc.GLProgram}
+ */
+ ctor: function (vShaderFileName, fShaderFileName, glContext) {
+ this._uniforms = {};
+ this._hashForUniforms = {};
+ this._glContext = glContext || cc._renderContext;
+
+ vShaderFileName && fShaderFileName && this.init(vShaderFileName, fShaderFileName);
+ },
+
+ /**
+ * destroy program
+ */
+ destroyProgram: function () {
+ this._vertShader = null;
+ this._fragShader = null;
+ this._uniforms = null;
+ this._hashForUniforms = null;
+
+ this._glContext.deleteProgram(this._programObj);
+ },
+
+ /**
+ * Initializes the cc.GLProgram with a vertex and fragment with string
+ * @param {String} vertShaderStr
+ * @param {String} fragShaderStr
+ * @return {Boolean}
+ */
+ initWithVertexShaderByteArray: function (vertShaderStr, fragShaderStr) {
+ var locGL = this._glContext;
+ this._programObj = locGL.createProgram();
+ //cc.checkGLErrorDebug();
+
+ this._vertShader = null;
+ this._fragShader = null;
+
+ if (vertShaderStr) {
+ this._vertShader = locGL.createShader(locGL.VERTEX_SHADER);
+ if (!this._compileShader(this._vertShader, locGL.VERTEX_SHADER, vertShaderStr)) {
+ cc.log("cocos2d: ERROR: Failed to compile vertex shader");
+ }
+ }
+
+ // Create and compile fragment shader
+ if (fragShaderStr) {
+ this._fragShader = locGL.createShader(locGL.FRAGMENT_SHADER);
+ if (!this._compileShader(this._fragShader, locGL.FRAGMENT_SHADER, fragShaderStr)) {
+ cc.log("cocos2d: ERROR: Failed to compile fragment shader");
+ }
+ }
+
+ if (this._vertShader)
+ locGL.attachShader(this._programObj, this._vertShader);
+ cc.checkGLErrorDebug();
+
+ if (this._fragShader)
+ locGL.attachShader(this._programObj, this._fragShader);
+
+ if (Object.keys(this._hashForUniforms).length > 0) this._hashForUniforms = {};
+
+ cc.checkGLErrorDebug();
+ return true;
+ },
+
+ /**
+ * Initializes the cc.GLProgram with a vertex and fragment with string
+ * @param {String} vertShaderStr
+ * @param {String} fragShaderStr
+ * @return {Boolean}
+ */
+ initWithString: function (vertShaderStr, fragShaderStr) {
+ return this.initWithVertexShaderByteArray(vertShaderStr, fragShaderStr);
+ },
+
+ /**
+ * Initializes the CCGLProgram with a vertex and fragment with contents of filenames
+ * @param {String} vShaderFilename
+ * @param {String} fShaderFileName
+ * @return {Boolean}
+ */
+ initWithVertexShaderFilename: function (vShaderFilename, fShaderFileName) {
+ var vertexSource = cc.loader.getRes(vShaderFilename);
+ if (!vertexSource) throw new Error("Please load the resource firset : " + vShaderFilename);
+ var fragmentSource = cc.loader.getRes(fShaderFileName);
+ if (!fragmentSource) throw new Error("Please load the resource firset : " + fShaderFileName);
+ return this.initWithVertexShaderByteArray(vertexSource, fragmentSource);
+ },
+
+ /**
+ * Initializes the CCGLProgram with a vertex and fragment with contents of filenames
+ * @param {String} vShaderFilename
+ * @param {String} fShaderFileName
+ * @return {Boolean}
+ */
+ init: function (vShaderFilename, fShaderFileName) {
+ return this.initWithVertexShaderFilename(vShaderFilename, fShaderFileName);
+ },
+
+ /**
+ * It will add a new attribute to the shader
+ * @param {String} attributeName
+ * @param {Number} index
+ */
+ addAttribute: function (attributeName, index) {
+ this._glContext.bindAttribLocation(this._programObj, index, attributeName);
+ },
+
+ /**
+ * links the glProgram
+ * @return {Boolean}
+ */
+ link: function () {
+ if (!this._programObj) {
+ cc.log("cc.GLProgram.link(): Cannot link invalid program");
+ return false;
+ }
+
+ this._glContext.linkProgram(this._programObj);
+
+ if (this._vertShader)
+ this._glContext.deleteShader(this._vertShader);
+ if (this._fragShader)
+ this._glContext.deleteShader(this._fragShader);
+
+ this._vertShader = null;
+ this._fragShader = null;
+
+ if (cc.game.config[cc.game.CONFIG_KEY.debugMode]) {
+ var status = this._glContext.getProgramParameter(this._programObj, this._glContext.LINK_STATUS);
+ if (!status) {
+ cc.log("cocos2d: ERROR: Failed to link program: " + this._glContext.getProgramInfoLog(this._programObj));
+ cc.glDeleteProgram(this._programObj);
+ this._programObj = null;
+ return false;
+ }
+ }
+
+ return true;
+ },
+
+ /**
+ * it will call glUseProgram()
+ */
+ use: function () {
+ cc.glUseProgram(this._programObj);
+ },
+
+ /**
+ * It will create 4 uniforms:
+ * cc.UNIFORM_PMATRIX
+ * cc.UNIFORM_MVMATRIX
+ * cc.UNIFORM_MVPMATRIX
+ * cc.UNIFORM_SAMPLER
+ */
+ updateUniforms: function () {
+ this._addUniformLocation(cc.UNIFORM_PMATRIX_S);
+ this._addUniformLocation(cc.UNIFORM_MVMATRIX_S);
+ this._addUniformLocation(cc.UNIFORM_MVPMATRIX_S);
+ this._addUniformLocation(cc.UNIFORM_TIME_S);
+ this._addUniformLocation(cc.UNIFORM_SINTIME_S);
+ this._addUniformLocation(cc.UNIFORM_COSTIME_S);
+ this._addUniformLocation(cc.UNIFORM_RANDOM01_S);
+ this._addUniformLocation(cc.UNIFORM_SAMPLER_S);
+ this._usesTime = (this._uniforms[cc.UNIFORM_TIME_S] != null || this._uniforms[cc.UNIFORM_SINTIME_S] != null || this._uniforms[cc.UNIFORM_COSTIME_S] != null);
+
+ this.use();
+ // Since sample most probably won't change, set it to 0 now.
+ this.setUniformLocationWith1i(this._uniforms[cc.UNIFORM_SAMPLER_S], 0);
+ },
+
+ _addUniformLocation: function (name) {
+ var location = this._glContext.getUniformLocation(this._programObj, name);
+ if (location) location._name = name;
+ this._uniforms[name] = location;
+ return location;
+ },
+
+ /**
+ * calls retrieves the named uniform location for this shader program.
+ * @param {String} name
+ * @returns {Number}
+ */
+ getUniformLocationForName: function (name) {
+ if (!name)
+ throw new Error("cc.GLProgram.getUniformLocationForName(): uniform name should be non-null");
+ if (!this._programObj)
+ throw new Error("cc.GLProgram.getUniformLocationForName(): Invalid operation. Cannot get uniform location when program is not initialized");
+
+ var location = this._uniforms[name] || this._addUniformLocation(name);
+ return location;
+ },
+
+ /**
+ * get uniform MVP matrix
+ * @returns {WebGLUniformLocation}
+ */
+ getUniformMVPMatrix: function () {
+ return this._uniforms[cc.UNIFORM_MVPMATRIX_S];
+ },
+
+ /**
+ * get uniform sampler
+ * @returns {WebGLUniformLocation}
+ */
+ getUniformSampler: function () {
+ return this._uniforms[cc.UNIFORM_SAMPLER_S];
+ },
+
+ /**
+ * calls glUniform1i only if the values are different than the previous call for this same shader program.
+ * @param {WebGLUniformLocation|String} location
+ * @param {Number} i1
+ */
+ setUniformLocationWith1i: function (location, i1) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, i1)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform1i(location, i1);
+ }
+ } else {
+ this._glContext.uniform1i(location, i1);
+ }
+ },
+
+ /**
+ * calls glUniform2i only if the values are different than the previous call for this same shader program.
+ * @param {WebGLUniformLocation|String} location
+ * @param {Number} i1
+ * @param {Number} i2
+ */
+ setUniformLocationWith2i: function (location, i1, i2) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, i1, i2)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform2i(location, i1, i2);
+ }
+ } else {
+ this._glContext.uniform2i(location, i1, i2);
+ }
+ },
+
+ /**
+ * calls glUniform3i only if the values are different than the previous call for this same shader program.
+ * @param {WebGLUniformLocation|String} location
+ * @param {Number} i1
+ * @param {Number} i2
+ * @param {Number} i3
+ */
+ setUniformLocationWith3i: function (location, i1, i2, i3) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, i1, i2, i3)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform3i(location, i1, i2, i3);
+ }
+ } else {
+ this._glContext.uniform3i(location, i1, i2, i3);
+ }
+ },
+
+ /**
+ * calls glUniform4i only if the values are different than the previous call for this same shader program.
+ * @param {WebGLUniformLocation|String} location
+ * @param {Number} i1
+ * @param {Number} i2
+ * @param {Number} i3
+ * @param {Number} i4
+ */
+ setUniformLocationWith4i: function (location, i1, i2, i3, i4) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, i1, i2, i3, i4)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform4i(location, i1, i2, i3, i4);
+ }
+ } else {
+ this._glContext.uniform4i(location, i1, i2, i3, i4);
+ }
+ },
+
+ /**
+ * calls glUniform2iv
+ * @param {WebGLUniformLocation|String} location
+ * @param {Int32Array} intArray
+ * @param {Number} numberOfArrays
+ */
+ setUniformLocationWith2iv: function (location, intArray) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, intArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform2iv(location, intArray);
+ }
+ } else {
+ this._glContext.uniform2iv(location, intArray);
+ }
+ },
+
+ /**
+ * calls glUniform3iv
+ * @param {WebGLUniformLocation|String} location
+ * @param {Int32Array} intArray
+ */
+ setUniformLocationWith3iv: function (location, intArray) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, intArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform3iv(location, intArray);
+ }
+ } else {
+ this._glContext.uniform3iv(location, intArray);
+ }
+ },
+
+ /**
+ * calls glUniform4iv
+ * @param {WebGLUniformLocation|String} location
+ * @param {Int32Array} intArray
+ */
+ setUniformLocationWith4iv: function (location, intArray) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, intArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform4iv(location, intArray);
+ }
+ } else {
+ this._glContext.uniform4iv(location, intArray);
+ }
+ },
+
+ /**
+ * calls glUniform1i only if the values are different than the previous call for this same shader program.
+ * @param {WebGLUniformLocation|String} location
+ * @param {Number} i1
+ */
+ setUniformLocationI32: function (location, i1) {
+ this.setUniformLocationWith1i(location, i1);
+ },
+
+ /**
+ * calls glUniform1f only if the values are different than the previous call for this same shader program.
+ * @param {WebGLUniformLocation|String} location
+ * @param {Number} f1
+ */
+ setUniformLocationWith1f: function (location, f1) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, f1)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform1f(location, f1);
+ }
+ } else {
+ this._glContext.uniform1f(location, f1);
+ }
+ },
+
+ /**
+ * calls glUniform2f only if the values are different than the previous call for this same shader program.
+ * @param {WebGLUniformLocation|String} location
+ * @param {Number} f1
+ * @param {Number} f2
+ */
+ setUniformLocationWith2f: function (location, f1, f2) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, f1, f2)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform2f(location, f1, f2);
+ }
+ } else {
+ this._glContext.uniform2f(location, f1, f2);
+ }
+ },
+
+ /**
+ * calls glUniform3f only if the values are different than the previous call for this same shader program.
+ * @param {WebGLUniformLocation|String} location
+ * @param {Number} f1
+ * @param {Number} f2
+ * @param {Number} f3
+ */
+ setUniformLocationWith3f: function (location, f1, f2, f3) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, f1, f2, f3)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform3f(location, f1, f2, f3);
+ }
+ } else {
+ this._glContext.uniform3f(location, f1, f2, f3);
+ }
+ },
+
+ /**
+ * calls glUniform4f only if the values are different than the previous call for this same shader program.
+ * @param {WebGLUniformLocation|String} location
+ * @param {Number} f1
+ * @param {Number} f2
+ * @param {Number} f3
+ * @param {Number} f4
+ */
+ setUniformLocationWith4f: function (location, f1, f2, f3, f4) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, f1, f2, f3, f4)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform4f(location, f1, f2, f3, f4);
+ }
+ } else {
+ this._glContext.uniform4f(location, f1, f2, f3, f4);
+ cc.log('uniform4f', f1, f2, f3, f4);
+ }
+ },
+
+ /**
+ * calls glUniform2fv
+ * @param {WebGLUniformLocation|String} location
+ * @param {Float32Array} floatArray
+ */
+ setUniformLocationWith2fv: function (location, floatArray) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, floatArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform2fv(location, floatArray);
+ }
+ } else {
+ this._glContext.uniform2fv(location, floatArray);
+ }
+ },
+
+ /**
+ * calls glUniform3fv
+ * @param {WebGLUniformLocation|String} location
+ * @param {Float32Array} floatArray
+ */
+ setUniformLocationWith3fv: function (location, floatArray) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, floatArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform3fv(location, floatArray);
+ }
+ } else {
+ this._glContext.uniform3fv(location, floatArray);
+ }
+ },
+
+ /**
+ * calls glUniform4fv
+ * @param {WebGLUniformLocation|String} location
+ * @param {Float32Array} floatArray
+ */
+ setUniformLocationWith4fv: function (location, floatArray) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, floatArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniform4fv(location, floatArray);
+ }
+ } else {
+ this._glContext.uniform4fv(location, floatArray);
+ cc.log('uniform4fv', floatArray);
+ }
+ },
+
+ /**
+ * calls glUniformMatrix2fv
+ * @param {WebGLUniformLocation|String} location
+ * @param {Float32Array} matrixArray
+ */
+ setUniformLocationWithMatrix2fv: function (location, matrixArray) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, matrixArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniformMatrix2fv(location, false, matrixArray);
+ }
+ } else {
+ this._glContext.uniformMatrix2fv(location, false, matrixArray);
+ }
+ },
+
+ /**
+ * calls glUniformMatrix3fv
+ * @param {WebGLUniformLocation|String} location
+ * @param {Float32Array} matrixArray
+ */
+ setUniformLocationWithMatrix3fv: function (location, matrixArray) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, matrixArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniformMatrix3fv(location, false, matrixArray);
+ }
+ } else {
+ this._glContext.uniformMatrix3fv(location, false, matrixArray);
+ }
+ },
+
+ /**
+ * calls glUniformMatrix4fv
+ * @param {WebGLUniformLocation|String} location
+ * @param {Float32Array} matrixArray
+ */
+ setUniformLocationWithMatrix4fv: function (location, matrixArray) {
+ var isString = typeof location === 'string';
+ var name = isString ? location : location && location._name;
+ if (name) {
+ if (this._updateUniform(name, matrixArray)) {
+ if (isString) location = this.getUniformLocationForName(name);
+ this._glContext.uniformMatrix4fv(location, false, matrixArray);
+ }
+ } else {
+ this._glContext.uniformMatrix4fv(location, false, matrixArray);
+ }
+ },
+
+ setUniformLocationF32: function () {
+ if (arguments.length < 2)
+ return;
+
+ switch (arguments.length) {
+ case 2:
+ this.setUniformLocationWith1f(arguments[0], arguments[1]);
+ break;
+ case 3:
+ this.setUniformLocationWith2f(arguments[0], arguments[1], arguments[2]);
+ break;
+ case 4:
+ this.setUniformLocationWith3f(arguments[0], arguments[1], arguments[2], arguments[3]);
+ break;
+ case 5:
+ this.setUniformLocationWith4f(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
+ break;
+ }
+ },
+
+ /**
+ * will update the builtin uniforms if they are different than the previous call for this same shader program.
+ */
+ setUniformsForBuiltins: function () {
+ var matrixP = new cc.math.Matrix4();
+ var matrixMV = new cc.math.Matrix4();
+ var matrixMVP = new cc.math.Matrix4();
+
+ cc.kmGLGetMatrix(cc.KM_GL_PROJECTION, matrixP);
+ cc.kmGLGetMatrix(cc.KM_GL_MODELVIEW, matrixMV);
+
+ cc.kmMat4Multiply(matrixMVP, matrixP, matrixMV);
+
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], matrixP.mat, 1);
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], matrixMV.mat, 1);
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S], matrixMVP.mat, 1);
+
+ if (this._usesTime) {
+ var director = cc.director;
+ // This doesn't give the most accurate global time value.
+ // Cocos2D doesn't store a high precision time value, so this will have to do.
+ // Getting Mach time per frame per shader using time could be extremely expensive.
+ var time = director.getTotalFrames() * director.getAnimationInterval();
+
+ this.setUniformLocationWith4f(this._uniforms[cc.UNIFORM_TIME_S], time / 10.0, time, time * 2, time * 4);
+ this.setUniformLocationWith4f(this._uniforms[cc.UNIFORM_SINTIME_S], time / 8.0, time / 4.0, time / 2.0, Math.sin(time));
+ this.setUniformLocationWith4f(this._uniforms[cc.UNIFORM_COSTIME_S], time / 8.0, time / 4.0, time / 2.0, Math.cos(time));
+ }
+
+ if (this._uniforms[cc.UNIFORM_RANDOM01_S] !== -1)
+ this.setUniformLocationWith4f(this._uniforms[cc.UNIFORM_RANDOM01_S], Math.random(), Math.random(), Math.random(), Math.random());
+ },
+
+ _setUniformsForBuiltinsForRenderer: function (node) {
+ if (!node || !node._renderCmd)
+ return;
+
+ var matrixP = new cc.math.Matrix4();
+ //var matrixMV = new cc.kmMat4();
+ var matrixMVP = new cc.math.Matrix4();
+
+ cc.kmGLGetMatrix(cc.KM_GL_PROJECTION, matrixP);
+ //cc.kmGLGetMatrix(cc.KM_GL_MODELVIEW, node._stackMatrix);
+
+ cc.kmMat4Multiply(matrixMVP, matrixP, node._renderCmd._stackMatrix);
+
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], matrixP.mat, 1);
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], node._renderCmd._stackMatrix.mat, 1);
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S], matrixMVP.mat, 1);
+
+ if (this._usesTime) {
+ var director = cc.director;
+ // This doesn't give the most accurate global time value.
+ // Cocos2D doesn't store a high precision time value, so this will have to do.
+ // Getting Mach time per frame per shader using time could be extremely expensive.
+ var time = director.getTotalFrames() * director.getAnimationInterval();
+
+ this.setUniformLocationWith4f(this._uniforms[cc.UNIFORM_TIME_S], time / 10.0, time, time * 2, time * 4);
+ this.setUniformLocationWith4f(this._uniforms[cc.UNIFORM_SINTIME_S], time / 8.0, time / 4.0, time / 2.0, Math.sin(time));
+ this.setUniformLocationWith4f(this._uniforms[cc.UNIFORM_COSTIME_S], time / 8.0, time / 4.0, time / 2.0, Math.cos(time));
+ }
+
+ if (this._uniforms[cc.UNIFORM_RANDOM01_S] !== -1)
+ this.setUniformLocationWith4f(this._uniforms[cc.UNIFORM_RANDOM01_S], Math.random(), Math.random(), Math.random(), Math.random());
+ },
+
+ /**
+ * will update the MVP matrix on the MVP uniform if it is different than the previous call for this same shader program.
+ */
+ setUniformForModelViewProjectionMatrix: function () {
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S],
+ cc.getMat4MultiplyValue(cc.projection_matrix_stack.top, cc.modelview_matrix_stack.top));
+ },
+
+ setUniformForModelViewProjectionMatrixWithMat4: function (swapMat4) {
+ cc.kmMat4Multiply(swapMat4, cc.projection_matrix_stack.top, cc.modelview_matrix_stack.top);
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S], swapMat4.mat);
+ },
+
+ setUniformForModelViewAndProjectionMatrixWithMat4: function () {
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], cc.modelview_matrix_stack.top.mat);
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], cc.projection_matrix_stack.top.mat);
+ },
+
+ _setUniformForMVPMatrixWithMat4: function (modelViewMatrix) {
+ if (!modelViewMatrix)
+ throw new Error("modelView matrix is undefined.");
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], modelViewMatrix.mat);
+ this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], cc.projection_matrix_stack.top.mat);
+ },
+
+ _updateProjectionUniform: function () {
+ var stack = cc.projection_matrix_stack;
+ if (stack.lastUpdated !== this._projectionUpdated) {
+ this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], false, stack.top.mat);
+ this._projectionUpdated = stack.lastUpdated;
+ }
+ },
+
+ /**
+ * returns the vertexShader error log
+ * @return {String}
+ */
+ vertexShaderLog: function () {
+ return this._glContext.getShaderInfoLog(this._vertShader);
+ },
+
+ /**
+ * returns the vertexShader error log
+ * @return {String}
+ */
+ getVertexShaderLog: function () {
+ return this._glContext.getShaderInfoLog(this._vertShader);
+ },
+
+ /**
+ * returns the fragmentShader error log
+ * @returns {String}
+ */
+ getFragmentShaderLog: function () {
+ return this._glContext.getShaderInfoLog(this._vertShader);
+ },
+
+ /**
+ * returns the fragmentShader error log
+ * @return {String}
+ */
+ fragmentShaderLog: function () {
+ return this._glContext.getShaderInfoLog(this._fragShader);
+ },
+
+ /**
+ * returns the program error log
+ * @return {String}
+ */
+ programLog: function () {
+ return this._glContext.getProgramInfoLog(this._programObj);
+ },
+
+ /**
+ * returns the program error log
+ * @return {String}
+ */
+ getProgramLog: function () {
+ return this._glContext.getProgramInfoLog(this._programObj);
+ },
+
+ /**
+ * reload all shaders, this function is designed for android
+ * when opengl context lost, so don't call it.
+ */
+ reset: function () {
+ this._vertShader = null;
+ this._fragShader = null;
+ if (Object.keys(this._uniforms).length > 0) this._uniforms = {};
+
+ // it is already deallocated by android
+ //ccGLDeleteProgram(m_uProgram);
+ this._glContext.deleteProgram(this._programObj);
+ this._programObj = null;
+
+ // Purge uniform hash
+ if (Object.keys(this._hashForUniforms).length > 0) this._hashForUniforms = {};
+ },
+
+ /**
+ * get WebGLProgram object
+ * @return {WebGLProgram}
+ */
+ getProgram: function () {
+ return this._programObj;
+ },
+
+ /**
+ * Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
+ * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
+ * This is a hack, and should be removed once JSB fixes the retain/release bug
+ */
+ retain: function () {
+ },
+ release: function () {
+ }
+});
+
+/**
+ * Create a cc.GLProgram object
+ * @deprecated since v3.0, please use new cc.GLProgram(vShaderFileName, fShaderFileName) instead
+ * @param {String} vShaderFileName
+ * @param {String} fShaderFileName
+ * @returns {cc.GLProgram}
+ */
+cc.GLProgram.create = function (vShaderFileName, fShaderFileName) {
+ return new cc.GLProgram(vShaderFileName, fShaderFileName);
+};
+
+cc.GLProgram._highpSupported = null;
+
+cc.GLProgram._isHighpSupported = function () {
+ var ctx = cc._renderContext;
+ if (ctx.getShaderPrecisionFormat && cc.GLProgram._highpSupported == null) {
+ var highp = ctx.getShaderPrecisionFormat(ctx.FRAGMENT_SHADER, ctx.HIGH_FLOAT);
+ cc.GLProgram._highpSupported = highp.precision !== 0;
+ }
+ return cc.GLProgram._highpSupported;
+};
+
+/**
+ *
+ * Sets the shader program for this node
+ *
+ * Since v2.0, each rendering node must set its shader program.
+ * It should be set in initialize phase.
+ *
+ * @function
+ * @param {cc.Node} node
+ * @param {cc.GLProgram} program The shader program which fetches from CCShaderCache.
+ * @example
+ * cc.setGLProgram(node, cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR));
+ */
+cc.setProgram = function (node, program) {
+ node.shaderProgram = program;
+
+ var children = node.children;
+ if (!children)
+ return;
+
+ for (var i = 0; i < children.length; i++)
+ cc.setProgram(children[i], program);
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/shaders/CCGLProgramState.js b/frameworks/cocos2d-html5/cocos2d/shaders/CCGLProgramState.js
new file mode 100644
index 0000000..c5bc2fd
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/shaders/CCGLProgramState.js
@@ -0,0 +1,303 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+var types =
+ {
+ GL_FLOAT: 0,
+ GL_INT: 1,
+ GL_FLOAT_VEC2: 2,
+ GL_FLOAT_VEC3: 3,
+ GL_FLOAT_VEC4: 4,
+ GL_FLOAT_MAT4: 5,
+ GL_CALLBACK: 6,
+ GL_TEXTURE: 7
+ };
+
+
+
+cc.UniformValue = function (uniform, glprogram) {
+ this._uniform = uniform;
+ this._glprogram = glprogram;
+
+ this._value = null;
+ this._type = -1;
+};
+
+cc.UniformValue.prototype = {
+ setFloat: function setFloat(value) {
+ this._value = value;
+ this._type = types.GL_FLOAT;
+ },
+
+ setInt: function setInt(value) {
+ this._value = value;
+ this._type = types.GL_INT;
+ },
+
+ setVec2: function setVec2(v1, v2) {
+ this._value = [v1, v2];
+ this._type = types.GL_FLOAT_VEC2;
+ },
+
+ setVec2v: function setVec2v(value) {
+ this._value = value.slice(0);
+ this._type = types.GL_FLOAT_VEC2;
+ },
+
+ setVec3: function setVec3(v1, v2, v3) {
+ this._value = [v1, v2, v3];
+ this._type = types.GL_FLOAT_VEC3;
+ },
+
+ setVec3v: function setVec3v(value) {
+ this._value = value.slice(0);
+ this._type = types.GL_FLOAT_VEC3;
+ },
+
+ setVec4: function setVec4(v1, v2, v3, v4) {
+ this._value = [v1, v2, v3, v4];
+ this._type = types.GL_FLOAT_VEC4;
+ },
+
+ setVec4v: function setVec4v(value) {
+ this._value = value.slice(0);
+ this._type = types.GL_FLOAT_VEC4;
+ },
+
+ setMat4: function setMat4(value) {
+ this._value = value.slice(0);
+ this._type = types.GL_FLOAT_MAT4;
+ },
+
+ setCallback: function setCallback(fn) {
+ this._value = fn;
+ this._type = types.GL_CALLBACK;
+ },
+
+ setTexture: function setTexture(textureId, textureUnit) {
+ this._value = textureUnit;
+ this._textureId = textureId;
+ this._type = types.GL_TEXTURE;
+ },
+
+ apply: function apply() {
+ switch (this._type) {
+ case types.GL_INT:
+ this._glprogram.setUniformLocationWith1i(this._uniform._location, this._value);
+ break;
+ case types.GL_FLOAT:
+ this._glprogram.setUniformLocationWith1f(this._uniform._location, this._value);
+ break;
+ case types.GL_FLOAT_VEC2:
+ this._glprogram.setUniformLocationWith2fv(this._uniform._location, this._value);
+ break;
+ case types.GL_FLOAT_VEC3:
+ this._glprogram.setUniformLocationWith3fv(this._uniform._location, this._value);
+ break;
+ case types.GL_FLOAT_VEC4:
+ this._glprogram.setUniformLocationWith4fv(this._uniform._location, this._value);
+ break;
+ case types.GL_FLOAT_MAT4:
+ this._glprogram.setUniformLocationWithMatrix4fv(this._uniform._location, this._value);
+ break;
+ case types.GL_CALLBACK:
+ this._value(this._glprogram, this._uniform);
+ break;
+ case types.GL_TEXTURE:
+ this._glprogram.setUniformLocationWith1i(this._uniform._location, this._value);
+ cc.glBindTexture2DN(this._value, this._textureId);
+ break;
+ default:
+ ;
+ }
+ },
+};
+
+cc.GLProgramState = function (glprogram) {
+ this._glprogram = glprogram;
+ this._uniforms = {};
+ this._boundTextureUnits = {};
+ this._textureUnitIndex = 1; // Start at 1, as CC_Texture0 is bound to 0
+
+ var activeUniforms = glprogram._glContext.getProgramParameter(glprogram._programObj,
+ glprogram._glContext.ACTIVE_UNIFORMS);
+
+ for (var i = 0; i < activeUniforms; i += 1) {
+ var uniform = glprogram._glContext.getActiveUniform(glprogram._programObj, i);
+ if (uniform.name.indexOf("CC_") !== 0) {
+ uniform._location = glprogram._glContext.getUniformLocation(glprogram._programObj, uniform.name);
+ uniform._location._name = uniform.name;
+ var uniformValue = new cc.UniformValue(uniform, glprogram);
+ this._uniforms[uniform.name] = uniformValue;
+ }
+ }
+};
+
+cc.GLProgramState.prototype = {
+ apply: function apply(modelView) {
+ this._glprogram.use();
+ if (modelView) {
+ this._glprogram._setUniformForMVPMatrixWithMat4(modelView);
+ }
+
+ for (var name in this._uniforms) {
+ this._uniforms[name].apply();
+ };
+ },
+
+ setGLProgram: function setGLProgram(glprogram) {
+ this._glprogram = glprogram;
+ },
+
+ getGLProgram: function getGLProgram() {
+ return this._glprogram;
+ },
+
+ getUniformCount: function getUniformCount() {
+ return this._uniforms.length;
+ },
+
+ getUniformValue: function getUniformValue(uniform) {
+ return this._uniforms[uniform];
+ },
+
+ setUniformInt: function setUniformInt(uniform, value) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setInt(value);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+ setUniformFloat: function setUniformFloat(uniform, value) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setFloat(value);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+ setUniformVec2: function setUniformVec2(uniform, v1, v2) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setVec2(v1, v2);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+ setUniformVec2v: function setUniformVec2v(uniform, value) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setVec2v(value);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+ setUniformVec3: function setUniformVec3(uniform, v1, v2, v3) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setVec3(v1, v2, v3);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+ setUniformVec3v: function setUniformVec3v(uniform, value) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setVec3v(value);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+ setUniformVec4: function setUniformVec4(uniform, v1, v2, v3, v4) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setVec4(v1, v2, v3, v4);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+ setUniformVec4v: function setUniformVec4v(uniform, value) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setVec4v(value);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+ },
+
+
+ setUniformMat4: function setUniformMat4(uniform, value) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setMat4(value);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+
+ },
+
+ setUniformCallback: function setUniformCallback(uniform, callback) {
+ var v = this.getUniformValue(uniform);
+ if (v) {
+ v.setCallback(callback);
+ } else {
+ cc.log("cocos2d: warning: Uniform not found: " + uniform);
+ }
+
+ },
+
+ setUniformTexture: function setUniformTexture(uniform, texture) {
+ var uniformValue = this.getUniformValue(uniform);
+ if (uniformValue) {
+ var textureUnit = this._boundTextureUnits[uniform];
+ if (textureUnit) {
+ uniformValue.setTexture(texture, textureUnit);
+ } else {
+ uniformValue.setTexture(texture, this._textureUnitIndex);
+ this._boundTextureUnits[uniform] = this._textureUnitIndex++;
+ }
+ }
+ }
+};
+
+cc.GLProgramState._cache = {};
+cc.GLProgramState.getOrCreateWithGLProgram = function (glprogram) {
+ var programState = cc.GLProgramState._cache[glprogram.__instanceId];
+ if (!programState) {
+ programState = new cc.GLProgramState(glprogram);
+ cc.GLProgramState._cache[glprogram.__instanceId] = programState;
+ }
+
+ return programState;
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/shaders/CCGLStateCache.js b/frameworks/cocos2d-html5/cocos2d/shaders/CCGLStateCache.js
new file mode 100644
index 0000000..626c587
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/shaders/CCGLStateCache.js
@@ -0,0 +1,276 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc._currentProjectionMatrix = -1;
+
+if (cc.ENABLE_GL_STATE_CACHE) {
+ cc.MAX_ACTIVETEXTURE = 16;
+
+ cc._currentShaderProgram = -1;
+ cc._currentBoundTexture = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1];
+ cc._blendingSource = -1;
+ cc._blendingDest = -1;
+ cc._GLServerState = 0;
+ if(cc.TEXTURE_ATLAS_USE_VAO)
+ cc._uVAO = 0;
+}
+
+// GL State Cache functions
+
+/**
+ * Invalidates the GL state cache.
+ * If CC_ENABLE_GL_STATE_CACHE it will reset the GL state cache.
+ * @function
+ */
+cc.glInvalidateStateCache = function () {
+ cc.kmGLFreeAll();
+ cc._currentProjectionMatrix = -1;
+ if (cc.ENABLE_GL_STATE_CACHE) {
+ cc._currentShaderProgram = -1;
+ for (var i = 0; i < cc.MAX_ACTIVETEXTURE; i++) {
+ cc._currentBoundTexture[i] = -1;
+ }
+ cc._blendingSource = -1;
+ cc._blendingDest = -1;
+ cc._GLServerState = 0;
+ }
+};
+
+/**
+ * Uses the GL program in case program is different than the current one.
+ * If CC_ENABLE_GL_STATE_CACHE is disabled, it will the glUseProgram() directly.
+ * @function
+ * @param {WebGLProgram} program
+ */
+cc.glUseProgram = cc.ENABLE_GL_STATE_CACHE ? function (program) {
+ if (program !== cc._currentShaderProgram) {
+ cc._currentShaderProgram = program;
+ cc._renderContext.useProgram(program);
+ }
+} : function (program) {
+ cc._renderContext.useProgram(program);
+};
+
+/**
+ * Deletes the GL program. If it is the one that is being used, it invalidates it.
+ * If CC_ENABLE_GL_STATE_CACHE is disabled, it will the glDeleteProgram() directly.
+ * @function
+ * @param {WebGLProgram} program
+ */
+cc.glDeleteProgram = function (program) {
+ if (cc.ENABLE_GL_STATE_CACHE) {
+ if (program === cc._currentShaderProgram)
+ cc._currentShaderProgram = -1;
+ }
+ gl.deleteProgram(program);
+};
+
+/**
+ * @function
+ * @param {Number} sfactor
+ * @param {Number} dfactor
+ */
+cc.setBlending = function (sfactor, dfactor) {
+ var ctx = cc._renderContext;
+ if ((sfactor === ctx.ONE) && (dfactor === ctx.ZERO)) {
+ ctx.disable(ctx.BLEND);
+ } else {
+ ctx.enable(ctx.BLEND);
+ cc._renderContext.blendFunc(sfactor,dfactor);
+ //TODO need fix for WebGL
+ //ctx.blendFuncSeparate(ctx.SRC_ALPHA, dfactor, sfactor, dfactor);
+ }
+};
+
+/**
+ * Uses a blending function in case it not already used.
+ * If CC_ENABLE_GL_STATE_CACHE is disabled, it will the glBlendFunc() directly.
+ * @function
+ * @param {Number} sfactor
+ * @param {Number} dfactor
+ */
+cc.glBlendFunc = cc.ENABLE_GL_STATE_CACHE ? function (sfactor, dfactor) {
+ if ((sfactor !== cc._blendingSource) || (dfactor !== cc._blendingDest)) {
+ cc._blendingSource = sfactor;
+ cc._blendingDest = dfactor;
+ cc.setBlending(sfactor, dfactor);
+ }
+} : cc.setBlending;
+
+/**
+ * @function
+ * @param {Number} sfactor
+ * @param {Number} dfactor
+ */
+cc.glBlendFuncForParticle = function(sfactor, dfactor) {
+ if ((sfactor !== cc._blendingSource) || (dfactor !== cc._blendingDest)) {
+ cc._blendingSource = sfactor;
+ cc._blendingDest = dfactor;
+ var ctx = cc._renderContext;
+ if ((sfactor === ctx.ONE) && (dfactor === ctx.ZERO)) {
+ ctx.disable(ctx.BLEND);
+ } else {
+ ctx.enable(ctx.BLEND);
+ //TODO need fix for WebGL
+ ctx.blendFuncSeparate(ctx.SRC_ALPHA, dfactor, sfactor, dfactor);
+ }
+ }
+};
+
+/**
+ * Resets the blending mode back to the cached state in case you used glBlendFuncSeparate() or glBlendEquation().
+ * If CC_ENABLE_GL_STATE_CACHE is disabled, it will just set the default blending mode using GL_FUNC_ADD.
+ * @function
+ */
+cc.glBlendResetToCache = function () {
+ var ctx = cc._renderContext;
+ ctx.blendEquation(ctx.FUNC_ADD);
+ if (cc.ENABLE_GL_STATE_CACHE)
+ cc.setBlending(cc._blendingSource, cc._blendingDest);
+ else
+ cc.setBlending(ctx.BLEND_SRC, ctx.BLEND_DST);
+};
+
+/**
+ * sets the projection matrix as dirty
+ * @function
+ */
+cc.setProjectionMatrixDirty = function () {
+ cc._currentProjectionMatrix = -1;
+};
+
+/**
+ * If the texture is not already bound, it binds it.
+ * If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glBindTexture() directly.
+ * @function
+ * @param {cc.Texture2D} textureId
+ */
+cc.glBindTexture2D = function (textureId) {
+ cc.glBindTexture2DN(0, textureId);
+};
+
+/**
+ * If the texture is not already bound to a given unit, it binds it.
+ * If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glBindTexture() directly.
+ * @function
+ * @param {Number} textureUnit
+ * @param {cc.Texture2D} textureId
+ */
+cc.glBindTexture2DN = cc.ENABLE_GL_STATE_CACHE ? function (textureUnit, textureId) {
+ if (cc._currentBoundTexture[textureUnit] === textureId)
+ return;
+ cc._currentBoundTexture[textureUnit] = textureId;
+
+ var ctx = cc._renderContext;
+ ctx.activeTexture(ctx.TEXTURE0 + textureUnit);
+ if(textureId)
+ ctx.bindTexture(ctx.TEXTURE_2D, textureId._webTextureObj);
+ else
+ ctx.bindTexture(ctx.TEXTURE_2D, null);
+} : function (textureUnit, textureId) {
+ var ctx = cc._renderContext;
+ ctx.activeTexture(ctx.TEXTURE0 + textureUnit);
+ if(textureId)
+ ctx.bindTexture(ctx.TEXTURE_2D, textureId._webTextureObj);
+ else
+ ctx.bindTexture(ctx.TEXTURE_2D, null);
+};
+
+/**
+ * It will delete a given texture. If the texture was bound, it will invalidate the cached.
+ * If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glDeleteTextures() directly.
+ * @function
+ * @param {WebGLTexture} textureId
+ */
+cc.glDeleteTexture = function (textureId) {
+ cc.glDeleteTextureN(0, textureId);
+};
+
+/**
+ * It will delete a given texture. If the texture was bound, it will invalidate the cached for the given texture unit.
+ * If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glDeleteTextures() directly.
+ * @function
+ * @param {Number} textureUnit
+ * @param {WebGLTexture} textureId
+ */
+cc.glDeleteTextureN = function (textureUnit, textureId) {
+ if (cc.ENABLE_GL_STATE_CACHE) {
+ if (textureId === cc._currentBoundTexture[ textureUnit ])
+ cc._currentBoundTexture[ textureUnit ] = -1;
+ }
+ cc._renderContext.deleteTexture(textureId._webTextureObj);
+};
+
+/**
+ * If the vertex array is not already bound, it binds it.
+ * If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glBindVertexArray() directly.
+ * @function
+ * @param {Number} vaoId
+ */
+cc.glBindVAO = function (vaoId) {
+ if (!cc.TEXTURE_ATLAS_USE_VAO)
+ return;
+
+ if (cc.ENABLE_GL_STATE_CACHE) {
+ if (cc._uVAO !== vaoId) {
+ cc._uVAO = vaoId;
+ //TODO need fixed
+ //glBindVertexArray(vaoId);
+ }
+ } else {
+ //glBindVertexArray(vaoId);
+ }
+};
+
+/**
+ * It will enable / disable the server side GL states.
+ * If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glEnable() directly.
+ * @function
+ * @param {Number} flags
+ */
+cc.glEnable = function (flags) {
+ if (cc.ENABLE_GL_STATE_CACHE) {
+ /*var enabled;
+
+ */
+ /* GL_BLEND */
+ /*
+ if ((enabled = (flags & cc.GL_BLEND)) != (cc._GLServerState & cc.GL_BLEND)) {
+ if (enabled) {
+ cc._renderContext.enable(cc._renderContext.BLEND);
+ cc._GLServerState |= cc.GL_BLEND;
+ } else {
+ cc._renderContext.disable(cc._renderContext.BLEND);
+ cc._GLServerState &= ~cc.GL_BLEND;
+ }
+ }*/
+ } else {
+ /*if ((flags & cc.GL_BLEND))
+ cc._renderContext.enable(cc._renderContext.BLEND);
+ else
+ cc._renderContext.disable(cc._renderContext.BLEND);*/
+ }
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/shaders/CCShaderCache.js b/frameworks/cocos2d-html5/cocos2d/shaders/CCShaderCache.js
new file mode 100644
index 0000000..462f208
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/shaders/CCShaderCache.js
@@ -0,0 +1,322 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.shaderCache is a singleton object that stores manages GL shaders
+ * @class
+ * @name cc.shaderCache
+ */
+cc.shaderCache = /** @lends cc.shaderCache# */{
+
+ /**
+ * @public
+ * @constant
+ * @type {Number}
+ */
+ TYPE_POSITION_TEXTURECOLOR: 0,
+ /**
+ * @public
+ * @constant
+ * @type {Number}
+ */
+ TYPE_POSITION_TEXTURECOLOR_ALPHATEST: 1,
+ /**
+ * @public
+ * @constant
+ * @type {Number}
+ */
+ TYPE_POSITION_COLOR: 2,
+ /**
+ * @public
+ * @constant
+ * @type {Number}
+ */
+ TYPE_POSITION_TEXTURE: 3,
+ /**
+ * @public
+ * @constant
+ * @type {Number}
+ */
+ TYPE_POSITION_TEXTURE_UCOLOR: 4,
+ /**
+ * @public
+ * @constant
+ * @type {Number}
+ */
+ TYPE_POSITION_TEXTURE_A8COLOR: 5,
+ /**
+ * @public
+ * @constant
+ * @type {Number}
+ */
+ TYPE_POSITION_UCOLOR: 6,
+ /**
+ * @public
+ * @constant
+ * @type {Number}
+ */
+ TYPE_POSITION_LENGTH_TEXTURECOLOR: 7,
+ /**
+ * @public
+ * @constant
+ * @type {Number}
+ */
+ TYPE_SPRITE_POSITION_TEXTURECOLOR: 8,
+ /**
+ * @public
+ * @constant
+ * @type {Number}
+ */
+ TYPE_SPRITE_POSITION_TEXTURECOLOR_ALPHATEST: 9,
+ /**
+ * @public
+ * @constant
+ * @type {Number}
+ */
+ TYPE_SPRITE_POSITION_COLOR: 10,
+ /**
+ * @public
+ * @constant
+ * @type {Number}
+ */
+ TYPE_SPRITE_POSITION_TEXTURECOLOR_GRAY: 11,
+ /**
+ * @public
+ * @constant
+ * @type {Number}
+ */
+ TYPE_MAX: 11,
+
+ _keyMap: [
+ cc.SHADER_POSITION_TEXTURECOLOR,
+ cc.SHADER_POSITION_TEXTURECOLORALPHATEST,
+ cc.SHADER_POSITION_COLOR,
+ cc.SHADER_POSITION_TEXTURE,
+ cc.SHADER_POSITION_TEXTURE_UCOLOR,
+ cc.SHADER_POSITION_TEXTUREA8COLOR,
+ cc.SHADER_POSITION_UCOLOR,
+ cc.SHADER_POSITION_LENGTHTEXTURECOLOR,
+ cc.SHADER_SPRITE_POSITION_TEXTURECOLOR,
+ cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST,
+ cc.SHADER_SPRITE_POSITION_COLOR,
+ cc.SHADER_SPRITE_POSITION_TEXTURECOLOR_GRAY
+ ],
+
+ _programs: {},
+
+ _init: function () {
+ this.loadDefaultShaders();
+ return true;
+ },
+
+ _loadDefaultShader: function (program, type) {
+ switch (type) {
+ case cc.SHADER_POSITION_TEXTURECOLOR:
+ program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_COLOR_VERT, cc.SHADER_POSITION_TEXTURE_COLOR_FRAG);
+ program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
+ program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
+ program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
+ break;
+ case cc.SHADER_SPRITE_POSITION_TEXTURECOLOR:
+ program.initWithVertexShaderByteArray(cc.SHADER_SPRITE_POSITION_TEXTURE_COLOR_VERT, cc.SHADER_POSITION_TEXTURE_COLOR_FRAG);
+ program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
+ program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
+ program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
+ break;
+ case cc.SHADER_SPRITE_POSITION_TEXTURECOLOR_GRAY:
+ program.initWithVertexShaderByteArray(cc.SHADER_SPRITE_POSITION_TEXTURE_COLOR_VERT, cc.SHADER_SPRITE_POSITION_TEXTURE_COLOR_GRAY_FRAG);
+ program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
+ program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
+ program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
+ break;
+ case cc.SHADER_POSITION_TEXTURECOLORALPHATEST:
+ program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_COLOR_VERT, cc.SHADER_POSITION_TEXTURE_COLOR_ALPHATEST_FRAG);
+ program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
+ program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
+ program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
+ break;
+ case cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST:
+ program.initWithVertexShaderByteArray(cc.SHADER_SPRITE_POSITION_TEXTURE_COLOR_VERT, cc.SHADER_POSITION_TEXTURE_COLOR_ALPHATEST_FRAG);
+ program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
+ program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
+ program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
+ break;
+ case cc.SHADER_POSITION_COLOR:
+ program.initWithVertexShaderByteArray(cc.SHADER_POSITION_COLOR_VERT, cc.SHADER_POSITION_COLOR_FRAG);
+ program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
+ program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
+ break;
+ case cc.SHADER_SPRITE_POSITION_COLOR:
+ program.initWithVertexShaderByteArray(cc.SHADER_SPRITE_POSITION_COLOR_VERT, cc.SHADER_POSITION_COLOR_FRAG);
+ program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
+ program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
+ break;
+ case cc.SHADER_POSITION_TEXTURE:
+ program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_VERT, cc.SHADER_POSITION_TEXTURE_FRAG);
+ program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
+ program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
+ break;
+ case cc.SHADER_POSITION_TEXTURE_UCOLOR:
+ program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_UCOLOR_VERT, cc.SHADER_POSITION_TEXTURE_UCOLOR_FRAG);
+ program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
+ program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
+ break;
+ case cc.SHADER_POSITION_TEXTUREA8COLOR:
+ program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_A8COLOR_VERT, cc.SHADER_POSITION_TEXTURE_A8COLOR_FRAG);
+ program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
+ program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
+ program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
+ break;
+ case cc.SHADER_POSITION_UCOLOR:
+ program.initWithVertexShaderByteArray(cc.SHADER_POSITION_UCOLOR_VERT, cc.SHADER_POSITION_UCOLOR_FRAG);
+ program.addAttribute("aVertex", cc.VERTEX_ATTRIB_POSITION);
+ break;
+ case cc.SHADER_POSITION_LENGTHTEXTURECOLOR:
+ program.initWithVertexShaderByteArray(cc.SHADER_POSITION_COLOR_LENGTH_TEXTURE_VERT, cc.SHADER_POSITION_COLOR_LENGTH_TEXTURE_FRAG);
+ program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
+ program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
+ program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
+ break;
+ default:
+ cc.log("cocos2d: cc.shaderCache._loadDefaultShader, error shader type");
+ return;
+ }
+
+ program.link();
+ program.updateUniforms();
+
+ //cc.checkGLErrorDebug();
+ },
+
+ /**
+ * loads the default shaders
+ */
+ loadDefaultShaders: function () {
+ for (var i = 0; i < this.TYPE_MAX; ++i) {
+ var key = this._keyMap[i];
+ this.programForKey(key);
+ }
+ },
+
+ /**
+ * reload the default shaders
+ */
+ reloadDefaultShaders: function () {
+ // reset all programs and reload them
+
+ // Position Texture Color shader
+ var program = this.programForKey(cc.SHADER_POSITION_TEXTURECOLOR);
+ program.reset();
+ this._loadDefaultShader(program, cc.SHADER_POSITION_TEXTURECOLOR);
+
+ // Sprite Position Texture Color shader
+ program = this.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR);
+ program.reset();
+ this._loadDefaultShader(program, cc.SHADER_SPRITE_POSITION_TEXTURECOLOR);
+
+ // Position Texture Color alpha test
+ program = this.programForKey(cc.SHADER_POSITION_TEXTURECOLORALPHATEST);
+ program.reset();
+ this._loadDefaultShader(program, cc.SHADER_POSITION_TEXTURECOLORALPHATEST);
+
+ // Sprite Position Texture Color alpha shader
+ program = this.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST);
+ program.reset();
+ this._loadDefaultShader(program, cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST);
+
+ //
+ // Position, Color shader
+ //
+ program = this.programForKey(cc.SHADER_POSITION_COLOR);
+ program.reset();
+ this._loadDefaultShader(program, cc.SHADER_POSITION_COLOR);
+
+ //
+ // Position Texture shader
+ //
+ program = this.programForKey(cc.SHADER_POSITION_TEXTURE);
+ program.reset();
+ this._loadDefaultShader(program, cc.SHADER_POSITION_TEXTURE);
+
+ //Position Texture Gray shader
+ program = this.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURE_COLOR_GRAY_FRAG);
+ program.reset();
+ this._loadDefaultShader(program, cc.SHADER_SPRITE_POSITION_TEXTURE_COLOR_GRAY_FRAG);
+
+ //
+ // Position, Texture attribs, 1 Color as uniform shader
+ //
+ program = this.programForKey(cc.SHADER_POSITION_TEXTURE_UCOLOR);
+ program.reset();
+ this._loadDefaultShader(program, cc.SHADER_POSITION_TEXTURE_UCOLOR);
+
+ //
+ // Position Texture A8 Color shader
+ //
+ program = this.programForKey(cc.SHADER_POSITION_TEXTUREA8COLOR);
+ program.reset();
+ this._loadDefaultShader(program, cc.SHADER_POSITION_TEXTUREA8COLOR);
+
+ //
+ // Position and 1 color passed as a uniform (to similate glColor4ub )
+ //
+ program = this.programForKey(cc.SHADER_POSITION_UCOLOR);
+ program.reset();
+ this._loadDefaultShader(program, cc.SHADER_POSITION_UCOLOR);
+ },
+
+ /**
+ * returns a GL program for a given key
+ * @param {String} key
+ */
+ programForKey: function (key) {
+ if (!this._programs[key]) {
+ var program = new cc.GLProgram();
+ this._loadDefaultShader(program, key);
+ this._programs[key] = program;
+ }
+
+ return this._programs[key];
+ },
+
+ /**
+ * returns a GL program for a shader name
+ * @param {String} shaderName
+ * @return {cc.GLProgram}
+ */
+ getProgram: function (shaderName) {
+ return this.programForKey(shaderName);
+ },
+
+ /**
+ * adds a CCGLProgram to the cache for a given name
+ * @param {cc.GLProgram} program
+ * @param {String} key
+ */
+ addProgram: function (program, key) {
+ this._programs[key] = program;
+ }
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/shaders/CCShaders.js b/frameworks/cocos2d-html5/cocos2d/shaders/CCShaders.js
new file mode 100644
index 0000000..eb656c5
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/shaders/CCShaders.js
@@ -0,0 +1,314 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2016 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+//-----------------------Shader_Position_uColor Shader Source--------------------------
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_UCOLOR_FRAG =
+ "precision lowp float;\n"
+ + "varying vec4 v_fragmentColor;\n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_FragColor = v_fragmentColor; \n"
+ + "}\n";
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_UCOLOR_VERT =
+ "attribute vec4 a_position;\n"
+ + "uniform vec4 u_color;\n"
+ + "uniform float u_pointSize;\n"
+ + "varying lowp vec4 v_fragmentColor; \n"
+ + "void main(void) \n"
+ + "{\n"
+ //+ " gl_Position = CC_MVPMatrix * a_position; \n"
+ + " gl_Position = (CC_PMatrix * CC_MVMatrix) * a_position; \n"
+ + " gl_PointSize = u_pointSize; \n"
+ + " v_fragmentColor = u_color; \n"
+ + "}";
+
+//---------------------Shader_PositionColor Shader Source-----------------------
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_COLOR_FRAG =
+ "precision lowp float; \n"
+ + "varying vec4 v_fragmentColor; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_FragColor = v_fragmentColor; \n"
+ + "} ";
+
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_COLOR_VERT =
+ "attribute vec4 a_position;\n"
+ + "attribute vec4 a_color;\n"
+ + "varying lowp vec4 v_fragmentColor;\n"
+ + "void main()\n"
+ + "{\n"
+ + " gl_Position = (CC_PMatrix * CC_MVMatrix) * a_position; \n"
+ + " v_fragmentColor = a_color; \n"
+ + "}";
+
+cc.SHADER_SPRITE_POSITION_COLOR_VERT =
+ "attribute vec4 a_position;\n"
+ + "attribute vec4 a_color;\n"
+ + "varying lowp vec4 v_fragmentColor;\n"
+ + "void main()\n"
+ + "{\n"
+ + " gl_Position = CC_PMatrix * a_position; \n"
+ + " v_fragmentColor = a_color; \n"
+ + "}";
+
+// --------------------- Shader_PositionColorLengthTexture Shader source------------------------
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_COLOR_LENGTH_TEXTURE_FRAG =
+ "// #extension GL_OES_standard_derivatives : enable\n"
+ + "varying mediump vec4 v_color;\n"
+ + "varying mediump vec2 v_texcoord;\n"
+ + "void main() \n"
+ + "{ \n"
+ + "// #if defined GL_OES_standard_derivatives \n"
+ + "// gl_FragColor = v_color*smoothstep(0.0, length(fwidth(v_texcoord)), 1.0 - length(v_texcoord)); \n"
+ + "// #else \n"
+ + "gl_FragColor = v_color * step(0.0, 1.0 - length(v_texcoord)); \n"
+ + "// #endif \n"
+ + "}";
+
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_COLOR_LENGTH_TEXTURE_VERT =
+ "attribute mediump vec4 a_position; \n"
+ + "attribute mediump vec2 a_texcoord; \n"
+ + "attribute mediump vec4 a_color; \n"
+ + "varying mediump vec4 v_color; \n"
+ + "varying mediump vec2 v_texcoord; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " v_color = a_color;//vec4(a_color.rgb * a_color.a, a_color.a); \n"
+ + " v_texcoord = a_texcoord; \n"
+ //+ " gl_Position = CC_MVPMatrix * a_position; \n"
+ + " gl_Position = (CC_PMatrix * CC_MVMatrix) * a_position; \n"
+ + "}";
+
+// ----------------------Shader_PositionTexture Shader Source-------------------------------------
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_TEXTURE_FRAG =
+ "precision lowp float; \n"
+ + "varying vec2 v_texCoord; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_FragColor = texture2D(CC_Texture0, v_texCoord); \n"
+ + "}";
+
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_TEXTURE_VERT =
+ "attribute vec4 a_position; \n"
+ + "attribute vec2 a_texCoord; \n"
+ + "varying mediump vec2 v_texCoord; \n"
+ + "void main() \n"
+ + "{ \n"
+ //+ " gl_Position = CC_MVPMatrix * a_position; \n"
+ + " gl_Position = (CC_PMatrix * CC_MVMatrix) * a_position; \n"
+ + " v_texCoord = a_texCoord; \n"
+ + "}";
+
+// ------------------------Shader_PositionTexture_uColor Shader Source-------------------------------
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_TEXTURE_UCOLOR_FRAG =
+ "precision lowp float; \n"
+ + "uniform vec4 u_color; \n"
+ + "varying vec2 v_texCoord; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_FragColor = texture2D(CC_Texture0, v_texCoord) * u_color; \n"
+ + "}";
+
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_TEXTURE_UCOLOR_VERT =
+ "attribute vec4 a_position;\n"
+ + "attribute vec2 a_texCoord; \n"
+ + "varying mediump vec2 v_texCoord; \n"
+ + "void main() \n"
+ + "{ \n"
+ //+ " gl_Position = CC_MVPMatrix * a_position; \n"
+ + " gl_Position = (CC_PMatrix * CC_MVMatrix) * a_position; \n"
+ + " v_texCoord = a_texCoord; \n"
+ + "}";
+
+//---------------------Shader_PositionTextureA8Color Shader source-------------------------------
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_TEXTURE_A8COLOR_FRAG =
+ "precision lowp float; \n"
+ + "varying vec4 v_fragmentColor; \n"
+ + "varying vec2 v_texCoord; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_FragColor = vec4( v_fragmentColor.rgb, \n" // RGB from uniform
+ + " v_fragmentColor.a * texture2D(CC_Texture0, v_texCoord).a \n" // A from texture and uniform
+ + " ); \n"
+ + "}";
+
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_TEXTURE_A8COLOR_VERT =
+ "attribute vec4 a_position; \n"
+ + "attribute vec2 a_texCoord; \n"
+ + "attribute vec4 a_color; \n"
+ + "varying lowp vec4 v_fragmentColor; \n"
+ + "varying mediump vec2 v_texCoord; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_Position = (CC_PMatrix * CC_MVMatrix) * a_position; \n"
+ + " v_fragmentColor = a_color; \n"
+ + " v_texCoord = a_texCoord; \n"
+ + "}";
+
+// ------------------------Shader_PositionTextureColor Shader source------------------------------------
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_TEXTURE_COLOR_FRAG =
+ "precision lowp float;\n"
+ + "varying vec4 v_fragmentColor; \n"
+ + "varying vec2 v_texCoord; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord); \n"
+ + "}";
+
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_TEXTURE_COLOR_VERT =
+ "attribute vec4 a_position; \n"
+ + "attribute vec2 a_texCoord; \n"
+ + "attribute vec4 a_color; \n"
+ + "varying lowp vec4 v_fragmentColor; \n"
+ + "varying mediump vec2 v_texCoord; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_Position = (CC_PMatrix * CC_MVMatrix) * a_position; \n"
+ + " v_fragmentColor = a_color; \n"
+ + " v_texCoord = a_texCoord; \n"
+ + "}";
+
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_SPRITE_POSITION_TEXTURE_COLOR_VERT =
+ "attribute vec4 a_position; \n"
+ + "attribute vec2 a_texCoord; \n"
+ + "attribute vec4 a_color; \n"
+ + "varying lowp vec4 v_fragmentColor; \n"
+ + "varying mediump vec2 v_texCoord; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_Position = CC_PMatrix * a_position; \n"
+ + " v_fragmentColor = a_color; \n"
+ + " v_texCoord = a_texCoord; \n"
+ + "}";
+
+cc.SHADER_SPRITE_POSITION_TEXTURE_COLOR_GRAY_FRAG =
+ "precision lowp float;\n"
+ + "varying vec4 v_fragmentColor; \n"
+ + "varying vec2 v_texCoord; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " vec4 c = texture2D(CC_Texture0, v_texCoord); \n"
+ + " gl_FragColor.xyz = vec3(0.2126*c.r + 0.7152*c.g + 0.0722*c.b); \n"
+ +" gl_FragColor.w = c.w ; \n"
+ + "}";
+//-----------------------Shader_PositionTextureColorAlphaTest_frag Shader Source----------------------------
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADER_POSITION_TEXTURE_COLOR_ALPHATEST_FRAG =
+ "precision lowp float; \n"
+ + "varying vec4 v_fragmentColor; \n"
+ + "varying vec2 v_texCoord; \n"
+ + "uniform float CC_alpha_value; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " vec4 texColor = texture2D(CC_Texture0, v_texCoord); \n"
+ // mimic: glAlphaFunc(GL_GREATER)
+ //pass if ( incoming_pixel >= CC_alpha_value ) => fail if incoming_pixel < CC_alpha_value
+ + " if ( texColor.a <= CC_alpha_value ) \n"
+ + " discard; \n"
+ + " gl_FragColor = texColor * v_fragmentColor; \n"
+ + "}";
+
+//-----------------------ShaderEx_SwitchMask_frag Shader Source----------------------------
+/**
+ * @constant
+ * @type {String}
+ */
+cc.SHADEREX_SWITCHMASK_FRAG =
+ "precision lowp float; \n"
+ + "varying vec4 v_fragmentColor; \n"
+ + "varying vec2 v_texCoord; \n"
+ + "uniform sampler2D u_texture; \n"
+ + "uniform sampler2D u_mask; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " vec4 texColor = texture2D(u_texture, v_texCoord); \n"
+ + " vec4 maskColor = texture2D(u_mask, v_texCoord); \n"
+ + " vec4 finalColor = vec4(texColor.r, texColor.g, texColor.b, maskColor.a * texColor.a); \n"
+ + " gl_FragColor = v_fragmentColor * finalColor; \n"
+ + "}";
diff --git a/frameworks/cocos2d-html5/cocos2d/shape-nodes/CCDrawNode.js b/frameworks/cocos2d-html5/cocos2d/shape-nodes/CCDrawNode.js
new file mode 100644
index 0000000..48caafa
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/shape-nodes/CCDrawNode.js
@@ -0,0 +1,1037 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2012 Scott Lembcke and Howling Moon Software
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * CCDrawNode
+ * Node that draws dots, segments and polygons.
+ * Faster than the "drawing primitives" since it draws everything in one single batch.
+ * @class
+ * @name cc.DrawNode
+ * @extends cc.Node
+ */
+cc.DrawNode = cc.Node.extend(/** @lends cc.DrawNode# */{
+//TODO need refactor
+
+ _buffer: null,
+ _blendFunc: null,
+ _lineWidth: 1,
+ _drawColor: null,
+
+ /**
+ * Gets the blend func
+ * @returns {Object}
+ */
+ getBlendFunc: function () {
+ return this._blendFunc;
+ },
+
+ /**
+ * Set the blend func
+ * @param blendFunc
+ * @param dst
+ */
+ setBlendFunc: function (blendFunc, dst) {
+ if (dst === undefined) {
+ this._blendFunc.src = blendFunc.src;
+ this._blendFunc.dst = blendFunc.dst;
+ } else {
+ this._blendFunc.src = blendFunc;
+ this._blendFunc.dst = dst;
+ }
+ },
+
+ /**
+ * line width setter
+ * @param {Number} width
+ */
+ setLineWidth: function (width) {
+ this._lineWidth = width;
+ },
+
+ /**
+ * line width getter
+ * @returns {Number}
+ */
+ getLineWidth: function () {
+ return this._lineWidth;
+ },
+
+ /**
+ * draw color setter
+ * @param {cc.Color} color
+ */
+ setDrawColor: function (color) {
+ var locDrawColor = this._drawColor;
+ locDrawColor.r = color.r;
+ locDrawColor.g = color.g;
+ locDrawColor.b = color.b;
+ locDrawColor.a = (color.a == null) ? 255 : color.a;
+ },
+
+ /**
+ * draw color getter
+ * @returns {cc.Color}
+ */
+ getDrawColor: function () {
+ return cc.color(this._drawColor.r, this._drawColor.g, this._drawColor.b, this._drawColor.a);
+ }
+});
+
+/**
+ * Creates a DrawNode
+ * @deprecated since v3.0 please use `new cc.DrawNode()` instead.
+ * @return {cc.DrawNode}
+ */
+cc.DrawNode.create = function () {
+ return new cc.DrawNode();
+};
+
+cc.DrawNode.TYPE_DOT = 0;
+cc.DrawNode.TYPE_SEGMENT = 1;
+cc.DrawNode.TYPE_POLY = 2;
+
+cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
+
+ function pMultOut(pin, floatVar, pout) {
+ pout.x = pin.x * floatVar;
+ pout.y = pin.y * floatVar;
+ }
+
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
+
+ cc._DrawNodeElement = function (type, verts, fillColor, lineWidth, lineColor, lineCap, isClosePolygon, isFill, isStroke) {
+ var _t = this;
+ _t.type = type;
+ _t.verts = verts || null;
+ _t.fillColor = fillColor || null;
+ _t.lineWidth = lineWidth || 0;
+ _t.lineColor = lineColor || null;
+ _t.lineCap = lineCap || "butt";
+ _t.isClosePolygon = isClosePolygon || false;
+ _t.isFill = isFill || false;
+ _t.isStroke = isStroke || false;
+ };
+
+ cc.extend(cc.DrawNode.prototype, /** @lends cc.DrawNode# */{
+ _className: "DrawNodeCanvas",
+
+ /**
+ * The cc.DrawNodeCanvas's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.DrawNodeCanvas()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor: function () {
+ cc.Node.prototype.ctor.call(this);
+ var locCmd = this._renderCmd;
+ locCmd._buffer = this._buffer = [];
+ locCmd._drawColor = this._drawColor = cc.color(255, 255, 255, 255);
+ locCmd._blendFunc = this._blendFunc = new cc.BlendFunc(cc.SRC_ALPHA, cc.ONE_MINUS_SRC_ALPHA);
+
+ this.init();
+ this._localBB = new cc.Rect();
+ },
+
+ setLocalBB: function (rectorX, y, width, height) {
+ var localBB = this._localBB;
+ if (y === undefined) {
+ localBB.x = rectorX.x;
+ localBB.y = rectorX.y;
+ localBB.width = rectorX.width;
+ localBB.height = rectorX.height;
+ } else {
+ localBB.x = rectorX;
+ localBB.y = y;
+ localBB.width = width;
+ localBB.height = height;
+ }
+ },
+ /**
+ * draws a rectangle given the origin and destination point measured in points.
+ * @param {cc.Point} origin
+ * @param {cc.Point} destination
+ * @param {cc.Color} fillColor
+ * @param {Number} lineWidth
+ * @param {cc.Color} lineColor
+ */
+ drawRect: function (origin, destination, fillColor, lineWidth, lineColor) {
+ lineWidth = (lineWidth == null) ? this._lineWidth : lineWidth;
+ lineColor = lineColor || this.getDrawColor();
+ if (lineColor.a == null)
+ lineColor.a = 255;
+
+ var vertices = [
+ origin,
+ cc.p(destination.x, origin.y),
+ destination,
+ cc.p(origin.x, destination.y)
+ ];
+ var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY);
+ element.verts = vertices;
+ element.lineWidth = lineWidth;
+ element.lineColor = lineColor;
+ element.isClosePolygon = true;
+ element.isStroke = true;
+ element.lineCap = "butt";
+ element.fillColor = fillColor;
+ if (fillColor) {
+ if (fillColor.a == null)
+ fillColor.a = 255;
+ element.isFill = true;
+ }
+ this._buffer.push(element);
+ },
+
+ /**
+ * draws a circle given the center, radius and number of segments.
+ * @override
+ * @param {cc.Point} center center of circle
+ * @param {Number} radius
+ * @param {Number} angle angle in radians
+ * @param {Number} segments
+ * @param {Boolean} drawLineToCenter
+ * @param {Number} lineWidth
+ * @param {cc.Color} color
+ */
+ drawCircle: function (center, radius, angle, segments, drawLineToCenter, lineWidth, color) {
+ lineWidth = lineWidth || this._lineWidth;
+ color = color || this.getDrawColor();
+ if (color.a == null)
+ color.a = 255;
+
+ var coef = 2.0 * Math.PI / segments;
+ var vertices = [];
+ for (var i = 0; i <= segments; i++) {
+ var rads = i * coef;
+ var j = radius * Math.cos(rads + angle) + center.x;
+ var k = radius * Math.sin(rads + angle) + center.y;
+ vertices.push(cc.p(j, k));
+ }
+ if (drawLineToCenter) {
+ vertices.push(cc.p(center.x, center.y));
+ }
+
+ var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY);
+ element.verts = vertices;
+ element.lineWidth = lineWidth;
+ element.lineColor = color;
+ element.isClosePolygon = true;
+ element.isStroke = true;
+ this._buffer.push(element);
+ },
+
+ /**
+ * draws a quad bezier path
+ * @override
+ * @param {cc.Point} origin
+ * @param {cc.Point} control
+ * @param {cc.Point} destination
+ * @param {Number} segments
+ * @param {Number} lineWidth
+ * @param {cc.Color} color
+ */
+ drawQuadBezier: function (origin, control, destination, segments, lineWidth, color) {
+ lineWidth = lineWidth || this._lineWidth;
+ color = color || this.getDrawColor();
+ if (color.a == null)
+ color.a = 255;
+
+ var vertices = [], t = 0.0;
+ for (var i = 0; i < segments; i++) {
+ var x = Math.pow(1 - t, 2) * origin.x + 2.0 * (1 - t) * t * control.x + t * t * destination.x;
+ var y = Math.pow(1 - t, 2) * origin.y + 2.0 * (1 - t) * t * control.y + t * t * destination.y;
+ vertices.push(cc.p(x, y));
+ t += 1.0 / segments;
+ }
+ vertices.push(cc.p(destination.x, destination.y));
+
+ var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY);
+ element.verts = vertices;
+ element.lineWidth = lineWidth;
+ element.lineColor = color;
+ element.isStroke = true;
+ element.lineCap = "round";
+ this._buffer.push(element);
+ },
+
+ /**
+ * draws a cubic bezier path
+ * @override
+ * @param {cc.Point} origin
+ * @param {cc.Point} control1
+ * @param {cc.Point} control2
+ * @param {cc.Point} destination
+ * @param {Number} segments
+ * @param {Number} lineWidth
+ * @param {cc.Color} color
+ */
+ drawCubicBezier: function (origin, control1, control2, destination, segments, lineWidth, color) {
+ lineWidth = lineWidth || this._lineWidth;
+ color = color || this.getDrawColor();
+ if (color.a == null)
+ color.a = 255;
+
+ var vertices = [], t = 0;
+ for (var i = 0; i < segments; i++) {
+ var x = Math.pow(1 - t, 3) * origin.x + 3.0 * Math.pow(1 - t, 2) * t * control1.x + 3.0 * (1 - t) * t * t * control2.x + t * t * t * destination.x;
+ var y = Math.pow(1 - t, 3) * origin.y + 3.0 * Math.pow(1 - t, 2) * t * control1.y + 3.0 * (1 - t) * t * t * control2.y + t * t * t * destination.y;
+ vertices.push(cc.p(x, y));
+ t += 1.0 / segments;
+ }
+ vertices.push(cc.p(destination.x, destination.y));
+
+ var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY);
+ element.verts = vertices;
+ element.lineWidth = lineWidth;
+ element.lineColor = color;
+ element.isStroke = true;
+ element.lineCap = "round";
+ this._buffer.push(element);
+ },
+
+ /**
+ * draw a CatmullRom curve
+ * @override
+ * @param {Array} points
+ * @param {Number} segments
+ * @param {Number} [lineWidth]
+ * @param {cc.Color} [color]
+ */
+ drawCatmullRom: function (points, segments, lineWidth, color) {
+ this.drawCardinalSpline(points, 0.5, segments, lineWidth, color);
+ },
+
+ /**
+ * draw a cardinal spline path
+ * @override
+ * @param {Array} config
+ * @param {Number} tension
+ * @param {Number} segments
+ * @param {Number} [lineWidth]
+ * @param {cc.Color} [color]
+ */
+ drawCardinalSpline: function (config, tension, segments, lineWidth, color) {
+ lineWidth = lineWidth || this._lineWidth;
+ color = color || this.getDrawColor();
+ if (color.a == null)
+ color.a = 255;
+
+ var vertices = [], p, lt, deltaT = 1.0 / config.length;
+ for (var i = 0; i < segments + 1; i++) {
+ var dt = i / segments;
+ // border
+ if (dt === 1) {
+ p = config.length - 1;
+ lt = 1;
+ } else {
+ p = 0 | (dt / deltaT);
+ lt = (dt - deltaT * p) / deltaT;
+ }
+
+ // Interpolate
+ var newPos = cc.cardinalSplineAt(
+ cc.getControlPointAt(config, p - 1),
+ cc.getControlPointAt(config, p - 0),
+ cc.getControlPointAt(config, p + 1),
+ cc.getControlPointAt(config, p + 2),
+ tension, lt);
+ vertices.push(newPos);
+ }
+
+ var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY);
+ element.verts = vertices;
+ element.lineWidth = lineWidth;
+ element.lineColor = color;
+ element.isStroke = true;
+ element.lineCap = "round";
+ this._buffer.push(element);
+ },
+
+ /**
+ * draw a dot at a position, with a given radius and color
+ * @param {cc.Point} pos
+ * @param {Number} radius
+ * @param {cc.Color} [color]
+ */
+ drawDot: function (pos, radius, color) {
+ color = color || this.getDrawColor();
+ if (color.a == null)
+ color.a = 255;
+ var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_DOT);
+ element.verts = [pos];
+ element.lineWidth = radius;
+ element.fillColor = color;
+ this._buffer.push(element);
+ },
+
+ /**
+ * draws an array of points.
+ * @override
+ * @param {Array} points point of array
+ * @param {Number} radius
+ * @param {cc.Color} [color]
+ */
+ drawDots: function (points, radius, color) {
+ if (!points || points.length == 0)
+ return;
+ color = color || this.getDrawColor();
+ if (color.a == null)
+ color.a = 255;
+ for (var i = 0, len = points.length; i < len; i++)
+ this.drawDot(points[i], radius, color);
+ },
+
+ /**
+ * draw a segment with a radius and color
+ * @param {cc.Point} from
+ * @param {cc.Point} to
+ * @param {Number} [lineWidth]
+ * @param {cc.Color} [color]
+ */
+ drawSegment: function (from, to, lineWidth, color) {
+ lineWidth = lineWidth || this._lineWidth;
+ color = color || this.getDrawColor();
+ if (color.a == null)
+ color.a = 255;
+ var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY);
+ element.verts = [from, to];
+ element.lineWidth = lineWidth * 2;
+ element.lineColor = color;
+ element.isStroke = true;
+ element.lineCap = "round";
+ this._buffer.push(element);
+ },
+
+ /**
+ * draw a polygon with a fill color and line color without copying the vertex list
+ * @param {Array} verts
+ * @param {cc.Color|null} fillColor Fill color or `null` for a hollow polygon.
+ * @param {Number} [lineWidth]
+ * @param {cc.Color} [color]
+ */
+ drawPoly_: function (verts, fillColor, lineWidth, color) {
+ lineWidth = (lineWidth == null ) ? this._lineWidth : lineWidth;
+ color = color || this.getDrawColor();
+ if (color.a == null)
+ color.a = 255;
+ var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY);
+
+ element.verts = verts;
+ element.fillColor = fillColor;
+ element.lineWidth = lineWidth;
+ element.lineColor = color;
+ element.isClosePolygon = true;
+ element.isStroke = true;
+ element.lineCap = "round";
+ if (fillColor)
+ element.isFill = true;
+ this._buffer.push(element);
+ },
+
+ /**
+ * draw a polygon with a fill color and line color, copying the vertex list
+ * @param {Array} verts
+ * @param {cc.Color|null} fillColor Fill color or `null` for a hollow polygon.
+ * @param {Number} [lineWidth]
+ * @param {cc.Color} [lineColor]
+ */
+ drawPoly: function (verts, fillColor, lineWidth, lineColor) {
+ var vertsCopy = [];
+ for (var i = 0; i < verts.length; i++) {
+ vertsCopy.push(cc.p(verts[i].x, verts[i].y));
+ }
+ return this.drawPoly_(vertsCopy, fillColor, lineWidth, lineColor);
+ },
+
+ /**
+ * Clear the geometry in the node's buffer.
+ */
+ clear: function () {
+ this._buffer.length = 0;
+ },
+
+ _createRenderCmd: function () {
+ return new cc.DrawNode.CanvasRenderCmd(this);
+ }
+ });
+ }
+ else if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+
+ // 9600 vertices by default configurable in ccConfig.js
+ // 20 is 2 float for position, 4 int for color and 2 float for uv
+ var _sharedBuffer = null;
+ var FLOAT_PER_VERTEX = 2 + 1 + 2;
+ var VERTEX_BYTE = FLOAT_PER_VERTEX * 4;
+ var FLOAT_PER_TRIANGLE = 3 * FLOAT_PER_VERTEX;
+ var TRIANGLE_BYTES = FLOAT_PER_TRIANGLE * 4;
+ var MAX_INCREMENT = 200;
+
+ var _vertices = [],
+ _from = cc.p(),
+ _to = cc.p(),
+ _color = new Uint32Array(1);
+
+ // Used in drawSegment
+ var _n = cc.p(), _t = cc.p(), _nw = cc.p(), _tw = cc.p(),
+ _extrude = [];
+
+ cc.extend(cc.DrawNode.prototype, {
+ _bufferCapacity: 0,
+ _vertexCount: 0,
+
+ _offset: 0,
+ _occupiedSize: 0,
+ _f32Buffer: null,
+ _ui32Buffer: null,
+
+ _dirty: false,
+ _className: "DrawNodeWebGL",
+
+ manualRelease: false,
+
+ ctor: function (capacity, manualRelease) {
+ cc.Node.prototype.ctor.call(this);
+
+ if (!_sharedBuffer) {
+ _sharedBuffer = new GlobalVertexBuffer(cc._renderContext, cc.DRAWNODE_TOTAL_VERTICES * VERTEX_BYTE);
+ }
+
+ this._renderCmd._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_LENGTHTEXTURECOLOR);
+ this._blendFunc = new cc.BlendFunc(cc.SRC_ALPHA, cc.ONE_MINUS_SRC_ALPHA);
+ this._drawColor = cc.color(255, 255, 255, 255);
+
+ this._bufferCapacity = capacity || 64;
+ this.manualRelease = manualRelease;
+
+ this._dirty = true;
+ },
+
+ onEnter: function () {
+ cc.Node.prototype.onEnter.call(this);
+ if (this._occupiedSize < this._bufferCapacity) {
+ this._ensureCapacity(this._bufferCapacity);
+ }
+ },
+
+ onExit: function () {
+ if (!this.manualRelease) {
+ this.release();
+ }
+ cc.Node.prototype.onExit.call(this);
+ },
+
+ release: function () {
+ if (this._occupiedSize > 0) {
+ this._vertexCount = 0;
+ _sharedBuffer.freeBuffer(this._offset, VERTEX_BYTE * this._occupiedSize);
+ this._occupiedSize = 0;
+ }
+ },
+
+ _ensureCapacity: function (count) {
+ var _t = this;
+ var prev = _t._occupiedSize;
+ var prevOffset = _t._offset;
+ if (count > prev || _t._bufferCapacity > prev) {
+ var request = Math.max(Math.min(prev + prev, MAX_INCREMENT), count, _t._bufferCapacity);
+ // free previous buffer
+ if (prev !== 0) {
+ _sharedBuffer.freeBuffer(prevOffset, VERTEX_BYTE * prev);
+ _t._occupiedSize = 0;
+ }
+ var offset = _t._offset = _sharedBuffer.requestBuffer(VERTEX_BYTE * request);
+ if (offset >= 0) {
+ _t._occupiedSize = _t._bufferCapacity = request;
+ // 5 floats per vertex
+ _t._f32Buffer = new Float32Array(_sharedBuffer.data, offset, FLOAT_PER_VERTEX * _t._occupiedSize);
+ _t._ui32Buffer = new Uint32Array(_sharedBuffer.data, offset, FLOAT_PER_VERTEX * _t._occupiedSize);
+
+ // Copy old data
+ if (prev !== 0 && prevOffset !== offset) {
+ // offset is in byte, we need to transform to float32 index
+ var last = prevOffset / 4 + prev * FLOAT_PER_VERTEX;
+ for (var i = offset / 4, j = prevOffset / 4; j < last; i++, j++) {
+ _sharedBuffer.dataArray[i] = _sharedBuffer.dataArray[j];
+ }
+ }
+
+ return true;
+ }
+ else {
+ cc.warn('Failed to allocate buffer for DrawNode: buffer for ' + request + ' vertices requested');
+ return false;
+ }
+ }
+ else {
+ return true;
+ }
+ },
+
+ drawRect: function (origin, destination, fillColor, lineWidth, lineColor) {
+ lineWidth = (lineWidth == null) ? this._lineWidth : lineWidth;
+ lineColor = lineColor || this._drawColor;
+ _vertices.length = 0;
+ _vertices.push(origin.x, origin.y, destination.x, origin.y, destination.x, destination.y, origin.x, destination.y);
+ if (fillColor == null)
+ this._drawSegments(_vertices, lineWidth, lineColor, true);
+ else
+ this.drawPoly(_vertices, fillColor, lineWidth, lineColor);
+ _vertices.length = 0;
+ },
+
+ drawCircle: function (center, radius, angle, segments, drawLineToCenter, lineWidth, color) {
+ lineWidth = lineWidth || this._lineWidth;
+ color = color || this._drawColor;
+ var coef = 2.0 * Math.PI / segments, i, len;
+ _vertices.length = 0;
+ for (i = 0; i <= segments; i++) {
+ var rads = i * coef;
+ var j = radius * Math.cos(rads + angle) + center.x;
+ var k = radius * Math.sin(rads + angle) + center.y;
+ _vertices.push(j, k);
+ }
+ if (drawLineToCenter)
+ _vertices.push(center.x, center.y);
+
+ lineWidth *= 0.5;
+ for (i = 0, len = _vertices.length - 2; i < len; i += 2) {
+ _from.x = _vertices[i];
+ _from.y = _vertices[i + 1];
+ _to.x = _vertices[i + 2];
+ _to.y = _vertices[i + 3];
+ this.drawSegment(_from, _to, lineWidth, color);
+ }
+ _vertices.length = 0;
+ },
+
+ drawQuadBezier: function (origin, control, destination, segments, lineWidth, color) {
+ lineWidth = lineWidth || this._lineWidth;
+ color = color || this._drawColor;
+ var t = 0.0;
+ _vertices.length = 0;
+ for (var i = 0; i < segments; i++) {
+ var x = Math.pow(1 - t, 2) * origin.x + 2.0 * (1 - t) * t * control.x + t * t * destination.x;
+ var y = Math.pow(1 - t, 2) * origin.y + 2.0 * (1 - t) * t * control.y + t * t * destination.y;
+ _vertices.push(x, y);
+ t += 1.0 / segments;
+ }
+ _vertices.push(destination.x, destination.y);
+ this._drawSegments(_vertices, lineWidth, color, false);
+ _vertices.length = 0;
+ },
+
+ drawCubicBezier: function (origin, control1, control2, destination, segments, lineWidth, color) {
+ lineWidth = lineWidth || this._lineWidth;
+ color = color || this._drawColor;
+ var t = 0;
+ _vertices.length = 0;
+ for (var i = 0; i < segments; i++) {
+ var x = Math.pow(1 - t, 3) * origin.x + 3.0 * Math.pow(1 - t, 2) * t * control1.x + 3.0 * (1 - t) * t * t * control2.x + t * t * t * destination.x;
+ var y = Math.pow(1 - t, 3) * origin.y + 3.0 * Math.pow(1 - t, 2) * t * control1.y + 3.0 * (1 - t) * t * t * control2.y + t * t * t * destination.y;
+ _vertices.push(x, y);
+ t += 1.0 / segments;
+ }
+ _vertices.push(destination.x, destination.y);
+ this._drawSegments(_vertices, lineWidth, color, false);
+ _vertices.length = 0;
+ },
+
+ drawCatmullRom: function (points, segments, lineWidth, color) {
+ this.drawCardinalSpline(points, 0.5, segments, lineWidth, color);
+ },
+
+ drawCardinalSpline: function (config, tension, segments, lineWidth, color) {
+ lineWidth = lineWidth || this._lineWidth;
+ color = color || this._drawColor;
+ var p, lt, deltaT = 1.0 / config.length;
+ _vertices.length = 0;
+
+ for (var i = 0; i < segments + 1; i++) {
+ var dt = i / segments;
+
+ // border
+ if (dt === 1) {
+ p = config.length - 1;
+ lt = 1;
+ } else {
+ p = 0 | (dt / deltaT);
+ lt = (dt - deltaT * p) / deltaT;
+ }
+
+ // Interpolate
+ cc.cardinalSplineAt(
+ cc.getControlPointAt(config, p - 1),
+ cc.getControlPointAt(config, p - 0),
+ cc.getControlPointAt(config, p + 1),
+ cc.getControlPointAt(config, p + 2),
+ tension, lt, _from);
+ _vertices.push(_from.x, _from.y);
+ }
+
+ lineWidth *= 0.5;
+ for (var j = 0, len = _vertices.length - 2; j < len; j += 2) {
+ _from.x = _vertices[j];
+ _from.y = _vertices[j + 1];
+ _to.x = _vertices[j + 2];
+ _to.y = _vertices[j + 3];
+ this.drawSegment(_from, _to, lineWidth, color);
+ }
+ _vertices.length = 0;
+ },
+
+ drawDots: function (points, radius, color) {
+ if (!points || points.length === 0)
+ return;
+ color = color || this._drawColor;
+ for (var i = 0, len = points.length; i < len; i++) {
+ this.drawDot(points[i], radius, color);
+ }
+ },
+
+ _render: function () {
+ var gl = cc._renderContext;
+ if (this._offset < 0 || this._vertexCount <= 0) {
+ return;
+ }
+
+ if (this._dirty) {
+ // bindBuffer is done in updateSubData
+ _sharedBuffer.updateSubData(this._offset, this._f32Buffer);
+ this._dirty = false;
+ }
+ else {
+ gl.bindBuffer(gl.ARRAY_BUFFER, _sharedBuffer.vertexBuffer);
+ }
+
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR);
+ gl.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS);
+
+ // vertex
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, gl.FLOAT, false, VERTEX_BYTE, 0);
+ // color
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, VERTEX_BYTE, 8);
+ // texcood
+ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, VERTEX_BYTE, 12);
+
+ gl.drawArrays(gl.TRIANGLES, this._offset / VERTEX_BYTE, this._vertexCount);
+ cc.incrementGLDraws(1);
+ //cc.checkGLErrorDebug();
+ },
+
+ appendVertexData: function (x, y, color, u, v) {
+ var f32Buffer = this._f32Buffer;
+ // Float offset = byte offset / 4 + vertex count * floats by vertex
+ var offset = this._vertexCount * FLOAT_PER_VERTEX;
+ f32Buffer[offset] = x;
+ f32Buffer[offset + 1] = y;
+ _color[0] = ((color.a << 24) | (color.b << 16) | (color.g << 8) | color.r);
+ this._ui32Buffer[offset + 2] = _color[0];
+ f32Buffer[offset + 3] = u;
+ f32Buffer[offset + 4] = v;
+ this._vertexCount++;
+ },
+
+ drawDot: function (pos, radius, color) {
+ color = color || this._drawColor;
+ if (color.a == null)
+ color.a = 255;
+ var l = pos.x - radius,
+ b = pos.y - radius,
+ r = pos.x + radius,
+ t = pos.y + radius;
+
+ var vertexCount = 2 * 3;
+ var succeed = this._ensureCapacity(this._vertexCount + vertexCount);
+ if (!succeed)
+ return;
+
+ // lb, lt, rt, lb, rt, rb
+ this.appendVertexData(l, b, color, -1, -1);
+ this.appendVertexData(l, t, color, -1, 1);
+ this.appendVertexData(r, t, color, 1, 1);
+ this.appendVertexData(l, b, color, -1, -1);
+ this.appendVertexData(r, t, color, 1, 1);
+ this.appendVertexData(r, b, color, 1, -1);
+
+ this._dirty = true;
+ },
+
+ drawSegment: function (from, to, radius, color) {
+ color = color || this.getDrawColor();
+ if (color.a == null)
+ color.a = 255;
+ radius = radius || (this._lineWidth * 0.5);
+ var vertexCount = 6 * 3;
+ var succeed = this._ensureCapacity(this._vertexCount + vertexCount);
+ if (!succeed)
+ return;
+
+ var a = from, b = to;
+ // var n = normalize(perp(sub(b, a)))
+ _n.x = a.y - b.y; _n.y = b.x - a.x;
+ cc.pNormalizeIn(_n);
+ // var t = perp(n);
+ _t.x = -_n.y; _t.y = _n.x;
+ // var nw = mult(n, radius), tw = mult(t, radius);
+ pMultOut(_n, radius, _nw);
+ pMultOut(_t, radius, _tw);
+
+ // var v0 = sub(b, add(nw, tw)); uv0 = neg(add(n, t))
+ var v0x = b.x - _nw.x - _tw.x, v0y = b.y - _nw.y - _tw.y, u0 = -(_n.x + _t.x), v0 = -(_n.y + _t.y);
+ // var v1 = add(b, sub(nw, tw)); uv1 = sub(n, t)
+ var v1x = b.x + _nw.x - _tw.x, v1y = b.y + _nw.y - _tw.y, u1 = _n.x - _t.x, v1 = _n.y - _t.y;
+ // var v2 = sub(b, nw); uv2 = neg(n)
+ var v2x = b.x - _nw.x, v2y = b.y - _nw.y, u2 = -_n.x, v2 = -_n.y;
+ // var v3 = add(b, nw); uv3 = n
+ var v3x = b.x + _nw.x, v3y = b.y + _nw.y, u3 = _n.x, v3 = _n.y;
+ // var v4 = sub(a, nw); uv4 = neg(n)
+ var v4x = a.x - _nw.x, v4y = a.y - _nw.y, u4 = u2, v4 = v2;
+ // var v5 = add(a, nw); uv5 = n
+ var v5x = a.x + _nw.x, v5y = a.y + _nw.y, u5 = _n.x, v5 = _n.y;
+ // var v6 = sub(a, sub(nw, tw)); uv6 = sub(t, n)
+ var v6x = a.x - _nw.x + _tw.x, v6y = a.y - _nw.y + _tw.y, u6 = _t.x - _n.x, v6 = _t.y - _n.y;
+ // var v7 = add(a, add(nw, tw)); uv7 = add(n, t)
+ var v7x = a.x + _nw.x + _tw.x, v7y = a.y + _nw.y + _tw.y, u7 = _n.x + _t.x, v7 = _n.y + _t.y;
+
+ this.appendVertexData(v0x, v0y, color, u0, v0);
+ this.appendVertexData(v1x, v1y, color, u1, v1);
+ this.appendVertexData(v2x, v2y, color, u2, v2);
+
+ this.appendVertexData(v3x, v3y, color, u3, v3);
+ this.appendVertexData(v1x, v1y, color, u1, v1);
+ this.appendVertexData(v2x, v2y, color, u2, v2);
+
+ this.appendVertexData(v3x, v3y, color, u3, v3);
+ this.appendVertexData(v4x, v4y, color, u4, v4);
+ this.appendVertexData(v2x, v2y, color, u2, v2);
+
+ this.appendVertexData(v3x, v3y, color, u3, v3);
+ this.appendVertexData(v4x, v4y, color, u4, v4);
+ this.appendVertexData(v5x, v5y, color, u5, v5);
+
+ this.appendVertexData(v6x, v6y, color, u6, v6);
+ this.appendVertexData(v4x, v4y, color, u4, v4);
+ this.appendVertexData(v5x, v5y, color, u5, v5);
+
+ this.appendVertexData(v6x, v6y, color, u6, v6);
+ this.appendVertexData(v7x, v7y, color, u7, v7);
+ this.appendVertexData(v5x, v5y, color, u5, v5);
+ this._dirty = true;
+ },
+
+ drawPoly: function (verts, fillColor, borderWidth, borderColor) {
+ // Backward compatibility
+ if (typeof verts[0] === 'object') {
+ _vertices.length = 0;
+ for (var i = 0; i < verts.length; i++) {
+ _vertices.push(verts[i].x, verts[i].y);
+ }
+ verts = _vertices;
+ }
+
+ if (fillColor == null) {
+ this._drawSegments(verts, borderWidth, borderColor, true);
+ return;
+ }
+ if (fillColor.a == null)
+ fillColor.a = 255;
+ if (borderColor.a == null)
+ borderColor.a = 255;
+ borderWidth = (borderWidth == null) ? this._lineWidth : borderWidth;
+ borderWidth *= 0.5;
+ var v0x, v0y, v1x, v1y, v2x, v2y,
+ factor, offx, offy,
+ i, count = verts.length;
+ _extrude.length = 0;
+ for (i = 0; i < count; i += 2) {
+ v0x = verts[(i - 2 + count) % count];
+ v0y = verts[(i - 1 + count) % count];
+ v1x = verts[i];
+ v1y = verts[i + 1];
+ v2x = verts[(i + 2) % count];
+ v2y = verts[(i + 3) % count];
+ // var n1 = normalize(perp(sub(v1, v0)));
+ // var n2 = normalize(perp(sub(v2, v1)));
+ _n.x = v0y - v1y; _n.y = v1x - v0x;
+ _nw.x = v1y - v2y; _nw.y = v2x - v1x;
+ cc.pNormalizeIn(_n);
+ cc.pNormalizeIn(_nw);
+ // var offset = mult(add(n1, n2), 1.0 / (dot(n1, n2) + 1.0));
+ factor = _n.x * _nw.x + _n.y * _nw.y + 1;
+ offx = (_n.x + _nw.x) / factor;
+ offy = (_n.y + _nw.y) / factor;
+ // extrude[i] = {offset: offset, n: n2};
+ _extrude.push(offx, offy, _nw.x, _nw.y);
+ }
+ // The actual input vertex count
+ count = count / 2;
+ var outline = (borderWidth > 0.0), triangleCount = 3 * count - 2, vertexCount = 3 * triangleCount;
+ var succeed = this._ensureCapacity(this._vertexCount + vertexCount);
+ if (!succeed)
+ return;
+
+ var inset = (outline == false ? 0.5 : 0.0);
+ for (i = 0; i < count - 2; i++) {
+ // v0 = sub(verts[0], multi(extrude[0].offset, inset));
+ v0x = verts[0] - _extrude[0] * inset;
+ v0y = verts[1] - _extrude[1] * inset;
+ // v1 = sub(verts[i + 1], multi(extrude[i + 1].offset, inset));
+ v1x = verts[i * 2 + 2] - _extrude[(i + 1) * 4] * inset;
+ v1y = verts[i * 2 + 3] - _extrude[(i + 1) * 4 + 1] * inset;
+ // v2 = sub(verts[i + 2], multi(extrude[i + 2].offset, inset));
+ v2x = verts[i * 2 + 4] - _extrude[(i + 2) * 4] * inset;
+ v2y = verts[i * 2 + 5] - _extrude[(i + 2) * 4 + 1] * inset;
+
+ this.appendVertexData(v0x, v0y, fillColor, 0, 0);
+ this.appendVertexData(v1x, v1y, fillColor, 0, 0);
+ this.appendVertexData(v2x, v2y, fillColor, 0, 0);
+ }
+
+ var off0x, off0y, off1x, off1y,
+ bw = outline ? borderWidth : 0.5,
+ color = outline ? borderColor : fillColor,
+ in0x, in0y, in1x, in1y, out0x, out0y, out1x, out1y;
+ for (i = 0; i < count; i++) {
+ var j = (i + 1) % count;
+ v0x = verts[i * 2];
+ v0y = verts[i * 2 + 1];
+ v1x = verts[j * 2];
+ v1y = verts[j * 2 + 1];
+
+ _n.x = _extrude[i * 4 + 2];
+ _n.y = _extrude[i * 4 + 3];
+ _nw.x = outline ? -_n.x : 0;
+ _nw.y = outline ? -_n.y : 0;
+ off0x = _extrude[i * 4];
+ off0y = _extrude[i * 4 + 1];
+ off1x = _extrude[j * 4];
+ off1y = _extrude[j * 4 + 1];
+
+ in0x = v0x - off0x * bw; in0y = v0y - off0y * bw;
+ in1x = v1x - off1x * bw; in1y = v1y - off1y * bw;
+ out0x = v0x + off0x * bw; out0y = v0y + off0y * bw;
+ out1x = v1x + off1x * bw; out1y = v1y + off1y * bw;
+
+ this.appendVertexData(in0x, in0y, color, _nw.x, _nw.y);
+ this.appendVertexData(in1x, in1y, color, _nw.x, _nw.y);
+ this.appendVertexData(out1x, out1y, color, _n.x, _n.y);
+
+ this.appendVertexData(in0x, in0y, color, _nw.x, _nw.y);
+ this.appendVertexData(out0x, out0y, color, _n.x, _n.y);
+ this.appendVertexData(out1x, out1y, color, _n.x, _n.y);
+ }
+ _extrude.length = 0;
+ _vertices.length = 0;
+ this._dirty = true;
+ },
+
+ _drawSegments: function (verts, borderWidth, borderColor, closePoly) {
+ borderWidth = (borderWidth == null) ? this._lineWidth : borderWidth;
+ if (borderWidth <= 0)
+ return;
+
+ borderColor = borderColor || this._drawColor;
+ if (borderColor.a == null)
+ borderColor.a = 255;
+ borderWidth *= 0.5;
+
+ var v0x, v0y, v1x, v1y, v2x, v2y,
+ factor, offx, offy,
+ i, count = verts.length;
+ _extrude.length = 0;
+ for (i = 0; i < count; i += 2) {
+ v0x = verts[(i - 2 + count) % count];
+ v0y = verts[(i - 1 + count) % count];
+ v1x = verts[i];
+ v1y = verts[i + 1];
+ v2x = verts[(i + 2) % count];
+ v2y = verts[(i + 3) % count];
+ // var n1 = normalize(perp(sub(v1, v0)));
+ // var n2 = normalize(perp(sub(v2, v1)));
+ _n.x = v0y - v1y; _n.y = v1x - v0x;
+ _nw.x = v1y - v2y; _nw.y = v2x - v1x;
+ cc.pNormalizeIn(_n);
+ cc.pNormalizeIn(_nw);
+ // var offset = multi(add(n1, n2), 1.0 / (dot(n1, n2) + 1.0));
+ factor = _n.x * _nw.x + _n.y * _nw.y + 1;
+ offx = (_n.x + _nw.x) / factor;
+ offy = (_n.y + _nw.y) / factor;
+ // extrude[i] = {offset: offset, n: n2};
+ _extrude.push(offx, offy, _nw.x, _nw.y);
+ }
+
+ // The actual input vertex count
+ count = count / 2;
+ var triangleCount = 3 * count - 2, vertexCount = 3 * triangleCount;
+ var succeed = this._ensureCapacity(this._vertexCount + vertexCount);
+ if (!succeed)
+ return;
+
+ var len = closePoly ? count : count - 1,
+ off0x, off0y, off1x, off1y,
+ in0x, in0y, in1x, in1y, out0x, out0y, out1x, out1y;
+ for (i = 0; i < len; i++) {
+ var j = (i + 1) % count;
+ v0x = verts[i * 2];
+ v0y = verts[i * 2 + 1];
+ v1x = verts[j * 2];
+ v1y = verts[j * 2 + 1];
+
+ _n.x = _extrude[i * 4 + 2];
+ _n.y = _extrude[i * 4 + 3];
+ off0x = _extrude[i * 4];
+ off0y = _extrude[i * 4 + 1];
+ off1x = _extrude[j * 4];
+ off1y = _extrude[j * 4 + 1];
+ in0x = v0x - off0x * borderWidth; in0y = v0y - off0y * borderWidth;
+ in1x = v1x - off1x * borderWidth; in1y = v1y - off1y * borderWidth;
+ out0x = v0x + off0x * borderWidth; out0y = v0y + off0y * borderWidth;
+ out1x = v1x + off1x * borderWidth; out1y = v1y + off1y * borderWidth;
+
+ this.appendVertexData(in0x, in0y, borderColor, -_n.x, -_n.y);
+ this.appendVertexData(in1x, in1y, borderColor, -_n.x, -_n.y);
+ this.appendVertexData(out1x, out1y, borderColor, _n.x, _n.y);
+
+ this.appendVertexData(in0x, in0y, borderColor, -_n.x, -_n.y);
+ this.appendVertexData(out0x, out0y, borderColor, _n.x, _n.y);
+ this.appendVertexData(out1x, out1y, borderColor, _n.x, _n.y);
+ }
+ _extrude.length = 0;
+ this._dirty = true;
+ },
+
+ clear: function () {
+ this.release();
+ this._dirty = true;
+ },
+
+ _createRenderCmd: function () {
+ return new cc.DrawNode.WebGLRenderCmd(this);
+ }
+ });
+ }
+});
diff --git a/frameworks/cocos2d-html5/cocos2d/shape-nodes/CCDrawNodeCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/shape-nodes/CCDrawNodeCanvasRenderCmd.js
new file mode 100644
index 0000000..9218945
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/shape-nodes/CCDrawNodeCanvasRenderCmd.js
@@ -0,0 +1,138 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+
+ cc.DrawNode.CanvasRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+ this._buffer = null;
+ this._drawColor = null;
+ this._blendFunc = null;
+ };
+
+
+ cc.DrawNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ cc.DrawNode.CanvasRenderCmd.prototype.constructor = cc.DrawNode.CanvasRenderCmd;
+
+ cc.DrawNode.CanvasRenderCmd.prototype.getLocalBB = function () {
+ var node = this._node;
+ return node._localBB;
+ };
+
+ cc.extend(cc.DrawNode.CanvasRenderCmd.prototype, {
+ rendering: function (ctx, scaleX, scaleY) {
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext(), node = this._node;
+ var alpha = this._displayedOpacity / 255;
+ if (alpha === 0)
+ return;
+
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+
+ //context.save();
+ wrapper.setGlobalAlpha(alpha);
+ if ((this._blendFunc && (this._blendFunc.src === cc.SRC_ALPHA) && (this._blendFunc.dst === cc.ONE)))
+ wrapper.setCompositeOperation('lighter'); //todo: need refactor
+ var locBuffer = this._buffer;
+ for (var i = 0, len = locBuffer.length; i < len; i++) {
+ var element = locBuffer[i];
+ switch (element.type) {
+ case cc.DrawNode.TYPE_DOT:
+ this._drawDot(wrapper, element, scaleX, scaleY);
+ break;
+ case cc.DrawNode.TYPE_SEGMENT:
+ this._drawSegment(wrapper, element, scaleX, scaleY);
+ break;
+ case cc.DrawNode.TYPE_POLY:
+ this._drawPoly(wrapper, element, scaleX, scaleY);
+ break;
+ }
+ }
+ //context.restore(); //todo It can be reserve
+ },
+
+ _drawDot: function (wrapper, element) {
+ var locColor = element.fillColor, locPos = element.verts[0], locRadius = element.lineWidth;
+
+ var ctx = wrapper.getContext();
+ wrapper.setFillStyle("rgba(" + (0 | locColor.r) + "," + (0 | locColor.g) + "," + (0 | locColor.b) + "," + locColor.a / 255 + ")");
+
+ ctx.beginPath();
+ ctx.arc(locPos.x, -locPos.y, locRadius, 0, Math.PI * 2, false);
+ ctx.closePath();
+ ctx.fill();
+ },
+
+ _drawSegment: function (wrapper, element, scaleX) {
+ var locColor = element.lineColor;
+ var locFrom = element.verts[0], locTo = element.verts[1];
+ var locLineWidth = element.lineWidth, locLineCap = element.lineCap;
+
+ var ctx = wrapper.getContext();
+ wrapper.setStrokeStyle("rgba(" + (0 | locColor.r) + "," + (0 | locColor.g) + "," + (0 | locColor.b) + "," + locColor.a / 255 + ")");
+
+ ctx.lineWidth = locLineWidth * scaleX;
+ ctx.beginPath();
+ ctx.lineCap = locLineCap;
+ ctx.moveTo(locFrom.x, -locFrom.y);
+ ctx.lineTo(locTo.x, -locTo.y);
+ ctx.stroke();
+ },
+
+ _drawPoly: function (wrapper, element, scaleX) {
+ var locVertices = element.verts, locLineCap = element.lineCap;
+ if (locVertices == null)
+ return;
+
+ var locFillColor = element.fillColor, locLineWidth = element.lineWidth;
+ var locLineColor = element.lineColor, locIsClosePolygon = element.isClosePolygon;
+ var locIsFill = element.isFill, locIsStroke = element.isStroke;
+
+ var ctx = wrapper.getContext();
+ var firstPoint = locVertices[0];
+ ctx.lineCap = locLineCap;
+ if (locFillColor)
+ wrapper.setFillStyle("rgba(" + (0 | locFillColor.r) + "," + (0 | locFillColor.g) + ","
+ + (0 | locFillColor.b) + "," + locFillColor.a / 255 + ")");
+ if (locLineWidth)
+ ctx.lineWidth = locLineWidth * scaleX;
+ if (locLineColor)
+ wrapper.setStrokeStyle("rgba(" + (0 | locLineColor.r) + "," + (0 | locLineColor.g) + ","
+ + (0 | locLineColor.b) + "," + locLineColor.a / 255 + ")");
+
+ ctx.beginPath();
+ ctx.moveTo(firstPoint.x, -firstPoint.y);
+ for (var i = 1, len = locVertices.length; i < len; i++)
+ ctx.lineTo(locVertices[i].x, -locVertices[i].y);
+
+ if (locIsClosePolygon)
+ ctx.closePath();
+ if (locIsFill)
+ ctx.fill();
+ if (locIsStroke)
+ ctx.stroke();
+ }
+ });
+
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js
new file mode 100644
index 0000000..cd7ea51
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js
@@ -0,0 +1,52 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ cc.DrawNode.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+ };
+
+ cc.DrawNode.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ cc.DrawNode.WebGLRenderCmd.prototype.constructor = cc.DrawNode.WebGLRenderCmd;
+
+ cc.DrawNode.WebGLRenderCmd.prototype.rendering = function (ctx) {
+ var node = this._node;
+ if (node._vertexCount > 0) {
+ var wt = this._worldTransform;
+ this._matrix.mat[0] = wt.a;
+ this._matrix.mat[4] = wt.c;
+ this._matrix.mat[12] = wt.tx;
+ this._matrix.mat[1] = wt.b;
+ this._matrix.mat[5] = wt.d;
+ this._matrix.mat[13] = wt.ty;
+
+ cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
+ this._glProgramState.apply(this._matrix);
+ node._render();
+ }
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/text-input/CCIMEDispatcher.js b/frameworks/cocos2d-html5/cocos2d/text-input/CCIMEDispatcher.js
new file mode 100644
index 0000000..e22f6da
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/text-input/CCIMEDispatcher.js
@@ -0,0 +1,535 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * IME Keyboard Notification Info structure
+ * @param {cc.Rect} begin the soft keyboard rectangle when animatin begin
+ * @param {cc.Rect} end the soft keyboard rectangle when animatin end
+ * @param {Number} duration the soft keyboard animation duration
+ */
+cc.IMEKeyboardNotificationInfo = function (begin, end, duration) {
+ this.begin = begin || cc.rect(0, 0, 0, 0);
+ this.end = end || cc.rect(0, 0, 0, 0);
+ this.duration = duration || 0;
+};
+
+/**
+ * Input method editor delegate.
+ * @class
+ * @extends cc.Class
+ */
+cc.IMEDelegate = cc.Class.extend(/** @lends cc.IMEDelegate# */{
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor: function () {
+ cc.imeDispatcher.addDelegate(this);
+ },
+ /**
+ * Remove delegate
+ */
+ removeDelegate: function () {
+ cc.imeDispatcher.removeDelegate(this);
+ },
+ /**
+ * Remove delegate
+ * @return {Boolean}
+ */
+ attachWithIME: function () {
+ return cc.imeDispatcher.attachDelegateWithIME(this);
+ },
+ /**
+ * Detach with IME
+ * @return {Boolean}
+ */
+ detachWithIME: function () {
+ return cc.imeDispatcher.detachDelegateWithIME(this);
+ },
+
+ /**
+ * Decide the delegate instance is ready for receive ime message or not.
+ * Called by CCIMEDispatcher.
+ * @return {Boolean}
+ */
+ canAttachWithIME: function () {
+ return false;
+ },
+
+ /**
+ * When the delegate detach with IME, this method call by CCIMEDispatcher.
+ */
+ didAttachWithIME: function () {
+ },
+
+ /**
+ * Decide the delegate instance can stop receive ime message or not.
+ * @return {Boolean}
+ */
+ canDetachWithIME: function () {
+ return false;
+ },
+
+ /**
+ * When the delegate detach with IME, this method call by CCIMEDispatcher.
+ */
+ didDetachWithIME: function () {
+ },
+
+ /**
+ * Called by CCIMEDispatcher when some text input from IME.
+ */
+ insertText: function (text, len) {
+ },
+
+ /**
+ * Called by CCIMEDispatcher when user clicked the backward key.
+ */
+ deleteBackward: function () {
+ },
+
+ /**
+ * Called by CCIMEDispatcher for get text which delegate already has.
+ * @return {String}
+ */
+ getContentText: function () {
+ return "";
+ },
+
+ //////////////////////////////////////////////////////////////////////////
+ // keyboard show/hide notification
+ //////////////////////////////////////////////////////////////////////////
+ keyboardWillShow: function (info) {
+ },
+ keyboardDidShow: function (info) {
+ },
+ keyboardWillHide: function (info) {
+ },
+ keyboardDidHide: function (info) {
+ }
+});
+
+/**
+ * cc.imeDispatcher is a singleton object which manage input message dispatching.
+ * @class
+ * @name cc.imeDispatcher
+ */
+cc.IMEDispatcher = cc.Class.extend(/** @lends cc.imeDispatcher# */{
+ _domInputControl: null,
+ impl: null,
+ _currentInputString: "",
+ _lastClickPosition: null,
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor: function () {
+ this.impl = new cc.IMEDispatcher.Impl();
+ this._lastClickPosition = cc.p(0, 0);
+ },
+
+ init: function () {
+ if (cc.sys.isMobile)
+ return;
+ this._domInputControl = cc.$("#imeDispatcherInput");
+ if (!this._domInputControl) {
+ this._domInputControl = cc.$new("input");
+ this._domInputControl.setAttribute("type", "text");
+ this._domInputControl.setAttribute("id", "imeDispatcherInput");
+ this._domInputControl.resize(0.0, 0.0);
+ this._domInputControl.translates(0, 0);
+ this._domInputControl.style.opacity = "0";
+ //this._domInputControl.style.filter = "alpha(opacity = 0)";
+ this._domInputControl.style.fontSize = "1px";
+ this._domInputControl.setAttribute('tabindex', 2);
+ this._domInputControl.style.position = "absolute";
+ this._domInputControl.style.top = 0;
+ this._domInputControl.style.left = 0;
+ document.body.appendChild(this._domInputControl);
+ }
+ var selfPointer = this;
+ //add event listener
+ this._domInputControl.addEventListener("input", function () {
+ selfPointer._processDomInputString(selfPointer._domInputControl.value);
+ }, false);
+ this._domInputControl.addEventListener("keydown", function (e) {
+ // ignore tab key
+ if (e.keyCode === cc.KEY.tab) {
+ e.stopPropagation();
+ e.preventDefault();
+ } else if (e.keyCode === cc.KEY.enter) {
+ selfPointer.dispatchInsertText("\n", 1);
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ }, false);
+
+ if (/msie/i.test(navigator.userAgent)) {
+ this._domInputControl.addEventListener("keyup", function (e) {
+ if (e.keyCode === cc.KEY.backspace) {
+ selfPointer._processDomInputString(selfPointer._domInputControl.value);
+ }
+ }, false);
+ }
+
+ window.addEventListener('mousedown', function (event) {
+ var tx = event.pageX || 0;
+ var ty = event.pageY || 0;
+
+ selfPointer._lastClickPosition.x = tx;
+ selfPointer._lastClickPosition.y = ty;
+ }, false);
+ },
+
+ _processDomInputString: function (text) {
+ var i, startPos;
+ var len = this._currentInputString.length < text.length ? this._currentInputString.length : text.length;
+ for (startPos = 0; startPos < len; startPos++) {
+ if (text[startPos] !== this._currentInputString[startPos])
+ break;
+ }
+ var delTimes = this._currentInputString.length - startPos;
+ var insTimes = text.length - startPos;
+ for (i = 0; i < delTimes; i++)
+ this.dispatchDeleteBackward();
+
+ for (i = 0; i < insTimes; i++)
+ this.dispatchInsertText(text[startPos + i], 1);
+
+ this._currentInputString = text;
+ },
+
+ /**
+ * Dispatch the input text from ime
+ * @param {String} text
+ * @param {Number} len
+ */
+ dispatchInsertText: function (text, len) {
+ if (!this.impl || !text || len <= 0)
+ return;
+
+ // there is no delegate attach with ime
+ if (!this.impl._delegateWithIme)
+ return;
+
+ this.impl._delegateWithIme.insertText(text, len);
+ },
+
+ /**
+ * Dispatch the delete backward operation
+ */
+ dispatchDeleteBackward: function () {
+ if (!this.impl) {
+ return;
+ }
+
+ // there is no delegate attach with ime
+ if (!this.impl._delegateWithIme)
+ return;
+
+ this.impl._delegateWithIme.deleteBackward();
+ },
+
+ /**
+ * Get the content text, which current CCIMEDelegate which attached with IME has.
+ * @return {String}
+ */
+ getContentText: function () {
+ if (this.impl && this.impl._delegateWithIme) {
+ var pszContentText = this.impl._delegateWithIme.getContentText();
+ return (pszContentText) ? pszContentText : "";
+ }
+ return "";
+ },
+
+ /**
+ * Dispatch keyboard notification
+ * @param {cc.IMEKeyboardNotificationInfo} info
+ */
+ dispatchKeyboardWillShow: function (info) {
+ if (this.impl) {
+ for (var i = 0; i < this.impl._delegateList.length; i++) {
+ var delegate = this.impl._delegateList[i];
+ if (delegate) {
+ delegate.keyboardWillShow(info);
+ }
+ }
+ }
+ },
+
+ /**
+ * Dispatch keyboard notification
+ * @param {cc.IMEKeyboardNotificationInfo} info
+ */
+ dispatchKeyboardDidShow: function (info) {
+ if (this.impl) {
+ for (var i = 0; i < this.impl._delegateList.length; i++) {
+ var delegate = this.impl._delegateList[i];
+ if (delegate)
+ delegate.keyboardDidShow(info);
+ }
+ }
+ },
+
+ /**
+ * Dispatch keyboard notification
+ * @param {cc.IMEKeyboardNotificationInfo} info
+ */
+ dispatchKeyboardWillHide: function (info) {
+ if (this.impl) {
+ for (var i = 0; i < this.impl._delegateList.length; i++) {
+ var delegate = this.impl._delegateList[i];
+ if (delegate) {
+ delegate.keyboardWillHide(info);
+ }
+ }
+ }
+ },
+
+ /**
+ * Dispatch keyboard notification
+ * @param {cc.IMEKeyboardNotificationInfo} info
+ */
+ dispatchKeyboardDidHide: function (info) {
+ if (this.impl) {
+ for (var i = 0; i < this.impl._delegateList.length; i++) {
+ var delegate = this.impl._delegateList[i];
+ if (delegate) {
+ delegate.keyboardDidHide(info);
+ }
+ }
+ }
+ },
+
+ /**
+ * Add delegate to concern ime msg
+ * @param {cc.IMEDelegate} delegate
+ * @example
+ * //example
+ * cc.imeDispatcher.addDelegate(this);
+ */
+ addDelegate: function (delegate) {
+ if (!delegate || !this.impl)
+ return;
+
+ if (this.impl._delegateList.indexOf(delegate) > -1) {
+ // delegate already in list
+ return;
+ }
+ this.impl._delegateList.splice(0, 0, delegate);
+ },
+
+ /**
+ * Attach the pDeleate with ime.
+ * @param {cc.IMEDelegate} delegate
+ * @return {Boolean} If the old delegate can detattach with ime and the new delegate can attach with ime, return true, otherwise return false.
+ * @example
+ * //example
+ * var ret = cc.imeDispatcher.attachDelegateWithIME(this);
+ */
+ attachDelegateWithIME: function (delegate) {
+ if (!this.impl || !delegate)
+ return false;
+
+ // if delegate is not in delegate list, return
+ if (this.impl._delegateList.indexOf(delegate) === -1)
+ return false;
+
+ if (this.impl._delegateWithIme) {
+ // if old delegate canDetachWithIME return false
+ // or delegate canAttachWithIME return false,
+ // do nothing.
+ if (!this.impl._delegateWithIme.canDetachWithIME()
+ || !delegate.canAttachWithIME())
+ return false;
+
+ // detach first
+ var pOldDelegate = this.impl._delegateWithIme;
+ this.impl._delegateWithIme = null;
+ pOldDelegate.didDetachWithIME();
+
+ this._focusDomInput(delegate);
+ return true;
+ }
+
+ // havn't delegate attached with IME yet
+ if (!delegate.canAttachWithIME())
+ return false;
+
+ this._focusDomInput(delegate);
+ return true;
+ },
+
+ _focusDomInput: function (delegate) {
+ if (cc.sys.isMobile) {
+ this.impl._delegateWithIme = delegate;
+ delegate.didAttachWithIME();
+ //prompt
+ this._currentInputString = delegate.string || "";
+
+ var tipMessage = delegate.getTipMessage ? delegate.getTipMessage() : "please enter your word:";
+ // wechat cover the prompt function .So need use the Window.prototype.prompt
+ var userInput;
+ var win = window.Window;
+ if (win && win.prototype.prompt && win.prototype.prompt != prompt) {
+ userInput = win.prototype.prompt.call(window, tipMessage, this._currentInputString);
+ } else {
+ userInput = prompt(tipMessage, this._currentInputString);
+ }
+ if (userInput != null)
+ this._processDomInputString(userInput);
+ this.dispatchInsertText("\n", 1);
+ } else {
+ this.impl._delegateWithIme = delegate;
+ this._currentInputString = delegate.string || "";
+ delegate.didAttachWithIME();
+ this._domInputControl.focus();
+ this._domInputControl.value = this._currentInputString;
+ this._domInputControlTranslate();
+ }
+ },
+
+ _domInputControlTranslate: function () {
+ if (/msie/i.test(navigator.userAgent)) {
+ this._domInputControl.style.left = this._lastClickPosition.x + "px";
+ this._domInputControl.style.top = this._lastClickPosition.y + "px";
+ } else {
+ this._domInputControl.translates(this._lastClickPosition.x, this._lastClickPosition.y);
+ }
+ },
+
+ /**
+ * Detach the pDeleate with ime.
+ * @param {cc.IMEDelegate} delegate
+ * @return {Boolean} If the old delegate can detattach with ime and the new delegate can attach with ime, return true, otherwise return false.
+ * @example
+ * //example
+ * var ret = cc.imeDispatcher.detachDelegateWithIME(this);
+ */
+ detachDelegateWithIME: function (delegate) {
+ if (!this.impl || !delegate)
+ return false;
+
+ // if delegate is not the current delegate attached with ime, return
+ if (this.impl._delegateWithIme !== delegate)
+ return false;
+
+ if (!delegate.canDetachWithIME())
+ return false;
+
+ this.impl._delegateWithIme = null;
+ delegate.didDetachWithIME();
+ cc._canvas.focus();
+ return true;
+ },
+
+ /**
+ * Remove the delegate from the delegates who concern ime msg
+ * @param {cc.IMEDelegate} delegate
+ * @example
+ * //example
+ * cc.imeDispatcher.removeDelegate(this);
+ */
+ removeDelegate: function (delegate) {
+ if (!this.impl || !delegate)
+ return;
+
+ // if delegate is not in delegate list, return
+ if (this.impl._delegateList.indexOf(delegate) === -1)
+ return;
+
+ if (this.impl._delegateWithIme) {
+ if (delegate === this.impl._delegateWithIme) {
+ this.impl._delegateWithIme = null;
+ }
+ }
+ cc.arrayRemoveObject(this.impl._delegateList, delegate);
+ },
+
+ /**
+ * Process keydown's keycode
+ * @param {Number} keyCode
+ * @example
+ * //example
+ * document.addEventListener("keydown", function (e) {
+ * cc.imeDispatcher.processKeycode(e.keyCode);
+ * });
+ */
+ processKeycode: function (keyCode) {
+ if (keyCode < 32) {
+ if (keyCode === cc.KEY.backspace) {
+ this.dispatchDeleteBackward();
+ } else if (keyCode === cc.KEY.enter) {
+ this.dispatchInsertText("\n", 1);
+ } else if (keyCode === cc.KEY.tab) {
+ //tab input
+ } else if (keyCode === cc.KEY.escape) {
+ //ESC input
+ }
+ } else if (keyCode < 255) {
+ this.dispatchInsertText(String.fromCharCode(keyCode), 1);
+ } else {
+ //
+ }
+ }
+});
+
+/**
+ * Create the cc.IMEDispatcher.Imp Object.
+ * This is the inner class...
+ * @class
+ * @extends cc.Class
+ * @name cc.IMEDispatcher.Impl
+ */
+cc.IMEDispatcher.Impl = cc.Class.extend(/** @lends cc.IMEDispatcher.Impl# */{
+ _delegateWithIme: null,
+ _delegateList: null,
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor: function () {
+ this._delegateList = [];
+ },
+ /**
+ * Find delegate
+ * @param {cc.IMEDelegate} delegate
+ * @return {Number|Null}
+ */
+ findDelegate: function (delegate) {
+ for (var i = 0; i < this._delegateList.length; i++) {
+ if (this._delegateList[i] === delegate)
+ return i;
+ }
+ return null;
+ }
+});
+
+// Initialize imeDispatcher singleton
+cc.imeDispatcher = new cc.IMEDispatcher();
+
+document.body ?
+ cc.imeDispatcher.init() :
+ window.addEventListener('load', function () {
+ cc.imeDispatcher.init();
+ }, false);
diff --git a/frameworks/cocos2d-html5/cocos2d/text-input/CCTextFieldTTF.js b/frameworks/cocos2d-html5/cocos2d/text-input/CCTextFieldTTF.js
new file mode 100644
index 0000000..c582afb
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/text-input/CCTextFieldTTF.js
@@ -0,0 +1,492 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Text field delegate
+ * @class
+ * @extends cc.Class
+ */
+cc.TextFieldDelegate = cc.Class.extend(/** @lends cc.TextFieldDelegate# */{
+ /**
+ * If the sender doesn't want to attach with IME, return true;
+ * @param {cc.TextFieldTTF} sender
+ * @return {Boolean}
+ */
+ onTextFieldAttachWithIME: function (sender) {
+ return false;
+ },
+
+ /**
+ * If the sender doesn't want to detach with IME, return true;
+ * @param {cc.TextFieldTTF} sender
+ * @return {Boolean}
+ */
+ onTextFieldDetachWithIME: function (sender) {
+ return false;
+ },
+
+ /**
+ * If the sender doesn't want to insert the text, return true;
+ * @param {cc.TextFieldTTF} sender
+ * @param {String} text
+ * @param {Number} len
+ * @return {Boolean}
+ */
+ onTextFieldInsertText: function (sender, text, len) {
+ return false
+ },
+
+ /**
+ * If the sender doesn't want to delete the delText, return true;
+ * @param {cc.TextFieldTTF} sender
+ * @param {String} delText
+ * @param {Number} len
+ * @return {Boolean}
+ */
+ onTextFieldDeleteBackward: function (sender, delText, len) {
+ return false;
+ },
+
+ /**
+ * If doesn't want draw sender as default, return true.
+ * @param {cc.TextFieldTTF} sender
+ * @return {Boolean}
+ */
+ onDraw: function (sender) {
+ return false;
+ }
+});
+
+/**
+ * A simple text input field with TTF font.
+ * @class
+ * @extends cc.LabelTTF
+ *
+ * @property {cc.Node} delegate - Delegate
+ * @property {Number} charCount - <@readonly> Characators count
+ * @property {String} placeHolder - Place holder for the field
+ * @property {cc.Color} colorSpaceHolder
+ *
+ * @param {String} placeholder
+ * @param {cc.Size} dimensions
+ * @param {Number} alignment
+ * @param {String} fontName
+ * @param {Number} fontSize
+ *
+ * @example
+ * //example
+ * // When five parameters
+ * var textField = new cc.TextFieldTTF("", cc.size(100,50), cc.TEXT_ALIGNMENT_LEFT,"Arial", 32);
+ * // When three parameters
+ * var textField = new cc.TextFieldTTF("", "Arial", 32);
+ */
+cc.TextFieldTTF = cc.LabelTTF.extend(/** @lends cc.TextFieldTTF# */{
+ delegate: null,
+ colorSpaceHolder: null,
+
+ _colorText: null,
+ _lens: null,
+ _inputText: "",
+ _placeHolder: "",
+ _charCount: 0,
+ _className: "TextFieldTTF",
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * creates a cc.TextFieldTTF from a fontName, alignment, dimension and font size.
+ * @param {String} placeholder
+ * @param {cc.Size} dimensions
+ * @param {Number} alignment
+ * @param {String} fontName
+ * @param {Number} fontSize
+ */
+ ctor: function (placeholder, dimensions, alignment, fontName, fontSize) {
+ this.colorSpaceHolder = cc.color(127, 127, 127);
+ this._colorText = cc.color(255, 255, 255, 255);
+ cc.LabelTTF.prototype.ctor.call(this);
+
+ if (fontSize !== undefined) {
+ this.initWithPlaceHolder("", dimensions, alignment, fontName, fontSize);
+ if (placeholder)
+ this.setPlaceHolder(placeholder);
+ } else if (fontName === undefined && alignment !== undefined) {
+ this.initWithString("", arguments[1], arguments[2]);
+ if (placeholder)
+ this.setPlaceHolder(placeholder);
+ }
+ },
+
+ onEnter: function () {
+ cc.LabelTTF.prototype.onEnter.call(this);
+ cc.imeDispatcher.addDelegate(this);
+ },
+
+ onExit: function () {
+ cc.LabelTTF.prototype.onExit.call(this);
+ cc.imeDispatcher.removeDelegate(this);
+ },
+
+ /**
+ * Gets the delegate.
+ * @return {cc.Node}
+ */
+ getDelegate: function () {
+ return this.delegate;
+ },
+
+ /**
+ * Set the delegate.
+ * @param {cc.Node} value
+ */
+ setDelegate: function (value) {
+ this.delegate = value;
+ },
+
+ /**
+ * Gets the char count.
+ * @return {Number}
+ */
+ getCharCount: function () {
+ return this._charCount;
+ },
+
+ /**
+ * Returns the color of space holder.
+ * @return {cc.Color}
+ */
+ getColorSpaceHolder: function () {
+ return cc.color(this.colorSpaceHolder);
+ },
+
+ /**
+ * Sets the color of space holder.
+ * @param {cc.Color} value
+ */
+ setColorSpaceHolder: function (value) {
+ this.colorSpaceHolder.r = value.r;
+ this.colorSpaceHolder.g = value.g;
+ this.colorSpaceHolder.b = value.b;
+ this.colorSpaceHolder.a = cc.isUndefined(value.a) ? 255 : value.a;
+ if (!this._inputText.length)
+ this.setColor(this.colorSpaceHolder);
+ },
+
+ /**
+ * Sets the color of cc.TextFieldTTF's text.
+ * @param {cc.Color} textColor
+ */
+ setTextColor: function (textColor) {
+ this._colorText.r = textColor.r;
+ this._colorText.g = textColor.g;
+ this._colorText.b = textColor.b;
+ this._colorText.a = cc.isUndefined(textColor.a) ? 255 : textColor.a;
+ if (this._inputText.length)
+ this.setColor(this._colorText);
+ },
+
+ /**
+ * Initializes the cc.TextFieldTTF with a font name, alignment, dimension and font size
+ * @param {String} placeholder
+ * @param {cc.Size} dimensions
+ * @param {Number} alignment
+ * @param {String} fontName
+ * @param {Number} fontSize
+ * @return {Boolean}
+ * @example
+ * //example
+ * var textField = new cc.TextFieldTTF();
+ * // When five parameters
+ * textField.initWithPlaceHolder("", cc.size(100,50), cc.TEXT_ALIGNMENT_LEFT,"Arial", 32);
+ * // When three parameters
+ * textField.initWithPlaceHolder("", "Arial", 32);
+ */
+ initWithPlaceHolder: function (placeholder, dimensions, alignment, fontName, fontSize) {
+ switch (arguments.length) {
+ case 5:
+ if (placeholder)
+ this.setPlaceHolder(placeholder);
+ return this.initWithString(this._placeHolder, fontName, fontSize, dimensions, alignment);
+ break;
+ case 3:
+ if (placeholder)
+ this.setPlaceHolder(placeholder);
+ return this.initWithString(this._placeHolder, arguments[1], arguments[2]);
+ break;
+ default:
+ throw new Error("Argument must be non-nil ");
+ break;
+ }
+ },
+
+ /**
+ * Input text property
+ * @param {String} text
+ */
+ setString: function (text) {
+ text = String(text);
+ this._inputText = text || "";
+
+ // if there is no input text, display placeholder instead
+ if (!this._inputText.length) {
+ cc.LabelTTF.prototype.setString.call(this, this._placeHolder);
+ this.setColor(this.colorSpaceHolder);
+ } else {
+ cc.LabelTTF.prototype.setString.call(this, this._inputText);
+ this.setColor(this._colorText);
+ }
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ this._renderCmd._updateTexture();
+ this._charCount = this._inputText.length;
+ },
+
+ /**
+ * Gets the string
+ * @return {String}
+ */
+ getString: function () {
+ return this._inputText;
+ },
+
+ /**
+ * Set the place holder.
+ * display this string if string equal "".
+ * @param {String} text
+ */
+ setPlaceHolder: function (text) {
+ this._placeHolder = text || "";
+ if (!this._inputText.length) {
+ cc.LabelTTF.prototype.setString.call(this, this._placeHolder);
+ this.setColor(this.colorSpaceHolder);
+ }
+ },
+
+ /**
+ * Gets the place holder.
+ * default display string.
+ * @return {String}
+ */
+ getPlaceHolder: function () {
+ return this._placeHolder;
+ },
+
+ /**
+ * Render function using the canvas 2d context or WebGL context, internal usage only, please do not call this function.
+ * @param {CanvasRenderingContext2D | WebGLRenderingContext} ctx The render context
+ */
+ draw: function (ctx) {
+ //console.log("size",this._contentSize);
+ var context = ctx || cc._renderContext;
+ if (this.delegate && this.delegate.onDraw(this))
+ return;
+
+ cc.LabelTTF.prototype.draw.call(this, context);
+ },
+
+ //////////////////////////////////////////////////////////////////////////
+ // CCIMEDelegate interface
+ //////////////////////////////////////////////////////////////////////////
+ /**
+ * Open keyboard and receive input text.
+ * @return {Boolean}
+ */
+ attachWithIME: function () {
+ return cc.imeDispatcher.attachDelegateWithIME(this);
+ },
+
+ /**
+ * End text input and close keyboard.
+ * @return {Boolean}
+ */
+ detachWithIME: function () {
+ return cc.imeDispatcher.detachDelegateWithIME(this);
+ },
+
+ /**
+ * Return whether to allow attach with IME.
+ * @return {Boolean}
+ */
+ canAttachWithIME: function () {
+ return (this.delegate) ? (!this.delegate.onTextFieldAttachWithIME(this)) : true;
+ },
+
+ /**
+ * When the delegate detach with IME, this method call by CCIMEDispatcher.
+ */
+ didAttachWithIME: function () {
+ },
+
+ /**
+ * Return whether to allow detach with IME.
+ * @return {Boolean}
+ */
+ canDetachWithIME: function () {
+ return (this.delegate) ? (!this.delegate.onTextFieldDetachWithIME(this)) : true;
+ },
+
+ /**
+ * When the delegate detach with IME, this method call by CCIMEDispatcher.
+ */
+ didDetachWithIME: function () {
+ },
+
+ /**
+ * Delete backward
+ */
+ deleteBackward: function () {
+ var strLen = this._inputText.length;
+ if (strLen === 0)
+ return;
+
+ // get the delete byte number
+ var deleteLen = 1; // default, erase 1 byte
+
+ if (this.delegate && this.delegate.onTextFieldDeleteBackward(this, this._inputText[strLen - deleteLen], deleteLen)) {
+ // delegate don't want delete backward
+ return;
+ }
+
+ // if delete all text, show space holder string
+ if (strLen <= deleteLen) {
+ this._inputText = "";
+ this._charCount = 0;
+ cc.LabelTTF.prototype.setString.call(this, this._placeHolder);
+ this.setColor(this.colorSpaceHolder);
+ return;
+ }
+
+ // set new input text
+ this.string = this._inputText.substring(0, strLen - deleteLen);
+ },
+
+ /**
+ * Remove delegate
+ */
+ removeDelegate: function () {
+ cc.imeDispatcher.removeDelegate(this);
+ },
+
+ _tipMessage: "please enter your word:",
+ /**
+ * Sets the input tip message to show on mobile browser. (mobile Web only)
+ * @param {string} tipMessage
+ */
+ setTipMessage: function (tipMessage) {
+ if (tipMessage == null)
+ return;
+ this._tipMessage = tipMessage;
+ },
+
+ /**
+ * Gets the input tip message to show on mobile browser. (mobile Web only)
+ * @returns {string}
+ */
+ getTipMessage: function () {
+ return this._tipMessage;
+ },
+
+ /**
+ * Append the text.
+ * Input the character.
+ * @param {String} text
+ * @param {Number} len
+ */
+ insertText: function (text, len) {
+ var sInsert = text;
+
+ // insert \n means input end
+ var pos = sInsert.indexOf('\n');
+ if (pos > -1) {
+ sInsert = sInsert.substring(0, pos);
+ }
+
+ if (sInsert.length > 0) {
+ if (this.delegate && this.delegate.onTextFieldInsertText(this, sInsert, sInsert.length)) {
+ // delegate doesn't want insert text
+ return;
+ }
+
+ var sText = this._inputText + sInsert;
+ this._charCount = sText.length;
+ this.string = sText;
+ }
+
+ if (pos === -1)
+ return;
+
+ // '\n' has inserted, let delegate process first
+ if (this.delegate && this.delegate.onTextFieldInsertText(this, "\n", 1))
+ return;
+
+ // if delegate hasn't process, detach with ime as default
+ this.detachWithIME();
+ },
+
+ /**
+ * Gets the input text.
+ * @return {String}
+ */
+ getContentText: function () {
+ return this._inputText;
+ },
+
+ //////////////////////////////////////////////////////////////////////////
+ // keyboard show/hide notification
+ //////////////////////////////////////////////////////////////////////////
+ keyboardWillShow: function (info) {
+ },
+ keyboardDidShow: function (info) {
+ },
+ keyboardWillHide: function (info) {
+ },
+ keyboardDidHide: function (info) {
+ }
+});
+
+var _p = cc.TextFieldTTF.prototype;
+
+// Extended properties
+/** @expose */
+_p.charCount;
+cc.defineGetterSetter(_p, "charCount", _p.getCharCount);
+/** @expose */
+_p.placeHolder;
+cc.defineGetterSetter(_p, "placeHolder", _p.getPlaceHolder, _p.setPlaceHolder);
+
+/**
+ * Please use new TextFieldTTF instead.
+ * Creates a cc.TextFieldTTF from a fontName, alignment, dimension and font size.
+ * @deprecated since v3.0 Please use new TextFieldTTF instead.
+ * @param {String} placeholder
+ * @param {cc.Size} dimensions
+ * @param {Number} alignment
+ * @param {String} fontName
+ * @param {Number} fontSize
+ * @return {cc.TextFieldTTF|Null}
+ */
+cc.TextFieldTTF.create = function (placeholder, dimensions, alignment, fontName, fontSize) {
+ return new cc.TextFieldTTF(placeholder, dimensions, alignment, fontName, fontSize);
+};
+
diff --git a/frameworks/cocos2d-html5/cocos2d/tilemap/CCTGAlib.js b/frameworks/cocos2d-html5/cocos2d/tilemap/CCTGAlib.js
new file mode 100644
index 0000000..76bd69b
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/tilemap/CCTGAlib.js
@@ -0,0 +1,438 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TGA_OK = 0;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TGA_ERROR_FILE_OPEN = 1;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TGA_ERROR_READING_FILE = 2;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TGA_ERROR_INDEXED_COLOR = 3;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TGA_ERROR_MEMORY = 4;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TGA_ERROR_COMPRESSED_FILE = 5;
+
+/**
+ * TGA format
+ * @param {Number} status
+ * @param {Number} type
+ * @param {Number} pixelDepth
+ * @param {Number} width map width
+ * @param {Number} height map height
+ * @param {Array} imageData raw data
+ * @param {Number} flipped
+ * @constructor
+ */
+cc.ImageTGA = function (status, type, pixelDepth, width, height, imageData, flipped) {
+ this.status = status || 0;
+ this.type = type || 0;
+ this.pixelDepth = pixelDepth || 0;
+ this.width = width || 0;
+ this.height = height || 0;
+ this.imageData = imageData || [];
+ this.flipped = flipped || 0;
+};
+
+/**
+ * load the image header field from stream. We only keep those that matter!
+ * @param {Array} buffer
+ * @param {Number} bufSize
+ * @param {cc.ImageTGA} psInfo
+ * @return {Boolean}
+ */
+cc.tgaLoadHeader = function (buffer, bufSize, psInfo) {
+ var step = 2;
+ if (step + 1 > bufSize)
+ return false;
+
+ var binaryReader = new cc.BinaryStreamReader(buffer);
+
+ binaryReader.setOffset(step);
+ psInfo.type = binaryReader.readByte();
+ step += 10; // . step += sizeof(unsigned char) * 2; step += sizeof(signed short) * 4;
+
+ if (step + 4 + 1 > bufSize)
+ return false;
+ binaryReader.setOffset(step);
+ psInfo.width = binaryReader.readUnsignedShort();
+ psInfo.height = binaryReader.readUnsignedInteger();
+ psInfo.pixelDepth = binaryReader.readByte();
+
+ step += 5; // . step += sizeof(unsigned char); step += sizeof(signed short) * 2;
+ if (step + 1 > bufSize)
+ return false;
+
+ var garbage = binaryReader.readByte();
+ psInfo.flipped = 0;
+ if (garbage & 0x20)
+ psInfo.flipped = 1;
+ return true;
+};
+
+/**
+ * loads the image pixels. You shouldn't call this function directly.
+ * @param {Array} buffer
+ * @param {Number} bufSize
+ * @param {cc.ImageTGA} psInfo
+ * @return {Boolean}
+ */
+cc.tgaLoadImageData = function (buffer, bufSize, psInfo) {
+ var mode, total, i, aux;
+ var step = 18; // .size_t step = (sizeof(unsigned char) + sizeof(signed short)) * 6;
+
+ // mode equal the number of components for each pixel
+ mode = 0 | (psInfo.pixelDepth / 2);
+ // total is the number of unsigned chars we'll have to read
+ total = psInfo.height * psInfo.width * mode;
+
+ if (step + total > bufSize)
+ return false;
+
+ psInfo.imageData = cc.__getSubArray(buffer, step, step + total);
+
+ // mode=3 or 4 implies that the image is RGB(A). However TGA
+ // stores it as BGR(A) so we'll have to swap R and B.
+ if (mode >= 3) {
+ for (i = 0; i < total; i += mode) {
+ aux = psInfo.imageData[i];
+ psInfo.imageData[i] = psInfo.imageData[i + 2];
+ psInfo.imageData[i + 2] = aux;
+ }
+ }
+ return true;
+};
+
+/**
+ * converts RGB to grayscale
+ * @param {cc.ImageTGA} psInfo
+ */
+cc.tgaRGBtogreyscale = function (psInfo) {
+ var i, j;
+
+ // if the image is already grayscale do nothing
+ if (psInfo.pixelDepth === 8)
+ return;
+
+ // compute the number of actual components
+ var mode = psInfo.pixelDepth / 8;
+
+ // allocate an array for the new image data
+ var newImageData = new Uint8Array(psInfo.height * psInfo.width);
+ if (newImageData === null)
+ return;
+
+ // convert pixels: grayscale = o.30 * R + 0.59 * G + 0.11 * B
+ for (i = 0, j = 0; j < psInfo.width * psInfo.height; i += mode, j++)
+ newImageData[j] = (0.30 * psInfo.imageData[i] + 0.59 * psInfo.imageData[i + 1] + 0.11 * psInfo.imageData[i + 2]);
+
+ // reassign pixelDepth and type according to the new image type
+ psInfo.pixelDepth = 8;
+ psInfo.type = 3;
+ // reassigning imageData to the new array.
+ psInfo.imageData = newImageData;
+};
+
+/**
+ * releases the memory used for the image
+ * @param {cc.ImageTGA} psInfo
+ */
+cc.tgaDestroy = function (psInfo) {
+ if (!psInfo)
+ return;
+
+ psInfo.imageData = null;
+ psInfo = null;
+};
+
+/**
+ * Load RLE image data
+ * @param buffer
+ * @param bufSize
+ * @param psInfo
+ * @returns {boolean}
+ */
+cc.tgaLoadRLEImageData = function (buffer, bufSize, psInfo) {
+ var mode, total, i, index = 0, skip = 0, flag = 0;
+ var aux = [], runlength = 0;
+
+ var step = 18; // . size_t step = (sizeof(unsigned char) + sizeof(signed short)) * 6;
+
+ // mode equal the number of components for each pixel
+ mode = psInfo.pixelDepth / 8;
+ // total is the number of unsigned chars we'll have to read
+ total = psInfo.height * psInfo.width;
+
+ for (i = 0; i < total; i++) {
+ // if we have a run length pending, run it
+ if (runlength !== 0) {
+ // we do, update the run length count
+ runlength--;
+ skip = (flag !== 0);
+ } else {
+ // otherwise, read in the run length token
+ if (step + 1 > bufSize)
+ break;
+ runlength = buffer[step];
+ step += 1;
+
+ // see if it's a RLE encoded sequence
+ flag = runlength & 0x80;
+ if (flag)
+ runlength -= 128;
+ skip = 0;
+ }
+
+ // do we need to skip reading this pixel?
+ if (!skip) {
+ // no, read in the pixel data
+ if (step + mode > bufSize)
+ break;
+ aux = cc.__getSubArray(buffer, step, step + mode);
+ step += mode;
+
+ // mode=3 or 4 implies that the image is RGB(A). However TGA
+ // stores it as BGR(A) so we'll have to swap R and B.
+ if (mode >= 3) {
+ var tmp = aux[0];
+ aux[0] = aux[2];
+ aux[2] = tmp;
+ }
+ }
+
+ // add the pixel to our image
+ for (var j = 0; j < mode; j++)
+ psInfo.imageData[index + j] = aux[j];
+
+ index += mode;
+ }
+
+ return true;
+};
+
+/**
+ * ImageTGA Flip
+ * @param {cc.ImageTGA} psInfo
+ */
+cc.tgaFlipImage = function (psInfo) {
+ // mode equal the number of components for each pixel
+ var mode = psInfo.pixelDepth / 8;
+ var rowbytes = psInfo.width * mode;
+
+ for (var y = 0; y < (psInfo.height / 2); y++) {
+ var row = cc.__getSubArray(psInfo.imageData, y * rowbytes, y * rowbytes + rowbytes);
+ cc.__setDataToArray(cc.__getSubArray(psInfo.imageData, (psInfo.height - (y + 1)) * rowbytes, rowbytes), psInfo.imageData, y * rowbytes);
+ cc.__setDataToArray(row, psInfo.imageData, (psInfo.height - (y + 1)) * rowbytes);
+ }
+ psInfo.flipped = 0;
+};
+
+cc.__getSubArray = function (array, start, end) {
+ if (array instanceof Array)
+ return array.slice(start, end);
+ else
+ return array.subarray(start, end);
+};
+
+cc.__setDataToArray = function (sourceData, destArray, startIndex) {
+ for (var i = 0; i < sourceData.length; i++)
+ destArray[startIndex + i] = sourceData[i];
+};
+
+/**
+ * Binary Stream Reader
+ *
+ * @class
+ * @param binaryData
+ */
+cc.BinaryStreamReader = cc.Class.extend({
+ _binaryData: null,
+ _offset: 0,
+
+ /**
+ * The cc.BinaryStreamReader's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.BinaryStreamReader()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param binaryData
+ */
+ ctor: function (binaryData) {
+ this._binaryData = binaryData;
+ },
+
+ /**
+ * Set the binaryData.
+ * @param binaryData
+ */
+ setBinaryData: function (binaryData) {
+ this._binaryData = binaryData;
+ this._offset = 0;
+ },
+
+ /**
+ * Gets the binaryData.
+ * @returns {Object}
+ */
+ getBinaryData: function () {
+ return this._binaryData;
+ },
+
+ _checkSize: function (neededBits) {
+ if (!(this._offset + Math.ceil(neededBits / 8) < this._data.length))
+ throw new Error("Index out of bound");
+ },
+
+ _decodeFloat: function (precisionBits, exponentBits) {
+ var length = precisionBits + exponentBits + 1;
+ var size = length >> 3;
+ this._checkSize(length);
+
+ var bias = Math.pow(2, exponentBits - 1) - 1;
+ var signal = this._readBits(precisionBits + exponentBits, 1, size);
+ var exponent = this._readBits(precisionBits, exponentBits, size);
+ var significand = 0;
+ var divisor = 2;
+ var curByte = 0; //length + (-precisionBits >> 3) - 1;
+ do {
+ var byteValue = this._readByte(++curByte, size);
+ var startBit = precisionBits % 8 || 8;
+ var mask = 1 << startBit;
+ while (mask >>= 1) {
+ if (byteValue & mask)
+ significand += 1 / divisor;
+ divisor *= 2;
+ }
+ } while (precisionBits -= startBit);
+
+ this._offset += size;
+
+ return exponent === (bias << 1) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity
+ : (1 + signal * -2) * (exponent || significand ? !exponent ? Math.pow(2, -bias + 1) * significand
+ : Math.pow(2, exponent - bias) * (1 + significand) : 0);
+ },
+
+ _readByte: function (i, size) {
+ return this._data[this._offset + size - i - 1];
+ },
+
+ _decodeInt: function (bits, signed) {
+ var x = this._readBits(0, bits, bits / 8), max = Math.pow(2, bits);
+ var result = signed && x >= max / 2 ? x - max : x;
+
+ this._offset += bits / 8;
+ return result;
+ },
+
+ _shl: function (a, b) {
+ for (++b; --b; a = ((a %= 0x7fffffff + 1) & 0x40000000) === 0x40000000 ? a * 2 : (a - 0x40000000) * 2 + 0x7fffffff + 1) {
+ }
+ return a;
+ },
+
+ _readBits: function (start, length, size) {
+ var offsetLeft = (start + length) % 8;
+ var offsetRight = start % 8;
+ var curByte = size - (start >> 3) - 1;
+ var lastByte = size + (-(start + length) >> 3);
+ var diff = curByte - lastByte;
+
+ var sum = (this._readByte(curByte, size) >> offsetRight) & ((1 << (diff ? 8 - offsetRight : length)) - 1);
+
+ if (diff && offsetLeft)
+ sum += (this._readByte(lastByte++, size) & ((1 << offsetLeft) - 1)) << (diff-- << 3) - offsetRight;
+
+ while (diff)
+ sum += this._shl(this._readByte(lastByte++, size), (diff-- << 3) - offsetRight);
+
+ return sum;
+ },
+
+ readInteger: function () {
+ return this._decodeInt(32, true);
+ },
+
+ readUnsignedInteger: function () {
+ return this._decodeInt(32, false);
+ },
+
+ readSingle: function () {
+ return this._decodeFloat(23, 8);
+ },
+
+ readShort: function () {
+ return this._decodeInt(16, true);
+ },
+
+ readUnsignedShort: function () {
+ return this._decodeInt(16, false);
+ },
+
+ readByte: function () {
+ var readByte = this._data[this._offset];
+ this._offset += 1;
+ return readByte;
+ },
+
+ readData: function (start, end) {
+ if (this._binaryData instanceof Array) {
+ return this._binaryData.slice(start, end);
+ } else {
+ //typed array
+ return this._binaryData.subarray(start, end);
+ }
+ },
+
+ setOffset: function (offset) {
+ this._offset = offset;
+ },
+
+ getOffset: function () {
+ return this._offset;
+ }
+});
diff --git a/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXLayer.js b/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXLayer.js
new file mode 100644
index 0000000..e78c8d0
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXLayer.js
@@ -0,0 +1,803 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.TMXLayer represents the TMX layer.
+ *
+ * It is a subclass of cc.SpriteBatchNode. By default the tiles are rendered using a cc.TextureAtlas.
+ * If you modify a tile on runtime, then, that tile will become a cc.Sprite, otherwise no cc.Sprite objects are created.
+ * The benefits of using cc.Sprite objects as tiles are:
+ * - tiles (cc.Sprite) can be rotated/scaled/moved with a nice API
+ *
+ * If the layer contains a property named "cc.vertexz" with an integer (in can be positive or negative),
+ * then all the tiles belonging to the layer will use that value as their OpenGL vertex Z for depth.
+ *
+ * On the other hand, if the "cc.vertexz" property has the "automatic" value, then the tiles will use an automatic vertex Z value.
+ * Also before drawing the tiles, GL_ALPHA_TEST will be enabled, and disabled after drawing them. The used alpha func will be:
+ *
+ * glAlphaFunc( GL_GREATER, value )
+ *
+ * "value" by default is 0, but you can change it from Tiled by adding the "cc_alpha_func" property to the layer.
+ * The value 0 should work for most cases, but if you have tiles that are semi-transparent, then you might want to use a different value, like 0.5.
+ * @class
+ * @extends cc.SpriteBatchNode
+ *
+ * @property {Array} tiles - Tiles for layer
+ * @property {cc.TMXTilesetInfo} tileset - Tileset for layer
+ * @property {Number} layerOrientation - Layer orientation
+ * @property {Array} properties - Properties from the layer. They can be added using tilemap editors
+ * @property {String} layerName - Name of the layer
+ * @property {Number} layerWidth - Width of the layer
+ * @property {Number} layerHeight - Height of the layer
+ * @property {Number} tileWidth - Width of a tile
+ * @property {Number} tileHeight - Height of a tile
+ */
+cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{
+ tiles: null,
+ tileset: null,
+ layerOrientation: null,
+ properties: null,
+ layerName: "",
+
+ _textures: null,
+ _texGrids: null,
+ _spriteTiles: null,
+
+ //size of the layer in tiles
+ _layerSize: null,
+ _mapTileSize: null,
+ //TMX Layer supports opacity
+ _opacity: 255,
+ _minGID: null,
+ _maxGID: null,
+ //Only used when vertexZ is used
+ _vertexZvalue: null,
+ _useAutomaticVertexZ: null,
+ //used for optimization
+ _reusedTile: null,
+ _atlasIndexArray: null,
+ //used for retina display
+ _contentScaleFactor: null,
+
+ _className:"TMXLayer",
+
+ /**
+ * Creates a cc.TMXLayer with an tile set info, a layer info and a map info
+ * Constructor of cc.TMXLayer
+ * @param {cc.TMXTilesetInfo} tilesetInfo
+ * @param {cc.TMXLayerInfo} layerInfo
+ * @param {cc.TMXMapInfo} mapInfo
+ */
+ ctor:function (tilesetInfo, layerInfo, mapInfo) {
+ cc.SpriteBatchNode.prototype.ctor.call(this);
+ this._descendants = [];
+
+ this._layerSize = cc.size(0, 0);
+ this._mapTileSize = cc.size(0, 0);
+ this._spriteTiles = {};
+
+ if(mapInfo !== undefined)
+ this.initWithTilesetInfo(tilesetInfo, layerInfo, mapInfo);
+ },
+
+ _createRenderCmd: function(){
+ if(cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.TMXLayer.CanvasRenderCmd(this);
+ else
+ return new cc.TMXLayer.WebGLRenderCmd(this);
+ },
+
+ _fillTextureGrids: function (tileset, texId) {
+ var tex = this._textures[texId];
+ if (!tex.isLoaded()) {
+ tex.addEventListener("load", function () {
+ this._fillTextureGrids(tileset, texId);
+ }, this);
+ return;
+ }
+ if (!tileset.imageSize.width || !tileset.imageSize.height) {
+ tileset.imageSize.width = tex.width;
+ tileset.imageSize.height = tex.height;
+ }
+ var tw = tileset._tileSize.width,
+ th = tileset._tileSize.height,
+ imageW = tex._contentSize.width,
+ imageH = tex._contentSize.height,
+ spacing = tileset.spacing,
+ margin = tileset.margin,
+
+ cols = Math.floor((imageW - margin*2 + spacing) / (tw + spacing)),
+ rows = Math.floor((imageH - margin*2 + spacing) / (th + spacing)),
+ count = rows * cols,
+
+ gid = tileset.firstGid,
+ maxGid = tileset.firstGid + count,
+ grids = this._texGrids,
+ grid = null,
+ override = grids[gid] ? true : false,
+
+ t, l, r, b;
+
+ for (; gid < maxGid; ++gid) {
+ // Avoid overlapping
+ if (override && !grids[gid]) {
+ override = false;
+ }
+ if (!override && grids[gid]) {
+ break;
+ }
+
+ grid = {
+ texId: texId,
+ x: 0, y: 0, width: tw, height: th,
+ t: 0, l: 0, r: 0, b: 0
+ };
+ tileset.rectForGID(gid, grid);
+ grid.t = grid.y / imageH;
+ grid.l = grid.x / imageW;
+ grid.r = (grid.x + grid.width) / imageW;
+ grid.b = (grid.y + grid.height) / imageH;
+ grids[gid] = grid;
+ }
+ },
+
+ /**
+ * Initializes a cc.TMXLayer with a tileset info, a layer info and a map info
+ * @param {cc.TMXTilesetInfo} tilesetInfo
+ * @param {cc.TMXLayerInfo} layerInfo
+ * @param {cc.TMXMapInfo} mapInfo
+ * @return {Boolean}
+ */
+ initWithTilesetInfo:function (tilesetInfo, layerInfo, mapInfo) {
+ var size = layerInfo._layerSize;
+ var totalNumberOfTiles = parseInt(size.width * size.height);
+
+ // layerInfo
+ this.layerName = layerInfo.name;
+ this.tiles = layerInfo._tiles;
+ this.properties = layerInfo.properties;
+ this._layerSize = size;
+ this._minGID = layerInfo._minGID;
+ this._maxGID = layerInfo._maxGID;
+ this._opacity = layerInfo._opacity;
+
+ // tilesetInfo
+ this.tileset = tilesetInfo;
+
+ // mapInfo
+ this.layerOrientation = mapInfo.orientation;
+ this._mapTileSize = mapInfo.getTileSize();
+
+ var tilesets = mapInfo._tilesets;
+ if (tilesets) {
+ this._textures = [];
+ this._texGrids = [];
+ var i, len = tilesets.length, tileset, tex;
+ for (i = 0; i < len; ++i) {
+ tileset = tilesets[i];
+ tex = cc.textureCache.addImage(tileset.sourceImage);
+ this._textures.push(tex);
+ this._fillTextureGrids(tileset, i);
+ if (tileset === tilesetInfo) {
+ this._texture = tex;
+ }
+ }
+ }
+
+ // offset (after layer orientation is set);
+ var offset = this._calculateLayerOffset(layerInfo.offset);
+ this.setPosition(cc.pointPixelsToPoints(offset));
+
+ // Parse cocos2d properties
+ this._parseInternalProperties();
+
+ this.setContentSize(cc.sizePixelsToPoints(cc.size(this._layerSize.width * this._mapTileSize.width,
+ this._layerSize.height * this._mapTileSize.height)));
+ this._useAutomaticVertexZ = false;
+ this._vertexZvalue = 0;
+ return true;
+ },
+
+ /**
+ * Gets layer size.
+ * @return {cc.Size}
+ */
+ getLayerSize:function () {
+ return cc.size(this._layerSize.width, this._layerSize.height);
+ },
+
+ /**
+ * Set layer size
+ * @param {cc.Size} Var
+ */
+ setLayerSize:function (Var) {
+ this._layerSize.width = Var.width;
+ this._layerSize.height = Var.height;
+ },
+
+ _getLayerWidth: function () {
+ return this._layerSize.width;
+ },
+ _setLayerWidth: function (width) {
+ this._layerSize.width = width;
+ },
+ _getLayerHeight: function () {
+ return this._layerSize.height;
+ },
+ _setLayerHeight: function (height) {
+ this._layerSize.height = height;
+ },
+
+ /**
+ * Size of the map's tile (could be different from the tile's size)
+ * @return {cc.Size}
+ */
+ getMapTileSize:function () {
+ return cc.size(this._mapTileSize.width,this._mapTileSize.height);
+ },
+
+ /**
+ * Set the map tile size.
+ * @param {cc.Size} Var
+ */
+ setMapTileSize:function (Var) {
+ this._mapTileSize.width = Var.width;
+ this._mapTileSize.height = Var.height;
+ },
+
+ _getTileWidth: function () {
+ return this._mapTileSize.width;
+ },
+ _setTileWidth: function (width) {
+ this._mapTileSize.width = width;
+ },
+ _getTileHeight: function () {
+ return this._mapTileSize.height;
+ },
+ _setTileHeight: function (height) {
+ this._mapTileSize.height = height;
+ },
+
+ /**
+ * Pointer to the map of tiles
+ * @return {Array}
+ */
+ getTiles:function () {
+ return this.tiles;
+ },
+
+ /**
+ * Pointer to the map of tiles
+ * @param {Array} Var
+ */
+ setTiles:function (Var) {
+ this.tiles = Var;
+ },
+
+ /**
+ * Tile set information for the layer
+ * @return {cc.TMXTilesetInfo}
+ */
+ getTileset:function () {
+ return this.tileset;
+ },
+
+ /**
+ * Tile set information for the layer
+ * @param {cc.TMXTilesetInfo} Var
+ */
+ setTileset:function (Var) {
+ this.tileset = Var;
+ },
+
+ /**
+ * Layer orientation, which is the same as the map orientation
+ * @return {Number}
+ */
+ getLayerOrientation:function () {
+ return this.layerOrientation;
+ },
+
+ /**
+ * Layer orientation, which is the same as the map orientation
+ * @param {Number} Var
+ */
+ setLayerOrientation:function (Var) {
+ this.layerOrientation = Var;
+ },
+
+ /**
+ * properties from the layer. They can be added using Tiled
+ * @return {Array}
+ */
+ getProperties:function () {
+ return this.properties;
+ },
+
+ /**
+ * properties from the layer. They can be added using Tiled
+ * @param {Array} Var
+ */
+ setProperties:function (Var) {
+ this.properties = Var;
+ },
+
+ /**
+ * Return the value for the specific property name
+ * @param {String} propertyName
+ * @return {*}
+ */
+ getProperty:function (propertyName) {
+ return this.properties[propertyName];
+ },
+
+ /**
+ * Gets the layer name
+ * @return {String}
+ */
+ getLayerName:function () {
+ return this.layerName;
+ },
+
+ /**
+ * Set the layer name
+ * @param {String} layerName
+ */
+ setLayerName:function (layerName) {
+ this.layerName = layerName;
+ },
+
+ /**
+ * Dealloc the map that contains the tile position from memory.
+ * Unless you want to know at runtime the tiles positions, you can safely call this method.
+ * If you are going to call layer.getTileGIDAt() then, don't release the map
+ */
+ releaseMap:function () {
+ this._spriteTiles = {};
+ },
+
+ /**
+ * Returns the tile (cc.Sprite) at a given a tile coordinate.
+ * The returned cc.Sprite will be already added to the cc.TMXLayer. Don't add it again.
+ * The cc.Sprite can be treated like any other cc.Sprite: rotated, scaled, translated, opacity, color, etc.
+ * You can remove either by calling:
+ * - layer.removeChild(sprite, cleanup);
+ * - or layer.removeTileAt(ccp(x,y));
+ * @param {cc.Point|Number} pos or x
+ * @param {Number} [y]
+ * @return {cc.Sprite}
+ */
+ getTileAt: function (pos, y) {
+ if (pos === undefined) {
+ throw new Error("cc.TMXLayer.getTileAt(): pos should be non-null");
+ }
+ var x = pos;
+ if (y === undefined) {
+ x = pos.x;
+ y = pos.y;
+ }
+ if (x >= this._layerSize.width || y >= this._layerSize.height || x < 0 || y < 0) {
+ throw new Error("cc.TMXLayer.getTileAt(): invalid position");
+ }
+ if (!this.tiles) {
+ cc.log("cc.TMXLayer.getTileAt(): TMXLayer: the tiles map has been released");
+ return null;
+ }
+
+ var tile = null, gid = this.getTileGIDAt(x, y);
+
+ // if GID == 0, then no tile is present
+ if (gid === 0) {
+ return tile;
+ }
+
+ var z = 0 | (x + y * this._layerSize.width);
+ tile = this._spriteTiles[z];
+ // tile not created yet. create it
+ if (!tile) {
+ var rect = this._texGrids[gid];
+ var tex = this._textures[rect.texId];
+ rect = cc.rectPixelsToPoints(rect);
+
+ tile = new cc.Sprite(tex, rect);
+ tile.setPosition(this.getPositionAt(x, y));
+ var vertexZ = this._vertexZForPos(x, y);
+ tile.setVertexZ(vertexZ);
+ tile.setAnchorPoint(0, 0);
+ tile.setOpacity(this._opacity);
+
+ this.addChild(tile, vertexZ, z);
+ }
+ return tile;
+ },
+
+ /**
+ * Returns the tile gid at a given tile coordinate.
+ * if it returns 0, it means that the tile is empty.
+ * This method requires the the tile map has not been previously released (eg. don't call layer.releaseMap())
+ * @param {cc.Point|Number} pos or x
+ * @param {Number} [y]
+ * @return {Number}
+ */
+ getTileGIDAt:function (pos, y) {
+ if (pos === undefined) {
+ throw new Error("cc.TMXLayer.getTileGIDAt(): pos should be non-null");
+ }
+ var x = pos;
+ if (y === undefined) {
+ x = pos.x;
+ y = pos.y;
+ }
+ if (x >= this._layerSize.width || y >= this._layerSize.height || x < 0 || y < 0) {
+ throw new Error("cc.TMXLayer.getTileGIDAt(): invalid position");
+ }
+ if (!this.tiles) {
+ cc.log("cc.TMXLayer.getTileGIDAt(): TMXLayer: the tiles map has been released");
+ return null;
+ }
+
+ var idx = 0 | (x + y * this._layerSize.width);
+ // Bits on the far end of the 32-bit global tile ID are used for tile flags
+ var tile = this.tiles[idx];
+
+ return (tile & cc.TMX_TILE_FLIPPED_MASK) >>> 0;
+ },
+ // XXX: deprecated
+ // tileGIDAt:getTileGIDAt,
+
+ /**
+ * Sets the tile gid (gid = tile global id) at a given tile coordinate.
+ * The Tile GID can be obtained by using the method "tileGIDAt" or by using the TMX editor . Tileset Mgr +1.
+ * If a tile is already placed at that position, then it will be removed.
+ * @param {Number} gid
+ * @param {cc.Point|Number} posOrX position or x
+ * @param {Number} flagsOrY flags or y
+ * @param {Number} [flags]
+ */
+ setTileGID: function(gid, posOrX, flagsOrY, flags) {
+ if (posOrX === undefined) {
+ throw new Error("cc.TMXLayer.setTileGID(): pos should be non-null");
+ }
+ var pos;
+ if (flags !== undefined) {
+ pos = cc.p(posOrX, flagsOrY);
+ } else {
+ pos = posOrX;
+ flags = flagsOrY;
+ }
+ if (pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) {
+ throw new Error("cc.TMXLayer.setTileGID(): invalid position");
+ }
+ if (!this.tiles) {
+ cc.log("cc.TMXLayer.setTileGID(): TMXLayer: the tiles map has been released");
+ return;
+ }
+ if (gid !== 0 && gid < this.tileset.firstGid) {
+ cc.log( "cc.TMXLayer.setTileGID(): invalid gid:" + gid);
+ return;
+ }
+
+ flags = flags || 0;
+ var currentFlags = this.getTileFlagsAt(pos);
+ var currentGID = this.getTileGIDAt(pos);
+
+ if (currentGID !== gid || currentFlags !== flags) {
+ var gidAndFlags = (gid | flags) >>> 0;
+ // setting gid=0 is equal to remove the tile
+ if (gid === 0)
+ this.removeTileAt(pos);
+ else if (currentGID === 0) // empty tile. create a new one
+ this._updateTileForGID(gidAndFlags, pos);
+ else { // modifying an existing tile with a non-empty tile
+ var z = pos.x + pos.y * this._layerSize.width;
+ var sprite = this.getChildByTag(z);
+ if (sprite) {
+ var rect = this._texGrids[gid];
+ var tex = this._textures[rect.texId];
+ rect = cc.rectPixelsToPoints(rect);
+ sprite.setTexture(tex);
+ sprite.setTextureRect(rect, false);
+ if (flags != null)
+ this._setupTileSprite(sprite, pos, gidAndFlags);
+
+ this.tiles[z] = gidAndFlags;
+ } else {
+ this._updateTileForGID(gidAndFlags, pos);
+ }
+ }
+ }
+ },
+
+ addChild: function (child, localZOrder, tag) {
+ cc.Node.prototype.addChild.call(this, child, localZOrder, tag);
+ if (tag !== undefined) {
+ this._spriteTiles[tag] = child;
+ child._vertexZ = this._vertexZ + cc.renderer.assignedZStep * tag / this.tiles.length;
+ // child._renderCmd._needDraw = false;
+ }
+ },
+
+ removeChild: function (child, cleanup) {
+ if (this._spriteTiles[child.tag]) {
+ this._spriteTiles[child.tag] = null;
+ // child._renderCmd._needDraw = true;
+ }
+ cc.Node.prototype.removeChild.call(this, child, cleanup);
+ },
+
+ /**
+ * lipped tiles can be changed dynamically
+ * @param {cc.Point|Number} pos or x
+ * @param {Number} [y]
+ * @return {Number}
+ */
+ getTileFlagsAt:function (pos, y) {
+ if(!pos)
+ throw new Error("cc.TMXLayer.getTileFlagsAt(): pos should be non-null");
+ if(y !== undefined)
+ pos = cc.p(pos, y);
+ if(pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0)
+ throw new Error("cc.TMXLayer.getTileFlagsAt(): invalid position");
+ if(!this.tiles){
+ cc.log("cc.TMXLayer.getTileFlagsAt(): TMXLayer: the tiles map has been released");
+ return null;
+ }
+
+ var idx = 0 | (pos.x + pos.y * this._layerSize.width);
+ // Bits on the far end of the 32-bit global tile ID are used for tile flags
+ var tile = this.tiles[idx];
+
+ return (tile & cc.TMX_TILE_FLIPPED_ALL) >>> 0;
+ },
+ // XXX: deprecated
+ // tileFlagAt:getTileFlagsAt,
+
+ /**
+ * Removes a tile at given tile coordinate
+ * @param {cc.Point|Number} pos position or x
+ * @param {Number} [y]
+ */
+ removeTileAt:function (pos, y) {
+ if (!pos) {
+ throw new Error("cc.TMXLayer.removeTileAt(): pos should be non-null");
+ }
+ if (y !== undefined) {
+ pos = cc.p(pos, y);
+ }
+ if (pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) {
+ throw new Error("cc.TMXLayer.removeTileAt(): invalid position");
+ }
+ if (!this.tiles) {
+ cc.log("cc.TMXLayer.removeTileAt(): TMXLayer: the tiles map has been released");
+ return;
+ }
+
+ var gid = this.getTileGIDAt(pos);
+ if (gid !== 0) {
+ var z = 0 | (pos.x + pos.y * this._layerSize.width);
+ // remove tile from GID map
+ this.tiles[z] = 0;
+
+ // remove it from sprites and/or texture atlas
+ var sprite = this._spriteTiles[z];
+ if (sprite) {
+ this.removeChild(sprite, true);
+ }
+ }
+ },
+
+ /**
+ * Returns the position in pixels of a given tile coordinate
+ * @param {cc.Point|Number} pos position or x
+ * @param {Number} [y]
+ * @return {cc.Point}
+ */
+ getPositionAt:function (pos, y) {
+ if (y !== undefined)
+ pos = cc.p(pos, y);
+ var ret = cc.p(0,0);
+ switch (this.layerOrientation) {
+ case cc.TMX_ORIENTATION_ORTHO:
+ ret = this._positionForOrthoAt(pos);
+ break;
+ case cc.TMX_ORIENTATION_ISO:
+ ret = this._positionForIsoAt(pos);
+ break;
+ case cc.TMX_ORIENTATION_HEX:
+ ret = this._positionForHexAt(pos);
+ break;
+ }
+ return cc.pointPixelsToPoints(ret);
+ },
+ // XXX: Deprecated. For backward compatibility only
+ // positionAt:getPositionAt,
+
+ _positionForIsoAt:function (pos) {
+ return cc.p(this._mapTileSize.width / 2 * ( this._layerSize.width + pos.x - pos.y - 1),
+ this._mapTileSize.height / 2 * (( this._layerSize.height * 2 - pos.x - pos.y) - 2));
+ },
+
+ _positionForOrthoAt:function (pos) {
+ return cc.p(pos.x * this._mapTileSize.width,
+ (this._layerSize.height - pos.y - 1) * this._mapTileSize.height);
+ },
+
+ _positionForHexAt:function (pos) {
+ var diffY = (pos.x % 2 === 1) ? (-this._mapTileSize.height / 2) : 0;
+ return cc.p(pos.x * this._mapTileSize.width * 3 / 4,
+ (this._layerSize.height - pos.y - 1) * this._mapTileSize.height + diffY);
+ },
+
+ _calculateLayerOffset:function (pos) {
+ var ret = cc.p(0,0);
+ switch (this.layerOrientation) {
+ case cc.TMX_ORIENTATION_ORTHO:
+ ret = cc.p(pos.x * this._mapTileSize.width, -pos.y * this._mapTileSize.height);
+ break;
+ case cc.TMX_ORIENTATION_ISO:
+ ret = cc.p((this._mapTileSize.width / 2) * (pos.x - pos.y),
+ (this._mapTileSize.height / 2 ) * (-pos.x - pos.y));
+ break;
+ case cc.TMX_ORIENTATION_HEX:
+ if(pos.x !== 0 || pos.y !== 0)
+ cc.log("offset for hexagonal map not implemented yet");
+ break;
+ }
+ return ret;
+ },
+
+ _updateTileForGID:function (gid, pos) {
+ if (!this._texGrids[gid]) {
+ return;
+ }
+
+ var idx = 0 | (pos.x + pos.y * this._layerSize.width);
+ if (idx < this.tiles.length) {
+ this.tiles[idx] = gid;
+ }
+ },
+
+ //The layer recognizes some special properties, like cc_vertez
+ _parseInternalProperties:function () {
+ // if cc_vertex=automatic, then tiles will be rendered using vertexz
+ var vertexz = this.getProperty("cc_vertexz");
+ if (vertexz) {
+ if (vertexz === "automatic") {
+ this._useAutomaticVertexZ = true;
+ var alphaFuncVal = this.getProperty("cc_alpha_func");
+ var alphaFuncValue = 0;
+ if (alphaFuncVal)
+ alphaFuncValue = parseFloat(alphaFuncVal);
+
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { //todo: need move to WebGL render cmd
+ this.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST);
+ // NOTE: alpha test shader is hard-coded to use the equivalent of a glAlphaFunc(GL_GREATER) comparison
+ this.shaderProgram.use();
+ this.shaderProgram.setUniformLocationWith1f(cc.UNIFORM_ALPHA_TEST_VALUE_S, alphaFuncValue);
+ }
+ } else
+ this._vertexZvalue = parseInt(vertexz, 10);
+ }
+ },
+
+ _setupTileSprite:function (sprite, pos, gid) {
+ var z = pos.x + pos.y * this._layerSize.width;
+ var posInPixel = this.getPositionAt(pos);
+ sprite.setPosition(posInPixel);
+ sprite.setVertexZ(this._vertexZForPos(pos));
+ sprite.setAnchorPoint(0, 0);
+ sprite.setOpacity(this._opacity);
+ sprite.setFlippedX(false);
+ sprite.setFlippedY(false);
+ sprite.setRotation(0.0);
+
+ // Rotation in tiled is achieved using 3 flipped states, flipping across the horizontal, vertical, and diagonal axes of the tiles.
+ if ((gid & cc.TMX_TILE_DIAGONAL_FLAG) >>> 0) {
+ // put the anchor in the middle for ease of rotation.
+ sprite.setAnchorPoint(0.5, 0.5);
+ sprite.setPosition(posInPixel.x + sprite.width/2, posInPixel.y + sprite.height/2);
+
+ var flag = (gid & (cc.TMX_TILE_HORIZONTAL_FLAG | cc.TMX_TILE_VERTICAL_FLAG) >>> 0) >>> 0;
+ // handle the 4 diagonally flipped states.
+ if (flag === cc.TMX_TILE_HORIZONTAL_FLAG)
+ sprite.setRotation(90);
+ else if (flag === cc.TMX_TILE_VERTICAL_FLAG)
+ sprite.setRotation(270);
+ else if (flag === (cc.TMX_TILE_VERTICAL_FLAG | cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0) {
+ sprite.setRotation(90);
+ sprite.setFlippedX(true);
+ } else {
+ sprite.setRotation(270);
+ sprite.setFlippedX(true);
+ }
+ } else {
+ if ((gid & cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0) {
+ sprite.setFlippedX(true);
+ }
+ if ((gid & cc.TMX_TILE_VERTICAL_FLAG) >>> 0) {
+ sprite.setFlippedY(true);
+ }
+ }
+ },
+
+ _vertexZForPos:function (x, y) {
+ if (y === undefined) {
+ y = x.y;
+ x = x.x;
+ }
+ var ret = 0;
+ var maxVal = 0;
+ if (this._useAutomaticVertexZ) {
+ switch (this.layerOrientation) {
+ case cc.TMX_ORIENTATION_ISO:
+ maxVal = this._layerSize.width + this._layerSize.height;
+ ret = -(maxVal - (x + y));
+ break;
+ case cc.TMX_ORIENTATION_ORTHO:
+ ret = -(this._layerSize.height - y);
+ break;
+ case cc.TMX_ORIENTATION_HEX:
+ cc.log("TMX Hexa zOrder not supported");
+ break;
+ default:
+ cc.log("TMX invalid value");
+ break;
+ }
+ } else {
+ ret = this._vertexZvalue;
+ }
+ return ret;
+ }
+});
+
+var _p = cc.TMXLayer.prototype;
+
+// Extended properties
+/** @expose */
+_p.layerWidth;
+cc.defineGetterSetter(_p, "layerWidth", _p._getLayerWidth, _p._setLayerWidth);
+/** @expose */
+_p.layerHeight;
+cc.defineGetterSetter(_p, "layerHeight", _p._getLayerHeight, _p._setLayerHeight);
+/** @expose */
+_p.tileWidth;
+cc.defineGetterSetter(_p, "tileWidth", _p._getTileWidth, _p._setTileWidth);
+/** @expose */
+_p.tileHeight;
+cc.defineGetterSetter(_p, "tileHeight", _p._getTileHeight, _p._setTileHeight);
+
+
+/**
+ * Creates a cc.TMXLayer with an tile set info, a layer info and a map info
+ * @deprecated since v3.0 please use new cc.TMXLayer(tilesetInfo, layerInfo, mapInfo) instead.
+ * @param {cc.TMXTilesetInfo} tilesetInfo
+ * @param {cc.TMXLayerInfo} layerInfo
+ * @param {cc.TMXMapInfo} mapInfo
+ * @return {cc.TMXLayer|Null}
+ */
+cc.TMXLayer.create = function (tilesetInfo, layerInfo, mapInfo) {
+ return new cc.TMXLayer(tilesetInfo, layerInfo, mapInfo);
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js
new file mode 100644
index 0000000..f354284
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js
@@ -0,0 +1,259 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ cc.TMXLayer.CanvasRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._needDraw = true;
+ };
+
+ var proto = cc.TMXLayer.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ proto.constructor = cc.TMXLayer.CanvasRenderCmd;
+
+ proto.visit = function (parentCmd) {
+ var node = this._node, renderer = cc.renderer;
+
+ parentCmd = parentCmd || this.getParentRenderCmd();
+ if (parentCmd) {
+ this._curLevel = parentCmd._curLevel + 1;
+ }
+
+ // quick return if not visible
+ if (!node._visible)
+ return;
+
+ if (isNaN(node._customZ)) {
+ node._vertexZ = renderer.assignedZ;
+ renderer.assignedZ += renderer.assignedZStep;
+ }
+
+ this._syncStatus(parentCmd);
+
+ // Visit children
+ var children = node._children, child,
+ spTiles = node._spriteTiles,
+ i, len = children.length;
+ if (len > 0) {
+ node.sortAllChildren();
+ // draw children zOrder < 0
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder < 0) {
+ child._renderCmd.visit(this);
+ }
+ else {
+ break;
+ }
+ }
+
+ renderer.pushRenderCommand(this);
+ for (; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder === 0 && spTiles[child.tag]) {
+ if (isNaN(child._customZ)) {
+ child._vertexZ = renderer.assignedZ;
+ renderer.assignedZ += renderer.assignedZStep;
+ }
+ child._renderCmd.updateStatus();
+ continue;
+ }
+ child._renderCmd.visit(this);
+ }
+ } else {
+ renderer.pushRenderCommand(this);
+ }
+ this._dirtyFlag = 0;
+ };
+
+ proto.rendering = function (ctx, scaleX, scaleY) {
+ var node = this._node, hasRotation = (node._rotationX || node._rotationY),
+ layerOrientation = node.layerOrientation,
+ tiles = node.tiles,
+ alpha = node._opacity / 255;
+
+ if (!tiles || alpha <= 0) {
+ return;
+ }
+
+ var maptw = node._mapTileSize.width,
+ mapth = node._mapTileSize.height,
+ tilew = node.tileset._tileSize.width / cc.director._contentScaleFactor,
+ tileh = node.tileset._tileSize.height / cc.director._contentScaleFactor,
+ extw = tilew - maptw,
+ exth = tileh - mapth,
+ winw = cc.winSize.width,
+ winh = cc.winSize.height,
+ rows = node._layerSize.height,
+ cols = node._layerSize.width,
+ grids = node._texGrids,
+ spTiles = node._spriteTiles,
+ wt = this._worldTransform,
+ ox = -node._contentSize.width * node._anchorPoint.x,
+ oy = -node._contentSize.height * node._anchorPoint.y,
+ a = wt.a, b = wt.b, c = wt.c, d = wt.d,
+ mapx = ox * a + oy * c + wt.tx,
+ mapy = ox * b + oy * d + wt.ty;
+
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext();
+
+ // Culling
+ var startCol = 0, startRow = 0,
+ maxCol = cols, maxRow = rows;
+ if (!hasRotation && layerOrientation === cc.TMX_ORIENTATION_ORTHO) {
+ startCol = Math.floor(-(mapx - extw * a) / (maptw * a));
+ startRow = Math.floor((mapy - exth * d + mapth * rows * d - winh) / (mapth * d));
+ maxCol = Math.ceil((winw - mapx + extw * a) / (maptw * a));
+ maxRow = rows - Math.floor(-(mapy + exth * d) / (mapth * d));
+ // Adjustment
+ if (startCol < 0) startCol = 0;
+ if (startRow < 0) startRow = 0;
+ if (maxCol > cols) maxCol = cols;
+ if (maxRow > rows) maxRow = rows;
+ }
+
+ var i, row, col, colOffset = startRow * cols, z,
+ gid, grid, tex, cmd,
+ mask = cc.TMX_TILE_FLIPPED_MASK,
+ top, left, bottom, right, dw = tilew, dh = tileh,
+ w = tilew * a, h = tileh * d, gt, gl, gb, gr,
+ flippedX = false, flippedY = false;
+
+ // Draw culled sprite tiles
+ z = colOffset + startCol;
+ for (i in spTiles) {
+ if (i < z && spTiles[i]) {
+ cmd = spTiles[i]._renderCmd;
+ if (spTiles[i]._localZOrder === 0 && !!cmd.rendering) {
+ cmd.rendering(ctx, scaleX, scaleY);
+ }
+ }
+ else if (i >= z) {
+ break;
+ }
+ }
+
+ wrapper.setTransform(wt, scaleX, scaleY);
+ wrapper.setGlobalAlpha(alpha);
+
+ for (row = startRow; row < maxRow; ++row) {
+ for (col = startCol; col < maxCol; ++col) {
+ z = colOffset + col;
+ // Skip sprite tiles
+ if (spTiles[z]) {
+ cmd = spTiles[z]._renderCmd;
+ if (spTiles[z]._localZOrder === 0 && !!cmd.rendering) {
+ cmd.rendering(ctx, scaleX, scaleY);
+ wrapper.setTransform(wt, scaleX, scaleY);
+ wrapper.setGlobalAlpha(alpha);
+ }
+ continue;
+ }
+
+ gid = node.tiles[z];
+ grid = grids[(gid & mask) >>> 0];
+ if (!grid) {
+ continue;
+ }
+ tex = node._textures[grid.texId];
+ if (!tex || !tex._htmlElementObj) {
+ continue;
+ }
+
+ switch (layerOrientation) {
+ case cc.TMX_ORIENTATION_ORTHO:
+ left = col * maptw;
+ bottom = -(rows - row - 1) * mapth;
+ break;
+ case cc.TMX_ORIENTATION_ISO:
+ left = maptw / 2 * ( cols + col - row - 1);
+ bottom = -mapth / 2 * ( rows * 2 - col - row - 2);
+ break;
+ case cc.TMX_ORIENTATION_HEX:
+ left = col * maptw * 3 / 4;
+ bottom = -(rows - row - 1) * mapth + ((col % 2 === 1) ? (-mapth / 2) : 0);
+ break;
+ }
+ right = left + tilew;
+ top = bottom - tileh;
+ // TMX_ORIENTATION_ISO trim
+ if (!hasRotation && layerOrientation === cc.TMX_ORIENTATION_ISO) {
+ gb = -mapy + bottom * d;
+ if (gb < -winh - h) {
+ col += Math.floor((-winh - gb) * 2 / h) - 1;
+ continue;
+ }
+ gr = mapx + right * a;
+ if (gr < -w) {
+ col += Math.floor((-gr) * 2 / w) - 1;
+ continue;
+ }
+ gl = mapx + left * a;
+ gt = -mapy + top * d;
+ if (gl > winw || gt > 0) {
+ col = maxCol;
+ continue;
+ }
+ }
+
+ // Rotation and Flip
+ if (gid > cc.TMX_TILE_DIAGONAL_FLAG) {
+ flippedX = (gid & cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0;
+ flippedY = (gid & cc.TMX_TILE_VERTICAL_FLAG) >>> 0;
+ }
+
+ if (flippedX) {
+ left = -right;
+ context.scale(-1, 1);
+ }
+ if (flippedY) {
+ top = -bottom;
+ context.scale(1, -1);
+ }
+
+ context.drawImage(tex._htmlElementObj,
+ grid.x, grid.y, grid.width, grid.height,
+ left, top, dw, dh);
+ // Revert flip
+ if (flippedX) {
+ context.scale(-1, 1);
+ }
+ if (flippedY) {
+ context.scale(1, -1);
+ }
+ cc.g_NumberOfDraws++;
+ }
+ colOffset += cols;
+ }
+
+ // Draw culled sprite tiles
+ for (i in spTiles) {
+ if (i > z && spTiles[i]) {
+ cmd = spTiles[i]._renderCmd;
+ if (spTiles[i]._localZOrder === 0 && !!cmd.rendering) {
+ cmd.rendering(ctx, scaleX, scaleY);
+ }
+ }
+ }
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js b/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js
new file mode 100644
index 0000000..d0e90be
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js
@@ -0,0 +1,259 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ cc.TMXLayer.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+ this._vertices = [
+ {x: 0, y: 0},
+ {x: 0, y: 0},
+ {x: 0, y: 0},
+ {x: 0, y: 0}
+ ];
+ this._color = new Uint32Array(1);
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST);
+
+ var radian = Math.PI * 90 / 180;
+ this._sin90 = Math.sin(radian);
+ this._cos90 = Math.cos(radian);
+ radian = radian * 3;
+ this._sin270 = Math.sin(radian);
+ this._cos270 = Math.cos(radian);
+ };
+
+ var proto = cc.TMXLayer.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ proto.constructor = cc.TMXLayer.WebGLRenderCmd;
+
+ proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset) {
+ var node = this._node, hasRotation = (node._rotationX || node._rotationY),
+ layerOrientation = node.layerOrientation,
+ tiles = node.tiles;
+
+ if (!tiles) {
+ return 0;
+ }
+
+ var scalex = cc.view._scaleX,
+ scaley = cc.view._scaleY,
+ maptw = node._mapTileSize.width,
+ mapth = node._mapTileSize.height,
+ tilew = node.tileset._tileSize.width / cc.director._contentScaleFactor,
+ tileh = node.tileset._tileSize.height / cc.director._contentScaleFactor,
+ extw = tilew - maptw,
+ exth = tileh - mapth,
+ winw = cc.winSize.width,
+ winh = cc.winSize.height,
+ rows = node._layerSize.height,
+ cols = node._layerSize.width,
+ grids = node._texGrids,
+ spTiles = node._spriteTiles,
+ wt = this._worldTransform,
+ a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty,
+ ox = -node._contentSize.width * node._anchorPoint.x,
+ oy = -node._contentSize.height * node._anchorPoint.y,
+ mapx = ox * a + oy * c + tx,
+ mapy = ox * b + oy * d + ty;
+
+ var opacity = node._opacity,
+ cr = this._displayedColor.r,
+ cg = this._displayedColor.g,
+ cb = this._displayedColor.b;
+ if (node._opacityModifyRGB) {
+ var ca = opacity / 255;
+ cr *= ca;
+ cg *= ca;
+ cb *= ca;
+ }
+ this._color[0] = ((opacity << 24) | (cb << 16) | (cg << 8) | cr);
+
+ // Culling
+ var startCol = 0, startRow = 0,
+ maxCol = cols, maxRow = rows;
+ if (!hasRotation && layerOrientation === cc.TMX_ORIENTATION_ORTHO) {
+ startCol = Math.floor(-(mapx - extw * a) / (maptw * a));
+ startRow = Math.floor((mapy - exth * d + mapth * rows * d - winh) / (mapth * d));
+ maxCol = Math.ceil((winw - mapx + extw * a) / (maptw * a));
+ maxRow = rows - Math.floor(-(mapy + exth * d) / (mapth * d));
+ // Adjustment
+ if (startCol < 0) startCol = 0;
+ if (startRow < 0) startRow = 0;
+ if (maxCol > cols) maxCol = cols;
+ if (maxRow > rows) maxRow = rows;
+ }
+
+ var row, col,
+ offset = vertexDataOffset,
+ colOffset = startRow * cols, z, gid, grid,
+ mask = cc.TMX_TILE_FLIPPED_MASK,
+ i, top, left, bottom, right,
+ w = tilew * a, h = tileh * d, gt, gl, gb, gr,
+ wa = a, wb = b, wc = c, wd = d, wtx = tx, wty = ty, // world
+ flagged = false, flippedX = false, flippedY = false,
+ vertices = this._vertices;
+ for (row = startRow; row < maxRow; ++row) {
+ for (col = startCol; col < maxCol; ++col) {
+ // No more buffer
+ if (offset + 24 > f32buffer.length) {
+ cc.renderer._increaseBatchingSize((offset - vertexDataOffset) / 6);
+ cc.renderer._batchRendering();
+ vertexDataOffset = 0;
+ offset = 0;
+ }
+
+ z = colOffset + col;
+ // Skip sprite tiles
+ if (spTiles[z]) {
+ continue;
+ }
+
+ gid = node.tiles[z];
+ grid = grids[(gid & mask) >>> 0];
+ if (!grid) {
+ continue;
+ }
+
+ // Vertices
+ switch (layerOrientation) {
+ case cc.TMX_ORIENTATION_ORTHO:
+ left = col * maptw;
+ bottom = (rows - row - 1) * mapth;
+ z = node._vertexZ + cc.renderer.assignedZStep * z / tiles.length;
+ break;
+ case cc.TMX_ORIENTATION_ISO:
+ left = maptw / 2 * ( cols + col - row - 1);
+ bottom = mapth / 2 * ( rows * 2 - col - row - 2);
+ z = node._vertexZ + cc.renderer.assignedZStep * (node.height - bottom) / node.height;
+ break;
+ case cc.TMX_ORIENTATION_HEX:
+ left = col * maptw * 3 / 4;
+ bottom = (rows - row - 1) * mapth + ((col % 2 === 1) ? (-mapth / 2) : 0);
+ z = node._vertexZ + cc.renderer.assignedZStep * (node.height - bottom) / node.height;
+ break;
+ }
+ right = left + tilew;
+ top = bottom + tileh;
+ // TMX_ORIENTATION_ISO trim
+ if (!hasRotation && layerOrientation === cc.TMX_ORIENTATION_ISO) {
+ gb = mapy + bottom * d;
+ if (gb > winh + h) {
+ col += Math.floor((gb - winh) * 2 / h) - 1;
+ continue;
+ }
+ gr = mapx + right * a;
+ if (gr < -w) {
+ col += Math.floor((-gr) * 2 / w) - 1;
+ continue;
+ }
+ gl = mapx + left * a;
+ gt = mapy + top * d;
+ if (gl > winw || gt < 0) {
+ col = maxCol;
+ continue;
+ }
+ }
+ // Rotation and Flip
+ if (gid > cc.TMX_TILE_DIAGONAL_FLAG) {
+ flagged = true;
+ flippedX = (gid & cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0;
+ flippedY = (gid & cc.TMX_TILE_VERTICAL_FLAG) >>> 0;
+ // if ((gid & cc.TMX_TILE_DIAGONAL_FLAG) >>> 0) {
+ // var flag = (gid & (cc.TMX_TILE_HORIZONTAL_FLAG | cc.TMX_TILE_VERTICAL_FLAG) >>> 0) >>> 0;
+ // // handle the 4 diagonally flipped states.
+ // var la, lb, lc, ld;
+ // if (flag === cc.TMX_TILE_HORIZONTAL_FLAG || flag === (cc.TMX_TILE_VERTICAL_FLAG | cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0) {
+ // lb = -(lc = this._sin90);
+ // la = ld = this._cos90;
+ // }
+ // else {
+ // lb = -(lc = this._sin270);
+ // la = ld = this._cos270;
+ // }
+ // left += grid.width * scalex / 2;
+ // bottom += grid.height * scaley / 2;
+ // wa = la * a + lb * c;
+ // wb = la * b + lb * d;
+ // wc = lc * a + ld * c;
+ // wd = lc * b + ld * d;
+ // wtx = a * left + c * bottom + tx;
+ // wty = d * bottom + ty + b * left;
+ // right = right - left;
+ // top = top - bottom;
+ // left = -right;
+ // bottom = -top;
+ // }
+ }
+
+ vertices[0].x = left * wa + top * wc + wtx; // tl
+ vertices[0].y = left * wb + top * wd + wty;
+ vertices[1].x = left * wa + bottom * wc + wtx; // bl
+ vertices[1].y = left * wb + bottom * wd + wty;
+ vertices[2].x = right * wa + top * wc + wtx; // tr
+ vertices[2].y = right * wb + top * wd + wty;
+ vertices[3].x = right * wa + bottom * wc + wtx; // br
+ vertices[3].y = right * wb + bottom * wd + wty;
+
+ for (i = 0; i < 4; ++i) {
+ f32buffer[offset] = vertices[i].x;
+ f32buffer[offset + 1] = vertices[i].y;
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = this._color[0];
+ switch (i) {
+ case 0: // tl
+ f32buffer[offset + 4] = flippedX ? grid.r : grid.l;
+ f32buffer[offset + 5] = flippedY ? grid.b : grid.t;
+ break;
+ case 1: // bl
+ f32buffer[offset + 4] = flippedX ? grid.r : grid.l;
+ f32buffer[offset + 5] = flippedY ? grid.t : grid.b;
+ break;
+ case 2: // tr
+ f32buffer[offset + 4] = flippedX ? grid.l : grid.r;
+ f32buffer[offset + 5] = flippedY ? grid.b : grid.t;
+ break;
+ case 3: // br
+ f32buffer[offset + 4] = flippedX ? grid.l : grid.r;
+ f32buffer[offset + 5] = flippedY ? grid.t : grid.b;
+ break;
+ }
+
+ offset += 6;
+ }
+ if (flagged) {
+ wa = a;
+ wb = b;
+ wc = c;
+ wd = d;
+ wtx = tx;
+ wty = ty;
+ flippedX = false;
+ flippedY = false;
+ flagged = false;
+ }
+ }
+ colOffset += cols;
+ }
+ return (offset - vertexDataOffset) / 6;
+ };
+})();
diff --git a/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXObjectGroup.js b/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXObjectGroup.js
new file mode 100644
index 0000000..b5d41db
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXObjectGroup.js
@@ -0,0 +1,157 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * cc.TMXObjectGroup represents the TMX object group.
+ * @class
+ * @extends cc.Class
+ *
+ * @property {Array} properties - Properties from the group. They can be added using tilemap editors
+ * @property {String} groupName - Name of the group
+ */
+cc.TMXObjectGroup = cc.Class.extend(/** @lends cc.TMXObjectGroup# */{
+ properties: null,
+ groupName: "",
+
+ _positionOffset: null,
+ _objects: null,
+
+ /**
+ * The cc.TMXObjectGroup's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.TMXObjectGroup()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor:function () {
+ this.groupName = "";
+ this._positionOffset = cc.p(0,0);
+ this.properties = [];
+ this._objects = [];
+ },
+
+ /**
+ * Offset position of child objects
+ * @return {cc.Point}
+ */
+ getPositionOffset:function () {
+ return cc.p(this._positionOffset);
+ },
+
+ /**
+ * Offset position of child objects
+ * @param {cc.Point} offset
+ */
+ setPositionOffset:function (offset) {
+ this._positionOffset.x = offset.x;
+ this._positionOffset.y = offset.y;
+ },
+
+ /**
+ * List of properties stored in a dictionary
+ * @return {Array}
+ */
+ getProperties:function () {
+ return this.properties;
+ },
+
+ /**
+ * List of properties stored in a dictionary
+ * @param {object} Var
+ */
+ setProperties:function (Var) {
+ this.properties.push(Var);
+ },
+
+ /**
+ * Gets the Group name.
+ * @return {String}
+ */
+ getGroupName:function () {
+ return this.groupName.toString();
+ },
+
+ /**
+ * Set the Group name
+ * @param {String} groupName
+ */
+ setGroupName:function (groupName) {
+ this.groupName = groupName;
+ },
+
+ /**
+ * Return the value for the specific property name
+ * @param {String} propertyName
+ * @return {object}
+ */
+ propertyNamed:function (propertyName) {
+ return this.properties[propertyName];
+ },
+
+ /**
+ * Return the dictionary for the specific object name.
+ * It will return the 1st object found on the array for the given name.
+ * @deprecated since v3.4 please use .getObject
+ * @param {String} objectName
+ * @return {object|Null}
+ */
+ objectNamed:function (objectName) {
+ return this.getObject(objectName);
+ },
+
+ /**
+ * Return the dictionary for the specific object name.
+ * It will return the 1st object found on the array for the given name.
+ * @param {String} objectName
+ * @return {object|Null}
+ */
+ getObject: function(objectName){
+ if (this._objects && this._objects.length > 0) {
+ var locObjects = this._objects;
+ for (var i = 0, len = locObjects.length; i < len; i++) {
+ var name = locObjects[i]["name"];
+ if (name && name === objectName)
+ return locObjects[i];
+ }
+ }
+ // object not found
+ return null;
+ },
+
+ /**
+ * Gets the objects.
+ * @return {Array}
+ */
+ getObjects:function () {
+ return this._objects;
+ },
+
+ /**
+ * Set the objects.
+ * @param {object} objects
+ */
+ setObjects:function (objects) {
+ this._objects.push(objects);
+ }
+});
diff --git a/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXTiledMap.js b/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXTiledMap.js
new file mode 100644
index 0000000..5ca4107
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXTiledMap.js
@@ -0,0 +1,478 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ Orthogonal orientation
+ * @constant
+ * @type Number
+ */
+cc.TMX_ORIENTATION_ORTHO = 0;
+
+/**
+ * Hexagonal orientation
+ * @constant
+ * @type Number
+ */
+
+cc.TMX_ORIENTATION_HEX = 1;
+
+/**
+ * Isometric orientation
+ * @constant
+ * @type Number
+ */
+cc.TMX_ORIENTATION_ISO = 2;
+
+/**
+ * cc.TMXTiledMap knows how to parse and render a TMX map.
+ *
+ * It adds support for the TMX tiled map format used by http://www.mapeditor.org
+ * It supports isometric, hexagonal and orthogonal tiles.
+ * It also supports object groups, objects, and properties.
+ *
+ * Features:
+ * - Each tile will be treated as an cc.Sprite
+ * - The sprites are created on demand. They will be created only when you call "layer.getTileAt(position)"
+ * - Each tile can be rotated / moved / scaled / tinted / "opacitied", since each tile is a cc.Sprite
+ * - Tiles can be added/removed in runtime
+ * - The z-order of the tiles can be modified in runtime
+ * - Each tile has an anchorPoint of (0,0)
+ * - The anchorPoint of the TMXTileMap is (0,0)
+ * - The TMX layers will be added as a child
+ * - The TMX layers will be aliased by default
+ * - The tileset image will be loaded using the cc.TextureCache
+ * - Each tile will have a unique tag
+ * - Each tile will have a unique z value. top-left: z=1, bottom-right: z=max z
+ * - Each object group will be treated as an cc.MutableArray
+ * - Object class which will contain all the properties in a dictionary
+ * - Properties can be assigned to the Map, Layer, Object Group, and Object
+ *
+ * Limitations:
+ * - It only supports one tileset per layer.
+ * - Embedded images are not supported
+ * - It only supports the XML format (the JSON format is not supported)
+ *
+ * Technical description:
+ * Each layer is created using an cc.TMXLayer (subclass of cc.SpriteBatchNode). If you have 5 layers, then 5 cc.TMXLayer will be created,
+ * unless the layer visibility is off. In that case, the layer won't be created at all.
+ * You can obtain the layers (cc.TMXLayer objects) at runtime by:
+ * - map.getChildByTag(tag_number); // 0=1st layer, 1=2nd layer, 2=3rd layer, etc...
+ * - map.getLayer(name_of_the_layer);
+ *
+ * Each object group is created using a cc.TMXObjectGroup which is a subclass of cc.MutableArray.
+ * You can obtain the object groups at runtime by:
+ * - map.getObjectGroup(name_of_the_object_group);
+ *
+ * Each object is a cc.TMXObject.
+ *
+ * Each property is stored as a key-value pair in an cc.MutableDictionary.
+ * You can obtain the properties at runtime by:
+ *
+ * map.getProperty(name_of_the_property);
+ * layer.getProperty(name_of_the_property);
+ * objectGroup.getProperty(name_of_the_property);
+ * object.getProperty(name_of_the_property);
+ * @class
+ * @extends cc.Node
+ * @param {String} tmxFile tmxFile fileName or content string
+ * @param {String} resourcePath If tmxFile is a file name ,it is not required.If tmxFile is content string ,it is must required.
+
+ *
+ * @property {Array} properties - Properties from the map. They can be added using tilemap editors
+ * @property {Number} mapOrientation - Map orientation
+ * @property {Array} objectGroups - Object groups of the map
+ * @property {Number} mapWidth - Width of the map
+ * @property {Number} mapHeight - Height of the map
+ * @property {Number} tileWidth - Width of a tile
+ * @property {Number} tileHeight - Height of a tile
+ *
+ * @example
+ * //example
+ * 1.
+ * //create a TMXTiledMap with file name
+ * var tmxTiledMap = new cc.TMXTiledMap("res/orthogonal-test1.tmx");
+ * 2.
+ * //create a TMXTiledMap with content string and resource path
+ * var resources = "res/TileMaps";
+ * var filePath = "res/TileMaps/orthogonal-test1.tmx";
+ * var xmlStr = cc.loader.getRes(filePath);
+ * var tmxTiledMap = new cc.TMXTiledMap(xmlStr, resources);
+ */
+cc.TMXTiledMap = cc.Node.extend(/** @lends cc.TMXTiledMap# */{
+ properties: null,
+ mapOrientation: null,
+ objectGroups: null,
+
+ //the map's size property measured in tiles
+ _mapSize: null,
+ _tileSize: null,
+ //tile properties
+ _tileProperties: null,
+ _className: "TMXTiledMap",
+
+ /**
+ * Creates a TMX Tiled Map with a TMX file or content string.
+ * Constructor of cc.TMXTiledMap
+ * @param {String} tmxFile tmxFile fileName or content string
+ * @param {String} resourcePath If tmxFile is a file name ,it is not required.If tmxFile is content string ,it is must required.
+ */
+ ctor:function(tmxFile,resourcePath){
+ cc.Node.prototype.ctor.call(this);
+ this._mapSize = cc.size(0, 0);
+ this._tileSize = cc.size(0, 0);
+
+ if(resourcePath !== undefined){
+ this.initWithXML(tmxFile,resourcePath);
+ }else if(tmxFile !== undefined){
+ this.initWithTMXFile(tmxFile);
+ }
+ },
+
+ /**
+ * Gets the map size.
+ * @return {cc.Size}
+ */
+ getMapSize:function () {
+ return cc.size(this._mapSize.width, this._mapSize.height);
+ },
+
+ /**
+ * Set the map size.
+ * @param {cc.Size} Var
+ */
+ setMapSize:function (Var) {
+ this._mapSize.width = Var.width;
+ this._mapSize.height = Var.height;
+ },
+
+ _getMapWidth: function () {
+ return this._mapSize.width;
+ },
+ _setMapWidth: function (width) {
+ this._mapSize.width = width;
+ },
+ _getMapHeight: function () {
+ return this._mapSize.height;
+ },
+ _setMapHeight: function (height) {
+ this._mapSize.height = height;
+ },
+
+ /**
+ * Gets the tile size.
+ * @return {cc.Size}
+ */
+ getTileSize:function () {
+ return cc.size(this._tileSize.width, this._tileSize.height);
+ },
+
+ /**
+ * Set the tile size
+ * @param {cc.Size} Var
+ */
+ setTileSize:function (Var) {
+ this._tileSize.width = Var.width;
+ this._tileSize.height = Var.height;
+ },
+
+ _getTileWidth: function () {
+ return this._tileSize.width;
+ },
+ _setTileWidth: function (width) {
+ this._tileSize.width = width;
+ },
+ _getTileHeight: function () {
+ return this._tileSize.height;
+ },
+ _setTileHeight: function (height) {
+ this._tileSize.height = height;
+ },
+
+ /**
+ * map orientation
+ * @return {Number}
+ */
+ getMapOrientation:function () {
+ return this.mapOrientation;
+ },
+
+ /**
+ * map orientation
+ * @param {Number} Var
+ */
+ setMapOrientation:function (Var) {
+ this.mapOrientation = Var;
+ },
+
+ /**
+ * object groups
+ * @return {Array}
+ */
+ getObjectGroups:function () {
+ return this.objectGroups;
+ },
+
+ /**
+ * object groups
+ * @param {Array} Var
+ */
+ setObjectGroups:function (Var) {
+ this.objectGroups = Var;
+ },
+
+ /**
+ * Gets the properties
+ * @return {object}
+ */
+ getProperties:function () {
+ return this.properties;
+ },
+
+ /**
+ * Set the properties
+ * @param {object} Var
+ */
+ setProperties:function (Var) {
+ this.properties = Var;
+ },
+
+ /**
+ * Initializes the instance of cc.TMXTiledMap with tmxFile
+ * @param {String} tmxFile
+ * @return {Boolean} Whether the initialization was successful.
+ * @example
+ * //example
+ * var map = new cc.TMXTiledMap()
+ * map.initWithTMXFile("hello.tmx");
+ */
+ initWithTMXFile:function (tmxFile) {
+ if(!tmxFile || tmxFile.length === 0)
+ throw new Error("cc.TMXTiledMap.initWithTMXFile(): tmxFile should be non-null or non-empty string.");
+ this.width = 0;
+ this.height = 0;
+ var mapInfo = new cc.TMXMapInfo(tmxFile);
+ if (!mapInfo)
+ return false;
+
+ var locTilesets = mapInfo.getTilesets();
+ if(!locTilesets || locTilesets.length === 0)
+ cc.log("cc.TMXTiledMap.initWithTMXFile(): Map not found. Please check the filename.");
+ this._buildWithMapInfo(mapInfo);
+ return true;
+ },
+
+ /**
+ * Initializes the instance of cc.TMXTiledMap with tmxString
+ * @param {String} tmxString
+ * @param {String} resourcePath
+ * @return {Boolean} Whether the initialization was successful.
+ */
+ initWithXML:function(tmxString, resourcePath){
+ this.width = 0;
+ this.height = 0;
+
+ var mapInfo = new cc.TMXMapInfo(tmxString, resourcePath);
+ var locTilesets = mapInfo.getTilesets();
+ if(!locTilesets || locTilesets.length === 0)
+ cc.log("cc.TMXTiledMap.initWithXML(): Map not found. Please check the filename.");
+ this._buildWithMapInfo(mapInfo);
+ return true;
+ },
+
+ _buildWithMapInfo:function (mapInfo) {
+ this._mapSize = mapInfo.getMapSize();
+ this._tileSize = mapInfo.getTileSize();
+ this.mapOrientation = mapInfo.orientation;
+ this.objectGroups = mapInfo.getObjectGroups();
+ this.properties = mapInfo.properties;
+ this._tileProperties = mapInfo.getTileProperties();
+
+ var idx = 0;
+ var layers = mapInfo.getLayers();
+ if (layers) {
+ var layerInfo = null;
+ for (var i = 0, len = layers.length; i < len; i++) {
+ layerInfo = layers[i];
+ if (layerInfo && layerInfo.visible) {
+ var child = this._parseLayer(layerInfo, mapInfo);
+ this.addChild(child, idx, idx);
+ // update content size with the max size
+ this.width = Math.max(this.width, child.width);
+ this.height = Math.max(this.height, child.height);
+ idx++;
+ }
+ }
+ }
+ },
+
+ /**
+ * Return All layers array.
+ * @returns {Array}
+ */
+ allLayers: function () {
+ var retArr = [], locChildren = this._children;
+ for(var i = 0, len = locChildren.length;i< len;i++){
+ var layer = locChildren[i];
+ if(layer && layer instanceof cc.TMXLayer)
+ retArr.push(layer);
+ }
+ return retArr;
+ },
+
+ /**
+ * return the TMXLayer for the specific layer
+ * @param {String} layerName
+ * @return {cc.TMXLayer}
+ */
+ getLayer:function (layerName) {
+ if(!layerName || layerName.length === 0)
+ throw new Error("cc.TMXTiledMap.getLayer(): layerName should be non-null or non-empty string.");
+ var locChildren = this._children;
+ for (var i = 0; i < locChildren.length; i++) {
+ var layer = locChildren[i];
+ if (layer && layer.layerName === layerName)
+ return layer;
+ }
+ // layer not found
+ return null;
+ },
+
+ /**
+ * Return the TMXObjectGroup for the specific group
+ * @param {String} groupName
+ * @return {cc.TMXObjectGroup}
+ */
+ getObjectGroup:function (groupName) {
+ if(!groupName || groupName.length === 0)
+ throw new Error("cc.TMXTiledMap.getObjectGroup(): groupName should be non-null or non-empty string.");
+ if (this.objectGroups) {
+ for (var i = 0; i < this.objectGroups.length; i++) {
+ var objectGroup = this.objectGroups[i];
+ if (objectGroup && objectGroup.groupName === groupName) {
+ return objectGroup;
+ }
+ }
+ }
+ // objectGroup not found
+ return null;
+ },
+
+ /**
+ * Return the value for the specific property name
+ * @param {String} propertyName
+ * @return {String}
+ */
+ getProperty:function (propertyName) {
+ return this.properties[propertyName.toString()];
+ },
+
+ /**
+ * Return properties dictionary for tile GID
+ * @param {Number} GID
+ * @return {object}
+ * @deprecated
+ */
+ propertiesForGID:function (GID) {
+ cc.log("propertiesForGID is deprecated. Please use getPropertiesForGID instead.");
+ return this.getPropertiesForGID[GID];
+ },
+
+ /**
+ * Return properties dictionary for tile GID
+ * @param {Number} GID
+ * @return {object}
+ */
+ getPropertiesForGID: function(GID) {
+ return this._tileProperties[GID];
+ },
+
+ _parseLayer:function (layerInfo, mapInfo) {
+ var tileset = this._tilesetForLayer(layerInfo, mapInfo);
+ var layer = new cc.TMXLayer(tileset, layerInfo, mapInfo);
+ // tell the layerinfo to release the ownership of the tiles map.
+ layerInfo.ownTiles = false;
+ return layer;
+ },
+
+ _tilesetForLayer:function (layerInfo, mapInfo) {
+ var size = layerInfo._layerSize;
+ var tilesets = mapInfo.getTilesets();
+ if (tilesets) {
+ for (var i = tilesets.length - 1; i >= 0; i--) {
+ var tileset = tilesets[i];
+ if (tileset) {
+ for (var y = 0; y < size.height; y++) {
+ for (var x = 0; x < size.width; x++) {
+ var pos = x + size.width * y;
+ var gid = layerInfo._tiles[pos];
+ if (gid !== 0) {
+ // Optimization: quick return
+ // if the layer is invalid (more than 1 tileset per layer) an cc.assert will be thrown later
+ if (((gid & cc.TMX_TILE_FLIPPED_MASK)>>>0) >= tileset.firstGid) {
+ return tileset;
+ }
+ }
+
+ }
+ }
+ }
+ }
+ }
+
+ // If all the tiles are 0, return empty tileset
+ cc.log("cocos2d: Warning: TMX Layer " + layerInfo.name + " has no tiles");
+ return null;
+ }
+});
+
+var _p = cc.TMXTiledMap.prototype;
+
+// Extended properties
+/** @expose */
+_p.mapWidth;
+cc.defineGetterSetter(_p, "mapWidth", _p._getMapWidth, _p._setMapWidth);
+/** @expose */
+_p.mapHeight;
+cc.defineGetterSetter(_p, "mapHeight", _p._getMapHeight, _p._setMapHeight);
+/** @expose */
+_p.tileWidth;
+cc.defineGetterSetter(_p, "tileWidth", _p._getTileWidth, _p._setTileWidth);
+/** @expose */
+_p.tileHeight;
+cc.defineGetterSetter(_p, "tileHeight", _p._getTileHeight, _p._setTileHeight);
+
+
+/**
+ * Creates a TMX Tiled Map with a TMX file or content string.
+ * Implementation cc.TMXTiledMap
+ * @deprecated since v3.0 please use new cc.TMXTiledMap(tmxFile,resourcePath) instead.
+ * @param {String} tmxFile tmxFile fileName or content string
+ * @param {String} resourcePath If tmxFile is a file name ,it is not required.If tmxFile is content string ,it is must required.
+ * @return {cc.TMXTiledMap|undefined}
+ */
+cc.TMXTiledMap.create = function (tmxFile,resourcePath) {
+ return new cc.TMXTiledMap(tmxFile,resourcePath);
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXXMLParser.js b/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXXMLParser.js
new file mode 100644
index 0000000..70509e6
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/tilemap/CCTMXXMLParser.js
@@ -0,0 +1,954 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMX_PROPERTY_NONE = 0;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMX_PROPERTY_MAP = 1;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMX_PROPERTY_LAYER = 2;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMX_PROPERTY_OBJECTGROUP = 3;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMX_PROPERTY_OBJECT = 4;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMX_PROPERTY_TILE = 5;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMX_TILE_HORIZONTAL_FLAG = 0x80000000;
+
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMX_TILE_VERTICAL_FLAG = 0x40000000;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMX_TILE_DIAGONAL_FLAG = 0x20000000;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMX_TILE_FLIPPED_ALL = (cc.TMX_TILE_HORIZONTAL_FLAG | cc.TMX_TILE_VERTICAL_FLAG | cc.TMX_TILE_DIAGONAL_FLAG) >>> 0;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMX_TILE_FLIPPED_MASK = (~(cc.TMX_TILE_FLIPPED_ALL)) >>> 0;
+
+// Bits on the far end of the 32-bit global tile ID (GID's) are used for tile flags
+
+/**
+ * cc.TMXLayerInfo contains the information about the layers like:
+ * - Layer name
+ * - Layer size
+ * - Layer opacity at creation time (it can be modified at runtime)
+ * - Whether the layer is visible (if it's not visible, then the CocosNode won't be created)
+ *
+ * This information is obtained from the TMX file.
+ * @class
+ * @extends cc.Class
+ *
+ * @property {Array} properties - Properties of the layer info.
+ */
+cc.TMXLayerInfo = cc.Class.extend(/** @lends cc.TMXLayerInfo# */{
+ properties:null,
+
+ name:"",
+ _layerSize:null,
+ _tiles:null,
+ visible:null,
+ _opacity:null,
+ ownTiles:true,
+ _minGID:100000,
+ _maxGID:0,
+ offset:null,
+
+ ctor:function () {
+ this.properties = [];
+ this.name = "";
+ this._layerSize = null;
+ this._tiles = null;
+ this.visible = true;
+ this._opacity = 0;
+ this.ownTiles = true;
+ this._minGID = 100000;
+ this._maxGID = 0;
+ this.offset = cc.p(0,0);
+ },
+
+ /**
+ * Gets the Properties.
+ * @return {Array}
+ */
+ getProperties:function () {
+ return this.properties;
+ },
+
+ /**
+ * Set the Properties.
+ * @param {object} value
+ */
+ setProperties:function (value) {
+ this.properties = value;
+ }
+});
+
+/**
+ * cc.TMXTilesetInfo contains the information about the tilesets like:
+ * - Tileset name
+ * - Tileset spacing
+ * - Tileset margin
+ * - size of the tiles
+ * - Image used for the tiles
+ * - Image size
+ *
+ * This information is obtained from the TMX file.
+ * @class
+ * @extends cc.Class
+ *
+ * @property {string} name - Tileset name
+ * @property {number} firstGid - First grid
+ * @property {number} spacing - Spacing
+ * @property {number} margin - Margin
+ * @property {string} sourceImage - Filename containing the tiles (should be sprite sheet / texture atlas)
+ * @property {cc.Size|null} imageSize - Size in pixels of the image
+ */
+cc.TMXTilesetInfo = cc.Class.extend(/** @lends cc.TMXTilesetInfo# */{
+
+ //Tileset name
+ name:"",
+
+ //First grid
+ firstGid:0,
+ _tileSize:null,
+
+ //Spacing
+ spacing:0,
+
+ //Margin
+ margin:0,
+
+ //Filename containing the tiles (should be sprite sheet / texture atlas)
+ sourceImage:"",
+
+ //Size in pixels of the image
+ imageSize:null,
+
+ ctor:function () {
+ this._tileSize = cc.size(0, 0);
+ this.imageSize = cc.size(0, 0);
+ },
+
+ /**
+ * Return rect
+ * @param {Number} gid
+ * @return {cc.Rect}
+ */
+ rectForGID:function (gid, result) {
+ var rect = result || cc.rect(0, 0, 0, 0);
+ rect.width = this._tileSize.width;
+ rect.height = this._tileSize.height;
+ gid &= cc.TMX_TILE_FLIPPED_MASK;
+ gid = gid - parseInt(this.firstGid, 10);
+ var max_x = parseInt((this.imageSize.width - this.margin * 2 + this.spacing) / (this._tileSize.width + this.spacing), 10);
+ rect.x = parseInt((gid % max_x) * (this._tileSize.width + this.spacing) + this.margin, 10);
+ rect.y = parseInt(parseInt(gid / max_x, 10) * (this._tileSize.height + this.spacing) + this.margin, 10);
+ return rect;
+ }
+});
+
+/**
+ * cc.TMXMapInfo contains the information about the map like:
+ *- Map orientation (hexagonal, isometric or orthogonal)
+ *- Tile size
+ *- Map size
+ *
+ * And it also contains:
+ * - Layers (an array of TMXLayerInfo objects)
+ * - Tilesets (an array of TMXTilesetInfo objects)
+ * - ObjectGroups (an array of TMXObjectGroupInfo objects)
+ *
+ * This information is obtained from the TMX file.
+ * @class
+ * @extends cc.saxParser
+ *
+ * @property {Array} properties - Properties of the map info.
+ * @property {Number} orientation - Map orientation.
+ * @property {Object} parentElement - Parent element.
+ * @property {Number} parentGID - Parent GID.
+ * @property {Object} layerAttrs - Layer attributes.
+ * @property {Boolean} storingCharacters - Is reading storing characters stream.
+ * @property {String} tmxFileName - TMX file name.
+ * @property {String} currentString - Current string stored from characters stream.
+ * @property {Number} mapWidth - Width of the map
+ * @property {Number} mapHeight - Height of the map
+ * @property {Number} tileWidth - Width of a tile
+ * @property {Number} tileHeight - Height of a tile
+ *
+ * @param {String} tmxFile fileName or content string
+ * @param {String} resourcePath If tmxFile is a file name ,it is not required.If tmxFile is content string ,it is must required.
+ * @example
+ * 1.
+ * //create a TMXMapInfo with file name
+ * var tmxMapInfo = new cc.TMXMapInfo("res/orthogonal-test1.tmx");
+ * 2.
+ * //create a TMXMapInfo with content string and resource path
+ * var resources = "res/TileMaps";
+ * var filePath = "res/TileMaps/orthogonal-test1.tmx";
+ * var xmlStr = cc.loader.getRes(filePath);
+ * var tmxMapInfo = new cc.TMXMapInfo(xmlStr, resources);
+ */
+cc.TMXMapInfo = cc.SAXParser.extend(/** @lends cc.TMXMapInfo# */{
+ properties:null,
+ orientation:null,
+ parentElement:null,
+ parentGID:null,
+ layerAttrs:0,
+ storingCharacters:false,
+ tmxFileName:null,
+ currentString:null,
+
+ _objectGroups:null,
+ _mapSize:null,
+ _tileSize:null,
+ _layers:null,
+ _tilesets:null,
+ // tile properties
+ _tileProperties:null,
+ _resources:"",
+ _currentFirstGID:0,
+
+ /**
+ * Creates a TMX Format with a tmx file or content string
+ * Constructor of cc.TMXMapInfo
+ * @param {String} tmxFile fileName or content string
+ * @param {String} resourcePath If tmxFile is a file name ,it is not required.If tmxFile is content string ,it is must required.
+ */
+ ctor:function (tmxFile, resourcePath) {
+ cc.SAXParser.prototype.ctor.apply(this);
+ this._mapSize = cc.size(0, 0);
+ this._tileSize = cc.size(0, 0);
+ this._layers = [];
+ this._tilesets = [];
+ this._objectGroups = [];
+ this.properties = [];
+ this._tileProperties = {};
+
+ this._currentFirstGID = 0;
+
+ if (resourcePath !== undefined) {
+ this.initWithXML(tmxFile,resourcePath);
+ } else if(tmxFile !== undefined){
+ this.initWithTMXFile(tmxFile);
+ }
+ },
+ /**
+ * Gets Map orientation.
+ * @return {Number}
+ */
+ getOrientation:function () {
+ return this.orientation;
+ },
+
+ /**
+ * Set the Map orientation.
+ * @param {Number} value
+ */
+ setOrientation:function (value) {
+ this.orientation = value;
+ },
+
+ /**
+ * Map width & height
+ * @return {cc.Size}
+ */
+ getMapSize:function () {
+ return cc.size(this._mapSize.width,this._mapSize.height);
+ },
+
+ /**
+ * Map width & height
+ * @param {cc.Size} value
+ */
+ setMapSize:function (value) {
+ this._mapSize.width = value.width;
+ this._mapSize.height = value.height;
+ },
+
+ _getMapWidth: function () {
+ return this._mapSize.width;
+ },
+ _setMapWidth: function (width) {
+ this._mapSize.width = width;
+ },
+ _getMapHeight: function () {
+ return this._mapSize.height;
+ },
+ _setMapHeight: function (height) {
+ this._mapSize.height = height;
+ },
+
+ /**
+ * Tiles width & height
+ * @return {cc.Size}
+ */
+ getTileSize:function () {
+ return cc.size(this._tileSize.width, this._tileSize.height);
+ },
+
+ /**
+ * Tiles width & height
+ * @param {cc.Size} value
+ */
+ setTileSize:function (value) {
+ this._tileSize.width = value.width;
+ this._tileSize.height = value.height;
+ },
+
+ _getTileWidth: function () {
+ return this._tileSize.width;
+ },
+ _setTileWidth: function (width) {
+ this._tileSize.width = width;
+ },
+ _getTileHeight: function () {
+ return this._tileSize.height;
+ },
+ _setTileHeight: function (height) {
+ this._tileSize.height = height;
+ },
+
+ /**
+ * Layers
+ * @return {Array}
+ */
+ getLayers:function () {
+ return this._layers;
+ },
+
+ /**
+ * Layers
+ * @param {cc.TMXLayerInfo} value
+ */
+ setLayers:function (value) {
+ this._layers.push(value);
+ },
+
+ /**
+ * tilesets
+ * @return {Array}
+ */
+ getTilesets:function () {
+ return this._tilesets;
+ },
+
+ /**
+ * tilesets
+ * @param {cc.TMXTilesetInfo} value
+ */
+ setTilesets:function (value) {
+ this._tilesets.push(value);
+ },
+
+ /**
+ * ObjectGroups
+ * @return {Array}
+ */
+ getObjectGroups:function () {
+ return this._objectGroups;
+ },
+
+ /**
+ * ObjectGroups
+ * @param {cc.TMXObjectGroup} value
+ */
+ setObjectGroups:function (value) {
+ this._objectGroups.push(value);
+ },
+
+ /**
+ * parent element
+ * @return {Object}
+ */
+ getParentElement:function () {
+ return this.parentElement;
+ },
+
+ /**
+ * parent element
+ * @param {Object} value
+ */
+ setParentElement:function (value) {
+ this.parentElement = value;
+ },
+
+ /**
+ * parent GID
+ * @return {Number}
+ */
+ getParentGID:function () {
+ return this.parentGID;
+ },
+
+ /**
+ * parent GID
+ * @param {Number} value
+ */
+ setParentGID:function (value) {
+ this.parentGID = value;
+ },
+
+ /**
+ * Layer attribute
+ * @return {Object}
+ */
+ getLayerAttribs:function () {
+ return this.layerAttrs;
+ },
+
+ /**
+ * Layer attribute
+ * @param {Object} value
+ */
+ setLayerAttribs:function (value) {
+ this.layerAttrs = value;
+ },
+
+ /**
+ * Is reading storing characters stream
+ * @return {Boolean}
+ */
+ getStoringCharacters:function () {
+ return this.storingCharacters;
+ },
+
+ /**
+ * Is reading storing characters stream
+ * @param {Boolean} value
+ */
+ setStoringCharacters:function (value) {
+ this.storingCharacters = value;
+ },
+
+ /**
+ * Properties
+ * @return {Array}
+ */
+ getProperties:function () {
+ return this.properties;
+ },
+
+ /**
+ * Properties
+ * @param {object} value
+ */
+ setProperties:function (value) {
+ this.properties = value;
+ },
+
+ /**
+ * Initializes a TMX format with a tmx file
+ * @param {String} tmxFile
+ * @return {Element}
+ */
+ initWithTMXFile:function (tmxFile) {
+ this._internalInit(tmxFile, null);
+ return this.parseXMLFile(tmxFile);
+ },
+
+ /**
+ * initializes a TMX format with an XML string and a TMX resource path
+ * @param {String} tmxString
+ * @param {String} resourcePath
+ * @return {Boolean}
+ */
+ initWithXML:function (tmxString, resourcePath) {
+ this._internalInit(null, resourcePath);
+ return this.parseXMLString(tmxString);
+ },
+
+ /** Initalises parsing of an XML file, either a tmx (Map) file or tsx (Tileset) file
+ * @param {String} tmxFile
+ * @param {boolean} [isXmlString=false]
+ * @return {Element}
+ */
+ parseXMLFile:function (tmxFile, isXmlString) {
+ isXmlString = isXmlString || false;
+ var xmlStr = isXmlString ? tmxFile : cc.loader.getRes(tmxFile);
+ if(!xmlStr) throw new Error("Please load the resource first : " + tmxFile);
+
+ var mapXML = this._parseXML(xmlStr);
+ var i, j;
+
+ // PARSE
+ var map = mapXML.documentElement;
+
+ var version = map.getAttribute('version');
+ var orientationStr = map.getAttribute('orientation');
+
+ if (map.nodeName === "map") {
+ if (version !== "1.0" && version !== null)
+ cc.log("cocos2d: TMXFormat: Unsupported TMX version:" + version);
+
+ if (orientationStr === "orthogonal")
+ this.orientation = cc.TMX_ORIENTATION_ORTHO;
+ else if (orientationStr === "isometric")
+ this.orientation = cc.TMX_ORIENTATION_ISO;
+ else if (orientationStr === "hexagonal")
+ this.orientation = cc.TMX_ORIENTATION_HEX;
+ else if (orientationStr !== null)
+ cc.log("cocos2d: TMXFomat: Unsupported orientation:" + orientationStr);
+
+ var mapSize = cc.size(0, 0);
+ mapSize.width = parseFloat(map.getAttribute('width'));
+ mapSize.height = parseFloat(map.getAttribute('height'));
+ this.setMapSize(mapSize);
+
+ mapSize = cc.size(0, 0);
+ mapSize.width = parseFloat(map.getAttribute('tilewidth'));
+ mapSize.height = parseFloat(map.getAttribute('tileheight'));
+ this.setTileSize(mapSize);
+
+ // The parent element is the map
+ var propertyArr = map.querySelectorAll("map > properties > property");
+ if (propertyArr) {
+ var aPropertyDict = {};
+ for (i = 0; i < propertyArr.length; i++) {
+ aPropertyDict[propertyArr[i].getAttribute('name')] = propertyArr[i].getAttribute('value');
+ }
+ this.properties = aPropertyDict;
+ }
+ }
+
+ // PARSE
+ var tilesets = map.getElementsByTagName('tileset');
+ if (map.nodeName !== "map") {
+ tilesets = [];
+ tilesets.push(map);
+ }
+
+ for (i = 0; i < tilesets.length; i++) {
+ var selTileset = tilesets[i];
+ // If this is an external tileset then start parsing that
+ var tsxName = selTileset.getAttribute('source');
+ if (tsxName) {
+ //this._currentFirstGID = parseInt(selTileset.getAttribute('firstgid'));
+ var tsxPath = isXmlString ? cc.path.join(this._resources, tsxName) : cc.path.changeBasename(tmxFile, tsxName);
+ this.parseXMLFile(tsxPath);
+ } else {
+ var tileset = new cc.TMXTilesetInfo();
+ tileset.name = selTileset.getAttribute('name') || "";
+ //TODO need fix
+ //if(this._currentFirstGID === 0){
+ tileset.firstGid = parseInt(selTileset.getAttribute('firstgid')) || 0;
+ //}else{
+ // tileset.firstGid = this._currentFirstGID;
+ // this._currentFirstGID = 0;
+ //}
+
+ tileset.spacing = parseInt(selTileset.getAttribute('spacing')) || 0;
+ tileset.margin = parseInt(selTileset.getAttribute('margin')) || 0;
+
+ var tilesetSize = cc.size(0, 0);
+ tilesetSize.width = parseFloat(selTileset.getAttribute('tilewidth'));
+ tilesetSize.height = parseFloat(selTileset.getAttribute('tileheight'));
+ tileset._tileSize = tilesetSize;
+
+ var image = selTileset.getElementsByTagName('image')[0];
+ var imagename = image.getAttribute('source');
+ var num = -1;
+ if(this.tmxFileName)
+ num = this.tmxFileName.lastIndexOf("/");
+ if (num !== -1) {
+ var dir = this.tmxFileName.substr(0, num + 1);
+ tileset.sourceImage = dir + imagename;
+ } else {
+ tileset.sourceImage = this._resources + (this._resources ? "/" : "") + imagename;
+ }
+ this.setTilesets(tileset);
+
+ // PARSE
+ var tiles = selTileset.getElementsByTagName('tile');
+ if (tiles) {
+ for (var tIdx = 0; tIdx < tiles.length; tIdx++) {
+ var t = tiles[tIdx];
+ this.parentGID = parseInt(tileset.firstGid) + parseInt(t.getAttribute('id') || 0);
+ var tp = t.querySelectorAll("properties > property");
+ if (tp) {
+ var dict = {};
+ for (j = 0; j < tp.length; j++) {
+ var name = tp[j].getAttribute('name');
+ dict[name] = tp[j].getAttribute('value');
+ }
+ this._tileProperties[this.parentGID] = dict;
+ }
+ }
+ }
+ }
+ }
+
+ // PARSE
+ var layers = map.getElementsByTagName('layer');
+ if (layers) {
+ for (i = 0; i < layers.length; i++) {
+ var selLayer = layers[i];
+ var data = selLayer.getElementsByTagName('data')[0];
+
+ var layer = new cc.TMXLayerInfo();
+ layer.name = selLayer.getAttribute('name');
+
+ var layerSize = cc.size(0, 0);
+ layerSize.width = parseFloat(selLayer.getAttribute('width'));
+ layerSize.height = parseFloat(selLayer.getAttribute('height'));
+ layer._layerSize = layerSize;
+
+ var visible = selLayer.getAttribute('visible');
+ layer.visible = !(visible == "0");
+
+ var opacity = selLayer.getAttribute('opacity') || 1;
+
+ if (opacity)
+ layer._opacity = parseInt(255 * parseFloat(opacity));
+ else
+ layer._opacity = 255;
+ layer.offset = cc.p(parseFloat(selLayer.getAttribute('x')) || 0, parseFloat(selLayer.getAttribute('y')) || 0);
+
+ var nodeValue = '';
+ for (j = 0; j < data.childNodes.length; j++) {
+ nodeValue += data.childNodes[j].nodeValue
+ }
+ nodeValue = nodeValue.trim();
+
+ // Unpack the tilemap data
+ var compression = data.getAttribute('compression');
+ var encoding = data.getAttribute('encoding');
+ if(compression && compression !== "gzip" && compression !== "zlib"){
+ cc.log("cc.TMXMapInfo.parseXMLFile(): unsupported compression method");
+ return null;
+ }
+ var tiles;
+ switch (compression) {
+ case 'gzip':
+ tiles = cc.unzipBase64AsArray(nodeValue, 4);
+ break;
+ case 'zlib':
+ var inflator = new Zlib.Inflate(cc.Codec.Base64.decodeAsArray(nodeValue, 1));
+ tiles = cc.uint8ArrayToUint32Array(inflator.decompress());
+ break;
+ case null:
+ case '':
+ // Uncompressed
+ if (encoding === "base64")
+ tiles = cc.Codec.Base64.decodeAsArray(nodeValue, 4);
+ else if (encoding === "csv") {
+ tiles = [];
+ var csvTiles = nodeValue.split(',');
+ for (var csvIdx = 0; csvIdx < csvTiles.length; csvIdx++)
+ tiles.push(parseInt(csvTiles[csvIdx]));
+ } else {
+ //XML format
+ var selDataTiles = data.getElementsByTagName("tile");
+ tiles = [];
+ for (var xmlIdx = 0; xmlIdx < selDataTiles.length; xmlIdx++)
+ tiles.push(parseInt(selDataTiles[xmlIdx].getAttribute("gid")));
+ }
+ break;
+ default:
+ if(this.layerAttrs === cc.TMXLayerInfo.ATTRIB_NONE)
+ cc.log("cc.TMXMapInfo.parseXMLFile(): Only base64 and/or gzip/zlib maps are supported");
+ break;
+ }
+ if (tiles) {
+ layer._tiles = new Uint32Array(tiles);
+ }
+
+ // The parent element is the last layer
+ var layerProps = selLayer.querySelectorAll("properties > property");
+ if (layerProps) {
+ var layerProp = {};
+ for (j = 0; j < layerProps.length; j++) {
+ layerProp[layerProps[j].getAttribute('name')] = layerProps[j].getAttribute('value');
+ }
+ layer.properties = layerProp;
+ }
+ this.setLayers(layer);
+ }
+ }
+
+ // PARSE
+ var objectGroups = map.getElementsByTagName('objectgroup');
+ if (objectGroups) {
+ for (i = 0; i < objectGroups.length; i++) {
+ var selGroup = objectGroups[i];
+ var objectGroup = new cc.TMXObjectGroup();
+ objectGroup.groupName = selGroup.getAttribute('name');
+ objectGroup.setPositionOffset(cc.p(parseFloat(selGroup.getAttribute('x')) * this.getTileSize().width || 0,
+ parseFloat(selGroup.getAttribute('y')) * this.getTileSize().height || 0));
+
+ var groupProps = selGroup.querySelectorAll("objectgroup > properties > property");
+ if (groupProps) {
+ for (j = 0; j < groupProps.length; j++) {
+ var groupProp = {};
+ groupProp[groupProps[j].getAttribute('name')] = groupProps[j].getAttribute('value');
+ // Add the property to the layer
+ objectGroup.properties = groupProp;
+ }
+ }
+
+ var objects = selGroup.querySelectorAll('object');
+ var getContentScaleFactor = cc.director.getContentScaleFactor();
+ if (objects) {
+ for (j = 0; j < objects.length; j++) {
+ var selObj = objects[j];
+ // The value for "type" was blank or not a valid class name
+ // Create an instance of TMXObjectInfo to store the object and its properties
+ var objectProp = {};
+
+ // Set the name of the object to the value for "name"
+ objectProp["name"] = selObj.getAttribute('name') || "";
+
+ // Assign all the attributes as key/name pairs in the properties dictionary
+ objectProp["type"] = selObj.getAttribute('type') || "";
+
+ objectProp["width"] = parseInt(selObj.getAttribute('width')) || 0;
+ objectProp["height"] = parseInt(selObj.getAttribute('height')) || 0;
+
+ objectProp["x"] = (((selObj.getAttribute('x') || 0) | 0) + objectGroup.getPositionOffset().x) / getContentScaleFactor;
+ var y = ((selObj.getAttribute('y') || 0) | 0) + objectGroup.getPositionOffset().y / getContentScaleFactor;
+ // Correct y position. (Tiled uses Flipped, cocos2d uses Standard)
+ objectProp["y"] = (parseInt(this.getMapSize().height * this.getTileSize().height) - y - objectProp["height"]) / cc.director.getContentScaleFactor();
+
+ objectProp["rotation"] = parseInt(selObj.getAttribute('rotation')) || 0;
+
+ var docObjProps = selObj.querySelectorAll("properties > property");
+ if (docObjProps) {
+ for (var k = 0; k < docObjProps.length; k++)
+ objectProp[docObjProps[k].getAttribute('name')] = docObjProps[k].getAttribute('value');
+ }
+
+ //polygon
+ var polygonProps = selObj.querySelectorAll("polygon");
+ if(polygonProps && polygonProps.length > 0) {
+ var selPgPointStr = polygonProps[0].getAttribute('points');
+ if(selPgPointStr)
+ objectProp["points"] = this._parsePointsString(selPgPointStr);
+ }
+
+ //polyline
+ var polylineProps = selObj.querySelectorAll("polyline");
+ if(polylineProps && polylineProps.length > 0) {
+ var selPlPointStr = polylineProps[0].getAttribute('points');
+ if(selPlPointStr)
+ objectProp["polylinePoints"] = this._parsePointsString(selPlPointStr);
+ }
+
+ // Add the object to the objectGroup
+ objectGroup.setObjects(objectProp);
+ }
+ }
+
+ this.setObjectGroups(objectGroup);
+ }
+ }
+ return map;
+ },
+
+ _parsePointsString:function(pointsString){
+ if(!pointsString)
+ return null;
+
+ var points = [];
+ var pointsStr = pointsString.split(' ');
+ for(var i = 0; i < pointsStr.length; i++){
+ var selPointStr = pointsStr[i].split(',');
+ points.push({'x':selPointStr[0], 'y':selPointStr[1]});
+ }
+ return points;
+ },
+
+ /**
+ * initializes parsing of an XML string, either a tmx (Map) string or tsx (Tileset) string
+ * @param {String} xmlString
+ * @return {Boolean}
+ */
+ parseXMLString:function (xmlString) {
+ return this.parseXMLFile(xmlString, true);
+ },
+
+ /**
+ * Gets the tile properties.
+ * @return {object}
+ */
+ getTileProperties:function () {
+ return this._tileProperties;
+ },
+
+ /**
+ * Set the tile properties.
+ * @param {object} tileProperties
+ */
+ setTileProperties:function (tileProperties) {
+ this._tileProperties.push(tileProperties);
+ },
+
+ /**
+ * Gets the currentString
+ * @return {String}
+ */
+ getCurrentString:function () {
+ return this.currentString;
+ },
+
+ /**
+ * Set the currentString
+ * @param {String} currentString
+ */
+ setCurrentString:function (currentString) {
+ this.currentString = currentString;
+ },
+
+ /**
+ * Gets the tmxFileName
+ * @return {String}
+ */
+ getTMXFileName:function () {
+ return this.tmxFileName;
+ },
+
+ /**
+ * Set the tmxFileName
+ * @param {String} fileName
+ */
+ setTMXFileName:function (fileName) {
+ this.tmxFileName = fileName;
+ },
+
+ _internalInit:function (tmxFileName, resourcePath) {
+ this._tilesets.length = 0;
+ this._layers.length = 0;
+
+ this.tmxFileName = tmxFileName;
+ if (resourcePath)
+ this._resources = resourcePath;
+
+ this._objectGroups.length = 0;
+ this.properties.length = 0;
+ this._tileProperties.length = 0;
+
+ // tmp vars
+ this.currentString = "";
+ this.storingCharacters = false;
+ this.layerAttrs = cc.TMXLayerInfo.ATTRIB_NONE;
+ this.parentElement = cc.TMX_PROPERTY_NONE;
+ this._currentFirstGID = 0;
+ }
+});
+
+var _p = cc.TMXMapInfo.prototype;
+
+// Extended properties
+/** @expose */
+_p.mapWidth;
+cc.defineGetterSetter(_p, "mapWidth", _p._getMapWidth, _p._setMapWidth);
+/** @expose */
+_p.mapHeight;
+cc.defineGetterSetter(_p, "mapHeight", _p._getMapHeight, _p._setMapHeight);
+/** @expose */
+_p.tileWidth;
+cc.defineGetterSetter(_p, "tileWidth", _p._getTileWidth, _p._setTileWidth);
+/** @expose */
+_p.tileHeight;
+cc.defineGetterSetter(_p, "tileHeight", _p._getTileHeight, _p._setTileHeight);
+
+
+/**
+ * Creates a TMX Format with a tmx file or content string
+ * @deprecated since v3.0 please use new cc.TMXMapInfo(tmxFile, resourcePath) instead.
+ * @param {String} tmxFile fileName or content string
+ * @param {String} resourcePath If tmxFile is a file name ,it is not required.If tmxFile is content string ,it is must required.
+ * @return {cc.TMXMapInfo}
+ */
+cc.TMXMapInfo.create = function (tmxFile, resourcePath) {
+ return new cc.TMXMapInfo(tmxFile, resourcePath);
+};
+
+
+cc.loader.register(["tmx", "tsx"], cc._txtLoader);
+
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMXLayerInfo.ATTRIB_NONE = 1 << 0;
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMXLayerInfo.ATTRIB_BASE64 = 1 << 1;
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMXLayerInfo.ATTRIB_GZIP = 1 << 2;
+/**
+ * @constant
+ * @type Number
+ */
+cc.TMXLayerInfo.ATTRIB_ZLIB = 1 << 3;
diff --git a/frameworks/cocos2d-html5/cocos2d/transitions/CCTransition.js b/frameworks/cocos2d-html5/cocos2d/transitions/CCTransition.js
new file mode 100644
index 0000000..09b1822
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/transitions/CCTransition.js
@@ -0,0 +1,1478 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+/**
+ * A tag constant for identifying fade scenes
+ * @constant
+ * @type Number
+ */
+cc.SCENE_FADE = 4208917214;
+
+/**
+ * horizontal orientation Type where the Left is nearer
+ * @constant
+ * @type Number
+ */
+cc.TRANSITION_ORIENTATION_LEFT_OVER = 0;
+/**
+ * horizontal orientation type where the Right is nearer
+ * @constant
+ * @type Number
+ */
+cc.TRANSITION_ORIENTATION_RIGHT_OVER = 1;
+/**
+ * vertical orientation type where the Up is nearer
+ * @constant
+ * @type Number
+ */
+cc.TRANSITION_ORIENTATION_UP_OVER = 0;
+/**
+ * vertical orientation type where the Bottom is nearer
+ * @constant
+ * @type Number
+ */
+cc.TRANSITION_ORIENTATION_DOWN_OVER = 1;
+
+/**
+ * @class
+ * @extends cc.Scene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene the scene to transit with
+ * @example
+ * var trans = new TransitionScene(time,scene);
+ */
+cc.TransitionScene = cc.Scene.extend(/** @lends cc.TransitionScene# */{
+ _inScene: null,
+ _outScene: null,
+ _duration: null,
+ _isInSceneOnTop: false,
+ _isSendCleanupToScene: false,
+ _className: "TransitionScene",
+
+ /**
+ * creates a base transition with duration and incoming scene
+ * Constructor of cc.TransitionScene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene the scene to transit with
+ */
+ ctor: function (t, scene) {
+ cc.Scene.prototype.ctor.call(this);
+ if (t !== undefined && scene !== undefined)
+ this.initWithDuration(t, scene);
+ },
+
+ //private
+ _setNewScene: function (dt) {
+ this.unschedule(this._setNewScene);
+ // Before replacing, save the "send cleanup to scene"
+ var director = cc.director;
+ this._isSendCleanupToScene = director.isSendCleanupToScene();
+ director.runScene(this._inScene);
+
+ // enable events while transitions
+ cc.eventManager.setEnabled(true);
+
+ // issue #267
+ this._outScene.visible = true;
+ },
+
+ //protected
+ _sceneOrder: function () {
+ this._isInSceneOnTop = true;
+ },
+
+ /**
+ * stuff gets drawn here
+ */
+ visit: function () {
+ if (this._isInSceneOnTop) {
+ this._outScene.visit();
+ this._inScene.visit();
+ } else {
+ this._inScene.visit();
+ this._outScene.visit();
+ }
+ cc.Node.prototype.visit.call(this);
+ },
+
+ /**
+ *
+ * Event callback that is invoked every time when cc.TransitionScene enters the 'stage'.
+ * If the TransitionScene enters the 'stage' with a transition, this event is called when the transition starts.
+ * During onEnter you can't access a "sister/brother" node.
+ * If you override onEnter, you must call its parent's onEnter function with this._super().
+ *
+ */
+ onEnter: function () {
+ cc.Node.prototype.onEnter.call(this);
+
+ // disable events while transitions
+ cc.eventManager.setEnabled(false);
+
+ // outScene should not receive the onEnter callback
+ // only the onExitTransitionDidStart
+ this._outScene._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+
+ this._inScene._performRecursive(cc.Node._stateCallbackType.onEnter);
+ },
+
+ /**
+ *
+ * callback that is called every time the cc.TransitionScene leaves the 'stage'.
+ * If the cc.TransitionScene leaves the 'stage' with a transition, this callback is called when the transition finishes.
+ * During onExit you can't access a sibling node.
+ * If you override onExit, you shall call its parent's onExit with this._super().
+ *
+ */
+ onExit: function () {
+ cc.Node.prototype.onExit.call(this);
+
+ // enable events while transitions
+ cc.eventManager.setEnabled(true);
+
+ this._outScene._performRecursive(cc.Node._stateCallbackType.onExit);
+
+ // _inScene should not receive the onEnter callback
+ // only the onEnterTransitionDidFinish
+ this._inScene._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
+ },
+
+ /**
+ * custom cleanup
+ */
+ cleanup: function () {
+ cc.Node.prototype.cleanup.call(this);
+
+ if (this._isSendCleanupToScene)
+ this._outScene._performRecursive(cc.Node._stateCallbackType.cleanup);
+ },
+
+ /**
+ * initializes a transition with duration and incoming scene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene a scene to transit to
+ * @return {Boolean} return false if error
+ */
+ initWithDuration: function (t, scene) {
+ if (!scene)
+ throw new Error("cc.TransitionScene.initWithDuration(): Argument scene must be non-nil");
+
+ if (this.init()) {
+ this._duration = t;
+ this.attr({
+ x: 0,
+ y: 0,
+ anchorX: 0,
+ anchorY: 0
+ });
+ // retain
+ this._inScene = scene;
+ this._outScene = cc.director.getRunningScene();
+ if (!this._outScene) {
+ this._outScene = new cc.Scene();
+ this._outScene.init();
+ }
+
+ if (this._inScene === this._outScene)
+ throw new Error("cc.TransitionScene.initWithDuration(): Incoming scene must be different from the outgoing scene");
+
+ this._sceneOrder();
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+ /**
+ * called after the transition finishes
+ */
+ finish: function () {
+ // clean up
+ this._inScene.attr({
+ visible: true,
+ x: 0,
+ y: 0,
+ scale: 1.0,
+ rotation: 0.0
+ });
+
+ this._outScene.attr({
+ visible: false,
+ x: 0,
+ y: 0,
+ scale: 1.0,
+ rotation: 0.0
+ });
+
+ //[self schedule:@selector(setNewScene:) interval:0];
+ this.schedule(this._setNewScene, 0);
+ },
+
+ /**
+ * set hide the out scene and show in scene
+ */
+ hideOutShowIn: function () {
+ this._inScene.visible = true;
+ this._outScene.visible = false;
+ }
+});
+/**
+ * creates a base transition with duration and incoming scene
+ * @deprecated since v3.0, please use new cc.TransitionScene(t,scene) instead
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene the scene to transit with
+ * @return {cc.TransitionScene|Null}
+ */
+cc.TransitionScene.create = function (t, scene) {
+ return new cc.TransitionScene(t, scene);
+};
+
+/**
+ * A cc.Transition that supports orientation like.
+ * Possible orientation: LeftOver, RightOver, UpOver, DownOver
+ * useful for when you want to make a transition happen between 2 orientations
+ * @class
+ * @extends cc.TransitionScene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} orientation
+ * @example
+ * var trans = new cc.TransitionSceneOriented(time,scene,orientation);
+ */
+cc.TransitionSceneOriented = cc.TransitionScene.extend(/** @lends cc.TransitionSceneOriented# */{
+ _orientation: 0,
+
+ /**
+ * Constructor of TransitionSceneOriented
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} orientation
+ */
+ ctor: function (t, scene, orientation) {
+ cc.TransitionScene.prototype.ctor.call(this);
+ orientation != undefined && this.initWithDuration(t, scene, orientation);
+ },
+ /**
+ * initialize the transition
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} orientation
+ * @return {Boolean}
+ */
+ initWithDuration: function (t, scene, orientation) {
+ if (cc.TransitionScene.prototype.initWithDuration.call(this, t, scene)) {
+ this._orientation = orientation;
+ }
+ return true;
+ }
+});
+
+/**
+ * creates a base transition with duration and incoming scene
+ * @deprecated since v3.0 ,please use new cc.TransitionSceneOriented(t, scene, orientation) instead.
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} orientation
+ * @return {cc.TransitionSceneOriented}
+ */
+cc.TransitionSceneOriented.create = function (t, scene, orientation) {
+ return new cc.TransitionSceneOriented(t, scene, orientation);
+};
+
+/**
+ * Rotate and zoom out the outgoing scene, and then rotate and zoom in the incoming
+ * @class
+ * @extends cc.TransitionScene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionRotoZoom(t, scene);
+ */
+cc.TransitionRotoZoom = cc.TransitionScene.extend(/** @lends cc.TransitionRotoZoom# */{
+
+ /**
+ * Constructor of TransitionRotoZoom
+ * @function
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionScene.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+ /**
+ * Custom On Enter callback
+ * @override
+ */
+ onEnter: function () {
+ cc.TransitionScene.prototype.onEnter.call(this);
+
+ this._inScene.attr({
+ scale: 0.001,
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ this._outScene.attr({
+ scale: 1.0,
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+
+ var rotoZoom = cc.sequence(
+ cc.spawn(cc.scaleBy(this._duration / 2, 0.001),
+ cc.rotateBy(this._duration / 2, 360 * 2)),
+ cc.delayTime(this._duration / 2));
+
+ this._outScene.runAction(rotoZoom);
+ this._inScene.runAction(
+ cc.sequence(rotoZoom.reverse(),
+ cc.callFunc(this.finish, this)));
+ }
+});
+
+/**
+ * Creates a Transition rotation and zoom
+ * @deprecated since v3.0,please use new cc.TransitionRotoZoom(t, scene) instead
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene the scene to work with
+ * @return {cc.TransitionRotoZoom}
+ */
+cc.TransitionRotoZoom.create = function (t, scene) {
+ return new cc.TransitionRotoZoom(t, scene);
+};
+
+/**
+ * Zoom out and jump the outgoing scene, and then jump and zoom in the incoming
+ * @class
+ * @extends cc.TransitionScene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionJumpZoom(t, scene);
+ */
+cc.TransitionJumpZoom = cc.TransitionScene.extend(/** @lends cc.TransitionJumpZoom# */{
+ /**
+ * Constructor of TransitionJumpZoom
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionScene.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+ /**
+ * Custom on enter
+ */
+ onEnter: function () {
+ cc.TransitionScene.prototype.onEnter.call(this);
+ var winSize = cc.director.getWinSize();
+
+ this._inScene.attr({
+ scale: 0.5,
+ x: winSize.width,
+ y: 0,
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ this._outScene.anchorX = 0.5;
+ this._outScene.anchorY = 0.5;
+
+ var jump = cc.jumpBy(this._duration / 4, cc.p(-winSize.width, 0), winSize.width / 4, 2);
+ var scaleIn = cc.scaleTo(this._duration / 4, 1.0);
+ var scaleOut = cc.scaleTo(this._duration / 4, 0.5);
+
+ var jumpZoomOut = cc.sequence(scaleOut, jump);
+ var jumpZoomIn = cc.sequence(jump, scaleIn);
+
+ var delay = cc.delayTime(this._duration / 2);
+ this._outScene.runAction(jumpZoomOut);
+ this._inScene.runAction(cc.sequence(delay, jumpZoomIn, cc.callFunc(this.finish, this)));
+ }
+});
+
+/**
+ * creates a scene transition that zooms then jump across the screen, the same for the incoming scene
+ * @deprecated since v3.0,please use new cc.TransitionJumpZoom(t, scene);
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionJumpZoom}
+ */
+cc.TransitionJumpZoom.create = function (t, scene) {
+ return new cc.TransitionJumpZoom(t, scene);
+};
+
+/**
+ * Move in from to the left the incoming scene.
+ * @class
+ * @extends cc.TransitionScene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionMoveInL(time,scene);
+ */
+cc.TransitionMoveInL = cc.TransitionScene.extend(/** @lends cc.TransitionMoveInL# */{
+ /**
+ * Constructor of TransitionMoveInL
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionScene.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+ /**
+ * Custom on enter
+ */
+ onEnter: function () {
+ cc.TransitionScene.prototype.onEnter.call(this);
+ this.initScenes();
+
+ var action = this.action();
+ this._inScene.runAction(
+ cc.sequence(this.easeActionWithAction(action), cc.callFunc(this.finish, this))
+ );
+ },
+
+ /**
+ * initializes the scenes
+ */
+ initScenes: function () {
+ this._inScene.setPosition(-cc.director.getWinSize().width, 0);
+ },
+
+ /**
+ * returns the action that will be performed
+ */
+ action: function () {
+ return cc.moveTo(this._duration, cc.p(0, 0));
+ },
+
+ /**
+ * creates an ease action from action
+ * @param {cc.ActionInterval} action
+ * @return {cc.EaseOut}
+ */
+ easeActionWithAction: function (action) {
+ return new cc.EaseOut(action, 2.0);
+ }
+});
+
+/**
+ * creates an action that Move in from to the left the incoming scene.
+ * @deprecated since v3.0,please use new cc.TransitionMoveInL(t, scene) instead
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionMoveInL}
+ */
+cc.TransitionMoveInL.create = function (t, scene) {
+ return new cc.TransitionMoveInL(t, scene);
+};
+
+/**
+ * Move in from to the right the incoming scene.
+ * @class
+ * @extends cc.TransitionMoveInL
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionMoveInR(time,scene);
+ */
+cc.TransitionMoveInR = cc.TransitionMoveInL.extend(/** @lends cc.TransitionMoveInR# */{
+ /**
+ * Constructor of TransitionMoveInR
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionMoveInL.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+ /**
+ * Init function
+ */
+ initScenes: function () {
+ this._inScene.setPosition(cc.director.getWinSize().width, 0);
+ }
+});
+
+/**
+ * create a scene transition that Move in from to the right the incoming scene.
+ * @deprecated since v3.0,please use new cc.TransitionMoveInR(t, scene) instead
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionMoveInR}
+ */
+cc.TransitionMoveInR.create = function (t, scene) {
+ return new cc.TransitionMoveInR(t, scene);
+};
+
+/**
+ * Move in from to the top the incoming scene.
+ * @class
+ * @extends cc.TransitionMoveInL
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionMoveInT(time,scene);
+ */
+cc.TransitionMoveInT = cc.TransitionMoveInL.extend(/** @lends cc.TransitionMoveInT# */{
+ /**
+ * Constructor of TransitionMoveInT
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionMoveInL.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+ /**
+ * init function
+ */
+ initScenes: function () {
+ this._inScene.setPosition(0, cc.director.getWinSize().height);
+ }
+});
+
+/**
+ * Move in from to the top the incoming scene.
+ * @deprecated since v3.0,please use new cc.TransitionMoveInT(t, scene) instead
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionMoveInT}
+ */
+cc.TransitionMoveInT.create = function (t, scene) {
+ return new cc.TransitionMoveInT(t, scene);
+};
+
+/**
+ * Move in from to the bottom the incoming scene.
+ * @class
+ * @extends cc.TransitionMoveInL
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionMoveInB(time,scene);
+ */
+cc.TransitionMoveInB = cc.TransitionMoveInL.extend(/** @lends cc.TransitionMoveInB# */{
+ /**
+ * Constructor of TransitionMoveInB
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionMoveInL.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+
+ /**
+ * init function
+ */
+ initScenes: function () {
+ this._inScene.setPosition(0, -cc.director.getWinSize().height);
+ }
+});
+
+/**
+ * create a scene transition that Move in from to the bottom the incoming scene.
+ * @deprecated since v3.0,please use new cc.TransitionMoveInB(t, scene) instead
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionMoveInB}
+ */
+cc.TransitionMoveInB.create = function (t, scene) {
+ return new cc.TransitionMoveInB(t, scene);
+};
+
+/**
+ * The adjust factor is needed to prevent issue #442
+ * One solution is to use DONT_RENDER_IN_SUBPIXELS images, but NO
+ * The other issue is that in some transitions (and I don't know why)
+ * the order should be reversed (In in top of Out or vice-versa).
+ * @constant
+ * @type Number
+ */
+cc.ADJUST_FACTOR = 0.5;
+
+/**
+ * a transition that a new scene is slided from left
+ * @class
+ * @extends cc.TransitionScene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = cc.TransitionSlideInL(time,scene);
+ */
+cc.TransitionSlideInL = cc.TransitionScene.extend(/** @lends cc.TransitionSlideInL# */{
+ /**
+ * Constructor of TransitionSlideInL
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionScene.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+ _sceneOrder: function () {
+ this._isInSceneOnTop = false;
+ },
+
+ /**
+ * custom on enter
+ */
+ onEnter: function () {
+ cc.TransitionScene.prototype.onEnter.call(this);
+ this.initScenes();
+
+ var inA = this.action();
+ var outA = this.action();
+
+ var inAction = cc.sequence(this.easeActionWithAction(inA), cc.callFunc(this.finish, this));
+ var outAction = this.easeActionWithAction(outA);
+ this._inScene.runAction(inAction);
+ this._outScene.runAction(outAction);
+ },
+
+ /**
+ * initializes the scenes
+ */
+ initScenes: function () {
+ this._inScene.setPosition(-cc.director.getWinSize().width + cc.ADJUST_FACTOR, 0);
+ },
+ /**
+ * returns the action that will be performed by the incoming and outgoing scene
+ * @return {cc.MoveBy}
+ */
+ action: function () {
+ return cc.moveBy(this._duration, cc.p(cc.director.getWinSize().width - cc.ADJUST_FACTOR, 0));
+ },
+
+ /**
+ * @param {cc.ActionInterval} action
+ * @return {*}
+ */
+ easeActionWithAction: function (action) {
+ return new cc.EaseInOut(action, 2.0);
+ }
+});
+
+/**
+ * create a transition that a new scene is slided from left
+ * @deprecated since v3.0,please use new cc.TransitionSlideInL(t, scene) instead
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionSlideInL}
+ */
+cc.TransitionSlideInL.create = function (t, scene) {
+ return new cc.TransitionSlideInL(t, scene);
+};
+
+/**
+ * Slide in the incoming scene from the right border.
+ * @class
+ * @extends cc.TransitionSlideInL
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionSlideInR(time,scene);
+ */
+cc.TransitionSlideInR = cc.TransitionSlideInL.extend(/** @lends cc.TransitionSlideInR# */{
+ /**
+ * Constructor of TransitionSlideInR
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionSlideInL.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+ _sceneOrder: function () {
+ this._isInSceneOnTop = true;
+ },
+ /**
+ * initializes the scenes
+ */
+ initScenes: function () {
+ this._inScene.setPosition(cc.director.getWinSize().width - cc.ADJUST_FACTOR, 0);
+ },
+ /**
+ * returns the action that will be performed by the incoming and outgoing scene
+ * @return {cc.MoveBy}
+ */
+ action: function () {
+ return cc.moveBy(this._duration, cc.p(-(cc.director.getWinSize().width - cc.ADJUST_FACTOR), 0));
+ }
+});
+
+/**
+ * create Slide in the incoming scene from the right border.
+ * @deprecated since v3.0,please use new cc.TransitionSlideInR(t, scene) instead
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionSlideInR}
+ */
+cc.TransitionSlideInR.create = function (t, scene) {
+ return new cc.TransitionSlideInR(t, scene);
+};
+
+/**
+ * Slide in the incoming scene from the bottom border.
+ * @class
+ * @extends cc.TransitionSlideInL
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionSlideInB(time,scene);
+ */
+cc.TransitionSlideInB = cc.TransitionSlideInL.extend(/** @lends cc.TransitionSlideInB# */{
+ /**
+ * Constructor of TransitionSlideInB
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionSlideInL.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+ _sceneOrder: function () {
+ this._isInSceneOnTop = false;
+ },
+
+ /**
+ * initializes the scenes
+ */
+ initScenes: function () {
+ this._inScene.setPosition(0, -(cc.director.getWinSize().height - cc.ADJUST_FACTOR));
+ },
+
+ /**
+ * returns the action that will be performed by the incoming and outgoing scene
+ * @return {cc.MoveBy}
+ */
+ action: function () {
+ return cc.moveBy(this._duration, cc.p(0, cc.director.getWinSize().height - cc.ADJUST_FACTOR));
+ }
+});
+
+/**
+ * create a Slide in the incoming scene from the bottom border.
+ * @deprecated since v3.0,please use new cc.TransitionSlideInB(t, scene) instead.
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionSlideInB}
+ */
+cc.TransitionSlideInB.create = function (t, scene) {
+ return new cc.TransitionSlideInB(t, scene);
+};
+
+/**
+ * Slide in the incoming scene from the top border.
+ * @class
+ * @extends cc.TransitionSlideInL
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionSlideInT(time,scene);
+ */
+cc.TransitionSlideInT = cc.TransitionSlideInL.extend(/** @lends cc.TransitionSlideInT# */{
+ /**
+ * Constructor of TransitionSlideInT
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionSlideInL.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+ _sceneOrder: function () {
+ this._isInSceneOnTop = true;
+ },
+
+ /**
+ * initializes the scenes
+ */
+ initScenes: function () {
+ this._inScene.setPosition(0, cc.director.getWinSize().height - cc.ADJUST_FACTOR);
+ },
+
+ /**
+ * returns the action that will be performed by the incoming and outgoing scene
+ * @return {cc.MoveBy}
+ */
+ action: function () {
+ return cc.moveBy(this._duration, cc.p(0, -(cc.director.getWinSize().height - cc.ADJUST_FACTOR)));
+ }
+});
+
+/**
+ * create a Slide in the incoming scene from the top border.
+ * @deprecated since v3.0,please use new cc.TransitionSlideInT(t, scene) instead.
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionSlideInT}
+ */
+cc.TransitionSlideInT.create = function (t, scene) {
+ return new cc.TransitionSlideInT(t, scene);
+};
+
+/**
+ * Shrink the outgoing scene while grow the incoming scene
+ * @class
+ * @extends cc.TransitionScene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionShrinkGrow(time,scene);
+ */
+cc.TransitionShrinkGrow = cc.TransitionScene.extend(/** @lends cc.TransitionShrinkGrow# */{
+ /**
+ * Constructor of TransitionShrinkGrow
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionScene.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+ /**
+ * Custom on enter
+ */
+ onEnter: function () {
+ cc.TransitionScene.prototype.onEnter.call(this);
+
+ this._inScene.attr({
+ scale: 0.001,
+ anchorX: 2 / 3.0,
+ anchorY: 0.5
+ });
+ this._outScene.attr({
+ scale: 1.0,
+ anchorX: 1 / 3.0,
+ anchorY: 0.5
+ });
+
+ var scaleOut = cc.scaleTo(this._duration, 0.01);
+ var scaleIn = cc.scaleTo(this._duration, 1.0);
+
+ this._inScene.runAction(cc.sequence(this.easeActionWithAction(scaleIn), cc.callFunc(this.finish, this)));
+ this._outScene.runAction(this.easeActionWithAction(scaleOut));
+ },
+
+ /**
+ * @param action
+ * @return {cc.EaseOut}
+ */
+ easeActionWithAction: function (action) {
+ return new cc.EaseOut(action, 2.0);
+ }
+});
+
+/**
+ * Shrink the outgoing scene while grow the incoming scene
+ * @deprecated since v3.0,please use new cc.TransitionShrinkGrow(t, scene) instead.
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionShrinkGrow}
+ */
+cc.TransitionShrinkGrow.create = function (t, scene) {
+ return new cc.TransitionShrinkGrow(t, scene);
+};
+
+/**
+ * Fade out the outgoing scene and then fade in the incoming scene.
+ * @class
+ * @extends cc.TransitionScene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o
+ * @example
+ * var trans = new cc.TransitionFade(time,scene,color)
+ */
+cc.TransitionFade = cc.TransitionScene.extend(/** @lends cc.TransitionFade# */{
+ _color: null,
+
+ /**
+ * Constructor of TransitionFade
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @param {cc.TRANSITION_ORIENTATION_LEFT_OVER|cc.TRANSITION_ORIENTATION_RIGHT_OVER|cc.TRANSITION_ORIENTATION_UP_OVER|cc.TRANSITION_ORIENTATION_DOWN_OVER} o
+ */
+ ctor: function (t, scene, color) {
+ cc.TransitionScene.prototype.ctor.call(this);
+ this._color = cc.color();
+ scene && this.initWithDuration(t, scene, color);
+ },
+
+ /**
+ * custom on enter
+ */
+ onEnter: function () {
+ cc.TransitionScene.prototype.onEnter.call(this);
+
+ var l = new cc.LayerColor(this._color);
+ this._inScene.visible = false;
+
+ this.addChild(l, 2, cc.SCENE_FADE);
+ var f = this.getChildByTag(cc.SCENE_FADE);
+
+ var a = cc.sequence(
+ cc.fadeIn(this._duration / 2),
+ cc.callFunc(this.hideOutShowIn, this),
+ cc.fadeOut(this._duration / 2),
+ cc.callFunc(this.finish, this)
+ );
+ f.runAction(a);
+ },
+
+ /**
+ * custom on exit
+ */
+ onExit: function () {
+ cc.TransitionScene.prototype.onExit.call(this);
+ this.removeChildByTag(cc.SCENE_FADE, false);
+ },
+
+ /**
+ * initializes the transition with a duration and with an RGB color
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @param {cc.Color} color
+ * @return {Boolean}
+ */
+ initWithDuration: function (t, scene, color) {
+ color = color || cc.color.BLACK;
+ if (cc.TransitionScene.prototype.initWithDuration.call(this, t, scene)) {
+ this._color.r = color.r;
+ this._color.g = color.g;
+ this._color.b = color.b;
+ this._color.a = 0;
+ }
+ return true;
+ }
+});
+
+
+/**
+ * Fade out the outgoing scene and then fade in the incoming scene.
+ * @deprecated since v3.0,please use new cc.TransitionFade(time,scene,color) instead.
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @param {cc.Color} color
+ * @return {cc.TransitionFade}
+ */
+cc.TransitionFade.create = function (t, scene, color) {
+ return new cc.TransitionFade(t, scene, color);
+};
+
+/**
+ * Cross fades two scenes using the cc.RenderTexture object.
+ * @class
+ * @extends cc.TransitionScene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionCrossFade(time,scene);
+ */
+cc.TransitionCrossFade = cc.TransitionScene.extend(/** @lends cc.TransitionCrossFade# */{
+ /**
+ * Constructor of TransitionCrossFade
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionScene.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+ /**
+ * custom on enter
+ */
+ onEnter: function () {
+ cc.TransitionScene.prototype.onEnter.call(this);
+
+ // create a transparent color layer
+ // in which we are going to add our rendertextures
+ var color = cc.color(0, 0, 0, 0);
+ var winSize = cc.director.getWinSize();
+ var layer = new cc.LayerColor(color);
+
+ // create the first render texture for inScene
+ var inTexture = new cc.RenderTexture(winSize.width, winSize.height);
+
+ inTexture.sprite.anchorX = 0.5;
+ inTexture.sprite.anchorY = 0.5;
+ inTexture.attr({
+ x: winSize.width / 2,
+ y: winSize.height / 2,
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+
+ // render inScene to its texturebuffer
+ inTexture.begin();
+ this._inScene.visit();
+ inTexture.end();
+
+ // create the second render texture for outScene
+ var outTexture = new cc.RenderTexture(winSize.width, winSize.height);
+ outTexture.setPosition(winSize.width / 2, winSize.height / 2);
+ outTexture.sprite.anchorX = outTexture.anchorX = 0.5;
+ outTexture.sprite.anchorY = outTexture.anchorY = 0.5;
+
+ // render outScene to its texturebuffer
+ outTexture.begin();
+ this._outScene.visit();
+ outTexture.end();
+
+ inTexture.sprite.setBlendFunc(cc.ONE, cc.ONE); // inScene will lay on background and will not be used with alpha
+ outTexture.sprite.setBlendFunc(cc.SRC_ALPHA, cc.ONE_MINUS_SRC_ALPHA); // we are going to blend outScene via alpha
+
+ // add render textures to the layer
+ layer.addChild(inTexture);
+ layer.addChild(outTexture);
+
+ // initial opacity:
+ inTexture.sprite.opacity = 255;
+ outTexture.sprite.opacity = 255;
+
+ // create the blend action
+ var layerAction = cc.sequence(
+ cc.fadeTo(this._duration, 0), cc.callFunc(this.hideOutShowIn, this),
+ cc.callFunc(this.finish, this)
+ );
+
+ // run the blend action
+ outTexture.sprite.runAction(layerAction);
+
+ // add the layer (which contains our two rendertextures) to the scene
+ this.addChild(layer, 2, cc.SCENE_FADE);
+ },
+
+ /**
+ * custom on exit
+ */
+ onExit: function () {
+ this.removeChildByTag(cc.SCENE_FADE, false);
+ cc.TransitionScene.prototype.onExit.call(this);
+ },
+});
+
+/**
+ * Cross fades two scenes using the cc.RenderTexture object.
+ * @deprecated since v3.0,please use new cc.TransitionCrossFade(t, scene) instead.
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionCrossFade}
+ */
+cc.TransitionCrossFade.create = function (t, scene) {
+ return new cc.TransitionCrossFade(t, scene);
+};
+
+/**
+ * Turn off the tiles of the outgoing scene in random order
+ * @class
+ * @extends cc.TransitionScene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionTurnOffTiles(time,scene);
+ */
+cc.TransitionTurnOffTiles = cc.TransitionScene.extend(/** @lends cc.TransitionTurnOffTiles# */{
+ _gridProxy: null,
+ /**
+ * Constructor of TransitionCrossFade
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionScene.prototype.ctor.call(this);
+ this._gridProxy = new cc.NodeGrid();
+ scene && this.initWithDuration(t, scene);
+ },
+
+ _sceneOrder: function () {
+ this._isInSceneOnTop = false;
+ },
+
+ /**
+ * custom on enter
+ */
+ onEnter: function () {
+ cc.TransitionScene.prototype.onEnter.call(this);
+ this._gridProxy.setTarget(this._outScene);
+ this._gridProxy._performRecursive(cc.Node._stateCallbackType.onEnter);
+
+ var winSize = cc.director.getWinSize();
+ var aspect = winSize.width / winSize.height;
+ var x = 0 | (12 * aspect);
+ var y = 12;
+ var toff = cc.turnOffTiles(this._duration, cc.size(x, y));
+ var action = this.easeActionWithAction(toff);
+ this._gridProxy.runAction(cc.sequence(action, cc.callFunc(this.finish, this), cc.stopGrid()));
+ },
+
+ visit: function () {
+ this._inScene.visit();
+ this._gridProxy.visit();
+ },
+
+ /**
+ * @param {cc.ActionInterval} action
+ * @return {cc.ActionInterval}
+ */
+ easeActionWithAction: function (action) {
+ return action;
+ }
+});
+
+/**
+ * Turn off the tiles of the outgoing scene in random order
+ * @deprecated since v3.0,please use new cc.TransitionTurnOffTiles(t, scene) instead.
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionTurnOffTiles}
+ */
+cc.TransitionTurnOffTiles.create = function (t, scene) {
+ return new cc.TransitionTurnOffTiles(t, scene);
+};
+
+/**
+ * The odd columns goes upwards while the even columns goes downwards.
+ * @class
+ * @extends cc.TransitionScene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionSplitCols(time,scene);
+ */
+cc.TransitionSplitCols = cc.TransitionScene.extend(/** @lends cc.TransitionSplitCols# */{
+ _gridProxy: null,
+
+ _switchTargetToInscene: function () {
+ this._gridProxy.setTarget(this._inScene);
+ },
+
+ /**
+ * Constructor of TransitionSplitCols
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionScene.prototype.ctor.call(this);
+ this._gridProxy = new cc.NodeGrid();
+ scene && this.initWithDuration(t, scene);
+ },
+ /**
+ * custom on enter
+ */
+ onEnter: function () {
+ cc.TransitionScene.prototype.onEnter.call(this);
+ //this._inScene.visible = false;
+ this._gridProxy.setTarget(this._outScene);
+ this._gridProxy._performRecursive(cc.Node._stateCallbackType.onEnter);
+
+ var split = this.action();
+ var seq = cc.sequence(
+ split, cc.callFunc(this._switchTargetToInscene, this), split.reverse());
+
+ this._gridProxy.runAction(
+ cc.sequence(this.easeActionWithAction(seq), cc.callFunc(this.finish, this), cc.stopGrid())
+ );
+ },
+
+ onExit: function () {
+ this._gridProxy.setTarget(null);
+ this._gridProxy._performRecursive(cc.Node._stateCallbackType.onExit);
+ cc.TransitionScene.prototype.onExit.call(this);
+ },
+
+ visit: function () {
+ this._gridProxy.visit();
+ },
+
+ /**
+ * @param {cc.ActionInterval} action
+ * @return {cc.EaseInOut}
+ */
+ easeActionWithAction: function (action) {
+ return new cc.EaseInOut(action, 3.0);
+ },
+
+ /**
+ * @return {*}
+ */
+ action: function () {
+ return cc.splitCols(this._duration / 2.0, 3);
+ }
+});
+
+/**
+ * The odd columns goes upwards while the even columns goes downwards.
+ * @deprecated since v3.0,please use new cc.TransitionSplitCols(t, scene) instead.
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionSplitCols}
+ */
+cc.TransitionSplitCols.create = function (t, scene) {
+ return new cc.TransitionSplitCols(t, scene);
+};
+
+/**
+ * The odd rows goes to the left while the even rows goes to the right.
+ * @class
+ * @extends cc.TransitionSplitCols
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionSplitRows(time,scene);
+ */
+cc.TransitionSplitRows = cc.TransitionSplitCols.extend(/** @lends cc.TransitionSplitRows# */{
+
+ /**
+ * Constructor of TransitionSplitRows
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionSplitCols.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+ /**
+ * @return {*}
+ */
+ action: function () {
+ return cc.splitRows(this._duration / 2.0, 3);
+ }
+});
+
+/**
+ * The odd rows goes to the left while the even rows goes to the right.
+ * @deprecated since v3.0,please use new cc.TransitionSplitRows(t, scene) instead.
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionSplitRows}
+ */
+cc.TransitionSplitRows.create = function (t, scene) {
+ return new cc.TransitionSplitRows(t, scene);
+};
+
+/**
+ * Fade the tiles of the outgoing scene from the left-bottom corner the to top-right corner.
+ * @class
+ * @extends cc.TransitionScene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionFadeTR(time,scene);
+ */
+cc.TransitionFadeTR = cc.TransitionScene.extend(/** @lends cc.TransitionFadeTR# */{
+ _gridProxy: null,
+ /**
+ * Constructor of TransitionFadeTR
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionScene.prototype.ctor.call(this);
+ this._gridProxy = new cc.NodeGrid();
+ scene && this.initWithDuration(t, scene);
+ },
+ _sceneOrder: function () {
+ this._isInSceneOnTop = false;
+ },
+
+ /**
+ * Custom on enter
+ */
+ onEnter: function () {
+ cc.TransitionScene.prototype.onEnter.call(this);
+
+ this._gridProxy.setTarget(this._outScene);
+ this._gridProxy._performRecursive(cc.Node._stateCallbackType.onEnter);
+
+ var winSize = cc.director.getWinSize();
+ var aspect = winSize.width / winSize.height;
+ var x = 0 | (12 * aspect);
+ var y = 12;
+
+ var action = this.actionWithSize(cc.size(x, y));
+ this._gridProxy.runAction(
+ cc.sequence(this.easeActionWithAction(action), cc.callFunc(this.finish, this), cc.stopGrid())
+ );
+ },
+
+ visit: function () {
+ this._inScene.visit();
+ this._gridProxy.visit();
+ },
+
+ /**
+ * @param {cc.ActionInterval} action
+ * @return {cc.ActionInterval}
+ */
+ easeActionWithAction: function (action) {
+ return action;
+ },
+
+ /**
+ * @param {cc.Size} size
+ * @return {*}
+ */
+ actionWithSize: function (size) {
+ return cc.fadeOutTRTiles(this._duration, size);
+ }
+});
+
+/**
+ * Fade the tiles of the outgoing scene from the left-bottom corner the to top-right corner.
+ * @deprecated since v3.0 please use new cc.TransitionFadeTR(t, scene) instead.
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionFadeTR}
+ */
+cc.TransitionFadeTR.create = function (t, scene) {
+ return new cc.TransitionFadeTR(t, scene);
+};
+
+/**
+ * Fade the tiles of the outgoing scene from the top-right corner to the bottom-left corner.
+ * @class
+ * @extends cc.TransitionFadeTR
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionFadeBL(time,scene)
+ */
+cc.TransitionFadeBL = cc.TransitionFadeTR.extend(/** @lends cc.TransitionFadeBL# */{
+ /**
+ * Constructor of TransitionFadeBL
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionFadeTR.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+
+ /**
+ * @param {cc.Size} size
+ * @return {*}
+ */
+ actionWithSize: function (size) {
+ return cc.fadeOutBLTiles(this._duration, size);
+ }
+});
+
+/**
+ * Fade the tiles of the outgoing scene from the top-right corner to the bottom-left corner.
+ * @deprecated since v3.0,please use new cc.TransitionFadeBL(t, scene);
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionFadeBL}
+ */
+cc.TransitionFadeBL.create = function (t, scene) {
+ return new cc.TransitionFadeBL(t, scene);
+};
+
+/**
+ * Fade the tiles of the outgoing scene from the top-right corner to the bottom-left corner.
+ * @class
+ * @extends cc.TransitionFadeTR
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionFadeUp(time,scene);
+ */
+cc.TransitionFadeUp = cc.TransitionFadeTR.extend(/** @lends cc.TransitionFadeUp# */{
+
+ /**
+ * Constructor of TransitionFadeUp
+ * @function
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionFadeTR.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+
+ /**
+ * @param {cc.Size} size
+ * @return {cc.FadeOutUpTiles}
+ */
+ actionWithSize: function (size) {
+ return new cc.FadeOutUpTiles(this._duration, size);
+ }
+});
+
+/**
+ * Fade the tiles of the outgoing scene from the top-right corner to the bottom-left corner.
+ * @deprecated since v3.0,please use new cc.TransitionFadeUp(t, scene) instead.
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionFadeUp}
+ */
+cc.TransitionFadeUp.create = function (t, scene) {
+ return new cc.TransitionFadeUp(t, scene);
+};
+
+/**
+ * Fade the tiles of the outgoing scene from the top to the bottom.
+ * @class
+ * @extends cc.TransitionFadeTR
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionFadeDown(time,scene);
+ */
+cc.TransitionFadeDown = cc.TransitionFadeTR.extend(/** @lends cc.TransitionFadeDown# */{
+
+ /**
+ * Constructor of TransitionFadeDown
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ */
+ ctor: function (t, scene) {
+ cc.TransitionFadeTR.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+
+ /**
+ * @param {cc.Size} size
+ * @return {*}
+ */
+ actionWithSize: function (size) {
+ return cc.fadeOutDownTiles(this._duration, size);
+ }
+});
+
+/**
+ * Fade the tiles of the outgoing scene from the top to the bottom.
+ * @deprecated since v3.0,please use new cc.TransitionFadeDown(t, scene) instead.
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionFadeDown}
+ */
+cc.TransitionFadeDown.create = function (t, scene) {
+ return new cc.TransitionFadeDown(t, scene);
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/transitions/CCTransitionPageTurn.js b/frameworks/cocos2d-html5/cocos2d/transitions/CCTransitionPageTurn.js
new file mode 100644
index 0000000..44a6bed
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/transitions/CCTransitionPageTurn.js
@@ -0,0 +1,152 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * A transition which peels back the bottom right hand corner of a scene
+ * to transition to the scene beneath it simulating a page turn.
+ *
+ * This uses a 3DAction so it's strongly recommended that depth buffering
+ * is turned on in cc.director using:
+ *
+ * cc.director.setDepthBufferFormat(kDepthBuffer16);
+ * @class
+ * @extends cc.TransitionScene
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @param {Boolean} backwards
+ * @example
+ * var trans = new cc.TransitionPageTurn(t, scene, backwards);
+ */
+cc.TransitionPageTurn = cc.TransitionScene.extend(/** @lends cc.TransitionPageTurn# */{
+
+ /**
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @param {Boolean} backwards
+ */
+ ctor: function (t, scene, backwards) {
+ cc.TransitionScene.prototype.ctor.call(this);
+ this._gridProxy = new cc.NodeGrid();
+ this.initWithDuration(t, scene, backwards);
+ },
+
+ /**
+ * @type Boolean
+ */
+ _back: true,
+ _gridProxy: null,
+ _className: "TransitionPageTurn",
+
+ /**
+ * Creates a base transition with duration and incoming scene.
+ * If back is true then the effect is reversed to appear as if the incoming
+ * scene is being turned from left over the outgoing scene.
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @param {Boolean} backwards
+ * @return {Boolean}
+ */
+ initWithDuration: function (t, scene, backwards) {
+ // XXX: needed before [super init]
+ this._back = backwards;
+
+ if (cc.TransitionScene.prototype.initWithDuration.call(this, t, scene)) {
+ // do something
+ }
+ return true;
+ },
+
+ /**
+ * @param {cc.Size} vector
+ * @return {cc.ReverseTime|cc.TransitionScene}
+ */
+ actionWithSize: function (vector) {
+ if (this._back)
+ return cc.reverseTime(cc.pageTurn3D(this._duration, vector)); // Get hold of the PageTurn3DAction
+ else
+ return cc.pageTurn3D(this._duration, vector); // Get hold of the PageTurn3DAction
+ },
+
+ /**
+ * custom on enter
+ */
+ onEnter: function () {
+ cc.TransitionScene.prototype.onEnter.call(this);
+ var winSize = cc.director.getWinSize();
+ var x, y;
+ if (winSize.width > winSize.height) {
+ x = 16;
+ y = 12;
+ } else {
+ x = 12;
+ y = 16;
+ }
+
+ var action = this.actionWithSize(cc.size(x, y)), gridProxy = this._gridProxy;
+
+ if (!this._back) {
+ gridProxy.setTarget(this._outScene);
+ gridProxy._performRecursive(cc.Node._stateCallbackType.onEnter);
+ gridProxy.runAction(cc.sequence(action, cc.callFunc(this.finish, this), cc.stopGrid()));
+ } else {
+ gridProxy.setTarget(this._inScene);
+ gridProxy._performRecursive(cc.Node._stateCallbackType.onEnter);
+ // to prevent initial flicker
+ this._inScene.visible = false;
+ gridProxy.runAction(
+ cc.sequence(action, cc.callFunc(this.finish, this), cc.stopGrid())
+ );
+ this._inScene.runAction(cc.show());
+ }
+ },
+
+ visit: function () {
+ //cc.TransitionScene.prototype.visit.call(this);
+ if (this._back)
+ this._outScene.visit();
+ else
+ this._inScene.visit();
+ this._gridProxy.visit();
+ },
+
+ _sceneOrder: function () {
+ this._isInSceneOnTop = this._back;
+ }
+});
+
+/**
+ * Creates a base transition with duration and incoming scene.
+ * If back is true then the effect is reversed to appear as if the incoming
+ * scene is being turned from left over the outgoing scene.
+ * @deprecated since v3.0,please use new cc.TransitionPageTurn(t, scene, backwards) instead.
+ * @param {Number} t time in seconds
+ * @param {cc.Scene} scene
+ * @param {Boolean} backwards
+ * @return {cc.TransitionPageTurn}
+ */
+cc.TransitionPageTurn.create = function (t, scene, backwards) {
+ return new cc.TransitionPageTurn(t, scene, backwards);
+};
diff --git a/frameworks/cocos2d-html5/cocos2d/transitions/CCTransitionProgress.js b/frameworks/cocos2d-html5/cocos2d/transitions/CCTransitionProgress.js
new file mode 100644
index 0000000..38e67e2
--- /dev/null
+++ b/frameworks/cocos2d-html5/cocos2d/transitions/CCTransitionProgress.js
@@ -0,0 +1,452 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * tag for scene redial
+ * @constant
+ * @type Number
+ */
+cc.SCENE_RADIAL = 0xc001;
+
+/**
+ * cc.TransitionProgress transition.
+ * @class
+ * @extends cc.TransitionScene
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionProgress(time,scene);
+ */
+cc.TransitionProgress = cc.TransitionScene.extend(/** @lends cc.TransitionProgress# */{
+ _to:0,
+ _from:0,
+ _sceneToBeModified:null,
+ _className:"TransitionProgress",
+
+ /**
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ */
+ ctor:function (t, scene) {
+ cc.TransitionScene.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+
+ _setAttrs: function(node, x, y) {
+ node.attr({
+ x: x,
+ y: y,
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ },
+
+ /**
+ * Custom on enter.
+ * @override
+ */
+ onEnter:function () {
+ cc.TransitionScene.prototype.onEnter.call(this);
+ this._setupTransition();
+
+ // create a transparent color layer
+ // in which we are going to add our rendertextures
+ var winSize = cc.director.getWinSize();
+
+ // create the second render texture for outScene
+ var texture = new cc.RenderTexture(winSize.width, winSize.height);
+ texture.sprite.anchorX = 0.5;
+ texture.sprite.anchorY = 0.5;
+ this._setAttrs(texture, winSize.width / 2, winSize.height / 2);
+
+ // render outScene to its texturebuffer
+ texture.clear(0, 0, 0, 1);
+ texture.begin();
+ this._sceneToBeModified.visit();
+ texture.end();
+
+ // Since we've passed the outScene to the texture we don't need it.
+ if (this._sceneToBeModified === this._outScene)
+ this.hideOutShowIn();
+
+ // We need the texture in RenderTexture.
+ var pNode = this._progressTimerNodeWithRenderTexture(texture);
+
+ // create the blend action
+ var layerAction = cc.sequence(
+ cc.progressFromTo(this._duration, this._from, this._to),
+ cc.callFunc(this.finish, this));
+ // run the blend action
+ pNode.runAction(layerAction);
+
+ // add the layer (which contains our two rendertextures) to the scene
+ this.addChild(pNode, 2, cc.SCENE_RADIAL);
+ },
+
+ /**
+ * custom on exit
+ * @override
+ */
+ onExit:function () {
+ // remove our layer and release all containing objects
+ this.removeChildByTag(cc.SCENE_RADIAL, true);
+ cc.TransitionScene.prototype.onExit.call(this);
+ },
+
+ _setupTransition:function () {
+ this._sceneToBeModified = this._outScene;
+ this._from = 100;
+ this._to = 0;
+ },
+
+ _progressTimerNodeWithRenderTexture:function (texture) {
+ cc.log("cc.TransitionProgress._progressTimerNodeWithRenderTexture(): should be overridden in subclass");
+ return null;
+ },
+
+ _sceneOrder:function () {
+ this._isInSceneOnTop = false;
+ }
+});
+
+/**
+ * create a cc.TransitionProgress object
+ * @deprecated since v3.0,please use new cc.TransitionProgress(t, scene) instead.
+ * @function
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionProgress}
+ */
+cc.TransitionProgress.create = function (t, scene) {
+ return new cc.TransitionProgress(t, scene);
+};
+
+/**
+ * cc.TransitionRadialCCW transition.
+ * A counter clock-wise radial transition to the next scene
+ * @class
+ * @extends cc.TransitionProgress
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionProgressRadialCCW(t, scene);
+ */
+cc.TransitionProgressRadialCCW = cc.TransitionProgress.extend(/** @lends cc.TransitionProgressRadialCCW# */{
+
+ /**
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ */
+ ctor:function (t, scene) {
+ cc.TransitionProgress.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+
+ _progressTimerNodeWithRenderTexture:function (texture) {
+ var size = cc.director.getWinSize();
+
+ var pNode = new cc.ProgressTimer(texture.sprite);
+ // but it is flipped upside down so we flip the sprite
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ pNode.sprite.flippedY = true;
+ pNode.type = cc.ProgressTimer.TYPE_RADIAL;
+
+ // Return the radial type that we want to use
+ pNode.reverseDir = false;
+ pNode.percentage = 100;
+ this._setAttrs(pNode, size.width / 2, size.height / 2);
+
+ return pNode;
+ }
+});
+
+/**
+ * create a cc.TransitionProgressRadialCCW object
+ * @deprecated since v3.0,please use new cc.TransitionProgressRadialCCW(t, scene) instead.
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionProgressRadialCCW}
+ * @example
+ * var trans = new cc.TransitionProgressRadialCCW(time,scene);
+ */
+cc.TransitionProgressRadialCCW.create = function (t, scene) {
+ return new cc.TransitionProgressRadialCCW(t, scene);
+};
+
+/**
+ * cc.TransitionRadialCW transition.
+ * A counter colock-wise radial transition to the next scene
+ * @class
+ * @extends cc.TransitionProgress
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionProgressRadialCW(t, scene);
+ */
+cc.TransitionProgressRadialCW = cc.TransitionProgress.extend(/** @lends cc.TransitionProgressRadialCW# */{
+ /**
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ */
+ ctor:function (t, scene) {
+ cc.TransitionProgress.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+
+ _progressTimerNodeWithRenderTexture:function (texture) {
+ var size = cc.director.getWinSize();
+
+ var pNode = new cc.ProgressTimer(texture.sprite);
+ // but it is flipped upside down so we flip the sprite
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ pNode.sprite.flippedY = true;
+ pNode.type = cc.ProgressTimer.TYPE_RADIAL;
+
+ // Return the radial type that we want to use
+ pNode.reverseDir = true;
+ pNode.percentage = 100;
+ this._setAttrs(pNode, size.width / 2, size.height / 2);
+
+ return pNode;
+ }
+});
+
+/**
+ * create a cc.TransitionProgressRadialCW object
+ * @deprecated since v3.0,please use cc.TransitionProgressRadialCW(t, scene) instead.
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionProgressRadialCW}
+ */
+cc.TransitionProgressRadialCW.create = function (t, scene) {
+ var tempScene = new cc.TransitionProgressRadialCW();
+ if ((tempScene !== null) && (tempScene.initWithDuration(t, scene))) {
+ return tempScene;
+ }
+ return new cc.TransitionProgressRadialCW(t, scene);
+};
+
+/**
+ * cc.TransitionProgressHorizontal transition.
+ * A colock-wise radial transition to the next scene
+ * @class
+ * @extends cc.TransitionProgress
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionProgressHorizontal(t, scene);
+ */
+cc.TransitionProgressHorizontal = cc.TransitionProgress.extend(/** @lends cc.TransitionProgressHorizontal# */{
+ /**
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ */
+ ctor:function (t, scene) {
+ cc.TransitionProgress.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+
+ _progressTimerNodeWithRenderTexture:function (texture) {
+ var size = cc.director.getWinSize();
+
+ var pNode = new cc.ProgressTimer(texture.sprite);
+ // but it is flipped upside down so we flip the sprite
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ pNode.sprite.flippedY = true;
+ pNode.type = cc.ProgressTimer.TYPE_BAR;
+
+ pNode.midPoint = cc.p(1, 0);
+ pNode.barChangeRate = cc.p(1, 0);
+
+ pNode.percentage = 100;
+ this._setAttrs(pNode, size.width / 2, size.height / 2);
+
+ return pNode;
+ }
+});
+
+/**
+ * create a cc.TransitionProgressHorizontal object
+ * @deprecated since v3.0,please use new cc.TransitionProgressHorizontal(t, scene) instead.
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionProgressHorizontal}
+ */
+cc.TransitionProgressHorizontal.create = function (t, scene) {
+ return new cc.TransitionProgressHorizontal(t, scene);
+};
+
+/**
+ * cc.TransitionProgressVertical transition.
+ * @class
+ * @extends cc.TransitionProgress
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ * @example
+ * var trans = new cc.TransitionProgressVertical(t, scene);
+ */
+cc.TransitionProgressVertical = cc.TransitionProgress.extend(/** @lends cc.TransitionProgressVertical# */{
+
+ /**
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ */
+ ctor:function (t, scene) {
+ cc.TransitionProgress.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+
+ _progressTimerNodeWithRenderTexture:function (texture) {
+ var size = cc.director.getWinSize();
+
+ var pNode = new cc.ProgressTimer(texture.sprite);
+ // but it is flipped upside down so we flip the sprite
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ pNode.sprite.flippedY = true;
+ pNode.type = cc.ProgressTimer.TYPE_BAR;
+
+ pNode.midPoint = cc.p(0, 0);
+ pNode.barChangeRate = cc.p(0, 1);
+
+ pNode.percentage = 100;
+ this._setAttrs(pNode, size.width / 2, size.height / 2);
+
+ return pNode;
+ }
+});
+
+/**
+ * create a cc.TransitionProgressVertical object
+ * @deprecated since v3.0,please use new cc.TransitionProgressVertical(t, scene) instead.
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionProgressVertical}
+ */
+cc.TransitionProgressVertical.create = function (t, scene) {
+ return new cc.TransitionProgressVertical(t, scene);
+};
+
+/**
+ * cc.TransitionProgressInOut transition.
+ * @class
+ * @extends cc.TransitionProgress
+ */
+cc.TransitionProgressInOut = cc.TransitionProgress.extend(/** @lends cc.TransitionProgressInOut# */{
+
+ /**
+ * The constructor of cc.TransitionProgressInOut. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ */
+ ctor:function (t, scene) {
+ cc.TransitionProgress.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+
+ _progressTimerNodeWithRenderTexture:function (texture) {
+ var size = cc.director.getWinSize();
+ var pNode = new cc.ProgressTimer(texture.sprite);
+ // but it is flipped upside down so we flip the sprite
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ pNode.sprite.flippedY = true;
+ pNode.type = cc.ProgressTimer.TYPE_BAR;
+
+ pNode.midPoint = cc.p(0.5, 0.5);
+ pNode.barChangeRate = cc.p(1, 1);
+
+ pNode.percentage = 0;
+ this._setAttrs(pNode, size.width / 2, size.height / 2);
+
+ return pNode;
+ },
+ _sceneOrder:function () {
+ this._isInSceneOnTop = false;
+ },
+ _setupTransition:function () {
+ this._sceneToBeModified = this._inScene;
+ this._from = 0;
+ this._to = 100;
+ }
+});
+
+/**
+ * create a cc.TransitionProgressInOut object
+ * @function
+ * @deprecated
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionProgressInOut}
+ */
+cc.TransitionProgressInOut.create = function (t, scene) {
+ return new cc.TransitionProgressInOut(t, scene);
+};
+
+/**
+ * cc.TransitionProgressOutIn transition.
+ * @class
+ * @extends cc.TransitionProgress
+ */
+cc.TransitionProgressOutIn = cc.TransitionProgress.extend(/** @lends cc.TransitionProgressOutIn# */{
+
+ /**
+ * The constructor of cc.TransitionProgressOutIn. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ */
+ ctor:function (t, scene) {
+ cc.TransitionProgress.prototype.ctor.call(this);
+ scene && this.initWithDuration(t, scene);
+ },
+
+ _progressTimerNodeWithRenderTexture:function (texture) {
+ var size = cc.director.getWinSize();
+ var pNode = new cc.ProgressTimer(texture.sprite);
+ // but it is flipped upside down so we flip the sprite
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ pNode.sprite.flippedY = true;
+ pNode.type = cc.ProgressTimer.TYPE_BAR;
+
+ pNode.midPoint = cc.p(0.5, 0.5);
+ pNode.barChangeRate = cc.p(1, 1);
+
+ pNode.percentage = 100;
+ this._setAttrs(pNode, size.width / 2, size.height / 2);
+
+ return pNode;
+ }
+});
+
+/**
+ * create a cc.TransitionProgressOutIn object
+ * @function
+ * @deprecated
+ * @param {Number} t time
+ * @param {cc.Scene} scene
+ * @return {cc.TransitionProgressOutIn}
+ */
+cc.TransitionProgressOutIn.create = function (t, scene) {
+ return new cc.TransitionProgressOutIn(t, scene);
+};
diff --git a/frameworks/cocos2d-html5/extensions/ccb-reader/CCBAnimationManager.js b/frameworks/cocos2d-html5/extensions/ccb-reader/CCBAnimationManager.js
new file mode 100644
index 0000000..54ab341
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccb-reader/CCBAnimationManager.js
@@ -0,0 +1,774 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+
+var _pos = cc.p();
+
+cc.BuilderAnimationManagerDelegate = cc.Class.extend({
+ completedAnimationSequenceNamed: function (name) {
+ }
+});
+
+cc.BuilderAnimationManager = cc.Class.extend({
+ _sequences: null,
+ _nodeSequences: null,
+ _baseValues: null,
+ _autoPlaySequenceId: 0,
+
+ _rootNode: null,
+ _owner: null,
+ _rootContainerSize: null,
+
+ _delegate: null,
+ _runningSequence: null,
+
+ _documentOutletNames: null,
+ _documentOutletNodes: null,
+ _documentCallbackNames: null,
+ _documentCallbackNodes: null,
+ _documentCallbackControlEvents: null,
+ _documentControllerName: "",
+ _lastCompletedSequenceName: "",
+ _keyframeCallbacks: null,
+ _keyframeCallFuncs: null,
+
+ _animationCompleteCallbackFunc: null,
+ _target: null,
+ _jsControlled: false,
+
+ ctor: function () {
+ this._rootContainerSize = cc.size(0, 0);
+ this.init();
+ },
+
+ init: function () {
+ this._sequences = [];
+ this._nodeSequences = new cc._Dictionary();
+ this._baseValues = new cc._Dictionary();
+
+ this._documentOutletNames = [];
+ this._documentOutletNodes = [];
+ this._documentCallbackNames = [];
+ this._documentCallbackNodes = [];
+ this._documentCallbackControlEvents = [];
+
+ this._keyframeCallbacks = [];
+ this._keyframeCallFuncs = {};
+
+ return true;
+ },
+
+ getSequences: function () {
+ return this._sequences;
+ },
+
+ setSequences: function (seqs) {
+ this._sequences = seqs;
+ },
+
+ getAutoPlaySequenceId: function () {
+ return this._autoPlaySequenceId;
+ },
+ setAutoPlaySequenceId: function (autoPlaySequenceId) {
+ this._autoPlaySequenceId = autoPlaySequenceId;
+ },
+
+ getRootNode: function () {
+ return this._rootNode;
+ },
+ setRootNode: function (rootNode) {
+ this._rootNode = rootNode;
+ },
+
+ getOwner: function () {
+ return this._owner;
+ },
+ setOwner: function (owner) {
+ this._owner = owner;
+ },
+
+ addDocumentCallbackNode: function (node) {
+ this._documentCallbackNodes.push(node);
+ },
+
+ addDocumentCallbackName: function (name) {
+ this._documentCallbackNames.push(name);
+ },
+
+ addDocumentCallbackControlEvents: function (controlEvents) {
+ this._documentCallbackControlEvents.push(controlEvents);
+ },
+
+ addDocumentOutletNode: function (node) {
+ this._documentOutletNodes.push(node);
+ },
+
+ addDocumentOutletName: function (name) {
+ this._documentOutletNames.push(name);
+ },
+
+ setDocumentControllerName: function (name) {
+ this._documentControllerName = name;
+ },
+
+ getDocumentControllerName: function () {
+ return this._documentControllerName;
+ },
+
+ getDocumentCallbackNames: function () {
+ return this._documentCallbackNames;
+ },
+
+ getDocumentCallbackNodes: function () {
+ return this._documentCallbackNodes;
+ },
+
+ getDocumentCallbackControlEvents: function () {
+ return this._documentCallbackControlEvents;
+ },
+
+ getDocumentOutletNames: function () {
+ return this._documentOutletNames;
+ },
+
+ getDocumentOutletNodes: function () {
+ return this._documentOutletNodes;
+ },
+
+ getLastCompletedSequenceName: function () {
+ return this._lastCompletedSequenceName;
+ },
+
+ getKeyframeCallbacks: function () {
+ return this._keyframeCallbacks;
+ },
+
+ getRootContainerSize: function () {
+ return this._rootContainerSize;
+ },
+ setRootContainerSize: function (rootContainerSize) {
+ this._rootContainerSize = cc.size(rootContainerSize.width, rootContainerSize.height);
+ },
+
+ getDelegate: function () {
+ return this._delegate;
+ },
+ setDelegate: function (delegate) {
+ this._delegate = delegate;
+ },
+
+ getRunningSequenceName: function () {
+ if (this._runningSequence)
+ return this._runningSequence.getName();
+ return null;
+ },
+
+ getContainerSize: function (node) {
+ if (node)
+ return node.getContentSize();
+ else
+ return this._rootContainerSize;
+ },
+
+ addNode: function (node, seq) {
+ this._nodeSequences.setObject(seq, node);
+ },
+ setBaseValue: function (value, node, propName) {
+ var props = this._baseValues.objectForKey(node);
+ if (!props) {
+ props = new cc._Dictionary();
+ this._baseValues.setObject(props, node);
+ }
+ props.setObject(value, propName);
+ },
+
+ moveAnimationsFromNode: function (fromNode, toNode) {
+ // Move base values
+ var locBaseValues = this._baseValues;
+ var baseValue = locBaseValues.objectForKey(fromNode);
+ if (baseValue !== null) {
+ locBaseValues.setObject(baseValue, toNode);
+ locBaseValues.removeObjectForKey(fromNode);
+ }
+
+ // Move seqs
+ var locNodeSequences = this._nodeSequences;
+ var seqs = locNodeSequences.objectForKey(fromNode);
+ if (seqs != null) {
+ locNodeSequences.setObject(seqs, toNode);
+ locNodeSequences.removeObjectForKey(fromNode);
+ }
+ },
+
+ getActionForCallbackChannel: function (channel) {
+ var lastKeyframeTime = 0;
+
+ var actions = [];
+ var keyframes = channel.getKeyframes();
+ var numKeyframes = keyframes.length;
+
+ for (var i = 0; i < numKeyframes; ++i) {
+ var keyframe = keyframes[i];
+ var timeSinceLastKeyframe = keyframe.getTime() - lastKeyframeTime;
+ lastKeyframeTime = keyframe.getTime();
+ if (timeSinceLastKeyframe > 0) {
+ actions.push(cc.delayTime(timeSinceLastKeyframe));
+ }
+
+ var keyVal = keyframe.getValue();
+ var selectorName = keyVal[0];
+ var selectorTarget = keyVal[1];
+
+ if (this._jsControlled) {
+ var callbackName = selectorTarget + ":" + selectorName; //add number to the stream
+ var callback = this._keyframeCallFuncs[callbackName];
+
+ if (callback != null)
+ actions.push(callback);
+ } else {
+ var target;
+ if (selectorTarget === CCB_TARGETTYPE_DOCUMENTROOT)
+ target = this._rootNode;
+ else if (selectorTarget === CCB_TARGETTYPE_OWNER)
+ target = this._owner;
+
+ if (target != null) {
+ if (selectorName.length > 0) {
+ var selCallFunc = 0;
+
+ if (target.onResolveCCBCCCallFuncSelector != null)
+ selCallFunc = target.onResolveCCBCCCallFuncSelector(target, selectorName);
+ if (selCallFunc === 0)
+ cc.log("Skipping selector '" + selectorName + "' since no CCBSelectorResolver is present.");
+ else
+ actions.push(cc.callFunc(selCallFunc, target));
+ } else {
+ cc.log("Unexpected empty selector.");
+ }
+ }
+ }
+ }
+ if (actions.length < 1)
+ return null;
+
+ return cc.sequence(actions);
+ },
+ getActionForSoundChannel: function (channel) {
+ var lastKeyframeTime = 0;
+
+ var actions = [];
+ var keyframes = channel.getKeyframes();
+ var numKeyframes = keyframes.length;
+
+ for (var i = 0; i < numKeyframes; ++i) {
+ var keyframe = keyframes[i];
+ var timeSinceLastKeyframe = keyframe.getTime() - lastKeyframeTime;
+ lastKeyframeTime = keyframe.getTime();
+ if (timeSinceLastKeyframe > 0) {
+ actions.push(cc.delayTime(timeSinceLastKeyframe));
+ }
+
+ var keyVal = keyframe.getValue();
+ var soundFile = cc.BuilderReader.getResourcePath() + keyVal[0];
+ var pitch = parseFloat(keyVal[1]), pan = parseFloat(keyVal[2]), gain = parseFloat(keyVal[3]);
+ actions.push(cc.BuilderSoundEffect.create(soundFile, pitch, pan, gain));
+ }
+
+ if (actions.length < 1)
+ return null;
+
+ return cc.sequence(actions);
+ },
+
+ runAnimationsForSequenceNamed: function (name) {
+ this.runAnimationsForSequenceIdTweenDuration(this._getSequenceId(name), 0);
+ },
+
+ runAnimationsForSequenceNamedTweenDuration: function (name, tweenDuration) {
+ this.runAnimationsForSequenceIdTweenDuration(this._getSequenceId(name), tweenDuration);
+ },
+
+ runAnimationsForSequenceIdTweenDuration: function (nSeqId, tweenDuration) {
+ if (nSeqId === -1)
+ throw new Error("cc.BuilderAnimationManager.runAnimationsForSequenceIdTweenDuration(): Sequence id should not be -1");
+ tweenDuration = tweenDuration || 0;
+
+ this._rootNode.stopAllActions();
+
+ var allKeys = this._nodeSequences.allKeys();
+ for (var i = 0, len = allKeys.length; i < len; i++) {
+ var node = allKeys[i];
+ node.stopAllActions();
+
+ var seqs = this._nodeSequences.objectForKey(node);
+ var seqNodeProps = seqs.objectForKey(nSeqId);
+ var j;
+ var seqNodePropNames = [];
+ if (seqNodeProps) {
+ var propKeys = seqNodeProps.allKeys();
+ for (j = 0; j < propKeys.length; j++) {
+ var propName = propKeys[j];
+ var seqProp = seqNodeProps.objectForKey(propName);
+ seqNodePropNames.push(propName);
+
+ this._setFirstFrame(node, seqProp, tweenDuration);
+ this._runAction(node, seqProp, tweenDuration);
+ }
+ }
+
+ var nodeBaseValues = this._baseValues.objectForKey(node);
+ if (nodeBaseValues) {
+ var baseKeys = nodeBaseValues.allKeys();
+ for (j = 0; j < baseKeys.length; j++) {
+ var selBaseKey = baseKeys[j];
+ if (seqNodePropNames.indexOf(selBaseKey) === -1) {
+ var value = nodeBaseValues.objectForKey(selBaseKey);
+ if (value != null)
+ this._setAnimatedProperty(selBaseKey, node, value, tweenDuration);
+ }
+ }
+ }
+ }
+
+ // Make callback at end of sequence
+ var seq = this._getSequence(nSeqId);
+ var completeAction = cc.sequence(cc.delayTime(seq.getDuration() + tweenDuration),
+ cc.callFunc(this._sequenceCompleted, this));
+ this._rootNode.runAction(completeAction);
+
+ // Playback callbacks and sounds
+ var action;
+ if (seq.getCallbackChannel()) {
+ // Build sound actions for channel
+ action = this.getActionForCallbackChannel(seq.getCallbackChannel());
+ if (action) {
+ this._rootNode.runAction(action);
+ }
+ }
+
+ if (seq.getSoundChannel()) {
+ // Build sound actions for channel
+ action = this.getActionForSoundChannel(seq.getSoundChannel());
+ if (action) {
+ this._rootNode.runAction(action);
+ }
+ }
+ // Set the running scene
+ this._runningSequence = this._getSequence(nSeqId);
+ },
+
+ runAnimations: function (name, tweenDuration) {
+ tweenDuration = tweenDuration || 0;
+ var nSeqId;
+ if (cc.isString(name))
+ nSeqId = this._getSequenceId(name);
+ else
+ nSeqId = name;
+
+ this.runAnimationsForSequenceIdTweenDuration(nSeqId, tweenDuration);
+ },
+
+ setAnimationCompletedCallback: function (target, callbackFunc) {
+ this._target = target;
+ this._animationCompleteCallbackFunc = callbackFunc;
+ },
+
+ setCompletedAnimationCallback: function (target, callbackFunc) {
+ this.setAnimationCompletedCallback(target, callbackFunc);
+ },
+ setCallFunc: function (callFunc, callbackNamed) {
+ this._keyframeCallFuncs[callbackNamed] = callFunc;
+ },
+
+ debug: function () {
+ },
+
+ _getBaseValue: function (node, propName) {
+ var props = this._baseValues.objectForKey(node);
+ if (props)
+ return props.objectForKey(propName);
+ return null;
+ },
+
+ _getSequenceId: function (sequenceName) {
+ var element = null;
+ var locSequences = this._sequences;
+ for (var i = 0, len = locSequences.length; i < len; i++) {
+ element = locSequences[i];
+ if (element && element.getName() === sequenceName)
+ return element.getSequenceId();
+ }
+ return -1;
+ },
+
+ _getSequence: function (sequenceId) {
+ var element = null;
+ var locSequences = this._sequences;
+ for (var i = 0, len = locSequences.length; i < len; i++) {
+ element = locSequences[i];
+ if (element && element.getSequenceId() === sequenceId)
+ return element;
+ }
+ return null;
+ },
+
+ _getAction: function (keyframe0, keyframe1, propName, node) {
+ var duration = keyframe1.getTime() - (keyframe0 ? keyframe0.getTime() : 0);
+ var getArr, type, getValueArr, x, y;
+
+ if (propName === "rotation") {
+ return cc.BuilderRotateTo.create(duration, keyframe1.getValue());
+ } else if (propName === "rotationX") {
+ return cc.BuilderRotateXTo.create(duration, keyframe1.getValue());
+ } else if (propName === "rotationY") {
+ return cc.BuilderRotateYTo.create(duration, keyframe1.getValue());
+ } else if (propName === "opacity") {
+ return cc.fadeTo(duration, keyframe1.getValue());
+ } else if (propName === "color") {
+ var selColor = keyframe1.getValue();
+ return cc.tintTo(duration, selColor.r, selColor.g, selColor.b);
+ } else if (propName === "visible") {
+ var isVisible = keyframe1.getValue();
+ if (isVisible) {
+ return cc.sequence(cc.delayTime(duration), cc.show());
+ } else {
+ return cc.sequence(cc.delayTime(duration), cc.hide());
+ }
+ } else if (propName === "displayFrame") {
+ return cc.sequence(cc.delayTime(duration), cc.BuilderSetSpriteFrame.create(keyframe1.getValue()));
+ } else if (propName === "position") {
+ getArr = this._getBaseValue(node, propName);
+ type = getArr[2];
+
+ //get relative position
+ getValueArr = keyframe1.getValue();
+ x = getValueArr[0];
+ y = getValueArr[1];
+
+ var containerSize = this.getContainerSize(node.getParent());
+
+ var absPos = cc.getAbsolutePosition(x, y, type, containerSize, propName);
+
+ return cc.moveTo(duration, absPos);
+ } else if (propName === "scale") {
+ getArr = this._getBaseValue(node, propName);
+ type = getArr[2];
+
+ //get relative position
+ getValueArr = keyframe1.getValue();
+ x = getValueArr[0];
+ y = getValueArr[1];
+
+ if (type === CCB_SCALETYPE_MULTIPLY_RESOLUTION) {
+ //TODO need to test
+ var resolutionScale = cc.BuilderReader.getResolutionScale();
+ x *= resolutionScale;
+ y *= resolutionScale;
+ }
+
+ return cc.scaleTo(duration, x, y);
+ } else if (propName === "skew") {
+ //get relative position
+ getValueArr = keyframe1.getValue();
+ x = getValueArr[0];
+ y = getValueArr[1];
+ return cc.skewTo(duration, x, y);
+ } else {
+ cc.log("BuilderReader: Failed to create animation for property: " + propName);
+ }
+ return null;
+ },
+
+ _setAnimatedProperty: function (propName, node, value, tweenDuration) {
+ if (tweenDuration > 0) {
+ // Create a fake keyframe to generate the action from
+ var kf1 = new cc.BuilderKeyframe();
+ kf1.setValue(value);
+ kf1.setTime(tweenDuration);
+ kf1.setEasingType(CCB_KEYFRAME_EASING_LINEAR);
+
+ // Animate
+ var tweenAction = this._getAction(null, kf1, propName, node);
+ node.runAction(tweenAction);
+ } else {
+ // Just set the value
+ var getArr, nType, x, y;
+ if (propName === "position") {
+ getArr = this._getBaseValue(node, propName);
+ nType = getArr[2];
+
+ x = value[0];
+ y = value[1];
+ cc.getAbsolutePosition(x, y, nType, this.getContainerSize(node.getParent()), propName, _pos);
+ node._position.x = _pos.x;
+ node._position.y = _pos.y;
+ } else if (propName === "scale") {
+ getArr = this._getBaseValue(node, propName);
+ nType = getArr[2];
+
+ x = value[0];
+ y = value[1];
+
+ cc.setRelativeScale(node, x, y, nType, propName);
+ } else if (propName === "skew") {
+ x = value[0];
+ y = value[1];
+ node._skewX = x;
+ node._skewY = y;
+ } else {
+ // [node setValue:value forKey:name];
+ // TODO only handle rotation, opacity, displayFrame, color
+ if (propName === "rotation") {
+ node.setRotation(value);
+ } else if (propName === "rotationX") {
+ node._rotationX = value;
+ } else if (propName === "rotationY") {
+ node._rotationY = value;
+ } else if (propName === "opacity") {
+ node._realOpacity = value;
+ } else if (propName === "displayFrame") {
+ node.setSpriteFrame(value);
+ } else if (propName === "color") {
+ if (value.r !== 255 || value.g !== 255 || value.b !== 255) {
+ node.setColor(value);
+ }
+ } else if (propName === "visible") {
+ value = value || false;
+ node.setVisible(value);
+ } else {
+ cc.log("unsupported property name is " + propName);
+ return;
+ }
+ }
+ node.setNodeDirty();
+ }
+ },
+
+ _setFirstFrame: function (node, seqProp, tweenDuration) {
+ var keyframes = seqProp.getKeyframes();
+
+ if (keyframes.length === 0) {
+ // Use base value (no animation)
+ var baseValue = this._getBaseValue(node, seqProp.getName());
+ if (!baseValue)
+ cc.log("cc.BuilderAnimationManager._setFirstFrame(): No baseValue found for property");
+ this._setAnimatedProperty(seqProp.getName(), node, baseValue, tweenDuration);
+ } else {
+ // Use first keyframe
+ var keyframe = keyframes[0];
+ this._setAnimatedProperty(seqProp.getName(), node, keyframe.getValue(), tweenDuration);
+ }
+ },
+
+ _getEaseAction: function (action, easingType, easingOpt) {
+ if (easingType === CCB_KEYFRAME_EASING_LINEAR || easingType === CCB_KEYFRAME_EASING_INSTANT) {
+ return action;
+ } else if (easingType === CCB_KEYFRAME_EASING_CUBIC_IN) {
+ return action.easing(cc.easeIn(easingOpt));
+ } else if (easingType === CCB_KEYFRAME_EASING_CUBIC_OUT) {
+ return action.easing(cc.easeOut(easingOpt));
+ } else if (easingType === CCB_KEYFRAME_EASING_CUBIC_INOUT) {
+ return action.easing(cc.easeInOut(easingOpt));
+ } else if (easingType === CCB_KEYFRAME_EASING_BACK_IN) {
+ return action.easing(cc.easeBackIn());
+ } else if (easingType === CCB_KEYFRAME_EASING_BACK_OUT) {
+ return action.easing(cc.easeBackOut());
+ } else if (easingType === CCB_KEYFRAME_EASING_BACK_INOUT) {
+ return action.easing(cc.easeBackInOut());
+ } else if (easingType === CCB_KEYFRAME_EASING_BOUNCE_IN) {
+ return action.easing(cc.easeBounceIn());
+ } else if (easingType === CCB_KEYFRAME_EASING_BOUNCE_OUT) {
+ return action.easing(cc.easeBounceOut());
+ } else if (easingType === CCB_KEYFRAME_EASING_BOUNCE_INOUT) {
+ return action.easing(cc.easeBounceInOut());
+ } else if (easingType === CCB_KEYFRAME_EASING_ELASTIC_IN) {
+ return action.easing(cc.easeElasticIn(easingOpt));
+ } else if (easingType === CCB_KEYFRAME_EASING_ELASTIC_OUT) {
+ return action.easing(cc.easeElasticOut(easingOpt));
+ } else if (easingType === CCB_KEYFRAME_EASING_ELASTIC_INOUT) {
+ return action.easing(cc.easeElasticInOut(easingOpt));
+ } else {
+ cc.log("BuilderReader: Unknown easing type " + easingType);
+ return action;
+ }
+ },
+
+ _runAction: function (node, seqProp, tweenDuration) {
+ var keyframes = seqProp.getKeyframes();
+ var numKeyframes = keyframes.length;
+
+ if (numKeyframes > 1) {
+ // Make an animation!
+ var actions = [];
+
+ var keyframeFirst = keyframes[0];
+ var timeFirst = keyframeFirst.getTime() + tweenDuration;
+
+ if (timeFirst > 0) {
+ actions.push(cc.delayTime(timeFirst));
+ }
+
+ for (var i = 0; i < numKeyframes - 1; ++i) {
+ var kf0 = keyframes[i];
+ var kf1 = keyframes[(i + 1)];
+
+ var action = this._getAction(kf0, kf1, seqProp.getName(), node);
+ if (action) {
+ // Apply easing
+ action = this._getEaseAction(action, kf0.getEasingType(), kf0.getEasingOpt());
+ actions.push(action);
+ }
+ }
+
+ node.runAction(cc.sequence(actions));
+ }
+ },
+
+ _sequenceCompleted: function () {
+ var locRunningSequence = this._runningSequence;
+
+ var locRunningName = locRunningSequence.getName();
+
+ if (this._lastCompletedSequenceName != locRunningSequence.getName()) {
+ this._lastCompletedSequenceName = locRunningSequence.getName();
+ }
+
+ var nextSeqId = locRunningSequence.getChainedSequenceId();
+ this._runningSequence = null;
+
+ if (nextSeqId !== -1)
+ this.runAnimations(nextSeqId, 0);
+
+ if (this._delegate)
+ this._delegate.completedAnimationSequenceNamed(locRunningName);
+
+ if (this._target && this._animationCompleteCallbackFunc) {
+ this._animationCompleteCallbackFunc.call(this._target);
+ }
+ }
+});
+
+
+cc.BuilderSetSpriteFrame = cc.ActionInstant.extend({
+ _spriteFrame: null,
+
+ initWithSpriteFrame: function (spriteFrame) {
+ this._spriteFrame = spriteFrame;
+ return true;
+ },
+ update: function (time) {
+ this.target.setSpriteFrame(this._spriteFrame);
+ }
+});
+
+cc.BuilderSetSpriteFrame.create = function (spriteFrame) {
+ var ret = new cc.BuilderSetSpriteFrame();
+ if (ret) {
+ if (ret.initWithSpriteFrame(spriteFrame))
+ return ret;
+ }
+ return null;
+};
+
+//
+// cc.BuilderRotateTo
+//
+cc.BuilderRotateTo = cc.ActionInterval.extend({
+ _startAngle: 0,
+ _dstAngle: 0,
+ _diffAngle: 0,
+
+ initWithDuration: function (duration, angle) {
+ if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
+ this._dstAngle = angle;
+ return true;
+ } else {
+ return false;
+ }
+ },
+ update: function (time) {
+ this.target.setRotation(this._startAngle + (this._diffAngle * time));
+ },
+
+ startWithTarget: function (node) {
+ cc.ActionInterval.prototype.startWithTarget.call(this, node);
+ this._startAngle = this.target.getRotation();
+ this._diffAngle = this._dstAngle - this._startAngle;
+ }
+});
+
+cc.BuilderRotateTo.create = function (duration, angle) {
+ var ret = new cc.BuilderRotateTo();
+ if (ret) {
+ if (ret.initWithDuration(duration, angle))
+ return ret;
+ }
+ return null;
+};
+
+//
+// cc.BuilderRotateXTo
+//
+cc.BuilderRotateXTo = cc.ActionInterval.extend({
+ // TODO: rotationX is not implemented in HTML5
+});
+
+cc.BuilderRotateXTo.create = function (duration, angle) {
+ throw new Error("rotationX has not been implemented in cocos2d-html5");
+};
+
+//
+// cc.BuilderRotateYTo
+//
+cc.BuilderRotateYTo = cc.ActionInterval.extend({
+ // TODO: rotationX is not implemented in HTML5
+});
+
+cc.BuilderRotateYTo.create = function (duration, angle) {
+ throw new Error("rotationY has not been implemented in cocos2d-html5");
+};
+
+//
+// cc.BuilderSoundEffect
+//
+cc.BuilderSoundEffect = cc.ActionInstant.extend({
+ init: function (file) {
+ this._file = file;
+ return true;
+ },
+ update: function (dt) {
+ cc.audioEngine.playEffect(this._file);
+ }
+});
+cc.BuilderSoundEffect.create = function (file, pitch, pan, gain) {
+ var ret = new cc.BuilderSoundEffect();
+ if (ret && ret.init(file)) {
+ return ret;
+ }
+ return null;
+};
+})();
diff --git a/frameworks/cocos2d-html5/extensions/ccb-reader/CCBKeyframe.js b/frameworks/cocos2d-html5/extensions/ccb-reader/CCBKeyframe.js
new file mode 100644
index 0000000..c3eb7af
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccb-reader/CCBKeyframe.js
@@ -0,0 +1,60 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.BuilderKeyframe = cc.Class.extend({
+ _value:null,
+ _time:0,
+ _easingType:0,
+ _easingOpt:0,
+
+ getValue:function(){
+ return this._value;
+ },
+ setValue:function(value){
+ this._value = value;
+ },
+
+ getTime:function(){
+ return this._time;
+ },
+ setTime:function(time){
+ this._time = time;
+ },
+
+ getEasingType:function(){
+ return this._easingType;
+ },
+ setEasingType:function(easingType){
+ this._easingType = easingType;
+ },
+
+ getEasingOpt:function(){
+ return this._easingOpt;
+ },
+ setEasingOpt:function(easingOpt){
+ this._easingOpt = easingOpt;
+ }
+});
diff --git a/frameworks/cocos2d-html5/extensions/ccb-reader/CCBReader.js b/frameworks/cocos2d-html5/extensions/ccb-reader/CCBReader.js
new file mode 100644
index 0000000..0baa27b
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccb-reader/CCBReader.js
@@ -0,0 +1,1105 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+var CCB_VERSION = 5;
+
+var CCB_PROPTYPE_POSITION = 0;
+var CCB_PROPTYPE_SIZE = 1;
+var CCB_PROPTYPE_POINT = 2;
+var CCB_PROPTYPE_POINTLOCK = 3;
+var CCB_PROPTYPE_SCALELOCK = 4;
+var CCB_PROPTYPE_DEGREES = 5;
+var CCB_PROPTYPE_INTEGER = 6;
+var CCB_PROPTYPE_FLOAT = 7;
+var CCB_PROPTYPE_FLOATVAR = 8;
+var CCB_PROPTYPE_CHECK = 9;
+var CCB_PROPTYPE_SPRITEFRAME = 10;
+var CCB_PROPTYPE_TEXTURE = 11;
+var CCB_PROPTYPE_BYTE = 12;
+var CCB_PROPTYPE_COLOR3 = 13;
+var CCB_PROPTYPE_COLOR4VAR = 14;
+var CCB_PROPTYPE_FLIP = 15;
+var CCB_PROPTYPE_BLENDMODE = 16;
+var CCB_PROPTYPE_FNTFILE = 17;
+var CCB_PROPTYPE_TEXT = 18;
+var CCB_PROPTYPE_FONTTTF = 19;
+var CCB_PROPTYPE_INTEGERLABELED = 20;
+var CCB_PROPTYPE_BLOCK = 21;
+var CCB_PROPTYPE_ANIMATION = 22;
+var CCB_PROPTYPE_CCBFILE = 23;
+var CCB_PROPTYPE_STRING = 24;
+var CCB_PROPTYPE_BLOCKCCCONTROL = 25;
+var CCB_PROPTYPE_FLOATSCALE = 26;
+var CCB_PROPTYPE_FLOATXY = 27;
+
+var CCB_FLOAT0 = 0;
+var CCB_FLOAT1 = 1;
+var CCB_FLOAT_MINUS1 = 2;
+var CCB_FLOAT05 = 3;
+var CCB_FLOAT_INTEGER = 4;
+var CCB_FLOAT_FULL = 5;
+
+var CCB_PLATFORM_ALL = 0;
+var CCB_PLATFORM_IOS = 1;
+var CCB_PLATFORM_MAC = 2;
+
+var CCB_TARGETTYPE_NONE = 0;
+var CCB_TARGETTYPE_DOCUMENTROOT = 1;
+var CCB_TARGETTYPE_OWNER = 2;
+
+var CCB_KEYFRAME_EASING_INSTANT = 0;
+var CCB_KEYFRAME_EASING_LINEAR = 1;
+var CCB_KEYFRAME_EASING_CUBIC_IN = 2;
+var CCB_KEYFRAME_EASING_CUBIC_OUT = 3;
+var CCB_KEYFRAME_EASING_CUBIC_INOUT = 4;
+var CCB_KEYFRAME_EASING_ELASTIC_IN = 5;
+var CCB_KEYFRAME_EASING_ELASTIC_OUT = 6;
+var CCB_KEYFRAME_EASING_ELASTIC_INOUT = 7;
+var CCB_KEYFRAME_EASING_BOUNCE_IN = 8;
+var CCB_KEYFRAME_EASING_BOUNCE_OUT = 9;
+var CCB_KEYFRAME_EASING_BOUNCE_INOUT = 10;
+var CCB_KEYFRAME_EASING_BACK_IN = 11;
+var CCB_KEYFRAME_EASING_BACK_OUT = 12;
+var CCB_KEYFRAME_EASING_BACK_INOUT = 13;
+
+var CCB_POSITIONTYPE_RELATIVE_BOTTOM_LEFT = 0;
+var CCB_POSITIONTYPE_RELATIVE_TOP_LEFT = 1;
+var CCB_POSITIONTYPE_RELATIVE_TOP_RIGHT = 2;
+var CCB_POSITIONTYPE_RELATIVE_BOTTOM_RIGHT = 3;
+var CCB_POSITIONTYPE_PERCENT = 4;
+var CCB_POSITIONTYPE_MULTIPLY_RESOLUTION = 5;
+
+var CCB_SIZETYPE_ABSOLUTE = 0;
+var CCB_SIZETYPE_PERCENT = 1;
+var CCB_SIZETYPE_RELATIVE_CONTAINER = 2;
+var CCB_SIZETYPE_HORIZONTAL_PERCENT = 3;
+var CCB_SIZETYPE_VERTICAL_PERCENT = 4;
+var CCB_SIZETYPE_MULTIPLY_RESOLUTION = 5;
+
+var CCB_SCALETYPE_ABSOLUTE = 0;
+var CCB_SCALETYPE_MULTIPLY_RESOLUTION = 1;
+
+/**
+ * Parse CCBI file which is generated by CocosBuilder
+ */
+cc.BuilderReader = cc.Class.extend({
+ _jsControlled: false,
+ _data: null,
+ _ccbRootPath: "",
+
+ _bytes: 0,
+ _currentByte: 0,
+ _currentBit: 0,
+
+ _stringCache: null,
+ _loadedSpriteSheets: null,
+
+ _owner: null,
+ _animationManager: null,
+ _animationManagers: null,
+ _animatedProps: null,
+
+ _ccNodeLoaderLibrary: null,
+ _ccNodeLoaderListener: null,
+ _ccbMemberVariableAssigner: null,
+ _ccbSelectorResolver: null,
+
+ _ownerOutletNames: null,
+ _ownerOutletNodes: null,
+ _nodesWithAnimationManagers: null,
+ _animationManagerForNodes: null,
+
+ _ownerCallbackNames: null,
+ _ownerCallbackNodes: null,
+ _ownerCallbackEvents: null,
+
+ _readNodeGraphFromData: false,
+
+ ctor: function (ccNodeLoaderLibrary, ccbMemberVariableAssigner, ccbSelectorResolver, ccNodeLoaderListener) {
+ this._stringCache = [];
+ this._loadedSpriteSheets = [];
+ this._currentBit = -1;
+ this._currentByte = -1;
+
+ if (arguments.length !== 0) {
+ if (ccNodeLoaderLibrary instanceof cc.BuilderReader) {
+ var ccbReader = ccNodeLoaderLibrary;
+
+ /* Borrow data from the 'parent' CCBReader. */
+ this._loadedSpriteSheets = ccbReader._loadedSpriteSheets;
+ this._ccNodeLoaderLibrary = ccbReader._ccNodeLoaderLibrary;
+
+ this._ccbMemberVariableAssigner = ccbReader._ccbMemberVariableAssigner;
+ this._ccbSelectorResolver = ccbReader._ccbSelectorResolver;
+ this._ccNodeLoaderListener = ccbReader._ccNodeLoaderListener;
+
+ this._ownerCallbackNames = ccbReader._ownerCallbackNames;
+ this._ownerCallbackNodes = ccbReader._ownerCallbackNodes;
+ this._ownerCallbackEvents = ccbReader._ownerCallbackEvents;
+ this._ownerOutletNames = ccbReader._ownerOutletNames;
+ this._ownerOutletNodes = ccbReader._ownerOutletNodes;
+ this._ccbRootPath = ccbReader._ccbRootPath;
+ } else {
+ this._ccNodeLoaderLibrary = ccNodeLoaderLibrary;
+ this._ccbMemberVariableAssigner = ccbMemberVariableAssigner;
+ this._ccbSelectorResolver = ccbSelectorResolver;
+ this._ccNodeLoaderListener = ccNodeLoaderListener;
+ }
+ }
+ },
+
+ getCCBRootPath: function () {
+ return this._ccbRootPath;
+ },
+
+ setCCBRootPath: function (rootPath) {
+ this._ccbRootPath = rootPath;
+ },
+
+ initWithData: function (data, owner) {
+ //setup action manager
+ this._animationManager = new cc.BuilderAnimationManager();
+
+ //setup byte array
+ //Array replace to CCData in Javascript
+ this._data = data;
+ this._bytes = data.length;
+ this._currentBit = 0;
+ this._currentByte = 0;
+
+ this._owner = owner;
+
+ //setup resolution scale and container size
+ this._animationManager.setRootContainerSize(cc.director.getWinSize());
+
+ return true;
+ },
+
+ _loadBinarySync: function (url) {
+ var self = this;
+ var req = this.getXMLHttpRequest();
+ var errInfo = "load " + url + " failed!";
+ req.open('GET', url, false);
+ var arrayInfo = null;
+ if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
+ req.setRequestHeader("Accept-Charset", "x-user-defined");
+ req.send(null);
+ if (req.status !== 200) {
+ cc.log(errInfo);
+ return null;
+ }
+
+ var fileContents = cc._convertResponseBodyToText(req["responseBody"]);
+ if (fileContents) {
+ arrayInfo = this._stringConvertToArray(fileContents);
+ this._fileDataCache[url] = arrayInfo;
+ }
+ } else {
+ if (req.overrideMimeType)
+ req.overrideMimeType('text\/plain; charset=x-user-defined');
+ req.send(null);
+ if (req.status !== 200) {
+ cc.log(errInfo);
+ return null;
+ }
+
+ arrayInfo = this._stringConvertToArray(req.responseText);
+ this._fileDataCache[url] = arrayInfo;
+ }
+ return arrayInfo;
+ },
+
+ readNodeGraphFromFile: function (ccbFileName, owner, parentSize, animationManager) {
+ if (parentSize == null) {
+ parentSize = cc.director.getWinSize();
+ } else if (parentSize instanceof cc.BuilderAnimationManager) {
+ animationManager = parentSize;
+ parentSize = cc.director.getWinSize();
+ }
+
+ var data = cc.loader.getRes(ccbFileName);
+ if (!data) {
+ var realUrl = cc.loader.getUrl(ccbFileName);
+ data = cc.loader.loadBinarySync(realUrl);
+ cc.loader.cache[ccbFileName] = data;
+ }
+
+ return this.readNodeGraphFromData(data, owner, parentSize, animationManager);
+ },
+
+ readNodeGraphFromData: function (data, owner, parentSize) {
+ this.initWithData(data, owner);
+ var locAnimationManager = this._animationManager;
+ locAnimationManager.setRootContainerSize(parentSize);
+ locAnimationManager.setOwner(owner);
+
+ this._ownerOutletNames = [];
+ this._ownerOutletNodes = [];
+ this._ownerCallbackNames = [];
+ this._ownerCallbackNodes = [];
+ this._ownerCallbackEvents = [];
+ this._animationManagers = new cc._Dictionary();
+
+ var nodeGraph = this.readFileWithCleanUp(true);
+
+ if (nodeGraph && locAnimationManager.getAutoPlaySequenceId() !== -1) {
+ //auto play animations
+ locAnimationManager.runAnimations(locAnimationManager.getAutoPlaySequenceId(), 0);
+ }
+
+ if (this._jsControlled) {
+ var locNodes = [];
+ var locAnimations = [];
+
+ var locAnimationManagers = this._animationManagers;
+ var getAllKeys = locAnimationManagers.allKeys();
+ for (var i = 0; i < getAllKeys.length; i++) {
+ locNodes.push(getAllKeys[i]);
+ locAnimations.push(locAnimationManagers.objectForKey(getAllKeys[i]));
+ }
+
+ this._nodesWithAnimationManagers = locNodes;
+ this._animationManagerForNodes = locAnimations;
+ }
+
+ return nodeGraph;
+ },
+
+ createSceneWithNodeGraphFromFile: function (ccbFileName, owner, parentSize, animationManager) {
+ var node = this.readNodeGraphFromFile(ccbFileName, owner, parentSize, animationManager);
+ var scene = new cc.Scene();
+ scene.addChild(node);
+ return scene;
+ },
+
+ getCCBMemberVariableAssigner: function () {
+ return this._ccbMemberVariableAssigner;
+ },
+
+ getCCBSelectorResolver: function () {
+ return this._ccbSelectorResolver;
+ },
+
+ getAnimationManager: function () {
+ return this._animationManager;
+ },
+
+ setAnimationManager: function (animationManager) {
+ this._animationManager = animationManager;
+ },
+
+ getAnimatedProperties: function () {
+ return this._animatedProps;
+ },
+
+ getLoadedSpriteSheet: function () {
+ return this._loadedSpriteSheets;
+ },
+
+ getOwner: function () {
+ return this._owner;
+ },
+
+ readInt: function (signed) {
+ var numBits = 0;
+ var data = this._data[this._currentByte];
+ var bit = !!(data & (1 << this._currentBit++));
+ while (!bit) {
+ numBits++;
+ bit = !!(data & (1 << this._currentBit++));
+ if (this._currentBit >= 8) {
+ this._currentBit = 0;
+ this._currentByte++;
+ data = this._data[this._currentByte];
+ if (this._currentByte > this._data.length)
+ throw new Error("out of the data bound");
+ }
+ }
+
+ var current = 0;
+ for (var a = numBits - 1; a >= 0; a--) {
+ bit = !!(data & (1 << this._currentBit++));
+ if (this._currentBit >= 8) {
+ this._currentBit = 0;
+ this._currentByte++;
+ data = this._data[this._currentByte];
+ if (this._currentByte > this._data.length)
+ throw new Error("out of the data bound");
+ }
+ if (bit) {
+ current |= 1 << a;
+ }
+ }
+ current |= 1 << numBits;
+
+ var num;
+ if (signed) {
+ var s = current % 2;
+ if (s) {
+ num = 0 | (current / 2);
+ } else {
+ num = 0 | (-current / 2);
+ }
+ } else {
+ num = current - 1;
+ }
+
+ if (this._currentBit) {
+ this._currentBit = 0;
+ this._currentByte++;
+ }
+
+ return num;
+ },
+
+ readByte: function () {
+ var byteValue = this._data[this._currentByte];
+ this._currentByte++;
+ return byteValue;
+ },
+
+ readBool: function () {
+ return !!this._data[this._currentByte++];
+ },
+
+ readFloat: function () {
+ var type = this._data[this._currentByte++];
+
+ switch (type) {
+ case CCB_FLOAT0:
+ return 0;
+ case CCB_FLOAT1:
+ return 1;
+ case CCB_FLOAT_MINUS1:
+ return -1;
+ case CCB_FLOAT05:
+ return 0.5;
+ case CCB_FLOAT_INTEGER:
+ return this.readInt(true);
+ default:
+ /* using a memcpy since the compiler isn't
+ * doing the float ptr math correctly on device.
+ */
+ var pF = this._decodeFloat(23, 8); //this._bytes + this._currentByte;
+ //this._currentByte += 4;
+ return pF;
+ }
+ },
+
+ _decodeFloat: function (precisionBits, exponentBits) {
+ var length = precisionBits + exponentBits + 1;
+ var size = length >> 3;
+ if (this._currentByte + size >= this._data.length) {
+ throw new Error("Index out of bound");
+ }
+
+ var bias = Math.pow(2, exponentBits - 1) - 1;
+ var signal = this._readBitsOnly(precisionBits + exponentBits, 1, size);
+ var exponent = this._readBitsOnly(precisionBits, exponentBits, size);
+ var significand = 0;
+ var divisor = 2;
+ var curByte = 0; //length + (-precisionBits >> 3) - 1;
+ do {
+ var byteValue = this._data[this._currentByte + size - (++curByte) - 1];
+ var startBit = precisionBits % 8 || 8;
+ var mask = 1 << startBit;
+ while (mask >>= 1) {
+ if (byteValue & mask) {
+ significand += 1 / divisor;
+ }
+ divisor *= 2;
+ }
+ } while (precisionBits -= startBit);
+
+ this._currentByte += size;
+
+ return exponent === (bias << 1) + 1 ? significand ? NaN : signal ? -Infinity : +Infinity
+ : (1 + signal * -2) * (exponent || significand ? !exponent ? Math.pow(2, -bias + 1) * significand
+ : Math.pow(2, exponent - bias) * (1 + significand) : 0);
+ },
+
+ _readBitsOnly: function (start, length, size) {
+ var offsetLeft = (start + length) % 8;
+ var offsetRight = start % 8;
+ var curByte = size - (start >> 3) - 1;
+ var lastByte = size + (-(start + length) >> 3);
+ var diff = curByte - lastByte;
+
+ var sum = (this._data[this._currentByte + size - curByte - 1] >> offsetRight) & ((1 << (diff ? 8 - offsetRight : length)) - 1);
+
+ if (diff && offsetLeft) {
+ sum += (this._data[this._currentByte + size - lastByte - 1] & ((1 << offsetLeft) - 1)) << (diff-- << 3) - offsetRight;
+ lastByte++;
+ }
+
+ while (diff) {
+ sum += this._shl(this._data[this._currentByte + size - lastByte - 1], (diff-- << 3) - offsetRight);
+ lastByte++;
+ }
+
+ return sum;
+ },
+
+ _shl: function (a, b) {
+ for (++b; --b; a = ((a %= 0x7fffffff + 1) & 0x40000000) === 0x40000000 ? a * 2 : (a - 0x40000000) * 2 + 0x7fffffff + 1);
+ return a;
+ },
+
+ readCachedString: function () {
+ return this._stringCache[this.readInt(false)];
+ },
+
+ isJSControlled: function () {
+ return this._jsControlled;
+ },
+
+ getOwnerCallbackNames: function () {
+ return this._ownerCallbackNames;
+ },
+
+ getOwnerCallbackNodes: function () {
+ return this._ownerCallbackNodes;
+ },
+
+ getOwnerCallbackControlEvents: function () {
+ return this._ownerCallbackEvents;
+ },
+
+ getOwnerOutletNames: function () {
+ return this._ownerOutletNames;
+ },
+
+ getOwnerOutletNodes: function () {
+ return this._ownerOutletNodes;
+ },
+
+ getNodesWithAnimationManagers: function () {
+ return this._nodesWithAnimationManagers;
+ },
+
+ getAnimationManagersForNodes: function () {
+ return this._animationManagerForNodes;
+ },
+
+ getAnimationManagers: function () {
+ return this._animationManagers;
+ },
+
+ setAnimationManagers: function (animationManagers) {
+ this._animationManagers = animationManagers;
+ },
+
+ addOwnerCallbackName: function (name) {
+ this._ownerCallbackNames.push(name);
+ },
+
+ addOwnerCallbackNode: function (node) {
+ this._ownerCallbackNodes.push(node);
+ },
+
+ addOwnerCallbackControlEvents: function (event) {
+ this._ownerCallbackEvents.push(event);
+ },
+
+ addDocumentCallbackName: function (name) {
+ this._animationManager.addDocumentCallbackName(name);
+ },
+
+ addDocumentCallbackNode: function (node) {
+ this._animationManager.addDocumentCallbackNode(node);
+ },
+
+ addDocumentCallbackControlEvents: function (controlEvents) {
+ this._animationManager.addDocumentCallbackControlEvents(controlEvents);
+ },
+
+ readFileWithCleanUp: function (cleanUp) {
+ if (!this._readHeader())
+ return null;
+ if (!this._readStringCache())
+ return null;
+ if (!this._readSequences())
+ return null;
+
+ var node = this._readNodeGraph();
+ this._animationManagers.setObject(this._animationManager, node);
+
+ if (cleanUp)
+ this._cleanUpNodeGraph(node);
+ return node;
+ },
+
+ addOwnerOutletName: function (name) {
+ this._ownerOutletNames.push(name);
+ },
+
+ addOwnerOutletNode: function (node) {
+ if (node == null)
+ return;
+
+ this._ownerOutletNodes.push(node);
+ },
+
+ _cleanUpNodeGraph: function (node) {
+ node.userObject = null;
+ var getChildren = node.getChildren();
+ for (var i = 0, len = getChildren.length; i < len; i++) {
+ this._cleanUpNodeGraph(getChildren[i]);
+ }
+ },
+
+ _readCallbackKeyframesForSeq: function (seq) {
+ var numKeyframes = this.readInt(false);
+
+ if (!numKeyframes)
+ return true;
+
+ var channel = new cc.BuilderSequenceProperty();
+ var locJsControlled = this._jsControlled, locAnimationManager = this._animationManager, locKeyframes = channel.getKeyframes();
+ for (var i = 0; i < numKeyframes; i++) {
+ var time = this.readFloat();
+ var callbackName = this.readCachedString();
+ var callbackType = this.readInt(false);
+
+ var value = [callbackName, callbackType];
+
+ var keyframe = new cc.BuilderKeyframe();
+ keyframe.setTime(time);
+ keyframe.setValue(value);
+
+ if (locJsControlled)
+ locAnimationManager.getKeyframeCallbacks().push(callbackType + ":" + callbackName);
+
+ locKeyframes.push(keyframe);
+ }
+
+ // Assign to sequence
+ seq.setCallbackChannel(channel);
+
+ return true;
+ },
+
+ _readSoundKeyframesForSeq: function (seq) {
+ var numKeyframes = this.readInt(false);
+
+ if (!numKeyframes)
+ return true;
+
+ var channel = new cc.BuilderSequenceProperty();
+ var locKeyframes = channel.getKeyframes();
+ for (var i = 0; i < numKeyframes; i++) {
+ var time = this.readFloat();
+ var soundFile = this.readCachedString();
+ var pitch = this.readFloat();
+ var pan = this.readFloat();
+ var gain = this.readFloat();
+
+ var value = [soundFile, pitch, pan, gain];
+ var keyframe = new cc.BuilderKeyframe();
+ keyframe.setTime(time);
+ keyframe.setValue(value);
+
+ locKeyframes.push(keyframe);
+ }
+
+ // Assign to sequence
+ seq.setSoundChannel(channel);
+ return true;
+ },
+ _readSequences: function () {
+ var sequences = this._animationManager.getSequences();
+ var numSeqs = this.readInt(false);
+ for (var i = 0; i < numSeqs; i++) {
+ var seq = new cc.BuilderSequence();
+ seq.setDuration(this.readFloat());
+ seq.setName(this.readCachedString());
+ seq.setSequenceId(this.readInt(false));
+ seq.setChainedSequenceId(this.readInt(true));
+
+ if (!this._readCallbackKeyframesForSeq(seq))
+ return false;
+ if (!this._readSoundKeyframesForSeq(seq))
+ return false;
+
+ sequences.push(seq);
+ }
+ this._animationManager.setAutoPlaySequenceId(this.readInt(true));
+ return true;
+ },
+
+ readKeyframe: function (type) {
+ var keyframe = new cc.BuilderKeyframe();
+ keyframe.setTime(this.readFloat());
+ var easingType = this.readInt(false);
+ var easingOpt = 0;
+ var value = null;
+
+ if (easingType === CCB_KEYFRAME_EASING_CUBIC_IN
+ || easingType === CCB_KEYFRAME_EASING_CUBIC_OUT
+ || easingType === CCB_KEYFRAME_EASING_CUBIC_INOUT
+ || easingType === CCB_KEYFRAME_EASING_ELASTIC_IN
+ || easingType === CCB_KEYFRAME_EASING_ELASTIC_OUT
+ || easingType === CCB_KEYFRAME_EASING_ELASTIC_INOUT) {
+ easingOpt = this.readFloat();
+ }
+
+ keyframe.setEasingType(easingType);
+ keyframe.setEasingOpt(easingOpt);
+
+ if (type === CCB_PROPTYPE_CHECK) {
+ value = !!this._data[this._currentByte++];
+ } else if (type === CCB_PROPTYPE_BYTE) {
+ value = this._data[this._currentByte++];
+ } else if (type === CCB_PROPTYPE_COLOR3) {
+ value = cc.color(this._data[this._currentByte++], this._data[this._currentByte++], this._data[this._currentByte++]);
+ } else if (type === CCB_PROPTYPE_FLOATXY) {
+ value = [this.readFloat(), this.readFloat()];
+ } else if (type === CCB_PROPTYPE_DEGREES) {
+ value = this.readFloat();
+ } else if (type === CCB_PROPTYPE_SCALELOCK || type === CCB_PROPTYPE_POSITION || type === CCB_PROPTYPE_FLOATXY) {
+ value = [this.readFloat(), this.readFloat()];
+ } else if (type === CCB_PROPTYPE_SPRITEFRAME) {
+ var spriteSheet = this.readCachedString();
+ var spriteFile = this.readCachedString();
+
+ if (spriteSheet === "") {
+ spriteFile = this._ccbRootPath + spriteFile;
+ var texture = cc.textureCache.addImage(spriteFile);
+ var locContentSize = texture.getContentSize();
+ var bounds = cc.rect(0, 0, locContentSize.width, locContentSize.height);
+ value = new cc.SpriteFrame(texture, bounds);
+ } else {
+ spriteSheet = this._ccbRootPath + spriteSheet;
+ var frameCache = cc.spriteFrameCache;
+ // Load the sprite sheet only if it is not loaded
+ if (this._loadedSpriteSheets.indexOf(spriteSheet) === -1) {
+ frameCache.addSpriteFrames(spriteSheet);
+ this._loadedSpriteSheets.push(spriteSheet);
+ }
+ value = frameCache.getSpriteFrame(spriteFile);
+ }
+ }
+ keyframe.setValue(value);
+ return keyframe;
+ },
+
+ _readHeader: function () {
+ /* If no bytes loaded, don't crash about it. */
+ if (!this._data)
+ return false;
+
+ /* Read magic bytes */
+ var magicBytes = this._readStringFromBytes(this._currentByte, 4, true);
+ this._currentByte += 4;
+
+ if (magicBytes !== 'ccbi') {
+ return false;
+ }
+
+ /* Read version. */
+ var version = this.readInt(false);
+ if (version !== CCB_VERSION) {
+ cc.log("WARNING! Incompatible ccbi file version (file: " + version + " reader: " + CCB_VERSION + ")");
+ return false;
+ }
+
+ this._jsControlled = !!this._data[this._currentByte++];
+ this._animationManager._jsControlled = this._jsControlled;
+ // no need to set if it is "jscontrolled". It is obvious.
+ return true;
+ },
+
+ _readStringFromBytes: function (startIndex, strLen, reverse) {
+ reverse = reverse || false;
+ var strValue = "";
+ var i, locData = this._data;
+ if (reverse) {
+ for (i = strLen - 1; i >= 0; i--)
+ strValue += String.fromCharCode(locData[startIndex + i]);
+ } else {
+ for (i = 0; i < strLen; i++)
+ strValue += String.fromCharCode(locData[startIndex + i]);
+ }
+ return strValue;
+ },
+
+ _readStringCache: function () {
+ var numStrings = this.readInt(false);
+ for (var i = 0; i < numStrings; i++)
+ this._readStringCacheEntry();
+ return true;
+ },
+
+ _readStringCacheEntry: function () {
+ var b0 = this._data[this._currentByte++];
+ var b1 = this._data[this._currentByte++];
+
+ var numBytes = b0 << 8 | b1;
+
+ var str = "", locData = this._data, locCurrentByte = this._currentByte;
+ for (var i = 0; i < numBytes; i++) {
+ var hexChar = locData[locCurrentByte + i].toString("16").toUpperCase();
+ hexChar = hexChar.length > 1 ? hexChar : "0" + hexChar;
+ str += "%" + hexChar;
+ }
+ str = decodeURIComponent(str);
+
+ this._currentByte += numBytes;
+ this._stringCache.push(str);
+ },
+
+ _readNodeGraph: function (parent) {
+ /* Read class name. */
+ var className = this.readCachedString();
+
+ var jsControlledName, locJsControlled = this._jsControlled, locActionManager = this._animationManager;
+ if (locJsControlled)
+ jsControlledName = this.readCachedString();
+
+ var memberVarAssignmentType = this.readInt(false);
+ var memberVarAssignmentName;
+ if (memberVarAssignmentType !== CCB_TARGETTYPE_NONE) {
+ memberVarAssignmentName = this.readCachedString();
+ }
+
+ var ccNodeLoader = this._ccNodeLoaderLibrary.getCCNodeLoader(className);
+ if (!ccNodeLoader) {
+ ccNodeLoader = this._ccNodeLoaderLibrary.getCCNodeLoader("CCNode");
+ //cc.log("no corresponding node loader for" + className);
+ //return null;
+ }
+ var node = ccNodeLoader.loadCCNode(parent, this);
+
+ //set root node
+ if (!locActionManager.getRootNode())
+ locActionManager.setRootNode(node);
+
+ if (locJsControlled && node === locActionManager.getRootNode()) {
+ locActionManager.setDocumentControllerName(jsControlledName);
+ }
+
+ //read animated properties
+ var seqs = new cc._Dictionary();
+ this._animatedProps = [];
+
+ var i, locAnimatedProps = this._animatedProps;
+ var numSequence = this.readInt(false);
+ for (i = 0; i < numSequence; ++i) {
+ var seqId = this.readInt(false);
+ var seqNodeProps = new cc._Dictionary();
+
+ var numProps = this.readInt(false);
+
+ for (var j = 0; j < numProps; ++j) {
+ var seqProp = new cc.BuilderSequenceProperty();
+ seqProp.setName(this.readCachedString());
+ seqProp.setType(this.readInt(false));
+
+ locAnimatedProps.push(seqProp.getName());
+ var numKeyframes = this.readInt(false);
+ var locKeyframes = seqProp.getKeyframes();
+ for (var k = 0; k < numKeyframes; ++k) {
+ var keyFrame = this.readKeyframe(seqProp.getType());
+ locKeyframes.push(keyFrame);
+ }
+ seqNodeProps.setObject(seqProp, seqProp.getName());
+ }
+ seqs.setObject(seqNodeProps, seqId);
+ }
+
+ if (seqs.count() > 0)
+ locActionManager.addNode(node, seqs);
+
+ //read properties
+ ccNodeLoader.parseProperties(node, parent, this);
+
+ //handle sub ccb files(remove middle node)
+ var isCCBFileNode = !!node.ccbFileNode;
+ if (isCCBFileNode) {
+ var embeddedNode = node.ccbFileNode;
+ embeddedNode.setPosition(node.getPosition());
+ embeddedNode.setRotation(node.getRotation());
+ embeddedNode.setScaleX(node.getScaleX());
+ embeddedNode.setScaleY(node.getScaleY());
+ embeddedNode.setTag(node.getTag());
+ embeddedNode.setVisible(true);
+ //embeddedNode.ignoreAnchorPointForPosition(node.isIgnoreAnchorPointForPosition());
+
+ locActionManager.moveAnimationsFromNode(node, embeddedNode);
+ node.ccbFileNode = null;
+ node = embeddedNode;
+ }
+ var target = null, locMemberAssigner = null;
+ if (memberVarAssignmentType !== CCB_TARGETTYPE_NONE) {
+ if (!locJsControlled) {
+ if (memberVarAssignmentType === CCB_TARGETTYPE_DOCUMENTROOT) {
+ target = locActionManager.getRootNode();
+ } else if (memberVarAssignmentType === CCB_TARGETTYPE_OWNER) {
+ target = this._owner;
+ }
+
+ if (!target) {
+ var assigned = false;
+
+ if (target.onAssignCCBMemberVariable)
+ assigned = target.onAssignCCBMemberVariable(target, memberVarAssignmentName, node);
+
+ locMemberAssigner = this._ccbMemberVariableAssigner;
+ if (!assigned && locMemberAssigner != null && locMemberAssigner.onAssignCCBMemberVariable) {
+ locMemberAssigner.onAssignCCBMemberVariable(target, memberVarAssignmentName, node);
+ }
+ }
+ } else {
+ if (memberVarAssignmentType === CCB_TARGETTYPE_DOCUMENTROOT) {
+ locActionManager.addDocumentOutletName(memberVarAssignmentName);
+ locActionManager.addDocumentOutletNode(node);
+ } else {
+ this._ownerOutletNames.push(memberVarAssignmentName);
+ this._ownerOutletNodes.push(node);
+ }
+ }
+ }
+
+ // Assign custom properties.
+ if (ccNodeLoader.getCustomProperties().length > 0) {
+ var customAssigned = false;
+ if (!locJsControlled) {
+ target = node;
+ if (target != null && target.onAssignCCBCustomProperty != null) {
+ var customProperties = ccNodeLoader.getCustomProperties();
+ var customPropKeys = customProperties.allKeys();
+ for (i = 0; i < customPropKeys.length; i++) {
+ var customPropValue = customProperties.objectForKey(customPropKeys[i]);
+ customAssigned = target.onAssignCCBCustomProperty(target, customPropKeys[i], customPropValue);
+ locMemberAssigner = this._ccbMemberVariableAssigner;
+ if (!customAssigned && (locMemberAssigner != null) && (locMemberAssigner.onAssignCCBCustomProperty != null))
+ customAssigned = locMemberAssigner.onAssignCCBCustomProperty(target, customPropKeys[i], customPropValue);
+ }
+ }
+ }
+ }
+
+ this._animatedProps = null;
+
+ /* Read and add children. */
+ var numChildren = this.readInt(false);
+ for (i = 0; i < numChildren; i++) {
+ var child = this._readNodeGraph(node);
+ node.addChild(child);
+ }
+
+ // FIX ISSUE #1860: "onNodeLoaded will be called twice if ccb was added as a CCBFile".
+ // If it's a sub-ccb node, skip notification to CCNodeLoaderListener since it will be
+ // notified at LINE #734: CCNode * child = this->readNodeGraph(node);
+ if (!isCCBFileNode) {
+ // Call onNodeLoaded
+ if (node != null && node.onNodeLoaded)
+ node.onNodeLoaded(node, ccNodeLoader);
+ else if (this._ccNodeLoaderListener != null)
+ this._ccNodeLoaderListener.onNodeLoaded(node, ccNodeLoader);
+ }
+
+ return node;
+ },
+
+ _readUTF8: function () {
+ }
+});
+
+cc.BuilderReader._ccbResolutionScale = 1;
+cc.BuilderReader.setResolutionScale = function (scale) {
+ cc.BuilderReader._ccbResolutionScale = scale;
+};
+
+cc.BuilderReader.getResolutionScale = function () {
+ return cc.BuilderReader._ccbResolutionScale;
+};
+
+cc.BuilderReader.loadAsScene = function (ccbFilePath, owner, parentSize, ccbRootPath) {
+ ccbRootPath = ccbRootPath || cc.BuilderReader.getResourcePath();
+
+ var getNode = cc.BuilderReader.load(ccbFilePath, owner, parentSize, ccbRootPath);
+
+ var scene = new cc.Scene();
+ scene.addChild(getNode);
+ return scene;
+};
+
+cc.BuilderReader._controllerClassCache = {};
+cc.BuilderReader.registerController = function (controllerName, controller) {
+ cc.BuilderReader._controllerClassCache[controllerName] = cc.Class.extend(controller);
+};
+cc.BuilderReader.load = function (ccbFilePath, owner, parentSize, ccbRootPath) {
+ ccbRootPath = ccbRootPath || cc.BuilderReader.getResourcePath();
+ var reader = new cc.BuilderReader(cc.NodeLoaderLibrary.newDefaultCCNodeLoaderLibrary());
+ reader.setCCBRootPath(ccbRootPath);
+ if ((ccbFilePath.length < 5) || (ccbFilePath.toLowerCase().lastIndexOf(".ccbi") !== ccbFilePath.length - 5))
+ ccbFilePath = ccbFilePath + ".ccbi";
+
+ var node = reader.readNodeGraphFromFile(ccbFilePath, owner, parentSize);
+ var i;
+ var callbackName, callbackNode, callbackControlEvents, outletName, outletNode;
+ // Assign owner callbacks & member variables
+ if (owner) {
+ // Callbacks
+ var ownerCallbackNames = reader.getOwnerCallbackNames();
+ var ownerCallbackNodes = reader.getOwnerCallbackNodes();
+ var ownerCallbackControlEvents = reader.getOwnerCallbackControlEvents();
+ for (i = 0; i < ownerCallbackNames.length; i++) {
+ callbackName = ownerCallbackNames[i];
+ callbackNode = ownerCallbackNodes[i];
+ callbackControlEvents = ownerCallbackControlEvents[i];
+ if (callbackNode instanceof cc.ControlButton)
+ callbackNode.addTargetWithActionForControlEvents(owner, owner[callbackName], callbackControlEvents); //register all type of events
+ else
+ callbackNode.setCallback(owner[callbackName], owner);
+ }
+
+ // Variables
+ var ownerOutletNames = reader.getOwnerOutletNames();
+ var ownerOutletNodes = reader.getOwnerOutletNodes();
+ for (i = 0; i < ownerOutletNames.length; i++) {
+ outletName = ownerOutletNames[i];
+ outletNode = ownerOutletNodes[i];
+ owner[outletName] = outletNode;
+ }
+ }
+
+ var nodesWithAnimationManagers = reader.getNodesWithAnimationManagers();
+ var animationManagersForNodes = reader.getAnimationManagersForNodes();
+ if (!nodesWithAnimationManagers || !animationManagersForNodes)
+ return node;
+
+ var controllerClassCache = cc.BuilderReader._controllerClassCache;
+ // Attach animation managers to nodes and assign root node callbacks and member variables
+ for (i = 0; i < nodesWithAnimationManagers.length; i++) {
+ var innerNode = nodesWithAnimationManagers[i];
+ var animationManager = animationManagersForNodes[i];
+
+ var j;
+ innerNode.animationManager = animationManager;
+
+ var controllerName = animationManager.getDocumentControllerName();
+ if (!controllerName) continue;
+
+ // Create a controller
+ var controllerClass = controllerClassCache[controllerName];
+ if (!controllerClass) throw new Error("Can not find controller : " + controllerName);
+ var controller = new controllerClass();
+ controller.controllerName = controllerName;
+
+ innerNode.controller = controller;
+ controller.rootNode = innerNode;
+
+ // Callbacks
+ var documentCallbackNames = animationManager.getDocumentCallbackNames();
+ var documentCallbackNodes = animationManager.getDocumentCallbackNodes();
+ var documentCallbackControlEvents = animationManager.getDocumentCallbackControlEvents();
+ for (j = 0; j < documentCallbackNames.length; j++) {
+ callbackName = documentCallbackNames[j];
+ callbackNode = documentCallbackNodes[j];
+ callbackControlEvents = documentCallbackControlEvents[j];
+ if (callbackNode instanceof cc.ControlButton)
+ callbackNode.addTargetWithActionForControlEvents(controller, controller[callbackName], callbackControlEvents); //register all type of events
+ else
+ callbackNode.setCallback(controller[callbackName], controller);
+ }
+
+ // Variables
+ var documentOutletNames = animationManager.getDocumentOutletNames();
+ var documentOutletNodes = animationManager.getDocumentOutletNodes();
+ for (j = 0; j < documentOutletNames.length; j++) {
+ outletName = documentOutletNames[j];
+ outletNode = documentOutletNodes[j];
+
+ controller[outletName] = outletNode;
+ }
+
+ if (controller.onDidLoadFromCCB && cc.isFunction(controller.onDidLoadFromCCB))
+ controller.onDidLoadFromCCB();
+
+ // Setup timeline callbacks
+ var keyframeCallbacks = animationManager.getKeyframeCallbacks();
+ for (j = 0; j < keyframeCallbacks.length; j++) {
+ var callbackSplit = keyframeCallbacks[j].split(":");
+ var callbackType = callbackSplit[0];
+ var kfCallbackName = callbackSplit[1];
+
+ if (callbackType == 1) { // Document callback
+ animationManager.setCallFunc(cc.callFunc(controller[kfCallbackName], controller), keyframeCallbacks[j]);
+ } else if (callbackType == 2 && owner) {// Owner callback
+ animationManager.setCallFunc(cc.callFunc(owner[kfCallbackName], owner), keyframeCallbacks[j]);
+ }
+ }
+ }
+
+ //auto play animations
+ animationManager.runAnimations(animationManager.getAutoPlaySequenceId(), 0);
+
+ return node;
+};
+
+cc.BuilderReader._resourcePath = "";
+cc.BuilderReader.setResourcePath = function (rootPath) {
+ cc.BuilderReader._resourcePath = rootPath;
+};
+
+cc.BuilderReader.getResourcePath = function () {
+ return cc.BuilderReader._resourcePath;
+};
+
+cc.BuilderReader.lastPathComponent = function (pathStr) {
+ var slashPos = pathStr.lastIndexOf("/");
+ if (slashPos !== -1) {
+ return pathStr.substring(slashPos + 1, pathStr.length - slashPos);
+ }
+ return pathStr;
+};
+
+cc.BuilderReader.deletePathExtension = function (pathStr) {
+ var dotPos = pathStr.lastIndexOf(".");
+ if (dotPos !== -1) {
+ return pathStr.substring(0, dotPos);
+ }
+ return pathStr;
+};
+
+cc.BuilderReader.toLowerCase = function (sourceStr) {
+ return sourceStr.toLowerCase();
+};
+
+cc.BuilderReader.endsWith = function (sourceStr, ending) {
+ if (sourceStr.length >= ending.length)
+ return (sourceStr.lastIndexOf(ending) === 0);
+ else
+ return false;
+};
+
+cc.BuilderReader.concat = function (stringA, stringB) {
+ return stringA + stringB;
+};
+
+cc.loader.register(["ccbi"], cc._binaryLoader);
diff --git a/frameworks/cocos2d-html5/extensions/ccb-reader/CCBReaderUtil.js b/frameworks/cocos2d-html5/extensions/ccb-reader/CCBReaderUtil.js
new file mode 100644
index 0000000..0de9c4f
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccb-reader/CCBReaderUtil.js
@@ -0,0 +1,70 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.NodeLoaderListener = cc.Class.extend({
+ onNodeLoaded: function (node, nodeLoader) {
+ }
+});
+
+cc.BuilderSelectorResolver = cc.Class.extend({
+ onResolveCCBCCMenuItemSelector: function (target, selectorName) {
+ },
+ onResolveCCBCCCallFuncSelector: function (target, selectorName) {
+ },
+ onResolveCCBCCControlSelector: function (target, selectorName) {
+ }
+});
+
+cc.BuilderScriptOwnerProtocol = cc.Class.extend({
+ createNew: function () {
+ }
+});
+
+cc.BuilderMemberVariableAssigner = cc.Class.extend({
+ /**
+ * The callback function of assigning member variable.
+ * @note The member variable must be CCNode or its subclass.
+ * @param {Object} target The custom class
+ * @param {string} memberVariableName The name of the member variable.
+ * @param {cc.Node} node The member variable.
+ * @return {Boolean} Whether the assignment was successful.
+ */
+ onAssignCCBMemberVariable: function (target, memberVariableName, node) {
+ return false;
+ },
+
+ /**
+ * The callback function of assigning custom properties.
+ * @note The member variable must be Integer, Float, Boolean or String.
+ * @param {Object} target The custom class.
+ * @param {string} memberVariableName The name of the member variable.
+ * @param {*} value The value of the property.
+ * @return {Boolean} Whether the assignment was successful.
+ */
+ onAssignCCBCustomProperty: function (target, memberVariableName, value) {
+ return false;
+ }
+});
diff --git a/frameworks/cocos2d-html5/extensions/ccb-reader/CCBRelativePositioning.js b/frameworks/cocos2d-html5/extensions/ccb-reader/CCBRelativePositioning.js
new file mode 100644
index 0000000..ed0d29a
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccb-reader/CCBRelativePositioning.js
@@ -0,0 +1,64 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.getAbsolutePosition = function (x, y, type, containerSize, propName, out) {
+ var absPt = out || cc.p(0, 0);
+ if (type === CCB_POSITIONTYPE_RELATIVE_BOTTOM_LEFT) {
+ absPt.x = x;
+ absPt.y = y;
+ } else if (type === CCB_POSITIONTYPE_RELATIVE_TOP_LEFT) {
+ absPt.x = x;
+ absPt.y = containerSize.height - y;
+ } else if (type === CCB_POSITIONTYPE_RELATIVE_TOP_RIGHT) {
+ absPt.x = containerSize.width - x;
+ absPt.y = containerSize.height - y;
+ } else if (type === CCB_POSITIONTYPE_RELATIVE_BOTTOM_RIGHT) {
+ absPt.x = containerSize.width - x;
+ absPt.y = y;
+ } else if (type === CCB_POSITIONTYPE_PERCENT) {
+ absPt.x = (containerSize.width * x / 100.0);
+ absPt.y = (containerSize.height * y / 100.0);
+ } else if (type === CCB_POSITIONTYPE_MULTIPLY_RESOLUTION) {
+ var resolutionScale = cc.BuilderReader.getResolutionScale();
+ absPt.x = x * resolutionScale;
+ absPt.y = y * resolutionScale;
+ }
+ return absPt;
+};
+
+cc.setRelativeScale = function (node, scaleX, scaleY, type, propName) {
+ if (!node)
+ throw new Error("cc.setRelativeScale(): node should be non-null");
+
+ if (type === CCB_POSITIONTYPE_MULTIPLY_RESOLUTION) {
+ var resolutionScale = cc.BuilderReader.getResolutionScale();
+
+ scaleX *= resolutionScale;
+ scaleY *= resolutionScale;
+ }
+
+ node.setScale(scaleX, scaleY);
+};
diff --git a/frameworks/cocos2d-html5/extensions/ccb-reader/CCBSequence.js b/frameworks/cocos2d-html5/extensions/ccb-reader/CCBSequence.js
new file mode 100644
index 0000000..a1bc0e2
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccb-reader/CCBSequence.js
@@ -0,0 +1,114 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.BuilderSequence = cc.Class.extend({
+ _duration:0,
+ _name:"",
+ _sequenceId:0,
+ _chainedSequenceId:0,
+ _callbackChannel:null,
+ _soundChannel:null,
+
+ ctor:function(){
+ this._name = "";
+ },
+
+ getDuration:function(){
+ return this._duration;
+ },
+ setDuration:function(duration){
+ this._duration = duration;
+ },
+
+ getName:function(){
+ return this._name;
+ },
+ setName:function(name){
+ this._name = name;
+ },
+
+ getSequenceId:function(){
+ return this._sequenceId;
+ },
+ setSequenceId:function(sequenceId){
+ this._sequenceId = sequenceId;
+ },
+
+ getChainedSequenceId:function(){
+ return this._chainedSequenceId;
+ },
+ setChainedSequenceId:function(chainedSequenceId){
+ this._chainedSequenceId = chainedSequenceId;
+ },
+
+ getCallbackChannel:function() {
+ return this._callbackChannel;
+ },
+ setCallbackChannel:function(channel) {
+ this._callbackChannel = channel;
+ },
+
+ getSoundChannel:function() {
+ return this._soundChannel;
+ },
+ setSoundChannel:function(channel) {
+ this._soundChannel = channel;
+ }
+});
+
+cc.BuilderSequenceProperty = cc.Class.extend({
+ _name : null,
+ _type:0,
+ _keyFrames:null,
+
+ ctor:function(){
+ this.init();
+ },
+
+ init:function(){
+ this._keyFrames = [];
+ this._name = "";
+ },
+
+ getName:function(){
+ return this._name;
+ },
+
+ setName :function(name){
+ this._name = name;
+ },
+
+ getType:function(){
+ return this._type;
+ },
+ setType :function(type){
+ this._type = type;
+ },
+
+ getKeyframes:function(){
+ return this._keyFrames;
+ }
+});
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/ccb-reader/CCBValue.js b/frameworks/cocos2d-html5/extensions/ccb-reader/CCBValue.js
new file mode 100644
index 0000000..dee4c7b
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccb-reader/CCBValue.js
@@ -0,0 +1,60 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.INT_VALUE = 0;
+
+cc.FLOAT_VALUE = 1;
+
+cc.POINTER_VALUE = 2;
+
+cc.BOOL_VALUE = 3;
+
+cc.UNSIGNEDCHAR_VALUE = 4;
+
+cc.BuilderValue = cc.Class.extend({
+ _value: null,
+ _type: 0,
+
+ getIntValue: function () {
+ },
+ getFloatValue: function () {
+ },
+ getBoolValue: function () {
+ },
+ getByteValue: function () {
+ },
+ getPointer: function () {
+ },
+
+ getValue: function () {
+ return this._value;
+ }
+});
+
+cc.BuilderValue.create = function (value) {
+ return new cc.BuilderValue();
+};
+
diff --git a/frameworks/cocos2d-html5/extensions/ccb-reader/CCControlLoader.js b/frameworks/cocos2d-html5/extensions/ccb-reader/CCControlLoader.js
new file mode 100644
index 0000000..3b1a5d6
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccb-reader/CCControlLoader.js
@@ -0,0 +1,320 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+var PROPERTY_CCBFILE = "ccbFile";
+
+cc.BuilderFileLoader = cc.NodeLoader.extend({
+ _createCCNode: function (parent, ccbReader) {
+ var node = new cc.Node();
+ node.ccbFileNode = null;
+ return node;
+ },
+ onHandlePropTypeCCBFile: function (node, parent, propertyName, ccbFileNode, ccbReader) {
+ if (propertyName === PROPERTY_CCBFILE) {
+ node.ccbFileNode = ccbFileNode;
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeCCBFile.call(this, node, parent, propertyName, ccbFileNode, ccbReader);
+ }
+ }
+});
+
+cc.BuilderFileLoader.loader = function () {
+ return new cc.BuilderFileLoader();
+};
+
+var PROPERTY_ENABLED = "enabled";
+var PROPERTY_SELECTED = "selected";
+var PROPERTY_CCCONTROL = "ccControl";
+
+cc.ControlLoader = cc.NodeLoader.extend({
+ _createCCNode: function (parent, ccbReander) {
+ },
+ onHandlePropTypeBlockCCControl: function (node, parent, propertyName, blockCCControlData, ccbReader) {
+ if (propertyName === PROPERTY_CCCONTROL) {
+ node.addTargetWithActionForControlEvents(blockCCControlData.target, blockCCControlData.selCCControlHandler, blockCCControlData.controlEvents);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeBlockCCControl.call(this, node, parent, propertyName, blockCCControlData, ccbReader);
+ }
+ },
+ onHandlePropTypeCheck: function (node, parent, propertyName, check, ccbReader) {
+ if (propertyName === PROPERTY_ENABLED) {
+ node.setEnabled(check);
+ } else if (propertyName === PROPERTY_SELECTED) {
+ node.setSelected(check);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeCheck.call(this, node, parent, propertyName, check, ccbReader);
+ }
+ }
+});
+
+var PROPERTY_ZOOMONTOUCHDOWN = "zoomOnTouchDown";
+var PROPERTY_TITLE_NORMAL = "title|1";
+var PROPERTY_TITLE_HIGHLIGHTED = "title|2";
+var PROPERTY_TITLE_DISABLED = "title|3";
+var PROPERTY_TITLECOLOR_NORMAL = "titleColor|1";
+var PROPERTY_TITLECOLOR_HIGHLIGHTED = "titleColor|2";
+var PROPERTY_TITLECOLOR_DISABLED = "titleColor|3";
+var PROPERTY_TITLETTF_NORMAL = "titleTTF|1";
+var PROPERTY_TITLETTF_HIGHLIGHTED = "titleTTF|2";
+var PROPERTY_TITLETTF_DISABLED = "titleTTF|3";
+var PROPERTY_TITLETTFSIZE_NORMAL = "titleTTFSize|1";
+var PROPERTY_TITLETTFSIZE_HIGHLIGHTED = "titleTTFSize|2";
+var PROPERTY_TITLETTFSIZE_DISABLED = "titleTTFSize|4";
+var PROPERTY_LABELANCHORPOINT = "labelAnchorPoint";
+var PROPERTY_PREFEREDSIZE = "preferedSize"; // TODO Should be = "preferredSize". This is a typo in cocos2d-iphone, cocos2d-x and CocosBuilder!
+var PROPERTY_BACKGROUNDSPRITEFRAME_NORMAL = "backgroundSpriteFrame|1";
+var PROPERTY_BACKGROUNDSPRITEFRAME_HIGHLIGHTED = "backgroundSpriteFrame|2";
+var PROPERTY_BACKGROUNDSPRITEFRAME_DISABLED = "backgroundSpriteFrame|3";
+
+cc.ControlButtonLoader = cc.ControlLoader.extend({
+ _createCCNode: function (parent, ccbReader) {
+ return new cc.ControlButton();
+ },
+
+ onHandlePropTypeCheck: function (node, parent, propertyName, check, ccbReader) {
+ if (propertyName === PROPERTY_ZOOMONTOUCHDOWN) {
+ node.zoomOnTouchDown = check;
+ } else {
+ cc.ControlLoader.prototype.onHandlePropTypeCheck.call(this, node, parent, propertyName, check, ccbReader);
+ }
+ },
+ onHandlePropTypeString: function (node, parent, propertyName, stringValue, ccbReader) {
+ if (propertyName === PROPERTY_TITLE_NORMAL) {
+ node.setTitleForState(stringValue, cc.CONTROL_STATE_NORMAL);
+ } else if (propertyName === PROPERTY_TITLE_HIGHLIGHTED) {
+ node.setTitleForState(stringValue, cc.CONTROL_STATE_HIGHLIGHTED);
+ } else if (propertyName === PROPERTY_TITLE_DISABLED) {
+ node.setTitleForState(stringValue, cc.CONTROL_STATE_DISABLED);
+ } else {
+ cc.ControlLoader.prototype.onHandlePropTypeString.call(this, node, parent, propertyName, stringValue, ccbReader);
+ }
+ },
+ onHandlePropTypeFontTTF: function (node, parent, propertyName, fontTTF, ccbReader) {
+ if (propertyName === PROPERTY_TITLETTF_NORMAL) {
+ node.setTitleTTFForState(fontTTF, cc.CONTROL_STATE_NORMAL);
+ } else if (propertyName === PROPERTY_TITLETTF_HIGHLIGHTED) {
+ node.setTitleTTFForState(fontTTF, cc.CONTROL_STATE_HIGHLIGHTED);
+ } else if (propertyName === PROPERTY_TITLETTF_DISABLED) {
+ node.setTitleTTFForState(fontTTF, cc.CONTROL_STATE_DISABLED);
+ } else {
+ cc.ControlLoader.prototype.onHandlePropTypeFontTTF.call(this, node, parent, propertyName, fontTTF, ccbReader);
+ }
+ },
+ onHandlePropTypeFloatScale: function (node, parent, propertyName, floatScale, ccbReader) {
+ if (propertyName === PROPERTY_TITLETTFSIZE_NORMAL) {
+ node.setTitleTTFSizeForState(floatScale, cc.CONTROL_STATE_NORMAL);
+ } else if (propertyName === PROPERTY_TITLETTFSIZE_HIGHLIGHTED) {
+ node.setTitleTTFSizeForState(floatScale, cc.CONTROL_STATE_HIGHLIGHTED);
+ } else if (propertyName === PROPERTY_TITLETTFSIZE_DISABLED) {
+ node.setTitleTTFSizeForState(floatScale, cc.CONTROL_STATE_DISABLED);
+ } else {
+ cc.ControlLoader.prototype.onHandlePropTypeFloatScale.call(this, node, parent, propertyName, floatScale, ccbReader);
+ }
+ },
+ onHandlePropTypePoint: function (node, parent, propertyName, point, ccbReader) {
+ if (propertyName === PROPERTY_LABELANCHORPOINT) {
+ node.setLabelAnchorPoint(point);
+ } else {
+ cc.ControlLoader.prototype.onHandlePropTypePoint.call(this, node, parent, propertyName, point, ccbReader);
+ }
+ },
+ onHandlePropTypeSize: function (node, parent, propertyName, size, ccbReader) {
+ if (propertyName === PROPERTY_PREFEREDSIZE) {
+ node.setPreferredSize(size);
+ } else {
+ cc.ControlLoader.prototype.onHandlePropTypeSize.call(this, node, parent, propertyName, size, ccbReader);
+ }
+ },
+ onHandlePropTypeSpriteFrame: function (node, parent, propertyName, spriteFrame, ccbReader) {
+ if (propertyName === PROPERTY_BACKGROUNDSPRITEFRAME_NORMAL) {
+ if (spriteFrame != null) {
+ node.setBackgroundSpriteFrameForState(spriteFrame, cc.CONTROL_STATE_NORMAL);
+ }
+ } else if (propertyName === PROPERTY_BACKGROUNDSPRITEFRAME_HIGHLIGHTED) {
+ if (spriteFrame != null) {
+ node.setBackgroundSpriteFrameForState(spriteFrame, cc.CONTROL_STATE_HIGHLIGHTED);
+ }
+ } else if (propertyName === PROPERTY_BACKGROUNDSPRITEFRAME_DISABLED) {
+ if (spriteFrame != null) {
+ node.setBackgroundSpriteFrameForState(spriteFrame, cc.CONTROL_STATE_DISABLED);
+ }
+ } else {
+ cc.ControlLoader.prototype.onHandlePropTypeSpriteFrame.call(this, node, parent, propertyName, spriteFrame, ccbReader);
+ }
+ },
+ onHandlePropTypeColor3: function (node, parent, propertyName, ccColor3B, ccbReader) {
+ if (propertyName === PROPERTY_TITLECOLOR_NORMAL) {
+ node.setTitleColorForState(ccColor3B, cc.CONTROL_STATE_NORMAL);
+ } else if (propertyName === PROPERTY_TITLECOLOR_HIGHLIGHTED) {
+ node.setTitleColorForState(ccColor3B, cc.CONTROL_STATE_HIGHLIGHTED);
+ } else if (propertyName === PROPERTY_TITLECOLOR_DISABLED) {
+ node.setTitleColorForState(ccColor3B, cc.CONTROL_STATE_DISABLED);
+ } else {
+ cc.ControlLoader.prototype.onHandlePropTypeColor3.call(this, node, parent, propertyName, ccColor3B, ccbReader);
+ }
+ }
+});
+
+cc.ControlButtonLoader.loader = function () {
+ return new cc.ControlButtonLoader();
+};
+
+var PROPERTY_CONTAINER = "container";
+var PROPERTY_DIRECTION = "direction";
+var PROPERTY_CLIPSTOBOUNDS = "clipsToBounds";
+var PROPERTY_BOUNCES = "bounces";
+var PROPERTY_SCALE = "scale";
+
+cc.ScrollViewLoader = cc.NodeLoader.extend({
+ _createCCNode: function (parent, ccbReader) {
+ return new cc.ScrollView();
+ },
+
+ onHandlePropTypeSize: function (node, parent, propertyName, size, ccbReader) {
+ if (propertyName === PROPERTY_CONTENTSIZE) {
+ node.setViewSize(size);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeSize.call(this, node, parent, propertyName, size, ccbReader);
+ }
+ },
+
+ onHandlePropTypeCCBFile: function (node, parent, propertyName, ccbFileNode, ccbReader) {
+ if (propertyName === PROPERTY_CONTAINER) {
+ node.setContainer(ccbFileNode);
+ node.updateInset();
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeCCBFile.call(this, node, parent, propertyName, ccbFileNode, ccbReader);
+ }
+ },
+ onHandlePropTypeCheck: function (node, parent, propertyName, check, ccbReader) {
+ if (propertyName === PROPERTY_CLIPSTOBOUNDS) {
+ node.setClippingToBounds(check);
+ } else if (propertyName === PROPERTY_BOUNCES) {
+ node.setBounceable(check);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeCheck.call(this, node, parent, propertyName, check, ccbReader);
+ }
+ },
+ onHandlePropTypeFloat: function (node, parent, propertyName, floatValue, ccbReader) {
+ if (propertyName === PROPERTY_SCALE) {
+ node.setScale(floatValue);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeFloat.call(this, node, parent, propertyName, floatValue, ccbReader);
+ }
+ },
+ onHandlePropTypeIntegerLabeled: function (node, parent, propertyName, integerLabeled, ccbReader) {
+ if (propertyName === PROPERTY_DIRECTION) {
+ node.setDirection(integerLabeled);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeIntegerLabeled.call(this, node, parent, propertyName, integerLabeled, ccbReader);
+ }
+ }
+});
+
+cc.ScrollViewLoader.loader = function () {
+ return new cc.ScrollViewLoader();
+};
+
+var PROPERTY_CONTENTSIZE = "contentSize";
+var PROPERTY_SPRITEFRAME = "spriteFrame";
+var PROPERTY_COLOR = "color";
+var PROPERTY_OPACITY = "opacity";
+var PROPERTY_BLENDFUNC = "blendFunc";
+var PROPERTY_INSETLEFT = "insetLeft";
+var PROPERTY_INSETTOP = "insetTop";
+var PROPERTY_INSETRIGHT = "insetRight";
+var PROPERTY_INSETBOTTOM = "insetBottom";
+
+cc.Scale9SpriteLoader = cc.NodeLoader.extend({
+ _createCCNode: function (parent, ccbReader) {
+ var sprite = new cc.Scale9Sprite();
+
+ sprite.setAnchorPoint(0, 0);
+
+ return sprite;
+ },
+
+ onHandlePropTypeColor3: function (node, parent, propertyName, ccColor3B, ccbReader) {
+ if (propertyName === PROPERTY_COLOR) {
+ if (ccColor3B.r !== 255 || ccColor3B.g !== 255 || ccColor3B.b !== 255) {
+ node.setColor(ccColor3B);
+ }
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeColor3.call(this, node, parent, propertyName, ccColor3B, ccbReader);
+ }
+ },
+ onHandlePropTypeByte: function (node, parent, propertyName, byteValue, ccbReader) {
+ if (propertyName === PROPERTY_OPACITY) {
+ node.setOpacity(byteValue);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeByte.call(this, node, parent, propertyName, byteValue, ccbReader);
+ }
+ },
+ onHandlePropTypeBlendFunc: function (node, parent, propertyName, ccBlendFunc, ccbReader) {
+ if (propertyName === PROPERTY_BLENDFUNC) {
+ // TODO Not exported by CocosBuilder yet!
+ // node.setBlendFunc(ccBlendFunc);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeBlendFunc.call(this, node, parent, propertyName, ccBlendFunc, ccbReader);
+ }
+ },
+ onHandlePropTypeSpriteFrame: function (node, parent, propertyName, spriteFrame, ccbReader) {
+ if (propertyName === PROPERTY_SPRITEFRAME) {
+ node.setSpriteFrame(spriteFrame);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeSpriteFrame.call(this, node, parent, propertyName, spriteFrame, ccbReader);
+ }
+ },
+ onHandlePropTypeSize: function (node, parent, propertyName, size, ccbReader) {
+ if (propertyName === PROPERTY_CONTENTSIZE) {
+ //node.setContentSize(size);
+ } else if (propertyName === PROPERTY_PREFEREDSIZE) {
+ node.setPreferredSize(size);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeSize.call(this, node, parent, propertyName, size, ccbReader);
+ }
+ },
+ onHandlePropTypeFloat: function (node, parent, propertyName, floatValue, ccbReader) {
+ if (propertyName === PROPERTY_INSETLEFT) {
+ node.setInsetLeft(floatValue);
+ } else if (propertyName === PROPERTY_INSETTOP) {
+ node.setInsetTop(floatValue);
+ } else if (propertyName === PROPERTY_INSETRIGHT) {
+ node.setInsetRight(floatValue);
+ } else if (propertyName === PROPERTY_INSETBOTTOM) {
+ node.setInsetBottom(floatValue);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeFloat.call(this, node, parent, propertyName, floatValue, ccbReader);
+ }
+ }
+});
+
+cc.Scale9SpriteLoader.loader = function () {
+ return new cc.Scale9SpriteLoader();
+};
+
+
+
diff --git a/frameworks/cocos2d-html5/extensions/ccb-reader/CCNodeLoader.js b/frameworks/cocos2d-html5/extensions/ccb-reader/CCNodeLoader.js
new file mode 100644
index 0000000..afa434b
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccb-reader/CCNodeLoader.js
@@ -0,0 +1,919 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+var PROPERTY_POSITION = "position";
+var PROPERTY_CONTENTSIZE = "contentSize";
+var PROPERTY_SKEW = "skew";
+var PROPERTY_ANCHORPOINT = "anchorPoint";
+var PROPERTY_SCALE = "scale";
+var PROPERTY_ROTATION = "rotation";
+var PROPERTY_TAG = "tag";
+var PROPERTY_IGNOREANCHORPOINTFORPOSITION = "ignoreAnchorPointForPosition";
+var PROPERTY_VISIBLE = "visible";
+
+var ASSERT_FAIL_UNEXPECTED_PROPERTY = function (propertyName) {
+ cc.log("Unexpected property: '" + propertyName + "'!");
+};
+
+var ASSERT_FAIL_UNEXPECTED_PROPERTYTYPE = function (propertyName) {
+ cc.log("Unexpected property type: '" + propertyName + "'!");
+};
+
+function BlockData(selMenuHander, target) {
+ this.selMenuHander = selMenuHander;
+ this.target = target;
+}
+
+function BlockCCControlData(selCCControlHandler, target, controlEvents) {
+ this.selCCControlHandler = selCCControlHandler;
+ this.target = target;
+ this.controlEvents = controlEvents;
+}
+
+cc.NodeLoader = cc.Class.extend({
+ _customProperties: null,
+ _pt: null,
+ _size: null,
+ _arr2: null,
+
+ ctor: function () {
+ this._customProperties = new cc._Dictionary();
+ this._pt = cc.p();
+ this._size = cc.size();
+ this._arr2 = new Array(2);
+ this._blockControlData = {
+ selCCControlHandler: null,
+ target: null,
+ controlEvents: null
+ };
+ },
+
+ loadCCNode: function (parent, ccbReader) {
+ return this._createCCNode(parent, ccbReader);
+ //this.parseProperties(node, parent, ccbReader);
+ //return node;
+ },
+
+ parseProperties: function (node, parent, ccbReader) {
+ var numRegularProps = ccbReader.readInt(false);
+ var numExturaProps = ccbReader.readInt(false);
+ var propertyCount = numRegularProps + numExturaProps;
+
+ for (var i = 0; i < propertyCount; i++) {
+ var isExtraProp = (i >= numRegularProps);
+ var type = ccbReader.readInt(false);
+ var propertyName = ccbReader.readCachedString();
+
+ // Check if the property can be set for this platform
+ var setProp = false;
+
+ var platform = ccbReader._data[ccbReader._currentByte++];
+ if ((platform === CCB_PLATFORM_ALL) || (platform === CCB_PLATFORM_IOS) || (platform === CCB_PLATFORM_MAC))
+ setProp = true;
+
+ //forward properties for sub ccb files
+ if (isExtraProp) {
+ if (node.ccbFileNode) {
+ node = node.ccbFileNode;
+ //skip properties that doesn't have a value to override
+ var getExtraPropsNames = node.userObject;
+ setProp = getExtraPropsNames.indexOf(propertyName) !== -1;
+ } else if (node === ccbReader._animationManager.getRootNode()) {
+ var extraPropsNames = node.userObject;
+ if (!extraPropsNames) {
+ extraPropsNames = [];
+ node.userObject = extraPropsNames;
+ }
+ extraPropsNames.push(propertyName);
+ }
+ }
+
+ switch (type) {
+ case CCB_PROPTYPE_POSITION:
+ {
+ var position = this.parsePropTypePosition(node, parent, ccbReader, propertyName);
+ if (setProp)
+ this.onHandlePropTypePosition(node, parent, propertyName, position, ccbReader);
+ break;
+ }
+ case CCB_PROPTYPE_POINT:
+ {
+ var point = this.parsePropTypePoint(node, parent, ccbReader);
+ if (setProp)
+ this.onHandlePropTypePoint(node, parent, propertyName, point, ccbReader);
+ break;
+ }
+ case CCB_PROPTYPE_POINTLOCK:
+ {
+ var pointLock = this.parsePropTypePointLock(node, parent, ccbReader);
+ if (setProp)
+ this.onHandlePropTypePointLock(node, parent, propertyName, pointLock, ccbReader);
+ break;
+ }
+ case CCB_PROPTYPE_SIZE:
+ {
+ var size = this.parsePropTypeSize(node, parent, ccbReader);
+ if (setProp)
+ this.onHandlePropTypeSize(node, parent, propertyName, size, ccbReader);
+ break;
+ }
+ case CCB_PROPTYPE_SCALELOCK:
+ {
+ var scaleLock = this.parsePropTypeScaleLock(node, parent, ccbReader, propertyName);
+ if (setProp)
+ this.onHandlePropTypeScaleLock(node, parent, propertyName, scaleLock, ccbReader);
+ break;
+ }
+ case CCB_PROPTYPE_FLOATXY:
+ {
+ var xy = this.parsePropTypeFloatXY(node, parent, ccbReader);
+ if (setProp)
+ this.onHandlePropTypeFloatXY(node, parent, propertyName, xy, ccbReader);
+ break;
+ }
+
+ case CCB_PROPTYPE_FLOAT:
+ {
+ var f = this.parsePropTypeFloat(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeFloat(node, parent, propertyName, f, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_DEGREES:
+ {
+ var degrees = this.parsePropTypeDegrees(node, parent, ccbReader, propertyName);
+ if (setProp) {
+ this.onHandlePropTypeDegrees(node, parent, propertyName, degrees, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_FLOATSCALE:
+ {
+ var floatScale = this.parsePropTypeFloatScale(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeFloatScale(node, parent, propertyName, floatScale, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_INTEGER:
+ {
+ var integer = this.parsePropTypeInteger(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeInteger(node, parent, propertyName, integer, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_INTEGERLABELED:
+ {
+ var integerLabeled = this.parsePropTypeIntegerLabeled(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeIntegerLabeled(node, parent, propertyName, integerLabeled, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_FLOATVAR:
+ {
+ var floatVar = this.parsePropTypeFloatVar(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeFloatVar(node, parent, propertyName, floatVar, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_CHECK:
+ {
+ var check = this.parsePropTypeCheck(node, parent, ccbReader, propertyName);
+ if (setProp) {
+ this.onHandlePropTypeCheck(node, parent, propertyName, check, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_SPRITEFRAME:
+ {
+ var ccSpriteFrame = this.parsePropTypeSpriteFrame(node, parent, ccbReader, propertyName);
+ if (setProp) {
+ this.onHandlePropTypeSpriteFrame(node, parent, propertyName, ccSpriteFrame, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_ANIMATION:
+ {
+ var ccAnimation = this.parsePropTypeAnimation(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeAnimation(node, parent, propertyName, ccAnimation, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_TEXTURE:
+ {
+ var ccTexture2D = this.parsePropTypeTexture(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeTexture(node, parent, propertyName, ccTexture2D, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_BYTE:
+ {
+ var byteValue = this.parsePropTypeByte(node, parent, ccbReader, propertyName);
+ if (setProp) {
+ this.onHandlePropTypeByte(node, parent, propertyName, byteValue, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_COLOR3:
+ {
+ var color = this.parsePropTypeColor3(node, parent, ccbReader, propertyName);
+ if (setProp) {
+ this.onHandlePropTypeColor3(node, parent, propertyName, color, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_COLOR4VAR:
+ {
+ var color4FVar = this.parsePropTypeColor4FVar(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeColor4FVar(node, parent, propertyName, color4FVar, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_FLIP:
+ {
+ var flip = this.parsePropTypeFlip(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeFlip(node, parent, propertyName, flip, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_BLENDMODE:
+ {
+ var blendFunc = this.parsePropTypeBlendFunc(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeBlendFunc(node, parent, propertyName, blendFunc, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_FNTFILE:
+ {
+ var fntFile = ccbReader.getCCBRootPath() + this.parsePropTypeFntFile(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeFntFile(node, parent, propertyName, fntFile, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_FONTTTF:
+ {
+ var fontTTF = this.parsePropTypeFontTTF(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeFontTTF(node, parent, propertyName, fontTTF, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_STRING:
+ {
+ var stringValue = this.parsePropTypeString(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeString(node, parent, propertyName, stringValue, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_TEXT:
+ {
+ var textValue = this.parsePropTypeText(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeText(node, parent, propertyName, textValue, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_BLOCK:
+ {
+ var blockData = this.parsePropTypeBlock(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeBlock(node, parent, propertyName, blockData, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_BLOCKCCCONTROL:
+ {
+ var blockCCControlData = this.parsePropTypeBlockCCControl(node, parent, ccbReader);
+ if (setProp && blockCCControlData != null) {
+ this.onHandlePropTypeBlockCCControl(node, parent, propertyName, blockCCControlData, ccbReader);
+ }
+ break;
+ }
+ case CCB_PROPTYPE_CCBFILE:
+ {
+ var ccbFileNode = this.parsePropTypeCCBFile(node, parent, ccbReader);
+ if (setProp) {
+ this.onHandlePropTypeCCBFile(node, parent, propertyName, ccbFileNode, ccbReader);
+ }
+ break;
+ }
+ default:
+ ASSERT_FAIL_UNEXPECTED_PROPERTYTYPE(type);
+ break;
+ }
+ }
+ },
+
+ getCustomProperties: function () {
+ return this._customProperties;
+ },
+
+ _createCCNode: function (parent, ccbReader) {
+ return new cc.Node();
+ },
+
+ parsePropTypePosition: function (node, parent, ccbReader, propertyName) {
+ var x = ccbReader.readFloat();
+ var y = ccbReader.readFloat();
+
+ var type = ccbReader.readInt(false);
+
+ // var containerSize = ccbReader._animationManager.getContainerSize(parent);
+ var containerSize = parent ? parent._contentSize : ccbReader._animationManager._rootContainerSize;
+ cc.getAbsolutePosition(x, y, type, containerSize, propertyName, this._pt);
+ node.setPosition(this._pt);
+
+ if (ccbReader._animatedProps.indexOf(propertyName) > -1) {
+ var baseValue = [x, y, type];
+ ccbReader._animationManager.setBaseValue(baseValue, node, propertyName);
+ }
+ return this._pt;
+ },
+
+ parsePropTypePoint: function (node, parent, ccbReader) {
+ this._pt.x = ccbReader.readFloat();
+ this._pt.y = ccbReader.readFloat();
+ return this._pt;
+ },
+
+ parsePropTypePointLock: function (node, parent, ccbReader) {
+ this._pt.x = ccbReader.readFloat();
+ this._pt.y = ccbReader.readFloat();
+ return this._pt;
+ },
+
+ parsePropTypeSize: function (node, parent, ccbReader) {
+ var width = ccbReader.readFloat();
+ var height = ccbReader.readFloat();
+
+ var type = ccbReader.readInt(false);
+
+ // var containerSize = ccbReader._animationManager.getContainerSize(parent);
+ var containerSize = parent ? parent._contentSize : ccbReader._animationManager._rootContainerSize;
+
+ switch (type) {
+ case CCB_SIZETYPE_ABSOLUTE:
+ /* Nothing. */
+ break;
+ case CCB_SIZETYPE_RELATIVE_CONTAINER:
+ width = containerSize.width - width;
+ height = containerSize.height - height;
+ break;
+ case CCB_SIZETYPE_PERCENT:
+ width = (containerSize.width * width / 100.0);
+ height = (containerSize.height * height / 100.0);
+ break;
+ case CCB_SIZETYPE_HORIZONTAL_PERCENT:
+ width = (containerSize.width * width / 100.0);
+ break;
+ case CCB_SIZETYPE_VERTICAL_PERCENT:
+ height = (containerSize.height * height / 100.0);
+ break;
+ case CCB_SIZETYPE_MULTIPLY_RESOLUTION:
+ var resolutionScale = cc.BuilderReader.getResolutionScale();
+ width *= resolutionScale;
+ height *= resolutionScale;
+ break;
+ default:
+ cc.log("Unknown CCB type.");
+ break;
+ }
+ this._size.width = width;
+ this._size.height = height;
+ return this._size;
+ },
+
+ parsePropTypeScaleLock: function (node, parent, ccbReader, propertyName) {
+ var x = ccbReader.readFloat();
+ var y = ccbReader.readFloat();
+
+ var type = ccbReader.readInt(false);
+
+ // cc.setRelativeScale(node, x, y, type, propertyName);
+
+ if (ccbReader._animatedProps.indexOf(propertyName) > -1) {
+ ccbReader._animationManager.setBaseValue([x, y, type], node, propertyName);
+ }
+
+ if (type === CCB_SCALETYPE_MULTIPLY_RESOLUTION) {
+ var resolutionScale = cc.BuilderReader.getResolutionScale();
+ x *= resolutionScale;
+ y *= resolutionScale;
+ }
+ this._pt.x = x;
+ this._pt.y = y;
+ return this._pt;
+ },
+
+ parsePropTypeFloat: function (node, parent, ccbReader) {
+ return ccbReader.readFloat();
+ },
+
+ parsePropTypeDegrees: function (node, parent, ccbReader, propertyName) {
+ var degrees = ccbReader.readFloat();
+ if (ccbReader._animatedProps.indexOf(propertyName) > -1) {
+ ccbReader._animationManager.setBaseValue(degrees, node, propertyName);
+ }
+ return degrees;
+ },
+
+ parsePropTypeFloatScale: function (node, parent, ccbReader) {
+ var f = ccbReader.readFloat();
+
+ var type = ccbReader.readInt(false);
+
+ if (type === CCB_SCALETYPE_MULTIPLY_RESOLUTION) {
+ f *= cc.BuilderReader.getResolutionScale();
+ }
+
+ return f;
+ },
+
+ parsePropTypeInteger: function (node, parent, ccbReader) {
+ return ccbReader.readInt(true);
+ },
+
+ parsePropTypeIntegerLabeled: function (node, parent, ccbReader) {
+ return ccbReader.readInt(true);
+ },
+
+ parsePropTypeFloatVar: function (node, parent, ccbReader) {
+ this._arr2[0] = ccbReader.readFloat();
+ this._arr2[1] = ccbReader.readFloat();
+ return this._arr2;
+ },
+
+ parsePropTypeCheck: function (node, parent, ccbReader, propertyName) {
+ var check = !!ccbReader._data[ccbReader._currentByte++];
+ if (ccbReader._animatedProps.indexOf(propertyName) > -1) {
+ ccbReader._animationManager.setBaseValue(check, node, propertyName);
+ }
+ return check;
+ },
+
+ parsePropTypeSpriteFrame: function (node, parent, ccbReader, propertyName) {
+ var spriteSheet = ccbReader.readCachedString();
+ var spriteFile = ccbReader.readCachedString();
+
+ var spriteFrame;
+ if (spriteFile) {
+ if (spriteSheet.length === 0) {
+ spriteFile = ccbReader._ccbRootPath + spriteFile;
+ var texture = cc.textureCache.addImage(spriteFile);
+
+ var locContentSize = texture.getContentSize();
+ var bounds = cc.rect(0, 0, locContentSize.width, locContentSize.height);
+ spriteFrame = new cc.SpriteFrame(texture, bounds);
+ } else {
+ var frameCache = cc.spriteFrameCache;
+ spriteSheet = ccbReader._ccbRootPath + spriteSheet;
+ //load the sprite sheet only if it is not loaded
+ if (ccbReader._loadedSpriteSheets.indexOf(spriteSheet) === -1) {
+ frameCache.addSpriteFrames(spriteSheet);
+ ccbReader._loadedSpriteSheets.push(spriteSheet);
+ }
+ spriteFrame = frameCache.getSpriteFrame(spriteFile);
+ }
+ if (ccbReader._animatedProps.indexOf(propertyName) > -1) {
+ ccbReader._animationManager.setBaseValue(spriteFrame, node, propertyName);
+ }
+ }
+
+ return spriteFrame;
+ },
+
+ parsePropTypeAnimation: function (node, parent, ccbReader) {
+ var animationFile = ccbReader._ccbRootPath + ccbReader.readCachedString();
+ var animation = ccbReader.readCachedString();
+
+ var ccAnimation = null;
+
+ // Support for stripping relative file paths, since ios doesn't currently
+ // know what to do with them, since its pulling from bundle.
+ // Eventually this should be handled by a client side asset manager
+ // interface which figured out what resources to load.
+ // TODO Does this problem exist in C++?
+ animation = cc.BuilderReader.lastPathComponent(animation);
+ animationFile = cc.BuilderReader.lastPathComponent(animationFile);
+
+ if (animation) {
+ var animationCache = cc.animationCache;
+ animationCache.addAnimations(animationFile);
+
+ ccAnimation = animationCache.getAnimation(animation);
+ }
+ return ccAnimation;
+ },
+
+ parsePropTypeTexture: function (node, parent, ccbReader) {
+ var spriteFile = ccbReader._ccbRootPath + ccbReader.readCachedString();
+
+ if (spriteFile)
+ return cc.textureCache.addImage(spriteFile);
+ return null;
+ },
+
+ parsePropTypeByte: function (node, parent, ccbReader, propertyName) {
+ var ret = ccbReader._data[ccbReader._currentByte++];
+ if (ccbReader._animatedProps.indexOf(propertyName) > -1) {
+ ccbReader._animationManager.setBaseValue(ret, node, propertyName);
+ }
+ return ret;
+ },
+
+ parsePropTypeColor3: function (node, parent, ccbReader, propertyName) {
+ var red = ccbReader._data[ccbReader._currentByte++];
+ var green = ccbReader._data[ccbReader._currentByte++];
+ var blue = ccbReader._data[ccbReader._currentByte++];
+ var color = cc.color(red, green, blue);
+ if (ccbReader._animatedProps.indexOf(propertyName) > -1) {
+ ccbReader._animationManager.setBaseValue(color, node, propertyName);
+ }
+ return color;
+ },
+
+ parsePropTypeColor4FVar: function (node, parent, ccbReader) {
+ //TODO Color4F doesn't supports on HTML5
+ var red = 0 | (ccbReader.readFloat() * 255);
+ var green = 0 | (ccbReader.readFloat() * 255);
+ var blue = 0 | (ccbReader.readFloat() * 255);
+ var alpha = ccbReader.readFloat();
+ alpha = alpha <= 1 ? (0 | (alpha * 255)) : alpha;
+ var redVar = 0 | (ccbReader.readFloat() * 255);
+ var greenVar = 0 | (ccbReader.readFloat() * 255);
+ var blueVar = 0 | (ccbReader.readFloat() * 255);
+ var alphaVar = ccbReader.readFloat();
+ alphaVar = alphaVar <= 1 ? (0 | (alphaVar * 255)) : alphaVar;
+
+ this._arr2[0] = {r: red, g: green, b: blue, a: alpha};
+ this._arr2[1] = {r: redVar, g: greenVar, b: blueVar, a: alphaVar};
+
+ return this._arr2;
+ },
+
+ parsePropTypeFlip: function (node, parent, ccbReader) {
+ this._arr2[0] = !!ccbReader._data[ccbReader._currentByte++];
+ this._arr2[1] = !!ccbReader._data[ccbReader._currentByte++];
+
+ return this._arr2;
+ },
+
+ parsePropTypeBlendFunc: function (node, parent, ccbReader) {
+ var source = ccbReader.readInt(false);
+ var destination = ccbReader.readInt(false);
+
+ return new cc.BlendFunc(source, destination);
+ },
+
+ parsePropTypeFntFile: function (node, parent, ccbReader) {
+ return ccbReader.readCachedString();
+ },
+
+ parsePropTypeString: function (node, parent, ccbReader) {
+ return ccbReader.readCachedString();
+ },
+
+ parsePropTypeText: function (node, parent, ccbReader) {
+ return ccbReader.readCachedString();
+ },
+
+ parsePropTypeFontTTF: function (node, parent, ccbReader) {
+ return ccbReader.readCachedString();
+ //var ttfEnding = ".ttf";
+
+ //TODO Fix me if it is wrong
+ /* If the fontTTF comes with the ".ttf" extension, prepend the absolute path.
+ * System fonts come without the ".ttf" extension and do not need the path prepended. */
+ /*if (cc.CCBReader.endsWith(fontTTF.toLowerCase(), ttfEnding)) {
+ fontTTF = ccbReader.getCCBRootPath() + fontTTF;
+ }*/
+ },
+
+ parsePropTypeBlock: function (node, parent, ccbReader) {
+ var selectorName = ccbReader.readCachedString();
+ var selectorTarget = ccbReader.readInt(false);
+
+ if (selectorTarget !== CCB_TARGETTYPE_NONE) {
+ var target = null;
+ if (!ccbReader._jsControlled) {
+ if (selectorTarget === CCB_TARGETTYPE_DOCUMENTROOT) {
+ target = ccbReader._animationManager._rootNode;
+ } else if (selectorTarget === CCB_TARGETTYPE_OWNER) {
+ target = ccbReader._owner;
+ }
+
+ if (target !== null) {
+ if (selectorName.length > 0) {
+ var selMenuHandler = 0;
+
+ //var targetAsCCBSelectorResolver = target;
+ if (target.onResolveCCBCCMenuItemSelector)
+ selMenuHandler = target.onResolveCCBCCMenuItemSelector(target, selectorName);
+
+ if (selMenuHandler === 0) {
+ var ccbSelectorResolver = ccbReader._ccbSelectorResolver;
+ if (ccbSelectorResolver)
+ selMenuHandler = ccbSelectorResolver.onResolveCCBCCMenuItemSelector(target, selectorName);
+ }
+
+ if (selMenuHandler === 0) {
+ cc.log("Skipping selector '" + selectorName + "' since no CCBSelectorResolver is present.");
+ } else {
+ return new BlockData(selMenuHandler, target);
+ }
+ } else {
+ cc.log("Unexpected empty selector.");
+ }
+ } else {
+ cc.log("Unexpected NULL target for selector.");
+ }
+ } else {
+ if (selectorTarget === CCB_TARGETTYPE_DOCUMENTROOT) {
+ ccbReader.addDocumentCallbackNode(node);
+ ccbReader.addDocumentCallbackName(selectorName);
+ ccbReader.addDocumentCallbackControlEvents(0);
+ } else {
+ ccbReader.addOwnerCallbackNode(node);
+ ccbReader.addOwnerCallbackName(selectorName);
+ ccbReader.addOwnerCallbackControlEvents(0);
+ }
+ }
+ }
+ return null;
+ },
+
+ parsePropTypeBlockCCControl: function (node, parent, ccbReader) {
+ var selectorName = ccbReader.readCachedString();
+ var selectorTarget = ccbReader.readInt(false);
+ var controlEvents = ccbReader.readInt(false);
+
+ if (selectorTarget !== CCB_TARGETTYPE_NONE) {
+ if (!ccbReader._jsControlled) {
+ var target = null;
+ if (selectorTarget === CCB_TARGETTYPE_DOCUMENTROOT) {
+ target = ccbReader._animationManager._rootNode;
+ } else if (selectorTarget === CCB_TARGETTYPE_OWNER) {
+ target = ccbReader._owner;
+ }
+
+ if (target !== null) {
+ if (selectorName.length > 0) {
+ var selCCControlHandler = 0;
+
+ if (target.onResolveCCBCCControlSelector) {
+ selCCControlHandler = target.onResolveCCBCCControlSelector(target, selectorName);
+ }
+ if (selCCControlHandler === 0) {
+ var ccbSelectorResolver = ccbReader._ccbSelectorResolver;
+ if (ccbSelectorResolver != null) {
+ selCCControlHandler = ccbSelectorResolver.onResolveCCBCCControlSelector(target, selectorName);
+ }
+ }
+
+ if (selCCControlHandler === 0) {
+ cc.log("Skipping selector '" + selectorName + "' since no CCBSelectorResolver is present.");
+ } else {
+ this._blockControlData.selCCControlHandler = selCCControlHandler;
+ this._blockControlData.target = target;
+ this._blockControlData.controlEvents = controlEvents;
+ return this._blockControlData;
+ }
+ } else {
+ cc.log("Unexpected empty selector.");
+ }
+ } else {
+ cc.log("Unexpected NULL target for selector.");
+ }
+ } else {
+ if (selectorTarget === CCB_TARGETTYPE_DOCUMENTROOT) {
+ ccbReader.addDocumentCallbackNode(node);
+ ccbReader.addDocumentCallbackName(selectorName);
+ ccbReader.addDocumentCallbackControlEvents(controlEvents);
+ } else {
+ ccbReader.addOwnerCallbackNode(node);
+ ccbReader.addOwnerCallbackName(selectorName);
+ ccbReader.addOwnerCallbackControlEvents(controlEvents);
+ }
+ }
+ }
+ return null;
+ },
+
+ parsePropTypeCCBFile: function (node, parent, ccbReader) {
+ var ccbFileName = ccbReader._ccbRootPath + ccbReader.readCachedString();
+
+ /* Change path extension to .ccbi. */
+ var ccbFileWithoutPathExtension = cc.BuilderReader.deletePathExtension(ccbFileName);
+ ccbFileName = ccbFileWithoutPathExtension + ".ccbi";
+
+ var myCCBReader = new cc.BuilderReader(ccbReader);
+
+ var bytes = cc.loader.getRes(ccbFileName);
+ if (!bytes) {
+ var realUrl = cc.loader.getUrl(ccbFileName);
+ realUrl = hlddz.convertToDownloadURL(realUrl);
+ bytes = cc.loader.loadBinarySync(realUrl);
+ cc.loader.cache[ccbFileName] = bytes;
+ }
+
+ myCCBReader.initWithData(bytes, ccbReader._owner);
+ myCCBReader._animationManager.setRootContainerSize(parent._contentSize);
+ myCCBReader.setAnimationManagers(ccbReader._animationManagers);
+
+ myCCBReader._animationManager.setOwner(ccbReader._owner);
+ var ccbFileNode = myCCBReader.readFileWithCleanUp(false);
+ ccbReader.setAnimationManagers(myCCBReader._animationManagers);
+
+ if (ccbFileNode && myCCBReader._animationManager._autoPlaySequenceId !== -1)
+ myCCBReader._animationManager.runAnimations(myCCBReader._animationManager._autoPlaySequenceId, 0);
+
+ return ccbFileNode;
+ },
+
+ parsePropTypeFloatXY: function (node, parent, ccbReader) {
+ this._pt.x = ccbReader.readFloat();
+ this._pt.y = ccbReader.readFloat();
+ return this._pt;
+ },
+
+ onHandlePropTypePosition: function (node, parent, propertyName, position, ccbReader) {
+ if (propertyName === PROPERTY_POSITION) {
+ node.setPosition(position);
+ } else {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ }
+ },
+
+ onHandlePropTypePoint: function (node, parent, propertyName, position, ccbReader) {
+ if (propertyName === PROPERTY_ANCHORPOINT) {
+ node.setAnchorPoint(position);
+ } else {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ }
+ },
+
+ onHandlePropTypePointLock: function (node, parent, propertyName, pointLock, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+
+ onHandlePropTypeSize: function (node, parent, propertyName, sizeValue, ccbReader) {
+ if (propertyName === PROPERTY_CONTENTSIZE) {
+ node.setContentSize(sizeValue);
+ } else {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ }
+ },
+
+ onHandlePropTypeScaleLock: function (node, parent, propertyName, scaleLock, ccbReader) {
+ if (propertyName === PROPERTY_SCALE) {
+ node.setScale(scaleLock.x, scaleLock.y);
+ } else {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ }
+ },
+ onHandlePropTypeFloatXY: function (node, parent, propertyName, xy, ccbReader) {
+ if (propertyName === PROPERTY_SKEW) {
+ node._skewX = xy.x;
+ node._skewY = xy.y;
+ } else {
+ var nameX = propertyName + "X";
+ var nameY = propertyName + "Y";
+ if (!node[nameX] || !node[nameY])
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ //TODO throw an error when source code was confused
+ node[nameX](xy.x);
+ node[nameY](xy.y);
+ }
+ },
+ onHandlePropTypeFloat: function (node, parent, propertyName, floatValue, ccbReader) {
+ //ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ // It may be a custom property, add it to custom property dictionary.
+ this._customProperties.setObject(floatValue, propertyName);
+ },
+
+ onHandlePropTypeDegrees: function (node, parent, propertyName, degrees, ccbReader) {
+ if (propertyName === PROPERTY_ROTATION) {
+ node.setRotation(degrees);
+ } else {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ }
+ },
+
+ onHandlePropTypeFloatScale: function (node, parent, propertyName, floatScale, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+
+ onHandlePropTypeInteger: function (node, parent, propertyName, integer, ccbReader) {
+ if (propertyName === PROPERTY_TAG) {
+ node.tag = integer;
+ } else {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ }
+ },
+
+ onHandlePropTypeIntegerLabeled: function (node, parent, propertyName, integerLabeled, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+
+ onHandlePropTypeFloatVar: function (node, parent, propertyName, floatVar, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+
+ onHandlePropTypeCheck: function (node, parent, propertyName, check, ccbReader) {
+ if (propertyName === PROPERTY_VISIBLE) {
+ node._visible = check;
+ } else if (propertyName === PROPERTY_IGNOREANCHORPOINTFORPOSITION) {
+ node._ignoreAnchorPointForPosition = check;
+ } else {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ }
+ },
+
+ onHandlePropTypeSpriteFrame: function (node, parent, propertyName, spriteFrame, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+
+ onHandlePropTypeAnimation: function (node, parent, propertyName, ccAnimation, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+
+ onHandlePropTypeTexture: function (node, parent, propertyName, ccTexture2D, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+ onHandlePropTypeByte: function (node, parent, propertyName, byteValue, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+ onHandlePropTypeColor3: function (node, parent, propertyName, ccColor3B, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+ onHandlePropTypeColor4FVar: function (node, parent, propertyName, ccColor4FVar, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+ onHandlePropTypeFlip: function (node, parent, propertyName, flip, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+ onHandlePropTypeBlendFunc: function (node, parent, propertyName, ccBlendFunc, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+ onHandlePropTypeFntFile: function (node, parent, propertyName, fntFile, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+ onHandlePropTypeString: function (node, parent, propertyName, strValue, ccbReader) {
+ //ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ // It may be a custom property, add it to custom property dictionary.
+ this._customProperties.setObject(strValue, propertyName);
+ },
+ onHandlePropTypeText: function (node, parent, propertyName, textValue, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+ onHandlePropTypeFontTTF: function (node, parent, propertyName, fontTTF, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+ onHandlePropTypeBlock: function (node, parent, propertyName, blockData, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+ onHandlePropTypeBlockCCControl: function (node, parent, propertyName, blockCCControlData, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ },
+ onHandlePropTypeCCBFile: function (node, parent, propertyName, ccbFileNode, ccbReader) {
+ ASSERT_FAIL_UNEXPECTED_PROPERTY(propertyName);
+ }
+});
+
+cc.NodeLoader.loader = function () {
+ return new cc.NodeLoader();
+};
diff --git a/frameworks/cocos2d-html5/extensions/ccb-reader/CCNodeLoaderLibrary.js b/frameworks/cocos2d-html5/extensions/ccb-reader/CCNodeLoaderLibrary.js
new file mode 100644
index 0000000..487dc7b
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccb-reader/CCNodeLoaderLibrary.js
@@ -0,0 +1,101 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.NodeLoaderLibrary = cc.Class.extend({
+ _ccNodeLoaders:null,
+
+ ctor:function(){
+ this._ccNodeLoaders = {};
+ },
+
+ registerDefaultCCNodeLoaders:function(){
+ this.registerCCNodeLoader("CCNode", cc.NodeLoader.loader());
+ this.registerCCNodeLoader("CCLayer", cc.LayerLoader.loader());
+ this.registerCCNodeLoader("CCLayerColor", cc.LayerColorLoader.loader());
+ this.registerCCNodeLoader("CCLayerGradient", cc.LayerGradientLoader.loader());
+ this.registerCCNodeLoader("CCSprite", cc.SpriteLoader.loader());
+ this.registerCCNodeLoader("CCLabelBMFont", cc.LabelBMFontLoader.loader());
+ this.registerCCNodeLoader("CCLabelTTF", cc.LabelTTFLoader.loader());
+ this.registerCCNodeLoader("CCScale9Sprite", cc.Scale9SpriteLoader.loader());
+ this.registerCCNodeLoader("CCScrollView", cc.ScrollViewLoader.loader());
+ this.registerCCNodeLoader("CCBFile", cc.BuilderFileLoader.loader());
+ this.registerCCNodeLoader("CCMenu", cc.MenuLoader.loader());
+ this.registerCCNodeLoader("CCMenuItemImage", cc.MenuItemImageLoader.loader());
+ this.registerCCNodeLoader("CCControlButton", cc.ControlButtonLoader.loader());
+ this.registerCCNodeLoader("CCParticleSystemQuad", cc.ParticleSystemLoader.loader());
+ },
+
+ registerCCNodeLoader:function(className,ccNodeLoader){
+ this._ccNodeLoaders[className] = ccNodeLoader;
+ },
+
+ unregisterCCNodeLoader:function(className){
+ if(this._ccNodeLoaders[className]){
+ delete this._ccNodeLoaders[className];
+ }
+ },
+
+ getCCNodeLoader:function(className){
+ if(this._ccNodeLoaders[className])
+ return this._ccNodeLoaders[className];
+ return null;
+ },
+
+ purge:function(releaseCCNodeLoaders){
+ if(releaseCCNodeLoaders) {
+ for(var className in this._ccNodeLoaders) {
+ delete this._ccNodeLoaders[className];
+ }
+ }
+ this._ccNodeLoaders = {};
+ }
+});
+
+cc.NodeLoaderLibrary.sSharedCCNodeLoaderLibrary = null;
+cc.NodeLoaderLibrary.library = function(){
+ return new cc.NodeLoaderLibrary();
+};
+
+cc.NodeLoaderLibrary.sharedCCNodeLoaderLibrary = function(){
+ if(cc.NodeLoaderLibrary.sSharedCCNodeLoaderLibrary == null) {
+ cc.NodeLoaderLibrary.sSharedCCNodeLoaderLibrary = new cc.NodeLoaderLibrary();
+ cc.NodeLoaderLibrary.sSharedCCNodeLoaderLibrary.registerDefaultCCNodeLoaders();
+ }
+ return cc.NodeLoaderLibrary.sSharedCCNodeLoaderLibrary;
+};
+
+cc.NodeLoaderLibrary.purgeSharedCCNodeLoaderLibrary = function(){
+ cc.NodeLoaderLibrary.sSharedCCNodeLoaderLibrary = null;
+};
+
+cc.NodeLoaderLibrary.newDefaultCCNodeLoaderLibrary = function(){
+ var ccNodeLoaderLibrary = cc.NodeLoaderLibrary.library();
+ ccNodeLoaderLibrary.registerDefaultCCNodeLoaders();
+ return ccNodeLoaderLibrary;
+};
+
+
+
diff --git a/frameworks/cocos2d-html5/extensions/ccb-reader/CCSpriteLoader.js b/frameworks/cocos2d-html5/extensions/ccb-reader/CCSpriteLoader.js
new file mode 100644
index 0000000..857b2bb
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccb-reader/CCSpriteLoader.js
@@ -0,0 +1,544 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+var PROPERTY_FLIP = "flip";
+var PROPERTY_DISPLAYFRAME = "displayFrame";
+var PROPERTY_COLOR = "color";
+var PROPERTY_OPACITY = "opacity";
+var PROPERTY_BLENDFUNC = "blendFunc";
+
+cc.SpriteLoader = cc.NodeLoader.extend({
+ _createCCNode:function (parent, ccbReader) {
+ return new cc.Sprite();
+ },
+
+ onHandlePropTypeColor3:function (node, parent, propertyName, ccColor3B, ccbReader) {
+ if (propertyName === PROPERTY_COLOR) {
+ if(ccColor3B.r !== 255 || ccColor3B.g !== 255 || ccColor3B.b !== 255){
+ node.setColor(ccColor3B);
+ }
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeColor3.call(this, node, parent, propertyName, ccColor3B, ccbReader);
+ }
+ },
+ onHandlePropTypeByte:function (node, parent, propertyName, byteValue, ccbReader) {
+ if (propertyName === PROPERTY_OPACITY) {
+ node.setOpacity(byteValue);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeByte.call(this, node, parent, propertyName, byteValue, ccbReader);
+ }
+ },
+ onHandlePropTypeBlendFunc:function (node, parent, propertyName, ccbBlendFunc, ccbReader) {
+ if (propertyName === PROPERTY_BLENDFUNC) {
+ node.setBlendFunc(ccbBlendFunc);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeBlendFunc.call(this, node, parent, propertyName, ccbBlendFunc, ccbReader);
+ }
+ },
+ onHandlePropTypeSpriteFrame:function (node, parent, propertyName, ccSpriteFrame, ccbReader) {
+ if (propertyName === PROPERTY_DISPLAYFRAME) {
+ if(ccSpriteFrame)
+ node.setSpriteFrame(ccSpriteFrame);
+ else
+ cc.log("ERROR: SpriteFrame is null");
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeSpriteFrame.call(this, node, parent, propertyName, ccSpriteFrame, ccbReader);
+ }
+ },
+ onHandlePropTypeFlip:function (node, parent, propertyName, flip, ccbReader) {
+ if (propertyName === PROPERTY_FLIP) {
+ node.setFlippedX(flip[0]);
+ node.setFlippedY(flip[1]);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeFlip.call(this, node, parent, propertyName, flip, ccbReader);
+ }
+ }
+});
+
+cc.SpriteLoader.loader = function () {
+ return new cc.SpriteLoader();
+};
+
+var PROPERTY_TOUCH_ENABLED = "touchEnabled";
+var PROPERTY_IS_TOUCH_ENABLED = "isTouchEnabled";
+var PROPERTY_ACCELEROMETER_ENABLED = "accelerometerEnabled";
+var PROPERTY_IS_ACCELEROMETER_ENABLED = "isAccelerometerEnabled";
+var PROPERTY_IS_MOUSE_ENABLED = "isMouseEnabled";
+var PROPERTY_MOUSE_ENABLED = "mouseEnabled";
+var PROPERTY_KEYBOARD_ENABLED = "keyboardEnabled";
+var PROPERTY_IS_KEYBOARD_ENABLED = "isKeyboardEnabled";
+
+cc.LayerLoader = cc.NodeLoader.extend({
+ _createCCNode:function (parent, ccbReader) {
+
+ var layer = new cc.Layer();
+
+ layer.setContentSize(0,0);
+
+ return layer;
+ },
+ onHandlePropTypeCheck:function (node, parent, propertyName, check, ccbReader) {
+ if (propertyName === PROPERTY_TOUCH_ENABLED || propertyName === PROPERTY_IS_TOUCH_ENABLED) {
+ //node.setTouchEnabled(check);
+ } else if (propertyName === PROPERTY_ACCELEROMETER_ENABLED || propertyName === PROPERTY_IS_ACCELEROMETER_ENABLED) {
+ //node.setAccelerometerEnabled(check);
+ } else if (propertyName === PROPERTY_MOUSE_ENABLED || propertyName === PROPERTY_IS_MOUSE_ENABLED ) {
+ //node.setMouseEnabled(check);
+ } else if (propertyName === PROPERTY_KEYBOARD_ENABLED || propertyName === PROPERTY_IS_KEYBOARD_ENABLED) {
+ // TODO XXX
+ if(node.setKeyboardEnabled && !cc.sys.isNative) {
+ node.setKeyboardEnabled(check);
+ } else {
+ cc.log("The property '" + PROPERTY_IS_KEYBOARD_ENABLED + "' is not supported!");
+ // This comes closest: ((CCLayer *)pNode).setKeypadEnabled(pCheck);
+ }
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeCheck.call(this, node, parent, propertyName, check, ccbReader);
+ }
+ }
+});
+
+cc.LayerLoader.loader = function () {
+ return new cc.LayerLoader();
+};
+
+
+cc.LayerColorLoader = cc.LayerLoader.extend({
+ _createCCNode:function (parent, ccbReader) {
+ return new cc.LayerColor();
+ },
+
+ onHandlePropTypeColor3:function (node, parent, propertyName, ccColor3B, ccbReader) {
+ if (propertyName === PROPERTY_COLOR) {
+ node.setColor(ccColor3B);
+ } else {
+ cc.LayerLoader.prototype.onHandlePropTypeColor3.call(this, node, parent, propertyName, ccColor3B, ccbReader);
+ }
+ },
+ onHandlePropTypeByte:function (node, parent, propertyName, byteValue, ccbReader) {
+ if (propertyName === PROPERTY_OPACITY) {
+ node.setOpacity(byteValue);
+ } else {
+ cc.LayerLoader.prototype.onHandlePropTypeByte.call(this, node, parent, propertyName, byteValue, ccbReader);
+ }
+ },
+ onHandlePropTypeBlendFunc:function (node, parent, propertyName, ccBlendFunc, ccbReader) {
+ if (propertyName === PROPERTY_BLENDFUNC) {
+ node.setBlendFunc(ccBlendFunc);
+ } else {
+ cc.LayerLoader.prototype.onHandlePropTypeBlendFunc.call(this, node, parent, propertyName, ccBlendFunc, ccbReader);
+ }
+ }
+});
+
+cc.LayerColorLoader.loader = function () {
+ return new cc.LayerColorLoader();
+};
+
+var PROPERTY_STARTCOLOR = "startColor";
+var PROPERTY_ENDCOLOR = "endColor";
+var PROPERTY_STARTOPACITY = "startOpacity";
+var PROPERTY_ENDOPACITY = "endOpacity";
+var PROPERTY_VECTOR = "vector";
+
+cc.LayerGradientLoader = cc.LayerLoader.extend({
+ _createCCNode:function (parent, ccbReader) {
+ return new cc.LayerGradient();
+ },
+ onHandlePropTypeColor3:function (node, parent, propertyName, ccColor3B, ccbReader) {
+ if (propertyName === PROPERTY_STARTCOLOR) {
+ node.setStartColor(ccColor3B);
+ } else if (propertyName === PROPERTY_ENDCOLOR) {
+ node.setEndColor(ccColor3B);
+ } else {
+ cc.LayerLoader.prototype.onHandlePropTypeColor3.call(this, node, parent, propertyName, ccColor3B, ccbReader);
+ }
+ },
+ onHandlePropTypeByte:function (node, parent, propertyName, byteValue, ccbReader) {
+ if (propertyName === PROPERTY_STARTOPACITY) {
+ node.setStartOpacity(byteValue);
+ } else if (propertyName === PROPERTY_ENDOPACITY) {
+ node.setEndOpacity(byteValue);
+ } else {
+ cc.LayerLoader.prototype.onHandlePropTypeByte.call(this, node, parent, propertyName, byteValue, ccbReader);
+ }
+ },
+ onHandlePropTypePoint:function (node, parent, propertyName, point, ccbReader) {
+ if (propertyName === PROPERTY_VECTOR) {
+ node.setVector(point);
+ // TODO Not passed along the ccbi file.
+ // node.setCompressedInterpolation(true);
+ } else {
+ cc.LayerLoader.prototype.onHandlePropTypePoint.call(this, node, parent, propertyName, point, ccbReader);
+ }
+ },
+ onHandlePropTypeBlendFunc:function (node, parent, propertyName, ccBlendFunc, ccbReader) {
+ if (propertyName === PROPERTY_BLENDFUNC) {
+ node.setBlendFunc(ccBlendFunc);
+ } else {
+ cc.LayerLoader.prototype.onHandlePropTypeBlendFunc.call(this, node, parent, propertyName, ccBlendFunc, ccbReader);
+ }
+ }
+});
+
+cc.LayerGradientLoader.loader = function () {
+ return new cc.LayerGradientLoader();
+};
+
+cc.MenuLoader = cc.LayerLoader.extend({
+ _createCCNode:function (parent, ccbReader) {
+ var menu = new cc.Menu();
+
+ menu.setContentSize(0,0);
+
+ return menu;
+ }
+});
+
+cc.MenuLoader.loader = function () {
+ return new cc.MenuLoader();
+};
+
+var PROPERTY_BLOCK = "block";
+var PROPERTY_ISENABLED = "isEnabled";
+
+cc.MenuItemLoader = cc.NodeLoader.extend({
+ _createCCNode:function (parent, ccbReader) {
+ return null;
+ },
+
+ onHandlePropTypeBlock:function (node, parent, propertyName, blockData, ccbReader) {
+ if (propertyName === PROPERTY_BLOCK) {
+ if (null != blockData) { // Add this condition to allow CCMenuItemImage without target/selector predefined
+ node.setTarget(blockData.selMenuHander, blockData.target);
+ }
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeBlock.call(this, node, parent, propertyName, blockData, ccbReader);
+ }
+ },
+ onHandlePropTypeCheck:function (node, parent, propertyName, check, ccbReader) {
+ if (propertyName === PROPERTY_ISENABLED) {
+ node.setEnabled(check);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeCheck.call(this, node, parent, propertyName, check, ccbReader);
+ }
+ }
+});
+
+var PROPERTY_NORMALDISPLAYFRAME = "normalSpriteFrame";
+var PROPERTY_SELECTEDDISPLAYFRAME = "selectedSpriteFrame";
+var PROPERTY_DISABLEDDISPLAYFRAME = "disabledSpriteFrame";
+
+cc.MenuItemImageLoader = cc.MenuItemLoader.extend({
+ _createCCNode:function (parent, ccbReader) {
+ return new cc.MenuItemImage();
+ },
+
+ onHandlePropTypeSpriteFrame:function (node, parent, propertyName, spriteFrame, ccbReader) {
+ if (propertyName === PROPERTY_NORMALDISPLAYFRAME) {
+ if (spriteFrame != null) {
+ node.setNormalSpriteFrame(spriteFrame);
+ }
+ } else if (propertyName === PROPERTY_SELECTEDDISPLAYFRAME) {
+ if (spriteFrame != null) {
+ node.setSelectedSpriteFrame(spriteFrame);
+ }
+ } else if (propertyName === PROPERTY_DISABLEDDISPLAYFRAME) {
+ if (spriteFrame != null) {
+ node.setDisabledSpriteFrame(spriteFrame);
+ }
+ } else {
+ cc.MenuItemLoader.prototype.onHandlePropTypeSpriteFrame.call(this, node, parent, propertyName, spriteFrame, ccbReader);
+ }
+ }
+});
+
+cc.MenuItemImageLoader.loader = function () {
+ return new cc.MenuItemImageLoader();
+};
+
+var PROPERTY_FONTNAME = "fontName";
+var PROPERTY_FONTSIZE = "fontSize";
+var PROPERTY_HORIZONTALALIGNMENT = "horizontalAlignment";
+var PROPERTY_VERTICALALIGNMENT = "verticalAlignment";
+var PROPERTY_STRING = "string";
+var PROPERTY_DIMENSIONS = "dimensions";
+
+cc.LabelTTFLoader = cc.NodeLoader.extend({
+ _createCCNode:function (parent, ccbReader) {
+ return new cc.LabelTTF();
+ },
+ onHandlePropTypeColor3:function (node, parent, propertyName, ccColor3B, ccbReader) {
+ if (propertyName === PROPERTY_COLOR) {
+ if(ccColor3B.r !== 255 || ccColor3B.g !== 255 || ccColor3B.b !== 255){
+ node.setColor(ccColor3B);
+ }
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeColor3.call(this, node, parent, propertyName, ccColor3B, ccbReader);
+ }
+ },
+ onHandlePropTypeByte:function (node, parent, propertyName, byteValue, ccbReader) {
+ if (propertyName === PROPERTY_OPACITY) {
+ node.setOpacity(byteValue);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeByte.call(this, node, parent, propertyName, byteValue, ccbReader);
+ }
+ },
+ onHandlePropTypeBlendFunc:function (node, parent, propertyName, ccBlendFunc, ccbReader) {
+ if (propertyName === PROPERTY_BLENDFUNC) {
+ node.setBlendFunc(ccBlendFunc);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeBlendFunc.call(this, node, parent, propertyName, ccBlendFunc, ccbReader);
+ }
+ },
+ onHandlePropTypeFontTTF:function (node, parent, propertyName, fontTTF, ccbReader) {
+ if (propertyName === PROPERTY_FONTNAME) {
+ node.setFontName(fontTTF);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeFontTTF.call(this, node, parent, propertyName, fontTTF, ccbReader);
+ }
+ },
+ onHandlePropTypeText:function (node, parent, propertyName, textValue, ccbReader) {
+ if (propertyName === PROPERTY_STRING) {
+ node.setString(textValue);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeText.call(this, node, parent, propertyName, textValue, ccbReader);
+ }
+ },
+ onHandlePropTypeFloatScale:function (node, parent, propertyName, floatScale, ccbReader) {
+ if (propertyName === PROPERTY_FONTSIZE) {
+ node.setFontSize(floatScale);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeFloatScale.call(this, node, parent, propertyName, floatScale, ccbReader);
+ }
+ },
+ onHandlePropTypeIntegerLabeled:function (node, parent, propertyName, integerLabeled, ccbReader) {
+ if (propertyName === PROPERTY_HORIZONTALALIGNMENT) {
+ node.setHorizontalAlignment(integerLabeled);
+ } else if (propertyName === PROPERTY_VERTICALALIGNMENT) {
+ node.setVerticalAlignment(integerLabeled);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeIntegerLabeled.call(this, node, parent, propertyName, integerLabeled, ccbReader);
+ }
+ },
+ onHandlePropTypeSize:function (node, parent, propertyName, size, ccbReader) {
+ if (propertyName === PROPERTY_DIMENSIONS) {
+ node.setDimensions(size);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeSize.call(this, node, parent, propertyName, size, ccbReader);
+ }
+ }
+});
+
+cc.LabelTTFLoader.loader = function () {
+ return new cc.LabelTTFLoader();
+};
+
+var PROPERTY_FNTFILE = "fntFile";
+
+cc.LabelBMFontLoader = cc.NodeLoader.extend({
+ _createCCNode:function (parent, ccbReader) {
+ return new cc.LabelBMFont();
+ },
+
+ onHandlePropTypeColor3:function (node, parent, propertyName, ccColor3B, ccbReader) {
+ if (propertyName === PROPERTY_COLOR) {
+ if(ccColor3B.r !== 255 || ccColor3B.g !== 255 || ccColor3B.b !== 255){
+ node.setColor(ccColor3B);
+ }
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeColor3.call(this, node, parent, propertyName, ccColor3B, ccbReader);
+ }
+ },
+ onHandlePropTypeByte:function (node, parent, propertyName, byteValue, ccbReader) {
+ if (propertyName === PROPERTY_OPACITY) {
+ node.setOpacity(byteValue);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeByte.call(this, node, parent, propertyName, byteValue, ccbReader);
+ }
+ },
+ onHandlePropTypeBlendFunc:function (node, parent, propertyName, ccBlendFunc, ccbReader) {
+ if (propertyName === PROPERTY_BLENDFUNC) {
+ node.setBlendFunc(ccBlendFunc);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeBlendFunc.call(this, node, parent, propertyName, ccBlendFunc, ccbReader);
+ }
+ },
+ onHandlePropTypeFntFile:function (node, parent, propertyName, fntFile, ccbReader) {
+ if (propertyName === PROPERTY_FNTFILE) {
+ node.setFntFile(fntFile);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeFntFile.call(this, node, parent, propertyName, fntFile, ccbReader);
+ }
+ },
+ onHandlePropTypeText:function (node, parent, propertyName, textValue, ccbReader) {
+ if (propertyName === PROPERTY_STRING) {
+ node.setString(textValue);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeText.call(this, node, parent, propertyName, textValue, ccbReader);
+ }
+ }
+});
+
+cc.LabelBMFontLoader.loader = function () {
+ return new cc.LabelBMFontLoader();
+};
+
+var PROPERTY_EMITERMODE = "emitterMode";
+var PROPERTY_POSVAR = "posVar";
+var PROPERTY_EMISSIONRATE = "emissionRate";
+var PROPERTY_DURATION = "duration";
+var PROPERTY_TOTALPARTICLES = "totalParticles";
+var PROPERTY_LIFE = "life";
+var PROPERTY_STARTSIZE = "startSize";
+var PROPERTY_ENDSIZE = "endSize";
+var PROPERTY_STARTSPIN = "startSpin";
+var PROPERTY_ENDSPIN = "endSpin";
+var PROPERTY_ANGLE = "angle";
+var PROPERTY_GRAVITY = "gravity";
+var PROPERTY_SPEED = "speed";
+var PROPERTY_TANGENTIALACCEL = "tangentialAccel";
+var PROPERTY_RADIALACCEL = "radialAccel";
+var PROPERTY_TEXTURE = "texture";
+var PROPERTY_STARTRADIUS = "startRadius";
+var PROPERTY_ENDRADIUS = "endRadius";
+var PROPERTY_ROTATEPERSECOND = "rotatePerSecond";
+
+cc.ParticleSystemLoader = cc.NodeLoader.extend({
+ _createCCNode:function (parent, ccbReader) {
+ return new cc.ParticleSystem();
+ },
+
+ onHandlePropTypeIntegerLabeled:function (node, parent, propertyName, integerLabeled, ccbReader) {
+ if (propertyName === PROPERTY_EMITERMODE) {
+ node.setEmitterMode(integerLabeled);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeIntegerLabeled.call(this, node, parent, propertyName, integerLabeled, ccbReader);
+ }
+ },
+ onHandlePropTypePoint:function (node, parent, propertyName, point, ccbReader) {
+ if (propertyName === PROPERTY_POSVAR) {
+ node.setPosVar(point);
+ } else if (propertyName === PROPERTY_GRAVITY) {
+ node.setGravity(point);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypePoint.call(this, node, parent, propertyName, point, ccbReader);
+ }
+ },
+ onHandlePropTypeFloat:function (node, parent, propertyName, floatValue, ccbReader) {
+ if (propertyName === PROPERTY_EMISSIONRATE) {
+ node.setEmissionRate(floatValue);
+ } else if (propertyName === PROPERTY_DURATION) {
+ node.setDuration(floatValue);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeFloat.call(this, node, parent, propertyName, floatValue, ccbReader);
+ }
+ },
+ onHandlePropTypeInteger:function (node, parent, propertyName, integerValue, ccbReader) {
+ if (propertyName === PROPERTY_TOTALPARTICLES) {
+ node.setTotalParticles(integerValue);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeInteger.call(this, node, parent, propertyName, integerValue, ccbReader);
+ }
+ },
+ onHandlePropTypeFloatVar:function (node, parent, propertyName, floatVar, ccbReader) {
+ if (propertyName === PROPERTY_LIFE) {
+ node.setLife(floatVar[0]);
+ node.setLifeVar(floatVar[1]);
+ } else if (propertyName === PROPERTY_STARTSIZE) {
+ node.setStartSize(floatVar[0]);
+ node.setStartSizeVar(floatVar[1]);
+ } else if (propertyName === PROPERTY_ENDSIZE) {
+ node.setEndSize(floatVar[0]);
+ node.setEndSizeVar(floatVar[1]);
+ } else if (propertyName === PROPERTY_STARTSPIN) {
+ node.setStartSpin(floatVar[0]);
+ node.setStartSpinVar(floatVar[1]);
+ } else if (propertyName === PROPERTY_ENDSPIN) {
+ node.setEndSpin(floatVar[0]);
+ node.setEndSpinVar(floatVar[1]);
+ } else if (propertyName === PROPERTY_ANGLE) {
+ node.setAngle(floatVar[0]);
+ node.setAngleVar(floatVar[1]);
+ } else if (propertyName === PROPERTY_SPEED) {
+ node.setSpeed(floatVar[0]);
+ node.setSpeedVar(floatVar[1]);
+ } else if (propertyName === PROPERTY_TANGENTIALACCEL) {
+ node.setTangentialAccel(floatVar[0]);
+ node.setTangentialAccelVar(floatVar[1]);
+ } else if (propertyName === PROPERTY_RADIALACCEL) {
+ node.setRadialAccel(floatVar[0]);
+ node.setRadialAccelVar(floatVar[1]);
+ } else if (propertyName === PROPERTY_STARTRADIUS) {
+ node.setStartRadius(floatVar[0]);
+ node.setStartRadiusVar(floatVar[1]);
+ } else if (propertyName === PROPERTY_ENDRADIUS) {
+ node.setEndRadius(floatVar[0]);
+ node.setEndRadiusVar(floatVar[1]);
+ } else if (propertyName === PROPERTY_ROTATEPERSECOND) {
+ node.setRotatePerSecond(floatVar[0]);
+ node.setRotatePerSecondVar(floatVar[1]);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeFloatVar.call(this, node, parent, propertyName, floatVar, ccbReader);
+ }
+ },
+ onHandlePropTypeColor4FVar:function (node, parent, propertyName, ccColor4FVar, ccbReader) {
+ if (propertyName === PROPERTY_STARTCOLOR) {
+ node.setStartColor(ccColor4FVar[0]);
+ node.setStartColorVar(ccColor4FVar[1]);
+ } else if (propertyName === PROPERTY_ENDCOLOR) {
+ node.setEndColor(ccColor4FVar[0]);
+ node.setEndColorVar(ccColor4FVar[1]);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeColor4FVar.call(this, node, parent, propertyName, ccColor4FVar, ccbReader);
+ }
+ },
+ onHandlePropTypeBlendFunc:function (node, parent, propertyName, ccBlendFunc, ccbReader) {
+ if (propertyName === PROPERTY_BLENDFUNC) {
+ node.setBlendFunc(ccBlendFunc);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeBlendFunc.call(this, node, parent, propertyName, ccBlendFunc, ccbReader);
+ }
+ },
+ onHandlePropTypeTexture:function (node, parent, propertyName, ccTexture2D, ccbReader) {
+ if (propertyName === PROPERTY_TEXTURE) {
+ node.setTexture(ccTexture2D);
+ } else {
+ cc.NodeLoader.prototype.onHandlePropTypeTexture.call(this, node, parent, propertyName, ccTexture2D, ccbReader);
+ }
+ }
+});
+
+cc.ParticleSystemLoader.loader = function () {
+ return new cc.ParticleSystemLoader();
+};
+
+
+
+
+
+
+
diff --git a/frameworks/cocos2d-html5/extensions/ccpool/CCPool.js b/frameworks/cocos2d-html5/extensions/ccpool/CCPool.js
new file mode 100644
index 0000000..2159c09
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccpool/CCPool.js
@@ -0,0 +1,146 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ *
+ * cc.pool is a singleton object serves as an object cache pool.
+ * It can helps you to improve your game performance for objects which need frequent release and recreate operations
+ * Some common use case is :
+ * 1. Bullets in game (die very soon, massive creation and recreation, no side effect on other objects)
+ * 2. Blocks in candy crash (massive creation and recreation)
+ * etc...
+ *
+ *
+ * @example
+ * var sp = new cc.Sprite("a.png");
+ * this.addChild(sp);
+ * cc.pool.putInPool(sp);
+ *
+ * cc.pool.getFromPool(cc.Sprite, "a.png");
+ * @class
+ * @name cc.pool
+ */
+cc.pool = /** @lends cc.pool# */{
+ _pool: {},
+
+ _releaseCB: function () {
+ this.release();
+ },
+
+ _autoRelease: function (obj) {
+ var running = obj._running === undefined ? false : !obj._running;
+ cc.director.getScheduler().schedule(this._releaseCB, obj, 0, 0, 0, running)
+ },
+
+ /**
+ * Put the obj in pool
+ * @param obj
+ */
+ putInPool: function (obj) {
+ var pid = obj.constructor.prototype['__pid'];
+ if (!pid) {
+ var desc = {writable: true, enumerable: false, configurable: true};
+ desc.value = ClassManager.getNewID();
+ Object.defineProperty(obj.constructor.prototype, '__pid', desc);
+ }
+ if (!this._pool[pid]) {
+ this._pool[pid] = [];
+ }
+ // JSB retain to avoid being auto released
+ obj.retain && obj.retain();
+ // User implementation for disable the object
+ obj.unuse && obj.unuse();
+ this._pool[pid].push(obj);
+ },
+
+ /**
+ * Check if this kind of obj has already in pool
+ * @param objClass
+ * @returns {boolean} if this kind of obj is already in pool return true,else return false;
+ */
+ hasObject: function (objClass) {
+ var pid = objClass.prototype['__pid'];
+ var list = this._pool[pid];
+ if (!list || list.length === 0) {
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * Remove the obj if you want to delete it;
+ * @param obj
+ */
+ removeObject: function (obj) {
+ var pid = obj.constructor.prototype['__pid'];
+ if (pid) {
+ var list = this._pool[pid];
+ if (list) {
+ for (var i = 0; i < list.length; i++) {
+ if (obj === list[i]) {
+ // JSB release to avoid memory leak
+ obj.release && obj.release();
+ list.splice(i, 1);
+ }
+ }
+ }
+ }
+ },
+
+ /**
+ * Get the obj from pool
+ * @param args
+ * @returns {*} call the reuse function an return the obj
+ */
+ getFromPool: function (objClass/*,args*/) {
+ if (this.hasObject(objClass)) {
+ var pid = objClass.prototype['__pid'];
+ var list = this._pool[pid];
+ var args = Array.prototype.slice.call(arguments);
+ args.shift();
+ var obj = list.pop();
+ // User implementation for re-enable the object
+ obj.reuse && obj.reuse.apply(obj, args);
+ // JSB release to avoid memory leak
+ cc.sys.isNative && obj.release && this._autoRelease(obj);
+ return obj;
+ }
+ },
+
+ /**
+ * remove all objs in pool and reset the pool
+ */
+ drainAllPools: function () {
+ for (var i in this._pool) {
+ for (var j = 0; j < this._pool[i].length; j++) {
+ var obj = this._pool[i][j];
+ // JSB release to avoid memory leak
+ obj.release && obj.release();
+ }
+ }
+ this._pool = {};
+ }
+};
diff --git a/frameworks/cocos2d-html5/extensions/ccui/base-classes/CCProtectedNode.js b/frameworks/cocos2d-html5/extensions/ccui/base-classes/CCProtectedNode.js
new file mode 100644
index 0000000..1925572
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/base-classes/CCProtectedNode.js
@@ -0,0 +1,305 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * A class inhert from cc.Node, use for saving some protected children in other list.
+ * @class
+ * @extends cc.Node
+ */
+cc.ProtectedNode = cc.Node.extend(/** @lends cc.ProtectedNode# */{
+ _protectedChildren: null,
+ _reorderProtectedChildDirty: false,
+
+ _insertProtectedChild: function (child, z) {
+ this._reorderProtectedChildDirty = true;
+ this._protectedChildren.push(child);
+ child._setLocalZOrder(z);
+ },
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @function
+ */
+ ctor: function () {
+ cc.Node.prototype.ctor.call(this);
+ this._protectedChildren = [];
+ },
+
+ visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
+
+ var renderer = cc.renderer;
+ var i, children = this._children, len = children.length, child;
+ var j, pChildren = this._protectedChildren, pLen = pChildren.length, pChild;
+
+ cmd.visit(parentCmd);
+
+ var locGrid = this.grid;
+ if (locGrid && locGrid._active)
+ locGrid.beforeDraw();
+
+ if (this._reorderChildDirty) this.sortAllChildren();
+ if (this._reorderProtectedChildDirty) this.sortAllProtectedChildren();
+
+ // draw children zOrder < 0
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder < 0) {
+ child.visit(this);
+ }
+ else {
+ break;
+ }
+ }
+ for (j = 0; j < pLen; j++) {
+ pChild = pChildren[j];
+ if (pChild && pChild._localZOrder < 0) {
+ cmd._changeProtectedChild(pChild);
+ pChild.visit(this);
+ }
+ else
+ break;
+ }
+
+ renderer.pushRenderCommand(cmd);
+
+ for (; i < len; i++) {
+ children[i].visit(this);
+ }
+ for (; j < pLen; j++) {
+ pChild = pChildren[j];
+ if (!pChild) continue;
+ cmd._changeProtectedChild(pChild);
+ pChild.visit(this);
+ }
+
+ if (locGrid && locGrid._active)
+ locGrid.afterDraw(this);
+
+ cmd._dirtyFlag = 0;
+ },
+
+ /**
+ *
+ * Adds a child to the container with z order and tag
+ * If the child is added to a 'running' node, then 'onEnter' and 'onEnterTransitionDidFinish' will be called immediately.
+ *
+ * @param {cc.Node} child A child node
+ * @param {Number} [localZOrder] Z order for drawing priority. Please refer to `setLocalZOrder(int)`
+ * @param {Number} [tag] An integer to identify the node easily. Please refer to `setTag(int)`
+ */
+ addProtectedChild: function (child, localZOrder, tag) {
+ cc.assert(child != null, "child must be non-nil");
+ cc.assert(!child.parent, "child already added. It can't be added again");
+
+ localZOrder = localZOrder || child.getLocalZOrder();
+ if (tag)
+ child.setTag(tag);
+
+ this._insertProtectedChild(child, localZOrder);
+ child.setParent(this);
+ child.setOrderOfArrival(cc.s_globalOrderOfArrival);
+
+ if (this._running) {
+ child._performRecursive(cc.Node._stateCallbackType.onEnter);
+ // prevent onEnterTransitionDidFinish to be called twice when a node is added in onEnter
+ if (this._isTransitionFinished)
+ child._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
+ }
+ if (this._cascadeColorEnabled)
+ this._renderCmd.setCascadeColorEnabledDirty();
+ if (this._cascadeOpacityEnabled)
+ this._renderCmd.setCascadeOpacityEnabledDirty();
+ },
+
+ /**
+ * Gets a child from the container with its tag
+ * @param {Number} tag An identifier to find the child node.
+ * @return {cc.Node} a Node object whose tag equals to the input parameter
+ */
+ getProtectedChildByTag: function (tag) {
+ cc.assert(tag !== cc.NODE_TAG_INVALID, "Invalid tag");
+ var locChildren = this._protectedChildren;
+ for (var i = 0, len = locChildren.length; i < len; i++)
+ if (locChildren.getTag() === tag)
+ return locChildren[i];
+ return null;
+ },
+
+ /**
+ * Removes a child from the container. It will also cleanup all running actions depending on the cleanup parameter.
+ * @param {cc.Node} child The child node which will be removed.
+ * @param {Boolean} [cleanup=true] true if all running actions and callbacks on the child node will be cleanup, false otherwise.
+ */
+ removeProtectedChild: function (child, cleanup) {
+ if (cleanup == null)
+ cleanup = true;
+ var locChildren = this._protectedChildren;
+ if (locChildren.length === 0)
+ return;
+ var idx = locChildren.indexOf(child);
+ if (idx > -1) {
+ if (this._running) {
+ child._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ child._performRecursive(cc.Node._stateCallbackType.onExit);
+ }
+
+ // If you don't do cleanup, the child's actions will not get removed and the
+ // its scheduledSelectors_ dict will not get released!
+ if (cleanup)
+ child._performRecursive(cc.Node._stateCallbackType.cleanup);
+
+ // set parent nil at the end
+ child.setParent(null);
+ locChildren.splice(idx, 1);
+ }
+ },
+
+ /**
+ * Removes a child from the container by tag value.
+ * It will also cleanup all running actions depending on the cleanup parameter
+ * @param {Number} tag
+ * @param {Boolean} [cleanup=true]
+ */
+ removeProtectedChildByTag: function (tag, cleanup) {
+ cc.assert(tag !== cc.NODE_TAG_INVALID, "Invalid tag");
+
+ if (cleanup == null)
+ cleanup = true;
+
+ var child = this.getProtectedChildByTag(tag);
+
+ if (child == null)
+ cc.log("cocos2d: removeChildByTag(tag = %d): child not found!", tag);
+ else
+ this.removeProtectedChild(child, cleanup);
+ },
+
+ /**
+ * Removes all children from the container with a cleanup.
+ * @see cc.ProtectedNode#removeAllProtectedChildrenWithCleanup
+ */
+ removeAllProtectedChildren: function () {
+ this.removeAllProtectedChildrenWithCleanup(true);
+ },
+
+ /**
+ * Removes all children from the container, and do a cleanup to all running actions depending on the cleanup parameter.
+ * @param {Boolean} [cleanup=true] true if all running actions on all children nodes should be cleanup, false otherwise.
+ */
+ removeAllProtectedChildrenWithCleanup: function (cleanup) {
+ if (cleanup == null)
+ cleanup = true;
+ var locChildren = this._protectedChildren;
+ // not using detachChild improves speed here
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ var child = locChildren[i];
+ // IMPORTANT:
+ // -1st do onExit
+ // -2nd cleanup
+ if (this._running) {
+ child._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ child._performRecursive(cc.Node._stateCallbackType.onExit);
+ }
+
+ if (cleanup)
+ child._performRecursive(cc.Node._stateCallbackType.cleanup);
+ // set parent nil at the end
+ child.setParent(null);
+ }
+ locChildren.length = 0;
+ },
+
+ /**
+ * Reorders a child according to a new z value.
+ * @param {cc.Node} child An already added child node. It MUST be already added.
+ * @param {Number} localZOrder Z order for drawing priority. Please refer to setLocalZOrder(int)
+ */
+ reorderProtectedChild: function (child, localZOrder) {
+ cc.assert(child != null, "Child must be non-nil");
+ this._reorderProtectedChildDirty = true;
+ child.setOrderOfArrival(cc.s_globalOrderOfArrival++);
+ child._setLocalZOrder(localZOrder);
+ },
+
+ /**
+ *
+ * Sorts the children array once before drawing, instead of every time when a child is added or reordered.
+ * This approach can improves the performance massively.
+ * @note Don't call this manually unless a child added needs to be removed in the same frame
+ *
+ */
+ sortAllProtectedChildren: function () {
+ if (this._reorderProtectedChildDirty) {
+ var _children = this._protectedChildren;
+
+ // insertion sort
+ var i, j, len = _children.length, tmp;
+ for (i = 1; i < len; i++) {
+ tmp = _children[i];
+ j = i - 1;
+
+ //continue moving element downwards while zOrder is smaller or when zOrder is the same but mutatedIndex is smaller
+ while (j >= 0) {
+ if (tmp._localZOrder < _children[j]._localZOrder) {
+ _children[j + 1] = _children[j];
+ } else if (tmp._localZOrder === _children[j]._localZOrder && tmp.arrivalOrder < _children[j].arrivalOrder) {
+ _children[j + 1] = _children[j];
+ } else
+ break;
+ j--;
+ }
+ _children[j + 1] = tmp;
+ }
+
+ //don't need to check children recursively, that's done in visit of each child
+ this._reorderProtectedChildDirty = false;
+ }
+ },
+
+ _changePosition: function () {
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new cc.ProtectedNode.CanvasRenderCmd(this);
+ else
+ return new cc.ProtectedNode.WebGLRenderCmd(this);
+ }
+});
+
+/**
+ * create a cc.ProtectedNode object;
+ * @deprecated since v3.0, please use new cc.ProtectedNode() instead.
+ * @return cc.ProtectedNode
+ */
+cc.ProtectedNode.create = function () {
+ return new cc.ProtectedNode();
+};
diff --git a/frameworks/cocos2d-html5/extensions/ccui/base-classes/CCProtectedNodeCanvasRenderCmd.js b/frameworks/cocos2d-html5/extensions/ccui/base-classes/CCProtectedNodeCanvasRenderCmd.js
new file mode 100644
index 0000000..1ae8b1e
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/base-classes/CCProtectedNodeCanvasRenderCmd.js
@@ -0,0 +1,169 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ cc.ProtectedNode.RenderCmd = {
+ _updateDisplayColor: function (parentColor) {
+ var node = this._node;
+ var locDispColor = this._displayedColor, locRealColor = node._realColor;
+ var i, len, selChildren, item;
+ if (this._cascadeColorEnabledDirty && !node._cascadeColorEnabled) {
+ locDispColor.r = locRealColor.r;
+ locDispColor.g = locRealColor.g;
+ locDispColor.b = locRealColor.b;
+ var whiteColor = new cc.Color(255, 255, 255, 255);
+ selChildren = node._children;
+ for (i = 0, len = selChildren.length; i < len; i++) {
+ item = selChildren[i];
+ if (item && item._renderCmd)
+ item._renderCmd._updateDisplayColor(whiteColor);
+ }
+ this._cascadeColorEnabledDirty = false;
+ } else {
+ if (parentColor === undefined) {
+ var locParent = node._parent;
+ if (locParent && locParent._cascadeColorEnabled)
+ parentColor = locParent.getDisplayedColor();
+ else
+ parentColor = cc.color.WHITE;
+ }
+ locDispColor.r = 0 | (locRealColor.r * parentColor.r / 255.0);
+ locDispColor.g = 0 | (locRealColor.g * parentColor.g / 255.0);
+ locDispColor.b = 0 | (locRealColor.b * parentColor.b / 255.0);
+ if (node._cascadeColorEnabled) {
+ selChildren = node._children;
+ for (i = 0, len = selChildren.length; i < len; i++) {
+ item = selChildren[i];
+ if (item && item._renderCmd) {
+ item._renderCmd._updateDisplayColor(locDispColor);
+ item._renderCmd._updateColor();
+ }
+ }
+ }
+ selChildren = node._protectedChildren;
+ for (i = 0, len = selChildren.length; i < len; i++) {
+ item = selChildren[i];
+ if (item && item._renderCmd) {
+ item._renderCmd._updateDisplayColor(locDispColor);
+ item._renderCmd._updateColor();
+ }
+ }
+ }
+ this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.colorDirty ^ this._dirtyFlag;
+ },
+
+ _updateDisplayOpacity: function (parentOpacity) {
+ var node = this._node;
+ var i, len, selChildren, item;
+ if (this._cascadeOpacityEnabledDirty && !node._cascadeOpacityEnabled) {
+ this._displayedOpacity = node._realOpacity;
+ selChildren = node._children;
+ for (i = 0, len = selChildren.length; i < len; i++) {
+ item = selChildren[i];
+ if (item && item._renderCmd)
+ item._renderCmd._updateDisplayOpacity(255);
+ }
+ this._cascadeOpacityEnabledDirty = false;
+ } else {
+ if (parentOpacity === undefined) {
+ var locParent = node._parent;
+ parentOpacity = 255;
+ if (locParent && locParent._cascadeOpacityEnabled)
+ parentOpacity = locParent.getDisplayedOpacity();
+ }
+ this._displayedOpacity = node._realOpacity * parentOpacity / 255.0;
+ if (node._cascadeOpacityEnabled) {
+ selChildren = node._children;
+ for (i = 0, len = selChildren.length; i < len; i++) {
+ item = selChildren[i];
+ if (item && item._renderCmd) {
+ item._renderCmd._updateDisplayOpacity(this._displayedOpacity);
+ item._renderCmd._updateColor();
+ }
+ }
+ }
+ selChildren = node._protectedChildren;
+ for (i = 0, len = selChildren.length; i < len; i++) {
+ item = selChildren[i];
+ if (item && item._renderCmd) {
+ item._renderCmd._updateDisplayOpacity(this._displayedOpacity);
+ item._renderCmd._updateColor();
+ }
+ }
+ }
+ this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.opacityDirty ^ this._dirtyFlag;
+ },
+
+ _changeProtectedChild: function (child) {
+ var cmd = child._renderCmd,
+ dirty = cmd._dirtyFlag,
+ flags = cc.Node._dirtyFlags;
+
+ if (this._dirtyFlag & flags.colorDirty)
+ dirty |= flags.colorDirty;
+
+ if (this._dirtyFlag & flags.opacityDirty)
+ dirty |= flags.opacityDirty;
+
+ var colorDirty = dirty & flags.colorDirty,
+ opacityDirty = dirty & flags.opacityDirty;
+
+ if (colorDirty)
+ cmd._updateDisplayColor(this._displayedColor);
+ if (opacityDirty)
+ cmd._updateDisplayOpacity(this._displayedOpacity);
+ if (colorDirty || opacityDirty)
+ cmd._updateColor();
+ }
+ };
+
+ cc.ProtectedNode.CanvasRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._cachedParent = null;
+ this._cacheDirty = false;
+ };
+
+ var proto = cc.ProtectedNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ cc.inject(cc.ProtectedNode.RenderCmd, proto);
+ proto.constructor = cc.ProtectedNode.CanvasRenderCmd;
+ proto._pNodeCmdCtor = cc.ProtectedNode.CanvasRenderCmd;
+
+ proto.transform = function (parentCmd, recursive) {
+ var node = this._node;
+
+ if (node._changePosition)
+ node._changePosition();
+
+ this.originTransform(parentCmd, recursive);
+
+ var i, len, locChildren = node._protectedChildren;
+ if (recursive && locChildren && locChildren.length !== 0) {
+ for (i = 0, len = locChildren.length; i < len; i++) {
+ locChildren[i]._renderCmd.transform(this, recursive);
+ }
+ }
+ };
+
+ proto.pNodeTransform = proto.transform;
+})();
diff --git a/frameworks/cocos2d-html5/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js b/frameworks/cocos2d-html5/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js
new file mode 100644
index 0000000..b22907d
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js
@@ -0,0 +1,50 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ if (!cc.Node.WebGLRenderCmd)
+ return;
+ cc.ProtectedNode.WebGLRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ };
+
+ var proto = cc.ProtectedNode.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ cc.inject(cc.ProtectedNode.RenderCmd, proto);
+ proto.constructor = cc.ProtectedNode.WebGLRenderCmd;
+ proto._pNodeCmdCtor = cc.ProtectedNode.WebGLRenderCmd;
+
+ proto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
+
+ var i, len,
+ locChildren = this._node._protectedChildren;
+ if (recursive && locChildren && locChildren.length !== 0) {
+ for (i = 0, len = locChildren.length; i < len; i++) {
+ locChildren[i]._renderCmd.transform(this, recursive);
+ }
+ }
+ };
+
+ proto.pNodeTransform = proto.transform;
+})();
diff --git a/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIScale9Sprite.js b/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIScale9Sprite.js
new file mode 100644
index 0000000..95df94c
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIScale9Sprite.js
@@ -0,0 +1,936 @@
+/* global ccui */
+
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2012 Neofect. All rights reserved.
+ Copyright (c) 2016 zilongshanren. All rights reserved.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+ Created by Jung Sang-Taik on 2012-03-16
+ ****************************************************************************/
+(function () {
+
+var dataPool = {
+ _pool: {},
+ _lengths: [],
+ put: function (data) {
+ var length = data.length;
+ if (!this._pool[length]) {
+ this._pool[length] = [data];
+ this._lengths.push(length);
+ this._lengths.sort();
+ }
+ else {
+ this._pool[length].push(data);
+ }
+ },
+ get: function (length) {
+ var id;
+ for (var i = 0; i < this._lengths.length; i++) {
+ if (this._lengths[i] >= length) {
+ id = this._lengths[i];
+ break;
+ }
+ }
+ if (id) {
+ return this._pool[id].pop();
+ }
+ else {
+ return undefined;
+ }
+ }
+};
+
+var FIX_ARTIFACTS_BY_STRECHING_TEXEL = cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL, cornerId = [], webgl;
+
+
+var simpleQuadGenerator = {
+ _rebuildQuads_base: function (sprite, spriteFrame, contentSize, isTrimmedContentSize) {
+ //build vertices
+ var vertices = sprite._vertices,
+ wt = sprite._renderCmd._worldTransform,
+ l, b, r, t;
+ if (isTrimmedContentSize) {
+ l = 0;
+ b = 0;
+ r = contentSize.width;
+ t = contentSize.height;
+ } else {
+ var originalSize = spriteFrame._originalSize;
+ var rect = spriteFrame._rect;
+ var offset = spriteFrame._offset;
+ var scaleX = contentSize.width / originalSize.width;
+ var scaleY = contentSize.height / originalSize.height;
+ var trimmLeft = offset.x + (originalSize.width - rect.width) / 2;
+ var trimmRight = offset.x - (originalSize.width - rect.width) / 2;
+ var trimmedBottom = offset.y + (originalSize.height - rect.height) / 2;
+ var trimmedTop = offset.y - (originalSize.height - rect.height) / 2;
+
+ l = trimmLeft * scaleX;
+ b = trimmedBottom * scaleY;
+ r = contentSize.width + trimmRight * scaleX;
+ t = contentSize.height + trimmedTop * scaleY;
+ }
+
+ if (vertices.length < 8) {
+ dataPool.put(vertices);
+ vertices = dataPool.get(8) || new Float32Array(8);
+ sprite._vertices = vertices;
+ }
+ // bl, br, tl, tr
+ if (webgl) {
+ vertices[0] = l * wt.a + b * wt.c + wt.tx;
+ vertices[1] = l * wt.b + b * wt.d + wt.ty;
+ vertices[2] = r * wt.a + b * wt.c + wt.tx;
+ vertices[3] = r * wt.b + b * wt.d + wt.ty;
+ vertices[4] = l * wt.a + t * wt.c + wt.tx;
+ vertices[5] = l * wt.b + t * wt.d + wt.ty;
+ vertices[6] = r * wt.a + t * wt.c + wt.tx;
+ vertices[7] = r * wt.b + t * wt.d + wt.ty;
+ }
+ else {
+ vertices[0] = l;
+ vertices[1] = b;
+ vertices[2] = r;
+ vertices[3] = b;
+ vertices[4] = l;
+ vertices[5] = t;
+ vertices[6] = r;
+ vertices[7] = t;
+ }
+
+ cornerId[0] = 0;
+ cornerId[1] = 2;
+ cornerId[2] = 4;
+ cornerId[3] = 6;
+
+ //build uvs
+ if (sprite._uvsDirty) {
+ this._calculateUVs(sprite, spriteFrame);
+ }
+
+ sprite._vertCount = 4;
+ },
+
+ _calculateUVs: function (sprite, spriteFrame) {
+ var uvs = sprite._uvs;
+ var atlasWidth = spriteFrame._texture._pixelsWide;
+ var atlasHeight = spriteFrame._texture._pixelsHigh;
+ var textureRect = spriteFrame._rect;
+ textureRect = cc.rectPointsToPixels(textureRect);
+
+ if (uvs.length < 8) {
+ dataPool.put(uvs);
+ uvs = dataPool.get(8) || new Float32Array(8);
+ sprite._uvs = uvs;
+ }
+
+ //uv computation should take spritesheet into account.
+ var l, b, r, t;
+ var texelCorrect = FIX_ARTIFACTS_BY_STRECHING_TEXEL ? 0.5 : 0;
+
+ if (spriteFrame._rotated) {
+ l = (textureRect.x + texelCorrect) / atlasWidth;
+ b = (textureRect.y + textureRect.width - texelCorrect) / atlasHeight;
+ r = (textureRect.x + textureRect.height - texelCorrect) / atlasWidth;
+ t = (textureRect.y + texelCorrect) / atlasHeight;
+ uvs[0] = l; uvs[1] = t;
+ uvs[2] = l; uvs[3] = b;
+ uvs[4] = r; uvs[5] = t;
+ uvs[6] = r; uvs[7] = b;
+ }
+ else {
+ l = (textureRect.x + texelCorrect) / atlasWidth;
+ b = (textureRect.y + textureRect.height - texelCorrect) / atlasHeight;
+ r = (textureRect.x + textureRect.width - texelCorrect) / atlasWidth;
+ t = (textureRect.y + texelCorrect) / atlasHeight;
+ uvs[0] = l; uvs[1] = b;
+ uvs[2] = r; uvs[3] = b;
+ uvs[4] = l; uvs[5] = t;
+ uvs[6] = r; uvs[7] = t;
+ }
+ }
+};
+
+var scale9QuadGenerator = {
+ x: new Array(4),
+ y: new Array(4),
+ _rebuildQuads_base: function (sprite, spriteFrame, contentSize, insetLeft, insetRight, insetTop, insetBottom) {
+ //build vertices
+ var vertices = sprite._vertices;
+ var wt = sprite._renderCmd._worldTransform;
+ var leftWidth, centerWidth, rightWidth;
+ var topHeight, centerHeight, bottomHeight;
+ var rect = spriteFrame._rect;
+
+ leftWidth = insetLeft;
+ rightWidth = insetRight;
+ centerWidth = rect.width - leftWidth - rightWidth;
+ topHeight = insetTop;
+ bottomHeight = insetBottom;
+ centerHeight = rect.height - topHeight - bottomHeight;
+
+ var preferSize = contentSize;
+ var sizableWidth = preferSize.width - leftWidth - rightWidth;
+ var sizableHeight = preferSize.height - topHeight - bottomHeight;
+ var xScale = preferSize.width / (leftWidth + rightWidth);
+ var yScale = preferSize.height / (topHeight + bottomHeight);
+ xScale = xScale > 1 ? 1 : xScale;
+ yScale = yScale > 1 ? 1 : yScale;
+ sizableWidth = sizableWidth < 0 ? 0 : sizableWidth;
+ sizableHeight = sizableHeight < 0 ? 0 : sizableHeight;
+ var x = this.x;
+ var y = this.y;
+ x[0] = 0;
+ x[1] = leftWidth * xScale;
+ x[2] = x[1] + sizableWidth;
+ x[3] = preferSize.width;
+ y[0] = 0;
+ y[1] = bottomHeight * yScale;
+ y[2] = y[1] + sizableHeight;
+ y[3] = preferSize.height;
+
+ if (vertices.length < 32) {
+ dataPool.put(vertices);
+ vertices = dataPool.get(32) || new Float32Array(32);
+ sprite._vertices = vertices;
+ }
+ var offset = 0, row, col;
+ if (webgl) {
+ for (row = 0; row < 4; row++) {
+ for (col = 0; col < 4; col++) {
+ vertices[offset] = x[col] * wt.a + y[row] * wt.c + wt.tx;
+ vertices[offset+1] = x[col] * wt.b + y[row] * wt.d + wt.ty;
+ offset += 2;
+ }
+ }
+ }
+ else {
+ for (row = 0; row < 4; row++) {
+ for (col = 0; col < 4; col++) {
+ vertices[offset] = x[col];
+ vertices[offset+1] = y[row];
+ offset += 2;
+ }
+ }
+ }
+
+ cornerId[0] = 0;
+ cornerId[1] = 6;
+ cornerId[2] = 24;
+ cornerId[3] = 30;
+
+ //build uvs
+ if (sprite._uvsDirty) {
+ this._calculateUVs(sprite, spriteFrame, insetLeft, insetRight, insetTop, insetBottom);
+ }
+ },
+
+ _calculateUVs: function (sprite, spriteFrame, insetLeft, insetRight, insetTop, insetBottom) {
+ var uvs = sprite._uvs;
+ var rect = spriteFrame._rect;
+ var atlasWidth = spriteFrame._texture._pixelsWide;
+ var atlasHeight = spriteFrame._texture._pixelsHigh;
+
+ //caculate texture coordinate
+ var leftWidth, centerWidth, rightWidth;
+ var topHeight, centerHeight, bottomHeight;
+ var textureRect = spriteFrame._rect;
+ textureRect = cc.rectPointsToPixels(textureRect);
+ rect = cc.rectPointsToPixels(rect);
+ var scale = cc.contentScaleFactor();
+
+ leftWidth = insetLeft * scale;
+ rightWidth = insetRight * scale;
+ centerWidth = rect.width - leftWidth - rightWidth;
+ topHeight = insetTop * scale;
+ bottomHeight = insetBottom * scale;
+ centerHeight = rect.height - topHeight - bottomHeight;
+
+ if (uvs.length < 32) {
+ dataPool.put(uvs);
+ uvs = dataPool.get(32) || new Float32Array(32);
+ sprite._uvs = uvs;
+ }
+
+ //uv computation should take spritesheet into account.
+ var u = this.x;
+ var v = this.y;
+ var texelCorrect = FIX_ARTIFACTS_BY_STRECHING_TEXEL ? 0.5 : 0;
+ var offset = 0, row, col;
+
+ if (spriteFrame._rotated) {
+ u[0] = (textureRect.x + texelCorrect) / atlasWidth;
+ u[1] = (bottomHeight + textureRect.x) / atlasWidth;
+ u[2] = (bottomHeight + centerHeight + textureRect.x) / atlasWidth;
+ u[3] = (textureRect.x + textureRect.height - texelCorrect) / atlasWidth;
+
+ v[3] = (textureRect.y + texelCorrect) / atlasHeight;
+ v[2] = (leftWidth + textureRect.y) / atlasHeight;
+ v[1] = (leftWidth + centerWidth + textureRect.y) / atlasHeight;
+ v[0] = (textureRect.y + textureRect.width - texelCorrect) / atlasHeight;
+
+ for (row = 0; row < 4; row++) {
+ for (col = 0; col < 4; col++) {
+ uvs[offset] = u[row];
+ uvs[offset+1] = v[3-col];
+ offset += 2;
+ }
+ }
+ }
+ else {
+ u[0] = (textureRect.x + texelCorrect) / atlasWidth;
+ u[1] = (leftWidth + textureRect.x) / atlasWidth;
+ u[2] = (leftWidth + centerWidth + textureRect.x) / atlasWidth;
+ u[3] = (textureRect.x + textureRect.width - texelCorrect) / atlasWidth;
+
+ v[3] = (textureRect.y + texelCorrect) / atlasHeight;
+ v[2] = (topHeight + textureRect.y) / atlasHeight;
+ v[1] = (topHeight + centerHeight + textureRect.y) / atlasHeight;
+ v[0] = (textureRect.y + textureRect.height - texelCorrect) / atlasHeight;
+
+ for (row = 0; row < 4; row++) {
+ for (col = 0; col < 4; col++) {
+ uvs[offset] = u[col];
+ uvs[offset+1] = v[row];
+ offset += 2;
+ }
+ }
+ }
+ }
+};
+
+/**
+ *
+ * A 9-slice sprite for cocos2d UI.
+ *
+ * 9-slice scaling allows you to specify how scaling is applied
+ * to specific areas of a sprite. With 9-slice scaling (3x3 grid),
+ * you can ensure that the sprite does not become distorted when
+ * scaled.
+ * @see http://yannickloriot.com/library/ios/cccontrolextension/Classes/CCScale9Sprite.html
+ *
+ * @class
+ * @extends cc.Node
+ *
+ * @property {cc.Size} preferredSize - The preferred size of the 9-slice sprite
+ * @property {cc.Rect} capInsets - The cap insets of the 9-slice sprite
+ * @property {Number} insetLeft - The left inset of the 9-slice sprite
+ * @property {Number} insetTop - The top inset of the 9-slice sprite
+ * @property {Number} insetRight - The right inset of the 9-slice sprite
+ * @property {Number} insetBottom - The bottom inset of the 9-slice sprite
+ */
+
+ccui.Scale9Sprite = cc.Scale9Sprite = cc.Node.extend(/** @lends ccui.Scale9Sprite# */{
+ //resource data, could be async loaded.
+ _spriteFrame: null,
+ _scale9Image: null,
+
+ //scale 9 data
+ _insetLeft: 0,
+ _insetRight: 0,
+ _insetTop: 0,
+ _insetBottom: 0,
+ //blend function
+ _blendFunc: null,
+ //sliced or simple
+ _renderingType: 1,
+ //bright or not
+ _brightState: 0,
+ _opacityModifyRGB: false,
+ //rendering quads shared by canvas and webgl
+ _rawVerts: null,
+ _rawUvs: null,
+ _vertices: null,
+ _uvs: null,
+ _vertCount: 0,
+ _quadsDirty: true,
+ _uvsDirty: true,
+ _isTriangle: false,
+ _isTrimmedContentSize: false,
+ _textureLoaded: false,
+
+ //v3.3
+ _flippedX: false,
+ _flippedY: false,
+ _className: "Scale9Sprite",
+
+ /**
+ * Constructor function.
+ * @function
+ * @param {string|cc.SpriteFrame} file file name of texture or a SpriteFrame
+ * @param {cc.Rect} rectOrCapInsets
+ * @param {cc.Rect} capInsets
+ * @returns {Scale9Sprite}
+ */
+ ctor: function (file, rectOrCapInsets, capInsets) {
+ cc.Node.prototype.ctor.call(this);
+
+ //for async texture load
+ this._loader = new cc.Sprite.LoadManager();
+
+ this._renderCmd.setState(this._brightState);
+ this._blendFunc = cc.BlendFunc._alphaPremultiplied();
+ this.setAnchorPoint(cc.p(0.5, 0.5));
+ // Init vertex data for simple
+ this._rawVerts = null;
+ this._rawUvs = null;
+ this._vertices = dataPool.get(8) || new Float32Array(8);
+ this._uvs = dataPool.get(8) || new Float32Array(8);
+
+ if (file !== undefined) {
+ if (file instanceof cc.SpriteFrame)
+ this.initWithSpriteFrame(file, rectOrCapInsets);
+ else {
+ var frame = cc.spriteFrameCache.getSpriteFrame(file);
+ if (frame)
+ this.initWithSpriteFrame(frame, rectOrCapInsets);
+ else
+ this.initWithFile(file, rectOrCapInsets, capInsets);
+ }
+ }
+
+
+ if (webgl === undefined) {
+ webgl = cc._renderType === cc.game.RENDER_TYPE_WEBGL;
+ }
+ },
+
+ textureLoaded: function () {
+ return this._textureLoaded;
+ },
+
+ getCapInsets: function () {
+ return cc.rect(this._capInsetsInternal);
+ },
+
+ _asyncSetCapInsets: function () {
+ this.removeEventListener('load', this._asyncSetCapInsets, this);
+ this.setCapInsets(this._cacheCapInsets);
+ this._cacheCapInsets = null;
+ },
+
+ setCapInsets: function (capInsets) {
+ // Asynchronous loading texture requires this data
+ // This data does not take effect immediately, so it does not affect the existing texture.
+ if (!this.loaded()) {
+ this._cacheCapInsets = capInsets;
+ this.removeEventListener('load', this._asyncSetCapInsets, this);
+ this.addEventListener('load', this._asyncSetCapInsets, this);
+ return false;
+ }
+
+ this._capInsetsInternal = capInsets;
+ this._updateCapInsets(this._spriteFrame._rect, this._capInsetsInternal);
+ },
+
+ _updateCapInsets: function (rect, capInsets) {
+ if(!capInsets || !rect || cc._rectEqualToZero(capInsets)) {
+ rect = rect || {x:0, y:0, width: this._contentSize.width, height: this._contentSize.height};
+ this._capInsetsInternal = cc.rect(rect.width /3,
+ rect.height /3,
+ rect.width /3,
+ rect.height /3);
+ } else {
+ this._capInsetsInternal = capInsets;
+ }
+
+ if(!cc._rectEqualToZero(rect)) {
+ this._insetLeft = this._capInsetsInternal.x;
+ this._insetTop = this._capInsetsInternal.y;
+ this._insetRight = rect.width - this._insetLeft - this._capInsetsInternal.width;
+ this._insetBottom = rect.height - this._insetTop - this._capInsetsInternal.height;
+ }
+ },
+
+
+ initWithFile: function (file, rect, capInsets) {
+ if (file instanceof cc.Rect) {
+ file = arguments[1];
+ capInsets = arguments[0];
+ rect = cc.rect(0, 0, 0, 0);
+ } else {
+ rect = rect || cc.rect(0, 0, 0, 0);
+ capInsets = capInsets || cc.rect(0, 0, 0, 0);
+ }
+
+ if(!file)
+ throw new Error("ccui.Scale9Sprite.initWithFile(): file should be non-null");
+
+ var texture = cc.textureCache.getTextureForKey(file);
+ if (!texture) {
+ texture = cc.textureCache.addImage(file);
+ }
+
+ var locLoaded = texture.isLoaded();
+ this._textureLoaded = locLoaded;
+ this._loader.clear();
+ if (!locLoaded) {
+ this._loader.once(texture, function () {
+ this.initWithFile(file, rect, capInsets);
+ this.dispatchEvent("load");
+ }, this);
+ return false;
+ }
+
+ //in this function, the texture already make sure is loaded.
+ if( cc._rectEqualToZero(rect)) {
+ var textureSize = texture.getContentSize();
+ rect = cc.rect(0, 0, textureSize.width, textureSize.height);
+ }
+ this.setTexture(texture, rect);
+ this._updateCapInsets(rect, capInsets);
+
+ return true;
+ },
+
+ updateWithBatchNode: function (batchNode, originalRect, rotated, capInsets) {
+ if (!batchNode) {
+ return false;
+ }
+
+ var texture = batchNode.getTexture();
+ this._loader.clear();
+ if (!texture.isLoaded()) {
+ this._loader.once(texture, function () {
+ this.updateWithBatchNode(batchNode, originalRect, rotated, capInsets);
+ this.dispatchEvent("load");
+ }, this);
+ return false;
+ }
+
+ this.setTexture(texture, originalRect);
+ this._updateCapInsets(originalRect, capInsets);
+
+ return true;
+ },
+
+
+ /**
+ * Initializes a 9-slice sprite with an sprite frame
+ * @param spriteFrameOrSFName The sprite frame object.
+ */
+ initWithSpriteFrame: function (spriteFrame, capInsets) {
+ this.setSpriteFrame(spriteFrame);
+
+ capInsets = capInsets || cc.rect(0, 0, 0, 0);
+
+ this._updateCapInsets(spriteFrame._rect, capInsets);
+ },
+
+ initWithSpriteFrameName: function (spriteFrameName, capInsets) {
+ if(!spriteFrameName)
+ throw new Error("ccui.Scale9Sprite.initWithSpriteFrameName(): spriteFrameName should be non-null");
+ capInsets = capInsets || cc.rect(0, 0, 0, 0);
+
+ var frame = cc.spriteFrameCache.getSpriteFrame(spriteFrameName);
+ if (frame == null) {
+ cc.log("ccui.Scale9Sprite.initWithSpriteFrameName(): can't find the sprite frame by spriteFrameName");
+ return false;
+ }
+ this.setSpriteFrame(frame);
+
+ capInsets = capInsets || cc.rect(0, 0, 0, 0);
+
+ this._updateCapInsets(frame._rect, capInsets);
+ },
+
+ loaded: function () {
+ if (this._spriteFrame === null) {
+ return false;
+ } else {
+ return this._spriteFrame.textureLoaded();
+ }
+ },
+
+ /**
+ * Change the texture file of 9 slice sprite
+ *
+ * @param textureOrTextureFile The name of the texture file.
+ */
+ setTexture: function (texture, rect) {
+ var spriteFrame = new cc.SpriteFrame(texture, rect);
+ this.setSpriteFrame(spriteFrame);
+ },
+
+ _updateBlendFunc: function () {
+ // it's possible to have an untextured sprite
+ var blendFunc = this._blendFunc;
+ if (!this._spriteFrame || !this._spriteFrame._texture.hasPremultipliedAlpha()) {
+ if (blendFunc.src === cc.ONE && blendFunc.dst === cc.BLEND_DST) {
+ blendFunc.src = cc.SRC_ALPHA;
+ }
+ this._opacityModifyRGB = false;
+ } else {
+ if (blendFunc.src === cc.SRC_ALPHA && blendFunc.dst === cc.BLEND_DST) {
+ blendFunc.src = cc.ONE;
+ }
+ this._opacityModifyRGB = true;
+ }
+ },
+
+ setOpacityModifyRGB: function (value) {
+ if (this._opacityModifyRGB !== value) {
+ this._opacityModifyRGB = value;
+ this._renderCmd._setColorDirty();
+ }
+ },
+
+ isOpacityModifyRGB: function () {
+ return this._opacityModifyRGB;
+ },
+
+ /**
+ * Change the sprite frame of 9 slice sprite
+ *
+ * @param spriteFrameOrSFFileName The name of the texture file.
+ */
+ setSpriteFrame: function (spriteFrame) {
+ if (spriteFrame) {
+ this._spriteFrame = spriteFrame;
+ this._quadsDirty = true;
+ this._uvsDirty = true;
+ var self = this;
+ var onResourceDataLoaded = function () {
+ if (cc.sizeEqualToSize(self._contentSize, cc.size(0, 0))) {
+ self.setContentSize(self._spriteFrame._rect);
+ }
+ self._textureLoaded = true;
+ self._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.contentDirty);
+ cc.renderer.childrenOrderDirty = true;
+ };
+ self._textureLoaded = spriteFrame.textureLoaded();
+ if (self._textureLoaded) {
+ onResourceDataLoaded();
+ } else {
+ this._loader.clear();
+ this._loader.once(spriteFrame, function () {
+ onResourceDataLoaded();
+ this.dispatchEvent("load");
+ }, this);
+ }
+ }
+ },
+
+ /**
+ * Sets the source blending function.
+ *
+ * @param blendFunc A structure with source and destination factor to specify pixel arithmetic. e.g. {GL_ONE, GL_ONE}, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA}.
+ */
+ setBlendFunc: function (blendFunc, dst) {
+ if (dst === undefined) {
+ this._blendFunc.src = blendFunc.src || cc.BLEND_SRC;
+ this._blendFunc.dst = blendFunc.dst || cc.BLEND_DST;
+ }
+ else {
+ this._blendFunc.src = blendFunc || cc.BLEND_SRC;
+ this._blendFunc.dst = dst || cc.BLEND_DST;
+ }
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.contentDirty);
+ },
+
+ /**
+ * Returns the blending function that is currently being used.
+ *
+ * @return A BlendFunc structure with source and destination factor which specified pixel arithmetic.
+ */
+ getBlendFunc: function () {
+ return new cc.BlendFunc(this._blendFunc.src, this._blendFunc.dst);
+ },
+
+ setPreferredSize: function (preferredSize) {
+ if (!preferredSize || cc.sizeEqualToSize(this._contentSize, preferredSize)) return;
+ this.setContentSize(preferredSize);
+ },
+
+ getPreferredSize: function () {
+ return this.getContentSize();
+ },
+
+ // overrides
+ setContentSize: function (width, height) {
+ if (height === undefined) {
+ height = width.height;
+ width = width.width;
+ }
+ if (width === this._contentSize.width && height === this._contentSize.height) {
+ return;
+ }
+
+ cc.Node.prototype.setContentSize.call(this, width, height);
+ this._quadsDirty = true;
+ },
+
+ getContentSize: function () {
+ if(this._renderingType === ccui.Scale9Sprite.RenderingType.SIMPLE) {
+ if(this._spriteFrame) {
+ return this._spriteFrame._originalSize;
+ }
+ return cc.size(this._contentSize);
+ } else {
+ return cc.size(this._contentSize);
+ }
+ },
+
+ _setWidth: function (value) {
+ cc.Node.prototype._setWidth.call(this, value);
+ this._quadsDirty = true;
+ },
+
+ _setHeight: function (value) {
+ cc.Node.prototype._setHeight.call(this, value);
+ this._quadsDirty = true;
+ },
+
+ /**
+ * Change the state of 9-slice sprite.
+ * @see `State`
+ * @param state A enum value in State.
+ */
+ setState: function (state) {
+ this._brightState = state;
+ this._renderCmd.setState(state);
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.contentDirty);
+ },
+
+ /**
+ * Query the current bright state.
+ * @return @see `State`
+ */
+ getState: function () {
+ return this._brightState;
+ },
+
+ /**
+ * change the rendering type, could be simple or slice
+ * @return @see `RenderingType`
+ */
+ setRenderingType: function (type) {
+ if (this._renderingType === type) return;
+
+ this._renderingType = type;
+ this._quadsDirty = true;
+ this._uvsDirty = true;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.contentDirty);
+ },
+ /**
+ * get the rendering type, could be simple or slice
+ * @return @see `RenderingType`
+ */
+ getRenderingType: function () {
+ return this._renderingType;
+ },
+ /**
+ * change the left border of 9 slice sprite, it should be specified before trimmed.
+ * @param insetLeft left border.
+ */
+ setInsetLeft: function (insetLeft) {
+ this._insetLeft = insetLeft;
+ this._quadsDirty = true;
+ this._uvsDirty = true;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.contentDirty);
+ },
+ /**
+ * get the left border of 9 slice sprite, the result is specified before trimmed.
+ * @return left border.
+ */
+ getInsetLeft: function () {
+ return this._insetLeft;
+ },
+ /**
+ * change the top border of 9 slice sprite, it should be specified before trimmed.
+ * @param insetTop top border.
+ */
+ setInsetTop: function (insetTop) {
+ this._insetTop = insetTop;
+ this._quadsDirty = true;
+ this._uvsDirty = true;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.contentDirty);
+ },
+
+ /**
+ * get the top border of 9 slice sprite, the result is specified before trimmed.
+ * @return top border.
+ */
+ getInsetTop: function () {
+ return this._insetTop;
+ },
+
+ /**
+ * change the right border of 9 slice sprite, it should be specified before trimmed.
+ * @param insetRight right border.
+ */
+ setInsetRight: function (insetRight) {
+ this._insetRight = insetRight;
+ this._quadsDirty = true;
+ this._uvsDirty = true;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.contentDirty);
+ },
+
+ /**
+ * get the right border of 9 slice sprite, the result is specified before trimmed.
+ * @return right border.
+ */
+ getInsetRight: function () {
+ return this._insetRight;
+ },
+
+ /**
+ * change the bottom border of 9 slice sprite, it should be specified before trimmed.
+ * @param insetBottom bottom border.
+ */
+ setInsetBottom: function (insetBottom) {
+ this._insetBottom = insetBottom;
+ this._quadsDirty = true;
+ this._uvsDirty = true;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.contentDirty);
+ },
+ /**
+ * get the bottom border of 9 slice sprite, the result is specified before trimmed.
+ * @return bottom border.
+ */
+ getInsetBottom: function () {
+ return this._insetBottom;
+ },
+
+ _rebuildQuads: function () {
+ if (!this._spriteFrame || !this._spriteFrame._textureLoaded) {
+ return;
+ }
+
+ this._updateBlendFunc();
+
+ this._isTriangle = false;
+ switch (this._renderingType) {
+ case RenderingType.SIMPLE:
+ simpleQuadGenerator._rebuildQuads_base(this, this._spriteFrame, this._contentSize, this._isTrimmedContentSize);
+ break;
+ case RenderingType.SLICED:
+ scale9QuadGenerator._rebuildQuads_base(this, this._spriteFrame, this._contentSize, this._insetLeft, this._insetRight, this._insetTop, this._insetBottom);
+ break;
+ default:
+ this._quadsDirty = false;
+ this._uvsDirty = false;
+ cc.error('Can not generate quad');
+ return;
+ }
+
+
+ this._quadsDirty = false;
+ this._uvsDirty = false;
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new ccui.Scale9Sprite.CanvasRenderCmd(this);
+ else
+ return new ccui.Scale9Sprite.WebGLRenderCmd(this);
+ }
+});
+
+var _p = ccui.Scale9Sprite.prototype;
+cc.EventHelper.prototype.apply(_p);
+
+// Extended properties
+/** @expose */
+_p.preferredSize;
+cc.defineGetterSetter(_p, "preferredSize", _p.getPreferredSize, _p.setPreferredSize);
+/** @expose */
+_p.capInsets;
+cc.defineGetterSetter(_p, "capInsets", _p.getCapInsets, _p.setCapInsets);
+/** @expose */
+_p.insetLeft;
+cc.defineGetterSetter(_p, "insetLeft", _p.getInsetLeft, _p.setInsetLeft);
+/** @expose */
+_p.insetTop;
+cc.defineGetterSetter(_p, "insetTop", _p.getInsetTop, _p.setInsetTop);
+/** @expose */
+_p.insetRight;
+cc.defineGetterSetter(_p, "insetRight", _p.getInsetRight, _p.setInsetRight);
+/** @expose */
+_p.insetBottom;
+cc.defineGetterSetter(_p, "insetBottom", _p.getInsetBottom, _p.setInsetBottom);
+
+_p = null;
+
+/**
+ * Creates a 9-slice sprite with a texture file, a delimitation zone and
+ * with the specified cap insets.
+ * @deprecated since v3.0, please use new ccui.Scale9Sprite(file, rect, capInsets) instead.
+ * @param {String|cc.SpriteFrame} file file name of texture or a cc.Sprite object
+ * @param {cc.Rect} rect the rect of the texture
+ * @param {cc.Rect} capInsets the cap insets of ccui.Scale9Sprite
+ * @returns {ccui.Scale9Sprite}
+ */
+ccui.Scale9Sprite.create = function (file, rect, capInsets) {
+ return new ccui.Scale9Sprite(file, rect, capInsets);
+};
+
+/**
+ * create a ccui.Scale9Sprite with Sprite frame.
+ * @deprecated since v3.0, please use "new ccui.Scale9Sprite(spriteFrame, capInsets)" instead.
+ * @param {cc.SpriteFrame} spriteFrame
+ * @param {cc.Rect} capInsets
+ * @returns {ccui.Scale9Sprite}
+ */
+ccui.Scale9Sprite.createWithSpriteFrame = function (spriteFrame, capInsets) {
+ return new ccui.Scale9Sprite(spriteFrame, capInsets);
+};
+
+/**
+ * create a ccui.Scale9Sprite with a Sprite frame name
+ * @deprecated since v3.0, please use "new ccui.Scale9Sprite(spriteFrameName, capInsets)" instead.
+ * @param {string} spriteFrameName
+ * @param {cc.Rect} capInsets
+ * @returns {Scale9Sprite}
+ */
+ccui.Scale9Sprite.createWithSpriteFrameName = function (spriteFrameName, capInsets) {
+ return new ccui.Scale9Sprite(spriteFrameName, capInsets);
+};
+
+/**
+ * @ignore
+ */
+ccui.Scale9Sprite.POSITIONS_CENTRE = 0;
+ccui.Scale9Sprite.POSITIONS_TOP = 1;
+ccui.Scale9Sprite.POSITIONS_LEFT = 2;
+ccui.Scale9Sprite.POSITIONS_RIGHT = 3;
+ccui.Scale9Sprite.POSITIONS_BOTTOM = 4;
+ccui.Scale9Sprite.POSITIONS_TOPRIGHT = 5;
+ccui.Scale9Sprite.POSITIONS_TOPLEFT = 6;
+ccui.Scale9Sprite.POSITIONS_BOTTOMRIGHT = 7;
+
+ccui.Scale9Sprite.state = {NORMAL: 0, GRAY: 1};
+
+var RenderingType = ccui.Scale9Sprite.RenderingType = {
+ /**
+ * @property {Number} SIMPLE
+ */
+ SIMPLE: 0,
+ /**
+ * @property {Number} SLICED
+ */
+ SLICED: 1
+};
+})();
diff --git a/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIScale9SpriteCanvasRenderCmd.js b/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIScale9SpriteCanvasRenderCmd.js
new file mode 100644
index 0000000..12f1bca
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIScale9SpriteCanvasRenderCmd.js
@@ -0,0 +1,154 @@
+/****************************************************************************
+ Copyright (c) 2013-2016 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function() {
+ ccui.Scale9Sprite.CanvasRenderCmd = function (renderable) {
+ cc.Node.CanvasRenderCmd.call(this, renderable);
+ this._needDraw = true;
+
+ this._state = ccui.Scale9Sprite.state.NORMAL;
+ this._originalTexture = this._textureToRender = null;
+ };
+
+ var proto = ccui.Scale9Sprite.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ proto.constructor = ccui.Scale9Sprite.CanvasRenderCmd;
+
+ proto.transform = function(parentCmd, recursive){
+ this.originTransform(parentCmd, recursive);
+ this._node._rebuildQuads();
+ };
+
+ proto.needDraw = function () {
+ return this._needDraw && this._node.loaded();
+ };
+
+ proto._updateDisplayColor = function(parentColor){
+ cc.Node.RenderCmd.prototype._updateDisplayColor.call(this, parentColor);
+ this._originalTexture = this._textureToRender = null;
+ };
+
+ proto.setState = function(state){
+ if(this._state === state) return;
+
+ this._state = state;
+ this._originalTexture = this._textureToRender = null;
+ };
+
+ proto._setColorDirty = function () {
+ this.setDirtyFlag(cc.Node._dirtyFlags.colorDirty | cc.Node._dirtyFlags.opacityDirty);
+ };
+
+ proto.rendering = function (ctx, scaleX, scaleY) {
+ var node = this._node;
+ var locDisplayOpacity = this._displayedOpacity;
+ var alpha = locDisplayOpacity/ 255;
+ var locTexture = null;
+ if (node._spriteFrame) locTexture = node._spriteFrame._texture;
+ if (!node.loaded() || locDisplayOpacity === 0)
+ return;
+ if (this._textureToRender === null || this._originalTexture !== locTexture) {
+ this._textureToRender = this._originalTexture = locTexture;
+ if (cc.Scale9Sprite.state.GRAY === this._state) {
+ this._textureToRender = this._textureToRender._generateGrayTexture();
+ }
+ var color = node.getDisplayedColor();
+ if (locTexture && (color.r !== 255 || color.g !==255 || color.b !== 255))
+ this._textureToRender = this._textureToRender._generateColorTexture(color.r,color.g,color.b);
+ }
+
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext();
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+ wrapper.setCompositeOperation(cc.Node.CanvasRenderCmd._getCompositeOperationByBlendFunc(node._blendFunc));
+ wrapper.setGlobalAlpha(alpha);
+
+ if (this._textureToRender) {
+ if (node._quadsDirty) {
+ node._rebuildQuads();
+ }
+ var sx,sy,sw,sh;
+ var x, y, w,h;
+ var textureWidth = this._textureToRender._pixelsWide;
+ var textureHeight = this._textureToRender._pixelsHigh;
+ var image = this._textureToRender._htmlElementObj;
+ var vertices = node._vertices;
+ var uvs = node._uvs;
+ var i = 0, off = 0;
+
+ if (node._renderingType === cc.Scale9Sprite.RenderingType.SLICED) {
+ // Sliced use a special vertices layout 16 vertices for 9 quads
+ for (var r = 0; r < 3; ++r) {
+ for (var c = 0; c < 3; ++c) {
+ off = r*8 + c*2;
+ x = vertices[off];
+ y = vertices[off+1];
+ w = vertices[off+10] - x;
+ h = vertices[off+11] - y;
+ y = - y - h;
+
+ sx = uvs[off] * textureWidth;
+ sy = uvs[off+11] * textureHeight;
+ sw = (uvs[off+10] - uvs[off]) * textureWidth;
+ sh = (uvs[off+1] - uvs[off+11]) * textureHeight;
+
+ if (sw > 0 && sh > 0 && w > 0 && h > 0) {
+ context.drawImage(image,
+ sx, sy, sw, sh,
+ x, y, w, h);
+ }
+ }
+ }
+ cc.g_NumberOfDraws += 9;
+ } else {
+ var quadCount = Math.floor(node._vertCount / 4);
+ for (i = 0, off = 0; i < quadCount; i++) {
+ x = vertices[off];
+ y = vertices[off+1];
+ w = vertices[off+6] - x;
+ h = vertices[off+7] - y;
+ y = - y - h;
+
+ sx = uvs[off] * textureWidth;
+ sy = uvs[off+7] * textureHeight;
+ sw = (uvs[off+6] - uvs[off]) * textureWidth;
+ sh = (uvs[off+1] - uvs[off+7]) * textureHeight;
+
+
+ if (this._textureToRender._pattern !== '') {
+ wrapper.setFillStyle(context.createPattern(image, this._textureToRender._pattern));
+ context.fillRect(x, y, w, h);
+ } else {
+ if (sw > 0 && sh > 0 && w > 0 && h > 0) {
+ context.drawImage(image,
+ sx, sy, sw, sh,
+ x, y, w, h);
+ }
+ }
+ off += 8;
+ }
+ cc.g_NumberOfDraws += quadCount;
+ }
+ }
+ };
+
+})();
diff --git a/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js b/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js
new file mode 100644
index 0000000..16df4ee
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js
@@ -0,0 +1,159 @@
+/****************************************************************************
+ Copyright (c) 2013-2016 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function() {
+ if(!cc.Node.WebGLRenderCmd) return;
+
+ ccui.Scale9Sprite.WebGLRenderCmd = function (renderable) {
+ cc.Node.WebGLRenderCmd.call(this, renderable);
+
+ this._needDraw = true;
+
+ this._color = new Uint32Array(1);
+ this._dirty = false;
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR);
+ };
+
+
+
+ var Scale9Sprite = ccui.Scale9Sprite;
+ var proto = ccui.Scale9Sprite.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ proto.constructor = ccui.Scale9Sprite.WebGLRenderCmd;
+
+ proto.needDraw = function () {
+ return this._needDraw && this._node.loaded();
+ };
+
+ proto._uploadSliced = function (vertices, uvs, color, z, f32buffer, ui32buffer, offset) {
+ var off;
+ for (var r = 0; r < 3; ++r) {
+ for (var c = 0; c < 3; ++c) {
+ off = r*8 + c*2;
+ // lb
+ f32buffer[offset] = vertices[off];
+ f32buffer[offset+1] = vertices[off+1];
+ f32buffer[offset+2] = z;
+ ui32buffer[offset+3] = color[0];
+ f32buffer[offset+4] = uvs[off];
+ f32buffer[offset+5] = uvs[off+1];
+ offset += 6;
+ // rb
+ f32buffer[offset] = vertices[off+2];
+ f32buffer[offset + 1] = vertices[off+3];
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = color[0];
+ f32buffer[offset + 4] = uvs[off+2];
+ f32buffer[offset + 5] = uvs[off+3];
+ offset += 6;
+ // lt
+ f32buffer[offset] = vertices[off+8];
+ f32buffer[offset + 1] = vertices[off+9];
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = color[0];
+ f32buffer[offset + 4] = uvs[off+8];
+ f32buffer[offset + 5] = uvs[off+9];
+ offset += 6;
+ // rt
+ f32buffer[offset] = vertices[off+10];
+ f32buffer[offset + 1] = vertices[off+11];
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = color[0];
+ f32buffer[offset + 4] = uvs[off+10];
+ f32buffer[offset + 5] = uvs[off+11];
+ offset += 6;
+ }
+ }
+ return 36;
+ };
+
+ proto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
+ this._node._rebuildQuads();
+ };
+
+ proto._setColorDirty = function () {
+ };
+
+ proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset){
+ var node = this._node;
+ if (this._displayedOpacity === 0) {
+ return 0;
+ }
+
+ // Rebuild vertex data
+ if (node._quadsDirty) {
+ node._rebuildQuads();
+ }
+
+ // Color & z
+ var opacity = this._displayedOpacity;
+ var r = this._displayedColor.r,
+ g = this._displayedColor.g,
+ b = this._displayedColor.b;
+ if (node._opacityModifyRGB) {
+ var a = opacity / 255;
+ r *= a;
+ g *= a;
+ b *= a;
+ }
+ this._color[0] = ((opacity<<24) | (b<<16) | (g<<8) | r);
+ var z = node._vertexZ;
+
+ // Upload data
+ var vertices = node._vertices;
+ var uvs = node._uvs;
+ var types = Scale9Sprite.RenderingType;
+ var offset = vertexDataOffset;
+ var len = 0;
+ switch (node._renderingType) {
+ case types.SIMPLE:
+ // Inline for performance
+ len = this._node._vertCount;
+ for (var i = 0, srcOff = 0; i < len; i++, srcOff += 2) {
+ f32buffer[offset] = vertices[srcOff];
+ f32buffer[offset + 1] = vertices[srcOff+1];
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = this._color[0];
+ f32buffer[offset + 4] = uvs[srcOff];
+ f32buffer[offset + 5] = uvs[srcOff+1];
+ offset += 6;
+ }
+ break;
+ case types.SLICED:
+ len = this._uploadSliced(vertices, uvs, this._color, z, f32buffer, ui32buffer, offset);
+ break;
+ }
+ return len;
+ };
+
+ proto.setState = function (state) {
+ if (state === Scale9Sprite.state.NORMAL) {
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR);
+ } else if (state === Scale9Sprite.state.GRAY) {
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR_GRAY);
+ }
+ };
+
+
+})();
diff --git a/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIWidget.js b/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIWidget.js
new file mode 100644
index 0000000..b01ac52
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIWidget.js
@@ -0,0 +1,2087 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+ccui._FocusNavigationController = cc.Class.extend({
+ _keyboardListener: null,
+ _firstFocusedWidget: null,
+ _enableFocusNavigation: false,
+ _keyboardEventPriority: 1,
+
+ enableFocusNavigation: function (flag) {
+ if (this._enableFocusNavigation === flag)
+ return;
+
+ this._enableFocusNavigation = flag;
+ if (flag)
+ this._addKeyboardEventListener();
+ else
+ this._removeKeyboardEventListener();
+ },
+
+ _setFirstFocsuedWidget: function (widget) {
+ this._firstFocusedWidget = widget;
+ },
+
+ _onKeyPressed: function (keyCode, event) {
+ if (this._enableFocusNavigation && this._firstFocusedWidget) {
+ if (keyCode === cc.KEY.dpadDown) {
+ this._firstFocusedWidget = this._firstFocusedWidget.findNextFocusedWidget(ccui.Widget.DOWN, this._firstFocusedWidget);
+ }
+ if (keyCode === cc.KEY.dpadUp) {
+ this._firstFocusedWidget = this._firstFocusedWidget.findNextFocusedWidget(ccui.Widget.UP, this._firstFocusedWidget);
+ }
+ if (keyCode === cc.KEY.dpadLeft) {
+ this._firstFocusedWidget = this._firstFocusedWidget.findNextFocusedWidget(ccui.Widget.LEFT, this._firstFocusedWidget);
+ }
+ if (keyCode === cc.KEY.dpadRight) {
+ this._firstFocusedWidget = this._firstFocusedWidget.findNextFocusedWidget(ccui.Widget.RIGHT, this._firstFocusedWidget);
+ }
+ }
+ },
+
+ _addKeyboardEventListener: function () {
+ if (!this._keyboardListener) {
+ this._keyboardListener = cc.EventListener.create({
+ event: cc.EventListener.KEYBOARD,
+ onKeyReleased: this._onKeyPressed.bind(this)
+ });
+ cc.eventManager.addListener(this._keyboardListener, this._keyboardEventPriority);
+ }
+ },
+
+ _removeKeyboardEventListener: function () {
+ if (this._keyboardListener) {
+ cc.eventManager.removeEventListener(this._keyboardListener);
+ this._keyboardListener = null;
+ }
+ }
+});
+
+ccui.__LAYOUT_COMPONENT_NAME = "__ui_layout";
+
+/**
+ * The base class for ccui controls and layout
+ * @sample
+ * var uiWidget = new ccui.Widget();
+ * this.addChild(uiWidget);
+ * @class
+ * @extends ccui.ProtectedNode
+ *
+ * @property {Number} xPercent - Position x in percentage of width
+ * @property {Number} yPercent - Position y in percentage of height
+ * @property {Number} widthPercent - Width in percentage of parent width
+ * @property {Number} heightPercent - Height in percentage of parent height
+ * @property {ccui.Widget} widgetParent - <@readonly> The direct parent when it's a widget also, otherwise equals null
+ * @property {Boolean} enabled - Indicate whether the widget is enabled
+ * @property {Boolean} focused - Indicate whether the widget is focused
+ * @property {ccui.Widget.SIZE_ABSOLUTE|ccui.Widget.SIZE_PERCENT} sizeType - The size type of the widget
+ * @property {ccui.Widget.TYPE_WIDGET|ccui.Widget.TYPE_CONTAINER} widgetType - <@readonly> The type of the widget
+ * @property {Boolean} touchEnabled - Indicate whether touch events are enabled
+ * @property {Boolean} updateEnabled - Indicate whether the update function is scheduled
+ * @property {Boolean} bright - Indicate whether the widget is bright
+ * @property {String} name - The name of the widget
+ * @property {Number} actionTag - The action tag of the widget
+ */
+ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
+ _enabled: true, ///< Highest control of widget
+ _bright: true, ///< is this widget bright
+ _touchEnabled: false, ///< is this widget touch endabled
+
+ _brightStyle: null, ///< bright style
+
+ _touchBeganPosition: null, ///< touch began point
+ _touchMovePosition: null, ///< touch moved point
+ _touchEndPosition: null, ///< touch ended point
+
+ _touchEventListener: null,
+ _touchEventSelector: null,
+
+ _name: "default",
+ _widgetType: null,
+ _actionTag: 0,
+ _customSize: null,
+ _layoutParameterDictionary: null,
+ _layoutParameterType: 0,
+
+ _focused: false,
+ _focusEnabled: true,
+
+ _ignoreSize: false,
+ _affectByClipping: false,
+
+ _sizeType: null,
+ _sizePercent: null,
+ _positionType: null,
+ _positionPercent: null,
+ _hit: false,
+ _nodes: null,
+ _touchListener: null,
+ _className: "Widget",
+ _flippedX: false,
+ _flippedY: false,
+ _opacity: 255,
+ _highlight: false,
+
+ _touchEventCallback: null,
+ _clickEventListener: null,
+
+ _propagateTouchEvents: true,
+ _unifySize: false,
+
+ _callbackName: null,
+ _callbackType: null,
+ _usingLayoutComponent: false,
+ _inViewRect: true,
+
+ /**
+ * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @function
+ */
+ ctor: function () {
+ cc.ProtectedNode.prototype.ctor.call(this);
+ this._brightStyle = ccui.Widget.BRIGHT_STYLE_NONE;
+ this._touchBeganPosition = cc.p(0, 0);
+ this._touchMovePosition = cc.p(0, 0);
+ this._touchEndPosition = cc.p(0, 0);
+ this._widgetType = ccui.Widget.TYPE_WIDGET;
+ this._customSize = cc.size(0, 0);
+ this._layoutParameterDictionary = {};
+ this._sizeType = ccui.Widget.SIZE_ABSOLUTE;
+ this._sizePercent = cc.p(0, 0);
+ this._positionType = ccui.Widget.POSITION_ABSOLUTE;
+ this._positionPercent = cc.p(0, 0);
+ this._nodes = [];
+ this._layoutParameterType = ccui.LayoutParameter.NONE;
+ ccui.Widget.prototype.init.call(this);
+ },
+
+ /**
+ * initializes state of widget. please do not call this function by yourself, you should pass the parameters to constructor to initialize it
.
+ * @returns {boolean}
+ */
+ init: function () {
+ this._layoutParameterDictionary = {};
+ this._initRenderer();
+ this.setBright(true);
+
+ this.onFocusChanged = this.onFocusChange;
+ this.onNextFocusedWidget = null;
+ this.setAnchorPoint(cc.p(0.5, 0.5));
+
+ this.ignoreContentAdaptWithSize(true);
+ return true;
+ },
+
+ /**
+ * Calls updateSizeAndPosition and its parent's onEnter
+ * @override
+ */
+ onEnter: function () {
+ var locListener = this._touchListener;
+ if (locListener && !locListener._isRegistered() && this._touchEnabled)
+ cc.eventManager.addListener(locListener, this);
+ if(!this._usingLayoutComponent)
+ this.updateSizeAndPosition();
+ if (this._sizeDirty)
+ this._onSizeChanged();
+ cc.ProtectedNode.prototype.onEnter.call(this);
+ },
+
+ /**
+ * Calls unscheduleUpdate and its parent's onExit
+ * @override
+ */
+ onExit: function () {
+ this.unscheduleUpdate();
+ cc.ProtectedNode.prototype.onExit.call(this);
+ },
+
+ _getOrCreateLayoutComponent: function(){
+ var layoutComponent = this.getComponent(ccui.__LAYOUT_COMPONENT_NAME);
+ if (null == layoutComponent){
+ layoutComponent = new ccui.LayoutComponent();
+ this.addComponent(layoutComponent);
+ }
+ return layoutComponent;
+ },
+
+ /**
+ * The direct parent when it's a widget also, otherwise equals null
+ * @returns {ccui.Widget|null}
+ */
+ getWidgetParent: function () {
+ var widget = this.getParent();
+ if (widget instanceof ccui.Widget)
+ return widget;
+ return null;
+ },
+
+ _updateContentSizeWithTextureSize: function (size) {
+ if(this._unifySize){
+ this.setContentSize(size);
+ return;
+ }
+ this.setContentSize(this._ignoreSize ? size : this._customSize);
+ },
+
+ _isAncestorsEnabled: function () {
+ var parentWidget = this._getAncensterWidget(this);
+ if (parentWidget == null)
+ return true;
+ if (parentWidget && !parentWidget.isEnabled())
+ return false;
+
+ return parentWidget._isAncestorsEnabled();
+ },
+
+ /**
+ * Allow widget touch events to propagate to its parents. Set false will disable propagation
+ * @since v3.2
+ * @param {Boolean} isPropagate
+ */
+ setPropagateTouchEvents: function (isPropagate) {
+ this._propagateTouchEvents = isPropagate;
+ },
+
+ /**
+ * Return whether the widget is propagate touch events to its parents or not
+ * @since v3.2
+ * @returns {boolean}
+ */
+ isPropagateTouchEvents: function () {
+ return this._propagateTouchEvents;
+ },
+
+ /**
+ * Specify widget to swallow touches or not
+ * @since v3.2
+ * @param {Boolean} swallow
+ */
+ setSwallowTouches: function (swallow) {
+ if (this._touchListener)
+ this._touchListener.setSwallowTouches(swallow);
+ },
+
+ /**
+ * Return whether the widget is swallowing touch or not
+ * @since v3.2
+ * @returns {boolean}
+ */
+ isSwallowTouches: function () {
+ if (this._touchListener) {
+ //return true; //todo need test
+ return this._touchListener.isSwallowTouches();
+ }
+ return false;
+ },
+
+ _getAncensterWidget: function (node) {
+ if (null == node)
+ return null;
+
+ var parent = node.getParent();
+ if (null == parent)
+ return null;
+
+ if (parent instanceof ccui.Widget)
+ return parent;
+ else
+ return this._getAncensterWidget(parent.getParent());
+ },
+
+ _isAncestorsVisible: function (node) {
+ if (null == node)
+ return true;
+
+ var parent = node.getParent();
+
+ if (parent && !parent.isVisible())
+ return false;
+ return this._isAncestorsVisible(parent);
+ },
+
+ /**
+ *
+ * Sets whether the widget is enabled
+ * true if the widget is enabled, widget may be touched , false if the widget is disabled, widget cannot be touched.
+ * The default value is true, a widget is default to enabled
+ *
+ * @param {Boolean} enabled
+ */
+ setEnabled: function (enabled) {
+ this._enabled = enabled;
+ this.setBright(enabled);
+ },
+
+ /**
+ * initializes renderer of widget.
+ */
+ _initRenderer: function () {
+ },
+
+ /**
+ * Sets _customSize of ccui.Widget, if ignoreSize is true, the content size is its renderer's contentSize, otherwise the content size is parameter.
+ * and updates size percent by parent content size. At last, updates its children's size and position.
+ * @param {cc.Size|Number} contentSize content size or width of content size
+ * @param {Number} [height]
+ * @override
+ */
+ setContentSize: function(contentSize, height){
+ cc.Node.prototype.setContentSize.call(this, contentSize, height);
+
+ var locWidth = this._contentSize.width;
+ var locHeight = this._contentSize.height;
+
+ this._customSize.width = locWidth;
+ this._customSize.height = locHeight;
+ if(this._unifySize){
+ //unify size logic
+ } else if (this._ignoreSize) {
+ this._contentSize = this.getVirtualRendererSize();
+ }
+ if (!this._usingLayoutComponent && this._running) {
+ var widgetParent = this.getWidgetParent();
+ var pSize = widgetParent ? widgetParent.getContentSize() : this._parent.getContentSize();
+ this._sizePercent.x = (pSize.width > 0.0) ? locWidth / pSize.width : 0.0;
+ this._sizePercent.y = (pSize.height > 0.0) ? locHeight / pSize.height : 0.0;
+ }
+
+ if (this._running) {
+ this._onSizeChanged();
+ } else {
+ this._sizeDirty = true;
+ }
+ },
+
+ _setWidth: function (w) {
+ if (w === this._contentSize.width) {
+ return;
+ }
+ cc.Node.prototype._setWidth.call(this, w);
+ this._customSize.width = w;
+ if(this._unifySize){
+ //unify size logic
+ } else if (this._ignoreSize) {
+ this._contentSize = this.getVirtualRendererSize();
+ }
+
+ if (!this._usingLayoutComponent && this._running) {
+ var widgetParent = this.getWidgetParent();
+ var locWidth = widgetParent ? widgetParent.width : this._parent.width;
+ this._sizePercent.x = locWidth > 0 ? this._customSize.width / locWidth : 0;
+ }
+
+ if (this._running) {
+ this._onSizeChanged();
+ } else {
+ this._sizeDirty = true;
+ }
+ },
+ _setHeight: function (h) {
+ if (h === this._contentSize.height) {
+ return;
+ }
+
+ cc.Node.prototype._setHeight.call(this, h);
+ this._customSize.height = h;
+ if(this._unifySize){
+ //unify size logic
+ } else if (this._ignoreSize) {
+ this._contentSize = this.getVirtualRendererSize();
+ }
+
+ if (!this._usingLayoutComponent && this._running) {
+ var widgetParent = this.getWidgetParent();
+ var locH = widgetParent ? widgetParent.height : this._parent.height;
+ this._sizePercent.y = locH > 0 ? this._customSize.height / locH : 0;
+ }
+
+ if (this._running) {
+ this._onSizeChanged();
+ } else {
+ this._sizeDirty = true;
+ }
+ },
+
+ /**
+ * Changes the percent that is widget's percent size
+ * @param {cc.Point} percent that is widget's percent size, width and height value from 0 to 1.
+ */
+ setSizePercent: function (percent) {
+ if(this._usingLayoutComponent){
+ var component = this._getOrCreateLayoutComponent();
+ component.setUsingPercentContentSize(true);
+ component.setPercentContentSize(percent);
+ component.refreshLayout();
+ return;
+ }
+
+ this._sizePercent.x = percent.x;
+ this._sizePercent.y = percent.y;
+ var width = this._customSize.width, height = this._customSize.height;
+ if (this._running) {
+ var widgetParent = this.getWidgetParent();
+ if (widgetParent) {
+ width = widgetParent.width * percent.x;
+ height = widgetParent.height * percent.y;
+ } else {
+ width = this._parent.width * percent.x;
+ height = this._parent.height * percent.y;
+ }
+ }
+ if (this._ignoreSize)
+ this.setContentSize(this.getVirtualRendererSize());
+ else
+ this.setContentSize(width, height);
+
+ this._customSize.width = width;
+ this._customSize.height = height;
+ },
+
+ _setWidthPercent: function (percent) {
+ this._sizePercent.x = percent;
+ var width = this._customSize.width;
+ if (this._running) {
+ var widgetParent = this.getWidgetParent();
+ width = (widgetParent ? widgetParent.width : this._parent.width) * percent;
+ }
+ if (this._ignoreSize)
+ this._setWidth(this.getVirtualRendererSize().width);
+ else
+ this._setWidth(width);
+ this._customSize.width = width;
+ },
+ _setHeightPercent: function (percent) {
+ this._sizePercent.y = percent;
+ var height = this._customSize.height;
+ if (this._running) {
+ var widgetParent = this.getWidgetParent();
+ height = (widgetParent ? widgetParent.height : this._parent.height) * percent;
+ }
+ if (this._ignoreSize)
+ this._setHeight(this.getVirtualRendererSize().height);
+ else
+ this._setHeight(height);
+ this._customSize.height = height;
+ },
+
+ /**
+ * updates its size by size type and its position by position type.
+ * @param {cc.Size} [parentSize] parent size
+ */
+ updateSizeAndPosition: function (parentSize) {
+ if (!parentSize) {
+ var widgetParent = this.getWidgetParent();
+ if (widgetParent)
+ parentSize = widgetParent.getLayoutSize();
+ else
+ parentSize = this._parent.getContentSize();
+ }
+
+ switch (this._sizeType) {
+ case ccui.Widget.SIZE_ABSOLUTE:
+ if (this._ignoreSize)
+ this.setContentSize(this.getVirtualRendererSize());
+ else
+ this.setContentSize(this._customSize);
+ this._sizePercent.x = (parentSize.width > 0) ? this._customSize.width / parentSize.width : 0;
+ this._sizePercent.y = (parentSize.height > 0) ? this._customSize.height / parentSize.height : 0;
+ break;
+ case ccui.Widget.SIZE_PERCENT:
+ var cSize = cc.size(parentSize.width * this._sizePercent.x, parentSize.height * this._sizePercent.y);
+ if (this._ignoreSize)
+ this.setContentSize(this.getVirtualRendererSize());
+ else
+ this.setContentSize(cSize);
+ this._customSize.width = cSize.width;
+ this._customSize.height = cSize.height;
+ break;
+ default:
+ break;
+ }
+ this._onSizeChanged();
+ var absPos = this.getPosition();
+ switch (this._positionType) {
+ case ccui.Widget.POSITION_ABSOLUTE:
+ if (parentSize.width <= 0 || parentSize.height <= 0) {
+ this._positionPercent.x = this._positionPercent.y = 0;
+ } else {
+ this._positionPercent.x = absPos.x / parentSize.width;
+ this._positionPercent.y = absPos.y / parentSize.height;
+ }
+ break;
+ case ccui.Widget.POSITION_PERCENT:
+ absPos = cc.p(parentSize.width * this._positionPercent.x, parentSize.height * this._positionPercent.y);
+ break;
+ default:
+ break;
+ }
+ if (this._parent instanceof ccui.ImageView) {
+ var renderer = this._parent._imageRenderer;
+ if (renderer && !renderer._textureLoaded)
+ return;
+ }
+ this.setPosition(absPos);
+ },
+
+ /**TEXTURE_RES_TYPE
+ * Changes the size type of widget.
+ * @param {ccui.Widget.SIZE_ABSOLUTE|ccui.Widget.SIZE_PERCENT} type that is widget's size type
+ */
+ setSizeType: function (type) {
+ this._sizeType = type;
+ if (this._usingLayoutComponent) {
+ var component = this._getOrCreateLayoutComponent();
+ component.setUsingPercentContentSize(this._sizeType === ccui.SIZE_PERCENT);
+ }
+ },
+
+ /**
+ * Gets the size type of widget.
+ * @returns {ccui.Widget.SIZE_ABSOLUTE|ccui.Widget.SIZE_PERCENT} that is widget's size type
+ */
+ getSizeType: function () {
+ return this._sizeType;
+ },
+
+ /**
+ * Ignore the widget size
+ * @param {Boolean} ignore true that widget will ignore it's size, use texture size, false otherwise. Default value is true.
+ */
+ ignoreContentAdaptWithSize: function (ignore) {
+ if(this._unifySize){
+ this.setContentSize(this._customSize);
+ return;
+ }
+
+ if (this._ignoreSize === ignore)
+ return;
+
+ this._ignoreSize = ignore;
+ this.setContentSize(ignore ? this.getVirtualRendererSize() : this._customSize);
+ //this._onSizeChanged();
+ },
+
+ /**
+ * Gets whether ignore the content size (custom size)
+ * @returns {boolean} true that widget will ignore it's size, use texture size, false otherwise.
+ */
+ isIgnoreContentAdaptWithSize: function () {
+ return this._ignoreSize;
+ },
+
+ /**
+ * Get custom size of ccui.Widget
+ * @returns {cc.Size}
+ */
+ getCustomSize: function () {
+ return cc.size(this._customSize);
+ },
+
+ /**
+ * Gets layout size of ccui.Widget.
+ * @returns {cc.Size}
+ */
+ getLayoutSize: function () {
+ return cc.size(this._contentSize);
+ },
+
+ /**
+ * Returns size percent of ccui.Widget
+ * @returns {cc.Point}
+ */
+ getSizePercent: function () {
+ if(this._usingLayoutComponent){
+ var component = this._getOrCreateLayoutComponent();
+ this._sizePercent = component.getPercentContentSize();
+ }
+ return this._sizePercent;
+ },
+ _getWidthPercent: function () {
+ return this._sizePercent.x;
+ },
+ _getHeightPercent: function () {
+ return this._sizePercent.y;
+ },
+
+ /**
+ * Gets world position of ccui.Widget.
+ * @returns {cc.Point} world position of ccui.Widget.
+ */
+ getWorldPosition: function () {
+ return this.convertToWorldSpace(cc.p(this._anchorPoint.x * this._contentSize.width, this._anchorPoint.y * this._contentSize.height));
+ },
+
+ /**
+ * Gets the Virtual Renderer of widget.
+ * @returns {ccui.Widget}
+ */
+ getVirtualRenderer: function () {
+ return this;
+ },
+
+ /**
+ * Gets the content size of widget. Content size is widget's texture size.
+ */
+ getVirtualRendererSize: function () {
+ return cc.size(this._contentSize);
+ },
+
+ /**
+ * call back function called when size changed.
+ */
+ _onSizeChanged: function () {
+ if(!this._usingLayoutComponent){
+ var locChildren = this.getChildren();
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ var child = locChildren[i];
+ if (child instanceof ccui.Widget)
+ child.updateSizeAndPosition();
+ }
+ this._sizeDirty = false;
+ }
+ },
+
+ /**
+ * Sets whether the widget is touch enabled. The default value is false, a widget is default to touch disabled
+ * @param {Boolean} enable true if the widget is touch enabled, false if the widget is touch disabled.
+ */
+ setTouchEnabled: function (enable) {
+ if (this._touchEnabled === enable)
+ return;
+
+ this._touchEnabled = enable; //TODO need consider remove and re-add.
+ if (this._touchEnabled) {
+ if (!this._touchListener)
+ this._touchListener = cc.EventListener.create({
+ event: cc.EventListener.TOUCH_ONE_BY_ONE,
+ swallowTouches: true,
+ onTouchBegan: this.onTouchBegan.bind(this),
+ onTouchMoved: this.onTouchMoved.bind(this),
+ onTouchEnded: this.onTouchEnded.bind(this)
+ });
+ cc.eventManager.addListener(this._touchListener, this);
+ } else {
+ cc.eventManager.removeListener(this._touchListener);
+ }
+ },
+
+ /**
+ * Returns whether or not touch is enabled.
+ * @returns {boolean} true if the widget is touch enabled, false if the widget is touch disabled.
+ */
+ isTouchEnabled: function () {
+ return this._touchEnabled;
+ },
+
+ /**
+ * Determines if the widget is highlighted
+ * @returns {boolean} true if the widget is highlighted, false if the widget is not highlighted .
+ */
+ isHighlighted: function () {
+ return this._highlight;
+ },
+
+ /**
+ * Sets whether the widget is highlighted. The default value is false, a widget is default to not highlighted
+ * @param highlight true if the widget is highlighted, false if the widget is not highlighted.
+ */
+ setHighlighted: function (highlight) {
+ if (highlight === this._highlight)
+ return;
+ this._highlight = highlight;
+ if (this._bright) {
+ if (this._highlight)
+ this.setBrightStyle(ccui.Widget.BRIGHT_STYLE_HIGH_LIGHT);
+ else
+ this.setBrightStyle(ccui.Widget.BRIGHT_STYLE_NORMAL);
+ } else
+ this._onPressStateChangedToDisabled();
+ },
+
+ /**
+ * Determines if the widget is on focused
+ * @returns {boolean} whether the widget is focused or not
+ */
+ isFocused: function () {
+ return this._focused;
+ },
+
+ /**
+ * Sets whether the widget is on focused
+ * The default value is false, a widget is default to not on focused
+ * @param {boolean} focus pass true to let the widget get focus or pass false to let the widget lose focus
+ */
+ setFocused: function (focus) {
+ this._focused = focus;
+ //make sure there is only one focusedWidget
+ if (focus) {
+ ccui.Widget._focusedWidget = this;
+ if (ccui.Widget._focusNavigationController)
+ ccui.Widget._focusNavigationController._setFirstFocsuedWidget(this);
+ }
+ },
+
+ /**
+ * returns whether the widget could accept focus.
+ * @returns {boolean} true represent the widget could accept focus, false represent the widget couldn't accept focus
+ */
+ isFocusEnabled: function () {
+ return this._focusEnabled;
+ },
+
+ /**
+ * sets whether the widget could accept focus.
+ * @param {Boolean} enable true represent the widget could accept focus, false represent the widget couldn't accept focus
+ */
+ setFocusEnabled: function (enable) {
+ this._focusEnabled = enable;
+ },
+
+ /**
+ *
+ * When a widget is in a layout, you could call this method to get the next focused widget within a specified direction.
+ * If the widget is not in a layout, it will return itself
+ *
+ * @param direction the direction to look for the next focused widget in a layout
+ * @param current the current focused widget
+ * @return the next focused widget in a layout
+ */
+ findNextFocusedWidget: function (direction, current) {
+ if (null === this.onNextFocusedWidget || null == this.onNextFocusedWidget(direction)) {
+ var isLayout = current instanceof ccui.Layout;
+ if (this.isFocused() || isLayout) {
+ var layout = this.getParent();
+ if (null === layout || !(layout instanceof ccui.Layout)) {
+ //the outer layout's default behaviour is : loop focus
+ if (isLayout)
+ return current.findNextFocusedWidget(direction, current);
+ return current;
+ } else
+ return layout.findNextFocusedWidget(direction, current);
+ } else
+ return current;
+ } else {
+ var getFocusWidget = this.onNextFocusedWidget(direction);
+ this.dispatchFocusEvent(this, getFocusWidget);
+ return getFocusWidget;
+ }
+ },
+
+ /**
+ * when a widget calls this method, it will get focus immediately.
+ */
+ requestFocus: function () {
+ if (this === ccui.Widget._focusedWidget)
+ return;
+ this.dispatchFocusEvent(ccui.Widget._focusedWidget, this);
+ },
+
+ /**
+ * no matter what widget object you call this method on , it will return you the exact one focused widget
+ */
+ getCurrentFocusedWidget: function () {
+ return ccui.Widget._focusedWidget;
+ },
+
+ /**
+ *
+ * When a widget lose/get focus, this method will be called. Be Caution when you provide your own version,
+ * you must call widget.setFocused(true/false) to change the focus state of the current focused widget;
+ *
+ */
+ onFocusChanged: null,
+
+ /**
+ * use this function to manually specify the next focused widget regards to each direction
+ */
+ onNextFocusedWidget: null,
+
+ /**
+ * Sends the touch event to widget's parent, its subclass will override it, e.g. ccui.ScrollView, ccui.PageView
+ * @param {Number} eventType
+ * @param {ccui.Widget} sender
+ * @param {cc.Touch} touch
+ */
+ interceptTouchEvent: function (eventType, sender, touch) {
+ var widgetParent = this.getWidgetParent();
+ if (widgetParent)
+ widgetParent.interceptTouchEvent(eventType, sender, touch);
+ },
+
+ /**
+ * This method is called when a focus change event happens
+ * @param {ccui.Widget} widgetLostFocus
+ * @param {ccui.Widget} widgetGetFocus
+ */
+ onFocusChange: function (widgetLostFocus, widgetGetFocus) {
+ //only change focus when there is indeed a get&lose happens
+ if (widgetLostFocus)
+ widgetLostFocus.setFocused(false);
+ if (widgetGetFocus)
+ widgetGetFocus.setFocused(true);
+ },
+
+ /**
+ * Dispatch a EventFocus through a EventDispatcher
+ * @param {ccui.Widget} widgetLostFocus
+ * @param {ccui.Widget} widgetGetFocus
+ */
+ dispatchFocusEvent: function (widgetLostFocus, widgetGetFocus) {
+ //if the widgetLoseFocus doesn't get focus, it will use the previous focused widget instead
+ if (widgetLostFocus && !widgetLostFocus.isFocused())
+ widgetLostFocus = ccui.Widget._focusedWidget;
+
+ if (widgetGetFocus !== widgetLostFocus) {
+ if (widgetGetFocus && widgetGetFocus.onFocusChanged)
+ widgetGetFocus.onFocusChanged(widgetLostFocus, widgetGetFocus);
+ if (widgetLostFocus && widgetGetFocus.onFocusChanged)
+ widgetLostFocus.onFocusChanged(widgetLostFocus, widgetGetFocus);
+ cc.eventManager.dispatchEvent(new cc.EventFocus(widgetLostFocus, widgetGetFocus));
+ }
+ },
+
+ /**
+ * Sets whether the widget is bright. The default value is true, a widget is default to bright
+ * @param {Boolean} bright true if the widget is bright, false if the widget is dark.
+ */
+ setBright: function (bright) {
+ this._bright = bright;
+ if (this._bright) {
+ this._brightStyle = ccui.Widget.BRIGHT_STYLE_NONE;
+ this.setBrightStyle(ccui.Widget.BRIGHT_STYLE_NORMAL);
+ } else
+ this._onPressStateChangedToDisabled();
+ },
+
+ /**
+ * To set the bright style of ccui.Widget.
+ * @param {Number} style BRIGHT_NORMAL the widget is normal state, BRIGHT_HIGHLIGHT the widget is height light state.
+ */
+ setBrightStyle: function (style) {
+ if (this._brightStyle === style)
+ return;
+
+ style = style || ccui.Widget.BRIGHT_STYLE_NORMAL;
+ this._brightStyle = style;
+ switch (this._brightStyle) {
+ case ccui.Widget.BRIGHT_STYLE_NORMAL:
+ this._onPressStateChangedToNormal();
+ break;
+ case ccui.Widget.BRIGHT_STYLE_HIGH_LIGHT:
+ this._onPressStateChangedToPressed();
+ break;
+ default:
+ break;
+ }
+ },
+
+ _onPressStateChangedToNormal: function () {
+ },
+
+ _onPressStateChangedToPressed: function () {
+ },
+
+ _onPressStateChangedToDisabled: function () {
+ },
+
+ _updateChildrenDisplayedRGBA: function () {
+ this.setColor(this.getColor());
+ this.setOpacity(this.getOpacity());
+ },
+
+ /**
+ * A call back function when widget lost of focus.
+ */
+ didNotSelectSelf: function () {
+ },
+
+ /**
+ *
+ * The callback of touch began event.
+ * If the bounding box of ccui.Widget contains the touch point, it will do the following things:
+ * 1. sets highlight state,
+ * 2. sends event to parent widget by interceptTouchEvent
+ * 3. calls the callback of touch began event.
+ * 4. returns true,
+ * otherwise returns false directly.
+ *
+ * @override
+ * @param {cc.Touch} touch
+ * @param {cc.Event} event
+ * @returns {boolean}
+ */
+ onTouchBegan: function (touch, event) {
+ this._hit = false;
+ if (this.isVisible() && this.isEnabled() && this._isAncestorsEnabled() && this._isAncestorsVisible(this)) {
+ var touchPoint = touch.getLocation();
+ this._touchBeganPosition.x = touchPoint.x;
+ this._touchBeganPosition.y = touchPoint.y;
+ if (this.hitTest(this._touchBeganPosition) && this.isClippingParentContainsPoint(this._touchBeganPosition))
+ this._hit = true;
+ }
+ if (!this._hit) {
+ return false;
+ }
+ this.setHighlighted(true);
+
+ /*
+ * Propagate touch events to its parents
+ */
+ if (this._propagateTouchEvents) {
+ this.propagateTouchEvent(ccui.Widget.TOUCH_BEGAN, this, touch);
+ }
+
+ this._pushDownEvent();
+ return true;
+ },
+
+ propagateTouchEvent: function (event, sender, touch) {
+ var widgetParent = this.getWidgetParent();
+ if (widgetParent) {
+ widgetParent.interceptTouchEvent(event, sender, touch);
+ }
+ },
+
+ /**
+ *
+ * The callback of touch moved event.
+ * It sets the highlight state by touch, sends event to parent widget by interceptTouchEvent and calls the callback of touch moved event.
+ *
+ * @param {cc.Touch} touch
+ * @param {cc.Event} event
+ */
+ onTouchMoved: function (touch, event) {
+ var touchPoint = touch.getLocation();
+ this._touchMovePosition.x = touchPoint.x;
+ this._touchMovePosition.y = touchPoint.y;
+ this.setHighlighted(this.hitTest(touchPoint));
+ /*
+ * Propagate touch events to its parents
+ */
+ if (this._propagateTouchEvents)
+ this.propagateTouchEvent(ccui.Widget.TOUCH_MOVED, this, touch);
+ this._moveEvent();
+ },
+
+ /**
+ *
+ * The callback of touch end event
+ * It sends event to parent widget by interceptTouchEvent,
+ * calls the callback of touch end event (highlight= true) or touch canceled event (highlight= false).
+ * sets the highlight state to false ,
+ *
+ * @param touch
+ * @param event
+ */
+ onTouchEnded: function (touch, event) {
+ var touchPoint = touch.getLocation();
+ this._touchEndPosition.x = touchPoint.x;
+ this._touchEndPosition.y = touchPoint.y;
+ /*
+ * Propagate touch events to its parents
+ */
+ if (this._propagateTouchEvents)
+ this.propagateTouchEvent(ccui.Widget.TOUCH_ENDED, this, touch);
+
+ var highlight = this._highlight;
+ this.setHighlighted(false);
+ if (highlight)
+ this._releaseUpEvent();
+ else
+ this._cancelUpEvent();
+ },
+
+ /**
+ * A call back function called when widget is selected, and on touch canceled.
+ * @param {cc.Point} touchPoint
+ */
+ onTouchCancelled: function (touchPoint) {
+ this.setHighlighted(false);
+ this._cancelUpEvent();
+ },
+
+ /**
+ * A call back function called when widget is selected, and on touch long clicked.
+ * @param {cc.Point} touchPoint
+ */
+ onTouchLongClicked: function (touchPoint) {
+ this.longClickEvent();
+ },
+
+ //call back function called widget's state changed to dark.
+ _pushDownEvent: function () {
+ if (this._touchEventCallback)
+ this._touchEventCallback(this, ccui.Widget.TOUCH_BEGAN);
+ if (this._touchEventListener && this._touchEventSelector)
+ this._touchEventSelector.call(this._touchEventListener, this, ccui.Widget.TOUCH_BEGAN);
+ },
+
+ _moveEvent: function () {
+ if (this._touchEventCallback)
+ this._touchEventCallback(this, ccui.Widget.TOUCH_MOVED);
+ if (this._touchEventListener && this._touchEventSelector)
+ this._touchEventSelector.call(this._touchEventListener, this, ccui.Widget.TOUCH_MOVED);
+ },
+
+ _releaseUpEvent: function () {
+ if (this._touchEventCallback)
+ this._touchEventCallback(this, ccui.Widget.TOUCH_ENDED);
+ if (this._touchEventListener && this._touchEventSelector)
+ this._touchEventSelector.call(this._touchEventListener, this, ccui.Widget.TOUCH_ENDED);
+ if (this._clickEventListener)
+ this._clickEventListener(this);
+ },
+
+ _cancelUpEvent: function () {
+ if (this._touchEventCallback)
+ this._touchEventCallback(this, ccui.Widget.TOUCH_CANCELED);
+ if (this._touchEventListener && this._touchEventSelector)
+ this._touchEventSelector.call(this._touchEventListener, this, ccui.Widget.TOUCH_CANCELED);
+ },
+
+ longClickEvent: function () {
+ //TODO it will implement in v3.1
+ },
+
+ /**
+ * Sets the touch event target/selector of the ccui.Widget
+ * @param {Function} selector
+ * @param {Object} target
+ */
+ addTouchEventListener: function (selector, target) {
+ if (target === undefined)
+ this._touchEventCallback = selector;
+ else {
+ this._touchEventSelector = selector;
+ this._touchEventListener = target;
+ }
+ },
+
+ addClickEventListener: function (callback) {
+ this._clickEventListener = callback;
+ },
+
+ /**
+ * Checks a point if is in widget's space
+ * @param {cc.Point} pt
+ * @returns {boolean} true if the point is in widget's space, false otherwise.
+ */
+ hitTest: function (pt) {
+ var bb = cc.rect(0, 0, this._contentSize.width, this._contentSize.height);
+ return cc.rectContainsPoint(bb, this.convertToNodeSpace(pt));
+ },
+
+ /**
+ * returns whether clipping parent widget contains point.
+ * @param {cc.Point} pt location point
+ * @returns {Boolean}
+ */
+ isClippingParentContainsPoint: function (pt) {
+ this._affectByClipping = false;
+ var parent = this.getParent();
+ var clippingParent = null;
+ while (parent) {
+ if (parent instanceof ccui.Layout) {
+ if (parent.isClippingEnabled()) {
+ this._affectByClipping = true;
+ clippingParent = parent;
+ break;
+ }
+ }
+ parent = parent.getParent();
+ }
+
+ if (!this._affectByClipping)
+ return true;
+
+ if (clippingParent) {
+ if (clippingParent.hitTest(pt))
+ return clippingParent.isClippingParentContainsPoint(pt);
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * Calls the checkChildInfo of widget's parent, its subclass will override it.
+ * @param {number} handleState
+ * @param {ccui.Widget} sender
+ * @param {cc.Point} touchPoint
+ */
+ checkChildInfo: function (handleState, sender, touchPoint) {
+ var widgetParent = this.getWidgetParent();
+ if (widgetParent)
+ widgetParent.checkChildInfo(handleState, sender, touchPoint);
+ },
+
+ /**
+ * Changes the position (x,y) of the widget .
+ * The original point (0,0) is at the left-bottom corner of screen.
+ * @override
+ * @param {cc.Point|Number} pos
+ * @param {Number} [posY]
+ */
+ setPosition: function (pos, posY) {
+ if (!this._usingLayoutComponent && this._running) {
+ var widgetParent = this.getWidgetParent();
+ if (widgetParent) {
+ var pSize = widgetParent.getContentSize();
+ if (pSize.width <= 0 || pSize.height <= 0) {
+ this._positionPercent.x = 0;
+ this._positionPercent.y = 0;
+ } else {
+ if (posY === undefined) {
+ this._positionPercent.x = pos.x / pSize.width;
+ this._positionPercent.y = pos.y / pSize.height;
+ } else {
+ this._positionPercent.x = pos / pSize.width;
+ this._positionPercent.y = posY / pSize.height;
+ }
+ }
+ }
+ }
+
+ cc.Node.prototype.setPosition.call(this, pos, posY);
+ //this._positionType = ccui.Widget.POSITION_ABSOLUTE;
+ },
+
+ setPositionX: function (x) {
+ if (this._running) {
+ var widgetParent = this.getWidgetParent();
+ if (widgetParent) {
+ var pw = widgetParent.width;
+ if (pw <= 0)
+ this._positionPercent.x = 0;
+ else
+ this._positionPercent.x = x / pw;
+ }
+ }
+
+ cc.Node.prototype.setPositionX.call(this, x);
+ },
+ setPositionY: function (y) {
+ if (this._running) {
+ var widgetParent = this.getWidgetParent();
+ if (widgetParent) {
+ var ph = widgetParent.height;
+ if (ph <= 0)
+ this._positionPercent.y = 0;
+ else
+ this._positionPercent.y = y / ph;
+ }
+ }
+
+ cc.Node.prototype.setPositionY.call(this, y);
+ },
+
+ /**
+ * Changes the position (x,y) of the widget
+ * @param {cc.Point} percent
+ */
+ setPositionPercent: function (percent) {
+ if (this._usingLayoutComponent){
+ var component = this._getOrCreateLayoutComponent();
+ component.setPositionPercentX(percent.x);
+ component.setPositionPercentY(percent.y);
+ component.refreshLayout();
+ return;
+ }else{
+ this._setXPercent(percent.x);
+ this._setYPercent(percent.y);
+ }
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+ _setXPercent: function (percent) {
+ if (this._usingLayoutComponent){
+ var component = this._getOrCreateLayoutComponent();
+ component.setPositionPercentX(percent.x);
+ component.refreshLayout();
+ return;
+ }
+ this._positionPercent.x = percent;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+ _setYPercent: function (percent) {
+ if (this._usingLayoutComponent){
+ var component = this._getOrCreateLayoutComponent();
+ component.setPositionPercentY(percent.x);
+ component.refreshLayout();
+ return;
+ }
+ this._positionPercent.y = percent;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Gets the percent (x,y) of the widget
+ * @returns {cc.Point} The percent (x,y) of the widget in OpenGL coordinates
+ */
+ getPositionPercent: function () {
+ if (this._usingLayoutComponent) {
+ var component = this._getOrCreateLayoutComponent();
+ this._positionPercent.x = component.getPositionPercentX();
+ this._positionPercent.y = component.getPositionPercentY();
+ }
+ return cc.p(this._positionPercent);
+ },
+
+ _getXPercent: function () {
+ if (this._usingLayoutComponent) {
+ var component = this._getOrCreateLayoutComponent();
+ this._positionPercent.x = component.getPositionPercentX();
+ this._positionPercent.y = component.getPositionPercentY();
+ }
+ return this._positionPercent.x;
+ },
+ _getYPercent: function () {
+ if (this._usingLayoutComponent) {
+ var component = this._getOrCreateLayoutComponent();
+ this._positionPercent.x = component.getPositionPercentX();
+ this._positionPercent.y = component.getPositionPercentY();
+ }
+ return this._positionPercent.y;
+ },
+
+ /**
+ * Changes the position type of the widget
+ * @param {Number} type the position type of widget
+ */
+ setPositionType: function (type) {
+ this._positionType = type;
+ if(this._usingLayoutComponent){
+ var component = this._getOrCreateLayoutComponent();
+ if (type === ccui.POSITION_ABSOLUTE){
+ component.setPositionPercentXEnabled(false);
+ component.setPositionPercentYEnabled(false);
+ } else {
+ component.setPositionPercentXEnabled(true);
+ component.setPositionPercentYEnabled(true);
+ }
+ }
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Gets the position type of the widget
+ * @returns {Number} the position type of widget
+ */
+ getPositionType: function () {
+ return this._positionType;
+ },
+
+ /**
+ * Sets whether the widget should be flipped horizontally or not.
+ * @param {Boolean} flipX true if the widget should be flipped horizontally, false otherwise.
+ */
+ setFlippedX: function (flipX) {
+ var realScale = this.getScaleX();
+ this._flippedX = flipX;
+ this.setScaleX(realScale);
+ },
+
+ /**
+ *
+ * Returns the flag which indicates whether the widget is flipped horizontally or not.
+ * It only flips the texture of the widget, and not the texture of the widget's children.
+ * Also, flipping the texture doesn't alter the anchorPoint.
+ * If you want to flip the anchorPoint too, and/or to flip the children too use:
+ * widget.setScaleX(sprite.getScaleX() * -1);
+ *
+ * @returns {Boolean} true if the widget is flipped horizontally, false otherwise.
+ */
+ isFlippedX: function () {
+ return this._flippedX;
+ },
+
+ /**
+ * Sets whether the widget should be flipped vertically or not.
+ * @param {Boolean} flipY true if the widget should be flipped vertically, false otherwise.
+ */
+ setFlippedY: function (flipY) {
+ var realScale = this.getScaleY();
+ this._flippedY = flipY;
+ this.setScaleY(realScale);
+ },
+
+ /**
+ *
+ * Return the flag which indicates whether the widget is flipped vertically or not.
+ * It only flips the texture of the widget, and not the texture of the widget's children.
+ * Also, flipping the texture doesn't alter the anchorPoint.
+ * If you want to flip the anchorPoint too, and/or to flip the children too use:
+ * widget.setScaleY(widget.getScaleY() * -1);
+ *
+ * @returns {Boolean} true if the widget is flipped vertically, false otherwise.
+ */
+ isFlippedY: function () {
+ return this._flippedY;
+ },
+
+ _adaptRenderers: function () {
+ },
+
+ /**
+ * Determines if the widget is bright
+ * @returns {boolean} true if the widget is bright, false if the widget is dark.
+ */
+ isBright: function () {
+ return this._bright;
+ },
+
+ /**
+ * Determines if the widget is enabled
+ * @returns {boolean}
+ */
+ isEnabled: function () {
+ return this._enabled;
+ },
+
+ /**
+ * Gets the left boundary position of this widget.
+ * @returns {number}
+ */
+ getLeftBoundary: function () {
+ return this.getPositionX() - this._getAnchorX() * this._contentSize.width;
+ },
+
+ /**
+ * Gets the bottom boundary position of this widget.
+ * @returns {number}
+ */
+ getBottomBoundary: function () {
+ return this.getPositionY() - this._getAnchorY() * this._contentSize.height;
+ },
+
+ /**
+ * Gets the right boundary position of this widget.
+ * @returns {number}
+ */
+ getRightBoundary: function () {
+ return this.getLeftBoundary() + this._contentSize.width;
+ },
+
+ /**
+ * Gets the top boundary position of this widget.
+ * @returns {number}
+ */
+ getTopBoundary: function () {
+ return this.getBottomBoundary() + this._contentSize.height;
+ },
+
+ /**
+ * Gets the position of touch began event.
+ * @returns {cc.Point}
+ */
+ getTouchBeganPosition: function () {
+ return cc.p(this._touchBeganPosition);
+ },
+
+ /**
+ * Gets the position of touch moved event
+ * @returns {cc.Point}
+ */
+ getTouchMovePosition: function () {
+ return cc.p(this._touchMovePosition);
+ },
+
+ /**
+ * Gets the position of touch end event
+ * @returns {cc.Point}
+ */
+ getTouchEndPosition: function () {
+ return cc.p(this._touchEndPosition);
+ },
+
+ /**
+ * get widget type
+ * @returns {ccui.Widget.TYPE_WIDGET|ccui.Widget.TYPE_CONTAINER}
+ */
+ getWidgetType: function () {
+ return this._widgetType;
+ },
+
+ /**
+ * Gets LayoutParameter of widget.
+ * @param {ccui.LayoutParameter} parameter
+ */
+ setLayoutParameter: function (parameter) {
+ if (!parameter)
+ return;
+ this._layoutParameterDictionary[parameter.getLayoutType()] = parameter;
+ this._layoutParameterType = parameter.getLayoutType();
+ },
+
+ /**
+ * Gets layout parameter
+ * @param {ccui.LayoutParameter.NONE|ccui.LayoutParameter.LINEAR|ccui.LayoutParameter.RELATIVE} type
+ * @returns {ccui.LayoutParameter}
+ */
+ getLayoutParameter: function (type) {
+ type = type || this._layoutParameterType;
+ return this._layoutParameterDictionary[type];
+ },
+
+ /**
+ * Returns the "class name" of widget.
+ * @returns {string}
+ */
+ getDescription: function () {
+ return "Widget";
+ },
+
+ /**
+ * Clones a new widget.
+ * @returns {ccui.Widget}
+ */
+ clone: function () {
+ var clonedWidget = this._createCloneInstance();
+ clonedWidget._copyProperties(this);
+ clonedWidget._copyClonedWidgetChildren(this);
+ return clonedWidget;
+ },
+
+ _createCloneInstance: function () {
+ return new ccui.Widget();
+ },
+
+ _copyClonedWidgetChildren: function (model) {
+ var widgetChildren = model.getChildren();
+ for (var i = 0; i < widgetChildren.length; i++) {
+ var locChild = widgetChildren[i];
+ if (locChild instanceof ccui.Widget)
+ this.addChild(locChild.clone());
+ }
+ },
+
+ _copySpecialProperties: function (model) {
+ },
+
+ _copyProperties: function (widget) {
+ this.setEnabled(widget.isEnabled());
+ this.setVisible(widget.isVisible());
+ this.setBright(widget.isBright());
+ this.setTouchEnabled(widget.isTouchEnabled());
+ this.setLocalZOrder(widget.getLocalZOrder());
+ this.setTag(widget.getTag());
+ this.setName(widget.getName());
+ this.setActionTag(widget.getActionTag());
+
+ this._ignoreSize = widget._ignoreSize;
+
+ this.setContentSize(widget._contentSize);
+ this._customSize.width = widget._customSize.width;
+ this._customSize.height = widget._customSize.height;
+
+ this._copySpecialProperties(widget);
+ this._sizeType = widget.getSizeType();
+ this._sizePercent.x = widget._sizePercent.x;
+ this._sizePercent.y = widget._sizePercent.y;
+
+ this._positionType = widget._positionType;
+ this._positionPercent.x = widget._positionPercent.x;
+ this._positionPercent.y = widget._positionPercent.y;
+
+ this.setPosition(widget.getPosition());
+ this.setAnchorPoint(widget.getAnchorPoint());
+ this.setScaleX(widget.getScaleX());
+ this.setScaleY(widget.getScaleY());
+ this.setRotation(widget.getRotation());
+ this.setRotationX(widget.getRotationX());
+ this.setRotationY(widget.getRotationY());
+ this.setFlippedX(widget.isFlippedX());
+ this.setFlippedY(widget.isFlippedY());
+ this.setColor(widget.getColor());
+ this.setOpacity(widget.getOpacity());
+
+ this._touchEventCallback = widget._touchEventCallback;
+ this._touchEventListener = widget._touchEventListener;
+ this._touchEventSelector = widget._touchEventSelector;
+ this._clickEventListener = widget._clickEventListener;
+ this._focused = widget._focused;
+ this._focusEnabled = widget._focusEnabled;
+ this._propagateTouchEvents = widget._propagateTouchEvents;
+
+ for (var key in widget._layoutParameterDictionary) {
+ var parameter = widget._layoutParameterDictionary[key];
+ if (parameter)
+ this.setLayoutParameter(parameter.clone());
+ }
+ },
+
+ /*temp action*/
+ setActionTag: function (tag) {
+ this._actionTag = tag;
+ },
+
+ getActionTag: function () {
+ return this._actionTag;
+ },
+
+ /**
+ * Gets the left boundary position of this widget.
+ * @deprecated since v3.0, please use getLeftBoundary instead.
+ * @returns {number}
+ */
+ getLeftInParent: function () {
+ cc.log("getLeftInParent is deprecated. Please use getLeftBoundary instead.");
+ return this.getLeftBoundary();
+ },
+
+ /**
+ * Gets the bottom boundary position of this widget.
+ * @deprecated since v3.0, please use getBottomBoundary instead.
+ * @returns {number}
+ */
+ getBottomInParent: function () {
+ cc.log("getBottomInParent is deprecated. Please use getBottomBoundary instead.");
+ return this.getBottomBoundary();
+ },
+
+ /**
+ * Gets the right boundary position of this widget.
+ * @deprecated since v3.0, please use getRightBoundary instead.
+ * @returns {number}
+ */
+ getRightInParent: function () {
+ cc.log("getRightInParent is deprecated. Please use getRightBoundary instead.");
+ return this.getRightBoundary();
+ },
+
+ /**
+ * Gets the top boundary position of this widget.
+ * @deprecated since v3.0, please use getTopBoundary instead.
+ * @returns {number}
+ */
+ getTopInParent: function () {
+ cc.log("getTopInParent is deprecated. Please use getTopBoundary instead.");
+ return this.getTopBoundary();
+ },
+
+ /**
+ * Gets the touch end point of widget when widget is selected.
+ * @deprecated since v3.0, please use getTouchEndPosition instead.
+ * @returns {cc.Point} the touch end point.
+ */
+ getTouchEndPos: function () {
+ cc.log("getTouchEndPos is deprecated. Please use getTouchEndPosition instead.");
+ return this.getTouchEndPosition();
+ },
+
+ /**
+ *Gets the touch move point of widget when widget is selected.
+ * @deprecated since v3.0, please use getTouchMovePosition instead.
+ * @returns {cc.Point} the touch move point.
+ */
+ getTouchMovePos: function () {
+ cc.log("getTouchMovePos is deprecated. Please use getTouchMovePosition instead.");
+ return this.getTouchMovePosition();
+ },
+
+ /**
+ * Checks a point if in parent's area.
+ * @deprecated since v3.0, please use isClippingParentContainsPoint instead.
+ * @param {cc.Point} pt
+ * @returns {Boolean}
+ */
+ clippingParentAreaContainPoint: function (pt) {
+ cc.log("clippingParentAreaContainPoint is deprecated. Please use isClippingParentContainsPoint instead.");
+ this.isClippingParentContainsPoint(pt);
+ },
+
+ /**
+ * Gets the touch began point of widget when widget is selected.
+ * @deprecated since v3.0, please use getTouchBeganPosition instead.
+ * @returns {cc.Point} the touch began point.
+ */
+ getTouchStartPos: function () {
+ cc.log("getTouchStartPos is deprecated. Please use getTouchBeganPosition instead.");
+ return this.getTouchBeganPosition();
+ },
+
+ /**
+ * Changes the size that is widget's size
+ * @deprecated since v3.0, please use setContentSize instead.
+ * @param {cc.Size} size that is widget's size
+ */
+ setSize: function (size) {
+ this.setContentSize(size);
+ },
+
+ /**
+ * Returns size of widget
+ * @deprecated since v3.0, please use getContentSize instead.
+ * @returns {cc.Size}
+ */
+ getSize: function () {
+ return this.getContentSize();
+ },
+
+ /**
+ * Adds a node for widget (this function is deleted in -x)
+ * @param {cc.Node} node
+ * @param {Number} zOrder
+ * @param {Number} tag
+ * @deprecated since v3.0, please use addChild instead.
+ */
+ addNode: function (node, zOrder, tag) {
+ if (node instanceof ccui.Widget) {
+ cc.log("Please use addChild to add a Widget.");
+ return;
+ }
+ cc.Node.prototype.addChild.call(this, node, zOrder, tag);
+ this._nodes.push(node);
+ },
+
+ /**
+ * Gets node by tag
+ * @deprecated since v3.0, please use getChildByTag instead.
+ * @param {Number} tag
+ * @returns {cc.Node}
+ */
+ getNodeByTag: function (tag) {
+ var _nodes = this._nodes;
+ for (var i = 0; i < _nodes.length; i++) {
+ var node = _nodes[i];
+ if (node && node.getTag() === tag) {
+ return node;
+ }
+ }
+ return null;
+ },
+
+ /**
+ * Returns all children.
+ * @deprecated since v3.0, please use getChildren instead.
+ * @returns {Array}
+ */
+ getNodes: function () {
+ return this._nodes;
+ },
+
+ /**
+ * Removes a node from ccui.Widget
+ * @deprecated since v3.0, please use removeChild instead.
+ * @param {cc.Node} node
+ * @param {Boolean} cleanup
+ */
+ removeNode: function (node, cleanup) {
+ cc.Node.prototype.removeChild.call(this, node, cleanup);
+ cc.arrayRemoveObject(this._nodes, node);
+ },
+
+ _getNormalGLProgram: function () {
+ return cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR);
+ },
+
+ _getGrayGLProgram: function () {
+ return cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR_GRAY);
+ },
+
+ /**
+ * Removes node by tag
+ * @deprecated since v3.0, please use removeChildByTag instead.
+ * @param {Number} tag
+ * @param {Boolean} [cleanup]
+ */
+ removeNodeByTag: function (tag, cleanup) {
+ var node = this.getChildByTag(tag);
+ if (!node)
+ cc.log("cocos2d: removeNodeByTag(tag = %d): child not found!", tag);
+ else
+ this.removeChild(node, cleanup);
+ },
+
+ /**
+ * Removes all node
+ * @deprecated since v3.0, please use removeAllChildren instead.
+ */
+ removeAllNodes: function () {
+ for (var i = 0; i < this._nodes.length; i++) {
+ var node = this._nodes[i];
+ cc.Node.prototype.removeChild.call(this, node);
+ }
+ this._nodes.length = 0;
+ },
+
+ _findLayout: function () {
+ cc.renderer.childrenOrderDirty = true;
+ var layout = this._parent;
+ while (layout) {
+ if (layout._doLayout) {
+ layout._doLayoutDirty = true;
+ break;
+ } else
+ layout = layout._parent;
+ }
+ },
+
+ /**
+ * @since v3.2
+ * @returns {boolean} true represent the widget use Unify Size, false represent the widget couldn't use Unify Size
+ */
+ isUnifySizeEnabled: function(){
+ return this._unifySize;
+ },
+
+ /**
+ * @since v3.2
+ * @param {Boolean} enable enable Unify Size of a widget
+ */
+ setUnifySizeEnabled: function(enable){
+ this._unifySize = enable;
+ },
+
+ //v3.3
+ _ccEventCallback: null,
+ /**
+ * Set a event handler to the widget in order to use cocostudio editor and framework
+ * @since v3.3
+ * @param {function} callback
+ */
+ addCCSEventListener: function (callback) {
+ this._ccEventCallback = callback;
+ },
+
+ //override the scale functions.
+ setScaleX: function (scaleX) {
+ if (this._flippedX)
+ scaleX = scaleX * -1;
+ cc.Node.prototype.setScaleX.call(this, scaleX);
+ },
+ setScaleY: function (scaleY) {
+ if (this._flippedY)
+ scaleY = scaleY * -1;
+ cc.Node.prototype.setScaleY.call(this, scaleY);
+ },
+ setScale: function (scaleX, scaleY) {
+ if (scaleY === undefined)
+ scaleY = scaleX;
+ this.setScaleX(scaleX);
+ this.setScaleY(scaleY);
+ },
+
+ getScaleX: function () {
+ var originalScale = cc.Node.prototype.getScaleX.call(this);
+ if (this._flippedX)
+ originalScale = originalScale * -1.0;
+ return originalScale;
+ },
+ getScaleY: function () {
+ var originalScale = cc.Node.prototype.getScaleY.call(this);
+ if (this._flippedY)
+ originalScale = originalScale * -1.0;
+ return originalScale;
+ },
+ getScale: function () {
+ if (this.getScaleX() !== this.getScaleY())
+ cc.log("Widget#scale. ScaleX != ScaleY. Don't know which one to return");
+ return this.getScaleX();
+ },
+
+ /**
+ * Sets callback name to widget.
+ * @since v3.3
+ * @param {String} callbackName
+ */
+ setCallbackName: function (callbackName) {
+ this._callbackName = callbackName;
+ },
+
+ /**
+ * Gets callback name of widget
+ * @since v3.3
+ * @returns {String|Null}
+ */
+ getCallbackName: function () {
+ return this._callbackName;
+ },
+
+ /**
+ * Sets callback type to widget
+ * @since v3.3
+ * @param {String} callbackType
+ */
+ setCallbackType: function (callbackType) {
+ this._callbackType = callbackType;
+ },
+
+ /**
+ * Gets callback type of widget
+ * @since v3.3
+ * @returns {String|null}
+ */
+ getCallbackType: function () {
+ return this._callbackType;
+ },
+
+ /**
+ * Whether enable layout component of a widget
+ * @since v3.3
+ * @param {Boolean} enable enable layout Component of a widget
+ */
+ setLayoutComponentEnabled: function(enable){
+ this._usingLayoutComponent = enable;
+ },
+
+ /**
+ * Returns whether enable layout component of a widget
+ * @return {Boolean} true represent the widget use Layout Component, false represent the widget couldn't use Layout Component.
+ */
+ isLayoutComponentEnabled: function(){
+ return this._usingLayoutComponent;
+ },
+
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ return new ccui.Widget.WebGLRenderCmd(this);
+ else
+ return new ccui.Widget.CanvasRenderCmd(this);
+ }
+});
+
+var _p = ccui.Widget.prototype;
+
+// Extended properties
+/** @expose */
+_p.xPercent;
+cc.defineGetterSetter(_p, "xPercent", _p._getXPercent, _p._setXPercent);
+/** @expose */
+_p.yPercent;
+cc.defineGetterSetter(_p, "yPercent", _p._getYPercent, _p._setYPercent);
+/** @expose */
+_p.widthPercent;
+cc.defineGetterSetter(_p, "widthPercent", _p._getWidthPercent, _p._setWidthPercent);
+/** @expose */
+_p.heightPercent;
+cc.defineGetterSetter(_p, "heightPercent", _p._getHeightPercent, _p._setHeightPercent);
+/** @expose */
+_p.widgetParent;
+cc.defineGetterSetter(_p, "widgetParent", _p.getWidgetParent);
+/** @expose */
+_p.enabled;
+cc.defineGetterSetter(_p, "enabled", _p.isEnabled, _p.setEnabled);
+/** @expose */
+_p.focused;
+cc.defineGetterSetter(_p, "focused", _p.isFocused, _p.setFocused);
+/** @expose */
+_p.sizeType;
+cc.defineGetterSetter(_p, "sizeType", _p.getSizeType, _p.setSizeType);
+/** @expose */
+_p.widgetType;
+cc.defineGetterSetter(_p, "widgetType", _p.getWidgetType);
+/** @expose */
+_p.touchEnabled;
+cc.defineGetterSetter(_p, "touchEnabled", _p.isTouchEnabled, _p.setTouchEnabled);
+/** @expose */
+_p.updateEnabled;
+cc.defineGetterSetter(_p, "updateEnabled", _p.isUpdateEnabled, _p.setUpdateEnabled);
+/** @expose */
+_p.bright;
+cc.defineGetterSetter(_p, "bright", _p.isBright, _p.setBright);
+/** @expose */
+_p.name;
+cc.defineGetterSetter(_p, "name", _p.getName, _p.setName);
+/** @expose */
+_p.actionTag;
+cc.defineGetterSetter(_p, "actionTag", _p.getActionTag, _p.setActionTag);
+/** @expose */
+_p.opacity;
+cc.defineGetterSetter(_p, "opacity", _p.getOpacity, _p.setOpacity);
+
+_p = null;
+
+/**
+ * allocates and initializes a UIWidget.
+ * @deprecated
+ * @return {ccui.Widget}
+ */
+ccui.Widget.create = function () {
+ return new ccui.Widget();
+};
+
+ccui.Widget._focusedWidget = null; //both layout & widget will be stored in this variable
+ccui.Widget._focusNavigationController = null;
+
+/**
+ * call this method with parameter true to enable the Android Dpad focus navigation feature
+ * @note it doesn't implemented on Web
+ * @param {Boolean} enable set true to enable dpad focus navigation, otherwise disable dpad focus navigation
+ */
+ccui.Widget.enableDpadNavigation = function (enable) {
+ if (enable) {
+ if (null == ccui.Widget._focusNavigationController) {
+ ccui.Widget._focusNavigationController = new ccui._FocusNavigationController();
+ if (ccui.Widget._focusedWidget) {
+ ccui.Widget._focusNavigationController._setFirstFocsuedWidget(ccui.Widget._focusedWidget);
+ }
+ }
+ ccui.Widget._focusNavigationController.enableFocusNavigation(true);
+ } else {
+ if (ccui.Widget._focusNavigationController) {
+ ccui.Widget._focusNavigationController.enableFocusNavigation(false);
+ ccui.Widget._focusNavigationController = null;
+ }
+ }
+};
+
+/**
+ * Gets the focused widget of current stage.
+ * @function
+ * @returns {null|ccui.Widget}
+ */
+ccui.Widget.getCurrentFocusedWidget = function () {
+ return ccui.Widget._focusedWidget;
+};
+
+// Constants
+//bright style
+/**
+ * None bright style of ccui.Widget.
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.BRIGHT_STYLE_NONE = -1;
+/**
+ * Normal bright style of ccui.Widget.
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.BRIGHT_STYLE_NORMAL = 0;
+/**
+ * Light bright style of ccui.Widget.
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.BRIGHT_STYLE_HIGH_LIGHT = 1;
+
+//widget type
+/**
+ * The type code of Widget for ccui controls.
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.TYPE_WIDGET = 0;
+/**
+ * The type code of Container for ccui controls.
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.TYPE_CONTAINER = 1;
+
+//Focus Direction
+/**
+ * The left of Focus direction for ccui.Widget
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.LEFT = 0;
+/**
+ * The right of Focus direction for ccui.Widget
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.RIGHT = 1;
+/**
+ * The up of Focus direction for ccui.Widget
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.UP = 2;
+/**
+ * The down of Focus direction for ccui.Widget
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.DOWN = 3;
+
+//texture resource type
+/**
+ * The image file texture type of ccui.Widget loads.
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.LOCAL_TEXTURE = 0;
+/**
+ * The sprite frame texture type of ccui.Widget loads.
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.PLIST_TEXTURE = 1;
+
+//touch event type
+/**
+ * The touch began type of ccui.Widget's touch event
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.TOUCH_BEGAN = 0;
+/**
+ * The touch moved type of ccui.Widget's touch event
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.TOUCH_MOVED = 1;
+/**
+ * The touch end type of ccui.Widget's touch event
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.TOUCH_ENDED = 2;
+/**
+ * The touch canceled type of ccui.Widget's touch event
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.TOUCH_CANCELED = 3;
+
+//size type
+/**
+ * The absolute of ccui.Widget's size type.
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.SIZE_ABSOLUTE = 0;
+/**
+ * The percent of ccui.Widget's size type.
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.SIZE_PERCENT = 1;
+
+//position type
+/**
+ * The absolute of ccui.Widget's position type.
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.POSITION_ABSOLUTE = 0;
+/**
+ * The percent of ccui.Widget's position type.
+ * @constant
+ * @type {number}
+ */
+ccui.Widget.POSITION_PERCENT = 1;
diff --git a/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIWidgetRenderCmd.js b/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIWidgetRenderCmd.js
new file mode 100644
index 0000000..fca76f9
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/base-classes/UIWidgetRenderCmd.js
@@ -0,0 +1,126 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
+ ccui.Widget.CanvasRenderCmd = function (renderable) {
+ this._pNodeCmdCtor(renderable);
+ this._needDraw = false;
+ };
+
+ var proto = ccui.Widget.CanvasRenderCmd.prototype = Object.create(cc.ProtectedNode.CanvasRenderCmd.prototype);
+ proto.constructor = ccui.Widget.CanvasRenderCmd;
+
+ proto.visit = function (parentCmd) {
+ var node = this._node, renderer = cc.renderer;
+
+ parentCmd = parentCmd || this.getParentRenderCmd();
+ if (parentCmd)
+ this._curLevel = parentCmd._curLevel + 1;
+
+ if (isNaN(node._customZ)) {
+ node._vertexZ = renderer.assignedZ;
+ renderer.assignedZ += renderer.assignedZStep;
+ }
+
+ node._adaptRenderers();
+ this._syncStatus(parentCmd);
+ };
+
+ proto.transform = function (parentCmd, recursive) {
+ if (!this._transform) {
+ this._transform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ this._worldTransform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ }
+
+ var node = this._node;
+ if (node._visible && node._running) {
+ node._adaptRenderers();
+ if(!this._usingLayoutComponent){
+ var widgetParent = node.getWidgetParent();
+ if (widgetParent) {
+ var parentSize = widgetParent.getContentSize();
+ if (parentSize.width !== 0 && parentSize.height !== 0) {
+ node._position.x = parentSize.width * node._positionPercent.x;
+ node._position.y = parentSize.height * node._positionPercent.y;
+ }
+ }
+ }
+ this.pNodeTransform(parentCmd, recursive);
+ }
+ };
+
+ proto.widgetTransform = proto.transform;
+ } else {
+ ccui.Widget.WebGLRenderCmd = function (renderable) {
+ this._pNodeCmdCtor(renderable);
+ this._needDraw = false;
+ };
+
+ var proto = ccui.Widget.WebGLRenderCmd.prototype = Object.create(cc.ProtectedNode.WebGLRenderCmd.prototype);
+ proto.constructor = ccui.Widget.WebGLRenderCmd;
+
+ proto.visit = function (parentCmd) {
+ var node = this._node, renderer = cc.renderer;
+
+ parentCmd = parentCmd || this.getParentRenderCmd();
+ if (parentCmd)
+ this._curLevel = parentCmd._curLevel + 1;
+
+ if (isNaN(node._customZ)) {
+ node._vertexZ = renderer.assignedZ;
+ renderer.assignedZ += renderer.assignedZStep;
+ }
+
+ node._adaptRenderers();
+ this._syncStatus(parentCmd);
+ };
+
+ proto.transform = function (parentCmd, recursive) {
+ if (!this._transform) {
+ this._transform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ this._worldTransform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ }
+
+ var node = this._node;
+ if (node._visible && node._running) {
+ node._adaptRenderers();
+
+ if(!this._usingLayoutComponent) {
+ var widgetParent = node.getWidgetParent();
+ if (widgetParent) {
+ var parentSize = widgetParent.getContentSize();
+ if (parentSize.width !== 0 && parentSize.height !== 0) {
+ node._position.x = parentSize.width * node._positionPercent.x;
+ node._position.y = parentSize.height * node._positionPercent.y;
+ }
+ }
+ }
+ this.pNodeTransform(parentCmd, recursive);
+ }
+ };
+
+ proto.widgetTransform = proto.transform;
+ }
+});
diff --git a/frameworks/cocos2d-html5/extensions/ccui/layouts/UIHBox.js b/frameworks/cocos2d-html5/extensions/ccui/layouts/UIHBox.js
new file mode 100644
index 0000000..f808668
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/layouts/UIHBox.js
@@ -0,0 +1,55 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The horizontal box of Cocos UI. Its layout type is ccui.Layout.LINEAR_HORIZONTAL.
+ * @class
+ * @extends ccui.Layout
+ */
+ccui.HBox = ccui.Layout.extend(/** @lends ccui.HBox# */{
+ /**
+ * The constructor of ccui.HBox
+ * @function
+ * @param {cc.Size} [size]
+ */
+ ctor: function(size){
+ ccui.Layout.prototype.ctor.call(this);
+ this.setLayoutType(ccui.Layout.LINEAR_HORIZONTAL);
+
+ if(size) {
+ this.setContentSize(size);
+ }
+ }
+});
+
+/**
+ * Creates a HBox object
+ * @deprecated since v3.0, please use new ccui.HBox(size) instead.
+ * @param {cc.Size} size
+ * @returns {ccui.HBox}
+ */
+ccui.HBox.create = function(size){
+ return new ccui.HBox(size);
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayout.js b/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayout.js
new file mode 100644
index 0000000..34361aa
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayout.js
@@ -0,0 +1,1571 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * ccui.Layout is the base class of ccui.PageView and ccui.ScrollView, it does layout by layout manager
+ * and clips area by its _clippingStencil when clippingEnabled is true.
+ * @class
+ * @extends ccui.Widget
+ *
+ * @property {Boolean} clippingEnabled - Indicate whether clipping is enabled
+ * @property {ccui.Layout.CLIPPING_STENCIL|ccui.Layout.CLIPPING_SCISSOR} clippingType
+ * @property {ccui.Layout.ABSOLUTE|ccui.Layout.LINEAR_VERTICAL|ccui.Layout.LINEAR_HORIZONTAL|ccui.Layout.RELATIVE} layoutType
+ *
+ */
+ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{
+ _clippingEnabled: false,
+ _backGroundScale9Enabled: null,
+ _backGroundImage: null,
+ _backGroundImageFileName: null,
+ _backGroundImageCapInsets: null,
+ _colorType: null,
+ _bgImageTexType: ccui.Widget.LOCAL_TEXTURE,
+ _colorRender: null,
+ _gradientRender: null,
+ _color: null,
+ _startColor: null,
+ _endColor: null,
+ _alongVector: null,
+ _opacity: 255,
+ _backGroundImageTextureSize: null,
+ _layoutType: null,
+ _doLayoutDirty: true,
+ _clippingRectDirty: true,
+ _clippingType: null,
+ _clippingStencil: null,
+ _scissorRectDirty: false,
+ _clippingRect: null,
+ _clippingParent: null,
+ _className: "Layout",
+ _backGroundImageColor: null,
+ _finalPositionX: 0,
+ _finalPositionY: 0,
+
+ _backGroundImageOpacity: 0,
+
+ _loopFocus: false, //whether enable loop focus or not
+ __passFocusToChild: true, //on default, it will pass the focus to the next nearest widget
+ _isFocusPassing: false, //when finding the next focused widget, use this variable to pass focus between layout & widget
+ _isInterceptTouch: false,
+
+ /**
+ * Allocates and initializes an UILayout.
+ * Constructor of ccui.Layout
+ * @function
+ * @example
+ * // example
+ * var uiLayout = new ccui.Layout();
+ */
+ ctor: function () {
+ this._layoutType = ccui.Layout.ABSOLUTE;
+ this._widgetType = ccui.Widget.TYPE_CONTAINER;
+ this._clippingType = ccui.Layout.CLIPPING_SCISSOR;
+ this._colorType = ccui.Layout.BG_COLOR_NONE;
+
+ ccui.Widget.prototype.ctor.call(this);
+
+ this.ignoreContentAdaptWithSize(false);
+ this.setContentSize(cc.size(0, 0));
+ this.setAnchorPoint(0, 0);
+ this.onPassFocusToChild = this._findNearestChildWidgetIndex.bind(this);
+
+ this._backGroundImageCapInsets = cc.rect(0, 0, 0, 0);
+
+ this._color = cc.color(255, 255, 255, 255);
+ this._startColor = cc.color(255, 255, 255, 255);
+ this._endColor = cc.color(255, 255, 255, 255);
+ this._alongVector = cc.p(0, -1);
+ this._backGroundImageTextureSize = cc.size(0, 0);
+
+ this._clippingRect = cc.rect(0, 0, 0, 0);
+ this._backGroundImageColor = cc.color(255, 255, 255, 255);
+ },
+
+ /**
+ * Calls its parent's onEnter, and calls its clippingStencil's onEnter if clippingStencil isn't null.
+ * @override
+ */
+ onEnter: function () {
+ ccui.Widget.prototype.onEnter.call(this);
+ if (this._clippingStencil)
+ this._clippingStencil._performRecursive(cc.Node._stateCallbackType.onEnter);
+ this._doLayoutDirty = true;
+ this._clippingRectDirty = true;
+ },
+
+ /**
+ * Calls its parent's onExit, and calls its clippingStencil's onExit if clippingStencil isn't null.
+ * @override
+ */
+ onExit: function () {
+ ccui.Widget.prototype.onExit.call(this);
+ if (this._clippingStencil)
+ this._clippingStencil._performRecursive(cc.Node._stateCallbackType.onExit);
+ },
+
+ /**
+ *
+ * Calls adaptRenderers (its subclass will override it.) and do layout.
+ * If clippingEnabled is true, it will clip/scissor area.
+ *
+ * @override
+ * @param {cc.Node} [parent]
+ */
+ visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
+
+ this._adaptRenderers();
+ this._doLayout();
+
+ var renderer = cc.renderer;
+ cmd.visit(parentCmd);
+
+ var stencilClipping = this._clippingEnabled && this._clippingType === ccui.Layout.CLIPPING_STENCIL;
+ var scissorClipping = this._clippingEnabled && this._clippingType === ccui.Layout.CLIPPING_SCISSOR;
+
+ if (stencilClipping) {
+ cmd.stencilClippingVisit(parentCmd);
+ }
+ else if (scissorClipping) {
+ cmd.scissorClippingVisit(parentCmd);
+ }
+
+ var i, children = this._children, len = children.length, child;
+ var j, pChildren = this._protectedChildren, pLen = pChildren.length, pChild;
+
+ if (this._reorderChildDirty) this.sortAllChildren();
+ if (this._reorderProtectedChildDirty) this.sortAllProtectedChildren();
+ // draw children zOrder < 0
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder < 0) {
+ child.visit(this);
+ }
+ else break;
+ }
+ for (j = 0; j < pLen; j++) {
+ pChild = pChildren[j];
+ if (pChild._localZOrder < 0) {
+ cmd._changeProtectedChild(pChild);
+ pChild.visit(this);
+ }
+ else break;
+ }
+ // draw children zOrder >= 0
+ for (; i < len; i++) {
+ children[i].visit(this);
+ }
+ for (; j < pLen; j++) {
+ pChild = pChildren[j];
+ cmd._changeProtectedChild(pChild);
+ pChild.visit(this);
+ }
+
+ if (stencilClipping) {
+ cmd.postStencilVisit();
+ }
+ else if (scissorClipping) {
+ cmd.postScissorVisit();
+ }
+
+ cmd._dirtyFlag = 0;
+ },
+
+ /**
+ * If a layout is loop focused which means that the focus movement will be inside the layout
+ * @param {Boolean} loop pass true to let the focus movement loop inside the layout
+ */
+ setLoopFocus: function (loop) {
+ this._loopFocus = loop;
+ },
+
+ /**
+ * Gets whether enable focus loop
+ * @returns {boolean} If focus loop is enabled, then it will return true, otherwise it returns false. The default value is false.
+ */
+ isLoopFocus: function () {
+ return this._loopFocus;
+ },
+
+ /**
+ * Specifies whether the layout pass its focus to its child
+ * @param pass To specify whether the layout pass its focus to its child
+ */
+ setPassFocusToChild: function (pass) {
+ this.__passFocusToChild = pass;
+ },
+
+ /**
+ * Returns whether the layout will pass the focus to its children or not. The default value is true
+ * @returns {boolean} To query whether the layout will pass the focus to its children or not. The default value is true
+ */
+ isPassFocusToChild: function () {
+ return this.__passFocusToChild;
+ },
+
+ /**
+ * When a widget is in a layout, you could call this method to get the next focused widget within a specified direction.
+ * If the widget is not in a layout, it will return itself
+ * @param {Number} direction the direction to look for the next focused widget in a layout
+ * @param {ccui.Widget} current the current focused widget
+ * @returns {ccui.Widget} return the index of widget in the layout
+ */
+ findNextFocusedWidget: function (direction, current) {
+ if (this._isFocusPassing || this.isFocused()) {
+ var parent = this.getParent();
+ this._isFocusPassing = false;
+ if (this.__passFocusToChild) {
+ var w = this._passFocusToChild(direction, current);
+ if (w instanceof ccui.Layout && parent) {
+ parent._isFocusPassing = true;
+ return parent.findNextFocusedWidget(direction, this);
+ }
+ return w;
+ }
+
+ if (null == parent || !(parent instanceof ccui.Layout))
+ return this;
+ parent._isFocusPassing = true;
+ return parent.findNextFocusedWidget(direction, this);
+ } else if (current.isFocused() || current instanceof ccui.Layout) {
+ if (this._layoutType === ccui.Layout.LINEAR_HORIZONTAL) {
+ switch (direction) {
+ case ccui.Widget.LEFT:
+ return this._getPreviousFocusedWidget(direction, current);
+ break;
+ case ccui.Widget.RIGHT:
+ return this._getNextFocusedWidget(direction, current);
+ break;
+ case ccui.Widget.DOWN:
+ case ccui.Widget.UP:
+ if (this._isLastWidgetInContainer(this, direction)) {
+ if (this._isWidgetAncestorSupportLoopFocus(current, direction))
+ return ccui.Widget.prototype.findNextFocusedWidget.call(this, direction, this);
+ return current;
+ } else {
+ return ccui.Widget.prototype.findNextFocusedWidget.call(this, direction, this);
+ }
+ break;
+ default:
+ cc.assert(0, "Invalid Focus Direction");
+ return current;
+ }
+ } else if (this._layoutType === ccui.Layout.LINEAR_VERTICAL) {
+ switch (direction) {
+ case ccui.Widget.LEFT:
+ case ccui.Widget.RIGHT:
+ if (this._isLastWidgetInContainer(this, direction)) {
+ if (this._isWidgetAncestorSupportLoopFocus(current, direction))
+ return ccui.Widget.prototype.findNextFocusedWidget.call(this, direction, this);
+ return current;
+ }
+ else
+ return ccui.Widget.prototype.findNextFocusedWidget.call(this, direction, this);
+ break;
+ case ccui.Widget.DOWN:
+ return this._getNextFocusedWidget(direction, current);
+ break;
+ case ccui.Widget.UP:
+ return this._getPreviousFocusedWidget(direction, current);
+ break;
+ default:
+ cc.assert(0, "Invalid Focus Direction");
+ return current;
+ }
+ } else {
+ cc.assert(0, "Un Supported Layout type, please use VBox and HBox instead!!!");
+ return current;
+ }
+ } else
+ return current;
+ },
+
+ /**
+ * To specify a user-defined functor to decide which child widget of the layout should get focused
+ * @function
+ * @param {Number} direction
+ * @param {ccui.Widget} current
+ */
+ onPassFocusToChild: null,
+
+ /**
+ * Adds a widget to the container.
+ * @param {ccui.Widget} widget
+ * @param {Number} [zOrder]
+ * @param {Number|string} [tag] tag or name
+ * @override
+ */
+ addChild: function (widget, zOrder, tag) {
+ if ((widget instanceof ccui.Widget)) {
+ this._supplyTheLayoutParameterLackToChild(widget);
+ }
+ ccui.Widget.prototype.addChild.call(this, widget, zOrder, tag);
+ this._doLayoutDirty = true;
+ },
+
+ /**
+ * Removes child widget from ccui.Layout, and sets the layout dirty flag to true.
+ * @param {ccui.Widget} widget
+ * @param {Boolean} [cleanup=true]
+ * @override
+ */
+ removeChild: function (widget, cleanup) {
+ ccui.Widget.prototype.removeChild.call(this, widget, cleanup);
+ this._doLayoutDirty = true;
+ },
+
+ /**
+ * Removes all children from the container with a cleanup, and sets the layout dirty flag to true.
+ * @param {Boolean} cleanup
+ */
+ removeAllChildren: function (cleanup) {
+ ccui.Widget.prototype.removeAllChildren.call(this, cleanup);
+ this._doLayoutDirty = true;
+ },
+
+ /**
+ * Removes all children from the container, do a cleanup to all running actions depending on the cleanup parameter,
+ * and sets the layout dirty flag to true.
+ * @param {Boolean} cleanup true if all running actions on all children nodes should be cleanup, false otherwise.
+ */
+ removeAllChildrenWithCleanup: function (cleanup) {
+ ccui.Widget.prototype.removeAllChildrenWithCleanup.call(this, cleanup);
+ this._doLayoutDirty = true;
+ },
+
+ /**
+ * Gets if layout is clipping enabled.
+ * @returns {Boolean} if layout is clipping enabled.
+ */
+ isClippingEnabled: function () {
+ return this._clippingEnabled;
+ },
+
+ /**
+ * Changes if layout can clip it's content and locChild.
+ * If you really need this, please enable it. But it would reduce the rendering efficiency.
+ * @param {Boolean} able clipping enabled.
+ */
+ setClippingEnabled: function (able) {
+ if (able === this._clippingEnabled)
+ return;
+ this._clippingEnabled = able;
+ switch (this._clippingType) {
+ case ccui.Layout.CLIPPING_SCISSOR:
+ case ccui.Layout.CLIPPING_STENCIL:
+ if (able) {
+ this._clippingStencil = new cc.DrawNode();
+ this._renderCmd.rebindStencilRendering(this._clippingStencil);
+ if (this._running)
+ this._clippingStencil._performRecursive(cc.Node._stateCallbackType.onEnter);
+ this._setStencilClippingSize(this._contentSize);
+ } else {
+ if (this._running && this._clippingStencil)
+ this._clippingStencil._performRecursive(cc.Node._stateCallbackType.onExit);
+ this._clippingStencil = null;
+ }
+ break;
+ default:
+ break;
+ }
+ },
+
+ /**
+ * Sets clipping type to ccui.Layout
+ * @param {ccui.Layout.CLIPPING_STENCIL|ccui.Layout.CLIPPING_SCISSOR} type
+ */
+ setClippingType: function (type) {
+ if (type === this._clippingType)
+ return;
+ var clippingEnabled = this.isClippingEnabled();
+ this.setClippingEnabled(false);
+ this._clippingType = type;
+ this.setClippingEnabled(clippingEnabled);
+ },
+
+ /**
+ * Gets clipping type of ccui.Layout
+ * @returns {ccui.Layout.CLIPPING_STENCIL|ccui.Layout.CLIPPING_SCISSOR}
+ */
+ getClippingType: function () {
+ return this._clippingType;
+ },
+
+ _setStencilClippingSize: function (size) {
+ if (this._clippingEnabled) {
+ var rect = [];
+ rect[0] = cc.p(0, 0);
+ rect[1] = cc.p(size.width, 0);
+ rect[2] = cc.p(size.width, size.height);
+ rect[3] = cc.p(0, size.height);
+ var green = cc.color.GREEN;
+ this._clippingStencil.clear();
+ this._clippingStencil.setLocalBB && this._clippingStencil.setLocalBB(0, 0, size.width, size.height);
+ this._clippingStencil.drawPoly(rect, 4, green, 0, green);
+ }
+ },
+
+ _getClippingRect: function () {
+ if (this._clippingRectDirty) {
+ var worldPos = this.convertToWorldSpace(cc.p(0, 0));
+ var t = this.getNodeToWorldTransform();
+ var scissorWidth = this._contentSize.width * t.a;
+ var scissorHeight = this._contentSize.height * t.d;
+ var parentClippingRect;
+ var parent = this;
+
+ while (parent) {
+ parent = parent.getParent();
+ if (parent && parent instanceof ccui.Layout && parent.isClippingEnabled()) {
+ this._clippingParent = parent;
+ break;
+ }
+ }
+
+ if (this._clippingParent) {
+ parentClippingRect = this._clippingParent._getClippingRect();
+
+ this._clippingRect.x = Math.max(worldPos.x, parentClippingRect.x);
+ this._clippingRect.y = Math.max(worldPos.y, parentClippingRect.y);
+
+ var right = Math.min(worldPos.x + scissorWidth, parentClippingRect.x + parentClippingRect.width);
+ var top = Math.min(worldPos.y + scissorHeight, parentClippingRect.y + parentClippingRect.height);
+
+ this._clippingRect.width = Math.max(0.0, right - this._clippingRect.x);
+ this._clippingRect.height = Math.max(0.0, top - this._clippingRect.y);
+ } else {
+ this._clippingRect.x = worldPos.x;
+ this._clippingRect.y = worldPos.y;
+ this._clippingRect.width = scissorWidth;
+ this._clippingRect.height = scissorHeight;
+ }
+ this._clippingRectDirty = false;
+ }
+ return this._clippingRect;
+ },
+
+ _onSizeChanged: function () {
+ ccui.Widget.prototype._onSizeChanged.call(this);
+ var locContentSize = this._contentSize;
+ this._setStencilClippingSize(locContentSize);
+ this._doLayoutDirty = true;
+ this._clippingRectDirty = true;
+ if (this._backGroundImage) {
+ this._backGroundImage.setPosition(locContentSize.width * 0.5, locContentSize.height * 0.5);
+ if (this._backGroundScale9Enabled && this._backGroundImage instanceof ccui.Scale9Sprite)
+ this._backGroundImage.setPreferredSize(locContentSize);
+ }
+ if (this._colorRender)
+ this._colorRender.setContentSize(locContentSize);
+ if (this._gradientRender)
+ this._gradientRender.setContentSize(locContentSize);
+ },
+
+ /**
+ * Sets background image use scale9 renderer.
+ * @param {Boolean} able true that use scale9 renderer, false otherwise.
+ */
+ setBackGroundImageScale9Enabled: function (able) {
+ if (this._backGroundScale9Enabled === able)
+ return;
+ this.removeProtectedChild(this._backGroundImage);
+ this._backGroundImage = null;
+ this._backGroundScale9Enabled = able;
+ this._addBackGroundImage();
+ this.setBackGroundImage(this._backGroundImageFileName, this._bgImageTexType);
+ this.setBackGroundImageCapInsets(this._backGroundImageCapInsets);
+ },
+
+ /**
+ * Get whether background image is use scale9 renderer.
+ * @returns {Boolean}
+ */
+ isBackGroundImageScale9Enabled: function () {
+ return this._backGroundScale9Enabled;
+ },
+
+ /**
+ * Sets a background image for layout
+ * @param {String} fileName
+ * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
+ */
+ setBackGroundImage: function (fileName, texType) {
+ if (!fileName)
+ return;
+ texType = texType || ccui.Widget.LOCAL_TEXTURE;
+ if (this._backGroundImage === null) {
+ this._addBackGroundImage();
+ this.setBackGroundImageScale9Enabled(this._backGroundScale9Enabled);
+ }
+ this._backGroundImageFileName = fileName;
+ this._bgImageTexType = texType;
+ var locBackgroundImage = this._backGroundImage;
+ switch (this._bgImageTexType) {
+ case ccui.Widget.LOCAL_TEXTURE:
+ locBackgroundImage.initWithFile(fileName);
+ break;
+ case ccui.Widget.PLIST_TEXTURE:
+ locBackgroundImage.initWithSpriteFrameName(fileName);
+ break;
+ default:
+ break;
+ }
+ if (this._backGroundScale9Enabled)
+ locBackgroundImage.setPreferredSize(this._contentSize);
+
+ this._backGroundImageTextureSize = locBackgroundImage.getContentSize();
+ locBackgroundImage.setPosition(this._contentSize.width * 0.5, this._contentSize.height * 0.5);
+ this._updateBackGroundImageColor();
+ },
+
+ /**
+ * Sets a background image CapInsets for layout, if the background image is a scale9 render.
+ * @param {cc.Rect} capInsets capinsets of background image.
+ */
+ setBackGroundImageCapInsets: function (capInsets) {
+ if (!capInsets)
+ return;
+ var locInsets = this._backGroundImageCapInsets;
+ locInsets.x = capInsets.x;
+ locInsets.y = capInsets.y;
+ locInsets.width = capInsets.width;
+ locInsets.height = capInsets.height;
+ if (this._backGroundScale9Enabled)
+ this._backGroundImage.setCapInsets(capInsets);
+ },
+
+ /**
+ * Gets background image capinsets of ccui.Layout.
+ * @returns {cc.Rect}
+ */
+ getBackGroundImageCapInsets: function () {
+ return cc.rect(this._backGroundImageCapInsets);
+ },
+
+ _supplyTheLayoutParameterLackToChild: function (locChild) {
+ if (!locChild) {
+ return;
+ }
+ switch (this._layoutType) {
+ case ccui.Layout.ABSOLUTE:
+ break;
+ case ccui.Layout.LINEAR_HORIZONTAL:
+ case ccui.Layout.LINEAR_VERTICAL:
+ var layoutParameter = locChild.getLayoutParameter(ccui.LayoutParameter.LINEAR);
+ if (!layoutParameter)
+ locChild.setLayoutParameter(new ccui.LinearLayoutParameter());
+ break;
+ case ccui.Layout.RELATIVE:
+ var layoutParameter = locChild.getLayoutParameter(ccui.LayoutParameter.RELATIVE);
+ if (!layoutParameter)
+ locChild.setLayoutParameter(new ccui.RelativeLayoutParameter());
+ break;
+ default:
+ break;
+ }
+ },
+
+ _addBackGroundImage: function () {
+ var contentSize = this._contentSize;
+ if (this._backGroundScale9Enabled) {
+ this._backGroundImage = new ccui.Scale9Sprite();
+ this._backGroundImage.setPreferredSize(contentSize);
+ } else
+ this._backGroundImage = new cc.Sprite();
+ this.addProtectedChild(this._backGroundImage, ccui.Layout.BACKGROUND_IMAGE_ZORDER, -1);
+ this._backGroundImage.setPosition(contentSize.width * 0.5, contentSize.height * 0.5);
+ },
+
+ /**
+ * Remove the background image of ccui.Layout.
+ */
+ removeBackGroundImage: function () {
+ if (!this._backGroundImage)
+ return;
+ this.removeProtectedChild(this._backGroundImage);
+ this._backGroundImage = null;
+ this._backGroundImageFileName = "";
+ this._backGroundImageTextureSize.width = 0;
+ this._backGroundImageTextureSize.height = 0;
+ },
+
+ /**
+ * Sets Color Type for ccui.Layout.
+ * @param {ccui.Layout.BG_COLOR_NONE|ccui.Layout.BG_COLOR_SOLID|ccui.Layout.BG_COLOR_GRADIENT} type
+ */
+ setBackGroundColorType: function (type) {
+ if (this._colorType === type)
+ return;
+ switch (this._colorType) {
+ case ccui.Layout.BG_COLOR_NONE:
+ if (this._colorRender) {
+ this.removeProtectedChild(this._colorRender);
+ this._colorRender = null;
+ }
+ if (this._gradientRender) {
+ this.removeProtectedChild(this._gradientRender);
+ this._gradientRender = null;
+ }
+ break;
+ case ccui.Layout.BG_COLOR_SOLID:
+ if (this._colorRender) {
+ this.removeProtectedChild(this._colorRender);
+ this._colorRender = null;
+ }
+ break;
+ case ccui.Layout.BG_COLOR_GRADIENT:
+ if (this._gradientRender) {
+ this.removeProtectedChild(this._gradientRender);
+ this._gradientRender = null;
+ }
+ break;
+ default:
+ break;
+ }
+ this._colorType = type;
+ switch (this._colorType) {
+ case ccui.Layout.BG_COLOR_NONE:
+ break;
+ case ccui.Layout.BG_COLOR_SOLID:
+ this._colorRender = new cc.LayerColor();
+ this._colorRender.setContentSize(this._contentSize);
+ this._colorRender.setOpacity(this._opacity);
+ this._colorRender.setColor(this._color);
+ this.addProtectedChild(this._colorRender, ccui.Layout.BACKGROUND_RENDERER_ZORDER, -1);
+ break;
+ case ccui.Layout.BG_COLOR_GRADIENT:
+ this._gradientRender = new cc.LayerGradient(cc.color(255, 0, 0, 255), cc.color(0, 255, 0, 255));
+ this._gradientRender.setContentSize(this._contentSize);
+ this._gradientRender.setOpacity(this._opacity);
+ this._gradientRender.setStartColor(this._startColor);
+ this._gradientRender.setEndColor(this._endColor);
+ this._gradientRender.setVector(this._alongVector);
+ this.addProtectedChild(this._gradientRender, ccui.Layout.BACKGROUND_RENDERER_ZORDER, -1);
+ break;
+ default:
+ break;
+ }
+ },
+
+ /**
+ * Get background color type of ccui.Layout.
+ * @returns {ccui.Layout.BG_COLOR_NONE|ccui.Layout.BG_COLOR_SOLID|ccui.Layout.BG_COLOR_GRADIENT}
+ */
+ getBackGroundColorType: function () {
+ return this._colorType;
+ },
+
+ /**
+ * Sets background color for layout, if color type is Layout.COLOR_SOLID
+ * @param {cc.Color} color
+ * @param {cc.Color} [endColor]
+ */
+ setBackGroundColor: function (color, endColor) {
+ if (!endColor) {
+ this._color.r = color.r;
+ this._color.g = color.g;
+ this._color.b = color.b;
+ if (this._colorRender)
+ this._colorRender.setColor(color);
+ } else {
+ this._startColor.r = color.r;
+ this._startColor.g = color.g;
+ this._startColor.b = color.b;
+ if (this._gradientRender)
+ this._gradientRender.setStartColor(color);
+
+ this._endColor.r = endColor.r;
+ this._endColor.g = endColor.g;
+ this._endColor.b = endColor.b;
+ if (this._gradientRender)
+ this._gradientRender.setEndColor(endColor);
+ }
+ },
+
+ /**
+ * Gets background color of ccui.Layout, if color type is Layout.COLOR_SOLID.
+ * @returns {cc.Color}
+ */
+ getBackGroundColor: function () {
+ var tmpColor = this._color;
+ return cc.color(tmpColor.r, tmpColor.g, tmpColor.b, tmpColor.a);
+ },
+
+ /**
+ * Gets background start color of ccui.Layout
+ * @returns {cc.Color}
+ */
+ getBackGroundStartColor: function () {
+ var tmpColor = this._startColor;
+ return cc.color(tmpColor.r, tmpColor.g, tmpColor.b, tmpColor.a);
+ },
+
+ /**
+ * Gets background end color of ccui.Layout
+ * @returns {cc.Color}
+ */
+ getBackGroundEndColor: function () {
+ var tmpColor = this._endColor;
+ return cc.color(tmpColor.r, tmpColor.g, tmpColor.b, tmpColor.a);
+ },
+
+ /**
+ * Sets background opacity to ccui.Layout.
+ * @param {number} opacity
+ */
+ setBackGroundColorOpacity: function (opacity) {
+ this._opacity = opacity;
+ switch (this._colorType) {
+ case ccui.Layout.BG_COLOR_NONE:
+ break;
+ case ccui.Layout.BG_COLOR_SOLID:
+ this._colorRender.setOpacity(opacity);
+ break;
+ case ccui.Layout.BG_COLOR_GRADIENT:
+ this._gradientRender.setOpacity(opacity);
+ break;
+ default:
+ break;
+ }
+ },
+
+ /**
+ * Get background opacity value of ccui.Layout.
+ * @returns {Number}
+ */
+ getBackGroundColorOpacity: function () {
+ return this._opacity;
+ },
+
+ /**
+ * Sets background color vector for layout, if color type is Layout.COLOR_GRADIENT
+ * @param {cc.Point} vector
+ */
+ setBackGroundColorVector: function (vector) {
+ this._alongVector.x = vector.x;
+ this._alongVector.y = vector.y;
+ if (this._gradientRender) {
+ this._gradientRender.setVector(vector);
+ }
+ },
+
+ /**
+ * Gets background color vector of ccui.Layout, if color type is Layout.COLOR_GRADIENT
+ * @returns {cc.Point}
+ */
+ getBackGroundColorVector: function () {
+ return this._alongVector;
+ },
+
+ /**
+ * Sets backGround image color
+ * @param {cc.Color} color
+ */
+ setBackGroundImageColor: function (color) {
+ this._backGroundImageColor.r = color.r;
+ this._backGroundImageColor.g = color.g;
+ this._backGroundImageColor.b = color.b;
+
+ this._updateBackGroundImageColor();
+ },
+
+ /**
+ * Sets backGround image Opacity
+ * @param {Number} opacity
+ */
+ setBackGroundImageOpacity: function (opacity) {
+ this._backGroundImageColor.a = opacity;
+ this.getBackGroundImageColor();
+ },
+
+ /**
+ * Gets backGround image color
+ * @returns {cc.Color}
+ */
+ getBackGroundImageColor: function () {
+ var color = this._backGroundImageColor;
+ return cc.color(color.r, color.g, color.b, color.a);
+ },
+
+ /**
+ * Gets backGround image opacity
+ * @returns {Number}
+ */
+ getBackGroundImageOpacity: function () {
+ return this._backGroundImageColor.a;
+ },
+
+ _updateBackGroundImageColor: function () {
+ if (this._backGroundImage)
+ this._backGroundImage.setColor(this._backGroundImageColor);
+ },
+
+ /**
+ * Gets background image texture size.
+ * @returns {cc.Size}
+ */
+ getBackGroundImageTextureSize: function () {
+ return this._backGroundImageTextureSize;
+ },
+
+ /**
+ * Sets LayoutType to ccui.Layout, LayoutManager will do layout by layout type..
+ * @param {ccui.Layout.ABSOLUTE|ccui.Layout.LINEAR_VERTICAL|ccui.Layout.LINEAR_HORIZONTAL|ccui.Layout.RELATIVE} type
+ */
+ setLayoutType: function (type) {
+ this._layoutType = type;
+ var layoutChildrenArray = this._children;
+ var locChild = null;
+ for (var i = 0; i < layoutChildrenArray.length; i++) {
+ locChild = layoutChildrenArray[i];
+ if (locChild instanceof ccui.Widget)
+ this._supplyTheLayoutParameterLackToChild(locChild);
+ }
+ this._doLayoutDirty = true;
+ },
+
+ /**
+ * Gets LayoutType of ccui.Layout.
+ * @returns {null}
+ */
+ getLayoutType: function () {
+ return this._layoutType;
+ },
+
+ /**
+ * request to refresh widget layout, it will do layout at visit calls
+ */
+ requestDoLayout: function () {
+ this._doLayoutDirty = true;
+ },
+
+ _doLayout: function () {
+ if (!this._doLayoutDirty)
+ return;
+
+ this.sortAllChildren();
+
+ var executant = ccui.getLayoutManager(this._layoutType);
+ if (executant)
+ executant._doLayout(this);
+ this._doLayoutDirty = false;
+ },
+
+ _getLayoutContentSize: function () {
+ return this.getContentSize();
+ },
+
+ _getLayoutElements: function () {
+ return this.getChildren();
+ },
+
+ _updateBackGroundImageOpacity: function () {
+ if (this._backGroundImage)
+ this._backGroundImage.setOpacity(this._backGroundImageOpacity);
+ },
+
+ _updateBackGroundImageRGBA: function () {
+ if (this._backGroundImage) {
+ this._backGroundImage.setColor(this._backGroundImageColor);
+ this._backGroundImage.setOpacity(this._backGroundImageOpacity);
+ }
+ },
+
+ /**
+ * Gets the content size of the layout, it will accumulate all its children's content size
+ * @returns {cc.Size}
+ * @private
+ */
+ _getLayoutAccumulatedSize: function () {
+ var children = this.getChildren();
+ var layoutSize = cc.size(0, 0);
+ var widgetCount = 0, locSize;
+ for (var i = 0, len = children.length; i < len; i++) {
+ var layout = children[i];
+ if (null !== layout && layout instanceof ccui.Layout) {
+ locSize = layout._getLayoutAccumulatedSize();
+ layoutSize.width += locSize.width;
+ layoutSize.height += locSize.height;
+ } else {
+ if (layout instanceof ccui.Widget) {
+ widgetCount++;
+ var m = layout.getLayoutParameter().getMargin();
+ locSize = layout.getContentSize();
+ layoutSize.width += locSize.width + (m.right + m.left) * 0.5;
+ layoutSize.height += locSize.height + (m.top + m.bottom) * 0.5;
+ }
+ }
+ }
+
+ //substract extra size
+ var type = this.getLayoutType();
+ if (type === ccui.Layout.LINEAR_HORIZONTAL)
+ layoutSize.height = layoutSize.height - layoutSize.height / widgetCount * (widgetCount - 1);
+
+ if (type === ccui.Layout.LINEAR_VERTICAL)
+ layoutSize.width = layoutSize.width - layoutSize.width / widgetCount * (widgetCount - 1);
+ return layoutSize;
+ },
+
+ /**
+ * When the layout get focused, it the layout pass the focus to its child, it will use this method to determine which child
+ * will get the focus. The current algorithm to determine which child will get focus is nearest-distance-priority algorithm
+ * @param {Number} direction next focused widget direction
+ * @param {ccui.Widget} baseWidget
+ * @returns {Number}
+ * @private
+ */
+ _findNearestChildWidgetIndex: function (direction, baseWidget) {
+ if (baseWidget == null || baseWidget === this)
+ return this._findFirstFocusEnabledWidgetIndex();
+
+ var index = 0, locChildren = this.getChildren();
+ var count = locChildren.length, widgetPosition;
+
+ var distance = cc.FLT_MAX, found = 0;
+ if (direction === ccui.Widget.LEFT || direction === ccui.Widget.RIGHT || direction === ccui.Widget.DOWN || direction === ccui.Widget.UP) {
+ widgetPosition = this._getWorldCenterPoint(baseWidget);
+ while (index < count) {
+ var w = locChildren[index];
+ if (w && w instanceof ccui.Widget && w.isFocusEnabled()) {
+ var length = (w instanceof ccui.Layout) ? w._calculateNearestDistance(baseWidget)
+ : cc.pLength(cc.pSub(this._getWorldCenterPoint(w), widgetPosition));
+ if (length < distance) {
+ found = index;
+ distance = length;
+ }
+ }
+ index++;
+ }
+ return found;
+ }
+ cc.log("invalid focus direction!");
+ return 0;
+ },
+
+ /**
+ * When the layout get focused, it the layout pass the focus to its child, it will use this method to determine which child
+ * will get the focus. The current algorithm to determine which child will get focus is farthest-distance-priority algorithm
+ * @param {Number} direction next focused widget direction
+ * @param {ccui.Widget} baseWidget
+ * @returns {Number} The index of child widget in the container
+ * @private
+ */
+ _findFarthestChildWidgetIndex: function (direction, baseWidget) {
+ if (baseWidget == null || baseWidget === this)
+ return this._findFirstFocusEnabledWidgetIndex();
+
+ var index = 0, locChildren = this.getChildren();
+ var count = locChildren.length;
+
+ var distance = -cc.FLT_MAX, found = 0;
+ if (direction === ccui.Widget.LEFT || direction === ccui.Widget.RIGHT || direction === ccui.Widget.DOWN || direction === ccui.Widget.UP) {
+ var widgetPosition = this._getWorldCenterPoint(baseWidget);
+ while (index < count) {
+ var w = locChildren[index];
+ if (w && w instanceof ccui.Widget && w.isFocusEnabled()) {
+ var length = (w instanceof ccui.Layout) ? w._calculateFarthestDistance(baseWidget)
+ : cc.pLength(cc.pSub(this._getWorldCenterPoint(w), widgetPosition));
+ if (length > distance) {
+ found = index;
+ distance = length;
+ }
+ }
+ index++;
+ }
+ return found;
+ }
+ cc.log("invalid focus direction!!!");
+ return 0;
+ },
+
+ /**
+ * calculate the nearest distance between the baseWidget and the children of the layout
+ * @param {ccui.Widget} baseWidget the base widget which will be used to calculate the distance between the layout's children and itself
+ * @returns {Number} return the nearest distance between the baseWidget and the layout's children
+ * @private
+ */
+ _calculateNearestDistance: function (baseWidget) {
+ var distance = cc.FLT_MAX;
+ var widgetPosition = this._getWorldCenterPoint(baseWidget);
+ var locChildren = this._children;
+
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ var widget = locChildren[i], length;
+ if (widget instanceof ccui.Layout)
+ length = widget._calculateNearestDistance(baseWidget);
+ else {
+ if (widget instanceof ccui.Widget && widget.isFocusEnabled())
+ length = cc.pLength(cc.pSub(this._getWorldCenterPoint(widget), widgetPosition));
+ else
+ continue;
+ }
+ if (length < distance)
+ distance = length;
+ }
+ return distance;
+ },
+
+ /**
+ * calculate the farthest distance between the baseWidget and the children of the layout
+ * @param baseWidget
+ * @returns {number}
+ * @private
+ */
+ _calculateFarthestDistance: function (baseWidget) {
+ var distance = -cc.FLT_MAX;
+ var widgetPosition = this._getWorldCenterPoint(baseWidget);
+ var locChildren = this._children;
+
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ var layout = locChildren[i];
+ var length;
+ if (layout instanceof ccui.Layout)
+ length = layout._calculateFarthestDistance(baseWidget);
+ else {
+ if (layout instanceof ccui.Widget && layout.isFocusEnabled()) {
+ var wPosition = this._getWorldCenterPoint(layout);
+ length = cc.pLength(cc.pSub(wPosition, widgetPosition));
+ } else
+ continue;
+ }
+
+ if (length > distance)
+ distance = length;
+ }
+ return distance;
+ },
+
+ /**
+ * when a layout pass the focus to it's child, use this method to determine which algorithm to use, nearest or farthest distance algorithm or not
+ * @param direction
+ * @param baseWidget
+ * @private
+ */
+ _findProperSearchingFunctor: function (direction, baseWidget) {
+ if (baseWidget === undefined)
+ return;
+
+ var previousWidgetPosition = this._getWorldCenterPoint(baseWidget);
+ var widgetPosition = this._getWorldCenterPoint(this._findFirstNonLayoutWidget());
+ if (direction === ccui.Widget.LEFT) {
+ this.onPassFocusToChild = (previousWidgetPosition.x > widgetPosition.x) ? this._findNearestChildWidgetIndex
+ : this._findFarthestChildWidgetIndex;
+ } else if (direction === ccui.Widget.RIGHT) {
+ this.onPassFocusToChild = (previousWidgetPosition.x > widgetPosition.x) ? this._findFarthestChildWidgetIndex
+ : this._findNearestChildWidgetIndex;
+ } else if (direction === ccui.Widget.DOWN) {
+ this.onPassFocusToChild = (previousWidgetPosition.y > widgetPosition.y) ? this._findNearestChildWidgetIndex
+ : this._findFarthestChildWidgetIndex;
+ } else if (direction === ccui.Widget.UP) {
+ this.onPassFocusToChild = (previousWidgetPosition.y < widgetPosition.y) ? this._findNearestChildWidgetIndex
+ : this._findFarthestChildWidgetIndex;
+ } else
+ cc.log("invalid direction!");
+ },
+
+ /**
+ * find the first non-layout widget in this layout
+ * @returns {ccui.Widget}
+ * @private
+ */
+ _findFirstNonLayoutWidget: function () {
+ var locChildren = this._children;
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ var child = locChildren[i];
+ if (child instanceof ccui.Layout) {
+ var widget = child._findFirstNonLayoutWidget();
+ if (widget)
+ return widget;
+ } else {
+ if (child instanceof ccui.Widget)
+ return child;
+ }
+ }
+ return null;
+ },
+
+ /**
+ * find the first focus enabled widget index in the layout, it will recursive searching the child widget
+ * @returns {number}
+ * @private
+ */
+ _findFirstFocusEnabledWidgetIndex: function () {
+ var index = 0, locChildren = this.getChildren();
+ var count = locChildren.length;
+ while (index < count) {
+ var w = locChildren[index];
+ if (w && w instanceof ccui.Widget && w.isFocusEnabled())
+ return index;
+ index++;
+ }
+ return 0;
+ },
+
+ /**
+ * find a focus enabled child Widget in the layout by index
+ * @param index
+ * @returns {*}
+ * @private
+ */
+ _findFocusEnabledChildWidgetByIndex: function (index) {
+ var widget = this._getChildWidgetByIndex(index);
+ if (widget) {
+ if (widget.isFocusEnabled())
+ return widget;
+ index = index + 1;
+ return this._findFocusEnabledChildWidgetByIndex(index);
+ }
+ return null;
+ },
+
+ /**
+ * get the center point of a widget in world space
+ * @param {ccui.Widget} widget
+ * @returns {cc.Point}
+ * @private
+ */
+ _getWorldCenterPoint: function (widget) {
+ //FIXEDME: we don't need to calculate the content size of layout anymore
+ var widgetSize = widget instanceof ccui.Layout ? widget._getLayoutAccumulatedSize() : widget.getContentSize();
+ return widget.convertToWorldSpace(cc.p(widgetSize.width / 2, widgetSize.height / 2));
+ },
+
+ /**
+ * this method is called internally by nextFocusedWidget. When the dir is Right/Down, then this method will be called
+ * @param {Number} direction
+ * @param {ccui.Widget} current the current focused widget
+ * @returns {ccui.Widget} the next focused widget
+ * @private
+ */
+ _getNextFocusedWidget: function (direction, current) {
+ var nextWidget = null, locChildren = this._children;
+ var previousWidgetPos = locChildren.indexOf(current);
+ previousWidgetPos = previousWidgetPos + 1;
+ if (previousWidgetPos < locChildren.length) {
+ nextWidget = this._getChildWidgetByIndex(previousWidgetPos);
+ //handle widget
+ if (nextWidget) {
+ if (nextWidget.isFocusEnabled()) {
+ if (nextWidget instanceof ccui.Layout) {
+ nextWidget._isFocusPassing = true;
+ return nextWidget.findNextFocusedWidget(direction, nextWidget);
+ } else {
+ this.dispatchFocusEvent(current, nextWidget);
+ return nextWidget;
+ }
+ } else
+ return this._getNextFocusedWidget(direction, nextWidget);
+ } else
+ return current;
+ } else {
+ if (this._loopFocus) {
+ if (this._checkFocusEnabledChild()) {
+ previousWidgetPos = 0;
+ nextWidget = this._getChildWidgetByIndex(previousWidgetPos);
+ if (nextWidget.isFocusEnabled()) {
+ if (nextWidget instanceof ccui.Layout) {
+ nextWidget._isFocusPassing = true;
+ return nextWidget.findNextFocusedWidget(direction, nextWidget);
+ } else {
+ this.dispatchFocusEvent(current, nextWidget);
+ return nextWidget;
+ }
+ } else
+ return this._getNextFocusedWidget(direction, nextWidget);
+ } else
+ return (current instanceof ccui.Layout) ? current : ccui.Widget._focusedWidget;
+ } else {
+ if (this._isLastWidgetInContainer(current, direction)) {
+ if (this._isWidgetAncestorSupportLoopFocus(this, direction))
+ return ccui.Widget.prototype.findNextFocusedWidget.call(this, direction, this);
+ return (current instanceof ccui.Layout) ? current : ccui.Widget._focusedWidget;
+ } else
+ return ccui.Widget.prototype.findNextFocusedWidget.call(this, direction, this);
+ }
+ }
+ },
+
+ /**
+ * this method is called internally by nextFocusedWidget. When the dir is Left/Up, then this method will be called
+ * @param direction
+ * @param {ccui.Widget} current the current focused widget
+ * @returns {ccui.Widget} the next focused widget
+ * @private
+ */
+ _getPreviousFocusedWidget: function (direction, current) {
+ var nextWidget = null, locChildren = this._children;
+ var previousWidgetPos = locChildren.indexOf(current);
+ previousWidgetPos = previousWidgetPos - 1;
+ if (previousWidgetPos >= 0) {
+ nextWidget = this._getChildWidgetByIndex(previousWidgetPos);
+ if (nextWidget.isFocusEnabled()) {
+ if (nextWidget instanceof ccui.Layout) {
+ nextWidget._isFocusPassing = true;
+ return nextWidget.findNextFocusedWidget(direction, nextWidget);
+ }
+ this.dispatchFocusEvent(current, nextWidget);
+ return nextWidget;
+ } else
+ return this._getPreviousFocusedWidget(direction, nextWidget); //handling the disabled widget, there is no actual focus lose or get, so we don't need any envet
+ } else {
+ if (this._loopFocus) {
+ if (this._checkFocusEnabledChild()) {
+ previousWidgetPos = locChildren.length - 1;
+ nextWidget = this._getChildWidgetByIndex(previousWidgetPos);
+ if (nextWidget.isFocusEnabled()) {
+ if (nextWidget instanceof ccui.Layout) {
+ nextWidget._isFocusPassing = true;
+ return nextWidget.findNextFocusedWidget(direction, nextWidget);
+ } else {
+ this.dispatchFocusEvent(current, nextWidget);
+ return nextWidget;
+ }
+ } else
+ return this._getPreviousFocusedWidget(direction, nextWidget);
+ } else
+ return (current instanceof ccui.Layout) ? current : ccui.Widget._focusedWidget;
+ } else {
+ if (this._isLastWidgetInContainer(current, direction)) {
+ if (this._isWidgetAncestorSupportLoopFocus(this, direction))
+ return ccui.Widget.prototype.findNextFocusedWidget.call(this, direction, this);
+ return (current instanceof ccui.Layout) ? current : ccui.Widget._focusedWidget;
+ } else
+ return ccui.Widget.prototype.findNextFocusedWidget.call(this, direction, this);
+ }
+ }
+ },
+
+ /**
+ * find the nth element in the _children array. Only the Widget descendant object will be returned
+ * @param {Number} index
+ * @returns {ccui.Widget}
+ * @private
+ */
+ _getChildWidgetByIndex: function (index) {
+ var locChildren = this._children;
+ var size = locChildren.length, count = 0, oldIndex = index;
+ while (index < size) {
+ var firstChild = locChildren[index];
+ if (firstChild && firstChild instanceof ccui.Widget)
+ return firstChild;
+ count++;
+ index++;
+ }
+
+ var begin = 0;
+ while (begin < oldIndex) {
+ var child = locChildren[begin];
+ if (child && child instanceof ccui.Widget)
+ return child;
+ count++;
+ begin++;
+ }
+ return null;
+ },
+
+ /**
+ * whether it is the last element according to all their parents
+ * @param {ccui.Widget} widget
+ * @param {Number} direction
+ * @returns {Boolean}
+ * @private
+ */
+ _isLastWidgetInContainer: function (widget, direction) {
+ var parent = widget.getParent();
+ if (parent == null || !(parent instanceof ccui.Layout))
+ return true;
+
+ var container = parent.getChildren();
+ var index = container.indexOf(widget);
+ if (parent.getLayoutType() === ccui.Layout.LINEAR_HORIZONTAL) {
+ if (direction === ccui.Widget.LEFT) {
+ if (index === 0)
+ return this._isLastWidgetInContainer(parent, direction);
+ else
+ return false;
+ }
+ if (direction === ccui.Widget.RIGHT) {
+ if (index === container.length - 1)
+ return this._isLastWidgetInContainer(parent, direction);
+ else
+ return false;
+ }
+ if (direction === ccui.Widget.DOWN)
+ return this._isLastWidgetInContainer(parent, direction);
+
+ if (direction === ccui.Widget.UP)
+ return this._isLastWidgetInContainer(parent, direction);
+ } else if (parent.getLayoutType() === ccui.Layout.LINEAR_VERTICAL) {
+ if (direction === ccui.Widget.UP) {
+ if (index === 0)
+ return this._isLastWidgetInContainer(parent, direction);
+ else
+ return false;
+ }
+ if (direction === ccui.Widget.DOWN) {
+ if (index === container.length - 1)
+ return this._isLastWidgetInContainer(parent, direction);
+ else
+ return false;
+ }
+ if (direction === ccui.Widget.LEFT)
+ return this._isLastWidgetInContainer(parent, direction);
+
+ if (direction === ccui.Widget.RIGHT)
+ return this._isLastWidgetInContainer(parent, direction);
+ } else {
+ cc.log("invalid layout Type");
+ return false;
+ }
+ },
+
+ /**
+ * Lookup any parent widget with a layout type as the direction, if the layout is loop focused, then return true, otherwise it returns false.
+ * @param {ccui.Widget} widget
+ * @param {Number} direction
+ * @returns {Boolean}
+ * @private
+ */
+ _isWidgetAncestorSupportLoopFocus: function (widget, direction) {
+ var parent = widget.getParent();
+ if (parent == null || !(parent instanceof ccui.Layout))
+ return false;
+ if (parent.isLoopFocus()) {
+ var layoutType = parent.getLayoutType();
+ if (layoutType === ccui.Layout.LINEAR_HORIZONTAL) {
+ if (direction === ccui.Widget.LEFT || direction === ccui.Widget.RIGHT)
+ return true;
+ else
+ return this._isWidgetAncestorSupportLoopFocus(parent, direction);
+ }
+ if (layoutType === ccui.Layout.LINEAR_VERTICAL) {
+ if (direction === ccui.Widget.DOWN || direction === ccui.Widget.UP)
+ return true;
+ else
+ return this._isWidgetAncestorSupportLoopFocus(parent, direction);
+ } else {
+ cc.assert(0, "invalid layout type");
+ return false;
+ }
+ } else
+ return this._isWidgetAncestorSupportLoopFocus(parent, direction);
+ },
+
+ /**
+ * pass the focus to the layout's next focus enabled child
+ * @param {Number} direction
+ * @param {ccui.Widget} current
+ * @returns {ccui.Widget}
+ * @private
+ */
+ _passFocusToChild: function (direction, current) {
+ if (this._checkFocusEnabledChild()) {
+ var previousWidget = ccui.Widget.getCurrentFocusedWidget();
+ this._findProperSearchingFunctor(direction, previousWidget);
+ var index = this.onPassFocusToChild(direction, previousWidget);
+
+ var widget = this._getChildWidgetByIndex(index);
+ if (widget instanceof ccui.Layout) {
+ widget._isFocusPassing = true;
+ return widget.findNextFocusedWidget(direction, widget);
+ } else {
+ this.dispatchFocusEvent(current, widget);
+ return widget;
+ }
+ } else
+ return this;
+ },
+
+ /**
+ * If there are no focus enabled child in the layout, it will return false, otherwise it returns true
+ * @returns {boolean}
+ * @private
+ */
+ _checkFocusEnabledChild: function () {
+ var locChildren = this._children;
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ var widget = locChildren[i];
+ if (widget && widget instanceof ccui.Widget && widget.isFocusEnabled())
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Returns the "class name" of widget.
+ * @returns {string}
+ */
+ getDescription: function () {
+ return "Layout";
+ },
+
+ _createCloneInstance: function () {
+ return new ccui.Layout();
+ },
+
+ _copyClonedWidgetChildren: function (model) {
+ ccui.Widget.prototype._copyClonedWidgetChildren.call(this, model);
+ },
+
+ _copySpecialProperties: function (layout) {
+ if (!(layout instanceof ccui.Layout))
+ return;
+ this.setBackGroundImageScale9Enabled(layout._backGroundScale9Enabled);
+ this.setBackGroundImage(layout._backGroundImageFileName, layout._bgImageTexType);
+ this.setBackGroundImageCapInsets(layout._backGroundImageCapInsets);
+ this.setBackGroundColorType(layout._colorType);
+ this.setBackGroundColor(layout._color);
+ this.setBackGroundColor(layout._startColor, layout._endColor);
+ this.setBackGroundColorOpacity(layout._opacity);
+ this.setBackGroundColorVector(layout._alongVector);
+ this.setLayoutType(layout._layoutType);
+ this.setClippingEnabled(layout._clippingEnabled);
+ this.setClippingType(layout._clippingType);
+ this._loopFocus = layout._loopFocus;
+ this.__passFocusToChild = layout.__passFocusToChild;
+ this._isInterceptTouch = layout._isInterceptTouch;
+ },
+
+ /**
+ * force refresh widget layout
+ */
+ forceDoLayout: function () {
+ this.requestDoLayout();
+ this._doLayout();
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ return new ccui.Layout.WebGLRenderCmd(this);
+ else
+ return new ccui.Layout.CanvasRenderCmd(this);
+ }
+});
+
+var _p = ccui.Layout.prototype;
+
+// Extended properties
+/** @expose */
+_p.clippingEnabled;
+cc.defineGetterSetter(_p, "clippingEnabled", _p.isClippingEnabled, _p.setClippingEnabled);
+/** @expose */
+_p.clippingType;
+cc.defineGetterSetter(_p, "clippingType", null, _p.setClippingType);
+/** @expose */
+_p.layoutType;
+cc.defineGetterSetter(_p, "layoutType", _p.getLayoutType, _p.setLayoutType);
+
+_p = null;
+
+/**
+ * allocates and initializes a UILayout.
+ * @deprecated since v3.0, please use new ccui.Layout() instead.
+ * @return {ccui.Layout}
+ */
+ccui.Layout.create = function () {
+ return new ccui.Layout();
+};
+
+// Constants
+
+//layoutBackGround color type
+/**
+ * The None of ccui.Layout's background color type
+ * @constant
+ * @type {number}
+ */
+ccui.Layout.BG_COLOR_NONE = 0;
+/**
+ * The solid of ccui.Layout's background color type, it will use a LayerColor to draw the background.
+ * @constant
+ * @type {number}
+ */
+ccui.Layout.BG_COLOR_SOLID = 1;
+/**
+ * The gradient of ccui.Layout's background color type, it will use a LayerGradient to draw the background.
+ * @constant
+ * @type {number}
+ */
+ccui.Layout.BG_COLOR_GRADIENT = 2;
+
+//Layout type
+/**
+ * The absolute of ccui.Layout's layout type.
+ * @type {number}
+ * @constant
+ */
+ccui.Layout.ABSOLUTE = 0;
+/**
+ * The vertical of ccui.Layout's layout type.
+ * @type {number}
+ * @constant
+ */
+ccui.Layout.LINEAR_VERTICAL = 1;
+/**
+ * The horizontal of ccui.Layout's layout type.
+ * @type {number}
+ * @constant
+ */
+ccui.Layout.LINEAR_HORIZONTAL = 2;
+/**
+ * The relative of ccui.Layout's layout type.
+ * @type {number}
+ * @constant
+ */
+ccui.Layout.RELATIVE = 3;
+
+//Layout clipping type
+/**
+ * The stencil of ccui.Layout's clipping type.
+ * @type {number}
+ * @constant
+ */
+ccui.Layout.CLIPPING_STENCIL = 0;
+/**
+ * The scissor of ccui.Layout's clipping type.
+ * @type {number}
+ * @constant
+ */
+ccui.Layout.CLIPPING_SCISSOR = 1;
+
+/**
+ * The zOrder value of ccui.Layout's image background.
+ * @type {number}
+ * @constant
+ */
+ccui.Layout.BACKGROUND_IMAGE_ZORDER = -1;
+/**
+ * The zOrder value of ccui.Layout's color background.
+ * @type {number}
+ * @constant
+ */
+ccui.Layout.BACKGROUND_RENDERER_ZORDER = -2;
diff --git a/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayoutCanvasRenderCmd.js b/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayoutCanvasRenderCmd.js
new file mode 100644
index 0000000..7d847cc
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayoutCanvasRenderCmd.js
@@ -0,0 +1,103 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ ccui.Layout.CanvasRenderCmd = function (renderable) {
+ this._pNodeCmdCtor(renderable);
+ this._needDraw = false;
+
+ this._rendererSaveCmd = null;
+ this._rendererClipCmd = null;
+ this._rendererRestoreCmd = null;
+ };
+
+ var proto = ccui.Layout.CanvasRenderCmd.prototype = Object.create(ccui.ProtectedNode.CanvasRenderCmd.prototype);
+ proto.constructor = ccui.Layout.CanvasRenderCmd;
+ proto._layoutCmdCtor = ccui.Layout.CanvasRenderCmd;
+
+ proto._onRenderSaveCmd = function (ctx, scaleX, scaleY) {
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext();
+ wrapper.save();
+ wrapper.save();
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+ var buffer = this._node._clippingStencil._renderCmd._buffer;
+
+ for (var i = 0, bufLen = buffer.length; i < bufLen; i++) {
+ var element = buffer[i], vertices = element.verts;
+ var firstPoint = vertices[0];
+ context.beginPath();
+ context.moveTo(firstPoint.x, -firstPoint.y);
+ for (var j = 1, len = vertices.length; j < len; j++)
+ context.lineTo(vertices[j].x, -vertices[j].y);
+ context.closePath();
+ }
+ };
+
+ proto._onRenderClipCmd = function (ctx) {
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext();
+ wrapper.restore();
+ context.clip();
+ };
+
+ proto._onRenderRestoreCmd = function (ctx) {
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext();
+
+ wrapper.restore();
+ };
+
+ proto.rebindStencilRendering = function (stencil) {
+ stencil._renderCmd.rendering = this.__stencilDraw;
+ stencil._renderCmd._canUseDirtyRegion = true;
+ };
+
+ proto.__stencilDraw = function (ctx, scaleX, scaleY) { //Only for Canvas
+ //do nothing, rendering in layout
+ };
+
+ proto.stencilClippingVisit = proto.scissorClippingVisit = function (parentCmd) {
+ var node = this._node;
+ if (!node._clippingStencil || !node._clippingStencil.isVisible())
+ return;
+
+ if (!this._rendererSaveCmd) {
+ this._rendererSaveCmd = new cc.CustomRenderCmd(this, this._onRenderSaveCmd);
+ this._rendererClipCmd = new cc.CustomRenderCmd(this, this._onRenderClipCmd);
+ this._rendererRestoreCmd = new cc.CustomRenderCmd(this, this._onRenderRestoreCmd);
+ }
+
+ cc.renderer.pushRenderCommand(this._rendererSaveCmd);
+ node._clippingStencil.visit(this);
+
+ cc.renderer.pushRenderCommand(this._rendererClipCmd);
+ };
+
+ proto.postStencilVisit = proto.postScissorVisit = function () {
+ cc.renderer.pushRenderCommand(this._rendererRestoreCmd);
+ };
+
+ ccui.Layout.CanvasRenderCmd._getSharedCache = function () {
+ return (cc.ClippingNode._sharedCache) || (cc.ClippingNode._sharedCache = document.createElement("canvas"));
+ };
+})();
diff --git a/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayoutComponent.js b/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayoutComponent.js
new file mode 100644
index 0000000..3a910f6
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayoutComponent.js
@@ -0,0 +1,598 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+ccui.LayoutComponent_ReferencePoint = {
+ BOTTOM_LEFT: 0,
+ TOP_LEFT: 1,
+ BOTTOM_RIGHT: 2,
+ TOP_RIGHT: 3
+};
+ccui.LayoutComponent_PositionType = {
+ Position: 0,
+ RelativePosition: 1,
+ PreRelativePosition: 2,
+ PreRelativePositionEnable: 3
+};
+ccui.LayoutComponent_SizeType = {
+ Size: 0,
+ PreSize: 1,
+ PreSizeEnable: 2
+};
+
+//refactor since v3.3
+ccui.LayoutComponent = cc.Component.extend({
+ _horizontalEdge: 0,
+ _verticalEdge: 0,
+
+ _leftMargin: 0,
+ _rightMargin: 0,
+ _bottomMargin: 0,
+ _topMargin: 0,
+
+ _usingPositionPercentX: false,
+ _positionPercentX: 0,
+ _usingPositionPercentY: false,
+ _positionPercentY: 0,
+
+ _usingStretchWidth: false,
+ _usingStretchHeight: false,
+
+ _percentWidth: 0,
+ _usingPercentWidth: false,
+
+ _percentHeight: 0,
+ _usingPercentHeight: false,
+
+ _actived: true,
+ _isPercentOnly: false,
+
+ ctor: function () {
+ this._name = ccui.LayoutComponent.NAME;
+ },
+
+ init: function () {
+ var ret = true;
+
+ if (!cc.Component.prototype.init.call(this)) {
+ return false;
+ }
+
+ //put layout component initalized code here
+
+ return ret;
+ },
+
+ getPercentContentSize: function () {
+ return cc.p(this._percentWidth, this._percentHeight);
+ },
+ setPercentContentSize: function (percent) {
+ this.setPercentWidth(percent.x);
+ this.setPercentHeight(percent.y);
+ },
+
+ setUsingPercentContentSize: function (isUsed) {
+ this._usingPercentWidth = this._usingPercentHeight = isUsed;
+ },
+
+ //old
+ SetActiveEnable: function (enable) {
+ this._actived = enable;
+ },
+
+ //v3.3
+ getUsingPercentContentSize: function () {
+ return this._usingPercentWidth && this._usingPercentHeight;
+ },
+
+ //position & margin
+ getAnchorPosition: function () {
+ return this._owner.getAnchorPoint();
+ },
+
+ setAnchorPosition: function (point, y) {
+ var oldRect = this._owner.getBoundingBox();
+ this._owner.setAnchorPoint(point, y);
+ var newRect = this._owner.getBoundingBox();
+ var offSetX = oldRect.x - newRect.x, offSetY = oldRect.y - newRect.y;
+
+ var ownerPosition = this._owner.getPosition();
+ ownerPosition.x += offSetX;
+ ownerPosition.y += offSetY;
+ this.setPosition(ownerPosition);
+ },
+
+ getPosition: function () {
+ return this._owner.getPosition();
+ },
+
+ setPosition: function (position, y) {
+ var parent = this._getOwnerParent(), x;
+ if (parent != null) {
+ if (y === undefined) {
+ x = position.x;
+ y = position.y;
+ } else
+ x = position;
+ var parentSize = parent.getContentSize();
+
+ if (parentSize.width !== 0)
+ this._positionPercentX = x / parentSize.width;
+ else {
+ this._positionPercentX = 0;
+ if (this._usingPositionPercentX)
+ x = 0;
+ }
+
+ if (parentSize.height !== 0)
+ this._positionPercentY = y / parentSize.height;
+ else {
+ this._positionPercentY = 0;
+ if (this._usingPositionPercentY)
+ y = 0;
+ }
+
+ this._owner.setPosition(x, y);
+ this._refreshHorizontalMargin();
+ this._refreshVerticalMargin();
+ } else
+ this._owner.setPosition(position, y);
+ },
+
+ isPositionPercentXEnabled: function () {
+ return this._usingPositionPercentX;
+ },
+ setPositionPercentXEnabled: function (isUsed) {
+ this._usingPositionPercentX = isUsed;
+ if (this._usingPositionPercentX)
+ this._horizontalEdge = ccui.LayoutComponent.horizontalEdge.NONE;
+ },
+
+ getPositionPercentX: function () {
+ return this._positionPercentX;
+ },
+ setPositionPercentX: function (percentMargin) {
+ this._positionPercentX = percentMargin;
+
+ var parent = this._getOwnerParent();
+ if (parent !== null) {
+ this._owner.setPositionX(parent.width * this._positionPercentX);
+ this._refreshHorizontalMargin();
+ }
+ },
+
+ isPositionPercentYEnabled: function () {
+ return this._usingPositionPercentY;
+ },
+ setPositionPercentYEnabled: function (isUsed) {
+ this._usingPositionPercentY = isUsed;
+ if (this._usingPositionPercentY)
+ this._verticalEdge = ccui.LayoutComponent.verticalEdge.NONE;
+ },
+
+ getPositionPercentY: function () {
+ return this._positionPercentY;
+ },
+ setPositionPercentY: function (percentMargin) {
+ this._positionPercentY = percentMargin;
+
+ var parent = this._getOwnerParent();
+ if (parent !== null) {
+ this._owner.setPositionY(parent.height * this._positionPercentY);
+ this._refreshVerticalMargin();
+ }
+ },
+
+ getHorizontalEdge: function () {
+ return this._horizontalEdge;
+ },
+ setHorizontalEdge: function (hEdge) {
+ this._horizontalEdge = hEdge;
+ if (this._horizontalEdge !== ccui.LayoutComponent.horizontalEdge.NONE)
+ this._usingPositionPercentX = false;
+
+ var parent = this._getOwnerParent();
+ if (parent !== null) {
+ var ownerPoint = this._owner.getPosition();
+ var parentSize = parent.getContentSize();
+ if (parentSize.width !== 0)
+ this._positionPercentX = ownerPoint.x / parentSize.width;
+ else {
+ this._positionPercentX = 0;
+ ownerPoint.x = 0;
+ if (this._usingPositionPercentX)
+ this._owner.setPosition(ownerPoint);
+ }
+ this._refreshHorizontalMargin();
+ }
+ },
+
+ getVerticalEdge: function () {
+ return this._verticalEdge;
+ },
+ setVerticalEdge: function (vEdge) {
+ this._verticalEdge = vEdge;
+ if (this._verticalEdge !== ccui.LayoutComponent.verticalEdge.NONE)
+ this._usingPositionPercentY = false;
+
+ var parent = this._getOwnerParent();
+ if (parent !== null) {
+ var ownerPoint = this._owner.getPosition();
+ var parentSize = parent.getContentSize();
+ if (parentSize.height !== 0)
+ this._positionPercentY = ownerPoint.y / parentSize.height;
+ else {
+ this._positionPercentY = 0;
+ ownerPoint.y = 0;
+ if (this._usingPositionPercentY)
+ this._owner.setPosition(ownerPoint);
+ }
+ this._refreshVerticalMargin();
+ }
+ },
+
+ getLeftMargin: function () {
+ return this._leftMargin;
+ },
+ setLeftMargin: function (margin) {
+ this._leftMargin = margin;
+ },
+
+ getRightMargin: function () {
+ return this._rightMargin;
+ },
+ setRightMargin: function (margin) {
+ this._rightMargin = margin;
+ },
+
+ getTopMargin: function () {
+ return this._topMargin;
+ },
+ setTopMargin: function (margin) {
+ this._topMargin = margin;
+ },
+
+ getBottomMargin: function () {
+ return this._bottomMargin;
+ },
+ setBottomMargin: function (margin) {
+ this._bottomMargin = margin;
+ },
+
+ //size &
+ getSize: function () {
+ return this.getOwner().getContentSize();
+ },
+ setSize: function (size) {
+ var parent = this._getOwnerParent();
+ if (parent !== null) {
+ var ownerSize = size, parentSize = parent.getContentSize();
+
+ if (parentSize.width !== 0)
+ this._percentWidth = ownerSize.width / parentSize.width;
+ else {
+ this._percentWidth = 0;
+ if (this._usingPercentWidth)
+ ownerSize.width = 0;
+ }
+
+ if (parentSize.height !== 0)
+ this._percentHeight = ownerSize.height / parentSize.height;
+ else {
+ this._percentHeight = 0;
+ if (this._usingPercentHeight)
+ ownerSize.height = 0;
+ }
+
+ this._owner.setContentSize(ownerSize);
+
+ this._refreshHorizontalMargin();
+ this._refreshVerticalMargin();
+ }
+ else
+ this._owner.setContentSize(size);
+ },
+
+ isPercentWidthEnabled: function () {
+ return this._usingPercentWidth;
+ },
+ setPercentWidthEnabled: function (isUsed) {
+ this._usingPercentWidth = isUsed;
+ if (this._usingPercentWidth)
+ this._usingStretchWidth = false;
+ },
+
+ getSizeWidth: function () {
+ return this._owner.width;
+ },
+ setSizeWidth: function (width) {
+ var ownerSize = this._owner.getContentSize();
+ ownerSize.width = width;
+
+ var parent = this._getOwnerParent();
+ if (parent !== null) {
+ var parentSize = parent.getContentSize();
+ if (parentSize.width !== 0)
+ this._percentWidth = ownerSize.width / parentSize.width;
+ else {
+ this._percentWidth = 0;
+ if (this._usingPercentWidth)
+ ownerSize.width = 0;
+ }
+ this._owner.setContentSize(ownerSize);
+ this._refreshHorizontalMargin();
+ } else
+ this._owner.setContentSize(ownerSize);
+ },
+
+ getPercentWidth: function () {
+ return this._percentWidth;
+ },
+ setPercentWidth: function (percentWidth) {
+ this._percentWidth = percentWidth;
+
+ var parent = this._getOwnerParent();
+ if (parent !== null) {
+ var ownerSize = this._owner.getContentSize();
+ ownerSize.width = parent.width * this._percentWidth;
+ this._owner.setContentSize(ownerSize);
+ this._refreshHorizontalMargin();
+ }
+ },
+
+ isPercentHeightEnabled: function () {
+ return this._usingPercentHeight;
+ },
+ setPercentHeightEnabled: function (isUsed) {
+ this._usingPercentHeight = isUsed;
+ if (this._usingPercentHeight)
+ this._usingStretchHeight = false;
+ },
+
+ getSizeHeight: function () {
+ return this._owner.height;
+ },
+ setSizeHeight: function (height) {
+ var ownerSize = this._owner.getContentSize();
+ ownerSize.height = height;
+
+ var parent = this._getOwnerParent();
+ if (parent !== null) {
+ var parentSize = parent.getContentSize();
+ if (parentSize.height !== 0)
+ this._percentHeight = ownerSize.height / parentSize.height;
+ else {
+ this._percentHeight = 0;
+ if (this._usingPercentHeight)
+ ownerSize.height = 0;
+ }
+ this._owner.setContentSize(ownerSize);
+ this._refreshVerticalMargin();
+ }
+ else
+ this._owner.setContentSize(ownerSize);
+ },
+
+ getPercentHeight: function () {
+ return this._percentHeight;
+ },
+ setPercentHeight: function (percentHeight) {
+ this._percentHeight = percentHeight;
+
+ var parent = this._getOwnerParent();
+ if (parent !== null) {
+ var ownerSize = this._owner.getContentSize();
+ ownerSize.height = parent.height * this._percentHeight;
+ this._owner.setContentSize(ownerSize);
+ this._refreshVerticalMargin();
+ }
+ },
+
+ isStretchWidthEnabled: function () {
+ return this._usingStretchWidth;
+ },
+ setStretchWidthEnabled: function (isUsed) {
+ this._usingStretchWidth = isUsed;
+ if (this._usingStretchWidth)
+ this._usingPercentWidth = false;
+ },
+
+ isStretchHeightEnabled: function () {
+ return this._usingStretchHeight;
+ },
+ setStretchHeightEnabled: function (isUsed) {
+ this._usingStretchHeight = isUsed;
+ if (this._usingStretchHeight)
+ this._usingPercentHeight = false;
+ },
+
+ setPercentOnlyEnabled: function(enable){
+ this._isPercentOnly = enable;
+ },
+
+ setActiveEnabled: function (enable) {
+ this._actived = enable;
+ },
+ refreshLayout: function () {
+ if(!this._actived)
+ return;
+
+ var parent = this._getOwnerParent();
+ if (parent === null)
+ return;
+
+ var parentSize = parent.getContentSize(), locOwner = this._owner;
+ var ownerAnchor = locOwner.getAnchorPoint(), ownerSize = locOwner.getContentSize();
+ var ownerPosition = locOwner.getPosition();
+
+ switch (this._horizontalEdge) {
+ case ccui.LayoutComponent.horizontalEdge.NONE:
+ if (this._usingStretchWidth && !this._isPercentOnly) {
+ ownerSize.width = parentSize.width * this._percentWidth;
+ ownerPosition.x = this._leftMargin + ownerAnchor.x * ownerSize.width;
+ } else {
+ if (this._usingPositionPercentX)
+ ownerPosition.x = parentSize.width * this._positionPercentX;
+ if (this._usingPercentWidth)
+ ownerSize.width = parentSize.width * this._percentWidth;
+ }
+ break;
+ case ccui.LayoutComponent.horizontalEdge.LEFT:
+ if(this._isPercentOnly)
+ break;
+ if (this._usingPercentWidth || this._usingStretchWidth)
+ ownerSize.width = parentSize.width * this._percentWidth;
+ ownerPosition.x = this._leftMargin + ownerAnchor.x * ownerSize.width;
+ break;
+ case ccui.LayoutComponent.horizontalEdge.RIGHT:
+ if(this._isPercentOnly)
+ break;
+ if (this._usingPercentWidth || this._usingStretchWidth)
+ ownerSize.width = parentSize.width * this._percentWidth;
+ ownerPosition.x = parentSize.width - (this._rightMargin + (1 - ownerAnchor.x) * ownerSize.width);
+ break;
+ case ccui.LayoutComponent.horizontalEdge.CENTER:
+ if(this._isPercentOnly)
+ break;
+ if (this._usingStretchWidth) {
+ ownerSize.width = parentSize.width - this._leftMargin - this._rightMargin;
+ if (ownerSize.width < 0)
+ ownerSize.width = 0;
+ ownerPosition.x = this._leftMargin + ownerAnchor.x * ownerSize.width;
+ } else {
+ if (this._usingPercentWidth)
+ ownerSize.width = parentSize.width * this._percentWidth;
+ ownerPosition.x = parentSize.width * this._positionPercentX;
+ }
+ break;
+ default:
+ break;
+ }
+
+ switch (this._verticalEdge) {
+ case ccui.LayoutComponent.verticalEdge.NONE:
+ if (this._usingStretchHeight && !this._isPercentOnly) {
+ ownerSize.height = parentSize.height * this._percentHeight;
+ ownerPosition.y = this._bottomMargin + ownerAnchor.y * ownerSize.height;
+ } else {
+ if (this._usingPositionPercentY)
+ ownerPosition.y = parentSize.height * this._positionPercentY;
+ if (this._usingPercentHeight)
+ ownerSize.height = parentSize.height * this._percentHeight;
+ }
+ break;
+ case ccui.LayoutComponent.verticalEdge.BOTTOM:
+ if(this._isPercentOnly)
+ break;
+ if (this._usingPercentHeight || this._usingStretchHeight)
+ ownerSize.height = parentSize.height * this._percentHeight;
+ ownerPosition.y = this._bottomMargin + ownerAnchor.y * ownerSize.height;
+ break;
+ case ccui.LayoutComponent.verticalEdge.TOP:
+ if(this._isPercentOnly)
+ break;
+ if (this._usingPercentHeight || this._usingStretchHeight)
+ ownerSize.height = parentSize.height * this._percentHeight;
+ ownerPosition.y = parentSize.height - (this._topMargin + (1 - ownerAnchor.y) * ownerSize.height);
+ break;
+ case ccui.LayoutComponent.verticalEdge.CENTER:
+ if(this._isPercentOnly)
+ break;
+ if (this._usingStretchHeight) {
+ ownerSize.height = parentSize.height - this._topMargin - this._bottomMargin;
+ if (ownerSize.height < 0)
+ ownerSize.height = 0;
+ ownerPosition.y = this._bottomMargin + ownerAnchor.y * ownerSize.height;
+ } else {
+ if(this._usingPercentHeight)
+ ownerSize.height = parentSize.height * this._percentHeight;
+ ownerPosition.y = parentSize.height * this._positionPercentY;
+ }
+ break;
+ default:
+ break;
+ }
+
+ locOwner.setPosition(ownerPosition);
+ locOwner.setContentSize(ownerSize);
+
+ if(locOwner instanceof ccui.PageView){
+ locOwner.forceDoLayout();
+
+ var layoutVector = locOwner.getPages();
+ for(var i=0; i 0) {
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ this._widget = locChildren[i];
+
+ var layoutParameter = this._widget.getLayoutParameter();
+ if (layoutParameter){
+ if (layoutParameter._put)
+ continue;
+
+ var ret = this._calculateFinalPositionWithRelativeWidget(layout);
+ if (!ret)
+ continue;
+
+ this._calculateFinalPositionWithRelativeAlign();
+
+ this._widget.setPosition(this._finalPositionX, this._finalPositionY);
+ layoutParameter._put = true;
+ }
+ }
+ this._unlayoutChildCount--;
+ }
+ this._widgetChildren.length = 0;
+ },
+
+ _getAllWidgets: function (layout) {
+ var container = layout._getLayoutElements();
+ var locWidgetChildren = this._widgetChildren;
+ locWidgetChildren.length = 0;
+ for (var i = 0, len = container.length; i < len; i++) {
+ var child = container[i];
+ if (child && child instanceof ccui.Widget) {
+ var layoutParameter = child.getLayoutParameter();
+ layoutParameter._put = false;
+ this._unlayoutChildCount++;
+ locWidgetChildren.push(child);
+ }
+ }
+ return locWidgetChildren;
+ },
+
+ _getRelativeWidget: function (widget) {
+ var relativeWidget = null;
+ var layoutParameter = widget.getLayoutParameter();
+ var relativeName = layoutParameter.getRelativeToWidgetName();
+
+ if (relativeName && relativeName.length !== 0) {
+ var locChildren = this._widgetChildren;
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ var child = locChildren[i];
+ if (child){
+ var rlayoutParameter = child.getLayoutParameter();
+ if (rlayoutParameter && rlayoutParameter.getRelativeName() === relativeName) {
+ relativeWidget = child;
+ this._relativeWidgetLP = rlayoutParameter;
+ break;
+ }
+ }
+ }
+ }
+ return relativeWidget;
+ },
+
+ _calculateFinalPositionWithRelativeWidget: function (layout) {
+ var locWidget = this._widget;
+ var ap = locWidget.getAnchorPoint();
+ var cs = locWidget.getContentSize();
+
+ this._finalPositionX = 0.0;
+ this._finalPositionY = 0.0;
+
+ var relativeWidget = this._getRelativeWidget(locWidget);
+ var layoutParameter = locWidget.getLayoutParameter();
+ var align = layoutParameter.getAlign();
+ var layoutSize = layout._getLayoutContentSize();
+
+ switch (align) {
+ case ccui.RelativeLayoutParameter.NONE:
+ case ccui.RelativeLayoutParameter.PARENT_TOP_LEFT:
+ this._finalPositionX = ap.x * cs.width;
+ this._finalPositionY = layoutSize.height - ((1.0 - ap.y) * cs.height);
+ break;
+ case ccui.RelativeLayoutParameter.PARENT_TOP_CENTER_HORIZONTAL:
+ this._finalPositionX = layoutSize.width * 0.5 - cs.width * (0.5 - ap.x);
+ this._finalPositionY = layoutSize.height - ((1.0 - ap.y) * cs.height);
+ break;
+ case ccui.RelativeLayoutParameter.PARENT_TOP_RIGHT:
+ this._finalPositionX = layoutSize.width - ((1.0 - ap.x) * cs.width);
+ this._finalPositionY = layoutSize.height - ((1.0 - ap.y) * cs.height);
+ break;
+ case ccui.RelativeLayoutParameter.PARENT_LEFT_CENTER_VERTICAL:
+ this._finalPositionX = ap.x * cs.width;
+ this._finalPositionY = layoutSize.height * 0.5 - cs.height * (0.5 - ap.y);
+ break;
+ case ccui.RelativeLayoutParameter.CENTER_IN_PARENT:
+ this._finalPositionX = layoutSize.width * 0.5 - cs.width * (0.5 - ap.x);
+ this._finalPositionY = layoutSize.height * 0.5 - cs.height * (0.5 - ap.y);
+ break;
+ case ccui.RelativeLayoutParameter.PARENT_RIGHT_CENTER_VERTICAL:
+ this._finalPositionX = layoutSize.width - ((1.0 - ap.x) * cs.width);
+ this._finalPositionY = layoutSize.height * 0.5 - cs.height * (0.5 - ap.y);
+ break;
+ case ccui.RelativeLayoutParameter.PARENT_LEFT_BOTTOM:
+ this._finalPositionX = ap.x * cs.width;
+ this._finalPositionY = ap.y * cs.height;
+ break;
+ case ccui.RelativeLayoutParameter.PARENT_BOTTOM_CENTER_HORIZONTAL:
+ this._finalPositionX = layoutSize.width * 0.5 - cs.width * (0.5 - ap.x);
+ this._finalPositionY = ap.y * cs.height;
+ break;
+ case ccui.RelativeLayoutParameter.PARENT_RIGHT_BOTTOM:
+ this._finalPositionX = layoutSize.width - ((1.0 - ap.x) * cs.width);
+ this._finalPositionY = ap.y * cs.height;
+ break;
+
+ case ccui.RelativeLayoutParameter.LOCATION_ABOVE_LEFTALIGN:
+ if (relativeWidget) {
+ if (this._relativeWidgetLP && !this._relativeWidgetLP._put)
+ return false;
+ this._finalPositionY = relativeWidget.getTopBoundary() + ap.y * cs.height;
+ this._finalPositionX = relativeWidget.getLeftBoundary() + ap.x * cs.width;
+ }
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_ABOVE_CENTER:
+ if (relativeWidget) {
+ if (this._relativeWidgetLP && !this._relativeWidgetLP._put)
+ return false;
+ var rbs = relativeWidget.getContentSize();
+ this._finalPositionY = relativeWidget.getTopBoundary() + ap.y * cs.height;
+ this._finalPositionX = relativeWidget.getLeftBoundary() + rbs.width * 0.5 + ap.x * cs.width - cs.width * 0.5;
+ }
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_ABOVE_RIGHTALIGN:
+ if (relativeWidget) {
+ if (this._relativeWidgetLP && !this._relativeWidgetLP._put)
+ return false;
+ this._finalPositionY = relativeWidget.getTopBoundary() + ap.y * cs.height;
+ this._finalPositionX = relativeWidget.getRightBoundary() - (1.0 - ap.x) * cs.width;
+ }
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_LEFT_OF_TOPALIGN:
+ if (relativeWidget) {
+ if (this._relativeWidgetLP && !this._relativeWidgetLP._put)
+ return false;
+ this._finalPositionY = relativeWidget.getTopBoundary() - (1.0 - ap.y) * cs.height;
+ this._finalPositionX = relativeWidget.getLeftBoundary() - (1.0 - ap.x) * cs.width;
+ }
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_LEFT_OF_CENTER:
+ if (relativeWidget) {
+ if (this._relativeWidgetLP && !this._relativeWidgetLP._put)
+ return false;
+ var rbs = relativeWidget.getContentSize();
+ this._finalPositionX = relativeWidget.getLeftBoundary() - (1.0 - ap.x) * cs.width;
+ this._finalPositionY = relativeWidget.getBottomBoundary() + rbs.height * 0.5 + ap.y * cs.height - cs.height * 0.5;
+ }
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_LEFT_OF_BOTTOMALIGN:
+ if (relativeWidget) {
+ if (this._relativeWidgetLP && !this._relativeWidgetLP._put)
+ return false;
+ this._finalPositionY = relativeWidget.getBottomBoundary() + ap.y * cs.height;
+ this._finalPositionX = relativeWidget.getLeftBoundary() - (1.0 - ap.x) * cs.width;
+ }
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_RIGHT_OF_TOPALIGN:
+ if (relativeWidget) {
+ if (this._relativeWidgetLP && !this._relativeWidgetLP._put)
+ return false;
+ this._finalPositionY = relativeWidget.getTopBoundary() - (1.0 - ap.y) * cs.height;
+ this._finalPositionX = relativeWidget.getRightBoundary() + ap.x * cs.width;
+ }
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_RIGHT_OF_CENTER:
+ if (relativeWidget) {
+ if (this._relativeWidgetLP && !this._relativeWidgetLP._put)
+ return false;
+ var rbs = relativeWidget.getContentSize();
+ var locationRight = relativeWidget.getRightBoundary();
+ this._finalPositionX = locationRight + ap.x * cs.width;
+ this._finalPositionY = relativeWidget.getBottomBoundary() + rbs.height * 0.5 + ap.y * cs.height - cs.height * 0.5;
+ }
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_RIGHT_OF_BOTTOMALIGN:
+ if (relativeWidget) {
+ if (this._relativeWidgetLP && !this._relativeWidgetLP._put)
+ return false;
+ this._finalPositionY = relativeWidget.getBottomBoundary() + ap.y * cs.height;
+ this._finalPositionX = relativeWidget.getRightBoundary() + ap.x * cs.width;
+ }
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_BELOW_LEFTALIGN:
+ if (relativeWidget) {
+ if (this._relativeWidgetLP && !this._relativeWidgetLP._put)
+ return false;
+ this._finalPositionY = relativeWidget.getBottomBoundary() - (1.0 - ap.y) * cs.height;
+ this._finalPositionX = relativeWidget.getLeftBoundary() + ap.x * cs.width;
+ }
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_BELOW_CENTER:
+ if (relativeWidget) {
+ if (this._relativeWidgetLP && !this._relativeWidgetLP._put)
+ return false;
+ var rbs = relativeWidget.getContentSize();
+ this._finalPositionY = relativeWidget.getBottomBoundary() - (1.0 - ap.y) * cs.height;
+ this._finalPositionX = relativeWidget.getLeftBoundary() + rbs.width * 0.5 + ap.x * cs.width - cs.width * 0.5;
+ }
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_BELOW_RIGHTALIGN:
+ if (relativeWidget) {
+ if (this._relativeWidgetLP && !this._relativeWidgetLP._put)
+ return false;
+ this._finalPositionY = relativeWidget.getBottomBoundary() - (1.0 - ap.y) * cs.height;
+ this._finalPositionX = relativeWidget.getRightBoundary() - (1.0 - ap.x) * cs.width;
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+ },
+
+ _calculateFinalPositionWithRelativeAlign: function () {
+ var layoutParameter = this._widget.getLayoutParameter();
+
+ var mg = layoutParameter.getMargin();
+ var align = layoutParameter.getAlign();
+
+ //handle margin
+ switch (align) {
+ case ccui.RelativeLayoutParameter.NONE:
+ case ccui.RelativeLayoutParameter.PARENT_TOP_LEFT:
+ this._finalPositionX += mg.left;
+ this._finalPositionY -= mg.top;
+ break;
+ case ccui.RelativeLayoutParameter.PARENT_TOP_CENTER_HORIZONTAL:
+ this._finalPositionY -= mg.top;
+ break;
+ case ccui.RelativeLayoutParameter.PARENT_TOP_RIGHT:
+ this._finalPositionX -= mg.right;
+ this._finalPositionY -= mg.top;
+ break;
+ case ccui.RelativeLayoutParameter.PARENT_LEFT_CENTER_VERTICAL:
+ this._finalPositionX += mg.left;
+ break;
+ case ccui.RelativeLayoutParameter.CENTER_IN_PARENT:
+ break;
+ case ccui.RelativeLayoutParameter.PARENT_RIGHT_CENTER_VERTICAL:
+ this._finalPositionX -= mg.right;
+ break;
+ case ccui.RelativeLayoutParameter.PARENT_LEFT_BOTTOM:
+ this._finalPositionX += mg.left;
+ this._finalPositionY += mg.bottom;
+ break;
+ case ccui.RelativeLayoutParameter.PARENT_BOTTOM_CENTER_HORIZONTAL:
+ this._finalPositionY += mg.bottom;
+ break;
+ case ccui.RelativeLayoutParameter.PARENT_RIGHT_BOTTOM:
+ this._finalPositionX -= mg.right;
+ this._finalPositionY += mg.bottom;
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_ABOVE_LEFTALIGN:
+ this._finalPositionY += mg.bottom;
+ this._finalPositionX += mg.left;
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_ABOVE_RIGHTALIGN:
+ this._finalPositionY += mg.bottom;
+ this._finalPositionX -= mg.right;
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_ABOVE_CENTER:
+ this._finalPositionY += mg.bottom;
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_LEFT_OF_TOPALIGN:
+ this._finalPositionX -= mg.right;
+ this._finalPositionY -= mg.top;
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_LEFT_OF_BOTTOMALIGN:
+ this._finalPositionX -= mg.right;
+ this._finalPositionY += mg.bottom;
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_LEFT_OF_CENTER:
+ this._finalPositionX -= mg.right;
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_RIGHT_OF_TOPALIGN:
+ this._finalPositionX += mg.left;
+ this._finalPositionY -= mg.top;
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_RIGHT_OF_BOTTOMALIGN:
+ this._finalPositionX += mg.left;
+ this._finalPositionY += mg.bottom;
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_RIGHT_OF_CENTER:
+ this._finalPositionX += mg.left;
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_BELOW_LEFTALIGN:
+ this._finalPositionY -= mg.top;
+ this._finalPositionX += mg.left;
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_BELOW_RIGHTALIGN:
+ this._finalPositionY -= mg.top;
+ this._finalPositionX -= mg.right;
+ break;
+ case ccui.RelativeLayoutParameter.LOCATION_BELOW_CENTER:
+ this._finalPositionY -= mg.top;
+ break;
+ default:
+ break;
+ }
+ }
+};
diff --git a/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayoutParameter.js b/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayoutParameter.js
new file mode 100644
index 0000000..2ea2919
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayoutParameter.js
@@ -0,0 +1,576 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Base class for ccui.Margin
+ * @class
+ * @extends ccui.Class
+ *
+ * @property {Number} left - Left of margin
+ * @property {Number} top - Top of margin
+ * @property {Number} right - right of margin
+ * @property {Number} bottom - bottom of margin
+ */
+ccui.Margin = ccui.Class.extend(/** @lends ccui.Margin# */{
+ left: 0,
+ top: 0,
+ right: 0,
+ bottom: 0,
+ /**
+ * Constructor of ccui.Margin.
+ * @param {Number|ccui.Margin} margin a margin or left
+ * @param {Number} [top]
+ * @param {Number} [right]
+ * @param {Number} [bottom]
+ */
+ ctor: function (margin, top, right, bottom) {
+ if (margin !== undefined && top === undefined) {
+ this.left = margin.left;
+ this.top = margin.top;
+ this.right = margin.right;
+ this.bottom = margin.bottom;
+ }
+ if (bottom !== undefined) {
+ this.left = margin;
+ this.top = top;
+ this.right = right;
+ this.bottom = bottom;
+ }
+ },
+ /**
+ * Sets boundary of margin
+ * @param {Number} l left
+ * @param {Number} t top
+ * @param {Number} r right
+ * @param {Number} b bottom
+ */
+ setMargin: function (l, t, r, b) {
+ this.left = l;
+ this.top = t;
+ this.right = r;
+ this.bottom = b;
+ },
+ /**
+ * Checks target whether equals itself.
+ * @param {ccui.Margin} target
+ * @returns {boolean}
+ */
+ equals: function (target) {
+ return (this.left === target.left && this.top === target.top && this.right === target.right && this.bottom === target.bottom);
+ }
+});
+
+/**
+ * Gets a zero margin object
+ * @function
+ * @returns {ccui.Margin}
+ */
+ccui.MarginZero = function(){
+ return new ccui.Margin(0,0,0,0);
+};
+
+/**
+ * Layout parameter contains a margin and layout parameter type. It uses for ccui.LayoutManager.
+ * @class
+ * @extends ccui.Class
+ */
+ccui.LayoutParameter = ccui.Class.extend(/** @lends ccui.LayoutParameter# */{
+ _margin: null,
+ _layoutParameterType: null,
+
+ /**
+ * The constructor of ccui.LayoutParameter.
+ * @function
+ */
+ ctor: function () {
+ this._margin = new ccui.Margin();
+ this._layoutParameterType = ccui.LayoutParameter.NONE;
+ },
+
+ /**
+ * Sets Margin to LayoutParameter.
+ * @param {ccui.Margin} margin
+ */
+ setMargin: function (margin) {
+ if(cc.isObject(margin)){
+ this._margin.left = margin.left;
+ this._margin.top = margin.top;
+ this._margin.right = margin.right;
+ this._margin.bottom = margin.bottom;
+ }else{
+ this._margin.left = arguments[0];
+ this._margin.top = arguments[1];
+ this._margin.right = arguments[2];
+ this._margin.bottom = arguments[3];
+ }
+ },
+
+ /**
+ * Gets Margin of LayoutParameter.
+ * @returns {ccui.Margin}
+ */
+ getMargin: function () {
+ return this._margin;
+ },
+
+ /**
+ * Gets LayoutParameterType of LayoutParameter.
+ * @returns {Number}
+ */
+ getLayoutType: function () {
+ return this._layoutParameterType;
+ },
+
+ /**
+ * Clones a ccui.LayoutParameter object from itself.
+ * @returns {ccui.LayoutParameter}
+ */
+ clone:function(){
+ var parameter = this._createCloneInstance();
+ parameter._copyProperties(this);
+ return parameter;
+ },
+
+ /**
+ * create clone instance.
+ * @returns {ccui.LayoutParameter}
+ */
+ _createCloneInstance:function(){
+ return new ccui.LayoutParameter();
+ },
+
+ /**
+ * copy properties from model.
+ * @param {ccui.LayoutParameter} model
+ */
+ _copyProperties:function(model){
+ this._margin.bottom = model._margin.bottom;
+ this._margin.left = model._margin.left;
+ this._margin.right = model._margin.right;
+ this._margin.top = model._margin.top;
+ }
+});
+
+/**
+ * allocates and initializes a LayoutParameter.
+ * @constructs
+ * @return {ccui.LayoutParameter}
+ */
+ccui.LayoutParameter.create = function () {
+ return new ccui.LayoutParameter();
+};
+
+// Constants
+//layout parameter type
+/**
+ * The none of ccui.LayoutParameter's type.
+ * @constant
+ * @type {number}
+ */
+ccui.LayoutParameter.NONE = 0;
+/**
+ * The linear of ccui.LayoutParameter's type.
+ * @constant
+ * @type {number}
+ */
+ccui.LayoutParameter.LINEAR = 1;
+/**
+ * The relative of ccui.LayoutParameter's type.
+ * @constant
+ * @type {number}
+ */
+ccui.LayoutParameter.RELATIVE = 2;
+
+/**
+ * The linear of Layout parameter. its parameter type is ccui.LayoutParameter.LINEAR.
+ * @class
+ * @extends ccui.LayoutParameter
+ */
+ccui.LinearLayoutParameter = ccui.LayoutParameter.extend(/** @lends ccui.LinearLayoutParameter# */{
+ _linearGravity: null,
+ /**
+ * The constructor of ccui.LinearLayoutParameter.
+ * @function
+ */
+ ctor: function () {
+ ccui.LayoutParameter.prototype.ctor.call(this);
+ this._linearGravity = ccui.LinearLayoutParameter.NONE;
+ this._layoutParameterType = ccui.LayoutParameter.LINEAR;
+ },
+
+ /**
+ * Sets LinearGravity to LayoutParameter.
+ * @param {Number} gravity
+ */
+ setGravity: function (gravity) {
+ this._linearGravity = gravity;
+ },
+
+ /**
+ * Gets LinearGravity of LayoutParameter.
+ * @returns {Number}
+ */
+ getGravity: function () {
+ return this._linearGravity;
+ },
+
+ _createCloneInstance: function () {
+ return new ccui.LinearLayoutParameter();
+ },
+
+ _copyProperties: function (model) {
+ ccui.LayoutParameter.prototype._copyProperties.call(this, model);
+ if (model instanceof ccui.LinearLayoutParameter)
+ this.setGravity(model._linearGravity);
+ }
+});
+
+/**
+ * allocates and initializes a LinearLayoutParameter.
+ * @constructs
+ * @return {ccui.LinearLayoutParameter}
+ * @deprecated since v3.0, please use new construction instead
+ */
+ccui.LinearLayoutParameter.create = function () {
+ return new ccui.LinearLayoutParameter();
+};
+
+// Constants
+//Linear layout parameter LinearGravity
+/**
+ * The none of ccui.LinearLayoutParameter's linear gravity.
+ * @constant
+ * @type {number}
+ */
+ccui.LinearLayoutParameter.NONE = 0;
+
+/**
+ * The left of ccui.LinearLayoutParameter's linear gravity.
+ * @constant
+ * @type {number}
+ */
+ccui.LinearLayoutParameter.LEFT = 1;
+/**
+ * The top of ccui.LinearLayoutParameter's linear gravity.
+ * @constant
+ * @type {number}
+ */
+ccui.LinearLayoutParameter.TOP = 2;
+/**
+ * The right of ccui.LinearLayoutParameter's linear gravity.
+ * @constant
+ * @type {number}
+ */
+ccui.LinearLayoutParameter.RIGHT = 3;
+/**
+ * The bottom of ccui.LinearLayoutParameter's linear gravity.
+ * @constant
+ * @type {number}
+ */
+ccui.LinearLayoutParameter.BOTTOM = 4;
+/**
+ * The center vertical of ccui.LinearLayoutParameter's linear gravity.
+ * @constant
+ * @type {number}
+ */
+ccui.LinearLayoutParameter.CENTER_VERTICAL = 5;
+/**
+ * The center horizontal of ccui.LinearLayoutParameter's linear gravity.
+ * @constant
+ * @type {number}
+ */
+ccui.LinearLayoutParameter.CENTER_HORIZONTAL = 6;
+
+/**
+ * The relative of layout parameter. Its layout parameter type is ccui.LayoutParameter.RELATIVE.
+ * @class
+ * @extends ccui.LayoutParameter
+ */
+ccui.RelativeLayoutParameter = ccui.LayoutParameter.extend(/** @lends ccui.RelativeLayoutParameter# */{
+ _relativeAlign: null,
+ _relativeWidgetName: "",
+ _relativeLayoutName: "",
+ _put:false,
+ /**
+ * The constructor of ccui.RelativeLayoutParameter
+ * @function
+ */
+ ctor: function () {
+ ccui.LayoutParameter.prototype.ctor.call(this);
+ this._relativeAlign = ccui.RelativeLayoutParameter.NONE;
+ this._relativeWidgetName = "";
+ this._relativeLayoutName = "";
+ this._put = false;
+ this._layoutParameterType = ccui.LayoutParameter.RELATIVE;
+ },
+
+ /**
+ * Sets RelativeAlign parameter for LayoutParameter.
+ * @param {Number} align
+ */
+ setAlign: function (align) {
+ this._relativeAlign = align;
+ },
+
+ /**
+ * Gets RelativeAlign parameter for LayoutParameter.
+ * @returns {Number}
+ */
+ getAlign: function () {
+ return this._relativeAlign;
+ },
+
+ /**
+ * Sets a key for LayoutParameter. Witch widget named this is relative to.
+ * @param {String} name
+ */
+ setRelativeToWidgetName: function (name) {
+ this._relativeWidgetName = name;
+ },
+
+ /**
+ * Gets the key of LayoutParameter. Witch widget named this is relative to.
+ * @returns {string}
+ */
+ getRelativeToWidgetName: function () {
+ return this._relativeWidgetName;
+ },
+
+ /**
+ * Sets a name in Relative Layout for LayoutParameter.
+ * @param {String} name
+ */
+ setRelativeName: function (name) {
+ this._relativeLayoutName = name;
+ },
+
+ /**
+ * Gets a name in Relative Layout of LayoutParameter.
+ * @returns {string}
+ */
+ getRelativeName: function () {
+ return this._relativeLayoutName;
+ },
+
+ _createCloneInstance:function(){
+ return new ccui.RelativeLayoutParameter();
+ },
+
+ _copyProperties:function(model){
+ ccui.LayoutParameter.prototype._copyProperties.call(this, model);
+ if (model instanceof ccui.RelativeLayoutParameter) {
+ this.setAlign(model._relativeAlign);
+ this.setRelativeToWidgetName(model._relativeWidgetName);
+ this.setRelativeName(model._relativeLayoutName);
+ }
+ }
+});
+
+/**
+ * Allocates and initializes a RelativeLayoutParameter.
+ * @function
+ * @deprecated since v3.0, please use new ccui.RelativeLayoutParameter() instead.
+ * @return {ccui.RelativeLayoutParameter}
+ */
+ccui.RelativeLayoutParameter.create = function () {
+ return new ccui.RelativeLayoutParameter();
+};
+
+// Constants
+//Relative layout parameter RelativeAlign
+/**
+ * The none of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.NONE = 0;
+/**
+ * The parent's top left of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.PARENT_TOP_LEFT = 1;
+/**
+ * The parent's top center horizontal of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.PARENT_TOP_CENTER_HORIZONTAL = 2;
+/**
+ * The parent's top right of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.PARENT_TOP_RIGHT = 3;
+/**
+ * The parent's left center vertical of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.PARENT_LEFT_CENTER_VERTICAL = 4;
+
+/**
+ * The center in parent of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.CENTER_IN_PARENT = 5;
+
+/**
+ * The parent's right center vertical of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.PARENT_RIGHT_CENTER_VERTICAL = 6;
+/**
+ * The parent's left bottom of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.PARENT_LEFT_BOTTOM = 7;
+/**
+ * The parent's bottom center horizontal of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.PARENT_BOTTOM_CENTER_HORIZONTAL = 8;
+/**
+ * The parent's right bottom of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.PARENT_RIGHT_BOTTOM = 9;
+
+/**
+ * The location above left align of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.LOCATION_ABOVE_LEFTALIGN = 10;
+/**
+ * The location above center of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.LOCATION_ABOVE_CENTER = 11;
+/**
+ * The location above right align of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.LOCATION_ABOVE_RIGHTALIGN = 12;
+/**
+ * The location left of top align of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.LOCATION_LEFT_OF_TOPALIGN = 13;
+/**
+ * The location left of center of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.LOCATION_LEFT_OF_CENTER = 14;
+/**
+ * The location left of bottom align of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.LOCATION_LEFT_OF_BOTTOMALIGN = 15;
+/**
+ * The location right of top align of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.LOCATION_RIGHT_OF_TOPALIGN = 16;
+/**
+ * The location right of center of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.LOCATION_RIGHT_OF_CENTER = 17;
+/**
+ * The location right of bottom align of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.LOCATION_RIGHT_OF_BOTTOMALIGN = 18;
+/**
+ * The location below left align of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.LOCATION_BELOW_LEFTALIGN = 19;
+/**
+ * The location below center of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.LOCATION_BELOW_CENTER = 20;
+/**
+ * The location below right align of ccui.RelativeLayoutParameter's relative align.
+ * @constant
+ * @type {number}
+ */
+ccui.RelativeLayoutParameter.LOCATION_BELOW_RIGHTALIGN = 21;
+
+/**
+ * @ignore
+ */
+ccui.LINEAR_GRAVITY_NONE = 0;
+ccui.LINEAR_GRAVITY_LEFT = 1;
+ccui.LINEAR_GRAVITY_TOP = 2;
+ccui.LINEAR_GRAVITY_RIGHT = 3;
+ccui.LINEAR_GRAVITY_BOTTOM = 4;
+ccui.LINEAR_GRAVITY_CENTER_VERTICAL = 5;
+ccui.LINEAR_GRAVITY_CENTER_HORIZONTAL = 6;
+
+//RelativeAlign
+ccui.RELATIVE_ALIGN_NONE = 0;
+ccui.RELATIVE_ALIGN_PARENT_TOP_LEFT = 1;
+ccui.RELATIVE_ALIGN_PARENT_TOP_CENTER_HORIZONTAL = 2;
+ccui.RELATIVE_ALIGN_PARENT_TOP_RIGHT = 3;
+ccui.RELATIVE_ALIGN_PARENT_LEFT_CENTER_VERTICAL = 4;
+ccui.RELATIVE_ALIGN_PARENT_CENTER = 5;
+ccui.RELATIVE_ALIGN_PARENT_RIGHT_CENTER_VERTICAL = 6;
+ccui.RELATIVE_ALIGN_PARENT_LEFT_BOTTOM = 7;
+ccui.RELATIVE_ALIGN_PARENT_BOTTOM_CENTER_HORIZONTAL = 8;
+ccui.RELATIVE_ALIGN_PARENT_RIGHT_BOTTOM = 9;
+
+ccui.RELATIVE_ALIGN_LOCATION_ABOVE_LEFT = 10;
+ccui.RELATIVE_ALIGN_LOCATION_ABOVE_CENTER = 11;
+ccui.RELATIVE_ALIGN_LOCATION_ABOVE_RIGHT = 12;
+
+ccui.RELATIVE_ALIGN_LOCATION_LEFT_TOP = 13;
+ccui.RELATIVE_ALIGN_LOCATION_LEFT_CENTER = 14;
+ccui.RELATIVE_ALIGN_LOCATION_LEFT_BOTTOM = 15;
+
+ccui.RELATIVE_ALIGN_LOCATION_RIGHT_TOP = 16;
+ccui.RELATIVE_ALIGN_LOCATION_RIGHT_CENTER = 17;
+ccui.RELATIVE_ALIGN_LOCATION_RIGHT_BOTTOM = 18;
+
+ccui.RELATIVE_ALIGN_LOCATION_BELOW_TOP = 19;
+ccui.RELATIVE_ALIGN_LOCATION_BELOW_CENTER = 20;
+ccui.RELATIVE_ALIGN_LOCATION_BELOW_BOTTOM = 21;
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayoutWebGLRenderCmd.js b/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayoutWebGLRenderCmd.js
new file mode 100644
index 0000000..e83dc0c
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/layouts/UILayoutWebGLRenderCmd.js
@@ -0,0 +1,204 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ if (!ccui.ProtectedNode.WebGLRenderCmd)
+ return;
+ ccui.Layout.WebGLRenderCmd = function (renderable) {
+ this._pNodeCmdCtor(renderable);
+ this._needDraw = false;
+
+ this._currentStencilEnabled = 0;
+ this._scissorOldState = false;
+ this._clippingOldRect = null;
+
+ this._mask_layer_le = 0;
+
+ this._beforeVisitCmdStencil = null;
+ this._afterDrawStencilCmd = null;
+ this._afterVisitCmdStencil = null;
+ this._beforeVisitCmdScissor = null;
+ this._afterVisitCmdScissor = null;
+ };
+
+ var proto = ccui.Layout.WebGLRenderCmd.prototype = Object.create(ccui.ProtectedNode.WebGLRenderCmd.prototype);
+ proto.constructor = ccui.Layout.WebGLRenderCmd;
+ proto._layoutCmdCtor = ccui.Layout.CanvasRenderCmd;
+
+ proto._syncStatus = function (parentCmd) {
+ this._originSyncStatus(parentCmd);
+
+ if (parentCmd && (parentCmd._dirtyFlag & cc.Node._dirtyFlags.transformDirty))
+ this._node._clippingRectDirty = true;
+ };
+
+ proto._onBeforeVisitStencil = function (ctx) {
+ var gl = ctx || cc._renderContext;
+
+ ccui.Layout.WebGLRenderCmd._layer++;
+
+ var mask_layer = 0x1 << ccui.Layout.WebGLRenderCmd._layer;
+ var mask_layer_l = mask_layer - 1;
+ this._mask_layer_le = mask_layer | mask_layer_l;
+
+ // manually save the stencil state
+ this._currentStencilEnabled = gl.isEnabled(gl.STENCIL_TEST);
+
+ gl.clear(gl.DEPTH_BUFFER_BIT);
+
+ gl.enable(gl.STENCIL_TEST);
+
+ gl.depthMask(false);
+
+ gl.stencilFunc(gl.NEVER, mask_layer, mask_layer);
+ gl.stencilOp(gl.REPLACE, gl.KEEP, gl.KEEP);
+
+ gl.stencilMask(mask_layer);
+ gl.clear(gl.STENCIL_BUFFER_BIT);
+ };
+
+ proto._onAfterDrawStencil = function (ctx) {
+ var gl = ctx || cc._renderContext;
+ gl.depthMask(true);
+ gl.stencilFunc(gl.EQUAL, this._mask_layer_le, this._mask_layer_le);
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
+ };
+
+ proto._onAfterVisitStencil = function (ctx) {
+ var gl = ctx || cc._renderContext;
+
+ ccui.Layout.WebGLRenderCmd._layer--;
+
+ if (this._currentStencilEnabled) {
+ var mask_layer = 0x1 << ccui.Layout.WebGLRenderCmd._layer;
+ var mask_layer_l = mask_layer - 1;
+ var mask_layer_le = mask_layer | mask_layer_l;
+
+ gl.stencilMask(mask_layer);
+ gl.stencilFunc(gl.EQUAL, mask_layer_le, mask_layer_le);
+ }
+ else {
+ gl.disable(gl.STENCIL_TEST);
+ }
+ };
+
+ proto._onBeforeVisitScissor = function (ctx) {
+ this._node._clippingRectDirty = true;
+ var clippingRect = this._node._getClippingRect();
+ var gl = ctx || cc._renderContext;
+
+ this._scissorOldState = gl.isEnabled(gl.SCISSOR_TEST);
+
+ if (!this._scissorOldState) {
+ gl.enable(gl.SCISSOR_TEST);
+ cc.view.setScissorInPoints(clippingRect.x, clippingRect.y, clippingRect.width, clippingRect.height);
+ }
+ else {
+ this._clippingOldRect = cc.view.getScissorRect();
+ if (!cc.rectEqualToRect(this._clippingOldRect, clippingRect))
+ cc.view.setScissorInPoints(clippingRect.x, clippingRect.y, clippingRect.width, clippingRect.height);
+ }
+ };
+
+ proto._onAfterVisitScissor = function (ctx) {
+ var gl = ctx || cc._renderContext;
+ if (this._scissorOldState) {
+ if (!cc.rectEqualToRect(this._clippingOldRect, this._node._clippingRect)) {
+ cc.view.setScissorInPoints(this._clippingOldRect.x,
+ this._clippingOldRect.y,
+ this._clippingOldRect.width,
+ this._clippingOldRect.height);
+ }
+ }
+ else {
+ gl.disable(gl.SCISSOR_TEST);
+ }
+ };
+
+ proto.rebindStencilRendering = function (stencil) {
+ };
+
+ proto.transform = function (parentCmd, recursive) {
+ var node = this._node;
+ this.pNodeTransform(parentCmd, recursive);
+ if (node._clippingStencil)
+ node._clippingStencil._renderCmd.transform(this, recursive);
+ };
+
+ proto.stencilClippingVisit = function (parentCmd) {
+ var node = this._node;
+ if (!node._clippingStencil || !node._clippingStencil.isVisible())
+ return;
+
+ // all the _stencilBits are in use?
+ if (ccui.Layout.WebGLRenderCmd._layer + 1 === cc.stencilBits) {
+ // warn once
+ ccui.Layout.WebGLRenderCmd._visit_once = true;
+ if (ccui.Layout.WebGLRenderCmd._visit_once) {
+ cc.log("Nesting more than " + cc.stencilBits + "stencils is not supported. Everything will be drawn without stencil for this node and its childs.");
+ ccui.Layout.WebGLRenderCmd._visit_once = false;
+ }
+ // draw everything, as if there where no stencil
+ return;
+ }
+
+ if (!this._beforeVisitCmdStencil) {
+ this._beforeVisitCmdStencil = new cc.CustomRenderCmd(this, this._onBeforeVisitStencil);
+ this._afterDrawStencilCmd = new cc.CustomRenderCmd(this, this._onAfterDrawStencil);
+ this._afterVisitCmdStencil = new cc.CustomRenderCmd(this, this._onAfterVisitStencil);
+ }
+
+ cc.renderer.pushRenderCommand(this._beforeVisitCmdStencil);
+
+ //optimize performance for javascript
+ var currentStack = cc.current_stack;
+ currentStack.stack.push(currentStack.top);
+ currentStack.top = this._stackMatrix;
+
+ node._clippingStencil.visit(this);
+
+ cc.renderer.pushRenderCommand(this._afterDrawStencilCmd);
+ };
+
+ proto.postStencilVisit = function () {
+ renderer.pushRenderCommand(cmd._afterVisitCmdStencil);
+ cc.current_stack.top = cc.current_stack.stack.pop();
+ };
+
+ proto.scissorClippingVisit = function (parentCmd) {
+ if (!this._beforeVisitCmdScissor) {
+ this._beforeVisitCmdScissor = new cc.CustomRenderCmd(this, this._onBeforeVisitScissor);
+ this._afterVisitCmdScissor = new cc.CustomRenderCmd(this, this._onAfterVisitScissor);
+ }
+ cc.renderer.pushRenderCommand(this._beforeVisitCmdScissor);
+ };
+
+ proto.postScissorVisit = function () {
+ cc.renderer.pushRenderCommand(this._afterVisitCmdScissor);
+ };
+
+ ccui.Layout.WebGLRenderCmd._layer = -1;
+ ccui.Layout.WebGLRenderCmd._visit_once = null;
+})();
diff --git a/frameworks/cocos2d-html5/extensions/ccui/layouts/UIRelativeBox.js b/frameworks/cocos2d-html5/extensions/ccui/layouts/UIRelativeBox.js
new file mode 100644
index 0000000..064be6e
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/layouts/UIRelativeBox.js
@@ -0,0 +1,55 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The Relative box for Cocos UI layout. Its layout type is ccui.Layout.RELATIVE.
+ * @class
+ * @extends ccui.Layout
+ */
+ccui.RelativeBox = ccui.Layout.extend(/** @lends ccui.RelativeBox# */{
+ /**
+ * The constructor of ccui.RelativeBox
+ * @function
+ * @param {cc.Size} [size]
+ */
+ ctor: function(size){
+ ccui.Layout.prototype.ctor.call(this);
+ this.setLayoutType(ccui.Layout.RELATIVE);
+
+ if(size) {
+ this.setContentSize(size);
+ }
+ }
+});
+
+/**
+ * Creates a relative box
+ * @deprecated since v3.0, please use new ccui.RelativeBox(size) instead.
+ * @param {cc.Size} size
+ * @returns {ccui.RelativeBox}
+ */
+ccui.RelativeBox.create = function(size){
+ return new ccui.RelativeBox(size);
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/ccui/layouts/UIVBox.js b/frameworks/cocos2d-html5/extensions/ccui/layouts/UIVBox.js
new file mode 100644
index 0000000..d6888be
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/layouts/UIVBox.js
@@ -0,0 +1,67 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The vertical box of Cocos UI. Its layout type is ccui.Layout.LINEAR_VERTICAL.
+ * @class
+ * @extends ccui.Layout
+ */
+ccui.VBox = ccui.Layout.extend(/** @lends ccui.VBox# */{
+ /**
+ * The constructor of ccui.VBox
+ * @function
+ * @param {cc.Size} size
+ */
+ ctor: function(size){
+ ccui.Layout.prototype.ctor.call(this);
+ this.setLayoutType(ccui.Layout.LINEAR_VERTICAL);
+
+ if (size) {
+ this.setContentSize(size);
+ }
+ },
+
+ /**
+ * Initializes a VBox with size.
+ * @param {cc.Size} size
+ * @returns {boolean}
+ */
+ initWithSize: function(size){
+ if(this.init()){
+
+ return true;
+ }
+ return false;
+ }
+});
+
+/**
+ * Creates a VBox
+ * @param {cc.Size} size
+ * @returns {ccui.VBox}
+ */
+ccui.VBox.create = function(size){
+ return new ccui.VBox(size);
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/ccui/system/CocosGUI.js b/frameworks/cocos2d-html5/extensions/ccui/system/CocosGUI.js
new file mode 100644
index 0000000..30622d0
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/system/CocosGUI.js
@@ -0,0 +1,62 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The namespace of Cocos UI
+ * @namespace
+ * @name ccui
+ */
+var ccui = ccui || {};
+
+//These classes defines are use for jsDoc
+/**
+ * The same as cc.Class
+ * @class
+ */
+ccui.Class = ccui.Class || cc.Class;
+ccui.Class.extend = ccui.Class.extend || cc.Class.extend;
+
+/**
+ * that same as cc.Node
+ * @class
+ * @extends ccui.Class
+ */
+ccui.Node = ccui.Node || cc.Node;
+ccui.Node.extend = ccui.Node.extend || cc.Node.extend;
+
+
+/**
+ * that same as cc.Node
+ * @class
+ * @extends ccui.Node
+ */
+ccui.ProtectedNode = ccui.ProtectedNode || cc.ProtectedNode;
+ccui.ProtectedNode.extend = ccui.ProtectedNode.extend || cc.ProtectedNode.extend;
+
+/**
+ * Cocos UI version
+ * @type {String}
+ */
+ccui.cocosGUIVersion = "CocosGUI v1.0.0.0";
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/ccui/system/UIHelper.js b/frameworks/cocos2d-html5/extensions/ccui/system/UIHelper.js
new file mode 100644
index 0000000..327bf8d
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/system/UIHelper.js
@@ -0,0 +1,179 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+//todo maybe need change here
+
+
+/**
+ * ccui.helper is the singleton object which is the Helper object contains some functions for seek widget
+ * @class
+ * @name ccui.helper
+ */
+ccui.helper = {
+ /**
+ * Finds a widget whose tag equals to param tag from root widget.
+ * @param {ccui.Widget} root
+ * @param {number} tag
+ * @returns {ccui.Widget}
+ */
+ seekWidgetByTag: function (root, tag) {
+ if (!root)
+ return null;
+ if (root.getTag() === tag)
+ return root;
+
+ var arrayRootChildren = root.getChildren();
+ var length = arrayRootChildren.length;
+ for (var i = 0; i < length; i++) {
+ var child = arrayRootChildren[i];
+ var res = ccui.helper.seekWidgetByTag(child, tag);
+ if (res !== null)
+ return res;
+ }
+ return null;
+ },
+
+ /**
+ * Finds a widget whose name equals to param name from root widget.
+ * @param {ccui.Widget} root
+ * @param {String} name
+ * @returns {ccui.Widget}
+ */
+ seekWidgetByName: function (root, name) {
+ if (!root)
+ return null;
+ if (root.getName() === name)
+ return root;
+ var arrayRootChildren = root.getChildren();
+ var length = arrayRootChildren.length;
+ for (var i = 0; i < length; i++) {
+ var child = arrayRootChildren[i];
+ var res = ccui.helper.seekWidgetByName(child, name);
+ if (res !== null)
+ return res;
+ }
+ return null;
+ },
+
+ /**
+ * Finds a widget whose name equals to param name from root widget.
+ * RelativeLayout will call this method to find the widget witch is needed.
+ * @param {ccui.Widget} root
+ * @param {String} name
+ * @returns {ccui.Widget}
+ */
+ seekWidgetByRelativeName: function (root, name) {
+ if (!root)
+ return null;
+ var arrayRootChildren = root.getChildren();
+ var length = arrayRootChildren.length;
+ for (var i = 0; i < length; i++) {
+ var child = arrayRootChildren[i];
+ var layoutParameter = child.getLayoutParameter(ccui.LayoutParameter.RELATIVE);
+ if (layoutParameter && layoutParameter.getRelativeName() === name)
+ return child;
+ }
+ return null;
+ },
+
+ /**
+ * Finds a widget whose action tag equals to param name from root widget.
+ * @param {ccui.Widget} root
+ * @param {Number} tag
+ * @returns {ccui.Widget}
+ */
+ seekActionWidgetByActionTag: function (root, tag) {
+ if (!root)
+ return null;
+ if (root.getActionTag() === tag)
+ return root;
+ var arrayRootChildren = root.getChildren();
+ for (var i = 0; i < arrayRootChildren.length; i++) {
+ var child = arrayRootChildren[i];
+ var res = ccui.helper.seekActionWidgetByActionTag(child, tag);
+ if (res !== null)
+ return res;
+ }
+ return null;
+ },
+
+ _activeLayout: true,
+ /**
+ * Refresh object and it's children layout state
+ * @param {cc.Node} rootNode
+ */
+ doLayout: function (rootNode) {
+ if (!this._activeLayout)
+ return;
+ var children = rootNode.getChildren(), node;
+ for(var i = 0, len = children.length;i < len; i++) {
+ node = children[i];
+ var com = node.getComponent(ccui.LayoutComponent.NAME);
+ var parent = node.getParent();
+ if (null != com && null !== parent && com.refreshLayout)
+ com.refreshLayout();
+ }
+ },
+
+ changeLayoutSystemActiveState: function (active) {
+ this._activeLayout = active;
+ },
+
+ /**
+ * restrict capInsetSize, when the capInsets' width is larger than the textureSize, it will restrict to 0,
+ * the height goes the same way as width.
+ * @param {cc.Rect} capInsets
+ * @param {cc.Size} textureSize
+ */
+ restrictCapInsetRect: function (capInsets, textureSize) {
+ var x = capInsets.x, y = capInsets.y;
+ var width = capInsets.width, height = capInsets.height;
+
+ if (textureSize.width < width) {
+ x = 0.0;
+ width = 0.0;
+ }
+ if (textureSize.height < height) {
+ y = 0.0;
+ height = 0.0;
+ }
+ return cc.rect(x, y, width, height);
+ },
+
+ _createSpriteFromBase64: function (base64String, key) {
+ var texture2D = cc.textureCache.getTextureForKey(key);
+
+ if (!texture2D) {
+ var image = new Image();
+ image.src = base64String;
+ cc.textureCache.cacheImage(key, image);
+ texture2D = cc.textureCache.getTextureForKey(key);
+ }
+
+ var sprite = new cc.Sprite(texture2D);
+
+ return sprite;
+ }
+};
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIButton.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIButton.js
new file mode 100644
index 0000000..4741e2e
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIButton.js
@@ -0,0 +1,857 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2015-2016 zilongshanren
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The button controls of Cocos UI.
+ * @class
+ * @extends ccui.Widget
+ *
+ * @property {String} titleText - The content string of the button title
+ * @property {String} titleFont - The content string font of the button title
+ * @property {Number} titleFontSize - The content string font size of the button title
+ * @property {String} titleFontName - The content string font name of the button title
+ * @property {cc.Color} titleColor - The content string font color of the button title
+ * @property {Boolean} pressedActionEnabled - Indicate whether button has zoom effect when clicked
+ */
+ccui.Button = ccui.Widget.extend(/** @lends ccui.Button# */{
+ _buttonScale9Renderer: null,
+ _buttonNormalSpriteFrame: null,
+ _buttonClickedSpriteFrame: null,
+ _buttonDisableSpriteFrame: null,
+ _titleRenderer: null,
+
+ _normalFileName: "",
+ _clickedFileName: "",
+ _disabledFileName: "",
+
+ _prevIgnoreSize: true,
+ _scale9Enabled: false,
+
+ _capInsetsNormal: null,
+
+ _normalTexType: ccui.Widget.LOCAL_TEXTURE,
+ _pressedTexType: ccui.Widget.LOCAL_TEXTURE,
+ _disabledTexType: ccui.Widget.LOCAL_TEXTURE,
+
+ _normalTextureSize: null,
+
+ pressedActionEnabled: false,
+ _titleColor: null,
+
+ _zoomScale: 0.1,
+
+ _normalTextureLoaded: false,
+ _pressedTextureLoaded: false,
+ _disabledTextureLoaded: false,
+
+ _className: "Button",
+ _normalTextureAdaptDirty: true,
+
+ _fontName: "Thonburi",
+ _fontSize: 12,
+ _type: 0,
+
+ /**
+ * Allocates and initializes a UIButton.
+ * Constructor of ccui.Button. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {String} normalImage
+ * @param {String} [selectedImage=""]
+ * @param {String} [disableImage=""]
+ * @param {Number} [texType=ccui.Widget.LOCAL_TEXTURE]
+ * @example
+ * // example
+ * var uiButton = new ccui.Button();
+ */
+ ctor: function (normalImage, selectedImage, disableImage, texType) {
+ this._capInsetsNormal = cc.rect(0, 0, 0, 0);
+ this._normalTextureSize = cc.size(0, 0);
+ ccui.Widget.prototype.ctor.call(this);
+ this.setTouchEnabled(true);
+
+ this._normalLoader = new cc.Sprite.LoadManager();
+ this._clickedLoader = new cc.Sprite.LoadManager();
+ this._disabledLoader = new cc.Sprite.LoadManager();
+
+ if (normalImage) {
+ this.loadTextures(normalImage, selectedImage,disableImage, texType);
+ }
+ },
+
+ _createTitleRendererIfNeeded: function ( ) {
+ if(!this._titleRenderer) {
+ this._titleRenderer = new cc.LabelTTF("");
+ this._titleRenderer.setAnchorPoint(0.5, 0.5);
+ this._titleColor = cc.color.WHITE;
+ this._titleRenderer.setVerticalAlignment(cc.VERTICAL_TEXT_ALIGNMENT_CENTER);
+ this.addProtectedChild(this._titleRenderer, ccui.Button.TITLE_RENDERER_ZORDER, -1);
+ }
+ },
+
+ _initRenderer: function () {
+ this._buttonScale9Renderer = new ccui.Scale9Sprite();
+
+ this._buttonScale9Renderer.setRenderingType(ccui.Scale9Sprite.RenderingType.SIMPLE);
+
+ this.addProtectedChild(this._buttonScale9Renderer, ccui.Button.DISABLED_RENDERER_ZORDER, -1);
+ },
+
+ /**
+ * Sets if button is using scale9 renderer.
+ * @param {Boolean} able true that using scale9 renderer, false otherwise.
+ */
+ setScale9Enabled: function (able) {
+ if (this._scale9Enabled === able)
+ return;
+
+ this._brightStyle = ccui.Widget.BRIGHT_STYLE_NONE;
+ this._scale9Enabled = able;
+
+ if (this._scale9Enabled) {
+ this._buttonScale9Renderer.setRenderingType(ccui.Scale9Sprite.RenderingType.SLICED);
+ } else {
+ this._buttonScale9Renderer.setRenderingType(ccui.Scale9Sprite.RenderingType.SIMPLE);
+ }
+
+ if (this._scale9Enabled) {
+ var ignoreBefore = this._ignoreSize;
+ this.ignoreContentAdaptWithSize(false);
+ this._prevIgnoreSize = ignoreBefore;
+ } else {
+ this.ignoreContentAdaptWithSize(this._prevIgnoreSize);
+ }
+ this.setCapInsets(this._capInsetsNormal);
+
+ this.setBright(this._bright);
+
+ this._normalTextureAdaptDirty = true;
+ },
+
+ /**
+ * Returns button is using scale9 renderer or not.
+ * @returns {Boolean}
+ */
+ isScale9Enabled: function () {
+ return this._scale9Enabled;
+ },
+
+ /**
+ * Sets whether ignore the widget size
+ * @param {Boolean} ignore true that widget will ignore it's size, use texture size, false otherwise. Default value is true.
+ * @override
+ */
+ ignoreContentAdaptWithSize: function (ignore) {
+ if(this._unifySize){
+ this._updateContentSize();
+ return;
+ }
+ if (!this._scale9Enabled || (this._scale9Enabled && !ignore)) {
+ ccui.Widget.prototype.ignoreContentAdaptWithSize.call(this, ignore);
+ this._prevIgnoreSize = ignore;
+ }
+ },
+
+ /**
+ * Returns the renderer size.
+ * @returns {cc.Size}
+ */
+ getVirtualRendererSize: function(){
+ if (this._unifySize)
+ return this._getNormalSize();
+
+ if (!this._normalTextureLoaded ) {
+ if(this._titleRenderer && this._titleRenderer.getString().length > 0) {
+ return this._titleRenderer.getContentSize();
+ }
+ }
+ return cc.size(this._normalTextureSize);
+ },
+
+ /**
+ * Load textures for button.
+ * @param {String} normal normal state of texture's filename.
+ * @param {String} selected selected state of texture's filename.
+ * @param {String} disabled disabled state of texture's filename.
+ * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
+ */
+ loadTextures: function (normal, selected, disabled, texType) {
+ this.loadTextureNormal(normal, texType);
+ this.loadTexturePressed(selected, texType);
+ this.loadTextureDisabled(disabled, texType);
+ },
+
+ _createSpriteFrameWithFile: function (file) {
+ var texture = cc.textureCache.getTextureForKey(file);
+ if (!texture) {
+ texture = cc.textureCache.addImage(file);
+ }
+ if(!texture._textureLoaded) {
+ return texture;
+ }
+
+ var textureSize = texture.getContentSize();
+ var rect = cc.rect(0, 0, textureSize.width, textureSize.height);
+ return new cc.SpriteFrame(texture, rect);
+ },
+
+ _createSpriteFrameWithName: function (name) {
+ var frame = cc.spriteFrameCache.getSpriteFrame(name);
+ if (frame == null) {
+ cc.log("ccui.Scale9Sprite.initWithSpriteFrameName(): can't find the sprite frame by spriteFrameName");
+ return null;
+ }
+
+ return frame;
+ },
+
+ /**
+ * Load normal state texture for button.
+ * @param {String} normal normal state of texture's filename.
+ * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
+ */
+ loadTextureNormal: function (normal, texType) {
+ if (!normal) return;
+
+ texType = texType || ccui.Widget.LOCAL_TEXTURE;
+ this._normalFileName = normal;
+ this._normalTexType = texType;
+
+ var normalSpriteFrame;
+ switch (this._normalTexType){
+ case ccui.Widget.LOCAL_TEXTURE:
+ normalSpriteFrame = this._createSpriteFrameWithFile(normal);
+ break;
+ case ccui.Widget.PLIST_TEXTURE:
+ if (normal[0] === "#") {
+ normal = normal.substr(1, normal.length - 1);
+ }
+ normalSpriteFrame = this._createSpriteFrameWithName(normal);
+ break;
+ default:
+ break;
+ }
+
+ if(!normalSpriteFrame) {
+ return;
+ }
+
+ if(!normalSpriteFrame._textureLoaded) {
+ this._normalLoader.clear();
+ this._normalLoader.once(normalSpriteFrame, function () {
+ this.loadTextureNormal(this._normalFileName, this._normalTexType);
+ }, this);
+ return;
+ }
+
+ this._normalTextureLoaded = normalSpriteFrame._textureLoaded;
+ this._buttonNormalSpriteFrame = normalSpriteFrame;
+ this._buttonScale9Renderer.setSpriteFrame(normalSpriteFrame);
+ if (this._scale9Enabled){
+ this._buttonScale9Renderer.setCapInsets(this._capInsetsNormal);
+ }
+
+ // FIXME: https://github.com/cocos2d/cocos2d-x/issues/12249
+ if(!this._ignoreSize && cc.sizeEqualToSize(this._customSize, cc.size(0, 0))) {
+ this._customSize = this._buttonScale9Renderer.getContentSize();
+ }
+
+ this._normalTextureSize = this._buttonScale9Renderer.getContentSize();
+ this._updateChildrenDisplayedRGBA();
+ if (this._unifySize){
+ if (this._scale9Enabled){
+ this._buttonScale9Renderer.setCapInsets(this._capInsetsNormal);
+ this._updateContentSizeWithTextureSize(this._getNormalSize());
+ }
+ }else {
+ this._updateContentSizeWithTextureSize(this._normalTextureSize);
+ }
+
+ this._normalTextureAdaptDirty = true;
+ this._findLayout();
+ },
+
+ /**
+ * Load selected state texture for button.
+ * @param {String} selected selected state of texture's filename.
+ * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
+ */
+ loadTexturePressed: function (selected, texType) {
+ if (!selected)
+ return;
+ texType = texType || ccui.Widget.LOCAL_TEXTURE;
+ this._clickedFileName = selected;
+ this._pressedTexType = texType;
+
+ var clickedSpriteFrame;
+ switch (this._pressedTexType) {
+ case ccui.Widget.LOCAL_TEXTURE:
+ clickedSpriteFrame = this._createSpriteFrameWithFile(selected);
+ break;
+ case ccui.Widget.PLIST_TEXTURE:
+ if (selected[0] === "#") {
+ selected = selected.substr(1, selected.length - 1);
+ }
+ clickedSpriteFrame = this._createSpriteFrameWithName(selected);
+ break;
+ default:
+ break;
+ }
+
+ if(!clickedSpriteFrame) return;
+
+ if(!clickedSpriteFrame._textureLoaded) {
+ this._clickedLoader.clear();
+ this._clickedLoader.once(clickedSpriteFrame, function () {
+ this.loadTexturePressed(this._clickedFileName, this._pressedTexType);
+ }, this);
+ return;
+ }
+
+ this._buttonClickedSpriteFrame = clickedSpriteFrame;
+ this._updateChildrenDisplayedRGBA();
+
+ this._pressedTextureLoaded = true;
+ },
+
+ /**
+ * Load dark state texture for button.
+ * @param {String} disabled disabled state of texture's filename.
+ * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
+ */
+ loadTextureDisabled: function (disabled, texType) {
+ if (!disabled)
+ return;
+
+ texType = texType || ccui.Widget.LOCAL_TEXTURE;
+ this._disabledFileName = disabled;
+ this._disabledTexType = texType;
+
+ var disabledSpriteframe;
+ switch (this._disabledTexType) {
+ case ccui.Widget.LOCAL_TEXTURE:
+ disabledSpriteframe = this._createSpriteFrameWithFile(disabled);
+ break;
+ case ccui.Widget.PLIST_TEXTURE:
+ if (disabled[0] === "#") {
+ disabled = disabled.substr(1, disabled.length - 1);
+ }
+ disabledSpriteframe = this._createSpriteFrameWithName(disabled);
+ break;
+ default:
+ break;
+ }
+
+ if(!disabledSpriteframe) return;
+
+ if(!disabledSpriteframe._textureLoaded) {
+ this._disabledLoader.clear();
+ this._disabledLoader.once(disabledSpriteframe, function () {
+ this.loadTextureDisabled(this._disabledFileName, this._disabledTexType);
+ }, this);
+ return;
+ }
+
+ this._buttonDisableSpriteFrame = disabledSpriteframe;
+ this._updateChildrenDisplayedRGBA();
+
+ this._disabledTextureLoaded = true;
+ this._findLayout();
+ },
+
+ /**
+ * Sets capinsets for button, if button is using scale9 renderer.
+ * @param {cc.Rect} capInsets
+ */
+ setCapInsets: function (capInsets) {
+ this.setCapInsetsNormalRenderer(capInsets);
+ },
+
+ /**
+ * Sets capinsets for button, if button is using scale9 renderer.
+ * @param {cc.Rect} capInsets
+ */
+ setCapInsetsNormalRenderer: function (capInsets) {
+ if(!capInsets || !this._scale9Enabled)
+ return;
+
+ var x = capInsets.x, y = capInsets.y;
+ var width = capInsets.width, height = capInsets.height;
+ if (this._normalTextureSize.width < width){
+ x = 0;
+ width = 0;
+ }
+ if (this._normalTextureSize.height < height){
+ y = 0;
+ height = 0;
+ }
+
+ var locInsets = this._capInsetsNormal;
+ locInsets.x = x;
+ locInsets.y = y;
+ locInsets.width = width;
+ locInsets.height = height;
+
+ this._capInsetsNormal = locInsets;
+ this._buttonScale9Renderer.setCapInsets(locInsets);
+ },
+
+ /**
+ * Returns normal renderer cap insets.
+ * @returns {cc.Rect}
+ */
+ getCapInsetsNormalRenderer:function(){
+ return cc.rect(this._capInsetsNormal);
+ },
+
+ /**
+ * Sets capinsets for button, if button is using scale9 renderer.
+ * @param {cc.Rect} capInsets
+ */
+ setCapInsetsPressedRenderer: function (capInsets) {
+ this.setCapInsetsNormalRenderer(capInsets);
+ },
+
+ /**
+ * Returns pressed renderer cap insets.
+ * @returns {cc.Rect}
+ */
+ getCapInsetsPressedRenderer: function () {
+ return cc.rect(this._capInsetsNormal);
+ },
+
+ /**
+ * Sets capinsets for button, if button is using scale9 renderer.
+ * @param {cc.Rect} capInsets
+ */
+ setCapInsetsDisabledRenderer: function (capInsets) {
+ this.setCapInsetsNormalRenderer(capInsets);
+ },
+
+ /**
+ * Returns disable renderer cap insets.
+ * @returns {cc.Rect}
+ */
+ getCapInsetsDisabledRenderer: function () {
+ return cc.rect(this._capInsetsNormal);
+ },
+
+ _onPressStateChangedToNormal: function () {
+ this._buttonScale9Renderer.setSpriteFrame(this._buttonNormalSpriteFrame);
+
+ this._buttonScale9Renderer.setState( ccui.Scale9Sprite.state.NORMAL);
+
+ if (this._pressedTextureLoaded) {
+ if (this.pressedActionEnabled){
+ this._buttonScale9Renderer.stopAllActions();
+ this._buttonScale9Renderer.setScale(1.0);
+
+ if(this._titleRenderer) {
+ this._titleRenderer.stopAllActions();
+
+ if (this._unifySize){
+ var zoomTitleAction = cc.scaleTo(ccui.Button.ZOOM_ACTION_TIME_STEP, 1, 1);
+ this._titleRenderer.runAction(zoomTitleAction);
+ }else{
+ this._titleRenderer.setScaleX(1);
+ this._titleRenderer.setScaleY(1);
+ }
+ }
+
+ }
+ } else {
+ this._buttonScale9Renderer.stopAllActions();
+ this._buttonScale9Renderer.setScale(1.0);
+
+ if (this._scale9Enabled) {
+ this._buttonScale9Renderer.setColor(cc.color.WHITE);
+ }
+
+ if(this._titleRenderer) {
+ this._titleRenderer.stopAllActions();
+
+ this._titleRenderer.setScaleX(1);
+ this._titleRenderer.setScaleY(1);
+ }
+ }
+ },
+
+ _onPressStateChangedToPressed: function () {
+ this._buttonScale9Renderer.setState(ccui.Scale9Sprite.state.NORMAL);
+
+ if (this._pressedTextureLoaded) {
+ this._buttonScale9Renderer.setSpriteFrame(this._buttonClickedSpriteFrame);
+
+ if (this.pressedActionEnabled) {
+ this._buttonScale9Renderer.stopAllActions();
+
+ var zoomAction = cc.scaleTo(ccui.Button.ZOOM_ACTION_TIME_STEP,
+ 1.0 + this._zoomScale,
+ 1.0 + this._zoomScale);
+ this._buttonScale9Renderer.runAction(zoomAction);
+
+ if(this._titleRenderer) {
+ this._titleRenderer.stopAllActions();
+ this._titleRenderer.runAction(cc.scaleTo(ccui.Button.ZOOM_ACTION_TIME_STEP,
+ 1 + this._zoomScale,
+ 1 + this._zoomScale));
+ }
+ }
+ } else {
+ this._buttonScale9Renderer.setSpriteFrame(this._buttonClickedSpriteFrame);
+
+ this._buttonScale9Renderer.stopAllActions();
+ this._buttonScale9Renderer.setScale(1.0 + this._zoomScale, 1.0 + this._zoomScale);
+
+ if (this._titleRenderer) {
+ this._titleRenderer.stopAllActions();
+ this._titleRenderer.setScaleX(1 + this._zoomScale);
+ this._titleRenderer.setScaleY(1 + this._zoomScale);
+ }
+ }
+ },
+
+ _onPressStateChangedToDisabled: function () {
+ //if disable resource is null
+ if (!this._disabledTextureLoaded){
+ if (this._normalTextureLoaded) {
+ this._buttonScale9Renderer.setState(ccui.Scale9Sprite.state.GRAY);
+ }
+ }else{
+ this._buttonScale9Renderer.setSpriteFrame(this._buttonDisableSpriteFrame);
+ }
+
+ this._buttonScale9Renderer.setScale(1.0);
+ },
+
+ _updateContentSize: function(){
+ if (this._unifySize){
+ if (this._scale9Enabled)
+ ccui.ProtectedNode.setContentSize(this._customSize);
+ else{
+ var s = this._getNormalSize();
+ ccui.ProtectedNode.setContentSize(s);
+ }
+ this._onSizeChanged();
+ return;
+ }
+
+ if (this._ignoreSize)
+ this.setContentSize(this.getVirtualRendererSize());
+ },
+
+ _onSizeChanged: function () {
+ ccui.Widget.prototype._onSizeChanged.call(this);
+ if(this._titleRenderer) {
+ this._updateTitleLocation();
+ }
+ this._normalTextureAdaptDirty = true;
+ },
+
+ /**
+ * Gets the Virtual Renderer of widget.
+ * @returns {cc.Node}
+ */
+ getVirtualRenderer: function () {
+ return this._buttonScale9Renderer;
+ },
+
+ _normalTextureScaleChangedWithSize: function () {
+ this._buttonScale9Renderer.setContentSize(this._contentSize);
+ this._buttonScale9Renderer.setPosition(this._contentSize.width / 2, this._contentSize.height / 2);
+ },
+
+ _adaptRenderers: function(){
+ if (this._normalTextureAdaptDirty) {
+ this._normalTextureScaleChangedWithSize();
+ this._normalTextureAdaptDirty = false;
+ }
+ },
+
+ _updateTitleLocation: function(){
+ this._titleRenderer.setPosition(this._contentSize.width * 0.5, this._contentSize.height * 0.5);
+ },
+
+ /**
+ * Changes if button can be clicked zoom effect.
+ * @param {Boolean} enabled
+ */
+ setPressedActionEnabled: function (enabled) {
+ this.pressedActionEnabled = enabled;
+ },
+
+ /**
+ * Sets title text to ccui.Button
+ * @param {String} text
+ */
+ setTitleText: function (text) {
+ if(text === this.getTitleText()) return;
+
+ this._createTitleRendererIfNeeded();
+
+ this._titleRenderer.setString(text);
+ if (this._ignoreSize){
+ var s = this.getVirtualRendererSize();
+ this.setContentSize(s);
+ }else{
+ this._titleRenderer._renderCmd._updateTTF();
+ }
+ },
+
+ /**
+ * Returns title text of ccui.Button
+ * @returns {String} text
+ */
+ getTitleText: function () {
+ if(this._titleRenderer) {
+ return this._titleRenderer.getString();
+ }
+ return "";
+ },
+
+ /**
+ * Sets title color to ccui.Button.
+ * @param {cc.Color} color
+ */
+ setTitleColor: function (color) {
+ this._createTitleRendererIfNeeded();
+ this._titleRenderer.setFontFillColor(color);
+ },
+
+ /**
+ * Returns title color of ccui.Button
+ * @returns {cc.Color}
+ */
+ getTitleColor: function () {
+ if (this._titleRenderer) {
+ return this._titleRenderer._getFillStyle();
+ }
+ return cc.color.WHITE;
+ },
+
+ /**
+ * Sets title fontSize to ccui.Button
+ * @param {cc.Size} size
+ */
+ setTitleFontSize: function (size) {
+ this._createTitleRendererIfNeeded();
+
+ this._titleRenderer.setFontSize(size);
+ this._fontSize = size;
+ },
+
+ /**
+ * Returns title fontSize of ccui.Button.
+ * @returns {Number}
+ */
+ getTitleFontSize: function () {
+ if (this._titleRenderer) {
+ return this._titleRenderer.getFontSize();
+ }
+ return this._fontSize;
+ },
+
+ /**
+ * When user pressed the button, the button will zoom to a scale.
+ * The final scale of the button equals (button original scale + _zoomScale)
+ * @since v3.2
+ * @param scale
+ */
+ setZoomScale: function(scale){
+ this._zoomScale = scale;
+ },
+
+ /**
+ * Returns a zoom scale
+ * @since v3.2
+ * @returns {number}
+ */
+ getZoomScale: function(){
+ return this._zoomScale;
+ },
+
+ /**
+ * Returns the normalize of texture size
+ * @since v3.3
+ * @returns {cc.Size}
+ */
+ getNormalTextureSize: function(){
+ return this._normalTextureSize;
+ },
+
+ /**
+ * Sets title fontName to ccui.Button.
+ * @param {String} fontName
+ */
+ setTitleFontName: function (fontName) {
+ this._createTitleRendererIfNeeded();
+
+ this._titleRenderer.setFontName(fontName);
+ this._fontName = fontName;
+ },
+
+ /**
+ * Get the title renderer.
+ * title ttf object.
+ * @returns {cc.LabelTTF}
+ */
+ getTitleRenderer: function(){
+ return this._titleRenderer;
+ },
+
+ /**
+ * Gets title fontName of ccui.Button.
+ * @returns {String}
+ */
+ getTitleFontName: function () {
+ if(this._titleRenderer) {
+ return this._titleRenderer.getFontName();
+ }
+ return this._fontName;
+ },
+
+ _setTitleFont: function (font) {
+ this._titleRenderer.font = font;
+ },
+ _getTitleFont: function () {
+ return this._titleRenderer.font;
+ },
+
+ /**
+ * Returns the "class name" of widget.
+ * @override
+ * @returns {string}
+ */
+ getDescription: function () {
+ return "Button";
+ },
+
+ _createCloneInstance: function () {
+ return new ccui.Button();
+ },
+
+ _copySpecialProperties: function (uiButton) {
+ this._prevIgnoreSize = uiButton._prevIgnoreSize;
+ this._capInsetsNormal = uiButton._capInsetsNormal;
+ this.setScale9Enabled(uiButton._scale9Enabled);
+
+ this.loadTextureNormal(uiButton._normalFileName, uiButton._normalTexType);
+ this.loadTexturePressed(uiButton._clickedFileName, uiButton._pressedTexType);
+ this.loadTextureDisabled(uiButton._disabledFileName, uiButton._disabledTexType);
+
+ if(uiButton._titleRenderer && uiButton._titleRenderer._string) {
+ this.setTitleText(uiButton.getTitleText());
+ this.setTitleFontName(uiButton.getTitleFontName());
+ this.setTitleFontSize(uiButton.getTitleFontSize());
+ this.setTitleColor(uiButton.getTitleColor());
+ }
+ this.setPressedActionEnabled(uiButton.pressedActionEnabled);
+ this.setZoomScale(uiButton._zoomScale);
+ },
+
+ _getNormalSize: function(){
+ var titleSize;
+ if (this._titleRenderer !== null)
+ titleSize = this._titleRenderer.getContentSize();
+
+ var imageSize = this._buttonScale9Renderer.getContentSize();
+ var width = titleSize.width > imageSize.width ? titleSize.width : imageSize.width;
+ var height = titleSize.height > imageSize.height ? titleSize.height : imageSize.height;
+
+ return cc.size(width,height);
+ }
+});
+
+var _p = ccui.Button.prototype;
+
+// Extended properties
+/** @expose */
+_p.titleText;
+cc.defineGetterSetter(_p, "titleText", _p.getTitleText, _p.setTitleText);
+/** @expose */
+_p.titleFont;
+cc.defineGetterSetter(_p, "titleFont", _p._getTitleFont, _p._setTitleFont);
+/** @expose */
+_p.titleFontSize;
+cc.defineGetterSetter(_p, "titleFontSize", _p.getTitleFontSize, _p.setTitleFontSize);
+/** @expose */
+_p.titleFontName;
+cc.defineGetterSetter(_p, "titleFontName", _p.getTitleFontName, _p.setTitleFontName);
+/** @expose */
+_p.titleColor;
+cc.defineGetterSetter(_p, "titleColor", _p.getTitleColor, _p.setTitleColor);
+
+_p = null;
+
+/**
+ * allocates and initializes a UIButton.
+ * @deprecated since v3.0, please use new ccui.Button() instead.
+ * @param {string} [normalImage] normal state texture name
+ * @param {string} [selectedImage] selected state texture name
+ * @param {string} [disableImage] disabled state texture name
+ * @param {string} [texType]
+ * @return {ccui.Button}
+ */
+ccui.Button.create = function (normalImage, selectedImage, disableImage, texType) {
+ return new ccui.Button(normalImage, selectedImage, disableImage, texType);
+};
+
+// Constants
+/**
+ * The normal renderer's zOrder value of ccui.Button.
+ * @constant
+ * @type {number}
+ */
+ccui.Button.NORMAL_RENDERER_ZORDER = -2;
+/**
+ * The pressed renderer's zOrder value ccui.Button.
+ * @constant
+ * @type {number}
+ */
+ccui.Button.PRESSED_RENDERER_ZORDER = -2;
+/**
+ * The disabled renderer's zOrder value of ccui.Button.
+ * @constant
+ * @type {number}
+ */
+ccui.Button.DISABLED_RENDERER_ZORDER = -2;
+/**
+ * The title renderer's zOrder value of ccui.Button.
+ * @constant
+ * @type {number}
+ */
+ccui.Button.TITLE_RENDERER_ZORDER = -1;
+
+/**
+ * the zoom action time step of ccui.Button
+ * @constant
+ * @type {number}
+ */
+ccui.Button.ZOOM_ACTION_TIME_STEP = 0.05;
+
+/**
+ * @ignore
+ */
+ccui.Button.SYSTEM = 0;
+ccui.Button.TTF = 1;
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UICheckBox.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UICheckBox.js
new file mode 100644
index 0000000..d76b4d5
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UICheckBox.js
@@ -0,0 +1,722 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The CheckBox control of Cocos UI.
+ * @class
+ * @extends ccui.Widget
+ *
+ * @property {Boolean} selected - Indicate whether the check box has been selected
+ */
+ccui.CheckBox = ccui.Widget.extend(/** @lends ccui.CheckBox# */{
+ _backGroundBoxRenderer: null,
+ _backGroundSelectedBoxRenderer: null,
+ _frontCrossRenderer: null,
+ _backGroundBoxDisabledRenderer: null,
+ _frontCrossDisabledRenderer: null,
+
+ _isSelected: true,
+
+ _checkBoxEventListener: null,
+ _checkBoxEventSelector:null,
+
+ _backGroundTexType: ccui.Widget.LOCAL_TEXTURE,
+ _backGroundSelectedTexType: ccui.Widget.LOCAL_TEXTURE,
+ _frontCrossTexType: ccui.Widget.LOCAL_TEXTURE,
+ _backGroundDisabledTexType: ccui.Widget.LOCAL_TEXTURE,
+ _frontCrossDisabledTexType: ccui.Widget.LOCAL_TEXTURE,
+
+ _backGroundFileName: "",
+ _backGroundSelectedFileName: "",
+ _frontCrossFileName: "",
+ _backGroundDisabledFileName: "",
+ _frontCrossDisabledFileName: "",
+ _className: "CheckBox",
+
+ _zoomScale: 0.1,
+ _backgroundTextureScaleX: 0.1,
+ _backgroundTextureScaleY: 0.1,
+
+ _backGroundBoxRendererAdaptDirty:true,
+ _backGroundSelectedBoxRendererAdaptDirty:true,
+ _frontCrossRendererAdaptDirty: true,
+ _backGroundBoxDisabledRendererAdaptDirty: true,
+ _frontCrossDisabledRendererAdaptDirty: true,
+
+ /**
+ * allocates and initializes a UICheckBox.
+ * Constructor of ccui.CheckBox, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {String} backGround
+ * @param {String} backGroundSelected
+ * @param {String} cross
+ * @param {String} backGroundDisabled
+ * @param {String} frontCrossDisabled
+ * @param {Number} [texType=ccui.Widget.LOCAL_TEXTURE]
+ * @example
+ * // example
+ * var uiCheckBox = new ccui.CheckBox();
+ */
+ ctor: function (backGround, backGroundSelected,cross,backGroundDisabled,frontCrossDisabled,texType) {
+ ccui.Widget.prototype.ctor.call(this);
+ this.setTouchEnabled(true);
+ var strNum = 0;
+ for(var i=0; i
+ * Constructor of ccui.LoadingBar, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {string} textureName
+ * @param {Number} percentage
+ * @example
+ * // example
+ * var uiLoadingBar = new ccui.LoadingBar;
+ */
+ ctor: function (textureName, percentage) {
+ this._direction = ccui.LoadingBar.TYPE_LEFT;
+ this._barRendererTextureSize = cc.size(0, 0);
+ this._capInsets = cc.rect(0, 0, 0, 0);
+ ccui.Widget.prototype.ctor.call(this);
+
+ if (textureName !== undefined)
+ this.loadTexture(textureName);
+ if (percentage !== undefined)
+ this.setPercent(percentage);
+ },
+
+ _initRenderer: function () {
+ //todo use Scale9Sprite
+ this._barRenderer = new cc.Sprite();
+ this.addProtectedChild(this._barRenderer, ccui.LoadingBar.RENDERER_ZORDER, -1);
+ this._barRenderer.setAnchorPoint(0.0, 0.5);
+ },
+
+ /**
+ * Changes the progress direction of LoadingBar.
+ * LoadingBarTypeLeft means progress left to right, LoadingBarTypeRight otherwise.
+ * @param {ccui.LoadingBar.TYPE_LEFT | ccui.LoadingBar.TYPE_RIGHT} dir
+ */
+ setDirection: function (dir) {
+ if (this._direction === dir)
+ return;
+ this._direction = dir;
+ switch (this._direction) {
+ case ccui.LoadingBar.TYPE_LEFT:
+ this._barRenderer.setAnchorPoint(0, 0.5);
+ this._barRenderer.setPosition(0, this._contentSize.height * 0.5);
+ if (!this._scale9Enabled)
+ this._barRenderer.setFlippedX(false);
+
+ break;
+ case ccui.LoadingBar.TYPE_RIGHT:
+ this._barRenderer.setAnchorPoint(1, 0.5);
+ this._barRenderer.setPosition(this._totalLength, this._contentSize.height * 0.5);
+ if (!this._scale9Enabled)
+ this._barRenderer.setFlippedX(true);
+
+ break;
+ }
+ },
+
+ /**
+ * Returns the progress direction of LoadingBar.
+ * LoadingBarTypeLeft means progress left to right, LoadingBarTypeRight otherwise.
+ * @returns {ccui.LoadingBar.TYPE_LEFT | ccui.LoadingBar.TYPE_RIGHT}
+ */
+ getDirection: function () {
+ return this._direction;
+ },
+
+ /**
+ * Loads texture for LoadingBar.
+ * @param {String} texture
+ * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
+ */
+ loadTexture: function (texture, texType) {
+ if (!texture)
+ return;
+ texType = texType || ccui.Widget.LOCAL_TEXTURE;
+ this._renderBarTexType = texType;
+ this._textureFile = texture;
+ var barRenderer = this._barRenderer;
+
+ var self = this;
+ if (!barRenderer._textureLoaded) {
+ barRenderer.addEventListener("load", function () {
+ self.loadTexture(self._textureFile, self._renderBarTexType);
+ self._setPercent(self._percent);
+ });
+ }
+
+ switch (this._renderBarTexType) {
+ case ccui.Widget.LOCAL_TEXTURE:
+ barRenderer.initWithFile(texture);
+ break;
+ case ccui.Widget.PLIST_TEXTURE:
+ barRenderer.initWithSpriteFrameName(texture);
+ break;
+ default:
+ break;
+ }
+
+ var bz = barRenderer.getContentSize();
+ this._barRendererTextureSize.width = bz.width;
+ this._barRendererTextureSize.height = bz.height;
+
+ switch (this._direction) {
+ case ccui.LoadingBar.TYPE_LEFT:
+ barRenderer.setAnchorPoint(0, 0.5);
+ if (!this._scale9Enabled)
+ barRenderer.setFlippedX(false);
+ break;
+ case ccui.LoadingBar.TYPE_RIGHT:
+ barRenderer.setAnchorPoint(1, 0.5);
+ if (!this._scale9Enabled)
+ barRenderer.setFlippedX(true);
+ break;
+ }
+ if (this._scale9Enabled)
+ barRenderer.setCapInsets(this._capInsets);
+
+ this._updateChildrenDisplayedRGBA();
+ this._barRendererScaleChangedWithSize();
+ this._updateContentSizeWithTextureSize(this._barRendererTextureSize);
+ this._barRendererAdaptDirty = true;
+ this._findLayout();
+ },
+
+ /**
+ * Sets if LoadingBar is using scale9 renderer.
+ * @param {Boolean} enabled
+ */
+ setScale9Enabled: function (enabled) {
+ //todo use setScale9Enabled
+ if (this._scale9Enabled === enabled)
+ return;
+ this._scale9Enabled = enabled;
+ this.removeProtectedChild(this._barRenderer);
+
+ this._barRenderer = this._scale9Enabled ? new ccui.Scale9Sprite() : new cc.Sprite();
+
+ this.loadTexture(this._textureFile, this._renderBarTexType);
+ this.addProtectedChild(this._barRenderer, ccui.LoadingBar.RENDERER_ZORDER, -1);
+ if (this._scale9Enabled) {
+ var ignoreBefore = this._ignoreSize;
+ this.ignoreContentAdaptWithSize(false);
+ this._prevIgnoreSize = ignoreBefore;
+ } else
+ this.ignoreContentAdaptWithSize(this._prevIgnoreSize);
+ this.setCapInsets(this._capInsets);
+ this.setPercent(this._percent);
+ this._barRendererAdaptDirty = true;
+ },
+
+ /**
+ * Returns LoadingBar is using scale9 renderer or not..
+ * @returns {Boolean}
+ */
+ isScale9Enabled: function () {
+ return this._scale9Enabled;
+ },
+
+ /**
+ * Sets capinsets for LoadingBar, if LoadingBar is using scale9 renderer.
+ * @param {cc.Rect} capInsets
+ */
+ setCapInsets: function (capInsets) {
+ if (!capInsets)
+ return;
+ var locInsets = this._capInsets;
+ locInsets.x = capInsets.x;
+ locInsets.y = capInsets.y;
+ locInsets.width = capInsets.width;
+ locInsets.height = capInsets.height;
+
+ if (this._scale9Enabled)
+ this._barRenderer.setCapInsets(capInsets);
+ },
+
+ /**
+ * Returns cap insets for loadingBar.
+ * @returns {cc.Rect}
+ */
+ getCapInsets: function () {
+ return cc.rect(this._capInsets);
+ },
+
+ /**
+ * The current progress of loadingBar
+ * @param {number} percent percent value from 1 to 100.
+ */
+ setPercent: function (percent) {
+ if (percent > 100)
+ percent = 100;
+ if (percent < 0)
+ percent = 0;
+ if (percent === this._percent)
+ return;
+ this._percent = percent;
+ this._setPercent(percent);
+ },
+
+ _setPercent: function () {
+ var res, rect, spriteRenderer, spriteTextureRect;
+
+ if (this._totalLength <= 0)
+ return;
+ res = this._percent / 100.0;
+
+ if (this._scale9Enabled)
+ this._setScale9Scale();
+ else {
+ spriteRenderer = this._barRenderer;
+ spriteTextureRect = this._barRendererTextureSize;
+ rect = spriteRenderer.getTextureRect();
+ rect.width = spriteTextureRect.width * res;
+ spriteRenderer.setTextureRect(
+ cc.rect(
+ rect.x,
+ rect.y,
+ spriteTextureRect.width * res,
+ spriteTextureRect.height
+ ),
+ spriteRenderer._rectRotated
+ );
+ }
+ },
+
+ /**
+ * Sets the contentSize of ccui.LoadingBar
+ * @override
+ * @param {Number|cc.Size} contentSize
+ * @param {Number} [height]
+ */
+ setContentSize: function (contentSize, height) {
+ ccui.Widget.prototype.setContentSize.call(this, contentSize, height);
+ this._totalLength = (height === undefined) ? contentSize.width : contentSize;
+ },
+
+ /**
+ * Returns the progress direction of LoadingBar.
+ * @returns {number} percent value from 1 to 100.
+ */
+ getPercent: function () {
+ return this._percent;
+ },
+
+ _onSizeChanged: function () {
+ ccui.Widget.prototype._onSizeChanged.call(this);
+ this._barRendererAdaptDirty = true;
+ },
+
+ _adaptRenderers: function () {
+ if (this._barRendererAdaptDirty) {
+ this._barRendererScaleChangedWithSize();
+ this._barRendererAdaptDirty = false;
+ }
+ },
+
+ /**
+ * Ignore the LoadingBar's custom size, if ignore is true that LoadingBar will ignore it's custom size, use renderer's content size, false otherwise.
+ * @override
+ * @param {Boolean}ignore
+ */
+ ignoreContentAdaptWithSize: function (ignore) {
+ if (!this._scale9Enabled || (this._scale9Enabled && !ignore)) {
+ ccui.Widget.prototype.ignoreContentAdaptWithSize.call(this, ignore);
+ this._prevIgnoreSize = ignore;
+ }
+ },
+
+ /**
+ * Returns the texture size of renderer.
+ * @returns {cc.Size|*}
+ */
+ getVirtualRendererSize: function () {
+ return cc.size(this._barRendererTextureSize);
+ },
+
+ /**
+ * Returns the renderer of ccui.LoadingBar
+ * @override
+ * @returns {cc.Node}
+ */
+ getVirtualRenderer: function () {
+ return this._barRenderer;
+ },
+
+ _barRendererScaleChangedWithSize: function () {
+ var locBarRender = this._barRenderer, locContentSize = this._contentSize;
+ if(this._unifySize){
+ this._totalLength = this._contentSize.width;
+ this.setPercent(this._percent);
+ }else if (this._ignoreSize) {
+ if (!this._scale9Enabled) {
+ this._totalLength = this._barRendererTextureSize.width;
+ locBarRender.setScale(1.0);
+ }
+ } else {
+ this._totalLength = locContentSize.width;
+ if (this._scale9Enabled) {
+ this._setScale9Scale();
+ locBarRender.setScale(1.0);
+ } else {
+ var textureSize = this._barRendererTextureSize;
+ if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
+ locBarRender.setScale(1.0);
+ return;
+ }
+ var scaleX = locContentSize.width / textureSize.width;
+ var scaleY = locContentSize.height / textureSize.height;
+ locBarRender.setScaleX(scaleX);
+ locBarRender.setScaleY(scaleY);
+ }
+ }
+ switch (this._direction) {
+ case ccui.LoadingBar.TYPE_LEFT:
+ locBarRender.setPosition(0, locContentSize.height * 0.5);
+ break;
+ case ccui.LoadingBar.TYPE_RIGHT:
+ locBarRender.setPosition(this._totalLength, locContentSize.height * 0.5);
+ break;
+ default:
+ break;
+ }
+ },
+
+ _setScale9Scale: function () {
+ var width = (this._percent) / 100 * this._totalLength;
+ this._barRenderer.setPreferredSize(cc.size(width, this._contentSize.height));
+ },
+
+ /**
+ * Returns the "class name" of widget.
+ * @returns {string}
+ */
+ getDescription: function () {
+ return "LoadingBar";
+ },
+
+ _createCloneInstance: function () {
+ return new ccui.LoadingBar();
+ },
+
+ _copySpecialProperties: function (loadingBar) {
+ if (loadingBar instanceof ccui.LoadingBar) {
+ this._prevIgnoreSize = loadingBar._prevIgnoreSize;
+ this.setScale9Enabled(loadingBar._scale9Enabled);
+ this.loadTexture(loadingBar._textureFile, loadingBar._renderBarTexType);
+ this.setCapInsets(loadingBar._capInsets);
+ this.setPercent(loadingBar._percent);
+ this.setDirection(loadingBar._direction);
+ }
+ }
+});
+
+var _p = ccui.LoadingBar.prototype;
+
+// Extended properties
+/** @expose */
+_p.direction;
+cc.defineGetterSetter(_p, "direction", _p.getDirection, _p.setDirection);
+/** @expose */
+_p.percent;
+cc.defineGetterSetter(_p, "percent", _p.getPercent, _p.setPercent);
+
+_p = null;
+
+/**
+ * Allocates and initializes a UILoadingBar.
+ * @deprecated since v3.0, please use new ccui.LoadingBar() instead.
+ * @param {string} textureName
+ * @param {Number} percentage
+ * @return {ccui.LoadingBar}
+ */
+ccui.LoadingBar.create = function (textureName, percentage) {
+ return new ccui.LoadingBar(textureName, percentage);
+};
+
+// Constants
+//loadingBar Type
+
+/**
+ * The left direction of ccui.LoadingBar.
+ * @constant
+ * @type {number}
+ */
+ccui.LoadingBar.TYPE_LEFT = 0;
+/**
+ * The right direction of ccui.LoadingBar.
+ * @constant
+ * @type {number}
+ */
+ccui.LoadingBar.TYPE_RIGHT = 1;
+
+/**
+ * The zOrder value of ccui.LoadingBar's renderer.
+ * @constant
+ * @type {number}
+ */
+ccui.LoadingBar.RENDERER_ZORDER = -1;
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIRichText.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIRichText.js
new file mode 100644
index 0000000..c057256
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIRichText.js
@@ -0,0 +1,681 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * ccui.RichElement is the base class of RichElementText, RichElementImage etc. It has type, tag, color and opacity attributes.
+ * @class
+ * @extends ccui.Class
+ */
+ccui.RichElement = ccui.Class.extend(/** @lends ccui.RichElement# */{
+ _type: 0,
+ _tag: 0,
+ _color: null,
+ _opacity: 0,
+ /**
+ * Constructor of ccui.RichElement
+ */
+ ctor: function (tag, color, opacity) {
+ this._type = 0;
+ this._tag = tag || 0;
+ this._color = cc.color(255, 255, 255, 255);
+ if (color) {
+ this._color.r = color.r;
+ this._color.g = color.g;
+ this._color.b = color.b;
+ }
+ this._opacity = opacity || 0;
+ if (opacity === undefined) {
+ this._color.a = color.a;
+ }
+ else {
+ this._color.a = opacity;
+ }
+ }
+});
+
+/**
+ * The text element for RichText, it has text, fontName, fontSize attributes.
+ * @class
+ * @extends ccui.RichElement
+ */
+ccui.RichElementText = ccui.RichElement.extend(/** @lends ccui.RichElementText# */{
+ _text: "",
+ _fontName: "",
+ _fontSize: 0,
+ /** @type cc.FontDefinition */
+ _fontDefinition: null,
+ /**
+ * Usage Example using FontDefinition:
+ *
+ * var rtEl = new ccui.RichElementText("tag", new cc.FontDefinition({
+ * fillStyle: cc.color.BLACK,
+ * fontName: "Arial",
+ * fontSize: 12,
+ * fontWeight: "bold",
+ * fontStyle: "normal",
+ * lineHeight: 14
+ * }), 255, "Some Text");
+ *
+ * Constructor of ccui.RichElementText
+ * @param {Number} tag
+ * @param {cc.Color|cc.FontDefinition} colorOrFontDef
+ * @param {Number} opacity
+ * @param {String} text
+ * @param {String} fontName
+ * @param {Number} fontSize
+ */
+ ctor: function (tag, colorOrFontDef, opacity, text, fontName, fontSize) {
+ var color = colorOrFontDef;
+ if (colorOrFontDef && colorOrFontDef instanceof cc.FontDefinition) {
+ color = colorOrFontDef.fillStyle;
+ fontName = colorOrFontDef.fontName;
+ fontSize = colorOrFontDef.fontSize;
+ this._fontDefinition = colorOrFontDef;
+ }
+ ccui.RichElement.prototype.ctor.call(this, tag, color, opacity);
+ this._type = ccui.RichElement.TEXT;
+ this._text = text;
+ this._fontName = fontName;
+ this._fontSize = fontSize;
+ }
+});
+
+/**
+ * Create a richElementText
+ * @deprecated since v3.0, please use new ccui.RichElementText() instead.
+ * @param {Number} tag
+ * @param {cc.Color} color
+ * @param {Number} opacity
+ * @param {String} text
+ * @param {String} fontName
+ * @param {Number} fontSize
+ * @returns {ccui.RichElementText}
+ */
+ccui.RichElementText.create = function (tag, color, opacity, text, fontName, fontSize) {
+ return new ccui.RichElementText(tag, color, opacity, text, fontName, fontSize);
+};
+
+/**
+ * The image element for RichText, it has filePath, textureRect, textureType attributes.
+ * @class
+ * @extends ccui.RichElement
+ */
+ccui.RichElementImage = ccui.RichElement.extend(/** @lends ccui.RichElementImage# */{
+ _filePath: "",
+ _textureRect: null,
+ _textureType: 0,
+
+ /**
+ * Constructor of ccui.RichElementImage
+ * @param {Number} tag
+ * @param {cc.Color} color
+ * @param {Number} opacity
+ * @param {String} filePath
+ */
+ ctor: function (tag, color, opacity, filePath) {
+ ccui.RichElement.prototype.ctor.call(this, tag, color, opacity);
+ this._type = ccui.RichElement.IMAGE;
+ this._filePath = filePath || "";
+ this._textureRect = cc.rect(0, 0, 0, 0);
+ this._textureType = 0;
+ }
+});
+
+/**
+ * Create a richElementImage
+ * @deprecated since v3.0, please use new ccui.RichElementImage() instead.
+ * @param {Number} tag
+ * @param {cc.Color} color
+ * @param {Number} opacity
+ * @param {String} filePath
+ * @returns {ccui.RichElementImage}
+ */
+ccui.RichElementImage.create = function (tag, color, opacity, filePath) {
+ return new ccui.RichElementImage(tag, color, opacity, filePath);
+};
+
+/**
+ * The custom node element for RichText.
+ * @class
+ * @extends ccui.RichElement
+ */
+ccui.RichElementCustomNode = ccui.RichElement.extend(/** @lends ccui.RichElementCustomNode# */{
+ _customNode: null,
+
+ /**
+ * Constructor of ccui.RichElementCustomNode
+ * @param {Number} tag
+ * @param {cc.Color} color
+ * @param {Number} opacity
+ * @param {cc.Node} customNode
+ */
+ ctor: function (tag, color, opacity, customNode) {
+ ccui.RichElement.prototype.ctor.call(this, tag, color, opacity);
+ this._type = ccui.RichElement.CUSTOM;
+ this._customNode = customNode || null;
+ }
+});
+
+/**
+ * Create a richElementCustomNode
+ * @deprecated since v3.0, please use new ccui.RichElementCustomNode() instead.
+ * @param {Number} tag
+ * @param {Number} color
+ * @param {Number} opacity
+ * @param {cc.Node} customNode
+ * @returns {ccui.RichElementCustomNode}
+ */
+ccui.RichElementCustomNode.create = function (tag, color, opacity, customNode) {
+ return new ccui.RichElementCustomNode(tag, color, opacity, customNode);
+};
+
+/**
+ * The rich text control of Cocos UI. It receives text, image, and custom node as its children to display.
+ * @class
+ * @extends ccui.Widget
+ */
+ccui.RichText = ccui.Widget.extend(/** @lends ccui.RichText# */{
+ _formatTextDirty: false,
+ _richElements: null,
+ _elementRenders: null,
+ _leftSpaceWidth: 0,
+ _verticalSpace: 0,
+ _elementRenderersContainer: null,
+ _lineBreakOnSpace: false,
+ _textHorizontalAlignment: null,
+ _textVerticalAlignment: null,
+
+ /**
+ * create a rich text
+ * Constructor of ccui.RichText. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @example
+ * var uiRichText = new ccui.RichTex();
+ */
+ ctor: function () {
+ ccui.Widget.prototype.ctor.call(this);
+ this._formatTextDirty = false;
+ this._richElements = [];
+ this._elementRenders = [];
+ this._leftSpaceWidth = 0;
+ this._verticalSpace = 0;
+ this._textHorizontalAlignment = cc.TEXT_ALIGNMENT_LEFT;
+ this._textVerticalAlignment = cc.VERTICAL_TEXT_ALIGNMENT_TOP;
+ },
+
+ _initRenderer: function () {
+ this._elementRenderersContainer = new cc.Node();
+ this._elementRenderersContainer.setAnchorPoint(0.5, 0.5);
+ this.addProtectedChild(this._elementRenderersContainer, 0, -1);
+ },
+
+ /**
+ * Insert a element
+ * @param {ccui.RichElement} element
+ * @param {Number} index
+ */
+ insertElement: function (element, index) {
+ this._richElements.splice(index, 0, element);
+ this._formatTextDirty = true;
+ },
+
+ /**
+ * Push a element
+ * @param {ccui.RichElement} element
+ */
+ pushBackElement: function (element) {
+ this._richElements.push(element);
+ this._formatTextDirty = true;
+ },
+
+ /**
+ * Remove element
+ * @param {ccui.RichElement} element
+ */
+ removeElement: function (element) {
+ if (cc.isNumber(element))
+ this._richElements.splice(element, 1);
+ else
+ cc.arrayRemoveObject(this._richElements, element);
+ this._formatTextDirty = true;
+ },
+
+ /**
+ * Formats the richText's content.
+ */
+ formatText: function () {
+ if (this._formatTextDirty) {
+ this._elementRenderersContainer.removeAllChildren();
+ this._elementRenders.length = 0;
+ var i, element, locRichElements = this._richElements;
+ if (this._ignoreSize) {
+ this._addNewLine();
+ for (i = 0; i < locRichElements.length; i++) {
+ element = locRichElements[i];
+ var elementRenderer = null;
+ switch (element._type) {
+ case ccui.RichElement.TEXT:
+ if (element._fontDefinition)
+ elementRenderer = new cc.LabelTTF(element._text, element._fontDefinition);
+ else //todo: There may be ambiguous
+ elementRenderer = new cc.LabelTTF(element._text, element._fontName, element._fontSize);
+ break;
+ case ccui.RichElement.IMAGE:
+ elementRenderer = new cc.Sprite(element._filePath);
+ break;
+ case ccui.RichElement.CUSTOM:
+ elementRenderer = element._customNode;
+ break;
+ default:
+ break;
+ }
+ elementRenderer.setColor(element._color);
+ elementRenderer.setOpacity(element._color.a);
+ this._pushToContainer(elementRenderer);
+ }
+ } else {
+ this._addNewLine();
+ for (i = 0; i < locRichElements.length; i++) {
+ element = locRichElements[i];
+ switch (element._type) {
+ case ccui.RichElement.TEXT:
+ if (element._fontDefinition)
+ this._handleTextRenderer(element._text, element._fontDefinition, element._fontDefinition.fontSize, element._fontDefinition.fillStyle);
+ else
+ this._handleTextRenderer(element._text, element._fontName, element._fontSize, element._color);
+ break;
+ case ccui.RichElement.IMAGE:
+ this._handleImageRenderer(element._filePath, element._color, element._color.a);
+ break;
+ case ccui.RichElement.CUSTOM:
+ this._handleCustomRenderer(element._customNode);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ this.formatRenderers();
+ this._formatTextDirty = false;
+ }
+ },
+ /**
+ * Prepare the child LabelTTF based on line breaking
+ * @param {String} text
+ * @param {String|cc.FontDefinition} fontNameOrFontDef
+ * @param {Number} fontSize
+ * @param {cc.Color} color
+ * @private
+ */
+ _handleTextRenderer: function (text, fontNameOrFontDef, fontSize, color) {
+ if (text === "")
+ return;
+
+ if (text === "\n") { //Force Line Breaking
+ this._addNewLine();
+ return;
+ }
+
+ var textRenderer = fontNameOrFontDef instanceof cc.FontDefinition ? new cc.LabelTTF(text, fontNameOrFontDef) : new cc.LabelTTF(text, fontNameOrFontDef, fontSize);
+ var textRendererWidth = textRenderer.getContentSize().width;
+ this._leftSpaceWidth -= textRendererWidth;
+ if (this._leftSpaceWidth < 0) {
+ var overstepPercent = (-this._leftSpaceWidth) / textRendererWidth;
+ var curText = text;
+ var stringLength = curText.length;
+ var leftLength = stringLength * (1 - overstepPercent);
+ var leftWords = curText.substr(0, leftLength);
+ var cutWords = curText.substr(leftLength, curText.length - 1);
+ var validLeftLength = leftLength > 0;
+
+ if (this._lineBreakOnSpace) {
+ var lastSpaceIndex = leftWords.lastIndexOf(' ');
+ leftLength = lastSpaceIndex === -1 ? leftLength : lastSpaceIndex + 1;
+ cutWords = curText.substr(leftLength, curText.length - 1);
+ validLeftLength = leftLength > 0 && cutWords !== " ";
+ }
+
+ if (validLeftLength) {
+ var leftRenderer = null;
+ if (fontNameOrFontDef instanceof cc.FontDefinition) {
+ leftRenderer = new cc.LabelTTF(leftWords.substr(0, leftLength), fontNameOrFontDef);
+ leftRenderer.setOpacity(fontNameOrFontDef.fillStyle.a); //TODO: Verify that might not be needed...
+ } else {
+ leftRenderer = new cc.LabelTTF(leftWords.substr(0, leftLength), fontNameOrFontDef, fontSize);
+ leftRenderer.setColor(color);
+ leftRenderer.setOpacity(color.a);
+ }
+ this._pushToContainer(leftRenderer);
+ }
+
+ this._addNewLine();
+ this._handleTextRenderer(cutWords, fontNameOrFontDef, fontSize, color);
+ } else {
+ if (fontNameOrFontDef instanceof cc.FontDefinition) {
+ textRenderer.setOpacity(fontNameOrFontDef.fillStyle.a); //TODO: Verify that might not be needed...
+ } else {
+ textRenderer.setColor(color);
+ textRenderer.setOpacity(color.a);
+ }
+ this._pushToContainer(textRenderer);
+ }
+ },
+
+ _handleImageRenderer: function (filePath, color, opacity) {
+ var imageRenderer = new cc.Sprite(filePath);
+ this._handleCustomRenderer(imageRenderer);
+ },
+
+ _handleCustomRenderer: function (renderer) {
+ var imgSize = renderer.getContentSize();
+ this._leftSpaceWidth -= imgSize.width;
+ if (this._leftSpaceWidth < 0) {
+ this._addNewLine();
+ this._pushToContainer(renderer);
+ this._leftSpaceWidth -= imgSize.width;
+ } else
+ this._pushToContainer(renderer);
+ },
+
+ _addNewLine: function () {
+ this._leftSpaceWidth = this._customSize.width;
+ this._elementRenders.push([]);
+ },
+
+ /**
+ * Formats richText's renderer.
+ */
+ formatRenderers: function () {
+ var newContentSizeHeight = 0, locRenderersContainer = this._elementRenderersContainer;
+ var locElementRenders = this._elementRenders;
+ var i, j, row, nextPosX, l;
+ var lineHeight, offsetX;
+ if (this._ignoreSize) {
+ var newContentSizeWidth = 0;
+ row = locElementRenders[0];
+ nextPosX = 0;
+
+ for (j = 0; j < row.length; j++) {
+ l = row[j];
+ l.setAnchorPoint(cc.p(0, 0));
+ l.setPosition(nextPosX, 0);
+ locRenderersContainer.addChild(l, 1, j);
+
+ lineHeight = l.getLineHeight ? l.getLineHeight() : newContentSizeHeight;
+
+ var iSize = l.getContentSize();
+ newContentSizeWidth += iSize.width;
+ newContentSizeHeight = Math.max(Math.min(newContentSizeHeight, lineHeight), iSize.height);
+ nextPosX += iSize.width;
+ }
+
+ //Text flow horizontal alignment:
+ if (this._textHorizontalAlignment !== cc.TEXT_ALIGNMENT_LEFT) {
+ offsetX = 0;
+ if (this._textHorizontalAlignment === cc.TEXT_ALIGNMENT_RIGHT)
+ offsetX = this._contentSize.width - nextPosX;
+ else if (this._textHorizontalAlignment === cc.TEXT_ALIGNMENT_CENTER)
+ offsetX = (this._contentSize.width - nextPosX) / 2;
+
+ for (j = 0; j < row.length; j++)
+ row[j].x += offsetX;
+ }
+
+ locRenderersContainer.setContentSize(newContentSizeWidth, newContentSizeHeight);
+ } else {
+ var maxHeights = [];
+ for (i = 0; i < locElementRenders.length; i++) {
+ row = locElementRenders[i];
+ var maxHeight = 0;
+ for (j = 0; j < row.length; j++) {
+ l = row[j];
+ lineHeight = l.getLineHeight ? l.getLineHeight() : l.getContentSize().height;
+ maxHeight = Math.max(Math.min(l.getContentSize().height, lineHeight), maxHeight);
+ }
+ maxHeights[i] = maxHeight;
+ newContentSizeHeight += maxHeights[i];
+ }
+
+ var nextPosY = this._customSize.height;
+
+ for (i = 0; i < locElementRenders.length; i++) {
+ row = locElementRenders[i];
+ nextPosX = 0;
+ nextPosY -= (maxHeights[i] + this._verticalSpace);
+
+ for (j = 0; j < row.length; j++) {
+ l = row[j];
+ l.setAnchorPoint(cc.p(0, 0));
+ l.setPosition(cc.p(nextPosX, nextPosY));
+ locRenderersContainer.addChild(l, 1);
+ nextPosX += l.getContentSize().width;
+ }
+ //Text flow alignment(s)
+ if (this._textHorizontalAlignment !== cc.TEXT_ALIGNMENT_LEFT || this._textVerticalAlignment !== cc.VERTICAL_TEXT_ALIGNMENT_TOP) {
+ offsetX = 0;
+ if (this._textHorizontalAlignment === cc.TEXT_ALIGNMENT_RIGHT)
+ offsetX = this._contentSize.width - nextPosX;
+ else if (this._textHorizontalAlignment === cc.TEXT_ALIGNMENT_CENTER)
+ offsetX = (this._contentSize.width - nextPosX) / 2;
+
+ var offsetY = 0;
+ if (this._textVerticalAlignment === cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM)
+ offsetY = this._customSize.height - newContentSizeHeight;
+ else if (this._textVerticalAlignment === cc.VERTICAL_TEXT_ALIGNMENT_CENTER)
+ offsetY = (this._customSize.height - newContentSizeHeight) / 2;
+
+ for (j = 0; j < row.length; j++) {
+ l = row[j];
+ l.x += offsetX;
+ l.y -= offsetY;
+ }
+ }
+ }
+
+ locRenderersContainer.setContentSize(this._contentSize);
+ }
+
+ var length = locElementRenders.length;
+ for (i = 0; i < length; i++) {
+ locElementRenders[i].length = 0;
+ }
+ this._elementRenders.length = 0;
+
+ this.setContentSize(this._ignoreSize ? this.getVirtualRendererSize() : this._customSize);
+ this._updateContentSizeWithTextureSize(this._contentSize);
+
+ locRenderersContainer.setPosition(this._contentSize.width * 0.5, this._contentSize.height * 0.5);
+ },
+
+ _pushToContainer: function (renderer) {
+ if (this._elementRenders.length <= 0)
+ return;
+ this._elementRenders[this._elementRenders.length - 1].push(renderer);
+ },
+
+ _adaptRenderers: function () {
+ this.formatText();
+ },
+
+ /**
+ * Sets vertical space
+ * @param {Number} space
+ */
+ setVerticalSpace: function (space) {
+ this._verticalSpace = space;
+ },
+
+ /**
+ * Sets anchor point
+ * @override
+ * @param {cc.Point} pt
+ */
+ setAnchorPoint: function (pt) {
+ ccui.Widget.prototype.setAnchorPoint.call(this, pt);
+ this._elementRenderersContainer.setAnchorPoint(pt);
+ },
+ _setAnchorX: function (x) {
+ ccui.Widget.prototype._setAnchorX.call(this, x);
+ this._elementRenderersContainer._setAnchorX(x);
+ },
+ _setAnchorY: function (y) {
+ ccui.Widget.prototype._setAnchorY.call(this, y);
+ this._elementRenderersContainer._setAnchorY(y);
+ },
+
+ /**
+ * Returns the renderer container's content size.
+ * @override
+ * @returns {cc.Size}
+ */
+ getVirtualRendererSize: function () {
+ return this._elementRenderersContainer.getContentSize();
+ },
+
+ /**
+ * Ignore the richText's custom size, If ignore is true that richText will ignore it's custom size, use renderer's content size, false otherwise.
+ * @param {Boolean} ignore
+ * @override
+ */
+ ignoreContentAdaptWithSize: function (ignore) {
+ if (this._ignoreSize !== ignore) {
+ this._formatTextDirty = true;
+ ccui.Widget.prototype.ignoreContentAdaptWithSize.call(this, ignore);
+ }
+ },
+
+ /**
+ * Gets the content size of ccui.RichText
+ * @override
+ * @return {cc.Size}
+ */
+ getContentSize: function () {
+ this.formatText();
+ return cc.Node.prototype.getContentSize.call(this);
+ },
+ _getWidth: function () {
+ this.formatText();
+ return cc.Node.prototype._getWidth.call(this);
+ },
+ _getHeight: function () {
+ this.formatText();
+ return cc.Node.prototype._getHeight.call(this);
+ },
+
+ setContentSize: function (contentSize, height) {
+ var locWidth = (height === undefined) ? contentSize.width : contentSize;
+ var locHeight = (height === undefined) ? contentSize.height : height;
+ ccui.Widget.prototype.setContentSize.call(this, locWidth, locHeight);
+ this._formatTextDirty = true;
+ },
+
+ /**
+ * Returns the class name of ccui.RichText.
+ * @returns {string}
+ */
+ getDescription: function () {
+ return "RichText";
+ },
+ /**
+ * Allow child renderer to be affected by ccui.RichText's opacity
+ * @param {boolean} value
+ */
+ setCascadeOpacityEnabled: function (value) {
+ ccui.Widget.prototype.setCascadeOpacityEnabled.call(this, value);
+ this._elementRenderersContainer.setCascadeOpacityEnabled(value);
+ },
+ /**
+ * This allow the RichText layout to break line on space only like in Latin text format
+ * by default the property is false, which break the line on characters
+ * @param value
+ */
+ setLineBreakOnSpace: function (value) {
+ this._lineBreakOnSpace = value;
+ this._formatTextDirty = true;
+ this.formatText();
+ },
+ /**
+ * Set the renderer horizontal flow alignment for the Control
+ * although it is named TextHorizontalAlignment, it should work with all type of renderer too.
+ * NOTE: we should rename this to setHorizontalAlignment directly
+ *
+ * @example
+ * var richText = new ccui.RichText();
+ * richText.setTextHorizontalAlignment(cc.Text_ALIGNMENT_RIGHT);
+ *
+ * @param {Number} value - example cc.TEXT_ALIGNMENT_RIGHT
+ */
+ setTextHorizontalAlignment: function (value) {
+ if (value !== this._textHorizontalAlignment) {
+ this._textHorizontalAlignment = value;
+ this.formatText();
+ }
+ },
+ /**
+ * Set the renderer vertical flow alignment for the Control
+ * although it is named TextVerticalAlignment, it should work with all type of renderer too.
+ *
+ * @example
+ * var richText = new ccui.RichText();
+ * richText.setTextVerticalAlignment(cc.VERTICAL_TEXT_ALIGNMENT_CENTER);
+ *
+ * @param {Number} value - example cc.VERTICAL_TEXT_ALIGNMENT_CENTER
+ */
+ setTextVerticalAlignment: function (value) {
+ if (value !== this._textVerticalAlignment) {
+ this._textVerticalAlignment = value;
+ this.formatText();
+ }
+ }
+});
+
+/**
+ * create a rich text
+ * @deprecated since v3.0, please use new ccui.RichText() instead.
+ * @returns {RichText}
+ */
+ccui.RichText.create = function () {
+ return new ccui.RichText();
+};
+
+// Constants
+//Rich element type
+/**
+ * The text type of rich element.
+ * @constant
+ * @type {number}
+ */
+ccui.RichElement.TEXT = 0;
+/**
+ * The image type of rich element.
+ * @constant
+ * @type {number}
+ */
+ccui.RichElement.IMAGE = 1;
+/**
+ * The custom type of rich element.
+ * @constant
+ * @type {number}
+ */
+ccui.RichElement.CUSTOM = 2;
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UISlider.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UISlider.js
new file mode 100644
index 0000000..c8362ff
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UISlider.js
@@ -0,0 +1,787 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The Slider control of Cocos UI.
+ * @class
+ * @extends ccui.Widget
+ *
+ * @property {Number} percent - The current progress of loadingbar
+ */
+ccui.Slider = ccui.Widget.extend(/** @lends ccui.Slider# */{
+ _barRenderer: null,
+ _progressBarRenderer: null,
+ _barTextureSize: null,
+ _progressBarTextureSize: null,
+ _slidBallNormalRenderer: null,
+ _slidBallPressedRenderer: null,
+ _slidBallDisabledRenderer: null,
+ _slidBallRenderer: null,
+ _barLength: 0,
+ _percent: 0,
+ _scale9Enabled: false,
+ _prevIgnoreSize: true,
+ _textureFile: "",
+ _progressBarTextureFile: "",
+ _slidBallNormalTextureFile: "",
+ _slidBallPressedTextureFile: "",
+ _slidBallDisabledTextureFile: "",
+ _capInsetsBarRenderer: null,
+ _capInsetsProgressBarRenderer: null,
+ _sliderEventListener: null,
+ _sliderEventSelector: null,
+ _barTexType: ccui.Widget.LOCAL_TEXTURE,
+ _progressBarTexType: ccui.Widget.LOCAL_TEXTURE,
+ _ballNTexType: ccui.Widget.LOCAL_TEXTURE,
+ _ballPTexType: ccui.Widget.LOCAL_TEXTURE,
+ _ballDTexType: ccui.Widget.LOCAL_TEXTURE,
+ _isTextureLoaded: false,
+ _className: "Slider",
+ _barRendererAdaptDirty: true,
+ _progressBarRendererDirty: true,
+ _unifySize: false,
+ _zoomScale: 0.1,
+
+ _sliderBallNormalTextureScaleX: 1,
+ _sliderBallNormalTextureScaleY: 1,
+
+ /**
+ * allocates and initializes a UISlider.
+ * Constructor of ccui.Slider. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @example
+ * // example
+ * var uiSlider = new ccui.Slider();
+ */
+ ctor: function (barTextureName, normalBallTextureName, resType) {
+ this._barTextureSize = cc.size(0, 0);
+ this._progressBarTextureSize = cc.size(0, 0);
+ this._capInsetsBarRenderer = cc.rect(0, 0, 0, 0);
+ this._capInsetsProgressBarRenderer = cc.rect(0, 0, 0, 0);
+ ccui.Widget.prototype.ctor.call(this);
+
+ resType = resType || 0;
+ this.setTouchEnabled(true);
+ if (barTextureName) {
+ this.loadBarTexture(barTextureName, resType);
+ }
+ if (normalBallTextureName) {
+ this.loadSlidBallTextures(normalBallTextureName, resType);
+ }
+ },
+
+ _initRenderer: function () {
+ //todo use Scale9Sprite
+ this._barRenderer = new cc.Sprite();
+ this._progressBarRenderer = new cc.Sprite();
+ this._progressBarRenderer.setAnchorPoint(0.0, 0.5);
+ this.addProtectedChild(this._barRenderer, ccui.Slider.BASEBAR_RENDERER_ZORDER, -1);
+ this.addProtectedChild(this._progressBarRenderer, ccui.Slider.PROGRESSBAR_RENDERER_ZORDER, -1);
+ this._slidBallNormalRenderer = new cc.Sprite();
+ this._slidBallPressedRenderer = new cc.Sprite();
+ this._slidBallPressedRenderer.setVisible(false);
+ this._slidBallDisabledRenderer = new cc.Sprite();
+ this._slidBallDisabledRenderer.setVisible(false);
+ this._slidBallRenderer = new cc.Node();
+ this._slidBallRenderer.addChild(this._slidBallNormalRenderer);
+ this._slidBallRenderer.addChild(this._slidBallPressedRenderer);
+ this._slidBallRenderer.addChild(this._slidBallDisabledRenderer);
+ this._slidBallRenderer.setCascadeColorEnabled(true);
+ this._slidBallRenderer.setCascadeOpacityEnabled(true);
+
+ this.addProtectedChild(this._slidBallRenderer, ccui.Slider.BALL_RENDERER_ZORDER, -1);
+ },
+
+ /**
+ * Loads texture for slider bar.
+ * @param {String} fileName
+ * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
+ */
+ loadBarTexture: function (fileName, texType) {
+ if (!fileName) {
+ return;
+ }
+ texType = texType || ccui.Widget.LOCAL_TEXTURE;
+ this._textureFile = fileName;
+ this._barTexType = texType;
+ var barRenderer = this._barRenderer;
+
+ var self = this;
+ if (!barRenderer._textureLoaded) {
+ barRenderer.addEventListener("load", function () {
+ self.loadBarTexture(self._textureFile, self._barTexType);
+ });
+ }
+
+ switch (this._barTexType) {
+ case ccui.Widget.LOCAL_TEXTURE:
+ //SetTexture cannot load resource
+ barRenderer.initWithFile(fileName);
+ break;
+ case ccui.Widget.PLIST_TEXTURE:
+ //SetTexture cannot load resource
+ barRenderer.initWithSpriteFrameName(fileName);
+ break;
+ default:
+ break;
+ }
+ this._updateChildrenDisplayedRGBA();
+
+ this._barRendererAdaptDirty = true;
+ this._progressBarRendererDirty = true;
+ this._updateContentSizeWithTextureSize(this._barRenderer.getContentSize());
+ this._findLayout();
+ this._barTextureSize = this._barRenderer.getContentSize();
+ },
+
+ /**
+ * Loads dark state texture for slider progress bar.
+ * @param {String} fileName
+ * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
+ */
+ loadProgressBarTexture: function (fileName, texType) {
+ if (!fileName) {
+ return;
+ }
+ texType = texType || ccui.Widget.LOCAL_TEXTURE;
+ this._progressBarTextureFile = fileName;
+ this._progressBarTexType = texType;
+ var progressBarRenderer = this._progressBarRenderer;
+
+ var self = this;
+ if (!progressBarRenderer._textureLoaded) {
+ progressBarRenderer.addEventListener("load", function () {
+ self.loadProgressBarTexture(self._progressBarTextureFile, self._progressBarTexType);
+ });
+ }
+
+ switch (this._progressBarTexType) {
+ case ccui.Widget.LOCAL_TEXTURE:
+ //SetTexture cannot load resource
+ progressBarRenderer.initWithFile(fileName);
+ break;
+ case ccui.Widget.PLIST_TEXTURE:
+ //SetTexture cannot load resource
+ progressBarRenderer.initWithSpriteFrameName(fileName);
+ break;
+ default:
+ break;
+ }
+ this._updateChildrenDisplayedRGBA();
+
+ this._progressBarRenderer.setAnchorPoint(cc.p(0, 0.5));
+ var tz = this._progressBarRenderer.getContentSize();
+ this._progressBarTextureSize = {width: tz.width, height: tz.height};
+ this._progressBarRendererDirty = true;
+ this._findLayout();
+ },
+
+ /**
+ * Sets if slider is using scale9 renderer.
+ * @param {Boolean} able
+ */
+ setScale9Enabled: function (able) {
+ //todo use setScale9Enabled
+ if (this._scale9Enabled === able)
+ return;
+
+ this._scale9Enabled = able;
+ this.removeProtectedChild(this._barRenderer, true);
+ this.removeProtectedChild(this._progressBarRenderer, true);
+ this._barRenderer = null;
+ this._progressBarRenderer = null;
+ if (this._scale9Enabled) {
+ this._barRenderer = new ccui.Scale9Sprite();
+ this._progressBarRenderer = new ccui.Scale9Sprite();
+ } else {
+ this._barRenderer = new cc.Sprite();
+ this._progressBarRenderer = new cc.Sprite();
+ }
+ this.loadBarTexture(this._textureFile, this._barTexType);
+ this.loadProgressBarTexture(this._progressBarTextureFile, this._progressBarTexType);
+ this.addProtectedChild(this._barRenderer, ccui.Slider.BASEBAR_RENDERER_ZORDER, -1);
+ this.addProtectedChild(this._progressBarRenderer, ccui.Slider.PROGRESSBAR_RENDERER_ZORDER, -1);
+ if (this._scale9Enabled) {
+ var ignoreBefore = this._ignoreSize;
+ this.ignoreContentAdaptWithSize(false);
+ this._prevIgnoreSize = ignoreBefore;
+ } else {
+ this.ignoreContentAdaptWithSize(this._prevIgnoreSize);
+ }
+ this.setCapInsetsBarRenderer(this._capInsetsBarRenderer);
+ this.setCapInsetProgressBarRenderer(this._capInsetsProgressBarRenderer);
+ this._barRendererAdaptDirty = true;
+ this._progressBarRendererDirty = true;
+ },
+
+ /**
+ * Returns slider is using scale9 renderer or not.
+ * @returns {Boolean}
+ */
+ isScale9Enabled: function () {
+ return this._scale9Enabled;
+ },
+
+ /**
+ * override "ignoreContentAdaptWithSize" method of widget.
+ * @param {Boolean} ignore
+ */
+ ignoreContentAdaptWithSize: function (ignore) {
+ if (!this._scale9Enabled || (this._scale9Enabled && !ignore)) {
+ ccui.Widget.prototype.ignoreContentAdaptWithSize.call(this, ignore);
+ this._prevIgnoreSize = ignore;
+ }
+ },
+
+ /**
+ * Sets capinsets for slider, if slider is using scale9 renderer.
+ * @param {cc.Rect} capInsets
+ */
+ setCapInsets: function (capInsets) {
+ this.setCapInsetsBarRenderer(capInsets);
+ this.setCapInsetProgressBarRenderer(capInsets);
+ },
+
+ /**
+ * Sets capinsets for slider's renderer, if slider is using scale9 renderer.
+ * @param {cc.Rect} capInsets
+ */
+ setCapInsetsBarRenderer: function (capInsets) {
+ if (!capInsets)
+ return;
+ var locInsets = this._capInsetsBarRenderer;
+ locInsets.x = capInsets.x;
+ locInsets.y = capInsets.y;
+ locInsets.width = capInsets.width;
+ locInsets.height = capInsets.height;
+ if (!this._scale9Enabled)
+ return;
+ this._barRenderer.setCapInsets(capInsets);
+ },
+
+ /**
+ * Returns cap insets for slider.
+ * @returns {cc.Rect}
+ */
+ getCapInsetsBarRenderer: function () {
+ return cc.rect(this._capInsetsBarRenderer);
+ },
+
+ /**
+ * Sets capinsets of ProgressBar for slider, if slider is using scale9 renderer.
+ * @param {cc.Rect} capInsets
+ */
+ setCapInsetProgressBarRenderer: function (capInsets) {
+ if (!capInsets)
+ return;
+ var locInsets = this._capInsetsProgressBarRenderer;
+ locInsets.x = capInsets.x;
+ locInsets.y = capInsets.y;
+ locInsets.width = capInsets.width;
+ locInsets.height = capInsets.height;
+ if (!this._scale9Enabled)
+ return;
+ this._progressBarRenderer.setCapInsets(capInsets);
+ },
+
+ /**
+ * Returns cap insets of ProgressBar for slider.
+ * @returns {cc.Rect}
+ */
+ getCapInsetsProgressBarRenderer: function () {
+ return cc.rect(this._capInsetsProgressBarRenderer);
+ },
+
+ /**
+ * Loads textures for slider ball.
+ * @param {String} normal
+ * @param {String} pressed
+ * @param {String} disabled
+ * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
+ */
+ loadSlidBallTextures: function (normal, pressed, disabled, texType) {
+ this.loadSlidBallTextureNormal(normal, texType);
+ this.loadSlidBallTexturePressed(pressed, texType);
+ this.loadSlidBallTextureDisabled(disabled, texType);
+ },
+
+ /**
+ * Loads normal state texture for slider ball.
+ * @param {String} normal
+ * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
+ */
+ loadSlidBallTextureNormal: function (normal, texType) {
+ if (!normal) {
+ return;
+ }
+ texType = texType || ccui.Widget.LOCAL_TEXTURE;
+ this._slidBallNormalTextureFile = normal;
+ this._ballNTexType = texType;
+
+ var self = this;
+ if (!this._slidBallNormalRenderer._textureLoaded) {
+ this._slidBallNormalRenderer.addEventListener("load", function () {
+ self.loadSlidBallTextureNormal(self._slidBallNormalTextureFile, self._ballNTexType);
+ });
+ }
+
+ switch (this._ballNTexType) {
+ case ccui.Widget.LOCAL_TEXTURE:
+ //SetTexture cannot load resource
+ this._slidBallNormalRenderer.initWithFile(normal);
+ break;
+ case ccui.Widget.PLIST_TEXTURE:
+ //SetTexture cannot load resource
+ this._slidBallNormalRenderer.initWithSpriteFrameName(normal);
+ break;
+ default:
+ break;
+ }
+ this._updateChildrenDisplayedRGBA();
+ this._findLayout();
+ },
+
+ /**
+ * Loads selected state texture for slider ball.
+ * @param {String} pressed
+ * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
+ */
+ loadSlidBallTexturePressed: function (pressed, texType) {
+ if (!pressed) {
+ return;
+ }
+ texType = texType || ccui.Widget.LOCAL_TEXTURE;
+ this._slidBallPressedTextureFile = pressed;
+ this._ballPTexType = texType;
+
+ var self = this;
+ if (!this._slidBallPressedRenderer._textureLoaded) {
+ this._slidBallPressedRenderer.addEventListener("load", function () {
+ self.loadSlidBallTexturePressed(self._slidBallPressedTextureFile, self._ballPTexType);
+ });
+ }
+
+ switch (this._ballPTexType) {
+ case ccui.Widget.LOCAL_TEXTURE:
+ //SetTexture cannot load resource
+ this._slidBallPressedRenderer.initWithFile(pressed);
+ break;
+ case ccui.Widget.PLIST_TEXTURE:
+ //SetTexture cannot load resource
+ this._slidBallPressedRenderer.initWithSpriteFrameName(pressed);
+ break;
+ default:
+ break;
+ }
+ this._updateChildrenDisplayedRGBA();
+ this._findLayout();
+ },
+
+ /**
+ * Load dark state texture for slider ball.
+ * @param {String} disabled
+ * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
+ */
+ loadSlidBallTextureDisabled: function (disabled, texType) {
+ if (!disabled) {
+ return;
+ }
+ texType = texType || ccui.Widget.LOCAL_TEXTURE;
+ this._slidBallDisabledTextureFile = disabled;
+ this._ballDTexType = texType;
+
+ var self = this;
+ if (!this._slidBallDisabledRenderer._textureLoaded) {
+ this._slidBallDisabledRenderer.addEventListener("load", function () {
+ self.loadSlidBallTextureDisabled(self._slidBallDisabledTextureFile, self._ballDTexType);
+ });
+ }
+
+ switch (this._ballDTexType) {
+ case ccui.Widget.LOCAL_TEXTURE:
+ //SetTexture cannot load resource
+ this._slidBallDisabledRenderer.initWithFile(disabled);
+ break;
+ case ccui.Widget.PLIST_TEXTURE:
+ //SetTexture cannot load resource
+ this._slidBallDisabledRenderer.initWithSpriteFrameName(disabled);
+ break;
+ default:
+ break;
+ }
+ this._updateChildrenDisplayedRGBA();
+ this._findLayout();
+ },
+
+ /**
+ * Changes the progress direction of slider.
+ * @param {number} percent
+ */
+ setPercent: function (percent) {
+ if (percent > 100)
+ percent = 100;
+ if (percent < 0)
+ percent = 0;
+ this._percent = percent;
+ var res = percent / 100.0;
+ var dis = this._barLength * res;
+ this._slidBallRenderer.setPosition(dis, this._contentSize.height / 2);
+ if (this._scale9Enabled)
+ this._progressBarRenderer.setPreferredSize(cc.size(dis, this._contentSize.height));
+ else {
+ var spriteRenderer = this._progressBarRenderer;
+ var rect = spriteRenderer.getTextureRect();
+ spriteRenderer.setTextureRect(
+ cc.rect(rect.x, rect.y, dis / spriteRenderer._scaleX, rect.height),
+ spriteRenderer.isTextureRectRotated()
+ );
+ }
+ },
+
+ /**
+ * test the point whether location in loadingBar's bounding box.
+ * @override
+ * @param {cc.Point} pt
+ * @returns {boolean}
+ */
+ hitTest: function (pt) {
+ var nsp = this._slidBallNormalRenderer.convertToNodeSpace(pt);
+ var ballSize = this._slidBallNormalRenderer.getContentSize();
+ var ballRect = cc.rect(0, 0, ballSize.width, ballSize.height);
+ return (nsp.x >= ballRect.x &&
+ nsp.x <= (ballRect.x + ballRect.width) &&
+ nsp.y >= ballRect.y &&
+ nsp.y <= (ballRect.y +ballRect.height));
+ },
+
+ onTouchBegan: function (touch, event) {
+ var pass = ccui.Widget.prototype.onTouchBegan.call(this, touch, event);
+ if (this._hit) {
+ var nsp = this.convertToNodeSpace(this._touchBeganPosition);
+ this.setPercent(this._getPercentWithBallPos(nsp.x));
+ this._percentChangedEvent();
+ }
+ return pass;
+ },
+
+ onTouchMoved: function (touch, event) {
+ var touchPoint = touch.getLocation();
+ var nsp = this.convertToNodeSpace(touchPoint);
+ this.setPercent(this._getPercentWithBallPos(nsp.x));
+ this._percentChangedEvent();
+ },
+
+ onTouchEnded: function (touch, event) {
+ ccui.Widget.prototype.onTouchEnded.call(this, touch, event);
+ },
+
+ onTouchCancelled: function (touch, event) {
+ ccui.Widget.prototype.onTouchCancelled.call(this, touch, event);
+ },
+
+ /**
+ * Returns percent with ball's position.
+ * @param {cc.Point} px
+ * @returns {number}
+ */
+ _getPercentWithBallPos: function (px) {
+ return ((px / this._barLength) * 100);
+ },
+
+ /**
+ * add event listener
+ * @param {Function} selector
+ * @param {Object} [target=]
+ * @deprecated since v3.0, please use addEventListener instead.
+ */
+ addEventListenerSlider: function (selector, target) {
+ this.addEventListener(selector, target);
+ },
+
+ /**
+ * Adds a callback
+ * @param {Function} selector
+ * @param {Object} [target=]
+ */
+ addEventListener: function (selector, target) {
+ this._sliderEventSelector = selector; //when target is undefined, _sliderEventSelector = _eventCallback
+ this._sliderEventListener = target;
+ },
+
+ _percentChangedEvent: function () {
+ if (this._sliderEventSelector) {
+ if (this._sliderEventListener)
+ this._sliderEventSelector.call(this._sliderEventListener, this, ccui.Slider.EVENT_PERCENT_CHANGED);
+ else
+ this._sliderEventSelector(this, ccui.Slider.EVENT_PERCENT_CHANGED); // _eventCallback
+ }
+ if (this._ccEventCallback)
+ this._ccEventCallback(this, ccui.Slider.EVENT_PERCENT_CHANGED);
+ },
+
+ /**
+ * Gets the progress direction of slider.
+ * @returns {number}
+ */
+ getPercent: function () {
+ return this._percent;
+ },
+
+ _onSizeChanged: function () {
+ ccui.Widget.prototype._onSizeChanged.call(this);
+ this._barRendererAdaptDirty = true;
+ this._progressBarRendererDirty = true;
+ },
+
+ _adaptRenderers: function () {
+ if (this._barRendererAdaptDirty) {
+ this._barRendererScaleChangedWithSize();
+ this._barRendererAdaptDirty = false;
+ }
+ if (this._progressBarRendererDirty) {
+ this._progressBarRendererScaleChangedWithSize();
+ this._progressBarRendererDirty = false;
+ }
+ },
+
+ /**
+ * Returns the content size of bar renderer.
+ * @returns {cc.Size}
+ */
+ getVirtualRendererSize: function () {
+ return this._barRenderer.getContentSize();
+ },
+
+ /**
+ * Returns the bar renderer.
+ * @returns {cc.Node}
+ */
+ getVirtualRenderer: function () {
+ return this._barRenderer;
+ },
+
+ _barRendererScaleChangedWithSize: function () {
+ if (this._unifySize) {
+ this._barLength = this._contentSize.width;
+ this._barRenderer.setPreferredSize(this._contentSize);
+ } else if (this._ignoreSize) {
+ this._barRenderer.setScale(1.0);
+ this._barLength = this._contentSize.width;
+ } else {
+ this._barLength = this._contentSize.width;
+ if (this._scale9Enabled) {
+ this._barRenderer.setPreferredSize(this._contentSize);
+ this._barRenderer.setScale(1.0);
+ } else {
+ var btextureSize = this._barTextureSize;
+ if (btextureSize.width <= 0.0 || btextureSize.height <= 0.0) {
+ this._barRenderer.setScale(1.0);
+ } else {
+ var bscaleX = this._contentSize.width / btextureSize.width;
+ var bscaleY = this._contentSize.height / btextureSize.height;
+ this._barRenderer.setScaleX(bscaleX);
+ this._barRenderer.setScaleY(bscaleY);
+ }
+ }
+ }
+ this._barRenderer.setPosition(this._contentSize.width / 2.0, this._contentSize.height / 2.0);
+ this.setPercent(this._percent);
+ },
+
+ _progressBarRendererScaleChangedWithSize: function () {
+ if (this._unifySize) {
+ this._progressBarRenderer.setPreferredSize(this._contentSize);
+ } else if (this._ignoreSize) {
+ if (!this._scale9Enabled) {
+ var ptextureSize = this._progressBarTextureSize;
+ var pscaleX = this._contentSize.width / ptextureSize.width;
+ var pscaleY = this._contentSize.height / ptextureSize.height;
+ this._progressBarRenderer.setScaleX(pscaleX);
+ this._progressBarRenderer.setScaleY(pscaleY);
+ }
+ }
+ else {
+ if (this._scale9Enabled) {
+ this._progressBarRenderer.setPreferredSize(this._contentSize);
+ this._progressBarRenderer.setScale(1);
+ }
+ else {
+ var ptextureSize = this._progressBarTextureSize;
+ if (ptextureSize.width <= 0.0 || ptextureSize.height <= 0.0) {
+ this._progressBarRenderer.setScale(1.0);
+ return;
+ }
+ var pscaleX = this._contentSize.width / ptextureSize.width;
+ var pscaleY = this._contentSize.height / ptextureSize.height;
+ this._progressBarRenderer.setScaleX(pscaleX);
+ this._progressBarRenderer.setScaleY(pscaleY);
+ }
+ }
+ this._progressBarRenderer.setPosition(0.0, this._contentSize.height / 2.0);
+ this.setPercent(this._percent);
+ },
+
+ _onPressStateChangedToNormal: function () {
+ this._slidBallNormalRenderer.setVisible(true);
+ this._slidBallPressedRenderer.setVisible(false);
+ this._slidBallDisabledRenderer.setVisible(false);
+
+ this._slidBallNormalRenderer.setScale(this._sliderBallNormalTextureScaleX, this._sliderBallNormalTextureScaleY);
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ this._slidBallNormalRenderer._renderCmd._shaderProgram = this._getNormalGLProgram();
+ } else {
+ // TODO: add canvas support
+ }
+ },
+
+ _onPressStateChangedToPressed: function () {
+ if (!this._slidBallPressedTextureFile) {
+ this._slidBallNormalRenderer.setScale(this._sliderBallNormalTextureScaleX + this._zoomScale, this._sliderBallNormalTextureScaleY + this._zoomScale);
+ } else {
+ this._slidBallNormalRenderer.setVisible(false);
+ this._slidBallPressedRenderer.setVisible(true);
+ this._slidBallDisabledRenderer.setVisible(false);
+ }
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ this._slidBallNormalRenderer._renderCmd._shaderProgram = this._getNormalGLProgram();
+ } else {
+ // TODO: add canvas support
+ }
+ },
+
+ _onPressStateChangedToDisabled: function () {
+ if (this._slidBallDisabledTextureFile) {
+ this._slidBallNormalRenderer.setVisible(false);
+ this._slidBallDisabledRenderer.setVisible(true);
+ } else {
+ this._slidBallNormalRenderer.setVisible(true);
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ this._slidBallNormalRenderer._renderCmd._shaderProgram = this._getGrayGLProgram();
+ } else {
+ // TODO: add canvas support
+ }
+ }
+ this._slidBallNormalRenderer.setScale(this._sliderBallNormalTextureScaleX, this._sliderBallNormalTextureScaleY);
+ this._slidBallPressedRenderer.setVisible(false);
+ },
+
+ setZoomScale: function (scale) {
+ this._zoomScale = scale;
+ },
+
+ getZoomScale: function () {
+ return this._zoomScale;
+ },
+
+ getSlidBallNormalRenderer: function () {
+ return this._slidBallNormalRenderer;
+ },
+
+ getSlidBallPressedRenderer: function () {
+ return this._slidBallPressedRenderer;
+ },
+
+ getSlidBallDisabledRenderer: function () {
+ return this._slidBallDisabledRenderer;
+ },
+
+ getSlidBallRenderer: function () {
+ return this._slidBallRenderer;
+ },
+
+ /**
+ * Returns the "class name" of ccui.LoadingBar.
+ * @returns {string}
+ */
+ getDescription: function () {
+ return "Slider";
+ },
+
+ _createCloneInstance: function () {
+ return new ccui.Slider();
+ },
+
+ _copySpecialProperties: function (slider) {
+ this._prevIgnoreSize = slider._prevIgnoreSize;
+ this.setScale9Enabled(slider._scale9Enabled);
+ this.loadBarTexture(slider._textureFile, slider._barTexType);
+ this.loadProgressBarTexture(slider._progressBarTextureFile, slider._progressBarTexType);
+ this.loadSlidBallTextureNormal(slider._slidBallNormalTextureFile, slider._ballNTexType);
+ this.loadSlidBallTexturePressed(slider._slidBallPressedTextureFile, slider._ballPTexType);
+ this.loadSlidBallTextureDisabled(slider._slidBallDisabledTextureFile, slider._ballDTexType);
+ this.setPercent(slider.getPercent());
+ this._sliderEventListener = slider._sliderEventListener;
+ this._sliderEventSelector = slider._sliderEventSelector;
+ this._zoomScale = slider._zoomScale;
+ this._ccEventCallback = slider._ccEventCallback;
+
+ }
+});
+
+var _p = ccui.Slider.prototype;
+
+// Extended properties
+/** @expose */
+_p.percent;
+cc.defineGetterSetter(_p, "percent", _p.getPercent, _p.setPercent);
+
+_p = null;
+
+/**
+ * allocates and initializes a UISlider.
+ * @deprecated since v3.0, please use new ccui.Slider() instead.
+ * @return {ccui.Slider}
+ */
+ccui.Slider.create = function (barTextureName, normalBallTextureName, resType) {
+ return new ccui.Slider(barTextureName, normalBallTextureName, resType);
+};
+
+// Constant
+//Slider event type
+/**
+ * The percent change event flag of ccui.Slider.
+ * @constant
+ * @type {number}
+ */
+ccui.Slider.EVENT_PERCENT_CHANGED = 0;
+
+//Render zorder
+/**
+ * The zOrder value of ccui.Slider's base bar renderer.
+ * @constant
+ * @type {number}
+ */
+ccui.Slider.BASEBAR_RENDERER_ZORDER = -3;
+/**
+ * The zOrder value of ccui.Slider's progress bar renderer.
+ * @constant
+ * @type {number}
+ */
+ccui.Slider.PROGRESSBAR_RENDERER_ZORDER = -2;
+/**
+ * The zOrder value of ccui.Slider's ball renderer.
+ * @constant
+ * @type {number}
+ */
+ccui.Slider.BALL_RENDERER_ZORDER = -1;
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIText.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIText.js
new file mode 100644
index 0000000..5d72e06
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIText.js
@@ -0,0 +1,525 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The text control of Cocos UI.
+ * @class
+ * @extends ccui.Widget
+ *
+ * @property {Number} boundingWidth - Width of the bounding area of label, the real content width is limited by boundingWidth
+ * @property {Number} boundingHeight - Height of the bounding area of label, the real content height is limited by boundingHeight
+ * @property {String} string - The content string of the label
+ * @property {Number} stringLength - <@readonly> The content string length of the label
+ * @property {String} font - The label font with a style string: e.g. "18px Verdana"
+ * @property {String} fontName - The label font name
+ * @property {Number} fontSize - The label font size
+ * @property {Number} textAlign - Horizontal Alignment of label, cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT
+ * @property {Number} verticalAlign - Vertical Alignment of label: cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM
+ * @property {Boolean} touchScaleEnabled - Indicate whether the label will scale when touching
+ */
+ccui.Text = ccui.Widget.extend(/** @lends ccui.Text# */{
+ _touchScaleChangeEnabled: false,
+ _normalScaleValueX: 1,
+ _normalScaleValueY: 1,
+ _fontName: "Arial",
+ _fontSize: 16,
+ _onSelectedScaleOffset: 0.5,
+ _labelRenderer: null,
+ _textAreaSize: null,
+ _textVerticalAlignment: 0,
+ _textHorizontalAlignment: 0,
+ _className: "Text",
+ _type: null,
+ _labelRendererAdaptDirty: true,
+
+ /**
+ * allocates and initializes a UILabel.
+ * Constructor of ccui.Text. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {String} textContent
+ * @param {String} fontName
+ * @param {Number} fontSize
+ * @example
+ * // example
+ * var uiLabel = new ccui.Text();
+ */
+ ctor: function (textContent, fontName, fontSize) {
+ this._type = ccui.Text.Type.SYSTEM;
+ this._textAreaSize = cc.size(0, 0);
+ ccui.Widget.prototype.ctor.call(this);
+
+ if (fontSize !== undefined) {
+ this.setFontName(fontName);
+ this.setFontSize(fontSize);
+ this.setString(textContent);
+ } else {
+ this.setFontName(this._fontName);
+ }
+ },
+
+ _initRenderer: function () {
+ this._labelRenderer = new cc.LabelTTF();
+ this.addProtectedChild(this._labelRenderer, ccui.Text.RENDERER_ZORDER, -1);
+ },
+
+ /**
+ * Changes the value of ccui.Text.
+ * @deprecated since v3.0, please use setString() instead.
+ * @param {String} text
+ */
+ setText: function (text) {
+ cc.log("Please use the setString");
+ this.setString(text);
+ },
+
+ /**
+ * Changes the value of ccui.Text.
+ * @param {String} text
+ */
+ setString: function (text) {
+ if(text === this._labelRenderer.getString()) return;
+ this._setString(text);
+
+ this._updateContentSizeWithTextureSize(this._labelRenderer.getContentSize());
+ },
+
+ _setString: function (text) {
+ this._labelRenderer.setString(text);
+ this._labelRendererAdaptDirty = true;
+ },
+
+ /**
+ * Gets the string value of ccui.Text.
+ * @deprecated since v3.0, please use getString instead.
+ * @returns {String}
+ */
+ getStringValue: function () {
+ cc.log("Please use the getString");
+ return this._labelRenderer.getString();
+ },
+
+ /**
+ * Gets the string value of ccui.Text.
+ * @returns {String}
+ */
+ getString: function () {
+ return this._labelRenderer.getString();
+ },
+
+ /**
+ * Gets the string length of ccui.Text.
+ * @returns {Number}
+ */
+ getStringLength: function () {
+ return this._labelRenderer.getStringLength();
+ },
+
+ /**
+ * Sets fontSize
+ * @param {Number} size
+ */
+ setFontSize: function (size) {
+ this._setFontSize(size);
+ this._updateContentSizeWithTextureSize(this._labelRenderer.getContentSize());
+ },
+
+ _setFontSize: function (size) {
+ this._labelRenderer.setFontSize(size);
+ this._fontSize = size;
+ this._labelRendererAdaptDirty = true;
+ },
+
+ /**
+ * Returns font Size of ccui.Text
+ * @returns {Number}
+ */
+ getFontSize: function () {
+ return this._fontSize;
+ },
+
+ /**
+ * Sets font name
+ * @return {String} name
+ */
+ setFontName: function (name) {
+ this._setFontName(name);
+ this._updateContentSizeWithTextureSize(this._labelRenderer.getContentSize());
+ },
+
+ _setFontName: function (name) {
+ this._fontName = name;
+ this._labelRenderer.setFontName(name);
+ this._labelRendererAdaptDirty = true;
+ },
+
+ _updateUITextContentSize: function () {
+ this._updateContentSizeWithTextureSize(this._labelRenderer.getContentSize());
+ },
+
+ /**
+ * Returns font name of ccui.Text.
+ * @returns {string}
+ */
+ getFontName: function () {
+ return this._fontName;
+ },
+
+ _setFont: function (font) {
+ var res = cc.LabelTTF._fontStyleRE.exec(font);
+ if (res) {
+ this._fontSize = parseInt(res[1]);
+ this._fontName = res[2];
+ this._labelRenderer._setFont(font);
+ this._labelScaleChangedWithSize();
+ }
+ },
+ _getFont: function () {
+ return this._labelRenderer._getFont();
+ },
+
+ /**
+ * Returns the type of ccui.Text.
+ * @returns {null}
+ */
+ getType: function () {
+ return this._type;
+ },
+
+ /**
+ * Sets text Area Size
+ * @param {cc.Size} size
+ */
+ setTextAreaSize: function (size) {
+ this._setTextAreaSize(size);
+ this._updateContentSizeWithTextureSize(this._labelRenderer.getContentSize());
+ },
+
+ _setTextAreaSize: function (size) {
+ this._labelRenderer.setDimensions(size);
+ if (!this._ignoreSize){
+ this._customSize = size;
+ }
+ this._labelRendererAdaptDirty = true;
+ },
+
+ /**
+ * Returns renderer's dimension.
+ * @returns {cc.Size}
+ */
+ getTextAreaSize: function () {
+ return this._labelRenderer.getDimensions();
+ },
+
+ /**
+ * Sets Horizontal Alignment of cc.LabelTTF
+ * @param {cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT} alignment Horizontal Alignment
+ */
+ setTextHorizontalAlignment: function (alignment) {
+ this._setTextHorizontalAlignment(alignment);
+ this._updateContentSizeWithTextureSize(this._labelRenderer.getContentSize());
+ },
+
+
+ _setTextHorizontalAlignment: function (alignment) {
+ this._labelRenderer.setHorizontalAlignment(alignment);
+ this._labelRendererAdaptDirty = true;
+ },
+
+ /**
+ * Returns Horizontal Alignment of label
+ * @returns {TEXT_ALIGNMENT_LEFT|TEXT_ALIGNMENT_CENTER|TEXT_ALIGNMENT_RIGHT}
+ */
+ getTextHorizontalAlignment: function () {
+ return this._labelRenderer.getHorizontalAlignment();
+ },
+
+ /**
+ * Sets Vertical Alignment of label
+ * @param {cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM} alignment
+ */
+ setTextVerticalAlignment: function (alignment) {
+ this._setTextVerticalAlignment(alignment);
+ this._updateContentSizeWithTextureSize(this._labelRenderer.getContentSize());
+ },
+
+ _setTextVerticalAlignment: function (alignment) {
+ this._labelRenderer.setVerticalAlignment(alignment);
+ this._labelRendererAdaptDirty = true;
+ },
+ /**
+ * Gets text vertical alignment.
+ * @returns {VERTICAL_TEXT_ALIGNMENT_TOP|VERTICAL_TEXT_ALIGNMENT_CENTER|VERTICAL_TEXT_ALIGNMENT_BOTTOM}
+ */
+ getTextVerticalAlignment: function () {
+ return this._labelRenderer.getVerticalAlignment();
+ },
+
+ /**
+ * Sets the touch scale enabled of label.
+ * @param {Boolean} enable
+ */
+ setTouchScaleChangeEnabled: function (enable) {
+ this._touchScaleChangeEnabled = enable;
+ },
+
+ /**
+ * Gets the touch scale enabled of label.
+ * @returns {Boolean}
+ */
+ isTouchScaleChangeEnabled: function () {
+ return this._touchScaleChangeEnabled;
+ },
+
+ _onPressStateChangedToNormal: function () {
+ if (!this._touchScaleChangeEnabled)
+ return;
+ this._labelRenderer.setScaleX(this._normalScaleValueX);
+ this._labelRenderer.setScaleY(this._normalScaleValueY);
+ },
+
+ _onPressStateChangedToPressed: function () {
+ if (!this._touchScaleChangeEnabled)
+ return;
+ this._labelRenderer.setScaleX(this._normalScaleValueX + this._onSelectedScaleOffset);
+ this._labelRenderer.setScaleY(this._normalScaleValueY + this._onSelectedScaleOffset);
+ },
+
+ _onPressStateChangedToDisabled: function () {
+ },
+
+ _onSizeChanged: function () {
+ ccui.Widget.prototype._onSizeChanged.call(this);
+ this._labelRendererAdaptDirty = true;
+ },
+
+ _adaptRenderers: function () {
+ if (this._labelRendererAdaptDirty) {
+ this._labelScaleChangedWithSize();
+ this._labelRendererAdaptDirty = false;
+ }
+ },
+
+ /**
+ * Returns the renderer's content size.
+ * @override
+ * @returns {cc.Size}
+ */
+ getVirtualRendererSize: function () {
+ return this._labelRenderer.getContentSize();
+ },
+
+ /**
+ * Returns the renderer of ccui.Text.
+ * @returns {cc.Node}
+ */
+ getVirtualRenderer: function () {
+ return this._labelRenderer;
+ },
+
+ //@since v3.3
+ getAutoRenderSize: function () {
+ var virtualSize = this._labelRenderer.getContentSize();
+ if (!this._ignoreSize) {
+ this._labelRenderer.setDimensions(0, 0);
+ virtualSize = this._labelRenderer.getContentSize();
+ this._labelRenderer.setDimensions(this._contentSize.width, this._contentSize.height);
+ }
+ return virtualSize;
+ },
+
+ _labelScaleChangedWithSize: function () {
+ var locContentSize = this._contentSize;
+ if (this._ignoreSize) {
+ this._labelRenderer.setScale(1.0);
+ this._normalScaleValueX = this._normalScaleValueY = 1;
+ } else {
+ this._labelRenderer.setDimensions(cc.size(locContentSize.width, locContentSize.height));
+ var textureSize = this._labelRenderer.getContentSize();
+ if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
+ this._labelRenderer.setScale(1.0);
+ return;
+ }
+ var scaleX = locContentSize.width / textureSize.width;
+ var scaleY = locContentSize.height / textureSize.height;
+ this._labelRenderer.setScaleX(scaleX);
+ this._labelRenderer.setScaleY(scaleY);
+ this._normalScaleValueX = scaleX;
+ this._normalScaleValueY = scaleY;
+ }
+ this._labelRenderer.setPosition(locContentSize.width / 2.0, locContentSize.height / 2.0);
+ },
+
+ /**
+ * Returns the "class name" of ccui.Text.
+ * @returns {string}
+ */
+ getDescription: function () {
+ return "Label";
+ },
+
+ /**
+ * Enables shadow style and sets color, offset and blur radius styles.
+ * @param {cc.Color} shadowColor
+ * @param {cc.Size} offset
+ * @param {Number} blurRadius
+ */
+ enableShadow: function (shadowColor, offset, blurRadius) {
+ this._labelRenderer.enableShadow(shadowColor, offset, blurRadius);
+ },
+
+ /**
+ * Enables outline style and sets outline's color and size.
+ * @param {cc.Color} outlineColor
+ * @param {cc.Size} outlineSize
+ */
+ enableOutline: function (outlineColor, outlineSize) {
+ this._labelRenderer.enableStroke(outlineColor, outlineSize);
+ },
+
+ /**
+ * Enables glow color
+ * @param glowColor
+ */
+ enableGlow: function (glowColor) {
+ if (this._type === ccui.Text.Type.TTF)
+ this._labelRenderer.enableGlow(glowColor);
+ },
+
+ /**
+ * Disables renderer's effect.
+ */
+ disableEffect: function () {
+ if (this._labelRenderer.disableEffect)
+ this._labelRenderer.disableEffect();
+ },
+
+ _createCloneInstance: function () {
+ return new ccui.Text();
+ },
+
+ _copySpecialProperties: function (uiLabel) {
+ if (uiLabel instanceof ccui.Text) {
+ this.setFontName(uiLabel._fontName);
+ this.setFontSize(uiLabel.getFontSize());
+ this.setString(uiLabel.getString());
+ this.setTouchScaleChangeEnabled(uiLabel.touchScaleEnabled);
+ this.setTextAreaSize(uiLabel._textAreaSize);
+ this.setTextHorizontalAlignment(uiLabel._labelRenderer.getHorizontalAlignment());
+ this.setTextVerticalAlignment(uiLabel._labelRenderer.getVerticalAlignment());
+ this.setContentSize(uiLabel.getContentSize());
+ this.setTextColor(uiLabel.getTextColor());
+ }
+ },
+
+ _setBoundingWidth: function (value) {
+ this._textAreaSize.width = value;
+ this._labelRenderer._setBoundingWidth(value);
+ this._labelScaleChangedWithSize();
+ },
+ _setBoundingHeight: function (value) {
+ this._textAreaSize.height = value;
+ this._labelRenderer._setBoundingHeight(value);
+ this._labelScaleChangedWithSize();
+ },
+ _getBoundingWidth: function () {
+ return this._textAreaSize.width;
+ },
+ _getBoundingHeight: function () {
+ return this._textAreaSize.height;
+ },
+
+ _changePosition: function () {
+ this._adaptRenderers();
+ },
+
+ setColor: function (color) {
+ cc.ProtectedNode.prototype.setColor.call(this, color);
+ this._labelRenderer.setColor(color);
+ },
+
+ setTextColor: function (color) {
+ this._labelRenderer.setFontFillColor(color);
+ },
+
+ getTextColor: function () {
+ return this._labelRenderer._getFillStyle();
+ }
+});
+
+var _p = ccui.Text.prototype;
+
+// Extended properties
+/** @expose */
+_p.boundingWidth;
+cc.defineGetterSetter(_p, "boundingWidth", _p._getBoundingWidth, _p._setBoundingWidth);
+/** @expose */
+_p.boundingHeight;
+cc.defineGetterSetter(_p, "boundingHeight", _p._getBoundingHeight, _p._setBoundingHeight);
+/** @expose */
+_p.string;
+cc.defineGetterSetter(_p, "string", _p.getString, _p.setString);
+/** @expose */
+_p.stringLength;
+cc.defineGetterSetter(_p, "stringLength", _p.getStringLength);
+/** @expose */
+_p.font;
+cc.defineGetterSetter(_p, "font", _p._getFont, _p._setFont);
+/** @expose */
+_p.fontSize;
+cc.defineGetterSetter(_p, "fontSize", _p.getFontSize, _p.setFontSize);
+/** @expose */
+_p.fontName;
+cc.defineGetterSetter(_p, "fontName", _p.getFontName, _p.setFontName);
+/** @expose */
+_p.textAlign;
+cc.defineGetterSetter(_p, "textAlign", _p.getTextHorizontalAlignment, _p.setTextHorizontalAlignment);
+/** @expose */
+_p.verticalAlign;
+cc.defineGetterSetter(_p, "verticalAlign", _p.getTextVerticalAlignment, _p.setTextVerticalAlignment);
+
+_p = null;
+
+/**
+ * allocates and initializes a UILabel.
+ * @deprecated since v3.0, please use new ccui.Text() instead.
+ * @return {ccui.Text}
+ */
+ccui.Label = ccui.Text.create = function (textContent, fontName, fontSize) {
+ return new ccui.Text(textContent, fontName, fontSize);
+};
+
+/**
+ * The zOrder value of ccui.Text's renderer.
+ * @constant
+ * @type {number}
+ */
+ccui.Text.RENDERER_ZORDER = -1;
+
+/**
+ * @ignore
+ */
+ccui.Text.Type = {
+ SYSTEM: 0,
+ TTF: 1
+};
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UITextAtlas.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UITextAtlas.js
new file mode 100644
index 0000000..98c4b89
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UITextAtlas.js
@@ -0,0 +1,236 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The text atlas control of Cocos UI.
+ * @class
+ * @extends ccui.Widget
+ *
+ * @property {String} string - Content string of the label
+ */
+ccui.TextAtlas = ccui.Widget.extend(/** @lends ccui.TextAtlas# */{
+ _labelAtlasRenderer: null,
+ _stringValue: "",
+ _charMapFileName: "",
+ _itemWidth: 0,
+ _itemHeight: 0,
+ _startCharMap: "",
+ _className: "TextAtlas",
+ _labelAtlasRendererAdaptDirty: null,
+
+ /**
+ * Allocates and initializes a UILabelAtlas.
+ * Constructor of ccui.TextAtlas, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {String} stringValue
+ * @param {String} charMapFile
+ * @param {number} itemWidth
+ * @param {number} itemHeight
+ * @param {String} startCharMap
+ * @example
+ * // example
+ * var uiLabelAtlas = new ccui.TextAtlas();
+ */
+ ctor: function (stringValue, charMapFile, itemWidth, itemHeight, startCharMap) {
+ ccui.Widget.prototype.ctor.call(this);
+ if (startCharMap !== undefined) {
+ this.setProperty(stringValue, charMapFile, itemWidth, itemHeight, startCharMap);
+ }
+ },
+
+ _initRenderer: function () {
+ this._labelAtlasRenderer = new cc.LabelAtlas();
+ this._labelAtlasRenderer.setAnchorPoint(cc.p(0.5, 0.5));
+ this.addProtectedChild(this._labelAtlasRenderer, ccui.TextAtlas.RENDERER_ZORDER, -1);
+
+ this._labelAtlasRenderer.addEventListener('load', function () {
+ this._updateContentSizeWithTextureSize(this._labelAtlasRenderer.getContentSize());
+ this._findLayout();
+ }, this);
+ },
+
+ /**
+ * initializes the UILabelAtlas with a string, a char map file(the atlas), the width and height of each element and the starting char of the atlas
+ * @param {String} stringValue
+ * @param {String} charMapFile
+ * @param {number} itemWidth
+ * @param {number} itemHeight
+ * @param {String} startCharMap
+ */
+ setProperty: function (stringValue, charMapFile, itemWidth, itemHeight, startCharMap) {
+ this._stringValue = stringValue;
+ this._charMapFileName = charMapFile;
+ this._itemWidth = itemWidth;
+ this._itemHeight = itemHeight;
+ this._startCharMap = startCharMap;
+
+ this._labelAtlasRenderer.initWithString(
+ stringValue,
+ this._charMapFileName,
+ this._itemWidth,
+ this._itemHeight,
+ this._startCharMap[0]
+ );
+
+ this._updateContentSizeWithTextureSize(this._labelAtlasRenderer.getContentSize());
+ this._labelAtlasRendererAdaptDirty = true;
+ },
+
+ /**
+ * Sets string value for ui text atlas.
+ * @param {String} value
+ */
+ setString: function (value) {
+ if (value === this._labelAtlasRenderer.getString())
+ return;
+ this._stringValue = value;
+ this._labelAtlasRenderer.setString(value);
+ this._updateContentSizeWithTextureSize(this._labelAtlasRenderer.getContentSize());
+ this._labelAtlasRendererAdaptDirty = true;
+ },
+
+ /**
+ * Sets string value for text atlas.
+ * @deprecated since v3.0, please use setString instead.
+ * @param {String} value
+ */
+ setStringValue: function (value) {
+ cc.log("Please use the setString");
+ this.setString(value);
+ },
+
+ /**
+ * get string value for text atlas.
+ * @deprecated since v3.0, please use getString instead.
+ * @returns {String}
+ */
+ getStringValue: function () {
+ cc.log("Please use the getString");
+ return this.getString();
+ },
+
+ /**
+ * get string value for ui text atlas.
+ * @returns {String}
+ */
+ getString: function () {
+ return this._labelAtlasRenderer.getString();
+ },
+
+ /**
+ * Returns the length of string.
+ * @returns {*|Number|long|int}
+ */
+ getStringLength: function () {
+ return this._labelAtlasRenderer.getStringLength();
+ },
+
+ _onSizeChanged: function () {
+ ccui.Widget.prototype._onSizeChanged.call(this);
+ this._labelAtlasRendererAdaptDirty = true;
+ },
+
+ _adaptRenderers: function () {
+ if (this._labelAtlasRendererAdaptDirty) {
+ this._labelAtlasScaleChangedWithSize();
+ this._labelAtlasRendererAdaptDirty = false;
+ }
+ },
+
+ /**
+ * Returns the renderer's content size
+ * @overrider
+ * @returns {cc.Size}
+ */
+ getVirtualRendererSize: function () {
+ return this._labelAtlasRenderer.getContentSize();
+ },
+
+ /**
+ * Returns the renderer of ccui.TextAtlas.
+ * @returns {cc.Node}
+ */
+ getVirtualRenderer: function () {
+ return this._labelAtlasRenderer;
+ },
+
+ _labelAtlasScaleChangedWithSize: function () {
+ var locRenderer = this._labelAtlasRenderer;
+ if (this._ignoreSize) {
+ locRenderer.setScale(1.0);
+ } else {
+ var textureSize = locRenderer.getContentSize();
+ if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
+ locRenderer.setScale(1.0);
+ return;
+ }
+ locRenderer.setScaleX(this._contentSize.width / textureSize.width);
+ locRenderer.setScaleY(this._contentSize.height / textureSize.height);
+ }
+ locRenderer.setPosition(this._contentSize.width / 2.0, this._contentSize.height / 2.0);
+ },
+
+ /**
+ * Returns the "class name" of ccui.TextAtlas.
+ * @returns {string}
+ */
+ getDescription: function () {
+ return "LabelAtlas";
+ },
+
+ _copySpecialProperties: function (labelAtlas) {
+ if (labelAtlas) {
+ this.setProperty(labelAtlas._stringValue, labelAtlas._charMapFileName, labelAtlas._itemWidth, labelAtlas._itemHeight, labelAtlas._startCharMap);
+ }
+ },
+
+ _createCloneInstance: function () {
+ return new ccui.TextAtlas();
+ }
+});
+
+var _p = ccui.TextAtlas.prototype;
+
+// Extended properties
+/** @expose */
+_p.string;
+cc.defineGetterSetter(_p, "string", _p.getString, _p.setString);
+
+_p = null;
+
+/**
+ * allocates and initializes a UILabelAtlas.
+ * @deprecated since v3.0, please use new ccui.TextAtlas() instead.
+ * @return {ccui.TextAtlas}
+ */
+ccui.TextAtlas.create = function (stringValue, charMapFile, itemWidth, itemHeight, startCharMap) {
+ return new ccui.TextAtlas(stringValue, charMapFile, itemWidth, itemHeight, startCharMap);
+};
+
+// Constants
+/**
+ * The zOrder value of ccui.TextAtlas's renderer.
+ * @type {number}
+ */
+ccui.TextAtlas.RENDERER_ZORDER = -1;
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UITextBMFont.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UITextBMFont.js
new file mode 100644
index 0000000..25c9231
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UITextBMFont.js
@@ -0,0 +1,224 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The TextBMFont control of Cocos UI, it rendered by LabelBMFont.
+ * @class
+ * @extends ccui.Widget
+ *
+ * @property {String} string - Content string of the label
+ */
+ccui.LabelBMFont = ccui.TextBMFont = ccui.Widget.extend(/** @lends ccui.TextBMFont# */{
+ _labelBMFontRenderer: null,
+ _fntFileHasInit: false,
+ _fntFileName: "",
+ _stringValue: "",
+ _className: "TextBMFont",
+ _labelBMFontRendererAdaptDirty: true,
+
+ /**
+ * Allocates and initializes a TextBMFont.
+ * Constructor of ccui.TextBMFont. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {String} text
+ * @param {String} filename
+ * @example
+ * // example
+ * var uiLabelBMFont = new ccui.TextBMFont();
+ */
+ ctor: function (text, filename) {
+ ccui.Widget.prototype.ctor.call(this);
+ this._loader = new cc.Sprite.LoadManager();
+
+ if (filename !== undefined) {
+ this.setFntFile(filename);
+ this.setString(text);
+ }
+ },
+
+ _initRenderer: function () {
+ this._labelBMFontRenderer = new cc.LabelBMFont();
+ this.addProtectedChild(this._labelBMFontRenderer, ccui.TextBMFont.RENDERER_ZORDER, -1);
+ },
+
+ /**
+ * Initializes a bitmap font atlas with an initial string and the FNT file
+ * @param {String} fileName
+ */
+ setFntFile: function (fileName) {
+ if (!fileName)
+ return;
+ this._fntFileName = fileName;
+
+ this._fntFileHasInit = true;
+ this._labelBMFontRenderer.initWithString(this._stringValue, fileName);
+ this._updateContentSizeWithTextureSize(this._labelBMFontRenderer.getContentSize());
+ this._labelBMFontRendererAdaptDirty = true;
+
+ var _self = this;
+ var locRenderer = _self._labelBMFontRenderer;
+ if (!locRenderer._textureLoaded) {
+ locRenderer.addEventListener("load", function () {
+ _self.setFntFile(_self._fntFileName);
+ });
+ }
+ },
+
+ /**
+ * Sets string value for TextBMFont
+ * @deprecated since v3.0, please use setString instead.
+ * @param {String} value
+ */
+ setText: function (value) {
+ cc.log("Please use the setString");
+ this.setString(value);
+ },
+
+ /**
+ * Sets string value for TextBMFont
+ * @param {String} value
+ */
+ setString: function (value) {
+ this._loader.clear();
+ if (!this._labelBMFontRenderer._textureLoaded) {
+ this._loader.add(this._labelBMFontRenderer, function () {
+ this.setString(value);
+ }, this);
+ return;
+ }
+ if (value === this._labelBMFontRenderer.getString())
+ return;
+ this._stringValue = value;
+ this._labelBMFontRenderer.setString(value);
+ if (!this._fntFileHasInit)
+ return;
+ this._updateContentSizeWithTextureSize(this._labelBMFontRenderer.getContentSize());
+ this._labelBMFontRendererAdaptDirty = true;
+ },
+
+ /**
+ * Returns string value for TextBMFont.
+ * @returns {String}
+ */
+ getString: function () {
+ return this._stringValue;
+ },
+
+ /**
+ * Returns the length of TextBMFont's string.
+ * @returns {Number}
+ */
+ getStringLength: function () {
+ return this._labelBMFontRenderer.getStringLength();
+ },
+
+ _onSizeChanged: function () {
+ ccui.Widget.prototype._onSizeChanged.call(this);
+ this._labelBMFontRendererAdaptDirty = true;
+ },
+
+ _adaptRenderers: function () {
+ if (this._labelBMFontRendererAdaptDirty) {
+ this._labelBMFontScaleChangedWithSize();
+ this._labelBMFontRendererAdaptDirty = false;
+ }
+ },
+
+ /**
+ * Returns TextBMFont's content size
+ * @override
+ * @returns {cc.Size}
+ */
+ getVirtualRendererSize: function () {
+ return this._labelBMFontRenderer.getContentSize();
+ },
+
+ /**
+ * Returns the renderer of TextBMFont
+ * @override
+ * @returns {cc.Node}
+ */
+ getVirtualRenderer: function () {
+ return this._labelBMFontRenderer;
+ },
+
+ _labelBMFontScaleChangedWithSize: function () {
+ var locRenderer = this._labelBMFontRenderer;
+ if (this._ignoreSize)
+ locRenderer.setScale(1.0);
+ else {
+ var textureSize = locRenderer.getContentSize();
+ if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
+ locRenderer.setScale(1.0);
+ return;
+ }
+ locRenderer.setScaleX(this._contentSize.width / textureSize.width);
+ locRenderer.setScaleY(this._contentSize.height / textureSize.height);
+ }
+ locRenderer.setPosition(this._contentSize.width / 2.0, this._contentSize.height / 2.0);
+ },
+
+ /**
+ * Returns the "class name" of ccui.TextBMFont.
+ * @returns {string}
+ */
+ getDescription: function () {
+ return "TextBMFont";
+ },
+
+ _createCloneInstance: function () {
+ return new ccui.TextBMFont();
+ },
+
+ _copySpecialProperties: function (labelBMFont) {
+ this.setFntFile(labelBMFont._fntFileName);
+ this.setString(labelBMFont._stringValue);
+ }
+});
+
+var _p = ccui.TextBMFont.prototype;
+
+// Extended properties
+/** @expose */
+_p.string;
+cc.defineGetterSetter(_p, "string", _p.getString, _p.setString);
+
+_p = null;
+
+/**
+ * allocates and initializes a UILabelBMFont.
+ * @deprecated since v3.0, please use new ccui.TextBMFont() instead.
+ * @return {ccui.TextBMFont}
+ */
+ccui.TextBMFont.create = function (text, filename) {
+ return new ccui.TextBMFont(text, filename);
+};
+
+// Constants
+/**
+ * The zOrder value of TextBMFont's renderer.
+ * @constant
+ * @type {number}
+ */
+ccui.TextBMFont.RENDERER_ZORDER = -1;
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UITextField.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UITextField.js
new file mode 100644
index 0000000..7d59983
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UITextField.js
@@ -0,0 +1,903 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * @ignore
+ */
+//it's a private class, it's a renderer of ccui.TextField.
+ccui._TextFieldRenderer = cc.TextFieldTTF.extend({
+ _maxLengthEnabled: false,
+ _maxLength: 0,
+ _passwordEnabled: false,
+ _passwordStyleText: "",
+ _attachWithIME: false,
+ _detachWithIME: false,
+ _insertText: false,
+ _deleteBackward: false,
+ _className: "_TextFieldRenderer",
+
+ ctor: function () {
+ cc.TextFieldTTF.prototype.ctor.call(this);
+ this._maxLengthEnabled = false;
+ this._maxLength = 0;
+ this._passwordEnabled = false;
+ this._passwordStyleText = "*";
+ this._attachWithIME = false;
+ this._detachWithIME = false;
+ this._insertText = false;
+ this._deleteBackward = false;
+ },
+
+ onEnter: function () {
+ cc.TextFieldTTF.prototype.onEnter.call(this);
+ cc.TextFieldTTF.prototype.setDelegate.call(this, this);
+ },
+
+ onTextFieldAttachWithIME: function (sender) {
+ this.setAttachWithIME(true);
+ return false;
+ },
+
+ onTextFieldInsertText: function (sender, text, len) {
+ if (len === 1 && text === "\n")
+ return false;
+
+ this.setInsertText(true);
+ return (this._maxLengthEnabled) && (cc.TextFieldTTF.prototype.getCharCount.call(this) >= this._maxLength);
+ },
+
+ onTextFieldDeleteBackward: function (sender, delText, nLen) {
+ this.setDeleteBackward(true);
+ return false;
+ },
+
+ onTextFieldDetachWithIME: function (sender) {
+ this.setDetachWithIME(true);
+ return false;
+ },
+
+ insertText: function (text, len) {
+ var input_text = text;
+
+ if (text !== "\n"){
+ if (this._maxLengthEnabled){
+ var text_count = this.getString().length;
+ if (text_count >= this._maxLength){
+ // password
+ if (this._passwordEnabled)
+ this.setPasswordText(this.getString());
+ return;
+ }
+ }
+ }
+ cc.TextFieldTTF.prototype.insertText.call(this, input_text, len);
+
+ // password
+ if (this._passwordEnabled && cc.TextFieldTTF.prototype.getCharCount.call(this) > 0)
+ this.setPasswordText(this.getString());
+ },
+
+ deleteBackward: function () {
+ cc.TextFieldTTF.prototype.deleteBackward.call(this);
+
+ if (cc.TextFieldTTF.prototype.getCharCount.call(this) > 0 && this._passwordEnabled)
+ this.setPasswordText(this._inputText);
+ },
+
+ openIME: function () {
+ cc.TextFieldTTF.prototype.attachWithIME.call(this);
+ },
+
+ closeIME: function () {
+ cc.TextFieldTTF.prototype.detachWithIME.call(this);
+ },
+
+ setMaxLengthEnabled: function (enable) {
+ this._maxLengthEnabled = enable;
+ },
+
+ isMaxLengthEnabled: function () {
+ return this._maxLengthEnabled;
+ },
+
+ setMaxLength: function (length) {
+ this._maxLength = length;
+ },
+
+ getMaxLength: function () {
+ return this._maxLength;
+ },
+
+ getCharCount: function () {
+ return cc.TextFieldTTF.prototype.getCharCount.call(this);
+ },
+
+ setPasswordEnabled: function (enable) {
+ this._passwordEnabled = enable;
+ },
+
+ isPasswordEnabled: function () {
+ return this._passwordEnabled;
+ },
+
+ setPasswordStyleText: function (styleText) {
+ if (styleText.length > 1)
+ return;
+ var header = styleText.charCodeAt(0);
+ if (header < 33 || header > 126)
+ return;
+ this._passwordStyleText = styleText;
+ },
+
+ setPasswordText: function (text) {
+ var tempStr = "";
+ var text_count = text.length;
+ var max = text_count;
+
+ if (this._maxLengthEnabled && text_count > this._maxLength)
+ max = this._maxLength;
+
+ for (var i = 0; i < max; ++i)
+ tempStr += this._passwordStyleText;
+
+ cc.LabelTTF.prototype.setString.call(this, tempStr);
+ },
+
+ setAttachWithIME: function (attach) {
+ this._attachWithIME = attach;
+ },
+
+ getAttachWithIME: function () {
+ return this._attachWithIME;
+ },
+
+ setDetachWithIME: function (detach) {
+ this._detachWithIME = detach;
+ },
+
+ getDetachWithIME: function () {
+ return this._detachWithIME;
+ },
+
+ setInsertText: function (insert) {
+ this._insertText = insert;
+ },
+
+ getInsertText: function () {
+ return this._insertText;
+ },
+
+ setDeleteBackward: function (deleteBackward) {
+ this._deleteBackward = deleteBackward;
+ },
+
+ getDeleteBackward: function () {
+ return this._deleteBackward;
+ },
+
+ onDraw: function (sender) {
+ return false;
+ }
+});
+
+ccui._TextFieldRenderer.create = function (placeholder, fontName, fontSize) {
+ var ret = new ccui._TextFieldRenderer();
+ if (ret && ret.initWithString("", fontName, fontSize)) {
+ if (placeholder)
+ ret.setPlaceHolder(placeholder);
+ return ret;
+ }
+ return null;
+};
+
+/**
+ *
+ * @class
+ * @extends ccui.Widget
+ *
+ * @property {String} string - The content string of the label
+ * @property {String} placeHolder - The place holder of the text field
+ * @property {String} font - The text field font with a style string: e.g. "18px Verdana"
+ * @property {String} fontName - The text field font name
+ * @property {Number} fontSize - The text field font size
+ * @property {Boolean} maxLengthEnabled - Indicate whether max length limit is enabled
+ * @property {Number} maxLength - The max length of the text field
+ * @property {Boolean} passwordEnabled - Indicate whether the text field is for entering password
+ */
+ccui.TextField = ccui.Widget.extend(/** @lends ccui.TextField# */{
+ _textFieldRenderer: null,
+ _touchWidth: 0,
+ _touchHeight: 0,
+ _useTouchArea: false,
+ _textFieldEventListener: null,
+ _textFieldEventSelector: null,
+ _passwordStyleText: "",
+ _textFieldRendererAdaptDirty: true,
+ _fontName: "",
+ _fontSize: 12,
+
+ _ccEventCallback: null,
+
+ /**
+ * allocates and initializes a UITextField.
+ * Constructor of ccui.TextField. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {string} placeholder
+ * @param {string} fontName
+ * @param {Number} fontSize
+ * @example
+ * // example
+ * var uiTextField = new ccui.TextField();
+ */
+ ctor: function (placeholder, fontName, fontSize) {
+ ccui.Widget.prototype.ctor.call(this);
+ this.setTouchEnabled(true);
+ if (fontName)
+ this.setFontName(fontName);
+ if (fontSize)
+ this.setFontSize(fontSize);
+ if (placeholder)
+ this.setPlaceHolder(placeholder);
+ },
+
+ /**
+ * Calls parent class' onEnter and schedules update function.
+ * @override
+ */
+ onEnter: function () {
+ ccui.Widget.prototype.onEnter.call(this);
+ this.scheduleUpdate();
+ },
+
+ _initRenderer: function () {
+ this._textFieldRenderer = ccui._TextFieldRenderer.create("input words here", "Thonburi", 20);
+ this.addProtectedChild(this._textFieldRenderer, ccui.TextField.RENDERER_ZORDER, -1);
+ },
+
+ /**
+ * Sets touch size of ccui.TextField.
+ * @param {cc.Size} size
+ */
+ setTouchSize: function (size) {
+ this._touchWidth = size.width;
+ this._touchHeight = size.height;
+ },
+
+ /**
+ * Sets whether use touch area.
+ * @param enable
+ */
+ setTouchAreaEnabled: function(enable){
+ this._useTouchArea = enable;
+ },
+
+ /**
+ * Checks a point if is in ccui.TextField's space
+ * @param {cc.Point} pt
+ * @returns {boolean}
+ */
+ hitTest: function(pt){
+ if (this._useTouchArea) {
+ var nsp = this.convertToNodeSpace(pt);
+ var bb = cc.rect(
+ -this._touchWidth * this._anchorPoint.x,
+ -this._touchHeight * this._anchorPoint.y,
+ this._touchWidth, this._touchHeight
+ );
+
+ return ( nsp.x >= bb.x && nsp.x <= bb.x + bb.width &&
+ nsp.y >= bb.y && nsp.y <= bb.y + bb.height );
+ } else
+ return ccui.Widget.prototype.hitTest.call(this, pt);
+ },
+
+ /**
+ * Returns touch size of ccui.TextField.
+ * @returns {cc.Size}
+ */
+ getTouchSize: function () {
+ return cc.size(this._touchWidth, this._touchHeight);
+ },
+
+ /**
+ * Changes the string value of textField.
+ * @deprecated since v3.0, please use setString instead.
+ * @param {String} text
+ */
+ setText: function (text) {
+ cc.log("Please use the setString");
+ this.setString(text);
+ },
+
+ /**
+ * Changes the string value of textField.
+ * @param {String} text
+ */
+ setString: function (text) {
+ if (text == null)
+ return;
+
+ text = String(text);
+ if (this.isMaxLengthEnabled())
+ text = text.substr(0, this.getMaxLength());
+ if (this.isPasswordEnabled()) {
+ this._textFieldRenderer.setPasswordText(text);
+ this._textFieldRenderer.setString("");
+ this._textFieldRenderer.insertText(text, text.length);
+ } else
+ this._textFieldRenderer.setString(text);
+ this._textFieldRendererAdaptDirty = true;
+ this._updateContentSizeWithTextureSize(this._textFieldRenderer.getContentSize());
+ },
+
+ /**
+ * Sets the placeholder string.
+ * display this string if string equal "".
+ * @param {String} value
+ */
+ setPlaceHolder: function (value) {
+ this._textFieldRenderer.setPlaceHolder(value);
+ this._textFieldRendererAdaptDirty = true;
+ this._updateContentSizeWithTextureSize(this._textFieldRenderer.getContentSize());
+ },
+
+ /**
+ * Returns the placeholder string.
+ * @returns {String}
+ */
+ getPlaceHolder: function () {
+ return this._textFieldRenderer.getPlaceHolder();
+ },
+
+ /**
+ * Returns the color of ccui.TextField's place holder.
+ * @returns {cc.Color}
+ */
+ getPlaceHolderColor: function(){
+ return this._textFieldRenderer.getPlaceHolderColor();
+ },
+
+ /**
+ * Sets the place holder color to ccui.TextField.
+ * @param color
+ */
+ setPlaceHolderColor: function(color){
+ this._textFieldRenderer.setColorSpaceHolder(color);
+ },
+
+ /**
+ * Sets the text color to ccui.TextField
+ * @param textColor
+ */
+ setTextColor: function(textColor){
+ this._textFieldRenderer.setTextColor(textColor);
+ },
+
+ /**
+ * Sets font size for ccui.TextField.
+ * @param {Number} size
+ */
+ setFontSize: function (size) {
+ this._textFieldRenderer.setFontSize(size);
+ this._fontSize = size;
+ this._textFieldRendererAdaptDirty = true;
+ this._updateContentSizeWithTextureSize(this._textFieldRenderer.getContentSize());
+ },
+
+ /**
+ * Gets font size of ccui.TextField.
+ * @return {Number} size
+ */
+ getFontSize: function () {
+ return this._fontSize;
+ },
+
+ /**
+ * Sets font name for ccui.TextField
+ * @param {String} name
+ */
+ setFontName: function (name) {
+ this._textFieldRenderer.setFontName(name);
+ this._fontName = name;
+ this._textFieldRendererAdaptDirty = true;
+ this._updateContentSizeWithTextureSize(this._textFieldRenderer.getContentSize());
+ },
+
+ /**
+ * Returns font name of ccui.TextField.
+ * @return {String} font name
+ */
+ getFontName: function () {
+ return this._fontName;
+ },
+
+ /**
+ * detach with IME
+ */
+ didNotSelectSelf: function () {
+ this._textFieldRenderer.detachWithIME();
+ },
+
+ /**
+ * Returns textField string value
+ * @deprecated since v3.0, please use getString instead.
+ * @returns {String}
+ */
+ getStringValue: function () {
+ cc.log("Please use the getString");
+ return this.getString();
+ },
+
+ /**
+ * Returns string value of ccui.TextField.
+ * @returns {String}
+ */
+ getString: function () {
+ return this._textFieldRenderer.getString();
+ },
+
+ /**
+ * Returns the length of ccui.TextField.
+ * @returns {Number}
+ */
+ getStringLength: function(){
+ return this._textFieldRenderer.getStringLength();
+ },
+
+ /**
+ * The touch began event callback handler.
+ * @param {cc.Point} touchPoint
+ */
+ onTouchBegan: function (touchPoint, unusedEvent) {
+ var self = this;
+ var pass = ccui.Widget.prototype.onTouchBegan.call(self, touchPoint, unusedEvent);
+ if (self._hit) {
+ setTimeout(function(){
+ self._textFieldRenderer.attachWithIME();
+ }, 0);
+ }else{
+ setTimeout(function(){
+ self._textFieldRenderer.detachWithIME();
+ }, 0);
+ }
+ return pass;
+ },
+
+ /**
+ * Sets Whether to open string length limit for ccui.TextField.
+ * @param {Boolean} enable
+ */
+ setMaxLengthEnabled: function (enable) {
+ this._textFieldRenderer.setMaxLengthEnabled(enable);
+ },
+
+ /**
+ * Returns Whether to open string length limit.
+ * @returns {Boolean}
+ */
+ isMaxLengthEnabled: function () {
+ return this._textFieldRenderer.isMaxLengthEnabled();
+ },
+
+ /**
+ * Sets the max length of ccui.TextField. Only when you turn on the string length limit, it is valid.
+ * @param {number} length
+ */
+ setMaxLength: function (length) {
+ this._textFieldRenderer.setMaxLength(length);
+ this.setString(this.getString());
+ },
+
+ /**
+ * Returns the max length of ccui.TextField.
+ * @returns {number} length
+ */
+ getMaxLength: function () {
+ return this._textFieldRenderer.getMaxLength();
+ },
+
+ /**
+ * Sets whether to open setting string as password character.
+ * @param {Boolean} enable
+ */
+ setPasswordEnabled: function (enable) {
+ this._textFieldRenderer.setPasswordEnabled(enable);
+ },
+
+ /**
+ * Returns whether to open setting string as password character.
+ * @returns {Boolean}
+ */
+ isPasswordEnabled: function () {
+ return this._textFieldRenderer.isPasswordEnabled();
+ },
+
+ /**
+ * Sets the password style character, Only when you turn on setting string as password character, it is valid.
+ * @param styleText
+ */
+ setPasswordStyleText: function(styleText){
+ this._textFieldRenderer.setPasswordStyleText(styleText);
+ this._passwordStyleText = styleText;
+
+ this.setString(this.getString());
+ },
+
+ /**
+ * Returns the password style character.
+ * @returns {String}
+ */
+ getPasswordStyleText: function () {
+ return this._passwordStyleText;
+ },
+
+ update: function (dt) {
+ if (this.getDetachWithIME()) {
+ this._detachWithIMEEvent();
+ this.setDetachWithIME(false);
+ }
+ if (this.getAttachWithIME()) {
+ this._attachWithIMEEvent();
+ this.setAttachWithIME(false);
+ }
+ if (this.getInsertText()) {
+ this._textFieldRendererAdaptDirty = true;
+ this._updateContentSizeWithTextureSize(this._textFieldRenderer.getContentSize());
+
+ this._insertTextEvent();
+ this.setInsertText(false);
+ }
+ if (this.getDeleteBackward()) {
+ this._textFieldRendererAdaptDirty = true;
+ this._updateContentSizeWithTextureSize(this._textFieldRenderer.getContentSize());
+
+ this._deleteBackwardEvent();
+ this.setDeleteBackward(false);
+ }
+ },
+
+ /**
+ * Returns whether attach with IME.
+ * @returns {Boolean}
+ */
+ getAttachWithIME: function () {
+ return this._textFieldRenderer.getAttachWithIME();
+ },
+
+ /**
+ * Sets attach with IME.
+ * @param {Boolean} attach
+ */
+ setAttachWithIME: function (attach) {
+ this._textFieldRenderer.setAttachWithIME(attach);
+ },
+
+ /**
+ * Returns whether detach with IME.
+ * @returns {Boolean}
+ */
+ getDetachWithIME: function () {
+ return this._textFieldRenderer.getDetachWithIME();
+ },
+
+ /**
+ * Sets detach with IME.
+ * @param {Boolean} detach
+ */
+ setDetachWithIME: function (detach) {
+ this._textFieldRenderer.setDetachWithIME(detach);
+ },
+
+ /**
+ * Returns insertText string of ccui.TextField.
+ * @returns {String}
+ */
+ getInsertText: function () {
+ return this._textFieldRenderer.getInsertText();
+ },
+
+ /**
+ * Sets insertText string to ccui.TextField.
+ * @param {String} insertText
+ */
+ setInsertText: function (insertText) {
+ this._textFieldRenderer.setInsertText(insertText);
+ },
+
+ /**
+ * Returns the delete backward of ccui.TextField.
+ * @returns {Boolean}
+ */
+ getDeleteBackward: function () {
+ return this._textFieldRenderer.getDeleteBackward();
+ },
+
+ /**
+ * Sets the delete backward of ccui.TextField.
+ * @param {Boolean} deleteBackward
+ */
+ setDeleteBackward: function (deleteBackward) {
+ this._textFieldRenderer.setDeleteBackward(deleteBackward);
+ },
+
+ _attachWithIMEEvent: function () {
+ if(this._textFieldEventSelector){
+ if (this._textFieldEventListener)
+ this._textFieldEventSelector.call(this._textFieldEventListener, this, ccui.TextField.EVENT_ATTACH_WITH_IME);
+ else
+ this._textFieldEventSelector(this, ccui.TextField.EVENT_ATTACH_WITH_IME);
+ }
+ if (this._ccEventCallback){
+ this._ccEventCallback(this, ccui.TextField.EVENT_ATTACH_WITH_IME);
+ }
+ },
+
+ _detachWithIMEEvent: function () {
+ if(this._textFieldEventSelector){
+ if (this._textFieldEventListener)
+ this._textFieldEventSelector.call(this._textFieldEventListener, this, ccui.TextField.EVENT_DETACH_WITH_IME);
+ else
+ this._textFieldEventSelector(this, ccui.TextField.EVENT_DETACH_WITH_IME);
+ }
+ if (this._ccEventCallback)
+ this._ccEventCallback(this, ccui.TextField.EVENT_DETACH_WITH_IME);
+ },
+
+ _insertTextEvent: function () {
+ if(this._textFieldEventSelector){
+ if (this._textFieldEventListener)
+ this._textFieldEventSelector.call(this._textFieldEventListener, this, ccui.TextField.EVENT_INSERT_TEXT);
+ else
+ this._textFieldEventSelector(this, ccui.TextField.EVENT_INSERT_TEXT); //eventCallback
+ }
+ if (this._ccEventCallback)
+ this._ccEventCallback(this, ccui.TextField.EVENT_INSERT_TEXT);
+ },
+
+ _deleteBackwardEvent: function () {
+ if(this._textFieldEventSelector){
+ if (this._textFieldEventListener)
+ this._textFieldEventSelector.call(this._textFieldEventListener, this, ccui.TextField.EVENT_DELETE_BACKWARD);
+ else
+ this._textFieldEventSelector(this, ccui.TextField.EVENT_DELETE_BACKWARD); //eventCallback
+ }
+ if (this._ccEventCallback)
+ this._ccEventCallback(this, ccui.TextField.EVENT_DELETE_BACKWARD);
+ },
+
+ /**
+ * Adds event listener to cuci.TextField.
+ * @param {Object} [target=]
+ * @param {Function} selector
+ * @deprecated since v3.0, please use addEventListener instead.
+ */
+ addEventListenerTextField: function (selector, target) {
+ this.addEventListener(selector, target);
+ },
+
+ /**
+ * Adds event listener callback.
+ * @param {Object} [target=]
+ * @param {Function} selector
+ */
+ addEventListener: function(selector, target){
+ this._textFieldEventSelector = selector; //when target is undefined, _textFieldEventSelector is ccEventCallback.
+ this._textFieldEventListener = target;
+ },
+
+ _onSizeChanged: function () {
+ ccui.Widget.prototype._onSizeChanged.call(this);
+ this._textFieldRendererAdaptDirty = true;
+ },
+
+ _adaptRenderers: function(){
+ if (this._textFieldRendererAdaptDirty) {
+ this._textfieldRendererScaleChangedWithSize();
+ this._textFieldRendererAdaptDirty = false;
+ }
+ },
+
+ _textfieldRendererScaleChangedWithSize: function () {
+ if (!this._ignoreSize)
+ this._textFieldRenderer.setDimensions(this._contentSize);
+ this._textFieldRenderer.setPosition(this._contentSize.width / 2, this._contentSize.height / 2);
+ },
+
+ //@since v3.3
+ getAutoRenderSize: function(){
+ var virtualSize = this._textFieldRenderer.getContentSize();
+ if (!this._ignoreSize) {
+ this._textFieldRenderer.setDimensions(0, 0);
+ virtualSize = this._textFieldRenderer.getContentSize();
+ this._textFieldRenderer.setDimensions(this._contentSize.width, this._contentSize.height);
+ }
+ return virtualSize;
+ },
+
+ /**
+ * Returns the ccui.TextField's content size.
+ * @returns {cc.Size}
+ */
+ getVirtualRendererSize: function(){
+ return this._textFieldRenderer.getContentSize();
+ },
+
+ /**
+ * Returns the renderer of ccui.TextField.
+ * @returns {cc.Node}
+ */
+ getVirtualRenderer: function () {
+ return this._textFieldRenderer;
+ },
+
+ /**
+ * Returns the "class name" of ccui.TextField.
+ * @returns {string}
+ */
+ getDescription: function () {
+ return "TextField";
+ },
+
+ /**
+ * Open keyboard and receive input text.
+ * @return {Boolean}
+ */
+ attachWithIME: function () {
+ this._textFieldRenderer.attachWithIME();
+ },
+
+ _createCloneInstance: function () {
+ return new ccui.TextField();
+ },
+
+ _copySpecialProperties: function (textField) {
+ this.setString(textField._textFieldRenderer.getString());
+ this.setPlaceHolder(textField.getString());
+ this.setFontSize(textField._textFieldRenderer.getFontSize());
+ this.setFontName(textField._textFieldRenderer.getFontName());
+ this.setMaxLengthEnabled(textField.isMaxLengthEnabled());
+ this.setMaxLength(textField.getMaxLength());
+ this.setPasswordEnabled(textField.isPasswordEnabled());
+ this.setPasswordStyleText(textField._passwordStyleText);
+ this.setAttachWithIME(textField.getAttachWithIME());
+ this.setDetachWithIME(textField.getDetachWithIME());
+ this.setInsertText(textField.getInsertText());
+ this.setDeleteBackward(textField.getDeleteBackward());
+ this._ccEventCallback = textField._ccEventCallback;
+ this._textFieldEventListener = textField._textFieldEventListener;
+ this._textFieldEventSelector = textField._textFieldEventSelector;
+ },
+
+ /**
+ * Sets the text area size to ccui.TextField.
+ * @param {cc.Size} size
+ */
+ setTextAreaSize: function(size){
+ this.setContentSize(size);
+ },
+
+ /**
+ * Sets the text horizontal alignment of ccui.TextField.
+ * @param alignment
+ */
+ setTextHorizontalAlignment: function(alignment){
+ this._textFieldRenderer.setHorizontalAlignment(alignment);
+ },
+
+ /**
+ * Sets the text vertical alignment of ccui.TextField.
+ * @param alignment
+ */
+ setTextVerticalAlignment: function(alignment){
+ this._textFieldRenderer.setVerticalAlignment(alignment);
+ },
+ _setFont: function (font) {
+ this._textFieldRenderer._setFont(font);
+ this._textFieldRendererAdaptDirty = true;
+ },
+
+ _getFont: function () {
+ return this._textFieldRenderer._getFont();
+ },
+
+ _changePosition: function(){
+ this._adaptRenderers();
+ }
+});
+
+/**
+ * Creates a ccui.TextField.
+ * @deprecated since v3.0, please use new ccui.TextField() instead.
+ * @param {String} placeholder
+ * @param {String} fontName
+ * @param {Number} fontSize
+ * @returns {ccui.TextField}
+ */
+ccui.TextField.create = function(placeholder, fontName, fontSize){
+ return new ccui.TextField(placeholder, fontName, fontSize);
+};
+
+var _p = ccui.TextField.prototype;
+
+// Extended properties
+/** @expose */
+_p.string;
+cc.defineGetterSetter(_p, "string", _p.getString, _p.setString);
+/** @expose */
+_p.placeHolder;
+cc.defineGetterSetter(_p, "placeHolder", _p.getPlaceHolder, _p.setPlaceHolder);
+/** @expose */
+_p.font;
+cc.defineGetterSetter(_p, "font", _p._getFont, _p._setFont);
+/** @expose */
+_p.fontSize;
+cc.defineGetterSetter(_p, "fontSize", _p.getFontSize, _p.setFontSize);
+/** @expose */
+_p.fontName;
+cc.defineGetterSetter(_p, "fontName", _p.getFontName, _p.setFontName);
+/** @expose */
+_p.maxLengthEnabled;
+cc.defineGetterSetter(_p, "maxLengthEnabled", _p.isMaxLengthEnabled, _p.setMaxLengthEnabled);
+/** @expose */
+_p.maxLength;
+cc.defineGetterSetter(_p, "maxLength", _p.getMaxLength, _p.setMaxLength);
+/** @expose */
+_p.passwordEnabled;
+cc.defineGetterSetter(_p, "passwordEnabled", _p.isPasswordEnabled, _p.setPasswordEnabled);
+
+_p = null;
+
+// Constants
+//TextField event
+/**
+ * The attach with IME event flag of ccui.TextField
+ * @constant
+ * @type {number}
+ */
+ccui.TextField.EVENT_ATTACH_WITH_IME = 0;
+/**
+ * The detach with IME event flag of ccui.TextField
+ * @constant
+ * @type {number}
+ */
+ccui.TextField.EVENT_DETACH_WITH_IME = 1;
+/**
+ * The insert text event flag of ccui.TextField
+ * @constant
+ * @type {number}
+ */
+ccui.TextField.EVENT_INSERT_TEXT = 2;
+/**
+ * The delete backward event flag of ccui.TextField
+ * @constant
+ * @type {number}
+ */
+ccui.TextField.EVENT_DELETE_BACKWARD = 3;
+
+/**
+ * The zOrder value of ccui.TextField's renderer.
+ * @constant
+ * @type {number}
+ */
+ccui.TextField.RENDERER_ZORDER = -1;
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIVideoPlayer.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIVideoPlayer.js
new file mode 100644
index 0000000..e4e3351
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIVideoPlayer.js
@@ -0,0 +1,562 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * @class
+ * @extends ccui.Widget
+ * @brief Displays a video file.
+ *
+ * @note VideoPlayer displays a video file based on DOM element
+ * VideoPlayer will be rendered above all other graphical elements.
+ *
+ * @property {String} path - The video path
+ */
+ccui.VideoPlayer = ccui.Widget.extend(/** @lends ccui.VideoPlayer# */{
+
+ _played: false,
+ _playing: false,
+ _stopped: true,
+
+ ctor: function (path) {
+ ccui.Widget.prototype.ctor.call(this);
+ this._EventList = {};
+ if (path)
+ this.setURL(path);
+ },
+
+ _createRenderCmd: function () {
+ return new ccui.VideoPlayer.RenderCmd(this);
+ },
+
+ visit: function () {
+ var cmd = this._renderCmd,
+ div = cmd._div,
+ container = cc.container,
+ eventManager = cc.eventManager;
+ if (this._visible) {
+ container.appendChild(cmd._video);
+ if (this._listener === null)
+ this._listener = cc.eventManager.addCustomListener(cc.game.EVENT_RESIZE, function () {
+ cmd.resize();
+ });
+ } else {
+ var hasChild = false;
+ if ('contains' in container) {
+ hasChild = container.contains(cmd._video);
+ } else {
+ hasChild = container.compareDocumentPosition(cmd._video) % 16;
+ }
+ if (hasChild)
+ container.removeChild(cmd._video);
+ eventManager.removeListener(cmd._listener);
+ cmd._listener = null;
+ }
+ cmd.updateStatus();
+ cmd.resize();
+ },
+
+ /**
+ * Set the video address
+ * Automatically replace extname
+ * All supported video formats will be added to the video
+ * @param {String} address
+ */
+ setURL: function (address) {
+ this._renderCmd.updateURL(address);
+ },
+
+ /**
+ * Get the video path
+ * @returns {String}
+ */
+ getURL: function () {
+ return this._renderCmd._url;
+ },
+
+ /**
+ * Play the video
+ */
+ play: function () {
+ var self = this,
+ video = this._renderCmd._video;
+ if (video) {
+ this._played = true;
+ video.pause();
+ if (this._stopped !== false || this._playing !== false || this._played !== true)
+ video.currentTime = 0;
+ if (ccui.VideoPlayer._polyfill.autoplayAfterOperation) {
+ setTimeout(function () {
+ video.play();
+ self._playing = true;
+ self._stopped = false;
+ }, 20);
+ } else {
+ video.play();
+ this._playing = true;
+ this._stopped = false;
+ }
+ }
+ },
+
+ /**
+ * Pause the video
+ */
+ pause: function () {
+ var video = this._renderCmd._video;
+ if (video && this._playing === true && this._stopped === false) {
+ video.pause();
+ this._playing = false;
+ }
+ },
+
+ /**
+ * Resume the video
+ */
+ resume: function () {
+ if (this._stopped === false && this._playing === false && this._played === true) {
+ this.play();
+ }
+ },
+
+ /**
+ * Stop the video
+ */
+ stop: function () {
+ var self = this,
+ video = this._renderCmd._video;
+ if (video) {
+ video.pause();
+ video.currentTime = 0;
+ this._playing = false;
+ this._stopped = true;
+ }
+
+ setTimeout(function () {
+ self._dispatchEvent(ccui.VideoPlayer.EventType.STOPPED);
+ }, 0);
+ },
+ /**
+ * Jump to the specified point in time
+ * @param {Number} sec
+ */
+ seekTo: function (sec) {
+ var video = this._renderCmd._video;
+ if (video) {
+ video.currentTime = sec;
+ if (ccui.VideoPlayer._polyfill.autoplayAfterOperation && this.isPlaying()) {
+ setTimeout(function () {
+ video.play();
+ }, 20);
+ }
+ }
+ },
+
+ /**
+ * Whether the video is playing
+ * @returns {boolean}
+ */
+ isPlaying: function () {
+ if (ccui.VideoPlayer._polyfill.autoplayAfterOperation && this._playing) {
+ setTimeout(function () {
+ video.play();
+ }, 20);
+ }
+ return this._playing;
+ },
+
+ /**
+ * Whether to keep the aspect ratio
+ */
+ setKeepAspectRatioEnabled: function (enable) {
+ cc.log("On the web is always keep the aspect ratio");
+ },
+ isKeepAspectRatioEnabled: function () {
+ return false;
+ },
+
+ /**
+ * Set whether the full screen
+ * May appear inconsistent in different browsers
+ * @param {boolean} enable
+ */
+ setFullScreenEnabled: function (enable) {
+ var video = this._renderCmd._video;
+ if (video) {
+ if (enable)
+ cc.screen.requestFullScreen(video);
+ else
+ cc.screen.exitFullScreen(video);
+ }
+ },
+
+ /**
+ * Determine whether already full screen
+ */
+ isFullScreenEnabled: function () {
+ cc.log("Can't know status");
+ },
+
+ /**
+ * The binding event
+ * @param {ccui.VideoPlayer.EventType} event
+ * @param {Function} callback
+ */
+ setEventListener: function (event, callback) {
+ this._EventList[event] = callback;
+ },
+
+ /**
+ * Delete events
+ * @param {ccui.VideoPlayer.EventType} event
+ */
+ removeEventListener: function (event) {
+ this._EventList[event] = null;
+ },
+
+ _dispatchEvent: function (event) {
+ var callback = this._EventList[event];
+ if (callback)
+ callback.call(this, this, this._renderCmd._video.src);
+ },
+
+ /**
+ * Trigger playing events
+ */
+ onPlayEvent: function () {
+ var list = this._EventList[ccui.VideoPlayer.EventType.PLAYING];
+ if (list)
+ for (var i = 0; i < list.length; i++)
+ list[i].call(this, this, this._renderCmd._video.src);
+ },
+
+ setContentSize: function (w, h) {
+ ccui.Widget.prototype.setContentSize.call(this, w, h);
+ if (h === undefined) {
+ h = w.height;
+ w = w.width;
+ }
+ this._renderCmd.changeSize(w, h);
+ },
+
+ cleanup: function () {
+ this._renderCmd.removeDom();
+ this.stopAllActions();
+ this.unscheduleAllCallbacks();
+ },
+
+ onEnter: function () {
+ ccui.Widget.prototype.onEnter.call(this);
+ var list = ccui.VideoPlayer.elements;
+ if (list.indexOf(this) === -1)
+ list.push(this);
+ },
+
+ onExit: function () {
+ ccui.Widget.prototype.onExit.call(this);
+ var list = ccui.VideoPlayer.elements;
+ var index = list.indexOf(this);
+ if (index !== -1)
+ list.splice(index, 1);
+ }
+
+});
+
+// VideoHTMLElement list
+ccui.VideoPlayer.elements = [];
+ccui.VideoPlayer.pauseElements = [];
+
+cc.eventManager.addCustomListener(cc.game.EVENT_HIDE, function () {
+ var list = ccui.VideoPlayer.elements;
+ for (var node, i = 0; i < list.length; i++) {
+ node = list[i];
+ if (list[i]._playing) {
+ node.pause();
+ ccui.VideoPlayer.pauseElements.push(node);
+ }
+ }
+});
+cc.eventManager.addCustomListener(cc.game.EVENT_SHOW, function () {
+ var list = ccui.VideoPlayer.pauseElements;
+ var node = list.pop();
+ while (node) {
+ node.play();
+ node = list.pop();
+ }
+});
+
+/**
+ * The VideoPlayer support list of events
+ * @type {{PLAYING: string, PAUSED: string, STOPPED: string, COMPLETED: string}}
+ */
+ccui.VideoPlayer.EventType = {
+ PLAYING: "play",
+ PAUSED: "pause",
+ STOPPED: "stop",
+ COMPLETED: "complete"
+};
+
+(function (video) {
+ /**
+ * Adapter various machines
+ * @devicePixelRatio Whether you need to consider devicePixelRatio calculated position
+ * @event To get the data using events
+ */
+ video._polyfill = {
+ devicePixelRatio: false,
+ event: "canplay",
+ canPlayType: []
+ };
+
+ (function () {
+ /**
+ * Some old browser only supports Theora encode video
+ * But native does not support this encode,
+ * so it is best to provide mp4 and webm or ogv file
+ */
+ var dom = document.createElement("video");
+ if (dom.canPlayType("video/ogg")) {
+ video._polyfill.canPlayType.push(".ogg");
+ video._polyfill.canPlayType.push(".ogv");
+ }
+ if (dom.canPlayType("video/mp4"))
+ video._polyfill.canPlayType.push(".mp4");
+ if (dom.canPlayType("video/webm"))
+ video._polyfill.canPlayType.push(".webm");
+ })();
+
+ if (cc.sys.OS_IOS === cc.sys.os) {
+ video._polyfill.devicePixelRatio = true;
+ video._polyfill.event = "progress";
+ }
+ if (cc.sys.browserType === cc.sys.BROWSER_TYPE_FIREFOX) {
+ video._polyfill.autoplayAfterOperation = true;
+ }
+
+ var style = document.createElement("style");
+ style.innerHTML = ".cocosVideo:-moz-full-screen{transform:matrix(1,0,0,1,0,0) !important;}" +
+ ".cocosVideo:full-screen{transform:matrix(1,0,0,1,0,0) !important;}" +
+ ".cocosVideo:-webkit-full-screen{transform:matrix(1,0,0,1,0,0) !important;}";
+ document.head.appendChild(style);
+
+})(ccui.VideoPlayer);
+
+(function (polyfill) {
+
+ var RenderCmd = null;
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ RenderCmd = cc.Node.WebGLRenderCmd;
+ } else {
+ RenderCmd = cc.Node.CanvasRenderCmd;
+ }
+
+ ccui.VideoPlayer.RenderCmd = function (node) {
+ this._rootCtor(node);
+ this._listener = null;
+ this._url = "";
+ this.initStyle();
+ };
+
+ var proto = ccui.VideoPlayer.RenderCmd.prototype = Object.create(RenderCmd.prototype);
+ proto.constructor = ccui.VideoPlayer.RenderCmd;
+
+ proto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
+ this.updateMatrix(this._worldTransform, cc.view._scaleX, cc.view._scaleY);
+ };
+
+ proto.updateStatus = function () {
+ polyfill.devicePixelRatio = cc.view.isRetinaEnabled();
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ if (locFlag & flags.transformDirty) {
+ //update the transform
+ this.transform(this.getParentRenderCmd(), true);
+ this.updateMatrix(this._worldTransform, cc.view._scaleX, cc.view._scaleY);
+ this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.transformDirty ^ this._dirtyFlag;
+ }
+
+ if (locFlag & flags.orderDirty) {
+ this._dirtyFlag = this._dirtyFlag & flags.orderDirty ^ this._dirtyFlag;
+ }
+ };
+
+ proto.resize = function (view) {
+ view = view || cc.view;
+ var node = this._node,
+ eventManager = cc.eventManager;
+ if (node._parent && node._visible)
+ this.updateMatrix(this._worldTransform, view._scaleX, view._scaleY);
+ else {
+ eventManager.removeListener(this._listener);
+ this._listener = null;
+ }
+ };
+
+ proto.updateMatrix = function (t, scaleX, scaleY) {
+ var node = this._node;
+ if (polyfill.devicePixelRatio) {
+ var dpr = cc.view.getDevicePixelRatio();
+ scaleX = scaleX / dpr;
+ scaleY = scaleY / dpr;
+ }
+ if (this._loaded === false) return;
+ var containerStyle = cc.game.container.style,
+ offsetX = parseInt(containerStyle.paddingLeft),
+ offsetY = parseInt(containerStyle.paddingBottom),
+ cw = node._contentSize.width,
+ ch = node._contentSize.height;
+ var a = t.a * scaleX,
+ b = t.b,
+ c = t.c,
+ d = t.d * scaleY,
+ tx = offsetX + t.tx * scaleX - cw / 2 + cw * node._scaleX / 2 * scaleX,
+ ty = offsetY + t.ty * scaleY - ch / 2 + ch * node._scaleY / 2 * scaleY;
+ var matrix = "matrix(" + a + "," + b + "," + c + "," + d + "," + tx + "," + -ty + ")";
+ this._video.style["transform"] = matrix;
+ this._video.style["-webkit-transform"] = matrix;
+ };
+
+ proto.updateURL = function (path) {
+ var source, video, hasChild, container, extname;
+ var node = this._node;
+
+ if (this._url == path)
+ return;
+
+ this._url = path;
+
+ if (cc.loader.resPath && !/^http/.test(path))
+ path = cc.path.join(cc.loader.resPath, path);
+
+ hasChild = false;
+ container = cc.container;
+ if ('contains' in container) {
+ hasChild = container.contains(this._video);
+ } else {
+ hasChild = container.compareDocumentPosition(this._video) % 16;
+ }
+ if (hasChild)
+ container.removeChild(this._video);
+
+ this._video = document.createElement("video");
+ video = this._video;
+ this.bindEvent();
+ var self = this;
+
+ var cb = function () {
+ if (self._loaded == true)
+ return;
+ self._loaded = true;
+ self.changeSize();
+ self.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ video.removeEventListener(polyfill.event, cb);
+ video.currentTime = 0;
+ video.style["visibility"] = "visible";
+ //IOS does not display video images
+ video.play();
+ if (!node._played) {
+ video.pause();
+ video.currentTime = 0;
+ }
+ };
+ video.addEventListener(polyfill.event, cb);
+
+ //video.controls = "controls";
+ video.preload = "metadata";
+ video.style["visibility"] = "hidden";
+ this._loaded = false;
+ node._played = false;
+ node._playing = false;
+ node._stopped = true;
+ this.initStyle();
+ this._node.visit();
+
+ source = document.createElement("source");
+ source.src = path;
+ video.appendChild(source);
+
+ extname = cc.path.extname(path);
+ for (var i = 0; i < polyfill.canPlayType.length; i++) {
+ if (extname !== polyfill.canPlayType[i]) {
+ source = document.createElement("source");
+ source.src = path.replace(extname, polyfill.canPlayType[i]);
+ video.appendChild(source);
+ }
+ }
+ };
+
+ proto.bindEvent = function () {
+ var self = this,
+ node = this._node,
+ video = this._video;
+ //binding event
+ video.addEventListener("ended", function () {
+ node._renderCmd.updateMatrix(self._worldTransform, cc.view._scaleX, cc.view._scaleY);
+ node._playing = false;
+ node._dispatchEvent(ccui.VideoPlayer.EventType.COMPLETED);
+ });
+ video.addEventListener("play", function () {
+ node._dispatchEvent(ccui.VideoPlayer.EventType.PLAYING);
+ });
+ video.addEventListener("pause", function () {
+ node._dispatchEvent(ccui.VideoPlayer.EventType.PAUSED);
+ });
+ };
+
+ proto.initStyle = function () {
+ if (!this._video) return;
+ var video = this._video;
+ video.style.position = "absolute";
+ video.style.bottom = "0px";
+ video.style.left = "0px";
+ video.className = "cocosVideo";
+ };
+
+ proto.changeSize = function (w, h) {
+ var contentSize = this._node._contentSize;
+ w = w || contentSize.width;
+ h = h || contentSize.height;
+ var video = this._video;
+ if (video) {
+ if (w !== 0)
+ video.width = w;
+ if (h !== 0)
+ video.height = h;
+ }
+ };
+
+ proto.removeDom = function () {
+ var video = this._video;
+ if (video) {
+ var hasChild = false;
+ if ('contains' in cc.container) {
+ hasChild = cc.container.contains(video);
+ } else {
+ hasChild = cc.container.compareDocumentPosition(video) % 16;
+ }
+ if (hasChild)
+ cc.container.removeChild(video);
+ }
+ };
+
+})(ccui.VideoPlayer._polyfill);
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIWebView.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIWebView.js
new file mode 100644
index 0000000..b301a95
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/UIWebView.js
@@ -0,0 +1,423 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * @class
+ * @extends ccui.Widget
+ * @brief A View that displays web pages.
+ *
+ * @note WebView displays web pages based on DOM element
+ * WebView will be rendered above all other graphical elements.
+ *
+ * @property {String} path - The url to be shown in the web view
+ */
+ccui.WebView = ccui.Widget.extend(/** @lends ccui.WebView# */{
+
+ ctor: function (path) {
+ ccui.Widget.prototype.ctor.call(this);
+ this._EventList = {};
+ if (path)
+ this.loadURL(path);
+ },
+
+ visit: function () {
+ var cmd = this._renderCmd,
+ div = cmd._div,
+ container = cc.container,
+ eventManager = cc.eventManager;
+ if (this._visible) {
+ container.appendChild(div);
+ if (this._listener === null)
+ this._listener = eventManager.addCustomListener(cc.game.EVENT_RESIZE, function () {
+ cmd.resize();
+ });
+ } else {
+ var hasChild = false;
+ if ('contains' in container) {
+ hasChild = container.contains(div);
+ } else {
+ hasChild = container.compareDocumentPosition(div) % 16;
+ }
+ if (hasChild)
+ container.removeChild(div);
+ var list = eventManager._listenersMap[cc.game.EVENT_RESIZE].getFixedPriorityListeners();
+ eventManager._removeListenerInVector(list, cmd._listener);
+ cmd._listener = null;
+ }
+ cmd.updateStatus();
+ cmd.resize(cc.view);
+ },
+
+ setJavascriptInterfaceScheme: function (scheme) {
+ },
+ loadData: function (data, MIMEType, encoding, baseURL) {
+ },
+ loadHTMLString: function (string, baseURL) {
+ },
+
+
+ /**
+ * Load an URL
+ * @param {String} url
+ */
+ loadURL: function (url) {
+ this._renderCmd.updateURL(url);
+ this._dispatchEvent(ccui.WebView.EventType.LOADING);
+ },
+
+ /**
+ * Stop loading
+ */
+ stopLoading: function () {
+ cc.log("Web does not support loading");
+ },
+
+ /**
+ * Reload the WebView
+ */
+ reload: function () {
+ var iframe = this._renderCmd._iframe;
+ if (iframe) {
+ var win = iframe.contentWindow;
+ if (win && win.location)
+ win.location.reload();
+ }
+ },
+
+ /**
+ * Determine whether to go back
+ */
+ canGoBack: function () {
+ cc.log("Web does not support query history");
+ return true;
+ },
+
+ /**
+ * Determine whether to go forward
+ */
+ canGoForward: function () {
+ cc.log("Web does not support query history");
+ return true;
+ },
+
+ /**
+ * go back
+ */
+ goBack: function () {
+ try {
+ if (ccui.WebView._polyfill.closeHistory)
+ return cc.log("The current browser does not support the GoBack");
+ var iframe = this._renderCmd._iframe;
+ if (iframe) {
+ var win = iframe.contentWindow;
+ if (win && win.location)
+ try {
+ win.history.back.call(win);
+ } catch (error) {
+ win.history.back();
+ }
+ }
+ } catch (err) {
+ cc.log(err);
+ }
+ },
+
+ /**
+ * go forward
+ */
+ goForward: function () {
+ try {
+ if (ccui.WebView._polyfill.closeHistory)
+ return cc.log("The current browser does not support the GoForward");
+ var iframe = this._renderCmd._iframe;
+ if (iframe) {
+ var win = iframe.contentWindow;
+ if (win && win.location)
+ try {
+ win.history.forward.call(win);
+ } catch (error) {
+ win.history.forward();
+ }
+ }
+ } catch (err) {
+ cc.log(err);
+ }
+ },
+
+ /**
+ * In the webview execution within a period of js string
+ * @param {String} str
+ */
+ evaluateJS: function (str) {
+ var iframe = this._renderCmd._iframe;
+ if (iframe) {
+ var win = iframe.contentWindow;
+ try {
+ win.eval(str);
+ this._dispatchEvent(ccui.WebView.EventType.JS_EVALUATED);
+ } catch (err) {
+ console.error(err);
+ }
+ }
+ },
+
+ /**
+ * Limited scale
+ */
+ setScalesPageToFit: function () {
+ cc.log("Web does not support zoom");
+ },
+
+ /**
+ * The binding event
+ * @param {ccui.WebView.EventType} event
+ * @param {Function} callback
+ */
+ setEventListener: function (event, callback) {
+ this._EventList[event] = callback;
+ },
+
+ /**
+ * Delete events
+ * @param {ccui.WebView.EventType} event
+ */
+ removeEventListener: function (event) {
+ this._EventList[event] = null;
+ },
+
+ _dispatchEvent: function (event) {
+ var callback = this._EventList[event];
+ if (callback)
+ callback.call(this, this, this._renderCmd._iframe.src);
+ },
+
+ _createRenderCmd: function () {
+ return new ccui.WebView.RenderCmd(this);
+ },
+
+ /**
+ * Set the contentSize
+ * @param {Number} w
+ * @param {Number} h
+ */
+ setContentSize: function (w, h) {
+ ccui.Widget.prototype.setContentSize.call(this, w, h);
+ if (h === undefined) {
+ h = w.height;
+ w = w.width;
+ }
+ this._renderCmd.changeSize(w, h);
+ },
+
+ /**
+ * remove node
+ */
+ cleanup: function () {
+ this._renderCmd.removeDom();
+ this.stopAllActions();
+ this.unscheduleAllCallbacks();
+ }
+});
+
+/**
+ * The WebView support list of events
+ * @type {{LOADING: string, LOADED: string, ERROR: string}}
+ */
+ccui.WebView.EventType = {
+ LOADING: "loading",
+ LOADED: "load",
+ ERROR: "error",
+ JS_EVALUATED: "js"
+};
+
+(function () {
+
+ var polyfill = ccui.WebView._polyfill = {
+ devicePixelRatio: false,
+ enableDiv: false
+ };
+
+ if (cc.sys.os === cc.sys.OS_IOS)
+ polyfill.enableDiv = true;
+
+ if (cc.sys.isMobile) {
+ if (cc.sys.browserType === cc.sys.BROWSER_TYPE_FIREFOX) {
+ polyfill.enableBG = true;
+ }
+ } else {
+ if (cc.sys.browserType === cc.sys.BROWSER_TYPE_IE) {
+ polyfill.closeHistory = true;
+ }
+ }
+
+
+})();
+
+(function (polyfill) {
+
+ var RenderCmd = null;
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ RenderCmd = cc.Node.WebGLRenderCmd;
+ } else {
+ RenderCmd = cc.Node.CanvasRenderCmd;
+ }
+
+ ccui.WebView.RenderCmd = function (node) {
+ this._rootCtor(node);
+
+ this._div = null;
+ this._iframe = null;
+
+ if (polyfill.enableDiv) {
+ this._div = document.createElement("div");
+ this._div.style["-webkit-overflow"] = "auto";
+ this._div.style["-webkit-overflow-scrolling"] = "touch";
+ this._iframe = document.createElement("iframe");
+ this._iframe.style["width"] = "100%";
+ this._iframe.style["height"] = "100%";
+ this._div.appendChild(this._iframe);
+ } else {
+ this._div = this._iframe = document.createElement("iframe");
+ }
+
+ if (polyfill.enableBG)
+ this._div.style["background"] = "#FFF";
+
+ this._iframe.addEventListener("load", function () {
+ node._dispatchEvent(ccui.WebView.EventType.LOADED);
+ });
+ this._iframe.addEventListener("error", function () {
+ node._dispatchEvent(ccui.WebView.EventType.ERROR);
+ });
+ this._div.style["background"] = "#FFF";
+ this._div.style.height = "200px";
+ this._div.style.width = "300px";
+ this._div.style.overflow = "scroll";
+ this._div.style["border"] = "none";
+ this._listener = null;
+ this.initStyle();
+ };
+
+ var proto = ccui.WebView.RenderCmd.prototype = Object.create(RenderCmd.prototype);
+ proto.constructor = ccui.WebView.RenderCmd;
+
+ proto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
+ this.updateMatrix(this._worldTransform, cc.view._scaleX, cc.view._scaleY);
+ };
+
+ proto.updateStatus = function () {
+ polyfill.devicePixelRatio = cc.view.isRetinaEnabled();
+ var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag;
+ if (locFlag & flags.transformDirty) {
+ //update the transform
+ this.transform(this.getParentRenderCmd(), true);
+ this.updateMatrix(this._worldTransform, cc.view._scaleX, cc.view._scaleY);
+ this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.transformDirty ^ this._dirtyFlag;
+ }
+
+ if (locFlag & flags.orderDirty) {
+ this._dirtyFlag = this._dirtyFlag & flags.orderDirty ^ this._dirtyFlag;
+ }
+ };
+
+ proto.resize = function (view) {
+ view = view || cc.view;
+ var node = this._node,
+ eventManager = cc.eventManager;
+ if (node._parent && node._visible)
+ this.updateMatrix(this._worldTransform, view._scaleX, view._scaleY);
+ else {
+ var list = eventManager._listenersMap[cc.game.EVENT_RESIZE].getFixedPriorityListeners();
+ eventManager._removeListenerInVector(list, this._listener);
+ this._listener = null;
+ }
+ };
+
+ proto.updateMatrix = function (t, scaleX, scaleY) {
+ var node = this._node;
+ if (polyfill.devicePixelRatio) {
+ var dpr = cc.view.getDevicePixelRatio();
+ scaleX = scaleX / dpr;
+ scaleY = scaleY / dpr;
+ }
+ if (this._loaded === false) return;
+ var containerStyle = cc.game.container.style,
+ offsetX = parseInt(containerStyle.paddingLeft),
+ offsetY = parseInt(containerStyle.paddingBottom),
+ cw = node._contentSize.width,
+ ch = node._contentSize.height;
+ var a = t.a * scaleX,
+ b = t.b,
+ c = t.c,
+ d = t.d * scaleY,
+ tx = offsetX + t.tx * scaleX - cw / 2 + cw * node._scaleX / 2 * scaleX,
+ ty = offsetY + t.ty * scaleY - ch / 2 + ch * node._scaleY / 2 * scaleY;
+ var matrix = "matrix(" + a + "," + b + "," + c + "," + d + "," + tx + "," + -ty + ")";
+ this._div.style["transform"] = matrix;
+ this._div.style["-webkit-transform"] = matrix;
+ };
+
+ proto.initStyle = function () {
+ if (!this._div) return;
+ var div = this._div;
+ div.style.position = "absolute";
+ div.style.bottom = "0px";
+ div.style.left = "0px";
+ };
+
+ proto.updateURL = function (url) {
+ var iframe = this._iframe;
+ iframe.src = url;
+ var self = this;
+ var cb = function () {
+ self._loaded = true;
+ iframe.removeEventListener("load", cb);
+ };
+ iframe.addEventListener("load", cb);
+ };
+
+ proto.changeSize = function (w, h) {
+ var div = this._div;
+ if (div) {
+ div.style["width"] = w + "px";
+ div.style["height"] = h + "px";
+ }
+ };
+
+ proto.removeDom = function () {
+ var div = this._div;
+ if (div) {
+ var hasChild = false;
+ if ('contains' in cc.container) {
+ hasChild = cc.container.contains(div);
+ } else {
+ hasChild = cc.container.compareDocumentPosition(div) % 16;
+ }
+ if (hasChild)
+ cc.container.removeChild(div);
+ }
+ };
+
+})(ccui.WebView._polyfill);
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIListView.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIListView.js
new file mode 100644
index 0000000..3d0f673
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIListView.js
@@ -0,0 +1,1085 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The list view control of Cocos UI.
+ * @class
+ * @extends ccui.ScrollView
+ * @example
+ * var listView = new ccui.ListView();
+ * // set list view ex direction
+ * listView.setDirection(ccui.ScrollView.DIR_VERTICAL);
+ * listView.setTouchEnabled(true);
+ * listView.setBounceEnabled(true);
+ * listView.setBackGroundImage("res/cocosui/green_edit.png");
+ * listView.setBackGroundImageScale9Enabled(true);
+ * listView.setContentSize(cc.size(240, 130));
+ * this.addChild(listView);
+ */
+ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{
+ _model: null,
+ _items: null,
+ _gravity: null,
+ _itemsMargin: 0,
+
+ _curSelectedIndex: 0,
+ _refreshViewDirty: true,
+
+ _listViewEventListener: null,
+ _listViewEventSelector: null,
+ _ccListViewEventCallback: null,
+ _magneticAllowedOutOfBoundary: true,
+ _magneticType: 0,
+ _className: "ListView",
+
+ /**
+ * allocates and initializes a UIListView.
+ * Constructor of ccui.ListView, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @example
+ * // example
+ * var aListView = new ccui.ListView();
+ */
+ ctor: function () {
+ this._items = [];
+ ccui.ScrollView.prototype.ctor.call(this);
+ this._gravity = ccui.ListView.GRAVITY_CENTER_VERTICAL;
+ this.setTouchEnabled(true);
+ this.setDirection(ccui.ScrollView.DIR_VERTICAL);
+ },
+
+ /**
+ * Sets a item model for ListView. A model will be cloned for adding default item.
+ * @param {ccui.Widget} model
+ */
+ setItemModel: function (model) {
+ if (!model) {
+ cc.log("Can't set a null to item model!");
+ return;
+ }
+
+ this._model = model;
+ },
+
+ _handleReleaseLogic: function (touch) {
+ ccui.ScrollView.prototype._handleReleaseLogic.call(this, touch);
+
+ if (!this._autoScrolling) {
+ this._startMagneticScroll();
+ }
+ },
+
+ _onItemListChanged: function () {
+ this._outOfBoundaryAmountDirty = true;
+ },
+
+ _updateInnerContainerSize: function () {
+ var i, locItems = this._items, length;
+ switch (this.direction) {
+ case ccui.ScrollView.DIR_VERTICAL:
+ length = locItems.length;
+ var totalHeight = (length - 1) * this._itemsMargin;
+ for (i = 0; i < length; i++) {
+ totalHeight += locItems[i].getContentSize().height;
+ }
+ this.setInnerContainerSize(cc.size(this._contentSize.width, totalHeight));
+ break;
+ case ccui.ScrollView.DIR_HORIZONTAL:
+ length = locItems.length;
+ var totalWidth = (length - 1) * this._itemsMargin;
+ for (i = 0; i < length; i++) {
+ totalWidth += locItems[i].getContentSize().width;
+ }
+ this.setInnerContainerSize(cc.size(totalWidth, this._contentSize.height));
+ break;
+ default:
+ break;
+ }
+ },
+
+ _remedyLayoutParameter: function (item) {
+ cc.assert(null != item, "ListView Item can't be nil!");
+
+ var linearLayoutParameter = item.getLayoutParameter(ccui.LayoutParameter.LINEAR);
+ var isLayoutParameterExists = true;
+ if (!linearLayoutParameter) {
+ linearLayoutParameter = new ccui.LinearLayoutParameter();
+ isLayoutParameterExists = false;
+ }
+ var itemIndex = this.getIndex(item);
+ switch (this.direction) {
+ case ccui.ScrollView.DIR_VERTICAL:
+ this._remedyVerticalLayoutParameter(linearLayoutParameter, itemIndex);
+ break;
+ case ccui.ScrollView.DIR_HORIZONTAL:
+ this._remedyHorizontalLayoutParameter(linearLayoutParameter, itemIndex);
+ break;
+ default:
+ break;
+ }
+ if (!isLayoutParameterExists)
+ item.setLayoutParameter(linearLayoutParameter);
+ },
+
+ //@since v3.3
+ _remedyVerticalLayoutParameter: function (layoutParameter, itemIndex) {
+ cc.assert(null != layoutParameter, "Layout parameter can't be nil!");
+
+ switch (this._gravity) {
+ case ccui.ListView.GRAVITY_LEFT:
+ layoutParameter.setGravity(ccui.LinearLayoutParameter.LEFT);
+ break;
+ case ccui.ListView.GRAVITY_RIGHT:
+ layoutParameter.setGravity(ccui.LinearLayoutParameter.RIGHT);
+ break;
+ case ccui.ListView.GRAVITY_CENTER_HORIZONTAL:
+ layoutParameter.setGravity(ccui.LinearLayoutParameter.CENTER_HORIZONTAL);
+ break;
+ default:
+ break;
+ }
+ if (0 === itemIndex)
+ layoutParameter.setMargin(ccui.MarginZero());
+ else
+ layoutParameter.setMargin(new ccui.Margin(0.0, this._itemsMargin, 0.0, 0.0));
+ },
+
+ //@since v3.3
+ _remedyHorizontalLayoutParameter: function (layoutParameter, itemIndex) {
+ cc.assert(null != layoutParameter, "Layout parameter can't be nil!");
+
+ switch (this._gravity) {
+ case ccui.ListView.GRAVITY_TOP:
+ layoutParameter.setGravity(ccui.LinearLayoutParameter.TOP);
+ break;
+ case ccui.ListView.GRAVITY_BOTTOM:
+ layoutParameter.setGravity(ccui.LinearLayoutParameter.BOTTOM);
+ break;
+ case ccui.ListView.GRAVITY_CENTER_VERTICAL:
+ layoutParameter.setGravity(ccui.LinearLayoutParameter.CENTER_VERTICAL);
+ break;
+ default:
+ break;
+ }
+ if (0 === itemIndex)
+ layoutParameter.setMargin(ccui.MarginZero());
+ else
+ layoutParameter.setMargin(new ccui.Margin(this._itemsMargin, 0.0, 0.0, 0.0));
+ },
+
+ /**
+ * Push back a default item(create by a cloned model) into ListView.
+ */
+ pushBackDefaultItem: function () {
+ if (this._model == null)
+ return;
+ var newItem = this._model.clone();
+ this._remedyLayoutParameter(newItem);
+ this.addChild(newItem);
+ this._refreshViewDirty = true;
+ },
+
+ /**
+ * Insert a default item(create by a cloned model) into ListView.
+ * @param {Number} index
+ */
+ insertDefaultItem: function (index) {
+ if (this._model == null)
+ return;
+ var newItem = this._model.clone();
+ this._items.splice(index, 0, newItem);
+ ccui.ScrollView.prototype.addChild.call(this, newItem);
+ this._remedyLayoutParameter(newItem);
+
+ this._refreshViewDirty = true;
+ },
+
+ /**
+ * Push back custom item into ListView.
+ * @param {ccui.Widget} item
+ */
+ pushBackCustomItem: function (item) {
+ this._remedyLayoutParameter(item);
+ this.addChild(item);
+ this._refreshViewDirty = true;
+ },
+
+ /**
+ * add child to ListView
+ * @override
+ * @param {cc.Node} widget
+ * @param {Number} [zOrder]
+ * @param {Number|String} [tag] tag or name
+ */
+ addChild: function (widget, zOrder, tag) {
+ if (widget) {
+ zOrder = zOrder || widget.getLocalZOrder();
+ tag = tag || widget.getName();
+ ccui.ScrollView.prototype.addChild.call(this, widget, zOrder, tag);
+ if (widget instanceof ccui.Widget) {
+ this._items.push(widget);
+ this._onItemListChanged();
+ }
+ }
+ },
+
+ /**
+ * remove child from ListView
+ * @override
+ * @param {cc.Node} widget
+ * @param {Boolean} [cleanup=true]
+ */
+ removeChild: function (widget, cleanup) {
+ if (widget) {
+ var index = this._items.indexOf(widget);
+ if (index > -1)
+ this._items.splice(index, 1);
+
+ this._onItemListChanged();
+
+ ccui.ScrollView.prototype.removeChild.call(this, widget, cleanup);
+ }
+ },
+
+ /**
+ * Removes all children from ccui.ListView.
+ */
+ removeAllChildren: function () {
+ this.removeAllChildrenWithCleanup(true);
+ },
+
+ /**
+ * Removes all children from ccui.ListView and do a cleanup all running actions depending on the cleanup parameter.
+ * @param {Boolean} cleanup
+ */
+ removeAllChildrenWithCleanup: function (cleanup) {
+ ccui.ScrollView.prototype.removeAllChildrenWithCleanup.call(this, cleanup);
+ this._items = [];
+
+ this._onItemListChanged();
+ },
+
+ /**
+ * Push back custom item into ccui.ListView.
+ * @param {ccui.Widget} item
+ * @param {Number} index
+ */
+ insertCustomItem: function (item, index) {
+ this._items.splice(index, 0, item);
+
+ this._onItemListChanged();
+ ccui.ScrollView.prototype.addChild.call(this, item);
+ this._remedyLayoutParameter(item);
+ this._refreshViewDirty = true;
+ },
+
+ /**
+ * Removes a item whose index is same as the parameter.
+ * @param {Number} index
+ */
+ removeItem: function (index) {
+ var item = this.getItem(index);
+ if (item == null)
+ return;
+ this.removeChild(item, true);
+ this._refreshViewDirty = true;
+ },
+
+ /**
+ * Removes the last item of ccui.ListView.
+ */
+ removeLastItem: function () {
+ this.removeItem(this._items.length - 1);
+ },
+
+ /**
+ * Removes all items from ccui.ListView.
+ */
+ removeAllItems: function () {
+ this.removeAllChildren();
+ },
+
+ /**
+ * Returns a item whose index is same as the parameter.
+ * @param {Number} index
+ * @returns {ccui.Widget}
+ */
+ getItem: function (index) {
+ if (index < 0 || index >= this._items.length)
+ return null;
+ return this._items[index];
+ },
+
+ /**
+ * Returns the item container.
+ * @returns {Array}
+ */
+ getItems: function () {
+ return this._items;
+ },
+
+ /**
+ * Returns the index of item.
+ * @param {ccui.Widget} item the item which need to be checked.
+ * @returns {Number} the index of item.
+ */
+ getIndex: function (item) {
+ if (item == null)
+ return -1;
+ return this._items.indexOf(item);
+ },
+
+ /**
+ * Changes the gravity of ListView.
+ * @param {ccui.ListView.GRAVITY_LEFT|ccui.ListView.GRAVITY_RIGHT|ccui.ListView.GRAVITY_CENTER_HORIZONTAL|ccui.ListView.GRAVITY_BOTTOM|ccui.ListView.GRAVITY_CENTER_VERTICAL} gravity
+ */
+ setGravity: function (gravity) {
+ if (this._gravity === gravity)
+ return;
+ this._gravity = gravity;
+ this._refreshViewDirty = true;
+ },
+
+ /**
+ * Set magnetic type of ListView.
+ * @param {ccui.ListView.MAGNETIC_NONE|ccui.ListView.MAGNETIC_CENTER,ccui.ListView.MAGNETIC_BOTH_END|ccui.ListView.MAGNETIC_LEFT|ccui.ListView.MAGNETIC_RIGHT|ccui.ListView.MAGNETIC_TOP|ccui.ListView.MAGNETIC_BOTTOM} magneticType
+ */
+ setMagneticType: function (magneticType) {
+ this._magneticType = magneticType;
+ this._onItemListChanged();
+ this._startMagneticScroll();
+ },
+
+ /**
+ * Get magnetic type of ListView.
+ * @returns {number}
+ */
+ getMagneticType: function () {
+ return this._magneticType;
+ },
+
+ /**
+ * Set magnetic allowed out of boundary.
+ * @param {boolean} magneticAllowedOutOfBoundary
+ */
+ setMagneticAllowedOutOfBoundary: function (magneticAllowedOutOfBoundary) {
+ this._magneticAllowedOutOfBoundary = magneticAllowedOutOfBoundary;
+ },
+
+ /**
+ * Query whether the magnetic out of boundary is allowed.
+ * @returns {boolean}
+ */
+ getMagneticAllowedOutOfBoundary: function () {
+ return this._magneticAllowedOutOfBoundary;
+ },
+
+ /**
+ * Changes the margin between each item.
+ * @param {Number} margin
+ */
+ setItemsMargin: function (margin) {
+ if (this._itemsMargin === margin)
+ return;
+ this._itemsMargin = margin;
+ this._refreshViewDirty = true;
+ },
+
+ /**
+ * Returns the margin between each item.
+ * @returns {Number}
+ */
+ getItemsMargin: function () {
+ return this._itemsMargin;
+ },
+
+ /**
+ * Changes scroll direction of ccui.ListView.
+ * @param {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_BOTH} dir
+ */
+ setDirection: function (dir) {
+ switch (dir) {
+ case ccui.ScrollView.DIR_VERTICAL:
+ this.setLayoutType(ccui.Layout.LINEAR_VERTICAL);
+ break;
+ case ccui.ScrollView.DIR_HORIZONTAL:
+ this.setLayoutType(ccui.Layout.LINEAR_HORIZONTAL);
+ break;
+ case ccui.ScrollView.DIR_BOTH:
+ return;
+ default:
+ return;
+ break;
+ }
+ ccui.ScrollView.prototype.setDirection.call(this, dir);
+ },
+
+ _getHowMuchOutOfBoundary: function (addition) {
+ if (addition === undefined)
+ addition = cc.p(0, 0);
+
+ if (!this._magneticAllowedOutOfBoundary || this._items.length === 0) {
+ return ccui.ScrollView.prototype._getHowMuchOutOfBoundary.call(this, addition);
+ }
+ else if (this._magneticType === ccui.ListView.MAGNETIC_NONE || this._magneticType === ccui.ListView.MAGNETIC_BOTH_END) {
+ return ccui.ScrollView.prototype._getHowMuchOutOfBoundary.call(this, addition);
+ }
+ else if (addition.x === 0 && addition.y === 0 && !this._outOfBoundaryAmountDirty) {
+ return this._outOfBoundaryAmount;
+ }
+
+ // If it is allowed to be out of boundary by magnetic, adjust the boundaries according to the magnetic type.
+ var leftBoundary = this._leftBoundary;
+ var rightBoundary = this._rightBoundary;
+ var topBoundary = this._topBoundary;
+ var bottomBoundary = this._bottomBoundary;
+
+ var lastItemIndex = this._items.length - 1;
+ var contentSize = this.getContentSize();
+ var firstItemAdjustment = cc.p(0, 0);
+ var lastItemAdjustment = cc.p(0, 0);
+
+ switch (this._magneticType) {
+ case ccui.ListView.MAGNETIC_CENTER:
+ firstItemAdjustment.x = (contentSize.width - this._items[0].width) / 2;
+ firstItemAdjustment.y = (contentSize.height - this._items[0].height) / 2;
+
+ lastItemAdjustment.x = (contentSize.width - this._items[lastItemIndex].width) / 2;
+ lastItemAdjustment.y = (contentSize.height - this._items[lastItemIndex].height) / 2;
+
+ break;
+ case ccui.ListView.MAGNETIC_LEFT:
+ case ccui.ListView.MAGNETIC_TOP:
+ lastItemAdjustment.x = contentSize.width - this._items[lastItemIndex].width;
+ lastItemAdjustment.y = contentSize.height - this._items[lastItemIndex].height;
+ break;
+ case ccui.ListView.MAGNETIC_RIGHT:
+ case ccui.ListView.MAGNETIC_BOTTOM:
+ firstItemAdjustment.x = contentSize.width - this._items[0].width;
+ firstItemAdjustment.y = contentSize.height - this._items[0].height;
+ break;
+ }
+
+ leftBoundary += firstItemAdjustment.x;
+ rightBoundary -= lastItemAdjustment.x;
+ topBoundary -= firstItemAdjustment.y;
+ bottomBoundary += lastItemAdjustment.y;
+
+
+ // Calculate the actual amount
+ var outOfBoundaryAmount = cc.p(0, 0);
+
+ if (this._innerContainer.getLeftBoundary() + addition.x > leftBoundary) {
+ outOfBoundaryAmount.x = leftBoundary - (this._innerContainer.getLeftBoundary() + addition.x);
+ }
+ else if (this._innerContainer.getRightBoundary() + addition.x < rightBoundary) {
+ outOfBoundaryAmount.x = rightBoundary - (this._innerContainer.getRightBoundary() + addition.x);
+ }
+
+ if (this._innerContainer.getTopBoundary() + addition.y < topBoundary) {
+ outOfBoundaryAmount.y = topBoundary - (this._innerContainer.getTopBoundary() + addition.y);
+ }
+ else if (this._innerContainer.getBottomBoundary() + addition.y > bottomBoundary) {
+ outOfBoundaryAmount.y = bottomBoundary - (this._innerContainer.getBottomBoundary() + addition.y);
+ }
+
+ if (addition.x === 0 && addition.y === 0) {
+ this._outOfBoundaryAmount = outOfBoundaryAmount;
+ this._outOfBoundaryAmountDirty = false;
+ }
+ return outOfBoundaryAmount;
+ },
+
+ _calculateItemPositionWithAnchor: function (item, itemAnchorPoint) {
+ var origin = cc.p(item.getLeftBoundary(), item.getBottomBoundary());
+ var size = item.getContentSize();
+
+ return cc.p(origin.x + size.width * itemAnchorPoint.x, origin.y + size.height * itemAnchorPoint.y);
+ },
+
+ _findClosestItem: function (targetPosition, items, itemAnchorPoint, firstIndex, distanceFromFirst, lastIndex, distanceFromLast) {
+ cc.assert(firstIndex >= 0 && lastIndex < items.length && firstIndex <= lastIndex, "");
+ if (firstIndex === lastIndex) {
+ return items[firstIndex];
+ }
+ if (lastIndex - firstIndex === 1) {
+ if (distanceFromFirst <= distanceFromLast) {
+ return items[firstIndex];
+ }
+ else {
+ return items[lastIndex];
+ }
+ }
+
+ // Binary search
+ var midIndex = Math.floor((firstIndex + lastIndex) / 2);
+ var itemPosition = this._calculateItemPositionWithAnchor(items[midIndex], itemAnchorPoint);
+ var distanceFromMid = cc.pLength(cc.pSub(targetPosition, itemPosition));
+
+ if (distanceFromFirst <= distanceFromLast) {
+ // Left half
+ return this._findClosestItem(targetPosition, items, itemAnchorPoint, firstIndex, distanceFromFirst, midIndex, distanceFromMid);
+ }
+ else {
+ // Right half
+ return this._findClosestItem(targetPosition, items, itemAnchorPoint, midIndex, distanceFromMid, lastIndex, distanceFromLast);
+ }
+ },
+
+ /**
+ * Query the closest item to a specific position in inner container.
+ *
+ * @param {cc.Point} targetPosition Specifies the target position in inner container's coordinates.
+ * @param {cc.Point} itemAnchorPoint Specifies an anchor point of each item for position to calculate distance.
+ * @returns {?ccui.Widget} A item instance if list view is not empty. Otherwise, returns null.
+ */
+ getClosestItemToPosition: function (targetPosition, itemAnchorPoint) {
+ if (this._items.length === 0) {
+ return null;
+ }
+
+ // Find the closest item through binary search
+ var firstIndex = 0;
+ var firstPosition = this._calculateItemPositionWithAnchor(this._items[firstIndex], itemAnchorPoint);
+ var distanceFromFirst = cc.pLength(cc.pSub(targetPosition, firstPosition));
+
+ var lastIndex = this._items.length - 1;
+ var lastPosition = this._calculateItemPositionWithAnchor(this._items[lastIndex], itemAnchorPoint);
+ var distanceFromLast = cc.pLength(cc.pSub(targetPosition, lastPosition));
+
+ return this._findClosestItem(targetPosition, this._items, itemAnchorPoint, firstIndex, distanceFromFirst, lastIndex, distanceFromLast);
+ },
+
+ /**
+ * Query the closest item to a specific position in current view.
+ * For instance, to find the item in the center of view, call 'getClosestItemToPositionInCurrentView(cc.p(0.5, 0.5), cc.p(0.5, 0.5))'.
+ *
+ * @param {cc.Point} positionRatioInView Specifies the target position with ratio in list view's content size.
+ * @param {cc.Point} itemAnchorPoint Specifies an anchor point of each item for position to calculate distance.
+ * @returns {?ccui.Widget} A item instance if list view is not empty. Otherwise, returns null.
+ */
+
+ getClosestItemToPositionInCurrentView: function (positionRatioInView, itemAnchorPoint) {
+ // Calculate the target position
+ var contentSize = this.getContentSize();
+ var targetPosition = cc.pMult(this._innerContainer.getPosition(), -1);
+ targetPosition.x += contentSize.width * positionRatioInView.x;
+ targetPosition.y += contentSize.height * positionRatioInView.y;
+
+ return this.getClosestItemToPosition(targetPosition, itemAnchorPoint);
+ },
+
+ /**
+ * Query the center item
+ * @returns {?ccui.Widget} A item instance.
+ */
+ getCenterItemInCurrentView: function () {
+ return this.getClosestItemToPositionInCurrentView(cc.p(0.5, 0.5), cc.p(0.5, 0.5));
+ },
+
+ /**
+ * Query the leftmost item in horizontal list
+ * @returns {?ccui.Widget} A item instance.
+ */
+ getLeftmostItemInCurrentView: function () {
+ if (this._direction === ccui.ScrollView.DIR_HORIZONTAL) {
+ return this.getClosestItemToPositionInCurrentView(cc.p(0, 0.5), cc.p(0.5, 0.5));
+ }
+
+ return null;
+ },
+
+ /**
+ * Query the rightmost item in horizontal list
+ * @returns {?ccui.Widget} A item instance.
+ */
+ getRightmostItemInCurrentView: function () {
+ if (this._direction === ccui.ScrollView.DIR_HORIZONTAL) {
+ return this.getClosestItemToPositionInCurrentView(cc.p(1, 0.5), cc.p(0.5, 0.5));
+ }
+
+ return null;
+ },
+
+ /**
+ * Query the topmost item in horizontal list
+ * @returns {?ccui.Widget} A item instance.
+ */
+ getTopmostItemInCurrentView: function () {
+ if (this._direction === ccui.ScrollView.DIR_VERTICAL) {
+ return this.getClosestItemToPositionInCurrentView(cc.p(0.5, 1), cc.p(0.5, 0.5));
+ }
+
+ return null;
+ },
+
+ /**
+ * Query the topmost item in horizontal list
+ * @returns {?ccui.Widget} A item instance.
+ */
+ getBottommostItemInCurrentView: function () {
+ if (this._direction === ccui.ScrollView.DIR_VERTICAL) {
+ return this.getClosestItemToPositionInCurrentView(cc.p(0.5, 0), cc.p(0.5, 0.5));
+ }
+
+ return null;
+ },
+
+ _calculateItemDestination: function (positionRatioInView, item, itemAnchorPoint) {
+ var contentSize = this.getContentSize();
+ var positionInView = cc.p(0, 0);
+ positionInView.x += contentSize.width * positionRatioInView.x;
+ positionInView.y += contentSize.height * positionRatioInView.y;
+
+ var itemPosition = this._calculateItemPositionWithAnchor(item, itemAnchorPoint);
+ return cc.pMult(cc.pSub(itemPosition, positionInView), -1);
+ },
+
+ jumpToBottom: function () {
+ this.doLayout();
+ ccui.ScrollView.prototype.jumpToBottom.call(this);
+ },
+
+ jumpToTop: function () {
+ this.doLayout();
+ ccui.ScrollView.prototype.jumpToTop.call(this);
+ },
+
+ jumpToLeft: function () {
+ this.doLayout();
+ ccui.ScrollView.prototype.jumpToLeft.call(this);
+ },
+
+ jumpToRight: function () {
+ this.doLayout();
+ ccui.ScrollView.prototype.jumpToRight.call(this);
+ },
+
+ jumpToTopLeft: function () {
+ this.doLayout();
+ ccui.ScrollView.prototype.jumpToTopLeft.call(this);
+ },
+
+ jumpToTopRight: function () {
+ this.doLayout();
+ ccui.ScrollView.prototype.jumpToTopRight.call(this);
+ },
+
+ jumpToBottomLeft: function () {
+ this.doLayout();
+ ccui.ScrollView.prototype.jumpToBottomLeft.call(this);
+ },
+
+ jumpToBottomRight: function () {
+ this.doLayout();
+ ccui.ScrollView.prototype.jumpToBottomRight.call(this);
+ },
+
+ jumpToPercentVertical: function (percent) {
+ this.doLayout();
+ ccui.ScrollView.prototype.jumpToPercentVertical.call(this, percent);
+ },
+
+ jumpToPercentHorizontal: function (percent) {
+ this.doLayout();
+ ccui.ScrollView.prototype.jumpToPercentHorizontal.call(this, percent);
+ },
+
+ jumpToPercentBothDirection: function (percent) {
+ this.doLayout();
+ ccui.ScrollView.prototype.jumpToPercentBothDirection.call(this, percent);
+ },
+
+ /**
+ * Jump to specific item
+ * @param {number} itemIndex Specifies the item's index
+ * @param {cc.Point} positionRatioInView Specifies the position with ratio in list view's content size.
+ * @param {cc.Point} itemAnchorPoint Specifies an anchor point of each item for position to calculate distance.
+ */
+ jumpToItem: function (itemIndex, positionRatioInView, itemAnchorPoint) {
+ var item = this.getItem(itemIndex);
+
+ if (!item)
+ return;
+
+ this.doLayout();
+
+ var destination = this._calculateItemDestination(positionRatioInView, item, itemAnchorPoint);
+
+ if (!this.bounceEnabled) {
+ var delta = cc.pSub(destination, this._innerContainer.getPosition());
+ var outOfBoundary = this._getHowMuchOutOfBoundary(delta);
+ destination.x += outOfBoundary.x;
+ destination.y += outOfBoundary.y;
+ }
+
+ this._jumpToDestination(destination);
+ },
+
+ /**
+ * Scroll to specific item
+ * @param {number} itemIndex Specifies the item's index
+ * @param {cc.Point} positionRatioInView Specifies the position with ratio in list view's content size.
+ * @param {cc.Point} itemAnchorPoint Specifies an anchor point of each item for position to calculate distance.
+ * @param {number} [timeInSec = 1.0] Scroll time
+ */
+ scrollToItem: function (itemIndex, positionRatioInView, itemAnchorPoint, timeInSec) {
+ if (timeInSec === undefined)
+ timeInSec = 1;
+
+ var item = this.getItem(itemIndex);
+
+ if (!item)
+ return;
+
+ var destination = this._calculateItemDestination(positionRatioInView, item, itemAnchorPoint);
+ this._startAutoScrollToDestination(destination, timeInSec, true);
+ },
+
+ /**
+ * Requests refresh list view.
+ * @deprecated Use method requestDoLayout() instead
+ */
+ requestRefreshView: function () {
+ this._refreshViewDirty = true;
+ },
+
+ /**
+ * Refreshes list view.
+ * @deprecated Use method forceDoLayout() instead
+ */
+ refreshView: function () {
+ this.forceDoLayout()
+ },
+
+ /**
+ * provides a public _doLayout function for Editor. it calls _doLayout.
+ */
+ doLayout: function () {
+ this._doLayout();
+ },
+
+ requestDoLayout: function () {
+ this._refreshViewDirty = true;
+ },
+
+ _doLayout: function () {
+ //ccui.Layout.prototype._doLayout.call(this);
+ if (this._refreshViewDirty) {
+ var locItems = this._items;
+ for (var i = 0; i < locItems.length; i++) {
+ var item = locItems[i];
+ item.setLocalZOrder(i);
+ this._remedyLayoutParameter(item);
+ }
+ this._updateInnerContainerSize();
+ this._innerContainer.forceDoLayout();
+ this._refreshViewDirty = false;
+ }
+ },
+
+ /**
+ * Adds event listener to ccui.ListView.
+ * @param {Function} selector
+ * @param {Object} [target=]
+ * @deprecated since v3.0, please use addEventListener instead.
+ */
+ addEventListenerListView: function (selector, target) {
+ this._listViewEventListener = target;
+ this._listViewEventSelector = selector;
+ },
+
+ /**
+ * Adds callback function called ListView event triggered
+ * @param {Function} selector
+ */
+ addEventListener: function (selector) {
+ this._ccListViewEventCallback = selector;
+ },
+
+ _selectedItemEvent: function (event) {
+ var eventEnum = (event === ccui.Widget.TOUCH_BEGAN) ? ccui.ListView.ON_SELECTED_ITEM_START : ccui.ListView.ON_SELECTED_ITEM_END;
+ if (this._listViewEventSelector) {
+ if (this._listViewEventListener)
+ this._listViewEventSelector.call(this._listViewEventListener, this, eventEnum);
+ else
+ this._listViewEventSelector(this, eventEnum);
+ }
+ if (this._ccListViewEventCallback)
+ this._ccListViewEventCallback(this, eventEnum);
+ },
+
+ /**
+ * Intercept touch event, handle its child's touch event.
+ * @param {Number} eventType
+ * @param {ccui.Widget} sender
+ * @param {cc.Touch} touch
+ */
+ interceptTouchEvent: function (eventType, sender, touch) {
+ ccui.ScrollView.prototype.interceptTouchEvent.call(this, eventType, sender, touch);
+ if (!this._touchEnabled) {
+ return;
+ }
+ if (eventType !== ccui.Widget.TOUCH_MOVED) {
+ var parent = sender;
+ while (parent) {
+ if (parent && parent.getParent() === this._innerContainer) {
+ this._curSelectedIndex = this.getIndex(parent);
+ break;
+ }
+ parent = parent.getParent();
+ }
+ if (sender.isHighlighted())
+ this._selectedItemEvent(eventType);
+ }
+ },
+
+ /**
+ * Returns current selected index
+ * @returns {number}
+ */
+ getCurSelectedIndex: function () {
+ return this._curSelectedIndex;
+ },
+
+ _onSizeChanged: function () {
+ ccui.ScrollView.prototype._onSizeChanged.call(this);
+ this._refreshViewDirty = true;
+ },
+
+ /**
+ * Returns the "class name" of ccui.ListView.
+ * @returns {string}
+ */
+ getDescription: function () {
+ return "ListView";
+ },
+
+ _createCloneInstance: function () {
+ return new ccui.ListView();
+ },
+
+ _copyClonedWidgetChildren: function (model) {
+ var arrayItems = model.getItems();
+ for (var i = 0; i < arrayItems.length; i++) {
+ var item = arrayItems[i];
+ this.pushBackCustomItem(item.clone());
+ }
+ },
+
+ _copySpecialProperties: function (listView) {
+ if (listView instanceof ccui.ListView) {
+ ccui.ScrollView.prototype._copySpecialProperties.call(this, listView);
+ this.setItemModel(listView._model);
+ this.setItemsMargin(listView._itemsMargin);
+ this.setGravity(listView._gravity);
+
+ this._listViewEventListener = listView._listViewEventListener;
+ this._listViewEventSelector = listView._listViewEventSelector;
+ }
+ },
+
+ _startAttenuatingAutoScroll: function (deltaMove, initialVelocity) {
+ var adjustedDeltaMove = deltaMove;
+
+ if (this._items.length !== 0 && this._magneticType !== ccui.ListView.MAGNETIC_NONE) {
+ adjustedDeltaMove = this._flattenVectorByDirection(adjustedDeltaMove);
+
+ var howMuchOutOfBoundary = this._getHowMuchOutOfBoundary(adjustedDeltaMove);
+ // If the destination is out of boundary, do nothing here. Because it will be handled by bouncing back.
+ if (howMuchOutOfBoundary.x === 0 && howMuchOutOfBoundary.y === 0) {
+ var magType = this._magneticType;
+ if (magType === ccui.ListView.MAGNETIC_BOTH_END) {
+ if (this._direction === ccui.ScrollView.DIR_HORIZONTAL) {
+ magType = (adjustedDeltaMove.x > 0 ? ccui.ListView.MAGNETIC_LEFT : ccui.ListView.MAGNETIC_RIGHT);
+ }
+ else if (this._direction === ccui.ScrollView.DIR_VERTICAL) {
+ magType = (adjustedDeltaMove.y > 0 ? ccui.ListView.MAGNETIC_BOTTOM : ccui.ListView.MAGNETIC_TOP);
+ }
+ }
+
+ // Adjust the delta move amount according to the magnetic type
+ var magneticAnchorPoint = this._getAnchorPointByMagneticType(magType);
+ var magneticPosition = cc.pMult(this._innerContainer.getPosition(), -1);
+ magneticPosition.x += this.width * magneticAnchorPoint.x;
+ magneticPosition.y += this.height * magneticAnchorPoint.y;
+
+ var pTargetItem = this.getClosestItemToPosition(cc.pSub(magneticPosition, adjustedDeltaMove), magneticAnchorPoint);
+ var itemPosition = this._calculateItemPositionWithAnchor(pTargetItem, magneticAnchorPoint);
+ adjustedDeltaMove = cc.pSub(magneticPosition, itemPosition);
+ }
+ }
+ ccui.ScrollView.prototype._startAttenuatingAutoScroll.call(this, adjustedDeltaMove, initialVelocity);
+ },
+
+ _getAnchorPointByMagneticType: function (magneticType) {
+ switch (magneticType) {
+ case ccui.ListView.MAGNETIC_NONE:
+ return cc.p(0, 0);
+ case ccui.ListView.MAGNETIC_BOTH_END:
+ return cc.p(0, 1);
+ case ccui.ListView.MAGNETIC_CENTER:
+ return cc.p(0.5, 0.5);
+ case ccui.ListView.MAGNETIC_LEFT:
+ return cc.p(0, 0.5);
+ case ccui.ListView.MAGNETIC_RIGHT:
+ return cc.p(1, 0.5);
+ case ccui.ListView.MAGNETIC_TOP:
+ return cc.p(0.5, 1);
+ case ccui.ListView.MAGNETIC_BOTTOM:
+ return cc.p(0.5, 0);
+ }
+
+ return cc.p(0, 0);
+ },
+
+ _startMagneticScroll: function () {
+ if (this._items.length === 0 || this._magneticType === ccui.ListView.MAGNETIC_NONE) {
+ return;
+ }
+
+ // Find the closest item
+ var magneticAnchorPoint = this._getAnchorPointByMagneticType(this._magneticType);
+ var magneticPosition = cc.pMult(this._innerContainer.getPosition(), -1);
+ magneticPosition.x += this.width * magneticAnchorPoint.x;
+ magneticPosition.y += this.height * magneticAnchorPoint.y;
+
+ var pTargetItem = this.getClosestItemToPosition(magneticPosition, magneticAnchorPoint);
+ this.scrollToItem(this.getIndex(pTargetItem), magneticAnchorPoint, magneticAnchorPoint);
+ }
+});
+
+/**
+ * allocates and initializes a UIListView.
+ * @deprecated since v3.0, please use new ccui.ListView() instead.
+ */
+ccui.ListView.create = function () {
+ return new ccui.ListView();
+};
+
+// Constants
+//listView event type
+/**
+ * The flag selected item of ccui.ListView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.EVENT_SELECTED_ITEM = 0;
+
+/**
+ * The flag selected item start of ccui.ListView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.ON_SELECTED_ITEM_START = 0;
+/**
+ * The flag selected item end of ccui.ListView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.ON_SELECTED_ITEM_END = 1;
+
+//listView gravity
+/**
+ * The left flag of ccui.ListView's gravity.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.GRAVITY_LEFT = 0;
+/**
+ * The right flag of ccui.ListView's gravity.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.GRAVITY_RIGHT = 1;
+/**
+ * The center horizontal flag of ccui.ListView's gravity.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.GRAVITY_CENTER_HORIZONTAL = 2;
+/**
+ * The top flag of ccui.ListView's gravity.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.GRAVITY_TOP = 3;
+/**
+ * The bottom flag of ccui.ListView's gravity.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.GRAVITY_BOTTOM = 4;
+/**
+ * The center vertical flag of ccui.ListView's gravity.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.GRAVITY_CENTER_VERTICAL = 5;
+
+/**
+ * The flag of ccui.ListView's magnetic none type.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.MAGNETIC_NONE = 0;
+/**
+ * The flag of ccui.ListView's magnetic center type.
+ * ListView tries to align its items in center of current view.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.MAGNETIC_CENTER = 1;
+/**
+ * The flag of ccui.ListView's magnetic both end type.
+ * ListView tries to align its items in left or right end if it is horizontal, top or bottom in vertical.
+ * The aligning side (left or right, top or bottom) is determined by user's scroll direction.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.MAGNETIC_BOTH_END = 2;
+/**
+ * The flag of ccui.ListView's magnetic left type.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.MAGNETIC_LEFT = 3;
+/**
+ * The flag of ccui.ListView's magnetic right type.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.MAGNETIC_RIGHT = 4;
+/**
+ * The flag of ccui.ListView's magnetic top type.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.MAGNETIC_TOP = 5;
+/**
+ * The flag of ccui.ListView's magnetic bottom type.
+ * @constant
+ * @type {number}
+ */
+ccui.ListView.MAGNETIC_BOTTOM = 6;
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js
new file mode 100644
index 0000000..e378537
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js
@@ -0,0 +1,593 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The PageView control of Cocos UI.
+ * @class
+ * @extends ccui.ListView
+ * @example
+ * var pageView = new ccui.PageView();
+ * pageView.setTouchEnabled(true);
+ * pageView.addPage(new ccui.Layout());
+ * this.addChild(pageView);
+ */
+ccui.PageView = ccui.ListView.extend(/** @lends ccui.PageView# */{
+ _curPageIdx: 0,
+ _childFocusCancelOffset: 0,
+ _pageViewEventListener: null,
+ _pageViewEventSelector: null,
+ _className: "PageView",
+
+ _indicator: null,
+ _indicatorPositionAsAnchorPoint: null,
+ /**
+ * Allocates and initializes a UIPageView.
+ * Constructor of ccui.PageView. please do not call this function by yourself, you should pass the parameters to constructor to initialize it
.
+ * @example
+ * // example
+ * var uiPageView = new ccui.PageView();
+ */
+ ctor: function () {
+ ccui.ListView.prototype.ctor.call(this);
+
+ this._childFocusCancelOffset = 5;
+ this._indicatorPositionAsAnchorPoint = cc.p(0.5, 0.1);
+ this._pageViewEventListener = null;
+ this._pageViewEventSelector = null;
+
+ this.setDirection(ccui.ScrollView.DIR_HORIZONTAL);
+ this.setMagneticType(ccui.ListView.MAGNETIC_CENTER);
+ this.setScrollBarEnabled(false);
+ },
+
+ /**
+ * Add a widget to a page of PageView.
+ * @deprecated since v3.9, please use 'insertPage(Widget* page, int idx)' instead.
+ * @param {ccui.Widget} widget widget to be added to PageView.
+ * @param {number} pageIdx index of page.
+ * @param {Boolean} forceCreate if force create and there is no page exist, PageView would create a default page for adding widget.
+ */
+ addWidgetToPage: function (widget, pageIdx, forceCreate) {
+ this.insertCustomItem(widget, pageIdx);
+ },
+
+ /**
+ * Insert a page into the end of PageView.
+ * @param {ccui.Widget} page Page to be inserted.
+ */
+ addPage: function (page) {
+ this.pushBackCustomItem(page);
+ },
+
+ /**
+ * Insert a page into PageView at a given index.
+ * @param {ccui.Widget} page Page to be inserted.
+ * @param {number} idx A given index.
+ */
+ insertPage: function (page, idx) {
+ this.insertCustomItem(page, idx);
+ },
+
+ /**
+ * Removes a page from PageView.
+ * @param {ccui.Widget} page Page to be removed.
+ */
+ removePage: function (page) {
+ this.removeItem(this.getIndex(page));
+ },
+
+ /**
+ * Removes a page at index of PageView.
+ * @param {number} index A given index.
+ */
+ removePageAtIndex: function (index) {
+ this.removeItem(index);
+ },
+
+ /**
+ * Removes all pages from PageView
+ */
+ removeAllPages: function () {
+ this.removeAllItems();
+ },
+
+ /**
+ * scroll PageView to index.
+ * @param {number} idx A given index in the PageView. Index start from 0 to pageCount -1.
+ */
+ scrollToItem: function (idx) {
+ ccui.ListView.prototype.scrollToItem.call(this, idx, cc.p(0.5, 0.5), cc.p(0.5, 0.5));
+ },
+
+ /**
+ * scroll PageView to index.
+ * @param {number} idx A given index in the PageView. Index start from 0 to pageCount -1.
+ */
+ scrollToPage: function (idx) {
+ this.scrollToItem(idx);
+ },
+
+
+ _doLayout: function () {
+ if (!this._refreshViewDirty)
+ return;
+
+ ccui.ListView.prototype._doLayout.call(this);
+
+ if (this._indicator) {
+ var index = this.getIndex(this.getCenterItemInCurrentView());
+ this._indicator.indicate(index);
+ }
+
+ this._refreshViewDirty = false;
+ },
+
+ /**
+ * Changes scroll direction of ccui.PageView.
+ * @param {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_BOTH} direction
+ */
+ setDirection: function (direction) {
+ ccui.ListView.prototype.setDirection.call(this, direction);
+ if (direction === ccui.ScrollView.DIR_HORIZONTAL) {
+ this._indicatorPositionAsAnchorPoint = cc.p(0.5, 0.1);
+ }
+ else if (direction === ccui.ScrollView.DIR_VERTICAL) {
+ this._indicatorPositionAsAnchorPoint = cc.p(0.1, 0.5);
+ }
+
+ if (this._indicator) {
+ this._indicator.setDirection(direction);
+ this._refreshIndicatorPosition();
+ }
+ },
+
+ /**
+ * Set custom scroll threshold to page view. If you don't specify the value, the pageView will scroll when half page view width reached.
+ * @since v3.2
+ * @param threshold
+ * @deprecated Since v3.9, this method has no effect.
+ */
+ setCustomScrollThreshold: function (threshold) {
+
+ },
+
+ /**
+ * Returns user defined scroll page threshold.
+ * @since v3.2
+ * @deprecated Since v3.9, this method always returns 0.
+ */
+ getCustomScrollThreshold: function () {
+ return 0;
+ },
+
+ /**
+ * Set using user defined scroll page threshold or not. If you set it to false, then the default scroll threshold is pageView.width / 2.
+ * @since v3.2
+ * @deprecated Since v3.9, this method has no effect.
+ */
+ setUsingCustomScrollThreshold: function (flag) {
+ },
+
+ /**
+ * Queries whether we are using user defined scroll page threshold or not
+ * @deprecated Since v3.9, this method always returns false.
+ */
+ isUsingCustomScrollThreshold: function () {
+ return false;
+ },
+
+ _moveInnerContainer: function (deltaMove, canStartBounceBack) {
+ ccui.ListView.prototype._moveInnerContainer.call(this, deltaMove, canStartBounceBack);
+ this._curPageIdx = this.getIndex(this.getCenterItemInCurrentView());
+ if (this._indicator) {
+ this._indicator.indicate(this._curPageIdx);
+ }
+ },
+
+ _onItemListChanged: function () {
+ ccui.ListView.prototype._onItemListChanged.call(this);
+ if (this._indicator) {
+ this._indicator.reset(this._items.length);
+ }
+ },
+
+ _onSizeChanged: function () {
+ ccui.ListView.prototype._onSizeChanged.call(this);
+ this._refreshIndicatorPosition();
+ },
+
+ _remedyLayoutParameter: function (item) {
+ item.setContentSize(this.getContentSize());
+ ccui.ListView.prototype._remedyLayoutParameter.call(this, item);
+ },
+
+ _refreshIndicatorPosition: function () {
+ if (this._indicator) {
+ var contentSize = this.getContentSize();
+ var posX = contentSize.width * this._indicatorPositionAsAnchorPoint.x;
+ var posY = contentSize.height * this._indicatorPositionAsAnchorPoint.y;
+ this._indicator.setPosition(cc.p(posX, posY));
+ }
+ },
+
+ _handleReleaseLogic: function (touchPoint) {
+
+ ccui.ScrollView.prototype._handleReleaseLogic.call(this, touchPoint);
+
+ if (this._items.length <= 0)
+ return;
+
+ var touchMoveVelocity = this._flattenVectorByDirection(this._calculateTouchMoveVelocity());
+
+ var INERTIA_THRESHOLD = 500;
+ if (cc.pLength(touchMoveVelocity) < INERTIA_THRESHOLD) {
+ this._startMagneticScroll();
+ }
+ else {
+ // Handle paging by inertia force.
+ var currentPage = this.getItem(this._curPageIdx);
+ var destination = this._calculateItemDestination(cc.p(0.5, 0.5), currentPage, cc.p(0.5, 0.5));
+ var deltaToCurrentPage = cc.pSub(destination, this.getInnerContainerPosition());
+ deltaToCurrentPage = this._flattenVectorByDirection(deltaToCurrentPage);
+
+ // If the direction of displacement to current page and the direction of touch are same, just start magnetic scroll to the current page.
+ // Otherwise, move to the next page of touch direction.
+ if (touchMoveVelocity.x * deltaToCurrentPage.x > 0 || touchMoveVelocity.y * deltaToCurrentPage.y > 0) {
+ this._startMagneticScroll();
+ }
+ else {
+ if (touchMoveVelocity.x < 0 || touchMoveVelocity.y > 0) {
+ ++this._curPageIdx;
+ }
+ else {
+ --this._curPageIdx;
+ }
+ this._curPageIdx = Math.min(this._curPageIdx, this._items.length);
+ this._curPageIdx = Math.max(this._curPageIdx, 0);
+ this.scrollToItem(this._curPageIdx);
+ }
+ }
+
+ },
+
+ _getAutoScrollStopEpsilon: function () {
+ return 0.001;
+ },
+
+ _pageTurningEvent: function () {
+ if (this._pageViewEventSelector) {
+ if (this._pageViewEventListener)
+ this._pageViewEventSelector.call(this._pageViewEventListener, this, ccui.PageView.EVENT_TURNING);
+ else
+ this._pageViewEventSelector(this, ccui.PageView.EVENT_TURNING);
+ }
+ if (this._ccEventCallback)
+ this._ccEventCallback(this, ccui.PageView.EVENT_TURNING);
+ },
+
+ /**
+ * Adds event listener to ccui.PageView.
+ * @param {Function} selector
+ * @param {Object} [target=]
+ * @deprecated since v3.0, please use addEventListener instead.
+ */
+ addEventListenerPageView: function (selector, target) {
+ this._pageViewEventSelector = selector;
+ this._pageViewEventListener = target;
+ },
+
+ addEventListener: function (selector) {
+ this._ccEventCallback = function (ref, eventType) {
+ if (eventType == ccui.ScrollView.EVENT_AUTOSCROLL_ENDED)
+ selector(this, eventType)
+ };
+ },
+
+ /**
+ * Jump to a page with a given index without scrolling.
+ * This is the different between scrollToPage.
+ * @param {number} index A given index in PageView. Index start from 0 to pageCount -1.
+ */
+ setCurrentPageIndex: function (index) {
+ this.jumpToItem(index, cc.p(0.5, 0.5), cc.p(0.5, 0.5));
+ },
+
+ /**
+ * Jump to a page with a given index without scrolling.
+ * This is the different between scrollToPage.
+ * @param {number} index A given index in PageView. Index start from 0 to pageCount -1.
+ * @deprecated since v3.9, this is deprecated. Use `setCurrentPageIndex()` instead.
+ */
+ setCurPageIndex: function (index) {
+ this.setCurrentPageIndex(index);
+ },
+
+ /**
+ * Returns current page index
+ * @returns {number}
+ */
+ getCurrentPageIndex: function () {
+ return this._curPageIdx;
+ },
+
+ /**
+ * Returns current page index
+ * @deprecated since v3.9, this is deprecated. Use `getCurrentPageIndex()` instead.
+ * @returns {number}
+ */
+ getCurPageIndex: function () {
+ var widget = this.getCenterItemInCurrentView();
+ return this.getIndex(widget);
+ },
+
+ /**
+ * Returns all pages of PageView
+ * @returns {Array}
+ */
+ getPages: function () {
+ return this.getItems();
+ },
+
+ /**
+ * Returns a page from PageView by index
+ * @param {Number} index
+ * @returns {ccui.Layout}
+ */
+ getPage: function (index) {
+ return this.getItem(index);
+ },
+
+ /**
+ * Returns the "class name" of ccui.PageView.
+ * @returns {string}
+ */
+ getDescription: function () {
+ return "PageView";
+ },
+
+ _createCloneInstance: function () {
+ return new ccui.PageView();
+ },
+
+ _copyClonedWidgetChildren: function (model) {
+ var arrayPages = model.getPages();
+ for (var i = 0; i < arrayPages.length; i++) {
+ var page = arrayPages[i];
+ this.addPage(page.clone());
+ }
+ },
+
+ _copySpecialProperties: function (pageView) {
+ ccui.ListView.prototype._copySpecialProperties.call(this, pageView);
+ this._ccEventCallback = pageView._ccEventCallback;
+ this._pageViewEventListener = pageView._pageViewEventListener;
+ this._pageViewEventSelector = pageView._pageViewEventSelector;
+ this._customScrollThreshold = pageView._customScrollThreshold;
+ },
+
+
+ /**
+ * Toggle page indicator enabled.
+ * @param {boolean} enabled True if enable page indicator, false otherwise.
+ */
+ setIndicatorEnabled: function (enabled) {
+ if (enabled == (this._indicator !== null)) {
+ return;
+ }
+
+ if (!enabled) {
+ this.removeProtectedChild(this._indicator);
+ this._indicator = null;
+ }
+ else {
+ this._indicator = new ccui.PageViewIndicator();
+ this._indicator.setDirection(this.getDirection());
+ this.addProtectedChild(this._indicator, 10000);
+ this.setIndicatorSelectedIndexColor(cc.color(100, 100, 255));
+ this._refreshIndicatorPosition();
+ }
+ },
+
+ /**
+ * Query page indicator state.
+ * @returns {boolean} True if page indicator is enabled, false otherwise.
+ */
+ getIndicatorEnabled: function () {
+ return this._indicator !== null;
+ },
+
+ /**
+ * Set the page indicator's position using anchor point.
+ * @param {cc.Point} positionAsAnchorPoint The position as anchor point.
+ */
+ setIndicatorPositionAsAnchorPoint: function (positionAsAnchorPoint) {
+ this._indicatorPositionAsAnchorPoint = positionAsAnchorPoint;
+ this._refreshIndicatorPosition();
+ },
+
+ /**
+ * Get the page indicator's position as anchor point.
+ * @returns {cc.Point}
+ */
+ getIndicatorPositionAsAnchorPoint: function () {
+ return this._indicatorPositionAsAnchorPoint;
+ },
+
+ /**
+ * Set the page indicator's position in page view.
+ * @param {cc.Point} position The position in page view
+ */
+ setIndicatorPosition: function (position) {
+ if (this._indicator) {
+ var contentSize = this.getContentSize();
+ this._indicatorPositionAsAnchorPoint.x = position.x / contentSize.width;
+ this._indicatorPositionAsAnchorPoint.y = position.y / contentSize.height;
+ this._indicator.setPosition(position);
+ }
+ },
+
+ /**
+ * Get the page indicator's position.
+ * @returns {cc.Point}
+ */
+ getIndicatorPosition: function () {
+ cc.assert(this._indicator !== null, "");
+ return this._indicator.getPosition();
+ },
+
+ /**
+ * Set space between page indicator's index nodes.
+ * @param {number} spaceBetweenIndexNodes Space between nodes in pixel.
+ */
+ setIndicatorSpaceBetweenIndexNodes: function (spaceBetweenIndexNodes) {
+ if (this._indicator) {
+ this._indicator.setSpaceBetweenIndexNodes(spaceBetweenIndexNodes);
+ }
+ },
+
+ /**
+ * Get the space between page indicator's index nodes.
+ * @returns {number}
+ */
+ getIndicatorSpaceBetweenIndexNodes: function () {
+ cc.assert(this._indicator !== null, "");
+ return this._indicator.getSpaceBetweenIndexNodes();
+ },
+
+ /**
+ * Set color of page indicator's selected index.
+ * @param {cc.Color} color Color for indicator
+ */
+ setIndicatorSelectedIndexColor: function (color) {
+ if (this._indicator) {
+ this._indicator.setSelectedIndexColor(color);
+ }
+ },
+
+ /**
+ * Get the color of page indicator's selected index.
+ * @returns {cc.Color}
+ */
+ getIndicatorSelectedIndexColor: function () {
+ cc.assert(this._indicator !== null, "");
+ return this._indicator.getSelectedIndexColor();
+ },
+
+ /**
+ * Set color of page indicator's index nodes.
+ * @param {cc.Color} color Color for indicator
+ */
+ setIndicatorIndexNodesColor: function (color) {
+ if (this._indicator) {
+ this._indicator.setIndexNodesColor(color);
+ }
+ },
+
+ /**
+ * Get the color of page indicator's index nodes.
+ * @returns {cc.Color}
+ */
+ getIndicatorIndexNodesColor: function () {
+ cc.assert(this._indicator !== null, "");
+ return this._indicator.getIndexNodesColor();
+ },
+
+ /**
+ * Set scale of page indicator's index nodes.
+ * @param {Number} scale Scale for indicator
+ */
+ setIndicatorIndexNodesScale: function (indexNodesScale) {
+ if (this._indicator) {
+ this._indicator.setIndexNodesScale(indexNodesScale);
+ this._indicator.indicate(this._curPageIdx);
+ }
+ },
+
+ /**
+ * Get the scale of page indicator's index nodes.
+ * @returns {Number}
+ */
+ getIndicatorIndexNodesScale: function () {
+ cc.assert(this._indicator !== null, "");
+ return this._indicator.getIndexNodesScale();
+ },
+
+ /**
+ * Sets texture of indicator index nodes
+ * @param {String} texName
+ * @param {ccui.Widget.LOCAL_TEXTURE | ccui.Widget.PLIST_TEXTURE} [texType = ccui.Widget.LOCAL_TEXTURE]
+ */
+ setIndicatorIndexNodesTexture: function (texName, texType) {
+ if (this._indicator) {
+ this._indicator.setIndexNodesTexture(texName, texType);
+ this._indicator.indicate(this._curPageIdx);
+ }
+ }
+});
+/**
+ * allocates and initializes a UIPageView.
+ * @deprecated since v3.0, please use new ccui.PageView() instead.
+ * @return {ccui.PageView}
+ */
+ccui.PageView.create = function () {
+ return new ccui.PageView();
+};
+
+// Constants
+//PageView event
+/**
+ * The turning flag of ccui.PageView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.PageView.EVENT_TURNING = 0;
+
+//PageView touch direction
+/**
+ * The left flag of ccui.PageView's touch direction.
+ * @constant
+ * @type {number}
+ */
+ccui.PageView.TOUCH_DIR_LEFT = 0;
+/**
+ * The right flag of ccui.PageView's touch direction.
+ * @constant
+ * @type {number}
+ */
+ccui.PageView.TOUCH_DIR_RIGHT = 1;
+
+//PageView auto scroll direction
+/**
+ * The right flag of ccui.PageView's auto scroll direction.
+ * @constant
+ * @type {number}
+ */
+ccui.PageView.DIRECTION_LEFT = 0;
+/**
+ * The right flag of ccui.PageView's auto scroll direction.
+ * @constant
+ * @type {number}
+ */
+ccui.PageView.DIRECTION_RIGHT = 1;
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js
new file mode 100644
index 0000000..8044ba2
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js
@@ -0,0 +1,305 @@
+/****************************************************************************
+ Copyright (c) 2015 Neo Kim (neo.kim@neofect.com)
+ Copyright (c) 2015 Nikita Besshaposhnikov (nikita.besshaposhnikov@gmail.com)
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The PageViewIndicator control of Cocos UI
+ * Indicator being attached to page view.
+ * @class
+ * @extends ccui.ProtectedNode
+ * @property {Number} spaceBetweenIndexNodes - Space between index nodes in PageViewIndicator
+ */
+ccui.PageViewIndicator = ccui.ProtectedNode.extend(/** @lends ccui.PageViewIndicator# */{
+ _direction: null,
+ _indexNodes: null,
+ _currentIndexNode: null,
+ _spaceBetweenIndexNodes: 0,
+ _indexNodesScale: 1.0,
+ _indexNodesColor: null,
+ _useDefaultTexture: true,
+ _indexNodesTextureFile: "",
+ _indexNodesTexType: ccui.Widget.LOCAL_TEXTURE,
+
+ _className: "PageViewIndicator",
+
+ /**
+ * Allocates and initializes a PageViewIndicator.
+ * Constructor of ccui.PageViewIndicator. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor: function () {
+ cc.ProtectedNode.prototype.ctor.call(this);
+
+ this._direction = ccui.ScrollView.DIR_HORIZONTAL;
+ this._indexNodes = [];
+ this._spaceBetweenIndexNodes = ccui.PageViewIndicator.SPACE_BETWEEN_INDEX_NODES_DEFAULT;
+ this._indexNodesColor = cc.color.WHITE;
+
+ this._currentIndexNode = ccui.helper._createSpriteFromBase64(ccui.PageViewIndicator.CIRCLE_IMAGE, ccui.PageViewIndicator.CIRCLE_IMAGE_KEY);
+ this._currentIndexNode.setVisible(false);
+ this.addProtectedChild(this._currentIndexNode, 1);
+
+ // this.setCascadeColorEnabled(true);
+ // this.setCascadeOpacityEnabled(true);
+ },
+
+ /**
+ * Sets direction of indicator
+ * @param {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_BOTH} direction
+ */
+ setDirection: function (direction) {
+ this._direction = direction;
+ this._rearrange();
+ },
+
+ /**
+ * resets indicator with new page count.
+ * @param {number} numberOfTotalPages
+ */
+ reset: function (numberOfTotalPages) {
+ while (this._indexNodes.length < numberOfTotalPages) {
+ this._increaseNumberOfPages();
+ }
+ while (this._indexNodes.length > numberOfTotalPages) {
+ this._decreaseNumberOfPages();
+ }
+ this._rearrange();
+ this._currentIndexNode.setVisible(this._indexNodes.length > 0);
+ },
+
+ /**
+ * Indicates node by index
+ * @param {number} index
+ */
+ indicate: function (index) {
+ if (index < 0 || index >= this._indexNodes.length) {
+ return;
+ }
+ this._currentIndexNode.setPosition(this._indexNodes[index].getPosition());
+ },
+
+ _rearrange: function () {
+ if (this._indexNodes.length === 0) {
+ return;
+ }
+
+ var horizontal = (this._direction === ccui.ScrollView.DIR_HORIZONTAL);
+
+ // Calculate total size
+ var indexNodeSize = this._indexNodes[0].getContentSize();
+ var sizeValue = (horizontal ? indexNodeSize.width : indexNodeSize.height);
+
+ var numberOfItems = this._indexNodes.length;
+ var totalSizeValue = sizeValue * numberOfItems + this._spaceBetweenIndexNodes * (numberOfItems - 1);
+
+ var posValue = -(totalSizeValue / 2) + (sizeValue / 2);
+ for (var i = 0; i < this._indexNodes.length; ++i) {
+ var position;
+ if (horizontal) {
+ position = cc.p(posValue, indexNodeSize.height / 2.0);
+ }
+ else {
+ position = cc.p(indexNodeSize.width / 2.0, -posValue);
+ }
+ this._indexNodes[i].setPosition(position);
+ posValue += sizeValue + this._spaceBetweenIndexNodes;
+ }
+ },
+
+ /**
+ * Sets space between index nodes.
+ * @param {number} spaceBetweenIndexNodes
+ */
+ setSpaceBetweenIndexNodes: function (spaceBetweenIndexNodes) {
+ if (this._spaceBetweenIndexNodes === spaceBetweenIndexNodes) {
+ return;
+ }
+ this._spaceBetweenIndexNodes = spaceBetweenIndexNodes;
+ this._rearrange();
+ },
+
+ /**
+ * Gets space between index nodes.
+ * @returns {number}
+ */
+ getSpaceBetweenIndexNodes: function () {
+ return this._spaceBetweenIndexNodes;
+ },
+
+ /**
+ * Sets color of selected index node
+ * @param {cc.Color} color
+ */
+ setSelectedIndexColor: function (color) {
+ this._currentIndexNode.setColor(color);
+ },
+
+ /**
+ * Gets color of selected index node
+ * @returns {cc.Color}
+ */
+ getSelectedIndexColor: function () {
+ return this._currentIndexNode.getColor();
+ },
+
+ /**
+ * Sets color of index nodes
+ * @param {cc.Color} indexNodesColor
+ */
+ setIndexNodesColor: function (indexNodesColor) {
+ this._indexNodesColor = indexNodesColor;
+
+ for (var i = 0; i < this._indexNodes.length; ++i) {
+ this._indexNodes[i].setColor(indexNodesColor);
+ }
+ },
+
+ /**
+ * Gets color of index nodes
+ * @returns {cc.Color}
+ */
+ getIndexNodesColor: function () {
+ var locRealColor = this._indexNodesColor;
+ return cc.color(locRealColor.r, locRealColor.g, locRealColor.b, locRealColor.a);
+ },
+
+ /**
+ * Sets scale of index nodes
+ * @param {Number} indexNodesScale
+ */
+ setIndexNodesScale: function (indexNodesScale) {
+ if (this._indexNodesScale === indexNodesScale) {
+ return;
+ }
+ this._indexNodesScale = indexNodesScale;
+
+ this._currentIndexNode.setScale(indexNodesScale);
+
+ for (var i = 0; i < this._indexNodes.length; ++i) {
+ this._indexNodes[i].setScale(this, _indexNodesScale);
+ }
+
+ this._rearrange();
+ },
+
+ /**
+ * Gets scale of index nodes
+ * @returns {Number}
+ */
+ getIndexNodesScale: function () {
+ return this._indexNodesScale;
+ },
+
+ /**
+ * Sets texture of index nodes
+ * @param {String} texName
+ * @param {ccui.Widget.LOCAL_TEXTURE | ccui.Widget.PLIST_TEXTURE} [texType = ccui.Widget.LOCAL_TEXTURE]
+ */
+ setIndexNodesTexture: function (texName, texType) {
+ if (texType === undefined)
+ texType = ccui.Widget.LOCAL_TEXTURE;
+
+ this._useDefaultTexture = false;
+ this._indexNodesTextureFile = texName;
+ this._indexNodesTexType = texType;
+
+ switch (texType) {
+ case ccui.Widget.LOCAL_TEXTURE:
+ this._currentIndexNode.setTexture(texName);
+ for (var i = 0; i < this._indexNodes.length; ++i) {
+ this._indexNodes[i].setTexture(texName);
+ }
+ break;
+ case ccui.Widget.PLIST_TEXTURE:
+ this._currentIndexNode.setSpriteFrame(texName);
+ for (var i = 0; i < this._indexNodes.length; ++i) {
+ this._indexNodes[i].setSpriteFrame(texName);
+ }
+ break;
+ default:
+ break;
+ }
+
+ this._rearrange();
+ },
+
+ _increaseNumberOfPages: function () {
+ var indexNode;
+
+ if (this._useDefaultTexture) {
+ indexNode = ccui.helper._createSpriteFromBase64(ccui.PageViewIndicator.CIRCLE_IMAGE, ccui.PageViewIndicator.CIRCLE_IMAGE_KEY);
+ }
+ else {
+ indexNode = new cc.Sprite();
+ switch (this._indexNodesTexType) {
+ case ccui.Widget.LOCAL_TEXTURE:
+ indexNode.initWithFile(this._indexNodesTextureFile);
+ break;
+ case ccui.Widget.PLIST_TEXTURE:
+ indexNode.initWithSpriteFrameName(this._indexNodesTextureFile);
+ break;
+ default:
+ break;
+ }
+ }
+
+ indexNode.setColor(this._indexNodesColor);
+ indexNode.setScale(this._indexNodesScale);
+
+ this.addProtectedChild(indexNode);
+ this._indexNodes.push(indexNode);
+ },
+
+ _decreaseNumberOfPages: function () {
+ if (this._indexNodes.length === 0) {
+ return;
+ }
+ this.removeProtectedChild(this._indexNodes[0]);
+ this._indexNodes.splice(0, 1);
+ },
+
+ /**
+ * Removes all index nodes.
+ */
+ clear: function () {
+ for (var i = 0; i < this._indexNodes.length; ++i) {
+ this.removeProtectedChild(this._indexNodes[i]);
+ }
+ this._indexNodes.length = 0;
+ this._currentIndexNode.setVisible(false);
+ }
+
+});
+
+var _p = ccui.PageViewIndicator.prototype;
+
+// Extended properties
+/** @expose */
+_p.spaceBetweenIndexNodes;
+cc.defineGetterSetter(_p, "spaceBetweenIndexNodes", _p.getSpaceBetweenIndexNodes, _p.setSpaceBetweenIndexNodes);
+/**
+ * @ignore
+ */
+ccui.PageViewIndicator.SPACE_BETWEEN_INDEX_NODES_DEFAULT = 23;
+ccui.PageViewIndicator.CIRCLE_IMAGE_KEY = "/__circle_image";
+ccui.PageViewIndicator.CIRCLE_IMAGE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAA8ElEQVRIx62VyRGCQBBF+6gWRCEmYDIQkhiBCgHhSclC8YqWzOV5oVzKAYZp3r1/9fpbxAIBMTsKrjx5cqVgR0wgLhCRUWOjJiPqD56xoaGPhpRZV/iSEy6crHmw5oIrF9b/lVeMofrJgjlnxlIy/wik+JB+mme8BExbBhm+5CJC2LE2LtSEQoyGWDioBA5CoRIohJtK4CYDxzNEM4GAugR1E9VjVC+SZpXvhCJCrjomESLvc17pDGX7bWmlh6UtpjPVCWy9zaJ0TD7qfm3pwERMz2trRVZk3K3BD/L34AY+dEDCniMVBkPFkT2J/b2/AIV+dRpFLOYoAAAAAElFTkSuQmCC";
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js
new file mode 100644
index 0000000..79741c9
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js
@@ -0,0 +1,1927 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The ScrollView control of Cocos UI
+ * @class
+ * @extends ccui.Layout
+ *
+ * @property {Number} innerWidth - Inner container width of the scroll view
+ * @property {Number} innerHeight - Inner container height of the scroll view
+ * @property {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_BOTH} direction - Scroll direction of the scroll view
+ * @property {Boolean} bounceEnabled - Indicate whether bounce is enabled
+ * @property {Boolean} inertiaScrollEnabled - Indicate whether inertiaScroll is enabled
+ * @property {Number} touchTotalTimeThreshold - Touch total time threshold
+ */
+ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{
+ _innerContainer: null,
+ _direction: null,
+
+ _topBoundary: 0,
+ _bottomBoundary: 0,
+ _leftBoundary: 0,
+ _rightBoundary: 0,
+
+ _touchMoveDisplacements: null,
+ _touchMoveTimeDeltas: null,
+ _touchMovePreviousTimestamp: 0,
+ _touchTotalTimeThreshold: 0.5,
+
+ _autoScrolling: false,
+ _autoScrollTargetDelta: null,
+ _autoScrollAttenuate: true,
+ _autoScrollStartPosition: null,
+ _autoScrollTotalTime: 0,
+ _autoScrollAccumulatedTime: 0,
+ _autoScrollCurrentlyOutOfBoundary: false,
+ _autoScrollBraking: false,
+ _autoScrollBrakingStartPosition: null,
+
+ _bePressed: false,
+
+ _childFocusCancelOffset: 0,
+
+ bounceEnabled: false,
+
+ _outOfBoundaryAmount: null,
+ _outOfBoundaryAmountDirty: true,
+
+ inertiaScrollEnabled: false,
+
+ _scrollBarEnabled: true,
+ _verticalScrollBar: null,
+ _horizontalScrollBar: null,
+
+ _scrollViewEventListener: null,
+ _scrollViewEventSelector: null,
+ _className: "ScrollView",
+
+ /**
+ * Allocates and initializes a UIScrollView.
+ * Constructor of ccui.ScrollView. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @example
+ * // example
+ * var uiScrollView = new ccui.ScrollView();
+ */
+ ctor: function () {
+ ccui.Layout.prototype.ctor.call(this);
+ this.setClippingEnabled(true);
+ this._innerContainer.setTouchEnabled(false);
+
+ this._direction = ccui.ScrollView.DIR_NONE;
+
+ this._childFocusCancelOffset = 5;
+ this.inertiaScrollEnabled = true;
+
+ this._outOfBoundaryAmount = cc.p(0, 0);
+ this._autoScrollTargetDelta = cc.p(0, 0);
+ this._autoScrollStartPosition = cc.p(0, 0);
+ this._autoScrollBrakingStartPosition = cc.p(0, 0);
+ this._touchMoveDisplacements = [];
+ this._touchMoveTimeDeltas = [];
+ this._touchMovePreviousTimestamp = 0;
+
+ this._scrollBarEnabled = true;
+ this._initScrollBar();
+
+ this.setTouchEnabled(true);
+ },
+
+ /**
+ * Calls the parent class' onEnter and schedules update function.
+ * @override
+ */
+ onEnter: function () {
+ ccui.Layout.prototype.onEnter.call(this);
+ this.scheduleUpdate();
+ },
+
+ onExit: function () {
+ cc.renderer._removeCache(this.__instanceId);
+ ccui.Layout.prototype.onExit.call(this);
+ },
+
+ visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
+
+ this._adaptRenderers();
+ this._doLayout();
+
+ var renderer = cc.renderer;
+ cmd.visit(parentCmd);
+
+ renderer.pushRenderCommand(cmd);
+ if (cmd instanceof ccui.ScrollView.WebGLRenderCmd) {
+ var currentID = this.__instanceId;
+ renderer._turnToCacheMode(currentID);
+ }
+
+ var stencilClipping = this._clippingEnabled && this._clippingType === ccui.Layout.CLIPPING_STENCIL;
+ var scissorClipping = this._clippingEnabled && this._clippingType === ccui.Layout.CLIPPING_SCISSOR;
+
+ if (stencilClipping) {
+ cmd.stencilClippingVisit(parentCmd);
+ }
+ else if (scissorClipping) {
+ cmd.scissorClippingVisit(parentCmd);
+ }
+
+ var i, children = this._children, len = children.length, child;
+ var j, pChildren = this._protectedChildren, pLen = pChildren.length, pChild;
+
+ if (this._reorderChildDirty) this.sortAllChildren();
+ if (this._reorderProtectedChildDirty) this.sortAllProtectedChildren();
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child && child._visible) {
+ child.visit(this);
+ }
+ }
+ for (j = 0; j < pLen; j++) {
+ pChild = pChildren[j];
+ if (pChild && pChild._visible) {
+ cmd._changeProtectedChild(pChild);
+ pChild.visit(this);
+ }
+ }
+
+ if (stencilClipping) {
+ cmd.postStencilVisit();
+ }
+ else if (scissorClipping) {
+ cmd.postScissorVisit();
+ }
+
+ if (cmd instanceof ccui.ScrollView.WebGLRenderCmd) {
+ renderer._turnToNormalMode();
+ }
+
+ // Need to update children after do layout
+ this.updateChildren();
+
+ cmd._dirtyFlag = 0;
+ },
+
+ /**
+ * When a widget is in a layout, you could call this method to get the next focused widget within a specified _direction.
+ * If the widget is not in a layout, it will return itself
+ *
+ * @param {Number} _direction the _direction to look for the next focused widget in a layout
+ * @param {ccui.Widget} current the current focused widget
+ * @returns {ccui.Widget}
+ */
+ findNextFocusedWidget: function (direction, current) {
+ if (this.getLayoutType() === ccui.Layout.LINEAR_VERTICAL
+ || this.getLayoutType() === ccui.Layout.LINEAR_HORIZONTAL) {
+ return this._innerContainer.findNextFocusedWidget(direction, current);
+ } else
+ return ccui.Widget.prototype.findNextFocusedWidget.call(this, direction, current);
+ },
+
+ _initRenderer: function () {
+ ccui.Layout.prototype._initRenderer.call(this);
+
+ this._innerContainer = new ccui.Layout();
+ this._innerContainer.setColor(cc.color(255, 255, 255));
+ this._innerContainer.setOpacity(255);
+ this._innerContainer.setCascadeColorEnabled(true);
+ this._innerContainer.setCascadeOpacityEnabled(true);
+
+ this.addProtectedChild(this._innerContainer, 1, 1);
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ return new ccui.ScrollView.WebGLRenderCmd(this);
+ else
+ return new ccui.ScrollView.CanvasRenderCmd(this);
+ },
+
+ _onSizeChanged: function () {
+ ccui.Layout.prototype._onSizeChanged.call(this);
+ var locSize = this._contentSize;
+ this._topBoundary = locSize.height;
+ this._rightBoundary = locSize.width;
+ var innerSize = this._innerContainer.getContentSize();
+ this._innerContainer.setContentSize(cc.size(Math.max(innerSize.width, locSize.width), Math.max(innerSize.height, locSize.height)));
+ this._innerContainer.setPosition(0, locSize.height - this._innerContainer.getContentSize().height);
+
+ if(this._verticalScrollBar)
+ this._verticalScrollBar.onScrolled(this._getHowMuchOutOfBoundary());
+
+ if(this._horizontalScrollBar)
+ this._horizontalScrollBar.onScrolled(this._getHowMuchOutOfBoundary());
+ },
+
+ /**
+ * Changes inner container size of ScrollView.
+ * Inner container size must be larger than or equal the size of ScrollView.
+ * @param {cc.Size} size inner container size.
+ */
+ setInnerContainerSize: function (size) {
+ var innerContainer = this._innerContainer,
+ locSize = this._contentSize,
+ innerSizeWidth = locSize.width, innerSizeHeight = locSize.height;
+
+ if (size.width < locSize.width)
+ cc.log("Inner width <= ScrollView width, it will be force sized!");
+ else
+ innerSizeWidth = size.width;
+
+ if (size.height < locSize.height)
+ cc.log("Inner height <= ScrollView height, it will be force sized!");
+ else
+ innerSizeHeight = size.height;
+
+ innerContainer.setContentSize(cc.size(innerSizeWidth, innerSizeHeight));
+
+ var pos = this._innerContainer.getPosition();
+ var contAP = this._innerContainer.getAnchorPoint();
+
+ if (this._innerContainer.getLeftBoundary() != 0.0)
+ {
+ pos.x = contAP.x * innerSizeWidth;
+ }
+ if (this._innerContainer.getTopBoundary() != this._contentSize.height)
+ {
+ pos.y = this._contentSize.height - (1.0 - contAP.y) * innerSizeHeight;
+ }
+ this.setInnerContainerPosition(pos);
+
+ this._updateScrollBar(cc.p(0 ,0));
+ },
+
+ _setInnerWidth: function (width) {
+ var locW = this._contentSize.width,
+ innerWidth = locW,
+ container = this._innerContainer,
+ oldInnerWidth = container.width;
+ if (width < locW)
+ cc.log("Inner width <= scrollview width, it will be force sized!");
+ else
+ innerWidth = width;
+ container.width = innerWidth;
+
+ switch (this._direction) {
+ case ccui.ScrollView.DIR_HORIZONTAL:
+ case ccui.ScrollView.DIR_BOTH:
+ if (container.getRightBoundary() <= locW) {
+ var newInnerWidth = container.width;
+ var offset = oldInnerWidth - newInnerWidth;
+ this._scrollChildren(offset, 0);
+ }
+ break;
+ }
+ var innerAX = container.anchorX;
+ if (container.getLeftBoundary() > 0.0)
+ container.x = innerAX * innerWidth;
+ if (container.getRightBoundary() < locW)
+ container.x = locW - ((1.0 - innerAX) * innerWidth);
+ },
+
+ _setInnerHeight: function (height) {
+ var locH = this._contentSize.height,
+ innerHeight = locH,
+ container = this._innerContainer,
+ oldInnerHeight = container.height;
+ if (height < locH)
+ cc.log("Inner height <= scrollview height, it will be force sized!");
+ else
+ innerHeight = height;
+ container.height = innerHeight;
+
+ switch (this._direction) {
+ case ccui.ScrollView.DIR_VERTICAL:
+ case ccui.ScrollView.DIR_BOTH:
+ var newInnerHeight = innerHeight;
+ var offset = oldInnerHeight - newInnerHeight;
+ this._scrollChildren(0, offset);
+ break;
+ }
+ var innerAY = container.anchorY;
+ if (container.getLeftBoundary() > 0.0)
+ container.y = innerAY * innerHeight;
+ if (container.getRightBoundary() < locH)
+ container.y = locH - ((1.0 - innerAY) * innerHeight);
+ },
+ /**
+ * Set inner container position
+ *
+ * @param {cc.Point} position Inner container position.
+ */
+ setInnerContainerPosition: function (position) {
+ if (position.x === this._innerContainer.getPositionX() && position.y === this._innerContainer.getPositionY()) {
+ return;
+ }
+ this._innerContainer.setPosition(position);
+ this._outOfBoundaryAmountDirty = true;
+
+ // Process bouncing events
+ if (this.bounceEnabled) {
+ for (var _direction = ccui.ScrollView.MOVEDIR_TOP; _direction < ccui.ScrollView.MOVEDIR_RIGHT; ++_direction) {
+ if (this._isOutOfBoundary(_direction)) {
+ this._processScrollEvent(_direction, true);
+ }
+ }
+ }
+
+ this._dispatchEvent(ccui.ScrollView.EVENT_CONTAINER_MOVED);
+ },
+
+ /**
+ * Get inner container position
+ *
+ * @return The inner container position.
+ */
+ getInnerContainerPosition: function () {
+ return this._innerContainer.getPosition();
+ },
+
+ /**
+ * Returns inner container size of ScrollView.
+ * Inner container size must be larger than or equal ScrollView's size.
+ *
+ * @return {cc.Size} inner container size.
+ */
+ getInnerContainerSize: function () {
+ return this._innerContainer.getContentSize();
+ },
+ _getInnerWidth: function () {
+ return this._innerContainer.width;
+ },
+ _getInnerHeight: function () {
+ return this._innerContainer.height;
+ },
+
+ _isInContainer: function (widget) {
+ if (!this._clippingEnabled)
+ return true;
+ var wPos = widget._position,
+ wSize = widget._contentSize,
+ wAnchor = widget._anchorPoint,
+ size = this._customSize,
+ pos = this._innerContainer._position,
+ bottom = 0, left = 0;
+ if (
+ // Top
+ (bottom = wPos.y - wAnchor.y * wSize.height) >= size.height - pos.y ||
+ // Bottom
+ bottom + wSize.height <= -pos.y ||
+ // right
+ (left = wPos.x - wAnchor.x * wSize.width) >= size.width - pos.x ||
+ // left
+ left + wSize.width <= -pos.x
+ )
+ return false;
+ else return true;
+ },
+
+ updateChildren: function () {
+ var child, i, l;
+ var childrenArray = this._innerContainer._children;
+ for (i = 0, l = childrenArray.length; i < l; i++) {
+ child = childrenArray[i];
+ if (child._inViewRect === true && this._isInContainer(child) === false)
+ child._inViewRect = false;
+ else if (child._inViewRect === false && this._isInContainer(child) === true)
+ child._inViewRect = true;
+ }
+ },
+ /**
+ * Add child to ccui.ScrollView.
+ * @param {cc.Node} widget
+ * @param {Number} [zOrder]
+ * @param {Number|string} [tag] tag or name
+ * @returns {boolean}
+ */
+ addChild: function (widget, zOrder, tag) {
+ if (!widget)
+ return false;
+ if (this._isInContainer(widget) === false)
+ widget._inViewRect = false;
+ zOrder = zOrder || widget.getLocalZOrder();
+ tag = tag || widget.getTag();
+ return this._innerContainer.addChild(widget, zOrder, tag);
+ },
+
+ /**
+ * Removes all children.
+ */
+ removeAllChildren: function () {
+ this.removeAllChildrenWithCleanup(true);
+ },
+
+ /**
+ * Removes all children.
+ * @param {Boolean} cleanup
+ */
+ removeAllChildrenWithCleanup: function (cleanup) {
+ this._innerContainer.removeAllChildrenWithCleanup(cleanup);
+ },
+
+ /**
+ * Removes widget child
+ * @override
+ * @param {ccui.Widget} child
+ * @param {Boolean} cleanup
+ * @returns {boolean}
+ */
+ removeChild: function (child, cleanup) {
+ return this._innerContainer.removeChild(child, cleanup);
+ },
+
+ /**
+ * Returns inner container's children
+ * @returns {Array}
+ */
+ getChildren: function () {
+ return this._innerContainer.getChildren();
+ },
+
+ /**
+ * Gets the count of inner container's children
+ * @returns {Number}
+ */
+ getChildrenCount: function () {
+ return this._innerContainer.getChildrenCount();
+ },
+
+ /**
+ * Gets a child from the container given its tag
+ * @param {Number} tag
+ * @returns {ccui.Widget}
+ */
+ getChildByTag: function (tag) {
+ return this._innerContainer.getChildByTag(tag);
+ },
+
+ /**
+ * Gets a child from the container given its name
+ * @param {String} name
+ * @returns {ccui.Widget}
+ */
+ getChildByName: function (name) {
+ return this._innerContainer.getChildByName(name);
+ },
+
+ _flattenVectorByDirection: function (vector) {
+ var result = cc.p(0, 0);
+ result.x = (this._direction === ccui.ScrollView.DIR_VERTICAL ? 0 : vector.x);
+ result.y = (this._direction === ccui.ScrollView.DIR_HORIZONTAL ? 0 : vector.y);
+ return result;
+ },
+
+ _getHowMuchOutOfBoundary: function (addition) {
+ if (addition === undefined)
+ addition = cc.p(0, 0);
+
+ if (addition.x === 0 && addition.y === 0 && !this._outOfBoundaryAmountDirty) {
+ return this._outOfBoundaryAmount;
+ }
+
+ var outOfBoundaryAmount = cc.p(0, 0);
+
+ if (this._innerContainer.getLeftBoundary() + addition.x > this._leftBoundary) {
+ outOfBoundaryAmount.x = this._leftBoundary - (this._innerContainer.getLeftBoundary() + addition.x);
+ }
+ else if (this._innerContainer.getRightBoundary() + addition.x < this._rightBoundary) {
+ outOfBoundaryAmount.x = this._rightBoundary - (this._innerContainer.getRightBoundary() + addition.x);
+ }
+
+ if (this._innerContainer.getTopBoundary() + addition.y < this._topBoundary) {
+ outOfBoundaryAmount.y = this._topBoundary - (this._innerContainer.getTopBoundary() + addition.y);
+ }
+ else if (this._innerContainer.getBottomBoundary() + addition.y > this._bottomBoundary) {
+ outOfBoundaryAmount.y = this._bottomBoundary - (this._innerContainer.getBottomBoundary() + addition.y);
+ }
+
+ if (addition.x === 0 && addition.y === 0) {
+ this._outOfBoundaryAmount = outOfBoundaryAmount;
+ this._outOfBoundaryAmountDirty = false;
+ }
+ return outOfBoundaryAmount;
+ },
+
+ _isOutOfBoundary: function (dir) {
+ var outOfBoundary = this._getHowMuchOutOfBoundary();
+ if (dir !== undefined) {
+ switch (dir) {
+ case ccui.ScrollView.MOVEDIR_TOP:
+ return outOfBoundary.y > 0;
+ case ccui.ScrollView.MOVEDIR_BOTTOM:
+ return outOfBoundary.y < 0;
+ case ccui.ScrollView.MOVEDIR_LEFT:
+ return outOfBoundary.x < 0;
+ case ccui.ScrollView.MOVEDIR_RIGHT:
+ return outOfBoundary.x > 0;
+ }
+ }
+ else {
+ return !this._fltEqualZero(outOfBoundary);
+ }
+
+ return false;
+ },
+
+
+ _moveInnerContainer: function (deltaMove, canStartBounceBack) {
+ var adjustedMove = this._flattenVectorByDirection(deltaMove);
+
+ this.setInnerContainerPosition(cc.pAdd(this.getInnerContainerPosition(), adjustedMove));
+
+ var outOfBoundary = this._getHowMuchOutOfBoundary();
+ this._updateScrollBar(outOfBoundary);
+
+ if (this.bounceEnabled && canStartBounceBack) {
+ this._startBounceBackIfNeeded();
+ }
+ },
+
+ _updateScrollBar: function(outOfBoundary)
+ {
+ if(this._verticalScrollBar)
+ {
+ this._verticalScrollBar.onScrolled(outOfBoundary);
+ }
+ if(this._horizontalScrollBar)
+ {
+ this._horizontalScrollBar.onScrolled(outOfBoundary);
+ }
+ },
+
+ _calculateTouchMoveVelocity: function () {
+ var totalTime = 0;
+ for (var i = 0; i < this._touchMoveTimeDeltas.length; ++i) {
+ totalTime += this._touchMoveTimeDeltas[i];
+ }
+ if (totalTime == 0 || totalTime >= this._touchTotalTimeThreshold) {
+ return cc.p(0, 0);
+ }
+
+ var totalMovement = cc.p(0, 0);
+
+ for (var i = 0; i < this._touchMoveDisplacements.length; ++i) {
+ totalMovement.x += this._touchMoveDisplacements[i].x;
+ totalMovement.y += this._touchMoveDisplacements[i].y;
+ }
+
+ return cc.pMult(totalMovement, 1 / totalTime);
+ },
+
+ /**
+ * Set the touch total time threshold
+ * @param {Number} touchTotalTimeThreshold
+ */
+ setTouchTotalTimeThreshold: function (touchTotalTimeThreshold) {
+ this._touchTotalTimeThreshold = touchTotalTimeThreshold;
+ },
+
+
+ /**
+ * Get the touch total time threshold
+ * @returns {Number}
+ */
+ getTouchTotalTimeThreshold: function () {
+ return this._touchTotalTimeThreshold;
+ },
+
+ _startInertiaScroll: function (touchMoveVelocity) {
+ var MOVEMENT_FACTOR = 0.7;
+ var inertiaTotalMovement = cc.pMult(touchMoveVelocity, MOVEMENT_FACTOR);
+ this._startAttenuatingAutoScroll(inertiaTotalMovement, touchMoveVelocity);
+ },
+
+ _startBounceBackIfNeeded: function () {
+ if (!this.bounceEnabled) {
+ return false;
+ }
+ var bounceBackAmount = this._getHowMuchOutOfBoundary();
+ if (this._fltEqualZero(bounceBackAmount)) {
+ return false;
+ }
+
+ var BOUNCE_BACK_DURATION = 1.0;
+ this._startAutoScroll(bounceBackAmount, BOUNCE_BACK_DURATION, true);
+ return true;
+ },
+
+ _startAutoScrollToDestination: function (destination, timeInSec, attenuated) {
+ this._startAutoScroll(cc.pSub(destination, this._innerContainer.getPosition()), timeInSec, attenuated);
+ },
+
+ _calculateAutoScrollTimeByInitialSpeed: function (initialSpeed) {
+ // Calculate the time from the initial speed according to quintic polynomial.
+ return Math.sqrt(Math.sqrt(initialSpeed / 5));
+ },
+
+ _startAttenuatingAutoScroll: function (deltaMove, initialVelocity) {
+ var time = this._calculateAutoScrollTimeByInitialSpeed(cc.pLength(initialVelocity));
+ this._startAutoScroll(deltaMove, time, true);
+ },
+
+ _startAutoScroll: function (deltaMove, timeInSec, attenuated) {
+ var adjustedDeltaMove = this._flattenVectorByDirection(deltaMove);
+
+ this._autoScrolling = true;
+ this._autoScrollTargetDelta = adjustedDeltaMove;
+ this._autoScrollAttenuate = attenuated;
+ this._autoScrollStartPosition = this._innerContainer.getPosition();
+ this._autoScrollTotalTime = timeInSec;
+ this._autoScrollAccumulatedTime = 0;
+ this._autoScrollBraking = false;
+ this._autoScrollBrakingStartPosition = cc.p(0, 0);
+
+ // If the destination is also out of boundary of same side, start brake from beggining.
+ var currentOutOfBoundary = this._getHowMuchOutOfBoundary();
+ if (!this._fltEqualZero(currentOutOfBoundary)) {
+ this._autoScrollCurrentlyOutOfBoundary = true;
+ var afterOutOfBoundary = this._getHowMuchOutOfBoundary(adjustedDeltaMove);
+ if (currentOutOfBoundary.x * afterOutOfBoundary.x > 0 || currentOutOfBoundary.y * afterOutOfBoundary.y > 0) {
+ this._autoScrollBraking = true;
+ }
+ }
+ },
+
+ /**
+ * Immediately stops inner container scroll initiated by any of the "scrollTo*" member functions
+ */
+ stopAutoScroll: function () {
+ this._autoScrolling = false;
+ this._autoScrollAttenuate = true;
+ this._autoScrollTotalTime = 0;
+ this._autoScrollAccumulatedTime = 0;
+ },
+
+ _isNecessaryAutoScrollBrake: function () {
+ if (this._autoScrollBraking) {
+ return true;
+ }
+
+ if (this._isOutOfBoundary()) {
+ // It just went out of boundary.
+ if (!this._autoScrollCurrentlyOutOfBoundary) {
+ this._autoScrollCurrentlyOutOfBoundary = true;
+ this._autoScrollBraking = true;
+ this._autoScrollBrakingStartPosition = this.getInnerContainerPosition();
+ return true;
+ }
+ }
+ else {
+ this._autoScrollCurrentlyOutOfBoundary = false;
+ }
+ return false;
+ },
+
+ _getAutoScrollStopEpsilon: function () {
+ return 0.0001;
+ },
+
+ _fltEqualZero: function (point) {
+ return (Math.abs(point.x) <= 0.0001 && Math.abs(point.y) <= 0.0001);
+ },
+
+ _processAutoScrolling: function (deltaTime) {
+ var OUT_OF_BOUNDARY_BREAKING_FACTOR = 0.05;
+ // Make auto scroll shorter if it needs to deaccelerate.
+ var brakingFactor = (this._isNecessaryAutoScrollBrake() ? OUT_OF_BOUNDARY_BREAKING_FACTOR : 1);
+
+ // Elapsed time
+ this._autoScrollAccumulatedTime += deltaTime * (1 / brakingFactor);
+
+ // Calculate the progress percentage
+ var percentage = Math.min(1, this._autoScrollAccumulatedTime / this._autoScrollTotalTime);
+ if (this._autoScrollAttenuate) {
+ percentage -= 1;
+ percentage = percentage * percentage * percentage * percentage * percentage + 1;
+ }
+
+ // Calculate the new position
+ var newPosition = cc.pAdd(this._autoScrollStartPosition, cc.pMult(this._autoScrollTargetDelta, percentage));
+ var reachedEnd = Math.abs(percentage - 1) <= this._getAutoScrollStopEpsilon();
+
+ if (this.bounceEnabled) {
+ // The new position is adjusted if out of boundary
+ newPosition = cc.pAdd(this._autoScrollBrakingStartPosition, cc.pMult(cc.pSub(newPosition, this._autoScrollBrakingStartPosition), brakingFactor));
+ }
+ else {
+ // Don't let go out of boundary
+ var moveDelta = cc.pSub(newPosition, this.getInnerContainerPosition());
+ var outOfBoundary = this._getHowMuchOutOfBoundary(moveDelta);
+ if (!this._fltEqualZero(outOfBoundary)) {
+ newPosition.x += outOfBoundary.x;
+ newPosition.y += outOfBoundary.y;
+
+ reachedEnd = true;
+ }
+ }
+
+ // Finish auto scroll if it ended
+ if (reachedEnd) {
+ this._autoScrolling = false;
+ this._dispatchEvent(ccui.ScrollView.EVENT_AUTOSCROLL_ENDED);
+ }
+
+ this._moveInnerContainer(cc.pSub(newPosition, this.getInnerContainerPosition()), reachedEnd);
+ },
+
+ _jumpToDestination: function (desOrX, y) {
+ if (desOrX.x === undefined) {
+ desOrX = cc.p(desOrX, y);
+ }
+
+ this._autoScrolling = false;
+ this._moveInnerContainer(cc.pSub(desOrX, this.getInnerContainerPosition()), true);
+ },
+
+ _scrollChildren: function (deltaMove) {
+ var realMove = deltaMove;
+ if (this.bounceEnabled) {
+ // If the position of the inner container is out of the boundary, the offsets should be divided by two.
+ var outOfBoundary = this._getHowMuchOutOfBoundary();
+ realMove.x *= (outOfBoundary.x == 0 ? 1 : 0.5);
+ realMove.y *= (outOfBoundary.y == 0 ? 1 : 0.5);
+ }
+
+ if (!this.bounceEnabled) {
+ var outOfBoundary = this._getHowMuchOutOfBoundary(realMove);
+ realMove.x += outOfBoundary.x;
+ realMove.y += outOfBoundary.y;
+ }
+
+ var scrolledToLeft = false;
+ var scrolledToRight = false;
+ var scrolledToTop = false;
+ var scrolledToBottom = false;
+
+ if (realMove.y > 0.0) // up
+ {
+ var icBottomPos = this._innerContainer.getBottomBoundary();
+ if (icBottomPos + realMove.y >= this._bottomBoundary) {
+ scrolledToBottom = true;
+ }
+ }
+ else if (realMove.y < 0.0) // down
+ {
+ var icTopPos = this._innerContainer.getTopBoundary();
+ if (icTopPos + realMove.y <= this._topBoundary) {
+ scrolledToTop = true;
+ }
+ }
+
+ if (realMove.x < 0.0) // left
+ {
+ var icRightPos = this._innerContainer.getRightBoundary();
+ if (icRightPos + realMove.x <= this._rightBoundary) {
+ scrolledToRight = true;
+ }
+ }
+ else if (realMove.x > 0.0) // right
+ {
+ var icLeftPos = this._innerContainer.getLeftBoundary();
+ if (icLeftPos + realMove.x >= this._leftBoundary) {
+ scrolledToLeft = true;
+ }
+ }
+ this._moveInnerContainer(realMove, false);
+
+ if (realMove.x != 0 || realMove.y != 0) {
+ this._processScrollingEvent();
+ }
+ if (scrolledToBottom) {
+ this._processScrollEvent(ccui.ScrollView.MOVEDIR_BOTTOM, false);
+ }
+ if (scrolledToTop) {
+ this._processScrollEvent(ccui.ScrollView.MOVEDIR_TOP, false);
+ }
+ if (scrolledToLeft) {
+ this._processScrollEvent(ccui.ScrollView.MOVEDIR_LEFT, false);
+ }
+ if (scrolledToRight) {
+ this._processScrollEvent(ccui.ScrollView.MOVEDIR_RIGHT, false);
+ }
+ },
+
+ /**
+ * Scroll inner container to bottom boundary of ScrollView.
+ * @param {Number} time
+ * @param {Boolean} attenuated
+ */
+ scrollToBottom: function (time, attenuated) {
+ this._startAutoScrollToDestination(cc.p(this._innerContainer.getPositionX(), 0), time, attenuated);
+ },
+
+ /**
+ * Scroll inner container to top boundary of ScrollView.
+ * @param {Number} time
+ * @param {Boolean} attenuated
+ */
+ scrollToTop: function (time, attenuated) {
+ this._startAutoScrollToDestination(
+ cc.p(this._innerContainer.getPositionX(), this._contentSize.height - this._innerContainer.getContentSize().height), time, attenuated);
+ },
+
+ /**
+ * Scroll inner container to left boundary of ScrollView.
+ * @param {Number} time
+ * @param {Boolean} attenuated
+ */
+ scrollToLeft: function (time, attenuated) {
+ this._startAutoScrollToDestination(cc.p(0, this._innerContainer.getPositionY()), time, attenuated);
+ },
+
+ /**
+ * Scroll inner container to right boundary of ScrollView.
+ * @param {Number} time
+ * @param {Boolean} attenuated
+ */
+ scrollToRight: function (time, attenuated) {
+ this._startAutoScrollToDestination(
+ cc.p(this._contentSize.width - this._innerContainer.getContentSize().width, this._innerContainer.getPositionY()), time, attenuated);
+ },
+
+ /**
+ * Scroll inner container to top and left boundary of ScrollView.
+ * @param {Number} time
+ * @param {Boolean} attenuated
+ */
+ scrollToTopLeft: function (time, attenuated) {
+ if (this._direction !== ccui.ScrollView.DIR_BOTH) {
+ cc.log("Scroll direction is not both!");
+ return;
+ }
+ this._startAutoScrollToDestination(cc.p(0, this._contentSize.height - this._innerContainer.getContentSize().height), time, attenuated);
+ },
+
+ /**
+ * Scroll inner container to top and right boundary of ScrollView.
+ * @param {Number} time
+ * @param {Boolean} attenuated
+ */
+ scrollToTopRight: function (time, attenuated) {
+ if (this._direction !== ccui.ScrollView.DIR_BOTH) {
+ cc.log("Scroll direction is not both!");
+ return;
+ }
+ var inSize = this._innerContainer.getContentSize();
+ this._startAutoScrollToDestination(cc.p(this._contentSize.width - inSize.width,
+ this._contentSize.height - inSize.height), time, attenuated);
+ },
+
+ /**
+ * Scroll inner container to bottom and left boundary of ScrollView.
+ * @param {Number} time
+ * @param {Boolean} attenuated
+ */
+ scrollToBottomLeft: function (time, attenuated) {
+ if (this._direction !== ccui.ScrollView.DIR_BOTH) {
+ cc.log("Scroll direction is not both!");
+ return;
+ }
+ this._startAutoScrollToDestination(cc.p(0, 0), time, attenuated);
+ },
+
+ /**
+ * Scroll inner container to bottom and right boundary of ScrollView.
+ * @param {Number} time
+ * @param {Boolean} attenuated
+ */
+ scrollToBottomRight: function (time, attenuated) {
+ if (this._direction !== ccui.ScrollView.DIR_BOTH) {
+ cc.log("Scroll direction is not both!");
+ return;
+ }
+ this._startAutoScrollToDestination(cc.p(this._contentSize.width - this._innerContainer.getContentSize().width, 0), time, attenuated);
+ },
+
+ /**
+ * Scroll inner container to vertical percent position of ScrollView.
+ * @param {Number} percent
+ * @param {Number} time
+ * @param {Boolean} attenuated
+ */
+ scrollToPercentVertical: function (percent, time, attenuated) {
+ var minY = this._contentSize.height - this._innerContainer.getContentSize().height;
+ var h = -minY;
+ this._startAutoScrollToDestination(cc.p(this._innerContainer.getPositionX(), minY + percent * h / 100), time, attenuated);
+ },
+
+ /**
+ * Scroll inner container to horizontal percent position of ScrollView.
+ * @param {Number} percent
+ * @param {Number} time
+ * @param {Boolean} attenuated
+ */
+ scrollToPercentHorizontal: function (percent, time, attenuated) {
+ var w = this._innerContainer.getContentSize().width - this._contentSize.width;
+ this._startAutoScrollToDestination(cc.p(-(percent * w / 100), this._innerContainer.getPositionY()), time, attenuated);
+ },
+
+ /**
+ * Scroll inner container to both _direction percent position of ScrollView.
+ * @param {cc.Point} percent
+ * @param {Number} time
+ * @param {Boolean} attenuated
+ */
+ scrollToPercentBothDirection: function (percent, time, attenuated) {
+ if (this._direction !== ccui.ScrollView.DIR_BOTH)
+ return;
+ var minY = this._contentSize.height - this._innerContainer.getContentSize().height;
+ var h = -minY;
+ var w = this._innerContainer.getContentSize().width - this._contentSize.width;
+ this._startAutoScrollToDestination(cc.p(-(percent.x * w / 100), minY + percent.y * h / 100), time, attenuated);
+ },
+
+ /**
+ * Move inner container to bottom boundary of ScrollView.
+ */
+ jumpToBottom: function () {
+ this._jumpToDestination(this._innerContainer.getPositionX(), 0);
+ },
+
+ /**
+ * Move inner container to top boundary of ScrollView.
+ */
+ jumpToTop: function () {
+ this._jumpToDestination(this._innerContainer.getPositionX(), this._contentSize.height - this._innerContainer.getContentSize().height);
+ },
+
+ /**
+ * Move inner container to left boundary of ScrollView.
+ */
+ jumpToLeft: function () {
+ this._jumpToDestination(0, this._innerContainer.getPositionY());
+ },
+
+ /**
+ * Move inner container to right boundary of ScrollView.
+ */
+ jumpToRight: function () {
+ this._jumpToDestination(this._contentSize.width - this._innerContainer.getContentSize().width, this._innerContainer.getPositionY());
+ },
+
+ /**
+ * Move inner container to top and left boundary of ScrollView.
+ */
+ jumpToTopLeft: function () {
+ if (this._direction !== ccui.ScrollView.DIR_BOTH) {
+ cc.log("Scroll _direction is not both!");
+ return;
+ }
+ this._jumpToDestination(0, this._contentSize.height - this._innerContainer.getContentSize().height);
+ },
+
+ /**
+ * Move inner container to top and right boundary of ScrollView.
+ */
+ jumpToTopRight: function () {
+ if (this._direction !== ccui.ScrollView.DIR_BOTH) {
+ cc.log("Scroll _direction is not both!");
+ return;
+ }
+ var inSize = this._innerContainer.getContentSize();
+ this._jumpToDestination(this._contentSize.width - inSize.width, this._contentSize.height - inSize.height);
+ },
+
+ /**
+ * Move inner container to bottom and left boundary of ScrollView.
+ */
+ jumpToBottomLeft: function () {
+ if (this._direction !== ccui.ScrollView.DIR_BOTH) {
+ cc.log("Scroll _direction is not both!");
+ return;
+ }
+ this._jumpToDestination(0, 0);
+ },
+
+ /**
+ * Move inner container to bottom and right boundary of ScrollView.
+ */
+ jumpToBottomRight: function () {
+ if (this._direction !== ccui.ScrollView.DIR_BOTH) {
+ cc.log("Scroll _direction is not both!");
+ return;
+ }
+ this._jumpToDestination(this._contentSize.width - this._innerContainer.getContentSize().width, 0);
+ },
+
+ /**
+ * Move inner container to vertical percent position of ScrollView.
+ * @param {Number} percent The destination vertical percent, accept value between 0 - 100
+ */
+ jumpToPercentVertical: function (percent) {
+ var minY = this._contentSize.height - this._innerContainer.getContentSize().height;
+ var h = -minY;
+ this._jumpToDestination(this._innerContainer.getPositionX(), minY + percent * h / 100);
+ },
+
+ /**
+ * Move inner container to horizontal percent position of ScrollView.
+ * @param {Number} percent The destination vertical percent, accept value between 0 - 100
+ */
+ jumpToPercentHorizontal: function (percent) {
+ var w = this._innerContainer.getContentSize().width - this._contentSize.width;
+ this._jumpToDestination(-(percent * w / 100), this._innerContainer.getPositionY());
+ },
+
+ /**
+ * Move inner container to both _direction percent position of ScrollView.
+ * @param {cc.Point} percent The destination vertical percent, accept value between 0 - 100
+ */
+ jumpToPercentBothDirection: function (percent) {
+ if (this._direction !== ccui.ScrollView.DIR_BOTH)
+ return;
+ var inSize = this._innerContainer.getContentSize();
+ var minY = this._contentSize.height - inSize.height;
+ var h = -minY;
+ var w = inSize.width - this._contentSize.width;
+ this._jumpToDestination(-(percent.x * w / 100), minY + percent.y * h / 100);
+ },
+
+ _gatherTouchMove: function (delta) {
+ var NUMBER_OF_GATHERED_TOUCHES_FOR_MOVE_SPEED = 5;
+ while (this._touchMoveDisplacements.length >= NUMBER_OF_GATHERED_TOUCHES_FOR_MOVE_SPEED) {
+ this._touchMoveDisplacements.splice(0, 1);
+ this._touchMoveTimeDeltas.splice(0, 1)
+ }
+ this._touchMoveDisplacements.push(delta);
+
+ var timestamp = (new Date()).getTime();
+ this._touchMoveTimeDeltas.push((timestamp - this._touchMovePreviousTimestamp) / 1000);
+ this._touchMovePreviousTimestamp = timestamp;
+ },
+
+ _handlePressLogic: function (touch) {
+ this._bePressed = true;
+ this._autoScrolling = false;
+
+ // Clear gathered touch move information
+
+ this._touchMovePreviousTimestamp = (new Date()).getTime();
+ this._touchMoveDisplacements.length = 0;
+ this._touchMoveTimeDeltas.length = 0;
+
+
+ if(this._verticalScrollBar)
+ {
+ this._verticalScrollBar.onTouchBegan();
+ }
+ if(this._horizontalScrollBar)
+ {
+ this._horizontalScrollBar.onTouchBegan();
+ }
+ },
+
+ _handleMoveLogic: function (touch) {
+ var touchPositionInNodeSpace = this.convertToNodeSpace(touch.getLocation()),
+ previousTouchPositionInNodeSpace = this.convertToNodeSpace(touch.getPreviousLocation());
+ var delta = cc.pSub(touchPositionInNodeSpace, previousTouchPositionInNodeSpace);
+
+ this._scrollChildren(delta);
+ this._gatherTouchMove(delta);
+ },
+
+ _handleReleaseLogic: function (touch) {
+
+ var touchPositionInNodeSpace = this.convertToNodeSpace(touch.getLocation()),
+ previousTouchPositionInNodeSpace = this.convertToNodeSpace(touch.getPreviousLocation());
+ var delta = cc.pSub(touchPositionInNodeSpace, previousTouchPositionInNodeSpace);
+
+ this._gatherTouchMove(delta);
+
+ this._bePressed = false;
+
+ var bounceBackStarted = this._startBounceBackIfNeeded();
+ if (!bounceBackStarted && this.inertiaScrollEnabled) {
+ var touchMoveVelocity = this._calculateTouchMoveVelocity();
+ if (touchMoveVelocity.x !== 0 || touchMoveVelocity.y !== 0) {
+ this._startInertiaScroll(touchMoveVelocity);
+ }
+ }
+
+ if(this._verticalScrollBar)
+ {
+ this._verticalScrollBar.onTouchEnded();
+ }
+ if(this._horizontalScrollBar)
+ {
+ this._horizontalScrollBar.onTouchEnded();
+ }
+ },
+
+ /**
+ * The touch began event callback handler of ccui.ScrollView.
+ * @param {cc.Touch} touch
+ * @param {cc.Event} event
+ * @returns {boolean}
+ */
+ onTouchBegan: function (touch, event) {
+ var pass = ccui.Layout.prototype.onTouchBegan.call(this, touch, event);
+ if (!this._isInterceptTouch) {
+ if (this._hit)
+ this._handlePressLogic(touch);
+ }
+ return pass;
+ },
+
+ /**
+ * The touch moved event callback handler of ccui.ScrollView.
+ * @param {cc.Touch} touch
+ * @param {cc.Event} event
+ */
+ onTouchMoved: function (touch, event) {
+ ccui.Layout.prototype.onTouchMoved.call(this, touch, event);
+ if (!this._isInterceptTouch)
+ this._handleMoveLogic(touch);
+ },
+
+ /**
+ * The touch ended event callback handler of ccui.ScrollView.
+ * @param {cc.Touch} touch
+ * @param {cc.Event} event
+ */
+ onTouchEnded: function (touch, event) {
+ ccui.Layout.prototype.onTouchEnded.call(this, touch, event);
+ if (!this._isInterceptTouch)
+ this._handleReleaseLogic(touch);
+ this._isInterceptTouch = false;
+ },
+
+ /**
+ * The touch canceled event callback of ccui.ScrollView.
+ * @param {cc.Touch} touch
+ * @param {cc.Event} event
+ */
+ onTouchCancelled: function (touch, event) {
+ ccui.Layout.prototype.onTouchCancelled.call(this, touch, event);
+ if (!this._isInterceptTouch)
+ this._handleReleaseLogic(touch);
+ this._isInterceptTouch = false;
+ },
+
+ /**
+ * The update callback handler.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ if (this._autoScrolling)
+ this._processAutoScrolling(dt);
+ },
+
+ /**
+ * Intercept touch event, handle its child's touch event.
+ * @override
+ * @param {number} event event type
+ * @param {ccui.Widget} sender
+ * @param {cc.Touch} touch
+ */
+ interceptTouchEvent: function (event, sender, touch) {
+ if (!this._touchEnabled) {
+ ccui.Layout.prototype.interceptTouchEvent.call(this, event, sender, touch);
+ return;
+ }
+
+ if (this._direction === ccui.ScrollView.DIR_NONE)
+ return;
+
+ var touchPoint = touch.getLocation();
+ switch (event) {
+ case ccui.Widget.TOUCH_BEGAN:
+ this._isInterceptTouch = true;
+ this._touchBeganPosition.x = touchPoint.x;
+ this._touchBeganPosition.y = touchPoint.y;
+ this._handlePressLogic(touch);
+ break;
+ case ccui.Widget.TOUCH_MOVED:
+ var offset = cc.pLength(cc.pSub(sender.getTouchBeganPosition(), touchPoint));
+ this._touchMovePosition.x = touchPoint.x;
+ this._touchMovePosition.y = touchPoint.y;
+ if (offset > this._childFocusCancelOffset) {
+ sender.setHighlighted(false);
+ this._handleMoveLogic(touch);
+ }
+ break;
+ case ccui.Widget.TOUCH_CANCELED:
+ case ccui.Widget.TOUCH_ENDED:
+ this._touchEndPosition.x = touchPoint.x;
+ this._touchEndPosition.y = touchPoint.y;
+ this._handleReleaseLogic(touch);
+ if (sender.isSwallowTouches())
+ this._isInterceptTouch = false;
+ break;
+ }
+ },
+
+ _processScrollEvent: function (_directionEvent, bounce) {
+ var event = 0;
+
+ switch (_directionEvent) {
+ case ccui.ScrollView.MOVEDIR_TOP:
+ event = (bounce ? ccui.ScrollView.EVENT_BOUNCE_TOP : ccui.ScrollView.EVENT_SCROLL_TO_TOP);
+ break;
+ case ccui.ScrollView.MOVEDIR_BOTTOM:
+ event = (bounce ? ccui.ScrollView.EVENT_BOUNCE_BOTTOM : ccui.ScrollView.EVENT_SCROLL_TO_BOTTOM);
+ break;
+ case ccui.ScrollView.MOVEDIR_LEFT:
+ event = (bounce ? ccui.ScrollView.EVENT_BOUNCE_LEFT : ccui.ScrollView.EVENT_SCROLL_TO_LEFT);
+ break;
+ case ccui.ScrollView.MOVEDIR_RIGHT:
+ event = (bounce ? ccui.ScrollView.EVENT_BOUNCE_RIGHT : ccui.ScrollView.EVENT_SCROLL_TO_RIGHT);
+ break;
+ }
+
+ this._dispatchEvent(event);
+ },
+
+ _processScrollingEvent: function () {
+ this._dispatchEvent(ccui.ScrollView.EVENT_SCROLLING);
+ },
+
+ _dispatchEvent: function (event) {
+ if (this._scrollViewEventSelector) {
+ if (this._scrollViewEventListener)
+ this._scrollViewEventSelector.call(this._scrollViewEventListener, this, event);
+ else
+ this._scrollViewEventSelector(this, event);
+ }
+ if (this._ccEventCallback)
+ this._ccEventCallback(this, event);
+ },
+
+ /**
+ * Adds callback function called ScrollView event triggered
+ * @param {Function} selector
+ * @param {Object} [target=]
+ * @deprecated since v3.0, please use addEventListener instead.
+ */
+ addEventListenerScrollView: function (selector, target) {
+ this._scrollViewEventSelector = selector;
+ this._scrollViewEventListener = target;
+ },
+
+ /**
+ * Adds callback function called ScrollView event triggered
+ * @param {Function} selector
+ */
+ addEventListener: function (selector) {
+ this._ccEventCallback = selector;
+ },
+
+ /**
+ * Changes scroll _direction of ScrollView.
+ * @param {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_BOTH} dir
+ * Direction::VERTICAL means vertical scroll, Direction::HORIZONTAL means horizontal scroll
+ */
+ setDirection: function (dir) {
+ this._direction = dir;
+
+ if(this._scrollBarEnabled)
+ {
+ this._removeScrollBar();
+ this._initScrollBar();
+ }
+ },
+
+ /**
+ * Returns scroll direction of ScrollView.
+ * @returns {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_BOTH}
+ */
+ getDirection: function () {
+ return this._direction;
+ },
+
+ /**
+ * Sets bounce enabled
+ * @param {Boolean} enabled
+ */
+ setBounceEnabled: function (enabled) {
+ this.bounceEnabled = enabled;
+ },
+
+ /**
+ * Returns whether bounce is enabled
+ * @returns {boolean}
+ */
+ isBounceEnabled: function () {
+ return this.bounceEnabled;
+ },
+
+ /**
+ * Sets inertiaScroll enabled
+ * @param {boolean} enabled
+ */
+ setInertiaScrollEnabled: function (enabled) {
+ this.inertiaScrollEnabled = enabled;
+ },
+
+ /**
+ * Returns whether inertiaScroll is enabled
+ * @returns {boolean}
+ */
+ isInertiaScrollEnabled: function () {
+ return this.inertiaScrollEnabled;
+ },
+
+ /**
+ * Toggle scroll bar enabled.
+ * @param {boolean} enabled True if enable scroll bar, false otherwise.
+ */
+ setScrollBarEnabled: function(enabled)
+ {
+ if(this._scrollBarEnabled === enabled)
+ {
+ return;
+ }
+
+ if(this._scrollBarEnabled)
+ {
+ this._removeScrollBar();
+ }
+ this._scrollBarEnabled = enabled;
+ if(this._scrollBarEnabled)
+ {
+ this._initScrollBar();
+ }
+ },
+ /**
+ * Query scroll bar state.
+ * @returns {boolean} True if scroll bar is enabled, false otherwise.
+ */
+ isScrollBarEnabled: function()
+ {
+ return this._scrollBarEnabled;
+ },
+
+ /**
+ * Set the scroll bar positions from the left-bottom corner (horizontal) and right-top corner (vertical).
+ * @param {cc.Point} positionFromCorner The position from the left-bottom corner (horizontal) and right-top corner (vertical).
+ */
+ setScrollBarPositionFromCorner: function(positionFromCorner)
+ {
+ if(this._direction !== ccui.ScrollView.DIR_HORIZONTAL)
+ {
+ this.setScrollBarPositionFromCornerForVertical(positionFromCorner);
+ }
+ if(this._direction !== ccui.ScrollView.DIR_VERTICAL)
+ {
+ this.setScrollBarPositionFromCornerForHorizontal(positionFromCorner);
+ }
+ },
+
+ /**
+ * Set the vertical scroll bar position from right-top corner.
+ * @param {cc.Point} positionFromCorner The position from right-top corner
+ */
+ setScrollBarPositionFromCornerForVertical: function(positionFromCorner)
+ {
+ cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!");
+ cc.assert(this._direction !== ccui.ScrollView.DIR_HORIZONTAL, "Scroll view doesn't have a vertical scroll bar!");
+ this._verticalScrollBar.setPositionFromCorner(positionFromCorner);
+ },
+
+ /**
+ * Get the vertical scroll bar's position from right-top corner.
+ * @returns {cc.Point}
+ */
+ getScrollBarPositionFromCornerForVertical: function()
+ {
+ cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!");
+ cc.assert(this._direction !== ccui.ScrollView.DIR_HORIZONTAL, "Scroll view doesn't have a vertical scroll bar!");
+ return this._verticalScrollBar.getPositionFromCorner();
+ },
+
+ /**
+ * Set the horizontal scroll bar position from left-bottom corner.
+ * @param {cc.Point} positionFromCorner The position from left-bottom corner
+ */
+ setScrollBarPositionFromCornerForHorizontal: function(positionFromCorner)
+ {
+ cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!");
+ cc.assert(this._direction !== ccui.ScrollView.DIR_VERTICAL, "Scroll view doesn't have a horizontal scroll bar!");
+ this._horizontalScrollBar.setPositionFromCorner(positionFromCorner);
+ },
+
+ /**
+ * Get the horizontal scroll bar's position from right-top corner.
+ * @returns {cc.Point}
+ */
+ getScrollBarPositionFromCornerForHorizontal: function()
+ {
+ cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!");
+ cc.assert(this._direction !== ccui.ScrollView.DIR_VERTICAL, "Scroll view doesn't have a horizontal scroll bar!");
+ return this._horizontalScrollBar.getPositionFromCorner();
+ },
+
+ /**
+ * Set the scroll bar's width
+ * @param {number} width The scroll bar's width
+ */
+ setScrollBarWidth: function(width)
+ {
+ cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!");
+ if(this._verticalScrollBar)
+ {
+ this._verticalScrollBar.setWidth(width);
+ }
+ if(this._horizontalScrollBar)
+ {
+ this._horizontalScrollBar.setWidth(width);
+ }
+ },
+
+ /**
+ * Get the scroll bar's width
+ * @returns {number} the scroll bar's width
+ */
+ getScrollBarWidth: function()
+ {
+ cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!");
+ if(this._verticalScrollBar)
+ {
+ return this._verticalScrollBar.getWidth();
+ }
+ if(this._horizontalScrollBar)
+ {
+ return this._horizontalScrollBar.getWidth();
+ }
+ return 0;
+ },
+
+ /**
+ * Set the scroll bar's color
+ * @param {cc.Color} color the scroll bar's color
+ */
+ setScrollBarColor: function(color)
+ {
+ cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!");
+ if(this._verticalScrollBar)
+ {
+ this._verticalScrollBar.setColor(color);
+ }
+ if(this._horizontalScrollBar)
+ {
+ this._horizontalScrollBar.setColor(color);
+ }
+ },
+
+ /**
+ * Get the scroll bar's color
+ * @returns {cc.Color} the scroll bar's color
+ */
+ getScrollBarColor: function()
+ {
+ cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!");
+ if(this._verticalScrollBar)
+ {
+ this._verticalScrollBar.getColor();
+ }
+ if(this._horizontalScrollBar)
+ {
+ this._horizontalScrollBar.getColor();
+ }
+ return cc.color.WHITE;
+ },
+
+ /**
+ * Set the scroll bar's opacity
+ * @param {number} opacity the scroll bar's opacity
+ */
+ setScrollBarOpacity: function(opacity)
+ {
+ cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!");
+ if(this._verticalScrollBar)
+ {
+ this._verticalScrollBar.opacity = opacity;
+ }
+ if(this._horizontalScrollBar)
+ {
+ this._horizontalScrollBar.opacity = opacity;
+ }
+ },
+
+ /**
+ * Get the scroll bar's opacity
+ * @returns {number}
+ */
+ getScrollBarOpacity: function()
+ {
+ cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!");
+ if(this._verticalScrollBar)
+ {
+ return this._verticalScrollBar.opacity;
+ }
+ if(this._horizontalScrollBar)
+ {
+ return this._horizontalScrollBar.opacity;
+ }
+ return -1;
+ },
+
+ /**
+ * Set scroll bar auto hide state
+ * @param {boolean} autoHideEnabled scroll bar auto hide state
+ */
+ setScrollBarAutoHideEnabled: function(autoHideEnabled)
+ {
+ cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!");
+ if(this._verticalScrollBar)
+ {
+ this._verticalScrollBar.autoHideEnabled = autoHideEnabled;
+ }
+ if(this._horizontalScrollBar)
+ {
+ this._horizontalScrollBar.autoHideEnabled = autoHideEnabled;
+ }
+ },
+
+ /**
+ * Query scroll bar auto hide state
+ * @returns {boolean}
+ */
+ isScrollBarAutoHideEnabled: function()
+ {
+ cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!");
+ if(this._verticalScrollBar)
+ {
+ return this._verticalScrollBar.autoHideEnabled;
+ }
+ if(this._horizontalScrollBar)
+ {
+ return this._horizontalScrollBar.autoHideEnabled;
+ }
+ return false;
+ },
+
+ /**
+ * Set scroll bar auto hide time
+ * @param {number} autoHideTime scroll bar auto hide state
+ */
+ setScrollBarAutoHideTime: function(autoHideTime)
+ {
+ cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!");
+ if(this._verticalScrollBar)
+ {
+ this._verticalScrollBar.autoHideTime = autoHideTime;
+ }
+ if(this._horizontalScrollBar)
+ {
+ this._horizontalScrollBar.autoHideTime = autoHideTime;
+ }
+ },
+
+ /**
+ * Get the scroll bar's auto hide time
+ * @returns {number}
+ */
+ getScrollBarAutoHideTime: function()
+ {
+ cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!");
+ if(this._verticalScrollBar)
+ {
+ return this._verticalScrollBar.autoHideTime;
+ }
+ if(this._horizontalScrollBar)
+ {
+ return this._horizontalScrollBar.autoHideTime;
+ }
+ return 0;
+ },
+
+ /**
+ * Gets inner container of ScrollView. Inner container is the container of ScrollView's children.
+ * @returns {ccui.Layout}
+ */
+ getInnerContainer: function () {
+ return this._innerContainer;
+ },
+
+ /**
+ * Sets LayoutType of ccui.ScrollView.
+ * @param {ccui.Layout.ABSOLUTE|ccui.Layout.LINEAR_VERTICAL|ccui.Layout.LINEAR_HORIZONTAL|ccui.Layout.RELATIVE} type
+ */
+ setLayoutType: function (type) {
+ this._innerContainer.setLayoutType(type);
+ },
+
+ /**
+ * Returns the layout type of ccui.ScrollView.
+ * @returns {ccui.Layout.ABSOLUTE|ccui.Layout.LINEAR_VERTICAL|ccui.Layout.LINEAR_HORIZONTAL|ccui.Layout.RELATIVE}
+ */
+ getLayoutType: function () {
+ return this._innerContainer.getLayoutType();
+ },
+
+ _doLayout: function () {
+ if (!this._doLayoutDirty)
+ return;
+ this._doLayoutDirty = false;
+ },
+
+ /**
+ * Returns the "class name" of ccui.ScrollView.
+ * @returns {string}
+ */
+ getDescription: function () {
+ return "ScrollView";
+ },
+
+ _createCloneInstance: function () {
+ return new ccui.ScrollView();
+ },
+
+ _copyClonedWidgetChildren: function (model) {
+ ccui.Layout.prototype._copyClonedWidgetChildren.call(this, model);
+ },
+
+ _copySpecialProperties: function (scrollView) {
+ if (scrollView instanceof ccui.ScrollView) {
+ ccui.Layout.prototype._copySpecialProperties.call(this, scrollView);
+ this.setInnerContainerSize(scrollView.getInnerContainerSize());
+ this.setInnerContainerPosition(scrollView.getInnerContainerPosition());
+ this.setDirection(scrollView._direction);
+
+ this._topBoundary = scrollView._topBoundary;
+ this._bottomBoundary = scrollView._bottomBoundary;
+ this._leftBoundary = scrollView._leftBoundary;
+ this._rightBoundary = scrollView._rightBoundary;
+ this._bePressed = scrollView._bePressed;
+ this._childFocusCancelOffset = scrollView._childFocusCancelOffset;
+ this._touchMoveDisplacements = scrollView._touchMoveDisplacements;
+ this._touchMoveTimeDeltas = scrollView._touchMoveTimeDeltas;
+ this._touchMovePreviousTimestamp = scrollView._touchMovePreviousTimestamp;
+ this._autoScrolling = scrollView._autoScrolling;
+ this._autoScrollAttenuate = scrollView._autoScrollAttenuate;
+ this._autoScrollStartPosition = scrollView._autoScrollStartPosition;
+ this._autoScrollTargetDelta = scrollView._autoScrollTargetDelta;
+ this._autoScrollTotalTime = scrollView._autoScrollTotalTime;
+ this._autoScrollAccumulatedTime = scrollView._autoScrollAccumulatedTime;
+ this._autoScrollCurrentlyOutOfBoundary = scrollView._autoScrollCurrentlyOutOfBoundary;
+ this._autoScrollBraking = scrollView._autoScrollBraking;
+ this._autoScrollBrakingStartPosition = scrollView._autoScrollBrakingStartPosition;
+
+ this.setBounceEnabled(scrollView.bounceEnabled);
+ this.setInertiaScrollEnabled(scrollView.inertiaScrollEnabled);
+
+ this._scrollViewEventListener = scrollView._scrollViewEventListener;
+ this._scrollViewEventSelector = scrollView._scrollViewEventSelector;
+ this._ccEventCallback = scrollView._ccEventCallback;
+
+ this.setScrollBarEnabled(scrollView.isScrollBarEnabled());
+ if(this.isScrollBarEnabled())
+ {
+ if(this._direction !== ccui.ScrollView.DIR_HORIZONTAL)
+ {
+ this.setScrollBarPositionFromCornerForVertical(scrollView.getScrollBarPositionFromCornerForVertical());
+ }
+ if(this._direction !== ccui.ScrollView.DIR_VERTICAL)
+ {
+ this.setScrollBarPositionFromCornerForHorizontal(scrollView.getScrollBarPositionFromCornerForHorizontal());
+ }
+ this.setScrollBarWidth(scrollView.getScrollBarWidth());
+ this.setScrollBarColor(scrollView.getScrollBarColor());
+ this.setScrollBarAutoHideEnabled(scrollView.isScrollBarAutoHideEnabled());
+ this.setScrollBarAutoHideTime(scrollView.getScrollBarAutoHideTime());
+ }
+ }
+ },
+
+ _initScrollBar: function()
+ {
+ if(this._direction !== ccui.ScrollView.DIR_HORIZONTAL && !this._verticalScrollBar)
+ {
+ this._verticalScrollBar = new ccui.ScrollViewBar(this, ccui.ScrollView.DIR_VERTICAL);
+ this.addProtectedChild(this._verticalScrollBar, 2);
+ }
+ if(this._direction !== ccui.ScrollView.DIR_VERTICAL && !this._horizontalScrollBar)
+ {
+ this._horizontalScrollBar = new ccui.ScrollViewBar(this, ccui.ScrollView.DIR_HORIZONTAL);
+ this.addProtectedChild(this._horizontalScrollBar, 2);
+ }
+ },
+
+ _removeScrollBar: function()
+ {
+ if(this._verticalScrollBar)
+ {
+ this.removeProtectedChild(this._verticalScrollBar);
+ this._verticalScrollBar = null;
+ }
+ if(this._horizontalScrollBar)
+ {
+ this.removeProtectedChild(this._horizontalScrollBar);
+ this._horizontalScrollBar = null;
+ }
+ },
+
+ /**
+ * Returns a node by tag
+ * @param {Number} tag
+ * @returns {cc.Node}
+ * @deprecated since v3.0, please use getChildByTag instead.
+ */
+ getNodeByTag: function (tag) {
+ return this._innerContainer.getNodeByTag(tag);
+ },
+
+ /**
+ * Returns all nodes of inner container
+ * @returns {Array}
+ * @deprecated since v3.0, please use getChildren instead.
+ */
+ getNodes: function () {
+ return this._innerContainer.getNodes();
+ },
+
+ /**
+ * Removes a node from ccui.ScrollView.
+ * @param {cc.Node} node
+ * @deprecated since v3.0, please use removeChild instead.
+ */
+ removeNode: function (node) {
+ this._innerContainer.removeNode(node);
+ },
+
+ /**
+ * Removes a node by tag
+ * @param {Number} tag
+ * @deprecated since v3.0, please use removeChildByTag instead.
+ */
+ removeNodeByTag: function (tag) {
+ this._innerContainer.removeNodeByTag(tag);
+ },
+
+ /**
+ * Remove all node from ccui.ScrollView.
+ * @deprecated since v3.0, please use removeAllChildren instead.
+ */
+ removeAllNodes: function () {
+ this._innerContainer.removeAllNodes();
+ },
+
+ /**
+ * Add node for scrollView
+ * @param {cc.Node} node
+ * @param {Number} zOrder
+ * @param {Number} tag
+ * @deprecated since v3.0, please use addChild instead.
+ */
+ addNode: function (node, zOrder, tag) {
+ this._innerContainer.addNode(node, zOrder, tag);
+ }
+});
+
+var _p = ccui.ScrollView.prototype;
+
+// Extended properties
+/** @expose */
+_p.innerWidth;
+cc.defineGetterSetter(_p, "innerWidth", _p._getInnerWidth, _p._setInnerWidth);
+/** @expose */
+_p.innerHeight;
+cc.defineGetterSetter(_p, "innerHeight", _p._getInnerHeight, _p._setInnerHeight);
+/** @expose */
+_p.direction;
+cc.defineGetterSetter(_p, "direction", _p.getDirection, _p.setDirection);
+/** @expose */
+_p.touchTotalTimeThreshold;
+cc.defineGetterSetter(_p, "touchTotalTimeThreshold", _p.getTouchTotalTimeThreshold, _p.setTouchTotalTimeThreshold);
+_p = null;
+/**
+ * allocates and initializes a UIScrollView.
+ * @deprecated since v3.0, please use new ccui.ScrollView() instead.
+ * @return {ccui.ScrollView}
+ */
+ccui.ScrollView.create = function () {
+ return new ccui.ScrollView();
+};
+
+// Constants
+//ScrollView direction
+/**
+ * The none flag of ccui.ScrollView's direction.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.DIR_NONE = 0;
+/**
+ * The vertical flag of ccui.ScrollView's direction.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.DIR_VERTICAL = 1;
+/**
+ * The horizontal flag of ccui.ScrollView's direction.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.DIR_HORIZONTAL = 2;
+/**
+ * The both flag of ccui.ScrollView's direction.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.DIR_BOTH = 3;
+
+//ScrollView event
+/**
+ * The flag scroll to top of ccui.ScrollView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.EVENT_SCROLL_TO_TOP = 0;
+/**
+ * The flag scroll to bottom of ccui.ScrollView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.EVENT_SCROLL_TO_BOTTOM = 1;
+/**
+ * The flag scroll to left of ccui.ScrollView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.EVENT_SCROLL_TO_LEFT = 2;
+/**
+ * The flag scroll to right of ccui.ScrollView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.EVENT_SCROLL_TO_RIGHT = 3;
+/**
+ * The scrolling flag of ccui.ScrollView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.EVENT_SCROLLING = 4;
+/**
+ * The flag bounce top of ccui.ScrollView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.EVENT_BOUNCE_TOP = 5;
+/**
+ * The flag bounce bottom of ccui.ScrollView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.EVENT_BOUNCE_BOTTOM = 6;
+/**
+ * The flag bounce left of ccui.ScrollView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.EVENT_BOUNCE_LEFT = 7;
+/**
+ * The flag bounce right of ccui.ScrollView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.EVENT_BOUNCE_RIGHT = 8;
+/**
+ * The flag container moved of ccui.ScrollView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.EVENT_CONTAINER_MOVED = 9;
+/**
+ * The flag autoscroll ended of ccui.ScrollView's event.
+ * @constant
+ * @type {number}
+ */
+ccui.ScrollView.EVENT_AUTOSCROLL_ENDED = 10;
+
+/**
+ * @ignore
+ */
+
+ccui.ScrollView.MOVEDIR_TOP = 0;
+ccui.ScrollView.MOVEDIR_BOTTOM = 1;
+ccui.ScrollView.MOVEDIR_LEFT = 2;
+ccui.ScrollView.MOVEDIR_RIGHT = 3;
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js
new file mode 100644
index 0000000..4e9c184
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js
@@ -0,0 +1,343 @@
+/****************************************************************************
+ Copyright (c) 2015 Neo Kim (neo.kim@neofect.com)
+ Copyright (c) 2015 Nikita Besshaposhnikov (nikita.besshaposhnikov@gmail.com)
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The ScrollViewBar control of Cocos UI
+ * Scroll bar being attached to ScrollView layout container.
+ * @class
+ * @extends ccui.ProtectedNode
+ *
+ * @property {Number} opacity - Opacity of the scroll view bar
+ * @property {Boolean} autoHideEnabled - Auto hide is enabled in the scroll view bar
+ * @property {Number} autoHideTime - Auto hide time of the scroll view bar
+ */
+ccui.ScrollViewBar = ccui.ProtectedNode.extend(/** @lends ccui.ScrollViewBar# */{
+ _parentScroll: null,
+ _direction: null,
+
+ _upperHalfCircle: null,
+ _lowerHalfCircle: null,
+ _body: null,
+
+ _opacity: 255,
+
+ _marginFromBoundary: 0,
+ _marginForLength: 0,
+
+ _touching: false,
+
+ _autoHideEnabled: true,
+ autoHideTime: 0,
+ _autoHideRemainingTime: 0,
+ _className: "ScrollViewBar",
+
+ /**
+ * Allocates and initializes a UIScrollViewBar.
+ * Constructor of ccui.ScrollViewBar. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ * @param {ccui.ScrollView} parent A parent of scroll bar.
+ * @param {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_BOTH} direction
+ */
+ ctor: function (parent, direction) {
+ cc.ProtectedNode.prototype.ctor.call(this);
+ this._direction = direction;
+ this._parentScroll = parent;
+
+ this._marginFromBoundary = ccui.ScrollViewBar.DEFAULT_MARGIN;
+ this._marginForLength = ccui.ScrollViewBar.DEFAULT_MARGIN;
+ this.opacity = 255 * ccui.ScrollViewBar.DEFAULT_SCROLLBAR_OPACITY;
+ this.autoHideTime = ccui.ScrollViewBar.DEFAULT_AUTO_HIDE_TIME;
+ this._autoHideEnabled = true;
+
+ ccui.ScrollViewBar.prototype.init.call(this);
+
+ this.setCascadeColorEnabled(true);
+ this.setCascadeOpacityEnabled(true);
+ },
+
+ /**
+ * Initializes a ccui.ScrollViewBar. Please do not call this function by yourself, you should pass the parameters to constructor to initialize it.
+ * @returns {boolean}
+ */
+ init: function () {
+ this._upperHalfCircle = ccui.helper._createSpriteFromBase64(ccui.ScrollViewBar.HALF_CIRCLE_IMAGE, ccui.ScrollViewBar.HALF_CIRCLE_IMAGE_KEY);
+ this._upperHalfCircle.setAnchorPoint(cc.p(0.5, 0));
+
+ this._lowerHalfCircle = ccui.helper._createSpriteFromBase64(ccui.ScrollViewBar.HALF_CIRCLE_IMAGE, ccui.ScrollViewBar.HALF_CIRCLE_IMAGE_KEY);
+ this._lowerHalfCircle.setAnchorPoint(cc.p(0.5, 0));
+ this._lowerHalfCircle.setScaleY(-1);
+
+ this.addProtectedChild(this._upperHalfCircle);
+ this.addProtectedChild(this._lowerHalfCircle);
+
+ this._body = ccui.helper._createSpriteFromBase64(ccui.ScrollViewBar.BODY_IMAGE_1_PIXEL_HEIGHT, ccui.ScrollViewBar.BODY_IMAGE_1_PIXEL_HEIGHT_KEY);
+ this._body.setAnchorPoint(cc.p(0.5, 0));
+ this.addProtectedChild(this._body);
+
+ this.setColor(ccui.ScrollViewBar.DEFAULT_COLOR);
+ this.onScrolled(cc.p(0, 0));
+ cc.ProtectedNode.prototype.setOpacity.call(this, 0);
+ this._autoHideRemainingTime = 0;
+
+ if (this._direction === ccui.ScrollView.DIR_HORIZONTAL) {
+ this.setRotation(90);
+ }
+ },
+
+ /**
+ * Set the scroll bar position from the left-bottom corner (horizontal) or right-top corner (vertical).
+ * @param {cc.Point} positionFromCorner The position from the left-bottom corner (horizontal) or right-top corner (vertical).
+ */
+ setPositionFromCorner: function (positionFromCorner) {
+ if (this._direction === ccui.ScrollView.DIR_VERTICAL) {
+ this._marginForLength = positionFromCorner.y;
+ this._marginFromBoundary = positionFromCorner.x;
+ }
+ else {
+ this._marginForLength = positionFromCorner.x;
+ this._marginFromBoundary = positionFromCorner.y;
+ }
+ },
+
+ onEnter: function () {
+ cc.ProtectedNode.prototype.onEnter.call(this);
+ this.scheduleUpdate();
+ },
+
+ /**
+ * Get the scroll bar position from the left-bottom corner (horizontal) or right-top corner (vertical).
+ * @returns {cc.Point}
+ */
+ getPositionFromCorner: function () {
+ if (this._direction === ccui.ScrollView.DIR_VERTICAL) {
+ return cc.p(this._marginFromBoundary, this._marginForLength);
+ }
+ else {
+ return cc.p(this._marginForLength, this._marginFromBoundary);
+ }
+ },
+ /**
+ * Set the scroll bar's width
+ * @param {number} width The scroll bar's width
+ */
+ setWidth: function (width) {
+ var scale = width / this._body.width;
+ this._body.setScaleX(scale);
+ this._upperHalfCircle.setScale(scale);
+ this._lowerHalfCircle.setScale(-scale);
+ },
+
+ /**
+ * Get the scroll bar's width
+ * @returns {number} the scroll bar's width
+ */
+ getWidth: function () {
+ return this._body.getBoundingBox().width;
+ },
+
+ /**
+ * Set scroll bar auto hide state
+ * @param {boolean} autoHideEnabled scroll bar auto hide state
+ */
+ setAutoHideEnabled: function (autoHideEnabled) {
+ this._autoHideEnabled = autoHideEnabled;
+
+ if (!this._autoHideEnabled && !this._touching && this._autoHideRemainingTime <= 0)
+ cc.ProtectedNode.prototype.setOpacity.call(this, this.opacity);
+ else
+ cc.ProtectedNode.prototype.setOpacity.call(this, 0);
+ },
+ /**
+ * Query scroll bar auto hide state
+ * @returns {boolean} True if scroll bar auto hide is enabled, false otherwise.
+ */
+ isAutoHideEnabled: function () {
+ return this._autoHideEnabled;
+ },
+
+ /**
+ * Set scroll bar opacity
+ * @param {number} opacity scroll bar opacity
+ */
+ setOpacity: function (opacity) {
+ this._opacity = opacity;
+ },
+
+ /**
+ * Get scroll bar opacity
+ * @returns {number}
+ */
+ getOpacity: function () {
+ return this._opacity;
+ },
+
+ _updateLength: function (length) {
+ var ratio = length / this._body.getTextureRect().height;
+ this._body.setScaleY(ratio);
+ this._upperHalfCircle.setPositionY(this._body.getPositionY() + length);
+ },
+
+ _processAutoHide: function (dt) {
+ if (!this._autoHideEnabled || this._autoHideRemainingTime <= 0) {
+ return;
+ }
+ else if (this._touching) {
+ // If it is touching, don't auto hide.
+ return;
+ }
+
+ this._autoHideRemainingTime -= dt;
+ if (this._autoHideRemainingTime <= this.autoHideTime) {
+ this._autoHideRemainingTime = Math.max(0, this._autoHideRemainingTime);
+ cc.ProtectedNode.prototype.setOpacity.call(this, this._opacity * (this._autoHideRemainingTime / this.autoHideTime));
+ }
+ },
+
+
+ update: function (dt) {
+ this._processAutoHide(dt);
+ },
+
+ /**
+ * This is called by parent ScrollView when a touch is began. Don't call this directly.
+ */
+ onTouchBegan: function () {
+ if (!this._autoHideEnabled) {
+ return;
+ }
+ this._touching = true;
+ },
+
+ /**
+ * This is called by parent ScrollView when a touch is ended. Don't call this directly.
+ */
+ onTouchEnded: function () {
+ if (!this._autoHideEnabled) {
+ return;
+ }
+ this._touching = false;
+
+ if (this._autoHideRemainingTime <= 0) {
+ // If the remaining time is 0, it means that it didn't moved after touch started so scroll bar is not showing.
+ return;
+ }
+ this._autoHideRemainingTime = this.autoHideTime;
+ },
+
+ /**
+ * @brief This is called by parent ScrollView when the parent is scrolled. Don't call this directly.
+ *
+ * @param {cc.Point} outOfBoundary amount how much the inner container of ScrollView is out of boundary
+ */
+ onScrolled: function (outOfBoundary) {
+ if (this._autoHideEnabled) {
+ this._autoHideRemainingTime = this.autoHideTime;
+ cc.ProtectedNode.prototype.setOpacity.call(this, this.opacity);
+ }
+
+ var innerContainer = this._parentScroll.getInnerContainer();
+
+ var innerContainerMeasure = 0;
+ var scrollViewMeasure = 0;
+ var outOfBoundaryValue = 0;
+ var innerContainerPosition = 0;
+
+ if (this._direction === ccui.ScrollView.DIR_VERTICAL) {
+ innerContainerMeasure = innerContainer.height;
+ scrollViewMeasure = this._parentScroll.height;
+ outOfBoundaryValue = outOfBoundary.y;
+ innerContainerPosition = -innerContainer.getPositionY();
+ }
+ else if (this._direction === ccui.ScrollView.DIR_HORIZONTAL) {
+ innerContainerMeasure = innerContainer.width;
+ scrollViewMeasure = this._parentScroll.width;
+ outOfBoundaryValue = outOfBoundary.x;
+ innerContainerPosition = -innerContainer.getPositionX();
+ }
+
+ var length = this._calculateLength(innerContainerMeasure, scrollViewMeasure, outOfBoundaryValue);
+ var position = this._calculatePosition(innerContainerMeasure, scrollViewMeasure, innerContainerPosition, outOfBoundaryValue, length);
+ this._updateLength(length);
+ this.setPosition(position);
+ },
+
+ _calculateLength: function (innerContainerMeasure, scrollViewMeasure, outOfBoundaryValue) {
+ var denominatorValue = innerContainerMeasure;
+ if (outOfBoundaryValue !== 0) {
+ // If it is out of boundary, the length of scroll bar gets shorter quickly.
+ var GETTING_SHORTER_FACTOR = 20;
+ denominatorValue += (outOfBoundaryValue > 0 ? outOfBoundaryValue : -outOfBoundaryValue) * GETTING_SHORTER_FACTOR;
+ }
+
+ var lengthRatio = scrollViewMeasure / denominatorValue;
+ return Math.abs(scrollViewMeasure - 2 * this._marginForLength) * lengthRatio;
+ },
+
+ _calculatePosition: function (innerContainerMeasure, scrollViewMeasure, innerContainerPosition, outOfBoundaryValue, length) {
+ var denominatorValue = innerContainerMeasure - scrollViewMeasure;
+ if (outOfBoundaryValue !== 0) {
+ denominatorValue += Math.abs(outOfBoundaryValue);
+ }
+
+ var positionRatio = 0;
+
+ if (denominatorValue !== 0) {
+ positionRatio = innerContainerPosition / denominatorValue;
+ positionRatio = Math.max(positionRatio, 0);
+ positionRatio = Math.min(positionRatio, 1);
+ }
+
+ var position = (scrollViewMeasure - length - 2 * this._marginForLength) * positionRatio + this._marginForLength;
+
+ if (this._direction === ccui.ScrollView.DIR_VERTICAL) {
+ return cc.p(this._parentScroll.width - this._marginFromBoundary, position);
+ }
+ else {
+ return cc.p(position, this._marginFromBoundary);
+ }
+ }
+
+});
+
+var _p = ccui.ScrollViewBar.prototype;
+
+// Extended properties
+/** @expose */
+_p.opacity;
+cc.defineGetterSetter(_p, "opacity", _p.getOpacity, _p.setOpacity);
+/** @expose */
+_p.autoHideEnabled;
+cc.defineGetterSetter(_p, "autoHideEnabled", _p.isAutoHideEnabled, _p.setAutoHideEnabled);
+
+/**
+ * @ignore
+ */
+ccui.ScrollViewBar.DEFAULT_COLOR = cc.color(52, 65, 87);
+ccui.ScrollViewBar.DEFAULT_MARGIN = 20;
+ccui.ScrollViewBar.DEFAULT_AUTO_HIDE_TIME = 0.2;
+ccui.ScrollViewBar.DEFAULT_SCROLLBAR_OPACITY = 0.4;
+ccui.ScrollViewBar.HALF_CIRCLE_IMAGE_KEY = "/__half_circle_image";
+ccui.ScrollViewBar.HALF_CIRCLE_IMAGE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAGCAMAAADAMI+zAAAAJ1BMVEX///////////////////////////////////////////////////9Ruv0SAAAADHRSTlMABgcbbW7Hz9Dz+PmlcJP5AAAAMElEQVR4AUXHwQ2AQAhFwYcLH1H6r1djzDK3ASxUpTBeK/uTCyz7dx54b44m4p5cD1MwAooEJyk3AAAAAElFTkSuQmCC";
+ccui.ScrollViewBar.BODY_IMAGE_1_PIXEL_HEIGHT_KEY = "/__body_image_height";
+ccui.ScrollViewBar.BODY_IMAGE_1_PIXEL_HEIGHT = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAABCAMAAADdNb8LAAAAA1BMVEX///+nxBvIAAAACklEQVR4AWNABgAADQABYc2cpAAAAABJRU5ErkJggg==";
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewCanvasRenderCmd.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewCanvasRenderCmd.js
new file mode 100644
index 0000000..4607932
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewCanvasRenderCmd.js
@@ -0,0 +1,32 @@
+(function () {
+ if (!ccui.ProtectedNode.CanvasRenderCmd)
+ return;
+ ccui.ScrollView.CanvasRenderCmd = function (renderable) {
+ this._layoutCmdCtor(renderable);
+ //this._needDraw = true;
+ this._dirty = false;
+ };
+
+ var proto = ccui.ScrollView.CanvasRenderCmd.prototype = Object.create(ccui.Layout.CanvasRenderCmd.prototype);
+ proto.constructor = ccui.ScrollView.CanvasRenderCmd;
+
+ proto.rendering = function (ctx) {
+ var currentID = this._node.__instanceId;
+ var i, locCmds = cc.renderer._cacheToCanvasCmds[currentID], len,
+ scaleX = cc.view.getScaleX(),
+ scaleY = cc.view.getScaleY();
+ var context = ctx || cc._renderContext;
+ context.computeRealOffsetY();
+
+ this._node.updateChildren();
+
+ for (i = 0, len = locCmds.length; i < len; i++) {
+ var checkNode = locCmds[i]._node;
+ if (checkNode instanceof ccui.ScrollView)
+ continue;
+ if (checkNode && checkNode._parent && checkNode._parent._inViewRect === false)
+ continue;
+ locCmds[i].rendering(context, scaleX, scaleY);
+ }
+ };
+})();
diff --git a/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewWebGLRenderCmd.js b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewWebGLRenderCmd.js
new file mode 100644
index 0000000..97ba7ff
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewWebGLRenderCmd.js
@@ -0,0 +1,45 @@
+(function () {
+ if (!ccui.ProtectedNode.WebGLRenderCmd)
+ return;
+ ccui.ScrollView.WebGLRenderCmd = function (renderable) {
+ this._layoutCmdCtor(renderable);
+ this._needDraw = true;
+ this._dirty = false;
+ };
+
+ var proto = ccui.ScrollView.WebGLRenderCmd.prototype = Object.create(ccui.Layout.WebGLRenderCmd.prototype);
+ proto.constructor = ccui.ScrollView.WebGLRenderCmd;
+
+ proto.rendering = function (ctx) {
+ var currentID = this._node.__instanceId,
+ locCmds = cc.renderer._cacheToBufferCmds[currentID],
+ i, len, checkNode, cmd,
+ context = ctx || cc._renderContext;
+ if (!locCmds) {
+ return;
+ }
+
+ this._node.updateChildren();
+
+ // Reset buffer for rendering
+ context.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ for (i = 0, len = locCmds.length; i < len; i++) {
+ cmd = locCmds[i];
+ checkNode = cmd._node;
+ if (checkNode && checkNode._parent && checkNode._parent._inViewRect === false)
+ continue;
+
+ if (cmd.uploadData) {
+ cc.renderer._uploadBufferData(cmd);
+ }
+ else {
+ if (cmd._batchingSize > 0) {
+ cc.renderer._batchRendering();
+ }
+ cmd.rendering(context);
+ }
+ cc.renderer._batchRendering();
+ }
+ };
+})();
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/CocoStudio.js b/frameworks/cocos2d-html5/extensions/cocostudio/CocoStudio.js
new file mode 100644
index 0000000..fdb2ddc
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/CocoStudio.js
@@ -0,0 +1,68 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+/**
+ * The main namespace of Cocostudio, all classes, functions, properties and constants of Spine are defined in this namespace
+ * @namespace
+ * @name ccs
+ */
+var ccs = ccs || {};
+
+/**
+ * The same as cc.Class
+ * @class
+ */
+ccs.Class = ccs.Class || cc.Class;
+ccs.Class.extend = ccs.Class.extend || cc.Class.extend;
+
+/**
+ * The same as cc.Node
+ * @class
+ * @extends ccs.Class
+ */
+ccs.Node = ccs.Node || cc.Node;
+ccs.Node.extend = ccs.Node.extend || cc.Node.extend;
+
+/**
+ * The same as cc.Sprite
+ * @class
+ * @extends ccs.Class
+ */
+ccs.Sprite = ccs.Sprite || cc.Sprite;
+ccs.Sprite.extend = ccs.Sprite.extend || cc.Sprite.extend;
+
+/**
+ * The same as cc.Component
+ * @class
+ * @extends ccs.Class
+ */
+ccs.Component = ccs.Component || cc.Component;
+ccs.Component.extend = ccs.Component.extend || cc.Component.extend;
+
+/**
+ * CocoStudio version
+ * @constant
+ * @type {string}
+ */
+ccs.cocostudioVersion = "v1.3.0.0";
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/action/CCActionFrame.js b/frameworks/cocos2d-html5/extensions/cocostudio/action/CCActionFrame.js
new file mode 100644
index 0000000..2571031
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/action/CCActionFrame.js
@@ -0,0 +1,530 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+//Action frame type
+/**
+ * The flag move action type of Cocostudio frame.
+ * @constant
+ * @type {number}
+ */
+ccs.FRAME_TYPE_MOVE = 0;
+/**
+ * The flag scale action type of Cocostudio frame.
+ * @constant
+ * @type {number}
+ */
+ccs.FRAME_TYPE_SCALE = 1;
+/**
+ * The flag rotate action type of Cocostudio frame.
+ * @constant
+ * @type {number}
+ */
+ccs.FRAME_TYPE_ROTATE = 2;
+/**
+ * The flag tint action type of Cocostudio frame.
+ * @constant
+ * @type {number}
+ */
+ccs.FRAME_TYPE_TINT = 3;
+/**
+ * The flag fade action type of Cocostudio frame.
+ * @constant
+ * @type {number}
+ */
+ccs.FRAME_TYPE_FADE = 4;
+/**
+ * The max flag of Cocostudio frame.
+ * @constant
+ * @type {number}
+ */
+ccs.FRAME_TYPE_MAX = 5;
+
+/**
+ * The ease type of Cocostudio frame.
+ * @constant
+ * @type {Object}
+ */
+ccs.FrameEaseType = {
+ CUSTOM : -1,
+
+ LINEAR : 0,
+
+ SINE_EASEIN : 1,
+ SINE_EASEOUT : 2,
+ SINE_EASEINOUT : 3,
+
+ QUAD_EASEIN : 4,
+ QUAD_EASEOUT : 5,
+ QUAD_EASEINOUT : 6,
+
+ CUBIC_EASEIN : 7,
+ CUBIC_EASEOUT : 8,
+ CUBIC_EASEINOUT : 9,
+
+ QUART_EASEIN : 10,
+ QUART_EASEOUT : 11,
+ QUART_EASEINOUT : 12,
+
+ QUINT_EASEIN : 13,
+ QUINT_EASEOUT : 14,
+ QUINT_EASEINOUT : 15,
+
+ EXPO_EASEIN : 16,
+ EXPO_EASEOUT : 17,
+ EXPO_EASEINOUT : 18,
+
+ CIRC_EASEIN : 19,
+ CIRC_EASEOUT : 20,
+ CIRC_EASEINOUT : 21,
+
+ ELASTIC_EASEIN : 22,
+ ELASTIC_EASEOUT : 23,
+ ELASTIC_EASEINOUT : 24,
+
+ BACK_EASEIN : 25,
+ BACK_EASEOUT : 26,
+ BACK_EASEINOUT : 27,
+
+ BOUNCE_EASEIN : 28,
+ BOUNCE_EASEOUT : 29,
+ BOUNCE_EASEINOUT : 30,
+
+ TWEEN_EASING_MAX: 1000
+};
+
+
+/**
+ * The action frame of Cocostudio. It's the base class of ccs.ActionMoveFrame, ccs.ActionScaleFrame etc.
+ * @class
+ * @extends ccs.Class
+ *
+ * @property {Number} frameType - frame type of ccs.ActionFrame
+ * @property {Number} easingType - easing type of ccs.ActionFrame
+ * @property {Number} frameIndex - frame index of ccs.ActionFrame
+ * @property {Number} time - time of ccs.ActionFrame
+ */
+ccs.ActionFrame = ccs.Class.extend(/** @lends ccs.ActionFrame# */{
+ frameType: 0,
+ easingType: 0,
+ frameIndex: 0,
+ _Parameter: null,
+ time: 0,
+
+ /**
+ * The constructor of cc.ActionFrame.
+ */
+ ctor: function () {
+ this.frameType = 0;
+ this.easingType = ccs.FrameEaseType.LINEAR;
+ this.frameIndex = 0;
+ this.time = 0;
+ },
+
+ /**
+ * Returns the action of ActionFrame. its subClass need override it.
+ * @param {number} duration the duration time of ActionFrame
+ * @param {ccs.ActionFrame} srcFrame source frame.
+ * @returns {null}
+ */
+ getAction: function (duration, srcFrame) {
+ cc.log("Need a definition of for ActionFrame");
+ return null;
+ },
+
+ _getEasingAction : function (action) {
+ if (action === null) {
+ console.error("Action cannot be null!");
+ return null;
+ }
+
+ var resultAction;
+ switch (this.easingType) {
+ case ccs.FrameEaseType.CUSTOM:
+ break;
+ case ccs.FrameEaseType.LINEAR:
+ resultAction = action;
+ break;
+ case ccs.FrameEaseType.SINE_EASEIN:
+ resultAction = action.easing(cc.easeSineIn());
+ break;
+ case ccs.FrameEaseType.SINE_EASEOUT:
+ resultAction = action.easing(cc.easeSineOut());
+ break;
+ case ccs.FrameEaseType.SINE_EASEINOUT:
+ resultAction = action.easing(cc.easeSineInOut());
+ break;
+ case ccs.FrameEaseType.QUAD_EASEIN:
+ resultAction = action.easing(cc.easeQuadraticActionIn());
+ break;
+ case ccs.FrameEaseType.QUAD_EASEOUT:
+ resultAction = action.easing(cc.easeQuadraticActionOut());
+ break;
+ case ccs.FrameEaseType.QUAD_EASEINOUT:
+ resultAction = action.easing(cc.easeQuadraticActionInOut());
+ break;
+ case ccs.FrameEaseType.CUBIC_EASEIN:
+ resultAction = action.easing(cc.easeCubicActionIn());
+ break;
+ case ccs.FrameEaseType.CUBIC_EASEOUT:
+ resultAction = action.easing(cc.easeCubicActionOut());
+ break;
+ case ccs.FrameEaseType.CUBIC_EASEINOUT:
+ resultAction = action.easing(cc.easeCubicActionInOut());
+ break;
+ case ccs.FrameEaseType.QUART_EASEIN:
+ resultAction = action.easing(cc.easeQuarticActionIn());
+ break;
+ case ccs.FrameEaseType.QUART_EASEOUT:
+ resultAction = action.easing(cc.easeQuarticActionOut());
+ break;
+ case ccs.FrameEaseType.QUART_EASEINOUT:
+ resultAction = action.easing(cc.easeQuarticActionInOut());
+ break;
+ case ccs.FrameEaseType.QUINT_EASEIN:
+ resultAction = action.easing(cc.easeQuinticActionIn());
+ break;
+ case ccs.FrameEaseType.QUINT_EASEOUT:
+ resultAction = action.easing(cc.easeQuinticActionOut());
+ break;
+ case ccs.FrameEaseType.QUINT_EASEINOUT:
+ resultAction = action.easing(cc.easeQuinticActionInOut());
+ break;
+ case ccs.FrameEaseType.EXPO_EASEIN:
+ resultAction = action.easing(cc.easeExponentialIn());
+ break;
+ case ccs.FrameEaseType.EXPO_EASEOUT:
+ resultAction = action.easing(cc.easeExponentialOut());
+ break;
+ case ccs.FrameEaseType.EXPO_EASEINOUT:
+ resultAction = action.easing(cc.easeExponentialInOut());
+ break;
+ case ccs.FrameEaseType.CIRC_EASEIN:
+ resultAction = action.easing(cc.easeCircleActionIn());
+ break;
+ case ccs.FrameEaseType.CIRC_EASEOUT:
+ resultAction = action.easing(cc.easeCircleActionOut());
+ break;
+ case ccs.FrameEaseType.CIRC_EASEINOUT:
+ resultAction = action.easing(cc.easeCircleActionInOut());
+ break;
+ case ccs.FrameEaseType.ELASTIC_EASEIN:
+ resultAction = action.easing(cc.easeElasticIn());
+ break;
+ case ccs.FrameEaseType.ELASTIC_EASEOUT:
+ resultAction = action.easing(cc.easeElasticOut());
+ break;
+ case ccs.FrameEaseType.ELASTIC_EASEINOUT:
+ resultAction = action.easing(cc.easeElasticInOut());
+ break;
+ case ccs.FrameEaseType.BACK_EASEIN:
+ resultAction = action.easing(cc.easeBackIn());
+ break;
+ case ccs.FrameEaseType.BACK_EASEOUT:
+ resultAction = action.easing(cc.easeBackOut());
+ break;
+ case ccs.FrameEaseType.BACK_EASEINOUT:
+ resultAction = action.easing(cc.easeBackInOut());
+ break;
+ case ccs.FrameEaseType.BOUNCE_EASEIN:
+ resultAction = action.easing(cc.easeBounceIn());
+ break;
+ case ccs.FrameEaseType.BOUNCE_EASEOUT:
+ resultAction = action.easing(cc.easeBounceOut());
+ break;
+ case ccs.FrameEaseType.BOUNCE_EASEINOUT:
+ resultAction = action.easing(cc.easeBounceInOut());
+ break;
+ }
+
+ return resultAction;
+ },
+
+ /**
+ * Sets the easing parameter to action frame.
+ * @param {Array} parameter
+ */
+ setEasingParameter: function(parameter){
+ this._Parameter = [];
+ for(var i=0;i locFrameIndex ? locFrameIndex : locFrameindex;
+ }
+ if (!bFindFrame)
+ locFrameindex = 0;
+ return locFrameindex;
+ },
+
+ /**
+ * Returns the index of last ccs.ActionFrame.
+ * @returns {number}
+ */
+ getLastFrameIndex: function () {
+ var locFrameindex = -1;
+ var locIsFindFrame = false, locFrameArray = this._frameArray;
+ for (var i = 0, len = this._frameArrayNum; i < len; i++) {
+ var locArray = locFrameArray[i];
+ if (locArray.length <= 0)
+ continue;
+ locIsFindFrame = true;
+ var locFrame = locArray[locArray.length - 1];
+ var locFrameIndex = locFrame.frameIndex;
+ locFrameindex = locFrameindex < locFrameIndex ? locFrameIndex : locFrameindex;
+ }
+ if (!locIsFindFrame)
+ locFrameindex = 0;
+ return locFrameindex;
+ },
+
+ /**
+ * Updates action states to some time.
+ * @param {Number} time
+ * @returns {boolean}
+ */
+ updateActionToTimeLine: function (time) {
+ var locIsFindFrame = false;
+ var locUnitTime = this.getUnitTime();
+ for (var i = 0; i < this._frameArrayNum; i++) {
+ var locArray = this._frameArray[i];
+ if (!locArray)
+ continue;
+
+ for (var j = 0; j < locArray.length; j++) {
+ var locFrame = locArray[j];
+ if (locFrame.frameIndex * locUnitTime === time) {
+ this._easingToFrame(1.0, 1.0, locFrame);
+ locIsFindFrame = true;
+ break;
+ } else if (locFrame.frameIndex * locUnitTime > time) {
+ if (j === 0) {
+ this._easingToFrame(1.0, 1.0, locFrame);
+ locIsFindFrame = false;
+ } else {
+ var locSrcFrame = locArray[j - 1];
+ var locDuration = (locFrame.frameIndex - locSrcFrame.frameIndex) * locUnitTime;
+ var locDelaytime = time - locSrcFrame.frameIndex * locUnitTime;
+ this._easingToFrame(locDuration, 1.0, locSrcFrame);
+ this._easingToFrame(locDuration, locDelaytime / locDuration, locFrame);
+ locIsFindFrame = true;
+ }
+ break;
+ }
+ }
+ }
+ return locIsFindFrame;
+ },
+
+ _easingToFrame: function (duration, delayTime, destFrame) {
+ var action = destFrame.getAction(duration);
+ var node = this.getActionNode();
+ if (action == null || node == null)
+ return;
+ action.startWithTarget(node);
+ action.update(delayTime);
+ },
+
+ /**
+ * Returns if the action is done once time.
+ * @returns {Boolean} that if the action is done once time
+ */
+ isActionDoneOnce: function () {
+ if (!this._action)
+ return true;
+ return this._action.isDone();
+ }
+});
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/action/CCActionObject.js b/frameworks/cocos2d-html5/extensions/cocostudio/action/CCActionObject.js
new file mode 100644
index 0000000..88597f3
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/action/CCActionObject.js
@@ -0,0 +1,263 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The Cocostudio's action object.
+ * @class
+ * @extends ccs.Class
+ */
+ccs.ActionObject = ccs.Class.extend(/** @lends ccs.ActionObject# */{
+ _actionNodeList: null,
+ _name: "",
+ _loop: false,
+ _pause: false,
+ _playing: false,
+ _unitTime: 0,
+ _currentTime: 0,
+ _scheduler:null,
+ _callback: null,
+ _fTotalTime: 0,
+
+ /**
+ * Construction of ccs.ActionObject.
+ */
+ ctor: function () {
+ this._actionNodeList = [];
+ this._name = "";
+ this._loop = false;
+ this._pause = false;
+ this._playing = false;
+ this._unitTime = 0.1;
+ this._currentTime = 0;
+ this._fTotalTime = 0;
+ this._scheduler = cc.director.getScheduler();
+ },
+
+ /**
+ * Sets name to ccs.ActionObject
+ * @param {string} name
+ */
+ setName: function (name) {
+ this._name = name;
+ },
+
+ /**
+ * Returns name fo ccs.ActionObject
+ * @returns {string}
+ */
+ getName: function () {
+ return this._name;
+ },
+
+ /**
+ * Sets if the action will loop play.
+ * @param {boolean} loop
+ */
+ setLoop: function (loop) {
+ this._loop = loop;
+ },
+
+ /**
+ * Returns if the action will loop play.
+ * @returns {boolean}
+ */
+ getLoop: function () {
+ return this._loop;
+ },
+
+ /**
+ * Sets the time interval of frame.
+ * @param {number} time
+ */
+ setUnitTime: function (time) {
+ this._unitTime = time;
+ var frameNum = this._actionNodeList.length;
+ for (var i = 0; i < frameNum; i++) {
+ var locActionNode = this._actionNodeList[i];
+ locActionNode.setUnitTime(this._unitTime);
+ }
+ },
+
+ /**
+ * Returns the time interval of frame.
+ * @returns {number} the time interval of frame
+ */
+ getUnitTime: function () {
+ return this._unitTime;
+ },
+
+ /**
+ * Returns the current time of frame.
+ * @returns {number}
+ */
+ getCurrentTime: function () {
+ return this._currentTime;
+ },
+
+ /**
+ * Sets the current time of frame.
+ * @param {Number} time the current time of frame
+ */
+ setCurrentTime: function (time) {
+ this._currentTime = time;
+ },
+
+ /**
+ * Returns the total time of frame.
+ * @returns {number} the total time of frame
+ */
+ getTotalTime: function(){
+ return this._fTotalTime;
+ },
+
+ /**
+ * Returns if the action is playing.
+ * @returns {boolean} true if the action is playing, false the otherwise
+ */
+ isPlaying: function () {
+ return this._playing;
+ },
+
+ /**
+ * Init properties with a json dictionary
+ * @param {Object} dic
+ * @param {Object} root
+ */
+ initWithDictionary: function (dic, root) {
+ this.setName(dic["name"]);
+ this.setLoop(dic["loop"]);
+ this.setUnitTime(dic["unittime"]);
+ var actionNodeList = dic["actionnodelist"];
+ var maxLength = 0;
+ for (var i = 0; i < actionNodeList.length; i++) {
+ var actionNode = new ccs.ActionNode();
+
+ var actionNodeDic = actionNodeList[i];
+ actionNode.initWithDictionary(actionNodeDic, root);
+ actionNode.setUnitTime(this.getUnitTime());
+ this._actionNodeList.push(actionNode);
+ var length = actionNode.getLastFrameIndex() - actionNode.getFirstFrameIndex();
+ if(length > maxLength){
+ maxLength = length;
+ }
+ }
+ this._fTotalTime = maxLength * this._unitTime;
+ },
+
+ /**
+ * Adds a ActionNode to play the action.
+ * @param {ccs.ActionNode} node
+ */
+ addActionNode: function (node) {
+ if (!node)
+ return;
+ this._actionNodeList.push(node);
+ node.setUnitTime(this._unitTime);
+ },
+
+ /**
+ * Removes a ActionNode which play the action.
+ * @param {ccs.ActionNode} node
+ */
+ removeActionNode: function (node) {
+ if (node == null)
+ return;
+ cc.arrayRemoveObject(this._actionNodeList, node);
+ },
+
+ /**
+ * Plays the action.
+ * @param {cc.CallFunc} [fun] Action Call Back
+ */
+ play: function (fun) {
+ this.stop();
+ this.updateToFrameByTime(0);
+ var locActionNodeList = this._actionNodeList;
+ var frameNum = locActionNodeList.length;
+ for (var i = 0; i < frameNum; i++) {
+ locActionNodeList[i].playAction(fun);
+ }
+ if (this._loop)
+ this._scheduler.schedule(this.simulationActionUpdate, this, 0, cc.REPEAT_FOREVER, 0, false, this.__instanceId + "");
+ if(fun !== undefined)
+ this._callback = fun;
+ },
+
+ /**
+ * Pauses the action.
+ */
+ pause: function () {
+ this._pause = true;
+ this._playing = false;
+ },
+
+ /**
+ * Stop the action.
+ */
+ stop: function () {
+ var locActionNodeList = this._actionNodeList;
+ for (var i = 0; i < locActionNodeList.length; i++)
+ locActionNodeList[i].stopAction();
+ this._scheduler.unschedule(this.simulationActionUpdate, this);
+ this._pause = false;
+ this._playing = false;
+ },
+
+ /**
+ * Updates frame by time.
+ */
+ updateToFrameByTime: function (time) {
+ this._currentTime = time;
+ for (var i = 0; i < this._actionNodeList.length; i++) {
+ var locActionNode = this._actionNodeList[i];
+ locActionNode.updateActionToTimeLine(time);
+ }
+ },
+
+ /**
+ * scheduler update function
+ * @param {Number} dt delta time
+ */
+ simulationActionUpdate: function (dt) {
+ var isEnd = true, locNodeList = this._actionNodeList;
+ for(var i = 0, len = locNodeList.length; i < len; i++) {
+ if (!locNodeList[i].isActionDoneOnce()){
+ isEnd = false;
+ break;
+ }
+ }
+
+ if (isEnd){
+ if (this._callback !== null)
+ this._callback.execute();
+ if (this._loop)
+ this.play();
+ else{
+ this._playing = false;
+ this._scheduler.unschedule(this.simulationActionUpdate, this);
+ }
+ }
+ }
+});
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/CCArmature.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/CCArmature.js
new file mode 100644
index 0000000..3836c34
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/CCArmature.js
@@ -0,0 +1,591 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The main class of Armature, it plays armature animation, manages and updates bones' state.
+ * @class
+ * @extends ccs.Node
+ *
+ * @property {ccs.Bone} parentBone - The parent bone of the armature node
+ * @property {ccs.ArmatureAnimation} animation - The animation
+ * @property {ccs.ArmatureData} armatureData - The armature data
+ * @property {String} name - The name of the armature
+ * @property {cc.SpriteBatchNode} batchNode - The batch node of the armature
+ * @property {Number} version - The version
+ * @property {Object} body - The body of the armature
+ * @property {ccs.ColliderFilter} colliderFilter - <@writeonly> The collider filter of the armature
+ */
+ccs.Armature = ccs.Node.extend(/** @lends ccs.Armature# */{
+ animation: null,
+ armatureData: null,
+ batchNode: null,
+ _parentBone: null,
+ _boneDic: null,
+ _topBoneList: null,
+ _armatureIndexDic: null,
+ _offsetPoint: null,
+ version: 0,
+ _armatureTransformDirty: true,
+ _body: null,
+ _blendFunc: null,
+ _className: "Armature",
+
+ /**
+ * Create a armature node.
+ * Constructor of ccs.Armature
+ * @param {String} name
+ * @param {ccs.Bone} parentBone
+ * @example
+ * var armature = new ccs.Armature();
+ */
+ ctor: function (name, parentBone) {
+ cc.Node.prototype.ctor.call(this);
+ this._name = "";
+ this._topBoneList = [];
+ this._armatureIndexDic = {};
+ this._offsetPoint = cc.p(0, 0);
+ this._armatureTransformDirty = true;
+ this._blendFunc = {src: cc.BLEND_SRC, dst: cc.BLEND_DST};
+ name && ccs.Armature.prototype.init.call(this, name, parentBone);
+ // Hack way to avoid RendererWebGL from skipping Armature
+ this._texture = {};
+ },
+
+ /**
+ * Initializes a CCArmature with the specified name and CCBone
+ * @param {String} [name]
+ * @param {ccs.Bone} [parentBone]
+ * @return {Boolean}
+ */
+ init: function (name, parentBone) {
+ if (parentBone)
+ this._parentBone = parentBone;
+ this.removeAllChildren();
+ this.animation = new ccs.ArmatureAnimation();
+ this.animation.init(this);
+
+ this._boneDic = {};
+ this._topBoneList.length = 0;
+
+ //this._name = name || "";
+ var armatureDataManager = ccs.armatureDataManager;
+
+ var animationData;
+ if (name !== "") {
+ //animationData
+ animationData = armatureDataManager.getAnimationData(name);
+ cc.assert(animationData, "AnimationData not exist!");
+
+ this.animation.setAnimationData(animationData);
+
+ //armatureData
+ var armatureData = armatureDataManager.getArmatureData(name);
+ cc.assert(armatureData, "ArmatureData not exist!");
+
+ this.armatureData = armatureData;
+
+ //boneDataDic
+ var boneDataDic = armatureData.getBoneDataDic();
+ for (var key in boneDataDic) {
+ var bone = this.createBone(String(key));
+
+ //! init bone's Tween to 1st movement's 1st frame
+ do {
+ var movData = animationData.getMovement(animationData.movementNames[0]);
+ if (!movData) break;
+
+ var _movBoneData = movData.getMovementBoneData(bone.getName());
+ if (!_movBoneData || _movBoneData.frameList.length <= 0) break;
+
+ var frameData = _movBoneData.getFrameData(0);
+ if (!frameData) break;
+
+ bone.getTweenData().copy(frameData);
+ bone.changeDisplayWithIndex(frameData.displayIndex, false);
+ } while (0);
+ }
+
+ this.update(0);
+ this.updateOffsetPoint();
+ } else {
+ name = "new_armature";
+ this.armatureData = new ccs.ArmatureData();
+ this.armatureData.name = name;
+
+ animationData = new ccs.AnimationData();
+ animationData.name = name;
+
+ armatureDataManager.addArmatureData(name, this.armatureData);
+ armatureDataManager.addAnimationData(name, animationData);
+
+ this.animation.setAnimationData(animationData);
+ }
+
+ this._renderCmd.initShaderCache();
+
+ this.setCascadeOpacityEnabled(true);
+ this.setCascadeColorEnabled(true);
+ return true;
+ },
+
+ visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
+
+ cmd.visit(parentCmd);
+ cmd._dirtyFlag = 0;
+ },
+
+ addChild: function (child, localZOrder, tag) {
+ if (child instanceof ccui.Widget) {
+ cc.log("Armature doesn't support to add Widget as its child, it will be fix soon.");
+ return;
+ }
+ cc.Node.prototype.addChild.call(this, child, localZOrder, tag);
+ },
+
+ /**
+ * create a bone with name
+ * @param {String} boneName
+ * @return {ccs.Bone}
+ */
+ createBone: function (boneName) {
+ var existedBone = this.getBone(boneName);
+ if (existedBone)
+ return existedBone;
+
+ var boneData = this.armatureData.getBoneData(boneName);
+ var parentName = boneData.parentName;
+
+ var bone = null;
+ if (parentName) {
+ this.createBone(parentName);
+ bone = new ccs.Bone(boneName);
+ this.addBone(bone, parentName);
+ } else {
+ bone = new ccs.Bone(boneName);
+ this.addBone(bone, "");
+ }
+
+ bone.setBoneData(boneData);
+ bone.getDisplayManager().changeDisplayWithIndex(-1, false);
+ return bone;
+ },
+
+ /**
+ * Add a Bone to this Armature
+ * @param {ccs.Bone} bone The Bone you want to add to Armature
+ * @param {String} parentName The parent Bone's name you want to add to. If it's null, then set Armature to its parent
+ */
+ addBone: function (bone, parentName) {
+ cc.assert(bone, "Argument must be non-nil");
+ var locBoneDic = this._boneDic;
+ if (bone.getName())
+ cc.assert(!locBoneDic[bone.getName()], "bone already added. It can't be added again");
+
+ if (parentName) {
+ var boneParent = locBoneDic[parentName];
+ if (boneParent)
+ boneParent.addChildBone(bone);
+ else
+ this._topBoneList.push(bone);
+ } else
+ this._topBoneList.push(bone);
+ bone.setArmature(this);
+
+ locBoneDic[bone.getName()] = bone;
+ this.addChild(bone);
+ },
+
+ /**
+ * Remove a bone with the specified name. If recursion it will also remove child Bone recursively.
+ * @param {ccs.Bone} bone The bone you want to remove
+ * @param {Boolean} recursion Determine whether remove the bone's child recursion.
+ */
+ removeBone: function (bone, recursion) {
+ cc.assert(bone, "bone must be added to the bone dictionary!");
+
+ bone.setArmature(null);
+ bone.removeFromParent(recursion);
+ cc.arrayRemoveObject(this._topBoneList, bone);
+
+ delete this._boneDic[bone.getName()];
+ this.removeChild(bone, true);
+ },
+
+ /**
+ * Gets a bone with the specified name
+ * @param {String} name The bone's name you want to get
+ * @return {ccs.Bone}
+ */
+ getBone: function (name) {
+ return this._boneDic[name];
+ },
+
+ /**
+ * Change a bone's parent with the specified parent name.
+ * @param {ccs.Bone} bone The bone you want to change parent
+ * @param {String} parentName The new parent's name
+ */
+ changeBoneParent: function (bone, parentName) {
+ cc.assert(bone, "bone must be added to the bone dictionary!");
+
+ var parentBone = bone.getParentBone();
+ if (parentBone) {
+ cc.arrayRemoveObject(parentBone.getChildren(), bone);
+ bone.setParentBone(null);
+ }
+
+ if (parentName) {
+ var boneParent = this._boneDic[parentName];
+ if (boneParent) {
+ boneParent.addChildBone(bone);
+ cc.arrayRemoveObject(this._topBoneList, bone);
+ } else
+ this._topBoneList.push(bone);
+ }
+ },
+
+ /**
+ * Get CCArmature's bone dictionary
+ * @return {Object} Armature's bone dictionary
+ */
+ getBoneDic: function () {
+ return this._boneDic;
+ },
+
+ /**
+ * Set contentSize and Calculate anchor point.
+ */
+ updateOffsetPoint: function () {
+ // Set contentsize and Calculate anchor point.
+ var rect = this.getBoundingBox();
+ this.setContentSize(rect);
+ var locOffsetPoint = this._offsetPoint;
+ locOffsetPoint.x = -rect.x;
+ locOffsetPoint.y = -rect.y;
+ if (rect.width !== 0 && rect.height !== 0)
+ this.setAnchorPoint(locOffsetPoint.x / rect.width, locOffsetPoint.y / rect.height);
+ },
+
+ getOffsetPoints: function () {
+ return {x: this._offsetPoint.x, y: this._offsetPoint.y};
+ },
+
+ /**
+ * Sets animation to this Armature
+ * @param {ccs.ArmatureAnimation} animation
+ */
+ setAnimation: function (animation) {
+ this.animation = animation;
+ },
+
+ /**
+ * Gets the animation of this Armature.
+ * @return {ccs.ArmatureAnimation}
+ */
+ getAnimation: function () {
+ return this.animation;
+ },
+
+ /**
+ * armatureTransformDirty getter
+ * @returns {Boolean}
+ */
+ getArmatureTransformDirty: function () {
+ return this._armatureTransformDirty;
+ },
+
+ /**
+ * The update callback of ccs.Armature, it updates animation's state and updates bone's state.
+ * @override
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ this.animation.update(dt);
+ var locTopBoneList = this._topBoneList;
+ for (var i = 0; i < locTopBoneList.length; i++)
+ locTopBoneList[i].update(dt);
+ this._armatureTransformDirty = false;
+ },
+
+ /**
+ * The callback when ccs.Armature enter stage.
+ * @override
+ */
+ onEnter: function () {
+ cc.Node.prototype.onEnter.call(this);
+ this.scheduleUpdate();
+ },
+
+ /**
+ * The callback when ccs.Armature exit stage.
+ * @override
+ */
+ onExit: function () {
+ cc.Node.prototype.onExit.call(this);
+ this.unscheduleUpdate();
+ },
+
+ /**
+ * This boundingBox will calculate all bones' boundingBox every time
+ * @returns {cc.Rect}
+ */
+ getBoundingBox: function () {
+ var minX, minY, maxX, maxY = 0;
+ var first = true;
+
+ var boundingBox = cc.rect(0, 0, 0, 0), locChildren = this._children;
+
+ var len = locChildren.length;
+ for (var i = 0; i < len; i++) {
+ var bone = locChildren[i];
+ if (bone) {
+ var r = bone.getDisplayManager().getBoundingBox();
+ if (r.x === 0 && r.y === 0 && r.width === 0 && r.height === 0)
+ continue;
+
+ if (first) {
+ minX = r.x;
+ minY = r.y;
+ maxX = r.x + r.width;
+ maxY = r.y + r.height;
+ first = false;
+ } else {
+ minX = r.x < boundingBox.x ? r.x : boundingBox.x;
+ minY = r.y < boundingBox.y ? r.y : boundingBox.y;
+ maxX = r.x + r.width > boundingBox.x + boundingBox.width ?
+ r.x + r.width : boundingBox.x + boundingBox.width;
+ maxY = r.y + r.height > boundingBox.y + boundingBox.height ?
+ r.y + r.height : boundingBox.y + boundingBox.height;
+ }
+
+ boundingBox.x = minX;
+ boundingBox.y = minY;
+ boundingBox.width = maxX - minX;
+ boundingBox.height = maxY - minY;
+ }
+ }
+ return cc.rectApplyAffineTransform(boundingBox, this.getNodeToParentTransform());
+ },
+
+ /**
+ * when bone contain the point ,then return it.
+ * @param {Number} x
+ * @param {Number} y
+ * @returns {ccs.Bone}
+ */
+ getBoneAtPoint: function (x, y) {
+ var locChildren = this._children;
+ for (var i = locChildren.length - 1; i >= 0; i--) {
+ var child = locChildren[i];
+ if (child instanceof ccs.Bone && child.getDisplayManager().containPoint(x, y))
+ return child;
+ }
+ return null;
+ },
+
+ /**
+ * Sets parent bone of this Armature
+ * @param {ccs.Bone} parentBone
+ */
+ setParentBone: function (parentBone) {
+ this._parentBone = parentBone;
+ var locBoneDic = this._boneDic;
+ for (var key in locBoneDic) {
+ locBoneDic[key].setArmature(this);
+ }
+ },
+
+ /**
+ * Return parent bone of ccs.Armature.
+ * @returns {ccs.Bone}
+ */
+ getParentBone: function () {
+ return this._parentBone;
+ },
+
+ /**
+ * draw contour
+ */
+ drawContour: function () {
+ cc._drawingUtil.setDrawColor(255, 255, 255, 255);
+ cc._drawingUtil.setLineWidth(1);
+ var locBoneDic = this._boneDic;
+ for (var key in locBoneDic) {
+ var bone = locBoneDic[key];
+ var detector = bone.getColliderDetector();
+ if (!detector)
+ continue;
+ var bodyList = detector.getColliderBodyList();
+ for (var i = 0; i < bodyList.length; i++) {
+ var body = bodyList[i];
+ var vertexList = body.getCalculatedVertexList();
+ cc._drawingUtil.drawPoly(vertexList, vertexList.length, true);
+ }
+ }
+ },
+
+ setBody: function (body) {
+ if (this._body === body)
+ return;
+
+ this._body = body;
+ this._body.data = this;
+ var child, displayObject, locChildren = this._children;
+ for (var i = 0; i < locChildren.length; i++) {
+ child = locChildren[i];
+ if (child instanceof ccs.Bone) {
+ var displayList = child.getDisplayManager().getDecorativeDisplayList();
+ for (var j = 0; j < displayList.length; j++) {
+ displayObject = displayList[j];
+ var detector = displayObject.getColliderDetector();
+ if (detector)
+ detector.setBody(this._body);
+ }
+ }
+ }
+ },
+
+ getShapeList: function () {
+ if (this._body)
+ return this._body.shapeList;
+ return null;
+ },
+
+ getBody: function () {
+ return this._body;
+ },
+
+ /**
+ * Sets the blendFunc to ccs.Armature
+ * @param {cc.BlendFunc|Number} blendFunc
+ * @param {Number} [dst]
+ */
+ setBlendFunc: function (blendFunc, dst) {
+ if (dst === undefined) {
+ this._blendFunc.src = blendFunc.src;
+ this._blendFunc.dst = blendFunc.dst;
+ } else {
+ this._blendFunc.src = blendFunc;
+ this._blendFunc.dst = dst;
+ }
+ },
+
+ /**
+ * Returns the blendFunc of ccs.Armature
+ * @returns {cc.BlendFunc}
+ */
+ getBlendFunc: function () {
+ return new cc.BlendFunc(this._blendFunc.src, this._blendFunc.dst);
+ },
+
+ /**
+ * set collider filter
+ * @param {ccs.ColliderFilter} filter
+ */
+ setColliderFilter: function (filter) {
+ var locBoneDic = this._boneDic;
+ for (var key in locBoneDic)
+ locBoneDic[key].setColliderFilter(filter);
+ },
+
+ /**
+ * Returns the armatureData of ccs.Armature
+ * @return {ccs.ArmatureData}
+ */
+ getArmatureData: function () {
+ return this.armatureData;
+ },
+
+ /**
+ * Sets armatureData to this Armature
+ * @param {ccs.ArmatureData} armatureData
+ */
+ setArmatureData: function (armatureData) {
+ this.armatureData = armatureData;
+ },
+
+ getBatchNode: function () {
+ return this.batchNode;
+ },
+
+ setBatchNode: function (batchNode) {
+ this.batchNode = batchNode;
+ },
+
+ /**
+ * version getter
+ * @returns {Number}
+ */
+ getVersion: function () {
+ return this.version;
+ },
+
+ /**
+ * version setter
+ * @param {Number} version
+ */
+ setVersion: function (version) {
+ this.version = version;
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new ccs.Armature.CanvasRenderCmd(this);
+ else
+ return new ccs.Armature.WebGLRenderCmd(this);
+ }
+});
+
+var _p = ccs.Armature.prototype;
+
+/** @expose */
+_p.parentBone;
+cc.defineGetterSetter(_p, "parentBone", _p.getParentBone, _p.setParentBone);
+/** @expose */
+_p.body;
+cc.defineGetterSetter(_p, "body", _p.getBody, _p.setBody);
+/** @expose */
+_p.colliderFilter;
+cc.defineGetterSetter(_p, "colliderFilter", null, _p.setColliderFilter);
+
+_p = null;
+
+/**
+ * Allocates an armature, and use the ArmatureData named name in ArmatureDataManager to initializes the armature.
+ * @param {String} [name] Bone name
+ * @param {ccs.Bone} [parentBone] the parent bone
+ * @return {ccs.Armature}
+ * @deprecated since v3.1, please use new construction instead
+ */
+ccs.Armature.create = function (name, parentBone) {
+ return new ccs.Armature(name, parentBone);
+};
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/CCArmatureCanvasRenderCmd.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/CCArmatureCanvasRenderCmd.js
new file mode 100644
index 0000000..bdb35f9
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/CCArmatureCanvasRenderCmd.js
@@ -0,0 +1,213 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ ccs.Armature.RenderCmd = {
+ _updateAnchorPointInPoint: function () {
+ var node = this._node;
+ var contentSize = node._contentSize, anchorPoint = node._anchorPoint, offsetPoint = node._offsetPoint;
+ this._anchorPointInPoints.x = contentSize.width * anchorPoint.x - offsetPoint.x;
+ this._anchorPointInPoints.y = contentSize.height * anchorPoint.y - offsetPoint.y;
+
+ this._realAnchorPointInPoints.x = contentSize.width * anchorPoint.x;
+ this._realAnchorPointInPoints.y = contentSize.height * anchorPoint.y;
+ this.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ getAnchorPointInPoints: function () {
+ return cc.p(this._realAnchorPointInPoints);
+ }
+ };
+})();
+
+(function () {
+ ccs.Armature.CanvasRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+
+ this._realAnchorPointInPoints = new cc.Point(0, 0);
+ this._canUseDirtyRegion = true;
+ this._startRenderCmd = new cc.CustomRenderCmd(this, this._startCmdCallback);
+ this._RestoreRenderCmd = new cc.CustomRenderCmd(this, this._RestoreCmdCallback);
+ this._startRenderCmd._canUseDirtyRegion = true;
+ this._RestoreRenderCmd._canUseDirtyRegion = true;
+
+ this._transform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ this._worldTransform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ };
+
+ var proto = ccs.Armature.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ cc.inject(ccs.Armature.RenderCmd, proto);
+ proto.constructor = ccs.Armature.CanvasRenderCmd;
+
+ proto._startCmdCallback = function (ctx, scaleX, scaleY) {
+ var node = this._node, parent = node._parent;
+ this.transform(parent ? parent._renderCmd : null);
+
+ var wrapper = ctx || cc._renderContext;
+ wrapper.save();
+ //set to armature mode
+ wrapper._switchToArmatureMode(true, this._worldTransform, scaleX, scaleY);
+ };
+
+ proto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
+
+ var locChildren = this._node._children;
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ var selBone = locChildren[i];
+ var boneCmd = selBone._renderCmd;
+ if (selBone && selBone.getDisplayRenderNode) {
+ var boneType = selBone.getDisplayRenderNodeType();
+ var selNode = selBone.getDisplayRenderNode();
+ if (selNode && selNode._renderCmd) {
+ var cmd = selNode._renderCmd;
+ cmd.transform(null); //must be null, use transform in armature mode
+ if (boneType !== ccs.DISPLAY_TYPE_ARMATURE && boneType !== ccs.DISPLAY_TYPE_SPRITE) {
+ cc.affineTransformConcatIn(cmd._worldTransform, selBone._worldTransform);
+ }
+
+ //update displayNode's color and opacity, because skin didn't call visit()
+ var flags = cc.Node._dirtyFlags, locFlag = cmd._dirtyFlag, boneFlag = boneCmd._dirtyFlag;
+ var colorDirty = boneFlag & flags.colorDirty,
+ opacityDirty = boneFlag & flags.opacityDirty;
+ if (colorDirty)
+ boneCmd._updateDisplayColor(this._displayedColor);
+ if (opacityDirty)
+ boneCmd._updateDisplayOpacity(this._displayedOpacity);
+ if (colorDirty || opacityDirty)
+ boneCmd._updateColor();
+
+ var parentColor = selBone._renderCmd._displayedColor, parentOpacity = selBone._renderCmd._displayedOpacity;
+ colorDirty = locFlag & flags.colorDirty;
+ opacityDirty = locFlag & flags.opacityDirty;
+ if (colorDirty)
+ cmd._updateDisplayColor(parentColor);
+ if (opacityDirty)
+ cmd._updateDisplayOpacity(parentOpacity);
+ if (colorDirty || opacityDirty) {
+ cmd._updateColor();
+ }
+ }
+ }
+ }
+ };
+
+ proto._RestoreCmdCallback = function (wrapper) {
+ this._cacheDirty = false;
+ wrapper._switchToArmatureMode(false);
+ wrapper.restore();
+ };
+
+ proto.initShaderCache = function () {
+ };
+ proto.setShaderProgram = function () {
+ };
+ proto.updateChildPosition = function (dis, bone) {
+ dis.visit();
+ // cc.renderer.pushRenderCommand(dis._renderCmd);
+ };
+
+ proto.rendering = function (ctx, scaleX, scaleY) {
+ var node = this._node;
+ var locChildren = node._children;
+ var alphaPremultiplied = cc.BlendFunc.ALPHA_PREMULTIPLIED, alphaNonPremultipled = cc.BlendFunc.ALPHA_NON_PREMULTIPLIED;
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ var selBone = locChildren[i];
+ if (selBone && selBone.getDisplayRenderNode) {
+ var selNode = selBone.getDisplayRenderNode();
+ if (null === selNode)
+ continue;
+
+ selBone._renderCmd._syncStatus(this);
+ switch (selBone.getDisplayRenderNodeType()) {
+ case ccs.DISPLAY_TYPE_SPRITE:
+ selNode.visit(selBone);
+ break;
+ case ccs.DISPLAY_TYPE_ARMATURE:
+ selNode._renderCmd.rendering(ctx, scaleX, scaleY);
+ break;
+ default:
+ selNode.visit(selBone);
+ break;
+ }
+ } else if (selBone instanceof cc.Node) {
+ this._visitNormalChild(selBone);
+ // selBone.visit(this);
+ }
+ }
+ };
+
+ proto._visitNormalChild = function (childNode) {
+ if (!childNode)
+ return;
+
+ var cmd = childNode._renderCmd;
+ // quick return if not visible
+ if (!childNode._visible)
+ return;
+ cmd._curLevel = this._curLevel + 1;
+
+ //visit for canvas
+ var i, children = childNode._children, child;
+ cmd._syncStatus(this);
+ //because armature use transform, not setTransform
+ cmd.transform(null);
+
+ var len = children.length;
+ if (len > 0) {
+ childNode.sortAllChildren();
+ // draw children zOrder < 0
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder < 0)
+ child.visit(childNode);
+ else
+ break;
+ }
+ cc.renderer.pushRenderCommand(cmd);
+ for (; i < len; i++)
+ children[i].visit(childNode);
+ } else {
+ cc.renderer.pushRenderCommand(cmd);
+ }
+ this._dirtyFlag = 0;
+ };
+
+ proto.visit = function (parentCmd) {
+ var node = this._node;
+ // quick return if not visible. children won't be drawn.
+ if (!node._visible)
+ return;
+
+ this._syncStatus(parentCmd);
+ node.sortAllChildren();
+
+ cc.renderer.pushRenderCommand(this._startRenderCmd);
+ this.rendering();
+ cc.renderer.pushRenderCommand(this._RestoreRenderCmd);
+
+ this._cacheDirty = false;
+ };
+})();
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js
new file mode 100644
index 0000000..6f24c7b
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js
@@ -0,0 +1,185 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+
+ ccs.Armature.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+
+ this._parentCmd = null;
+ this._realAnchorPointInPoints = new cc.Point(0, 0);
+
+ this._transform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ this._worldTransform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ };
+
+ var proto = ccs.Armature.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ cc.inject(ccs.Armature.RenderCmd, proto);
+ proto.constructor = ccs.Armature.WebGLRenderCmd;
+
+ proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset) {
+ var node = this._node, cmd;
+ var parentCmd = this._parentCmd || this;
+
+ var locChildren = node._children;
+ var alphaPremultiplied = cc.BlendFunc.ALPHA_PREMULTIPLIED, alphaNonPremultipled = cc.BlendFunc.ALPHA_NON_PREMULTIPLIED;
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ var selBone = locChildren[i];
+ var boneCmd = selBone._renderCmd;
+ if (selBone && selBone.getDisplayRenderNode) {
+ var selNode = selBone.getDisplayRenderNode();
+ if (null === selNode)
+ continue;
+ cmd = selNode._renderCmd;
+ switch (selBone.getDisplayRenderNodeType()) {
+ case ccs.DISPLAY_TYPE_SPRITE:
+ if (selNode instanceof ccs.Skin) {
+ selNode.setShaderProgram(this._shaderProgram);
+ this._updateColorAndOpacity(cmd, selBone); //because skin didn't call visit()
+ cmd.transform(parentCmd);
+
+ var func = selBone.getBlendFunc();
+ if (func.src !== alphaPremultiplied.src || func.dst !== alphaPremultiplied.dst)
+ selNode.setBlendFunc(selBone.getBlendFunc());
+ else {
+ var tex = selNode.getTexture();
+ if (node._blendFunc.src === alphaPremultiplied.src &&
+ node._blendFunc.dst === alphaPremultiplied.dst &&
+ tex && !tex.hasPremultipliedAlpha()) {
+ selNode.setBlendFunc(alphaNonPremultipled);
+ }
+ else {
+ selNode.setBlendFunc(node._blendFunc);
+ }
+ }
+ // Support batch for Armature skin
+ cc.renderer._uploadBufferData(cmd);
+ }
+ break;
+ case ccs.DISPLAY_TYPE_ARMATURE:
+ selNode.setShaderProgram(this._shaderProgram);
+ this._updateColorAndOpacity(cmd, selBone);
+ cmd._parentCmd = this;
+ // Continue rendering in default
+ default:
+ boneCmd._syncStatus(parentCmd);
+ cmd._syncStatus(boneCmd);
+ if (cmd.uploadData) {
+ cc.renderer._uploadBufferData(cmd);
+ }
+ else if (cmd.rendering) {
+ // Finish previous batch
+ cc.renderer._batchRendering();
+ cmd.rendering(cc._renderContext);
+ }
+ break;
+ }
+ } else if (selBone instanceof cc.Node) {
+ selBone.setShaderProgram(this._shaderProgram);
+ boneCmd._syncStatus(parentCmd);
+ if (boneCmd.uploadData) {
+ cc.renderer._uploadBufferData(boneCmd);
+ }
+ else if (boneCmd.rendering) {
+ // Finish previous batch
+ cc.renderer._batchRendering();
+ boneCmd.rendering(cc._renderContext);
+ }
+ }
+ }
+ this._parentCmd = null;
+ return 0;
+ };
+
+ proto.initShaderCache = function () {
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR);
+ };
+
+ proto.setShaderProgram = function (shaderProgram) {
+ this._glProgramState = cc.GLProgramState.getOrCreateWithGLProgram(shaderProgram);
+ };
+
+ proto._updateColorAndOpacity = function (skinRenderCmd, bone) {
+ //update displayNode's color and opacity
+ var parentColor = bone._renderCmd._displayedColor, parentOpacity = bone._renderCmd._displayedOpacity;
+
+ var flags = cc.Node._dirtyFlags, locFlag = skinRenderCmd._dirtyFlag;
+ var colorDirty = locFlag & flags.colorDirty,
+ opacityDirty = locFlag & flags.opacityDirty;
+ if (colorDirty)
+ skinRenderCmd._updateDisplayColor(parentColor);
+ if (opacityDirty)
+ skinRenderCmd._updateDisplayOpacity(parentOpacity);
+ if (colorDirty || opacityDirty)
+ skinRenderCmd._updateColor();
+ };
+
+ proto.visit = function (parentCmd) {
+ var node = this._node;
+ // quick return if not visible. children won't be drawn.
+ if (!node._visible)
+ return;
+
+ parentCmd = parentCmd || this.getParentRenderCmd();
+ if (parentCmd)
+ this._curLevel = parentCmd._curLevel + 1;
+
+ this._syncStatus(parentCmd);
+
+ node.sortAllChildren();
+ var renderer = cc.renderer,
+ children = node._children, child,
+ i, len = children.length;
+
+ if (isNaN(node._customZ)) {
+ node._vertexZ = renderer.assignedZ;
+ renderer.assignedZ += renderer.assignedZStep;
+ }
+
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder < 0) {
+ if (isNaN(child._customZ)) {
+ child._vertexZ = renderer.assignedZ;
+ renderer.assignedZ += renderer.assignedZStep;
+ }
+ }
+ else {
+ break;
+ }
+ }
+
+ renderer.pushRenderCommand(this);
+ for (; i < len; i++) {
+ child = children[i];
+ if (isNaN(child._customZ)) {
+ child._vertexZ = renderer.assignedZ;
+ renderer.assignedZ += renderer.assignedZStep;
+ }
+ }
+
+ this._dirtyFlag = 0;
+ };
+})();
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/CCBone.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/CCBone.js
new file mode 100644
index 0000000..953e786
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/CCBone.js
@@ -0,0 +1,747 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The Bone of Armature, it has bone data, display manager and transform data for armature.
+ * @class
+ * @extends ccs.Node
+ *
+ * @param {String} [name] The name of the bone
+ * @example
+ *
+ * var bone = new ccs.Bone("head");
+ *
+ * @property {ccs.BoneData} boneData - The bone data
+ * @property {ccs.Armature} armature - The armature
+ * @property {ccs.Bone} parentBone - The parent bone
+ * @property {ccs.Armature} childArmature - The child armature
+ * @property {Array} childrenBone - <@readonly> All children bones
+ * @property {ccs.Tween} tween - <@readonly> Tween
+ * @property {ccs.FrameData} tweenData - <@readonly> The tween data
+ * @property {ccs.ColliderFilter} colliderFilter - The collider filter
+ * @property {ccs.DisplayManager} displayManager - The displayManager
+ * @property {Boolean} ignoreMovementBoneData - Indicate whether force the bone to show When CCArmature play a animation and there isn't a CCMovementBoneData of this bone in this CCMovementData.
+ * @property {String} name - The name of the bone
+ * @property {Boolean} blendDirty - Indicate whether the blend is dirty
+ *
+ */
+ccs.Bone = ccs.Node.extend(/** @lends ccs.Bone# */{
+ _boneData: null,
+ _armature: null,
+ _childArmature: null,
+ _displayManager: null,
+ ignoreMovementBoneData: false,
+ _tween: null,
+ _tweenData: null,
+ _parentBone: null,
+ _boneTransformDirty: false,
+ _worldTransform: null,
+ _blendFunc: null,
+ blendDirty: false,
+ _worldInfo: null,
+ _armatureParentBone: null,
+ _dataVersion: 0,
+ _className: "Bone",
+
+ ctor: function (name) {
+ cc.Node.prototype.ctor.call(this);
+ this._tweenData = null;
+ this._parentBone = null;
+ this._armature = null;
+ this._childArmature = null;
+ this._boneData = null;
+ this._tween = null;
+ this._displayManager = null;
+ this.ignoreMovementBoneData = false;
+
+ this._worldTransform = cc.affineTransformMake(1, 0, 0, 1, 0, 0);
+ this._boneTransformDirty = true;
+ this._blendFunc = new cc.BlendFunc(cc.BLEND_SRC, cc.BLEND_DST);
+ this.blendDirty = false;
+ this._worldInfo = null;
+
+ this._armatureParentBone = null;
+ this._dataVersion = 0;
+
+ ccs.Bone.prototype.init.call(this, name);
+ },
+
+ /**
+ * Initializes a ccs.Bone with the specified name
+ * @param {String} name bone name
+ * @return {Boolean}
+ */
+ init: function (name) {
+// cc.Node.prototype.init.call(this);
+ if (name)
+ this._name = name;
+ this._tweenData = new ccs.FrameData();
+
+ this._tween = new ccs.Tween(this);
+
+ this._displayManager = new ccs.DisplayManager(this);
+
+ this._worldInfo = new ccs.BaseData();
+ this._boneData = new ccs.BaseData();
+
+ return true;
+ },
+
+ /**
+ * Sets the boneData to ccs.Bone.
+ * @param {ccs.BoneData} boneData
+ */
+ setBoneData: function (boneData) {
+ cc.assert(boneData, "_boneData must not be null");
+
+ if (this._boneData !== boneData)
+ this._boneData = boneData;
+
+ this.setName(this._boneData.name);
+ this._localZOrder = this._boneData.zOrder;
+ this._displayManager.initDisplayList(boneData);
+ },
+
+ /**
+ * Returns boneData of ccs.Bone.
+ * @return {ccs.BoneData}
+ */
+ getBoneData: function () {
+ return this._boneData;
+ },
+
+ /**
+ * Sets the armature reference to ccs.Bone.
+ * @param {ccs.Armature} armature
+ */
+ setArmature: function (armature) {
+ this._armature = armature;
+ if (armature) {
+ this._tween.setAnimation(this._armature.getAnimation());
+ this._dataVersion = this._armature.getArmatureData().dataVersion;
+ this._armatureParentBone = this._armature.getParentBone();
+ } else
+ this._armatureParentBone = null;
+ },
+
+ /**
+ * Returns the armature reference of ccs.Bone.
+ * @return {ccs.Armature}
+ */
+ getArmature: function () {
+ return this._armature;
+ },
+
+ /**
+ * Updates worldTransform by tween data and updates display state
+ * @param {Number} delta
+ */
+ update: function (delta) {
+ if (this._parentBone)
+ this._boneTransformDirty = this._boneTransformDirty || this._parentBone.isTransformDirty();
+
+ if (this._armatureParentBone && !this._boneTransformDirty)
+ this._boneTransformDirty = this._armatureParentBone.isTransformDirty();
+
+ if (this._boneTransformDirty) {
+ var locTweenData = this._tweenData;
+ if (this._dataVersion >= ccs.CONST_VERSION_COMBINED) {
+ ccs.TransformHelp.nodeConcat(locTweenData, this._boneData);
+ locTweenData.scaleX -= 1;
+ locTweenData.scaleY -= 1;
+ }
+
+ var locWorldInfo = this._worldInfo;
+ locWorldInfo.copy(locTweenData);
+ locWorldInfo.x = locTweenData.x + this._position.x;
+ locWorldInfo.y = locTweenData.y + this._position.y;
+ locWorldInfo.scaleX = locTweenData.scaleX * this._scaleX;
+ locWorldInfo.scaleY = locTweenData.scaleY * this._scaleY;
+ locWorldInfo.skewX = locTweenData.skewX + this._skewX + cc.degreesToRadians(this._rotationX);
+ locWorldInfo.skewY = locTweenData.skewY + this._skewY - cc.degreesToRadians(this._rotationY);
+
+ if (this._parentBone)
+ this._applyParentTransform(this._parentBone);
+ else {
+ if (this._armatureParentBone)
+ this._applyParentTransform(this._armatureParentBone);
+ }
+
+ ccs.TransformHelp.nodeToMatrix(locWorldInfo, this._worldTransform);
+ if (this._armatureParentBone)
+ cc.affineTransformConcatIn(this._worldTransform, this._armature.getNodeToParentTransform()); //TODO TransformConcat
+ }
+
+ ccs.displayFactory.updateDisplay(this, delta, this._boneTransformDirty || this._armature.getArmatureTransformDirty());
+ for (var i = 0; i < this._children.length; i++) {
+ var childBone = this._children[i];
+ childBone.update(delta);
+ }
+ this._boneTransformDirty = false;
+ },
+
+ _applyParentTransform: function (parent) {
+ var locWorldInfo = this._worldInfo;
+ var locParentWorldTransform = parent._worldTransform;
+ var locParentWorldInfo = parent._worldInfo;
+ var x = locWorldInfo.x;
+ var y = locWorldInfo.y;
+ locWorldInfo.x = x * locParentWorldTransform.a + y * locParentWorldTransform.c + locParentWorldInfo.x;
+ locWorldInfo.y = x * locParentWorldTransform.b + y * locParentWorldTransform.d + locParentWorldInfo.y;
+ locWorldInfo.scaleX = locWorldInfo.scaleX * locParentWorldInfo.scaleX;
+ locWorldInfo.scaleY = locWorldInfo.scaleY * locParentWorldInfo.scaleY;
+ locWorldInfo.skewX = locWorldInfo.skewX + locParentWorldInfo.skewX;
+ locWorldInfo.skewY = locWorldInfo.skewY + locParentWorldInfo.skewY;
+ },
+
+ /**
+ * Sets BlendFunc to ccs.Bone.
+ * @param {cc.BlendFunc|Number} blendFunc blendFunc or src of blendFunc
+ * @param {Number} [dst] dst of blendFunc
+ */
+ setBlendFunc: function (blendFunc, dst) {
+ var locBlendFunc = this._blendFunc, srcValue, dstValue;
+ if (dst === undefined) {
+ srcValue = blendFunc.src;
+ dstValue = blendFunc.dst;
+ } else {
+ srcValue = blendFunc;
+ dstValue = dst;
+ }
+ if (locBlendFunc.src !== srcValue || locBlendFunc.dst !== dstValue) {
+ locBlendFunc.src = srcValue;
+ locBlendFunc.dst = dstValue;
+ this.blendDirty = true;
+ }
+ },
+
+ /**
+ * Updates display color
+ */
+ updateColor: function () {
+ var display = this._displayManager.getDisplayRenderNode();
+ if (display !== null) {
+ var cmd = this._renderCmd;
+ display.setColor(
+ cc.color(
+ cmd._displayedColor.r * this._tweenData.r / 255,
+ cmd._displayedColor.g * this._tweenData.g / 255,
+ cmd._displayedColor.b * this._tweenData.b / 255));
+ display.setOpacity(cmd._displayedOpacity * this._tweenData.a / 255);
+ }
+ },
+
+ /**
+ * Updates display zOrder
+ */
+ updateZOrder: function () {
+ if (this._armature.getArmatureData().dataVersion >= ccs.CONST_VERSION_COMBINED) {
+ this.setLocalZOrder(this._tweenData.zOrder + this._boneData.zOrder);
+ } else {
+ this.setLocalZOrder(this._tweenData.zOrder);
+ }
+ },
+
+ /**
+ * Adds a child to this bone, and it will let this child call setParent(ccs.Bone) function to set self to it's parent
+ * @param {ccs.Bone} child
+ */
+ addChildBone: function (child) {
+ cc.assert(child, "Argument must be non-nil");
+ cc.assert(!child.parentBone, "child already added. It can't be added again");
+
+ if (this._children.indexOf(child) < 0) {
+ this._children.push(child);
+ child.setParentBone(this);
+ }
+ },
+
+ /**
+ * Removes a child bone
+ * @param {ccs.Bone} bone
+ * @param {Boolean} recursion
+ */
+ removeChildBone: function (bone, recursion) {
+ if (this._children.length > 0 && this._children.getIndex(bone) !== -1) {
+ if (recursion) {
+ var ccbones = bone._children;
+ for (var i = 0; i < ccbones.length; i++) {
+ var ccBone = ccbones[i];
+ bone.removeChildBone(ccBone, recursion);
+ }
+ }
+
+ bone.setParentBone(null);
+ bone.getDisplayManager().setCurrentDecorativeDisplay(null);
+ cc.arrayRemoveObject(this._children, bone);
+ }
+ },
+
+ /**
+ * Removes itself from its parent ccs.Bone.
+ * @param {Boolean} recursion
+ */
+ removeFromParent: function (recursion) {
+ if (this._parentBone)
+ this._parentBone.removeChildBone(this, recursion);
+ },
+
+ /**
+ * Sets parent bone to ccs.Bone.
+ * If _parent is NUll, then also remove this bone from armature.
+ * It will not set the ccs.Armature, if you want to add the bone to a ccs.Armature, you should use ccs.Armature.addBone(bone, parentName).
+ * @param {ccs.Bone} parent the parent bone.
+ */
+ setParentBone: function (parent) {
+ this._parentBone = parent;
+ },
+
+ /**
+ * Returns the parent bone of ccs.Bone.
+ * @returns {ccs.Bone}
+ */
+ getParentBone: function () {
+ return this._parentBone;
+ },
+
+ /**
+ * Sets ccs.Bone's child armature
+ * @param {ccs.Armature} armature
+ */
+ setChildArmature: function (armature) {
+ if (this._childArmature !== armature) {
+ if (armature == null && this._childArmature)
+ this._childArmature.setParentBone(null);
+ this._childArmature = armature;
+ }
+ },
+
+ /**
+ * Returns ccs.Bone's child armature.
+ * @return {ccs.Armature}
+ */
+ getChildArmature: function () {
+ return this._childArmature;
+ },
+
+ /**
+ * Return the tween of ccs.Bone
+ * @return {ccs.Tween}
+ */
+ getTween: function () {
+ return this._tween;
+ },
+
+ /**
+ * Sets the local zOrder to ccs.Bone.
+ * @param {Number} zOrder
+ */
+ setLocalZOrder: function (zOrder) {
+ if (this._localZOrder !== zOrder)
+ cc.Node.prototype.setLocalZOrder.call(this, zOrder);
+ },
+
+ /**
+ * Return the worldTransform of ccs.Bone.
+ * @returns {cc.AffineTransform}
+ */
+ getNodeToArmatureTransform: function () {
+ return this._worldTransform;
+ },
+
+ /**
+ * Returns the world transform of ccs.Bone.
+ * @override
+ * @returns {cc.AffineTransform}
+ */
+ getNodeToWorldTransform: function () {
+ return cc.affineTransformConcat(this._worldTransform, this._armature.getNodeToWorldTransform());
+ },
+
+ /**
+ * Returns the display render node.
+ * @returns {cc.Node}
+ */
+ getDisplayRenderNode: function () {
+ return this._displayManager.getDisplayRenderNode();
+ },
+
+ /**
+ * Returns the type of display render node
+ * @returns {Number}
+ */
+ getDisplayRenderNodeType: function () {
+ return this._displayManager.getDisplayRenderNodeType();
+ },
+
+ /**
+ * Add display and use _displayData init the display.
+ * If index already have a display, then replace it.
+ * If index is current display index, then also change display to _index
+ * @param {ccs.DisplayData} displayData it include the display information, like DisplayType.
+ * If you want to create a sprite display, then create a CCSpriteDisplayData param
+ *@param {Number} index the index of the display you want to replace or add to
+ * -1 : append display from back
+ */
+ addDisplay: function (displayData, index) {
+ index = index || 0;
+ return this._displayManager.addDisplay(displayData, index);
+ },
+
+ /**
+ * Removes display by index.
+ * @param {Number} index display renderer's index
+ */
+ removeDisplay: function (index) {
+ this._displayManager.removeDisplay(index);
+ },
+
+ /**
+ * Changes display by index
+ * @deprecated since v3.0, please use changeDisplayWithIndex instead.
+ * @param {Number} index
+ * @param {Boolean} force
+ */
+ changeDisplayByIndex: function (index, force) {
+ cc.log("changeDisplayByIndex is deprecated. Use changeDisplayWithIndex instead.");
+ this.changeDisplayWithIndex(index, force);
+ },
+
+ /**
+ * Changes display by name
+ * @deprecated since v3.0, please use changeDisplayWithName instead.
+ * @param {String} name
+ * @param {Boolean} force
+ */
+ changeDisplayByName: function (name, force) {
+ cc.log("changeDisplayByName is deprecated. Use changeDisplayWithName instead.");
+ this.changeDisplayWithName(name, force);
+ },
+
+ /**
+ * Changes display with index
+ * @param {Number} index
+ * @param {Boolean} force
+ */
+ changeDisplayWithIndex: function (index, force) {
+ this._displayManager.changeDisplayWithIndex(index, force);
+ },
+
+ /**
+ * Changes display with name
+ * @param {String} name
+ * @param {Boolean} force
+ */
+ changeDisplayWithName: function (name, force) {
+ this._displayManager.changeDisplayWithName(name, force);
+ },
+
+ /**
+ * Returns the collide detector of ccs.Bone.
+ * @returns {*}
+ */
+ getColliderDetector: function () {
+ var decoDisplay = this._displayManager.getCurrentDecorativeDisplay();
+ if (decoDisplay) {
+ var detector = decoDisplay.getColliderDetector();
+ if (detector)
+ return detector;
+ }
+ return null;
+ },
+
+ /**
+ * Sets collider filter to ccs.Bone.
+ * @param {ccs.ColliderFilter} filter
+ */
+ setColliderFilter: function (filter) {
+ var displayList = this._displayManager.getDecorativeDisplayList();
+ for (var i = 0; i < displayList.length; i++) {
+ var locDecoDisplay = displayList[i];
+ var locDetector = locDecoDisplay.getColliderDetector();
+ if (locDetector)
+ locDetector.setColliderFilter(filter);
+ }
+ },
+
+ /**
+ * Returns collider filter of ccs.Bone.
+ * @returns {cc.ColliderFilter}
+ */
+ getColliderFilter: function () {
+ var decoDisplay = this.displayManager.getCurrentDecorativeDisplay();
+ if (decoDisplay) {
+ var detector = decoDisplay.getColliderDetector();
+ if (detector)
+ return detector.getColliderFilter();
+ }
+ return null;
+ },
+
+ /**
+ * Sets ccs.Bone's transform dirty flag.
+ * @param {Boolean} dirty
+ */
+ setTransformDirty: function (dirty) {
+ this._boneTransformDirty = dirty;
+ },
+
+ /**
+ * Returns ccs.Bone's transform dirty flag whether is dirty.
+ * @return {Boolean}
+ */
+ isTransformDirty: function () {
+ return this._boneTransformDirty;
+ },
+
+ /**
+ * displayManager dirty getter
+ * @return {ccs.DisplayManager}
+ */
+ getDisplayManager: function () {
+ return this._displayManager;
+ },
+
+ /**
+ * When CCArmature play a animation, if there is not a CCMovementBoneData of this bone in this CCMovementData, this bone will hide.
+ * Set IgnoreMovementBoneData to true, then this bone will also show.
+ * @param {Boolean} bool
+ */
+ setIgnoreMovementBoneData: function (bool) {
+ this._ignoreMovementBoneData = bool;
+ },
+
+ /**
+ * Returns whether is ignore movement bone data.
+ * @returns {Boolean}
+ */
+ isIgnoreMovementBoneData: function () {
+ return this._ignoreMovementBoneData;
+ },
+
+ /**
+ * Returns the blendFunc of ccs.Bone.
+ * @return {cc.BlendFunc}
+ */
+ getBlendFunc: function () {
+ return new cc.BlendFunc(this._blendFunc.src, this._blendFunc.dst);
+ },
+
+ /**
+ * Sets blend dirty flag
+ * @param {Boolean} dirty
+ */
+ setBlendDirty: function (dirty) {
+ this._blendDirty = dirty;
+ },
+
+ /**
+ * Returns the blend dirty flag whether is dirty.
+ * @returns {Boolean|*|ccs.Bone._blendDirty}
+ */
+ isBlendDirty: function () {
+ return this._blendDirty;
+ },
+
+ /**
+ * Returns the tweenData of ccs.Bone.
+ * @return {ccs.FrameData}
+ */
+ getTweenData: function () {
+ return this._tweenData;
+ },
+
+ /**
+ * Returns the world information of ccs.Bone.
+ * @returns {ccs.BaseData}
+ */
+ getWorldInfo: function () {
+ return this._worldInfo;
+ },
+
+ /**
+ * Returns the children of ccs.Bone
+ * @return {Array}
+ * @deprecated since v3.0, please use getChildren instead.
+ */
+ getChildrenBone: function () {
+ return this._children;
+ },
+
+ /**
+ * Returns the worldTransform of ccs.Bone.
+ * @return {cc.AffineTransform}
+ * @deprecated since v3.0, please use getNodeToArmatureTransform instead.
+ */
+ nodeToArmatureTransform: function () {
+ return this.getNodeToArmatureTransform();
+ },
+
+ /**
+ * @deprecated
+ * Returns the world affine transform matrix. The matrix is in Pixels.
+ * @returns {cc.AffineTransform}
+ */
+ nodeToWorldTransform: function () {
+ return this.getNodeToWorldTransform();
+ },
+
+ /**
+ * Returns the collider body list in this bone.
+ * @returns {Array|null}
+ * @deprecated since v3.0, please use getColliderDetector to get a delector, and calls its getColliderBodyList instead.
+ */
+ getColliderBodyList: function () {
+ var detector = this.getColliderDetector();
+ if (detector)
+ return detector.getColliderBodyList();
+ return null;
+ },
+
+ /**
+ * Returns whether is ignore movement bone data.
+ * @return {Boolean}
+ * @deprecated since v3.0, please isIgnoreMovementBoneData instead.
+ */
+ getIgnoreMovementBoneData: function () {
+ return this.isIgnoreMovementBoneData();
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new ccs.Bone.CanvasRenderCmd(this);
+ else
+ return new ccs.Bone.WebGLRenderCmd(this);
+ }
+});
+
+var _p = ccs.Bone.prototype;
+
+// Extended properties
+/** @expose */
+_p.boneData;
+cc.defineGetterSetter(_p, "boneData", _p.getBoneData, _p.setBoneData);
+/** @expose */
+_p.armature;
+cc.defineGetterSetter(_p, "armature", _p.getArmature, _p.setArmature);
+/** @expose */
+_p.childArmature;
+cc.defineGetterSetter(_p, "childArmature", _p.getChildArmature, _p.setChildArmature);
+/** @expose */
+_p.childrenBone;
+cc.defineGetterSetter(_p, "childrenBone", _p.getChildrenBone);
+/** @expose */
+_p.tween;
+cc.defineGetterSetter(_p, "tween", _p.getTween);
+/** @expose */
+_p.tweenData;
+cc.defineGetterSetter(_p, "tweenData", _p.getTweenData);
+/** @expose */
+_p.colliderFilter;
+cc.defineGetterSetter(_p, "colliderFilter", _p.getColliderFilter, _p.setColliderFilter);
+
+_p = null;
+
+/**
+ * Allocates and initializes a bone.
+ * @return {ccs.Bone}
+ * @deprecated since v3.1, please use new construction instead
+ */
+ccs.Bone.create = function (name) {
+ return new ccs.Bone(name);
+};
+
+ccs.Bone.RenderCmd = {
+ _updateColor: function () {
+ var node = this._node;
+ var display = node._displayManager.getDisplayRenderNode();
+ if (display !== null) {
+ var displayCmd = display._renderCmd;
+ display.setColor(this._displayedColor);
+ display.setOpacity(this._displayedOpacity);
+ displayCmd._syncDisplayColor(node._tweenData);
+ displayCmd._syncDisplayOpacity(node._tweenData.a);
+ displayCmd._updateColor();
+ }
+ },
+
+ transform: function (parentCmd, recursive) {
+ if (!this._transform) {
+ this._transform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ this._worldTransform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ }
+
+ var node = this._node,
+ t = this._transform,
+ wt = this._worldTransform,
+ pt = parentCmd ? parentCmd._worldTransform : null;
+
+ if (pt) {
+ this.originTransform();
+ cc.affineTransformConcatIn(t, node._worldTransform);
+ }
+
+ if (pt) {
+ wt.a = t.a * pt.a + t.b * pt.c;
+ wt.b = t.a * pt.b + t.b * pt.d;
+ wt.c = t.c * pt.a + t.d * pt.c;
+ wt.d = t.c * pt.b + t.d * pt.d;
+ wt.tx = t.tx * pt.a + t.ty * pt.c + pt.tx;
+ wt.ty = t.tx * pt.b + t.ty * pt.d + pt.ty;
+ }
+ else {
+ wt.a = t.a;
+ wt.b = t.b;
+ wt.c = t.c;
+ wt.d = t.d;
+ wt.tx = t.tx;
+ wt.ty = t.ty;
+ }
+ }
+};
+
+(function () {
+ ccs.Bone.CanvasRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._needDraw = false;
+ };
+
+ var proto = ccs.Bone.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+ cc.inject(ccs.Bone.RenderCmd, proto);
+ proto.constructor = ccs.Bone.CanvasRenderCmd;
+})();
+
+(function () {
+ if (!cc.Node.WebGLRenderCmd)
+ return;
+ ccs.Bone.WebGLRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
+ this._needDraw = false;
+ };
+
+ var proto = ccs.Bone.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ cc.inject(ccs.Bone.RenderCmd, proto);
+ proto.constructor = ccs.Bone.WebGLRenderCmd;
+})();
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/animation/CCArmatureAnimation.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/animation/CCArmatureAnimation.js
new file mode 100644
index 0000000..09ab2fe
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/animation/CCArmatureAnimation.js
@@ -0,0 +1,672 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * movement event type enum
+ * @constant
+ * @type {Object}
+ */
+ccs.MovementEventType = {
+ start: 0,
+ complete: 1,
+ loopComplete: 2
+};
+
+/**
+ * The animation event class, it has the callback, target and arguments.
+ * @deprecated since v3.0.
+ * @class
+ * @extends ccs.Class
+ */
+ccs.AnimationEvent = ccs.Class.extend(/** @lends ccs.AnimationEvent# */{
+ _arguments: null,
+ _callFunc: null,
+ _selectorTarget: null,
+
+ /**
+ * Constructor of ccs.AnimationEvent
+ * @param {function} callFunc
+ * @param {object} target
+ * @param {object} [data]
+ */
+ ctor: function (callFunc,target, data) {
+ this._data = data;
+ this._callFunc = callFunc;
+ this._selectorTarget = target;
+ },
+ call: function () {
+ if (this._callFunc)
+ this._callFunc.apply(this._selectorTarget, this._arguments);
+ },
+ setArguments: function (args) {
+ this._arguments = args;
+ }
+});
+
+/**
+ * The movement event class for Armature.
+ * @constructor
+ *
+ * @property {ccs.Armature} armature - The armature reference of movement event.
+ * @property {Number} movementType - The type of movement.
+ * @property {String} movementID - The ID of movement.
+ */
+ccs.MovementEvent = function () {
+ this.armature = null;
+ this.movementType = ccs.MovementEventType.start;
+ this.movementID = "";
+};
+
+/**
+ * The frame event class for Armature.
+ * @constructor
+ *
+ * @property {ccs.Bone} bone - The bone reference of frame event.
+ * @property {String} frameEventName - The name of frame event.
+ * @property {Number} originFrameIndex - The index of origin frame.
+ * @property {Number} currentFrameIndex - The index of current frame.
+ */
+ccs.FrameEvent = function () {
+ this.bone = null;
+ this.frameEventName = "";
+ this.originFrameIndex = 0;
+ this.currentFrameIndex = 0;
+};
+
+/**
+ * The Animation class for Armature, it plays armature animation, and controls speed scale and manages animation frame.
+ * @class
+ * @extends ccs.ProcessBase
+ *
+ * @param {ccs.Armature} [armature] The armature
+ *
+ * @property {ccs.AnimationData} animationData - Animation data
+ * @property {Object} userObject - User custom object
+ * @property {Boolean} ignoreFrameEvent - Indicate whether the frame event is ignored
+ * @property {Number} speedScale - Animation play speed scale
+ * @property {Number} animationScale - Animation play speed scale
+ */
+ccs.ArmatureAnimation = ccs.ProcessBase.extend(/** @lends ccs.ArmatureAnimation# */{
+ _animationData: null,
+ _movementData: null,
+ _armature: null,
+ _movementID: "",
+ _toIndex: 0,
+ _tweenList: null,
+ _speedScale: 1,
+ _ignoreFrameEvent: false,
+ _frameEventQueue: null,
+ _movementEventQueue: null,
+ _movementList: null,
+ _onMovementList: false,
+ _movementListLoop: false,
+ _movementIndex: 0,
+ _movementListDurationTo: -1,
+
+ _movementEventCallFunc: null,
+ _frameEventCallFunc: null,
+ _movementEventTarget: null,
+ _frameEventTarget:null,
+ _movementEventListener: null,
+ _frameEventListener: null,
+
+ ctor: function (armature) {
+ ccs.ProcessBase.prototype.ctor.call(this);
+
+ this._tweenList = [];
+ this._movementList = [];
+ this._frameEventQueue = [];
+ this._movementEventQueue = [];
+ this._armature = null;
+
+ armature && ccs.ArmatureAnimation.prototype.init.call(this, armature);
+ },
+
+ /**
+ * Initializes with an armature object
+ * @param {ccs.Armature} armature
+ * @return {Boolean}
+ */
+ init: function (armature) {
+ this._armature = armature;
+ this._tweenList.length = 0;
+ return true;
+ },
+
+ /**
+ * Pauses armature animation.
+ */
+ pause: function () {
+ var locTweenList = this._tweenList;
+ for (var i = 0; i < locTweenList.length; i++)
+ locTweenList[i].pause();
+ ccs.ProcessBase.prototype.pause.call(this);
+ },
+
+ /**
+ * Resumes armature animation.
+ */
+ resume: function () {
+ var locTweenList = this._tweenList;
+ for (var i = 0; i < locTweenList.length; i++)
+ locTweenList[i].resume();
+ ccs.ProcessBase.prototype.resume.call(this);
+ },
+
+ /**
+ * Stops armature animation.
+ */
+ stop: function () {
+ var locTweenList = this._tweenList;
+ for (var i = 0; i < locTweenList.length; i++)
+ locTweenList[i].stop();
+ locTweenList.length = 0;
+ ccs.ProcessBase.prototype.stop.call(this);
+ },
+
+ /**
+ * Sets animation play speed scale.
+ * @deprecated since v3.0, please use setSpeedScale instead.
+ * @param {Number} animationScale
+ */
+ setAnimationScale: function (animationScale) {
+ this.setSpeedScale(animationScale);
+ },
+
+ /**
+ * Returns animation play speed scale.
+ * @deprecated since v3.0, please use getSpeedScale instead.
+ * @returns {Number}
+ */
+ getAnimationScale: function () {
+ return this.getSpeedScale();
+ },
+
+ /**
+ * Sets animation play speed scale.
+ * @param {Number} speedScale
+ */
+ setSpeedScale: function (speedScale) {
+ if (speedScale === this._speedScale)
+ return;
+ this._speedScale = speedScale;
+ this._processScale = !this._movementData ? this._speedScale : this._speedScale * this._movementData.scale;
+ var dict = this._armature.getBoneDic();
+ for (var key in dict) {
+ var bone = dict[key];
+ bone.getTween().setProcessScale(this._processScale);
+ if (bone.getChildArmature())
+ bone.getChildArmature().getAnimation().setSpeedScale(this._processScale);
+ }
+ },
+
+ /**
+ * Returns animation play speed scale.
+ * @returns {Number}
+ */
+ getSpeedScale: function () {
+ return this._speedScale;
+ },
+
+ /**
+ * play animation by animation name.
+ * @param {String} animationName The animation name you want to play
+ * @param {Number} [durationTo=-1]
+ * the frames between two animation changing-over.It's meaning is changing to this animation need how many frames
+ * -1 : use the value from CCMovementData get from flash design panel
+ * @param {Number} [loop=-1]
+ * Whether the animation is loop.
+ * loop < 0 : use the value from CCMovementData get from flash design panel
+ * loop = 0 : this animation is not loop
+ * loop > 0 : this animation is loop
+ * @example
+ * // example
+ * armature.getAnimation().play("run",-1,1);//loop play
+ * armature.getAnimation().play("run",-1,0);//not loop play
+ */
+ play: function (animationName, durationTo, loop) {
+ cc.assert(this._animationData, "this.animationData can not be null");
+
+ this._movementData = this._animationData.getMovement(animationName);
+ cc.assert(this._movementData, "this._movementData can not be null");
+
+ durationTo = (durationTo === undefined) ? -1 : durationTo;
+ loop = (loop === undefined) ? -1 : loop;
+
+ //! Get key frame count
+ this._rawDuration = this._movementData.duration;
+ this._movementID = animationName;
+ this._processScale = this._speedScale * this._movementData.scale;
+
+ //! Further processing parameters
+ durationTo = (durationTo === -1) ? this._movementData.durationTo : durationTo;
+ var durationTween = this._movementData.durationTween === 0 ? this._rawDuration : this._movementData.durationTween;
+
+ var tweenEasing = this._movementData.tweenEasing;
+ //loop = (!loop || loop < 0) ? this._movementData.loop : loop;
+ loop = (loop < 0) ? this._movementData.loop : loop;
+ this._onMovementList = false;
+
+ ccs.ProcessBase.prototype.play.call(this, durationTo, durationTween, loop, tweenEasing);
+
+ if (this._rawDuration === 0)
+ this._loopType = ccs.ANIMATION_TYPE_SINGLE_FRAME;
+ else {
+ this._loopType = loop ? ccs.ANIMATION_TYPE_TO_LOOP_FRONT : ccs.ANIMATION_TYPE_NO_LOOP;
+ this._durationTween = durationTween;
+ }
+
+ this._tweenList.length = 0;
+
+ var movementBoneData, map = this._armature.getBoneDic();
+ for(var element in map) {
+ var bone = map[element];
+ movementBoneData = this._movementData.movBoneDataDic[bone.getName()];
+
+ var tween = bone.getTween();
+ if(movementBoneData && movementBoneData.frameList.length > 0) {
+ this._tweenList.push(tween);
+ movementBoneData.duration = this._movementData.duration;
+ tween.play(movementBoneData, durationTo, durationTween, loop, tweenEasing);
+ tween.setProcessScale(this._processScale);
+
+ if (bone.getChildArmature()) {
+ bone.getChildArmature().getAnimation().setSpeedScale(this._processScale);
+ if (!bone.getChildArmature().getAnimation().isPlaying())
+ bone.getChildArmature().getAnimation().playWithIndex(0);
+ }
+ } else {
+ if(!bone.isIgnoreMovementBoneData()){
+ //! this bone is not include in this movement, so hide it
+ bone.getDisplayManager().changeDisplayWithIndex(-1, false);
+ tween.stop();
+ }
+ }
+ }
+ this._armature.update(0);
+ },
+
+ /**
+ * Plays animation with index, the other param is the same to play.
+ * @param {Number} animationIndex
+ * @param {Number} durationTo
+ * @param {Number} durationTween
+ * @param {Number} loop
+ * @param {Number} [tweenEasing]
+ * @deprecated since v3.0, please use playWithIndex instead.
+ */
+ playByIndex: function (animationIndex, durationTo, durationTween, loop, tweenEasing) {
+ cc.log("playByIndex is deprecated. Use playWithIndex instead.");
+ this.playWithIndex(animationIndex, durationTo, loop);
+ },
+
+ /**
+ * Plays animation with index, the other param is the same to play.
+ * @param {Number|Array} animationIndex
+ * @param {Number} durationTo
+ * @param {Number} loop
+ */
+ playWithIndex: function (animationIndex, durationTo, loop) {
+ var movName = this._animationData.movementNames;
+ cc.assert((animationIndex > -1) && (animationIndex < movName.length));
+
+ var animationName = movName[animationIndex];
+ this.play(animationName, durationTo, loop);
+ },
+
+ /**
+ * Plays animation with names
+ * @param {Array} movementNames
+ * @param {Number} durationTo
+ * @param {Boolean} loop
+ */
+ playWithNames: function (movementNames, durationTo, loop) {
+ durationTo = (durationTo === undefined) ? -1 : durationTo;
+ loop = (loop === undefined) ? true : loop;
+
+ this._movementListLoop = loop;
+ this._movementListDurationTo = durationTo;
+ this._onMovementList = true;
+ this._movementIndex = 0;
+ if(movementNames instanceof Array)
+ this._movementList = movementNames;
+ else
+ this._movementList.length = 0;
+ this.updateMovementList();
+ },
+
+ /**
+ * Plays animation by indexes
+ * @param {Array} movementIndexes
+ * @param {Number} durationTo
+ * @param {Boolean} loop
+ */
+ playWithIndexes: function (movementIndexes, durationTo, loop) {
+ durationTo = (durationTo === undefined) ? -1 : durationTo;
+ loop = (loop === undefined) ? true : loop;
+
+ this._movementList.length = 0;
+ this._movementListLoop = loop;
+ this._movementListDurationTo = durationTo;
+ this._onMovementList = true;
+ this._movementIndex = 0;
+
+ var movName = this._animationData.movementNames;
+
+ for (var i = 0; i < movementIndexes.length; i++) {
+ var name = movName[movementIndexes[i]];
+ this._movementList.push(name);
+ }
+
+ this.updateMovementList();
+ },
+
+ /**
+ *
+ * Goes to specified frame and plays current movement.
+ * You need first switch to the movement you want to play, then call this function.
+ *
+ * example : playByIndex(0);
+ * gotoAndPlay(0);
+ * playByIndex(1);
+ * gotoAndPlay(0);
+ * gotoAndPlay(15);
+ *
+ * @param {Number} frameIndex
+ */
+ gotoAndPlay: function (frameIndex) {
+ if (!this._movementData || frameIndex < 0 || frameIndex >= this._movementData.duration) {
+ cc.log("Please ensure you have played a movement, and the frameIndex is in the range.");
+ return;
+ }
+
+ var ignoreFrameEvent = this._ignoreFrameEvent;
+ this._ignoreFrameEvent = true;
+ this._isPlaying = true;
+ this._isComplete = this._isPause = false;
+
+ ccs.ProcessBase.prototype.gotoFrame.call(this, frameIndex);
+ this._currentPercent = this._curFrameIndex / (this._movementData.duration - 1);
+ this._currentFrame = this._nextFrameIndex * this._currentPercent;
+
+ var locTweenList = this._tweenList;
+ for (var i = 0; i < locTweenList.length; i++)
+ locTweenList[i].gotoAndPlay(frameIndex);
+ this._armature.update(0);
+ this._ignoreFrameEvent = ignoreFrameEvent;
+ },
+
+ /**
+ * Goes to specified frame and pauses current movement.
+ * @param {Number} frameIndex
+ */
+ gotoAndPause: function (frameIndex) {
+ this.gotoAndPlay(frameIndex);
+ this.pause();
+ },
+
+ /**
+ * Returns the length of armature's movements
+ * @return {Number}
+ */
+ getMovementCount: function () {
+ return this._animationData.getMovementCount();
+ },
+
+ /**
+ * Updates the state of ccs.Tween list, calls frame event's callback and calls movement event's callback.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ ccs.ProcessBase.prototype.update.call(this, dt);
+
+ var locTweenList = this._tweenList;
+ for (var i = 0; i < locTweenList.length; i++)
+ locTweenList[i].update(dt);
+
+ var frameEvents = this._frameEventQueue, event;
+ while (frameEvents.length > 0) {
+ event = frameEvents.shift();
+ this._ignoreFrameEvent = true;
+ if(this._frameEventCallFunc)
+ this._frameEventCallFunc.call(this._frameEventTarget, event.bone, event.frameEventName, event.originFrameIndex, event.currentFrameIndex);
+ if(this._frameEventListener)
+ this._frameEventListener(event.bone, event.frameEventName, event.originFrameIndex, event.currentFrameIndex);
+ this._ignoreFrameEvent = false;
+ }
+
+ var movementEvents = this._movementEventQueue;
+ while (movementEvents.length > 0) {
+ event = movementEvents.shift();
+ if(this._movementEventCallFunc)
+ this._movementEventCallFunc.call(this._movementEventTarget, event.armature, event.movementType, event.movementID);
+ if (this._movementEventListener)
+ this._movementEventListener(event.armature, event.movementType, event.movementID);
+ }
+ },
+
+ /**
+ * Updates will call this handler, you can handle your logic here
+ */
+ updateHandler: function () { //TODO set it to protected in v3.1
+ var locCurrentPercent = this._currentPercent;
+ if (locCurrentPercent >= 1) {
+ switch (this._loopType) {
+ case ccs.ANIMATION_TYPE_NO_LOOP:
+ this._loopType = ccs.ANIMATION_TYPE_MAX;
+ this._currentFrame = (locCurrentPercent - 1) * this._nextFrameIndex;
+ locCurrentPercent = this._currentFrame / this._durationTween;
+ if (locCurrentPercent < 1.0) {
+ this._nextFrameIndex = this._durationTween;
+ this.movementEvent(this._armature, ccs.MovementEventType.start, this._movementID);
+ break;
+ }
+ break;
+ case ccs.ANIMATION_TYPE_MAX:
+ case ccs.ANIMATION_TYPE_SINGLE_FRAME:
+ locCurrentPercent = 1;
+ this._isComplete = true;
+ this._isPlaying = false;
+
+ this.movementEvent(this._armature, ccs.MovementEventType.complete, this._movementID);
+
+ this.updateMovementList();
+ break;
+ case ccs.ANIMATION_TYPE_TO_LOOP_FRONT:
+ this._loopType = ccs.ANIMATION_TYPE_LOOP_FRONT;
+ locCurrentPercent = ccs.fmodf(locCurrentPercent, 1);
+ this._currentFrame = this._nextFrameIndex === 0 ? 0 : ccs.fmodf(this._currentFrame, this._nextFrameIndex);
+ this._nextFrameIndex = this._durationTween > 0 ? this._durationTween : 1;
+ this.movementEvent(this, ccs.MovementEventType.start, this._movementID);
+ break;
+ default:
+ //locCurrentPercent = ccs.fmodf(locCurrentPercent, 1);
+ this._currentFrame = ccs.fmodf(this._currentFrame, this._nextFrameIndex);
+ this._toIndex = 0;
+ this.movementEvent(this._armature, ccs.MovementEventType.loopComplete, this._movementID);
+ break;
+ }
+ this._currentPercent = locCurrentPercent;
+ }
+ },
+
+ /**
+ * Returns the Id of current movement
+ * @returns {String}
+ */
+ getCurrentMovementID: function () {
+ if (this._isComplete)
+ return "";
+ return this._movementID;
+ },
+
+ /**
+ * Sets movement event callback to animation.
+ * @param {function} callFunc
+ * @param {Object} target
+ */
+ setMovementEventCallFunc: function (callFunc, target) {
+ if(arguments.length === 1){
+ this._movementEventListener = callFunc;
+ }else if(arguments.length === 2){
+ this._movementEventTarget = target;
+ this._movementEventCallFunc = callFunc;
+ }
+ },
+
+ /**
+ * Sets frame event callback to animation.
+ * @param {function} callFunc
+ * @param {Object} target
+ */
+ setFrameEventCallFunc: function (callFunc, target) {
+ if(arguments.length === 1){
+ this._frameEventListener = callFunc;
+ }else if(arguments.length === 2){
+ this._frameEventTarget = target;
+ this._frameEventCallFunc = callFunc;
+ }
+ },
+
+ /**
+ * Sets user object to animation.
+ * @param {Object} userObject
+ */
+ setUserObject: function (userObject) {
+ this._userObject = userObject;
+ },
+
+ /**
+ * Emits a frame event
+ * @param {ccs.Bone} bone
+ * @param {String} frameEventName
+ * @param {Number} originFrameIndex
+ * @param {Number} currentFrameIndex
+ */
+ frameEvent: function (bone, frameEventName, originFrameIndex, currentFrameIndex) {
+ if ((this._frameEventTarget && this._frameEventCallFunc) || this._frameEventListener) {
+ var frameEvent = new ccs.FrameEvent();
+ frameEvent.bone = bone;
+ frameEvent.frameEventName = frameEventName;
+ frameEvent.originFrameIndex = originFrameIndex;
+ frameEvent.currentFrameIndex = currentFrameIndex;
+ this._frameEventQueue.push(frameEvent);
+ }
+ },
+
+ /**
+ * Emits a movement event
+ * @param {ccs.Armature} armature
+ * @param {Number} movementType
+ * @param {String} movementID
+ */
+ movementEvent: function (armature, movementType, movementID) {
+ if ((this._movementEventTarget && this._movementEventCallFunc) || this._movementEventListener) {
+ var event = new ccs.MovementEvent();
+ event.armature = armature;
+ event.movementType = movementType;
+ event.movementID = movementID;
+ this._movementEventQueue.push(event);
+ }
+ },
+
+ /**
+ * Updates movement list.
+ */
+ updateMovementList: function () {
+ if (this._onMovementList) {
+ var movementObj, locMovementList = this._movementList;
+ if (this._movementListLoop) {
+ movementObj = locMovementList[this._movementIndex];
+ this.play(movementObj, movementObj.durationTo, 0);
+ this._movementIndex++;
+ if (this._movementIndex >= locMovementList.length)
+ this._movementIndex = 0;
+ } else {
+ if (this._movementIndex < locMovementList.length) {
+ movementObj = locMovementList[this._movementIndex];
+ this.play(movementObj, movementObj.durationTo, 0);
+ this._movementIndex++;
+ } else
+ this._onMovementList = false;
+ }
+ this._onMovementList = true;
+ }
+ },
+
+ /**
+ * Sets animation data to animation.
+ * @param {ccs.AnimationData} data
+ */
+ setAnimationData: function (data) {
+ if(this._animationData !== data)
+ this._animationData = data;
+ },
+
+ /**
+ * Returns animation data of animation.
+ * @return {ccs.AnimationData}
+ */
+ getAnimationData: function () {
+ return this._animationData;
+ },
+
+ /**
+ * Returns the user object of animation.
+ * @return {Object}
+ */
+ getUserObject: function () {
+ return this._userObject;
+ },
+
+ /**
+ * Determines if the frame event is ignored
+ * @returns {boolean}
+ */
+ isIgnoreFrameEvent: function () {
+ return this._ignoreFrameEvent;
+ }
+});
+
+var _p = ccs.ArmatureAnimation.prototype;
+
+// Extended properties
+/** @expose */
+_p.speedScale;
+cc.defineGetterSetter(_p, "speedScale", _p.getSpeedScale, _p.setSpeedScale);
+/** @expose */
+_p.animationScale;
+cc.defineGetterSetter(_p, "animationScale", _p.getAnimationScale, _p.setAnimationScale);
+
+_p = null;
+
+/**
+ * Allocates and initializes a ArmatureAnimation.
+ * @return {ccs.ArmatureAnimation}
+ * @deprecated since v3.1, please use new construction instead
+ */
+ccs.ArmatureAnimation.create = function (armature) {
+ return new ccs.ArmatureAnimation(armature);
+};
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/animation/CCProcessBase.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/animation/CCProcessBase.js
new file mode 100644
index 0000000..a4707d3
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/animation/CCProcessBase.js
@@ -0,0 +1,365 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+//animation type
+/**
+ * The animation just have one frame
+ * @constant
+ * @type {number}
+ */
+ccs.ANIMATION_TYPE_SINGLE_FRAME = -4;
+/**
+ * The animation isn't loop
+ * @constant
+ * @type {number}
+ */
+ccs.ANIMATION_TYPE_NO_LOOP = -3;
+/**
+ * The animation to loop from front
+ * @constant
+ * @type {number}
+ */
+ccs.ANIMATION_TYPE_TO_LOOP_FRONT = -2;
+/**
+ * The animation to loop from back
+ * @constant
+ * @type {number}
+ */
+ccs.ANIMATION_TYPE_TO_LOOP_BACK = -1;
+/**
+ * The animation loop from front
+ * @constant
+ * @type {number}
+ */
+ccs.ANIMATION_TYPE_LOOP_FRONT = 0;
+/**
+ * The animation loop from back
+ * @constant
+ * @type {number}
+ */
+ccs.ANIMATION_TYPE_LOOP_BACK = 1;
+/**
+ * The animation max
+ * @constant
+ * @type {number}
+ */
+ccs.ANIMATION_TYPE_MAX = 2;
+
+/**
+ * The Base Process class for Cocostudio.
+ * @class
+ * @extends ccs.Class
+ *
+ * @property {Number} currentFrameIndex - <@readonly> The current frame's index
+ * @property {Boolean} paused - <@readonly> Indicate whether the process is paused
+ * @property {Boolean} completed - <@readonly> Indicate whether the process is done
+ * @property {Number} currentPercent - <@readonly> The current percentage of the process
+ * @property {Number} rawDuration - <@readonly> The duration
+ * @property {Number} loop - <@readonly> The number of loop
+ * @property {Number} tweenEasing - <@readonly> The tween easing
+ * @property {Number} animationInterval - The animation internal
+ * @property {Number} processScale - The process scale
+ * @property {Boolean} playing - <@readonly> Indicate whether the process is playing
+ */
+ccs.ProcessBase = ccs.Class.extend(/** @lends ccs.ProcessBase# */{
+ _processScale: 1,
+ _isComplete: true,
+ _isPause: true,
+ _isPlaying: false,
+ _currentPercent: 0.0,
+ _rawDuration: 0,
+ _loopType: 0,
+ _tweenEasing: 0,
+ animationInternal: null,
+ _currentFrame: 0,
+ _durationTween: 0,
+ _nextFrameIndex: 0,
+ _curFrameIndex: null,
+ _isLoopBack: false,
+
+ /**
+ * Constructor of ccs.ProcessBase
+ */
+ ctor: function () {
+ this._processScale = 1;
+ this._isComplete = true;
+ this._isPause = true;
+ this._isPlaying = false;
+ this._currentFrame = 0;
+ this._currentPercent = 0.0;
+ this._durationTween = 0;
+ this._rawDuration = 0;
+ this._loopType = ccs.ANIMATION_TYPE_LOOP_BACK;
+ this._tweenEasing = ccs.TweenType.LINEAR;
+ this.animationInternal = 1 / 60;
+ this._curFrameIndex = 0;
+ this._durationTween = 0;
+ this._isLoopBack = false;
+ },
+
+ /**
+ * Pauses the Process
+ */
+ pause: function () {
+ this._isPause = true;
+ this._isPlaying = false;
+ },
+
+ /**
+ * Resumes the Process
+ */
+ resume: function () {
+ this._isPause = false;
+ this._isPlaying = true;
+ },
+
+ /**
+ * Stops the Process
+ */
+ stop: function () {
+ this._isComplete = true;
+ this._isPlaying = false;
+ },
+
+ /**
+ * Plays animation by animation name.
+ * @param {Number} durationTo The frames between two animation changing-over.
+ * It's meaning is changing to this animation need how many frames
+ * -1 : use the value from MovementData get from flash design panel
+ * @param {Number} durationTween The frame count you want to play in the game.
+ * if _durationTween is 80, then the animation will played 80 frames in a loop
+ * -1 : use the value from MovementData get from flash design panel
+ * @param {Number} loop Whether the animation is loop
+ * loop < 0 : use the value from MovementData get from flash design panel
+ * loop = 0 : this animation is not loop
+ * loop > 0 : this animation is loop
+ * @param {Number} tweenEasing Tween easing is used for calculate easing effect
+ * TWEEN_EASING_MAX : use the value from MovementData get from flash design panel
+ * -1 : fade out
+ * 0 : line
+ * 1 : fade in
+ * 2 : fade in and out
+ */
+ play: function (durationTo, durationTween, loop, tweenEasing) {
+ this._isComplete = false;
+ this._isPause = false;
+ this._isPlaying = true;
+ this._currentFrame = 0;
+ /*
+ * Set m_iTotalFrames to durationTo, it is used for change tween between two animation.
+ * When changing end, m_iTotalFrames will be set to _durationTween
+ */
+ this._nextFrameIndex = durationTo;
+ this._tweenEasing = tweenEasing;
+ },
+
+ /**
+ * Update process' state.
+ * @param {Number} dt
+ */
+ update: function (dt) {
+ if (this._isComplete || this._isPause)
+ return;
+
+ /*
+ * Fileter the m_iDuration <=0 and dt >1
+ * If dt>1, generally speaking the reason is the device is stuck.
+ */
+ if (this._rawDuration <= 0 || dt > 1)
+ return;
+
+ var locNextFrameIndex = this._nextFrameIndex === undefined ? 0 : this._nextFrameIndex;
+ var locCurrentFrame = this._currentFrame;
+ if (locNextFrameIndex <= 0) {
+ this._currentPercent = 1;
+ locCurrentFrame = 0;
+ } else {
+ /*
+ * update currentFrame, every update add the frame passed.
+ * dt/this.animationInternal determine it is not a frame animation. If frame speed changed, it will not make our
+ * animation speed slower or quicker.
+ */
+ locCurrentFrame += this._processScale * (dt / this.animationInternal);
+ this._currentPercent = locCurrentFrame / locNextFrameIndex;
+
+ /*
+ * if currentFrame is bigger or equal than this._nextFrameIndex, then reduce it util currentFrame is
+ * smaller than this._nextFrameIndex
+ */
+ locCurrentFrame = ccs.fmodf(locCurrentFrame, locNextFrameIndex);
+ }
+ this._currentFrame = locCurrentFrame;
+ this.updateHandler();
+ },
+
+ /**
+ * Goes to specified frame by frameIndex.
+ * @param {Number} frameIndex
+ */
+ gotoFrame: function (frameIndex) {
+ var locLoopType = this._loopType;
+ if (locLoopType === ccs.ANIMATION_TYPE_NO_LOOP)
+ locLoopType = ccs.ANIMATION_TYPE_MAX;
+ else if (locLoopType === ccs.ANIMATION_TYPE_TO_LOOP_FRONT)
+ locLoopType = ccs.ANIMATION_TYPE_LOOP_FRONT;
+ this._loopType = locLoopType;
+ this._curFrameIndex = frameIndex;
+ this._nextFrameIndex = this._durationTween;
+ },
+
+ /**
+ * Returns the index of current frame.
+ * @return {Number}
+ */
+ getCurrentFrameIndex: function () {
+ this._curFrameIndex = (this._rawDuration - 1) * this._currentPercent;
+ return this._curFrameIndex;
+ },
+
+ /**
+ * Updates will call this handler, you can handle your logic here
+ */
+ updateHandler: function () {
+ //override
+ },
+
+ /**
+ * Returns whether the animation is pause
+ * @returns {boolean}
+ */
+ isPause: function () {
+ return this._isPause;
+ },
+
+ /**
+ * Returns whether the animation is complete
+ * @returns {boolean}
+ */
+ isComplete: function () {
+ return this._isComplete;
+ },
+
+ /**
+ * Returns current percent of ccs.ProcessBase
+ * @returns {number}
+ */
+ getCurrentPercent: function () {
+ return this._currentPercent;
+ },
+
+ /**
+ * Returns the raw duration of ccs.ProcessBase
+ * @returns {number}
+ */
+ getRawDuration: function () {
+ return this._rawDuration;
+ },
+
+ /**
+ * Returns loop type of ccs.ProcessBase
+ * @returns {number}
+ */
+ getLoop: function () {
+ return this._loopType;
+ },
+
+ /**
+ * Returns tween easing of ccs.ProcessBase
+ * @returns {number}
+ */
+ getTweenEasing: function () {
+ return this._tweenEasing;
+ },
+
+ /**
+ * Returns animation interval of ccs.ProcessBase
+ * @returns {number}
+ */
+ getAnimationInternal: function () { //TODO rename getAnimationInternal to getAnimationInterval in v3.1
+ return this.animationInternal;
+ },
+
+ /**
+ * Sets animation interval to ccs.ProcessBase.
+ * @param animationInternal
+ */
+ setAnimationInternal: function (animationInternal) {
+ this.animationInternal = animationInternal;
+ },
+
+ /**
+ * Returns process scale
+ * @returns {number}
+ */
+ getProcessScale: function () {
+ return this._processScale;
+ },
+
+ /**
+ * Sets process scale
+ * @param processScale
+ */
+ setProcessScale: function (processScale) {
+ this._processScale = processScale;
+ },
+
+ /**
+ * Returns whether the animation is playing
+ * @returns {boolean}
+ */
+ isPlaying: function () {
+ return this._isPlaying;
+ }
+});
+
+var _p = ccs.ProcessBase.prototype;
+
+// Extended properties
+/** @expose */
+_p.currentFrameIndex;
+cc.defineGetterSetter(_p, "currentFrameIndex", _p.getCurrentFrameIndex);
+/** @expose */
+_p.paused;
+cc.defineGetterSetter(_p, "paused", _p.isPause);
+/** @expose */
+_p.completed;
+cc.defineGetterSetter(_p, "completed", _p.isComplete);
+/** @expose */
+_p.currentPercent;
+cc.defineGetterSetter(_p, "currentPercent", _p.getCurrentPercent);
+/** @expose */
+_p.rawDuration;
+cc.defineGetterSetter(_p, "rawDuration", _p.getRawDuration);
+/** @expose */
+_p.loop;
+cc.defineGetterSetter(_p, "loop", _p.getLoop);
+/** @expose */
+_p.tweenEasing;
+cc.defineGetterSetter(_p, "tweenEasing", _p.getTweenEasing);
+/** @expose */
+_p.playing;
+cc.defineGetterSetter(_p, "playing", _p.isPlaying);
+
+_p = null;
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/animation/CCTween.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/animation/CCTween.js
new file mode 100644
index 0000000..5706d1d
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/animation/CCTween.js
@@ -0,0 +1,448 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The tween class for Armature.
+ * @class
+ * @extends ccs.ProcessBase
+ *
+ * @param {ccs.Bone} The bone to be animated
+ *
+ * @property {ccs.ArmatureAnimation} animation - The animation
+ */
+ccs.Tween = ccs.ProcessBase.extend(/** @lends ccs.Tween# */{
+ _tweenData:null,
+ _to:null,
+ _from:null,
+ _between:null,
+ _movementBoneData:null,
+ _bone:null,
+ _frameTweenEasing:0,
+ _betweenDuration:0,
+ _totalDuration:0,
+ _toIndex:0,
+ _fromIndex:0,
+ _animation:null,
+ _passLastFrame:false,
+
+ ctor:function (bone) {
+ ccs.ProcessBase.prototype.ctor.call(this);
+ this._frameTweenEasing = ccs.TweenType.LINEAR;
+
+ ccs.Tween.prototype.init.call(this, bone);
+ },
+
+ /**
+ * initializes a ccs.Tween with a CCBone
+ * @param {ccs.Bone} bone
+ * @return {Boolean}
+ */
+ init:function (bone) {
+ this._from = new ccs.FrameData();
+ this._between = new ccs.FrameData();
+
+ this._bone = bone;
+ this._tweenData = this._bone.getTweenData();
+ this._tweenData.displayIndex = -1;
+
+ this._animation = (this._bone !== null && this._bone.getArmature() !== null) ?
+ this._bone.getArmature().getAnimation() :
+ null;
+ return true;
+ },
+
+ /**
+ * Plays the tween.
+ * @param {ccs.MovementBoneData} movementBoneData
+ * @param {Number} durationTo
+ * @param {Number} durationTween
+ * @param {Boolean} loop
+ * @param {ccs.TweenType} tweenEasing
+ */
+ play:function (movementBoneData, durationTo, durationTween, loop, tweenEasing) {
+ ccs.ProcessBase.prototype.play.call(this, durationTo, durationTween, loop, tweenEasing);
+ this._loopType = (loop)?ccs.ANIMATION_TYPE_TO_LOOP_FRONT:ccs.ANIMATION_TYPE_NO_LOOP;
+
+ this._totalDuration = 0;
+ this._betweenDuration = 0;
+ this._fromIndex = this._toIndex = 0;
+
+ var difMovement = movementBoneData !== this._movementBoneData;
+
+ this.setMovementBoneData(movementBoneData);
+ this._rawDuration = this._movementBoneData.duration;
+
+ var nextKeyFrame = this._movementBoneData.getFrameData(0);
+ this._tweenData.displayIndex = nextKeyFrame.displayIndex;
+
+ if (this._bone.getArmature().getArmatureData().dataVersion >= ccs.CONST_VERSION_COMBINED) {
+ ccs.TransformHelp.nodeSub(this._tweenData, this._bone.getBoneData());
+ this._tweenData.scaleX += 1;
+ this._tweenData.scaleY += 1;
+ }
+
+ if (this._rawDuration === 0) {
+ this._loopType = ccs.ANIMATION_TYPE_SINGLE_FRAME;
+ if (durationTo === 0)
+ this.setBetween(nextKeyFrame, nextKeyFrame);
+ else
+ this.setBetween(this._tweenData, nextKeyFrame);
+ this._frameTweenEasing = ccs.TweenType.LINEAR;
+ }
+ else if (this._movementBoneData.frameList.length > 1) {
+ this._durationTween = durationTween * this._movementBoneData.scale;
+ if (loop && this._movementBoneData.delay !== 0)
+ this.setBetween(this._tweenData, this.tweenNodeTo(this.updateFrameData(1 - this._movementBoneData.delay), this._between));
+ else {
+ if (!difMovement || durationTo === 0)
+ this.setBetween(nextKeyFrame, nextKeyFrame);
+ else
+ this.setBetween(this._tweenData, nextKeyFrame);
+ }
+ }
+ this.tweenNodeTo(0);
+ },
+
+ /**
+ * Goes to specified frame and plays frame.
+ * @param {Number} frameIndex
+ */
+ gotoAndPlay: function (frameIndex) {
+ ccs.ProcessBase.prototype.gotoFrame.call(this, frameIndex);
+
+ this._totalDuration = 0;
+ this._betweenDuration = 0;
+ this._fromIndex = this._toIndex = 0;
+
+ this._isPlaying = true;
+ this._isComplete = this._isPause = false;
+
+ this._currentPercent = this._curFrameIndex / (this._rawDuration-1);
+ this._currentFrame = this._nextFrameIndex * this._currentPercent;
+ },
+
+ /**
+ * Goes to specified frame and pauses frame.
+ * @param {Number} frameIndex
+ */
+ gotoAndPause: function (frameIndex) {
+ this.gotoAndPlay(frameIndex);
+ this.pause();
+ },
+
+ /**
+ * update will call this handler, you can handle your logic here
+ */
+ updateHandler:function () {
+ var locCurrentPercent = this._currentPercent == null ? 1 : this._currentPercent;
+ var locLoopType = this._loopType;
+ if (locCurrentPercent >= 1) {
+ switch (locLoopType) {
+ case ccs.ANIMATION_TYPE_SINGLE_FRAME:
+ locCurrentPercent = 1;
+ this._isComplete = true;
+ this._isPlaying = false;
+ break;
+ case ccs.ANIMATION_TYPE_NO_LOOP:
+ locLoopType = ccs.ANIMATION_TYPE_MAX;
+ if (this._durationTween <= 0)
+ locCurrentPercent = 1;
+ else
+ locCurrentPercent = (locCurrentPercent - 1) * this._nextFrameIndex / this._durationTween;
+ if (locCurrentPercent >= 1) {
+ locCurrentPercent = 1;
+ this._isComplete = true;
+ this._isPlaying = false;
+ break;
+ } else {
+ this._nextFrameIndex = this._durationTween;
+ this._currentFrame = locCurrentPercent * this._nextFrameIndex;
+ this._totalDuration = 0;
+ this._betweenDuration = 0;
+ this._fromIndex = this._toIndex = 0;
+ break;
+ }
+ case ccs.ANIMATION_TYPE_TO_LOOP_FRONT:
+ locLoopType = ccs.ANIMATION_TYPE_LOOP_FRONT;
+ this._nextFrameIndex = this._durationTween > 0 ? this._durationTween : 1;
+
+ if (this._movementBoneData.delay !== 0) {
+ this._currentFrame = (1 - this._movementBoneData.delay) * this._nextFrameIndex;
+ locCurrentPercent = this._currentFrame / this._nextFrameIndex;
+ } else {
+ locCurrentPercent = 0;
+ this._currentFrame = 0;
+ }
+
+ this._totalDuration = 0;
+ this._betweenDuration = 0;
+ this._fromIndex = this._toIndex = 0;
+ break;
+ case ccs.ANIMATION_TYPE_MAX:
+ locCurrentPercent = 1;
+ this._isComplete = true;
+ this._isPlaying = false;
+ break;
+ default:
+ this._currentFrame = ccs.fmodf(this._currentFrame, this._nextFrameIndex);
+ break;
+ }
+ }
+
+ if (locCurrentPercent < 1 && locLoopType < ccs.ANIMATION_TYPE_TO_LOOP_BACK)
+ locCurrentPercent = Math.sin(locCurrentPercent * cc.PI / 2);
+
+ this._currentPercent = locCurrentPercent;
+ this._loopType = locLoopType;
+
+ if (locLoopType > ccs.ANIMATION_TYPE_TO_LOOP_BACK)
+ locCurrentPercent = this.updateFrameData(locCurrentPercent);
+ if (this._frameTweenEasing !== ccs.TweenType.TWEEN_EASING_MAX)
+ this.tweenNodeTo(locCurrentPercent);
+ },
+
+ /**
+ * Calculate the between value of _from and _to, and give it to between frame data
+ * @param {ccs.FrameData} from
+ * @param {ccs.FrameData} to
+ * @param {Boolean} [limit=true]
+ */
+ setBetween:function (from, to, limit) { //TODO set tweenColorTo to protected in v3.1
+ if(limit === undefined)
+ limit = true;
+ do {
+ if (from.displayIndex < 0 && to.displayIndex >= 0) {
+ this._from.copy(to);
+ this._between.subtract(to, to, limit);
+ break;
+ }
+ if (to.displayIndex < 0 && from.displayIndex >= 0) {
+ this._from.copy(from);
+ this._between.subtract(to, to, limit);
+ break;
+ }
+ this._from.copy(from);
+ this._between.subtract(from, to, limit);
+ } while (0);
+ if (!from.isTween){
+ this._tweenData.copy(from);
+ this._tweenData.isTween = true;
+ }
+ this.arriveKeyFrame(from);
+ },
+
+ /**
+ * Update display index and process the key frame event when arrived a key frame
+ * @param {ccs.FrameData} keyFrameData
+ */
+ arriveKeyFrame:function (keyFrameData) { //TODO set tweenColorTo to protected in v3.1
+ if (keyFrameData) {
+ var locBone = this._bone;
+ var displayManager = locBone.getDisplayManager();
+
+ //! Change bone's display
+ var displayIndex = keyFrameData.displayIndex;
+
+ if (!displayManager.getForceChangeDisplay())
+ displayManager.changeDisplayWithIndex(displayIndex, false);
+
+ //! Update bone zorder, bone's zorder is determined by frame zorder and bone zorder
+ this._tweenData.zOrder = keyFrameData.zOrder;
+ locBone.updateZOrder();
+
+ //! Update blend type
+ this._bone.setBlendFunc(keyFrameData.blendFunc);
+
+ var childAramture = locBone.getChildArmature();
+ if (childAramture) {
+ if (keyFrameData.movement !== "")
+ childAramture.getAnimation().play(keyFrameData.movement);
+ }
+ }
+ },
+
+ /**
+ * According to the percent to calculate current CCFrameData with tween effect
+ * @param {Number} percent
+ * @param {ccs.FrameData} [node]
+ * @return {ccs.FrameData}
+ */
+ tweenNodeTo:function (percent, node) { //TODO set tweenColorTo to protected in v3.1
+ if (!node)
+ node = this._tweenData;
+
+ var locFrom = this._from;
+ var locBetween = this._between;
+ if (!locFrom.isTween)
+ percent = 0;
+ node.x = locFrom.x + percent * locBetween.x;
+ node.y = locFrom.y + percent * locBetween.y;
+ node.scaleX = locFrom.scaleX + percent * locBetween.scaleX;
+ node.scaleY = locFrom.scaleY + percent * locBetween.scaleY;
+ node.skewX = locFrom.skewX + percent * locBetween.skewX;
+ node.skewY = locFrom.skewY + percent * locBetween.skewY;
+
+ this._bone.setTransformDirty(true);
+ if (node && locBetween.isUseColorInfo)
+ this.tweenColorTo(percent, node);
+
+ return node;
+ },
+
+ /**
+ * According to the percent to calculate current color with tween effect
+ * @param {Number} percent
+ * @param {ccs.FrameData} node
+ */
+ tweenColorTo:function(percent,node){ //TODO set tweenColorTo to protected in v3.1
+ var locFrom = this._from;
+ var locBetween = this._between;
+ node.a = locFrom.a + percent * locBetween.a;
+ node.r = locFrom.r + percent * locBetween.r;
+ node.g = locFrom.g + percent * locBetween.g;
+ node.b = locFrom.b + percent * locBetween.b;
+ this._bone.updateColor();
+ },
+
+ /**
+ * Calculate which frame arrived, and if current frame have event, then call the event listener
+ * @param {Number} currentPercent
+ * @return {Number}
+ */
+ updateFrameData:function (currentPercent) { //TODO set tweenColorTo to protected in v3.1
+ if (currentPercent > 1 && this._movementBoneData.delay !== 0)
+ currentPercent = ccs.fmodf(currentPercent,1);
+
+ var playedTime = (this._rawDuration-1) * currentPercent;
+
+ var from, to;
+ var locTotalDuration = this._totalDuration,locBetweenDuration = this._betweenDuration, locToIndex = this._toIndex;
+ // if play to current frame's front or back, then find current frame again
+ if (playedTime < locTotalDuration || playedTime >= locTotalDuration + locBetweenDuration) {
+ /*
+ * get frame length, if this._toIndex >= _length, then set this._toIndex to 0, start anew.
+ * this._toIndex is next index will play
+ */
+ var frames = this._movementBoneData.frameList;
+ var length = frames.length;
+
+ if (playedTime < frames[0].frameID){
+ from = to = frames[0];
+ this.setBetween(from, to);
+ return this._currentPercent;
+ }
+
+ if (playedTime >= frames[length - 1].frameID) {
+ // If _passLastFrame is true and playedTime >= frames[length - 1]->frameID, then do not need to go on.
+ if (this._passLastFrame) {
+ from = to = frames[length - 1];
+ this.setBetween(from, to);
+ return this._currentPercent;
+ }
+ this._passLastFrame = true;
+ } else
+ this._passLastFrame = false;
+
+ do {
+ this._fromIndex = locToIndex;
+ from = frames[this._fromIndex];
+ locTotalDuration = from.frameID;
+
+ locToIndex = this._fromIndex + 1;
+ if (locToIndex >= length)
+ locToIndex = 0;
+ to = frames[locToIndex];
+
+ //! Guaranteed to trigger frame event
+ if(from.strEvent && !this._animation.isIgnoreFrameEvent())
+ this._animation.frameEvent(this._bone, from.strEvent,from.frameID, playedTime);
+
+ if (playedTime === from.frameID|| (this._passLastFrame && this._fromIndex === length-1))
+ break;
+ } while (playedTime < from.frameID || playedTime >= to.frameID);
+
+ locBetweenDuration = to.frameID - from.frameID;
+ this._frameTweenEasing = from.tweenEasing;
+ this.setBetween(from, to, false);
+
+ this._totalDuration = locTotalDuration;
+ this._betweenDuration = locBetweenDuration;
+ this._toIndex = locToIndex;
+ }
+ currentPercent = locBetweenDuration === 0 ? 0 : (playedTime - this._totalDuration) / this._betweenDuration;
+
+ /*
+ * if frame tween easing equal to TWEEN_EASING_MAX, then it will not do tween.
+ */
+ var tweenType = (this._frameTweenEasing !== ccs.TweenType.LINEAR) ? this._frameTweenEasing : this._tweenEasing;
+ if (tweenType !== ccs.TweenType.TWEEN_EASING_MAX && tweenType !== ccs.TweenType.LINEAR && !this._passLastFrame) {
+ currentPercent = ccs.TweenFunction.tweenTo(currentPercent, tweenType, this._from.easingParams);
+ }
+ return currentPercent;
+ },
+
+ /**
+ * Sets Armature animation to ccs.Tween.
+ * @param {ccs.ArmatureAnimation} animation
+ */
+ setAnimation:function (animation) {
+ this._animation = animation;
+ },
+
+ /**
+ * Returns Armature animation of ccs.Tween.
+ * @return {ccs.ArmatureAnimation}
+ */
+ getAnimation:function () {
+ return this._animation;
+ },
+
+ /**
+ * Sets movement bone data to ccs.Tween.
+ * @param data
+ */
+ setMovementBoneData: function(data){
+ this._movementBoneData = data;
+ }
+});
+
+var _p = ccs.Tween.prototype;
+
+// Extended properties
+/** @expose */
+_p.animation;
+cc.defineGetterSetter(_p, "animation", _p.getAnimation, _p.setAnimation);
+
+_p = null;
+
+/**
+ * Allocates and initializes a ArmatureAnimation.
+ * @param {ccs.Bone} bone
+ * @return {ccs.Tween}
+ * @deprecated since v3.1, please use new construction instead
+ */
+ccs.Tween.create = function (bone) {
+ return new ccs.Tween(bone);
+};
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/datas/CCDatas.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/datas/CCDatas.js
new file mode 100644
index 0000000..6aa958b
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/datas/CCDatas.js
@@ -0,0 +1,807 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+//BlendType
+/**
+ * The value of the blend type of normal
+ * @constant
+ * @type Number
+ */
+ccs.BLEND_TYPE_NORMAL = 0;
+
+/**
+ * The value of the blend type of layer
+ * @constant
+ * @type Number
+ */
+ccs.BLEND_TYPE_LAYER = 1;
+
+/**
+ * The value of the blend type of darken
+ * @constant
+ * @type Number
+ */
+ccs.BLEND_TYPE_DARKEN = 2;
+
+/**
+ * The value of the blend type of multiply
+ * @constant
+ * @type Number
+ */
+ccs.BLEND_TYPE_MULTIPLY = 3;
+
+/**
+ * The value of the blend type of lighten
+ * @constant
+ * @type Number
+ */
+ccs.BLEND_TYPE_LIGHTEN = 4;
+
+/**
+ * The value of the blend type of screen
+ * @constant
+ * @type Number
+ */
+ccs.BLEND_TYPE_SCREEN = 5;
+
+/**
+ * The value of the blend type of overlay
+ * @constant
+ * @type Number
+ */
+ccs.BLEND_TYPE_OVERLAY = 6;
+
+/**
+ * The value of the blend type of highlight
+ * @constant
+ * @type Number
+ */
+ccs.BLEND_TYPE_HIGHLIGHT = 7;
+
+/**
+ * The value of the blend type of add
+ * @constant
+ * @type Number
+ */
+ccs.BLEND_TYPE_ADD = 8;
+
+/**
+ * The value of the blend type of subtract
+ * @constant
+ * @type Number
+ */
+ccs.BLEND_TYPE_SUBTRACT = 9;
+
+/**
+ * The value of the blend type of difference
+ * @constant
+ * @type Number
+ */
+ccs.BLEND_TYPE_DIFFERENCE = 10;
+
+/**
+ * The value of the blend type of invert
+ * @constant
+ * @type Number
+ */
+ccs.BLEND_TYPE_INVERT = 11;
+
+/**
+ * The value of the blend type of alpha
+ * @constant
+ * @type Number
+ */
+ccs.BLEND_TYPE_ALPHA = 12;
+
+/**
+ * The value of the blend type of erase
+ * @constant
+ * @type Number
+ */
+ccs.BLEND_TYPE_ERASE = 13;
+
+//DisplayType
+/**
+ * The Sprite flag of display render type.
+ * @constant
+ * @type Number
+ */
+ccs.DISPLAY_TYPE_SPRITE = 0;
+/**
+ * The Armature flag of display render type.
+ * @constant
+ * @type Number
+ */
+ccs.DISPLAY_TYPE_ARMATURE = 1;
+/**
+ * The Particle flag of display render type.
+ * @constant
+ * @type Number
+ */
+ccs.DISPLAY_TYPE_PARTICLE = 2;
+ccs.DISPLAY_TYPE_MAX = 3;
+
+/**
+ *
+ * The base data class for Armature. it contains position, zOrder, skew, scale, color datas.
+ * x y skewX skewY scaleX scaleY used to calculate transform matrix
+ * skewX, skewY can have rotation effect
+ * To get more matrix information, you can have a look at this pape : http://www.senocular.com/flash/tutorials/transformmatrix/
+ *
+ * @class
+ * @extends ccs.Class
+ *
+ * @property {Number} x - x
+ * @property {Number} y - y
+ * @property {Number} zOrder - zOrder
+ * @property {Number} skewX - skewX
+ * @property {Number} skewY - skewY
+ * @property {Number} scaleX - scaleX
+ * @property {Number} scaleY - scaleY
+ * @property {Number} tweenRotate - tween Rotate
+ * @property {Number} isUseColorInfo - is Use Color Info
+ * @property {Number} r - r of color
+ * @property {Number} g - g of color
+ * @property {Number} b - b of color
+ * @property {Number} a - a of color
+ */
+ccs.BaseData = ccs.Class.extend(/** @lends ccs.BaseData# */{
+ x:0,
+ y:0,
+ zOrder:0,
+ skewX:0,
+ skewY:0,
+ scaleX:1,
+ scaleY:1,
+ tweenRotate:0, //! SkewX, SkewY, and TweenRotate effect the rotation
+ isUseColorInfo:false, //! Whether or not this frame have the color changed Info
+ r:255,
+ g:255,
+ b:255,
+ a:255,
+
+ /**
+ * Construction of ccs.BaseData
+ */
+ ctor:function () {
+ this.x = 0;
+ this.y = 0;
+ this.zOrder = 0;
+ this.skewX = 0;
+ this.skewY = 0;
+ this.scaleX = 1;
+ this.scaleY = 1;
+ this.tweenRotate = 0;
+ this.isUseColorInfo = false;
+ this.r = 255;
+ this.g = 255;
+ this.b = 255;
+ this.a = 255;
+ },
+
+ /**
+ * Copy data from node
+ * @function
+ * @param {ccs.BaseData} node
+ */
+ copy:function (node) {
+ this.x = node.x;
+ this.y = node.y;
+ this.zOrder = node.zOrder;
+
+ this.scaleX = node.scaleX;
+ this.scaleY = node.scaleY;
+ this.skewX = node.skewX;
+ this.skewY = node.skewY;
+
+ this.tweenRotate = node.tweenRotate;
+
+ this.isUseColorInfo = node.isUseColorInfo;
+ this.r = node.r;
+ this.g = node.g;
+ this.b = node.b;
+ this.a = node.a;
+ },
+
+ /**
+ * Sets color to base data.
+ * @function
+ * @param {cc.Color} color
+ */
+ setColor:function(color){
+ this.r = color.r;
+ this.g = color.g;
+ this.b = color.b;
+ this.a = color.a;
+ },
+
+ /**
+ * Returns the color of ccs.BaseData
+ * @function
+ * @returns {cc.Color}
+ */
+ getColor:function(){
+ return cc.color(this.r, this.g, this.b, this.a);
+ },
+
+ /**
+ * Calculate two baseData's between value(to - from) and set to self
+ * @function
+ * @param {ccs.BaseData} from
+ * @param {ccs.BaseData} to
+ * @param {Boolean} limit
+ */
+ subtract:function (from, to, limit) {
+ this.x = to.x - from.x;
+ this.y = to.y - from.y;
+ this.scaleX = to.scaleX - from.scaleX;
+ this.scaleY = to.scaleY - from.scaleY;
+ this.skewX = to.skewX - from.skewX;
+ this.skewY = to.skewY - from.skewY;
+
+ if (this.isUseColorInfo || from.isUseColorInfo || to.isUseColorInfo) {
+ this.a = to.a - from.a;
+ this.r = to.r - from.r;
+ this.g = to.g - from.g;
+ this.b = to.b - from.b;
+ this.isUseColorInfo = true;
+ } else {
+ this.a = this.r = this.g = this.b = 0;
+ this.isUseColorInfo = false;
+ }
+
+ if (limit) {
+ if (this.skewX > ccs.M_PI)
+ this.skewX -= ccs.DOUBLE_PI;
+ if (this.skewX < -ccs.M_PI)
+ this.skewX += ccs.DOUBLE_PI;
+ if (this.skewY > ccs.M_PI)
+ this.skewY -= ccs.DOUBLE_PI;
+ if (this.skewY < -ccs.M_PI)
+ this.skewY += ccs.DOUBLE_PI;
+ }
+
+ if (to.tweenRotate) {
+ this.skewX += to.tweenRotate * ccs.PI * 2;
+ this.skewY -= to.tweenRotate * ccs.PI * 2;
+ }
+ }
+});
+
+/**
+ * The class use for save display data.
+ * @class
+ * @extends ccs.Class
+ *
+ * @property {Number} displayType - the display type
+ * @property {String} displayName - the display name
+ */
+ccs.DisplayData = ccs.Class.extend(/** @lends ccs.DisplayData# */{
+ displayType: ccs.DISPLAY_TYPE_MAX,
+ displayName: "",
+
+ /**
+ * Construction of ccs.DisplayData
+ */
+ ctor: function () {
+ this.displayType = ccs.DISPLAY_TYPE_MAX;
+ },
+ /**
+ * Changes display name to texture type
+ * @function
+ * @param {String} displayName
+ * @returns {String}
+ */
+ changeDisplayToTexture:function (displayName) {
+ // remove .xxx
+ var textureName = displayName;
+ var startPos = textureName.lastIndexOf(".");
+
+ if (startPos !== -1)
+ textureName = textureName.substring(0, startPos);
+ return textureName;
+ },
+
+ /**
+ * copy data
+ * @function
+ * @param {ccs.DisplayData} displayData
+ */
+ copy:function (displayData) {
+ this.displayName = displayData.displayName;
+ this.displayType = displayData.displayType;
+ }
+});
+
+/**
+ * The sprite display data class.
+ * @class
+ * @extends ccs.DisplayData
+ *
+ * @property {ccs.BaseData} skinData - the skin data
+ */
+ccs.SpriteDisplayData = ccs.DisplayData.extend(/** @lends ccs.SpriteDisplayData# */{
+ skinData:null,
+
+ /**
+ * Construction of ccs.SpriteDisplayData
+ */
+ ctor:function () {
+ this.skinData = new ccs.BaseData();
+ this.displayType = ccs.DISPLAY_TYPE_SPRITE;
+ },
+ /**
+ * copy data
+ * @function
+ * @param {ccs.SpriteDisplayData} displayData
+ */
+ copy:function (displayData) {
+ ccs.DisplayData.prototype.copy.call(this,displayData);
+ this.skinData = displayData.skinData;
+ }
+});
+
+/**
+ * The armature display data class
+ * @class ccs.ArmatureDisplayData
+ * @extends ccs.DisplayData
+ */
+ccs.ArmatureDisplayData = ccs.DisplayData.extend(/** @lends ccs.ArmatureDisplayData# */{
+ /**
+ * Construction of ccs.ArmatureDisplayData
+ */
+ ctor:function () {
+ this.displayName = "";
+ this.displayType = ccs.DISPLAY_TYPE_ARMATURE;
+ }
+});
+
+/**
+ * The particle display data class.
+ * @class ccs.ParticleDisplayData
+ * @extends ccs.DisplayData
+ */
+ccs.ParticleDisplayData = ccs.DisplayData.extend(/** @lends ccs.ParticleDisplayData# */{
+ /**
+ * Construction of ccs.ParticleDisplayData
+ */
+ ctor:function () {
+ this.displayType = ccs.DISPLAY_TYPE_PARTICLE;
+ }
+});
+
+/**
+ *
+ * BoneData used to init a Bone.
+ * BoneData keeps a DisplayData list, a Bone can have many display to change.
+ * The display information saved in the DisplayData
+ *
+ * @class ccs.BoneData
+ * @extends ccs.BaseData
+ *
+ * @property {Array} displayDataList - the display data list
+ * @property {String} name - the name of Bone
+ * @property {String} parentName - the parent name of bone
+ * @property {cc.AffineTransform} boneDataTransform - the bone transform data
+ */
+ccs.BoneData = ccs.BaseData.extend(/** @lends ccs.BoneData# */{
+ displayDataList: null,
+ name: "",
+ parentName: "",
+ boneDataTransform: null,
+
+ /**
+ * Construction of ccs.BoneData
+ */
+ ctor: function () {
+ this.displayDataList = [];
+ this.name = "";
+ this.parentName = "";
+ this.boneDataTransform = null;
+ },
+
+ /**
+ * Initializes a ccs.BoneData
+ * @returns {boolean}
+ */
+ init: function () {
+ this.displayDataList.length = 0;
+ return true;
+ },
+ /**
+ * Adds display data to list
+ * @function
+ * @param {ccs.DisplayData} displayData
+ */
+ addDisplayData:function (displayData) {
+ this.displayDataList.push(displayData);
+ },
+
+ /**
+ * Returns display data with index.
+ * @function
+ * @param {Number} index
+ * @returns {ccs.DisplayData}
+ */
+ getDisplayData:function (index) {
+ return this.displayDataList[index];
+ }
+});
+
+/**
+ *
+ * ArmatureData saved the Armature name and BoneData needed for the CCBones in this Armature
+ * When we create a Armature, we need to get each Bone's BoneData as it's init information.
+ * So we can get a BoneData from the Dictionary saved in the ArmatureData.
+ *
+ * @class ccs.ArmatureData
+ * @extends ccs.Class
+ *
+ * @property {Object} boneDataDic - the bone data dictionary
+ * @property {String} name - the name of armature data
+ * @property {Number} dataVersion - the data version of armature data
+ */
+ccs.ArmatureData = ccs.Class.extend(/** @lends ccs.ArmatureData# */{
+ boneDataDic:null,
+ name:"",
+ dataVersion:0.1,
+
+ /**
+ * Construction of ccs.ArmatureData
+ */
+ ctor:function () {
+ this.boneDataDic = {};
+ this.name = "";
+ this.dataVersion = 0.1;
+ },
+
+ /**
+ * Initializes a ccs.ArmatureData
+ * @returns {boolean}
+ */
+ init:function () {
+ return true;
+ },
+
+ /**
+ * Adds bone data to dictionary
+ * @param {ccs.BoneData} boneData
+ */
+ addBoneData:function (boneData) {
+ this.boneDataDic[boneData.name] = boneData;
+ },
+
+ /**
+ * Gets bone data dictionary
+ * @returns {Object}
+ */
+ getBoneDataDic:function () {
+ return this.boneDataDic;
+ },
+ /**
+ * Gets bone data by bone name
+ * @function
+ * @param {String} boneName
+ * @returns {ccs.BoneData}
+ */
+ getBoneData:function (boneName) {
+ return this.boneDataDic[boneName];
+ }
+});
+
+/**
+ * FrameData saved the frame data needed for armature animation in this Armature.
+ * @class ccs.FrameData
+ * @extends ccs.BaseData
+ *
+ * @property {Number} duration - the duration of frame
+ * @property {Number} tweenEasing - the easing type of frame
+ * @property {Number} easingParamNumber - the count of easing parameters.
+ * @property {Object} easingParams - the dictionary of easing parameters.
+ * @property {Number} displayIndex - the display renderer index.
+ * @property {String} movement - the movement name.
+ * @property {String} event - the event name
+ * @property {String} sound - the sound path.
+ * @property {String} soundEffect - the sound effect path.
+ * @property {Object} blendFunc - the blendFunc of frame.
+ * @property {Number} frameID - the frame ID of frame
+ * @property {Boolean} isTween - the flag which frame whether is tween.
+ */
+ccs.FrameData = ccs.BaseData.extend(/** @lends ccs.FrameData# */{
+ duration:0,
+ tweenEasing:0,
+ easingParamNumber: 0,
+ easingParams: null,
+ displayIndex:-1,
+ movement:"",
+ event:"",
+ sound:"",
+ soundEffect:"",
+ blendFunc:null,
+ frameID:0,
+ isTween:true,
+
+ /**
+ * Construction of ccs.FrameData.
+ */
+ ctor:function () {
+ ccs.BaseData.prototype.ctor.call(this);
+ this.duration = 1;
+ this.tweenEasing = ccs.TweenType.LINEAR;
+ this.easingParamNumber = 0;
+ this.easingParams = [];
+ this.displayIndex = 0;
+ this.movement = "";
+ this.event = "";
+ this.sound = "";
+ this.soundEffect = "";
+ this.blendFunc = new cc.BlendFunc(cc.BLEND_SRC, cc.BLEND_DST);
+ this.frameID = 0;
+ this.isTween = true;
+ },
+
+ /**
+ * copy data
+ * @function
+ * @param frameData
+ */
+ copy:function (frameData) {
+ ccs.BaseData.prototype.copy.call(this, frameData);
+ this.duration = frameData.duration;
+ this.displayIndex = frameData.displayIndex;
+
+ this.tweenEasing = frameData.tweenEasing;
+ this.easingParamNumber = frameData.easingParamNumber;
+
+// this.movement = frameData.movement;
+// this.event = frameData.event;
+// this.sound = frameData.sound;
+// this.soundEffect = frameData.soundEffect;
+// this.easingParams.length = 0;
+ if (this.easingParamNumber !== 0){
+ this.easingParams.length = 0;
+ for (var i = 0; i
+ * The animation data information of Cocos Armature. It include all movement information for the Armature.
+ * The struct is AnimationData -> MovementData -> MovementBoneData -> FrameData
+ * -> MovementFrameData
+ *
+ * @class ccs.AnimationData
+ * @extends ccs.Class
+ */
+ccs.AnimationData = function(){
+ this.movementDataDic = {};
+ this.movementNames = [];
+ this.name = "";
+};
+
+/**
+ * adds movement data to the movement data dictionary
+ * @param {ccs.MovementData} moveData
+ */
+ccs.AnimationData.prototype.addMovement = function(moveData){
+ this.movementDataDic[moveData.name] = moveData;
+ this.movementNames.push(moveData.name);
+};
+
+/**
+ * gets movement data from movement data dictionary
+ * @param {String} moveName
+ * @returns {ccs.MovementData}
+ */
+ccs.AnimationData.prototype.getMovement = function(moveName){
+ return this.movementDataDic[moveName];
+};
+
+/**
+ * gets the count of movement data dictionary
+ * @returns {Number}
+ */
+ccs.AnimationData.prototype.getMovementCount = function(){
+ return Object.keys(this.movementDataDic).length;
+};
+
+/**
+ * contour vertex
+ * @class ccs.ContourVertex2
+ * @param {Number} x
+ * @param {Number} y
+ * @constructor
+ */
+ccs.ContourVertex2 = function (x, y) {
+ this.x = x || 0;
+ this.y = y || 0;
+};
+
+/**
+ * The Contour data information of Cocos Armature.
+ * @class ccs.ContourData
+ * @constructor
+ */
+ccs.ContourData = function(){
+ this.vertexList = [];
+};
+
+ccs.ContourData.prototype.init = function(){
+ this.vertexList.length = 0;
+ return true;
+};
+
+/**
+ * add a vertex object to vertex list
+ * @param {cc.Point} p
+ */
+ccs.ContourData.prototype.addVertex = function(p){
+ //var v = new ccs.ContourVertex2(p.x, p.y); //ccs.ContourVertex2 is same as cc.Point, so we needn't create a ccs.ContourVertex2 object
+ this.vertexList.push(p);
+};
+
+/**
+ * The texture data information of Cocos Armature
+ * @class ccs.TextureData
+ */
+ccs.TextureData = function(){
+ this.height = 0;
+ this.width = 0;
+ this.pivotX = 0.5;
+ this.pivotY = 0.5;
+ this.name = "";
+ this.contourDataList = [];
+};
+
+ccs.TextureData.prototype.init = function(){
+ this.contourDataList.length = 0;
+};
+
+/**
+ * Adds a contourData to contourDataList
+ * @param {ccs.ContourData} contourData
+ */
+ccs.TextureData.prototype.addContourData = function(contourData){
+ this.contourDataList.push(contourData);
+};
+
+/**
+ * gets a contourData from contourDataList by index
+ * @param {Number} index
+ * @returns {ccs.ContourData}
+ */
+ccs.TextureData.prototype.getContourData = function(index){
+ return this.contourDataList[index];
+};
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCBatchNode.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCBatchNode.js
new file mode 100644
index 0000000..f20c238
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCBatchNode.js
@@ -0,0 +1,114 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * A batchNode to Armature
+ * @class ccs.BatchNode
+ * @extends cc.Node
+ */
+ccs.BatchNode = cc.Node.extend(/** @lends ccs.BatchNode# */{
+ _atlas:null,
+ _className:"BatchNode",
+
+ ctor:function () {
+ this._atlas = null;
+
+ ccs.BatchNode.prototype.init.call(this);
+ },
+
+ init:function () {
+ var ret = cc.Node.prototype.init.call(this);
+ this.setShaderProgram(cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE_UCOLOR));
+ return ret;
+ },
+
+ addChild:function (child, zOrder, tag) {
+ cc.Node.prototype.addChild.call(this, child, zOrder, tag);
+ if (child instanceof cc.Armature){
+ child.setBatchNode(this);
+ }
+ },
+
+ removeChild: function(child, cleanup){
+ if (child instanceof cc.Armature)
+ child.setBatchNode(null);
+ cc.Node.prototype.removeChild.call(this, child, cleanup);
+ },
+
+ visit:function (renderer, parentTransform, parentTransformUpdated) {
+ // quick return if not visible. children won't be drawn.
+ if (!this._visible)
+ return;
+
+ var dirty = parentTransformUpdated || this._transformUpdated;
+ if(dirty)
+ this._modelViewTransform = this.transform(parentTransform);
+ this._transformUpdated = false;
+
+ // IMPORTANT:
+ // To ease the migration to v3.0, we still support the kmGL stack,
+ // but it is deprecated and your code should not rely on it
+ cc.kmGLPushMatrixWitMat4(this._stackMatrix);
+
+ if (this.grid && this.grid.isActive())
+ this.grid.beforeDraw();
+
+ this.sortAllChildren();
+ this.draw(renderer, this._modelViewTransform, dirty);
+
+ if (this.grid && this.grid.isActive())
+ this.grid.afterDraw(this);
+
+ cc.kmGLPopMatrix();
+ },
+
+ draw:function (renderer, transform, transformUpdated) {
+ var locChildren = this._children;
+ if(locChildren.length === 0)
+ return;
+
+ var child = null;
+ for (var i = 0, len = locChildren.length; i < len; i++) {
+ child = locChildren[i];
+ child.visit();
+ if (child instanceof cc.Armature) {
+ this._atlas = child.getTextureAtlas();
+ }
+ }
+ if (this._atlas) {
+ this._atlas.drawQuads();
+ this._atlas.removeAllQuads();
+ }
+ }
+});
+
+/**
+ *
+ * @returns {ccs.BatchNode}
+ * @deprecated since v3.1, please use new construction instead
+ */
+ccs.BatchNode.create = function () {
+ return new ccs.BatchNode();
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCDecorativeDisplay.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCDecorativeDisplay.js
new file mode 100644
index 0000000..f7a7c3d
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCDecorativeDisplay.js
@@ -0,0 +1,118 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Decorative a display node for Cocos Armature
+ * @class
+ * @extends ccs.Class
+ */
+ccs.DecorativeDisplay = ccs.Class.extend(/** @lends ccs.DecorativeDisplay# */{
+ _display: null,
+ _colliderDetector: null,
+ _displayData: null,
+
+ ctor:function () {
+ this._display = null;
+ this._colliderDetector = null;
+ this._displayData = null;
+
+ //ccs.DecorativeDisplay.prototype.init.call(this);
+ },
+
+ /**
+ * Initializes a ccs.DecorativeDisplay
+ * @returns {boolean}
+ */
+ init:function () {
+ return true;
+ },
+
+ /**
+ * Sets display node to decorative
+ * @param {cc.Node} display
+ */
+ setDisplay:function (display) {
+ if(display._parent){
+ display._parent.removeChild(display);
+ delete display._parent;
+ }
+ this._display = display;
+ },
+
+ /**
+ * Returns the display node
+ * @returns {cc.Node}
+ */
+ getDisplay:function () {
+ return this._display;
+ },
+
+ /**
+ * Sets collide detector
+ * @param {ccs.ColliderDetector} colliderDetector
+ */
+ setColliderDetector:function (colliderDetector) {
+ this._colliderDetector = colliderDetector;
+ },
+
+ /**
+ * Returns collide detector
+ * @returns {ccs.ColliderDetector}
+ */
+ getColliderDetector:function () {
+ return this._colliderDetector;
+ },
+
+ /**
+ * Sets display data
+ * @param {ccs.DisplayData} displayData
+ */
+ setDisplayData:function (displayData) {
+ this._displayData = displayData;
+ },
+
+ /**
+ * Returns display data
+ * @returns {ccs.DisplayData}
+ */
+ getDisplayData:function () {
+ return this._displayData;
+ },
+
+ release:function () {
+ this._display = null;
+ this._displayData = null;
+ this._colliderDetector = null;
+ }
+});
+
+/**
+ * Allocates and initializes a decorative display.
+ * @return {ccs.DecorativeDisplay}
+ * @deprecated since v3.1, please use new construction instead
+ */
+ccs.DecorativeDisplay.create = function () {
+ return new ccs.DecorativeDisplay();
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCDisplayFactory.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCDisplayFactory.js
new file mode 100644
index 0000000..772bade
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCDisplayFactory.js
@@ -0,0 +1,219 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * @ignore
+ */
+ccs.displayFactory = {
+ addDisplay: function (bone, decoDisplay, displayData) {
+ switch (displayData.displayType) {
+ case ccs.DISPLAY_TYPE_SPRITE:
+ this.addSpriteDisplay(bone, decoDisplay, displayData);
+ break;
+ case ccs.DISPLAY_TYPE_PARTICLE:
+ this.addParticleDisplay(bone, decoDisplay, displayData);
+ break;
+ case ccs.DISPLAY_TYPE_ARMATURE:
+ this.addArmatureDisplay(bone, decoDisplay, displayData);
+ break;
+ default:
+ break;
+ }
+ },
+
+ createDisplay: function (bone, decoDisplay) {
+ switch (decoDisplay.getDisplayData().displayType) {
+ case ccs.DISPLAY_TYPE_SPRITE:
+ this.createSpriteDisplay(bone, decoDisplay);
+ break;
+ case ccs.DISPLAY_TYPE_PARTICLE:
+ this.createParticleDisplay(bone, decoDisplay);
+ break;
+ case ccs.DISPLAY_TYPE_ARMATURE:
+ this.createArmatureDisplay(bone, decoDisplay);
+ break;
+ default:
+ break;
+ }
+ },
+
+ _helpTransform: {a:1, b:0, c:0, d:1, tx:0, ty:0},
+ updateDisplay: function (bone, dt, dirty) {
+ var display = bone.getDisplayRenderNode();
+ if(!display)
+ return;
+
+ switch (bone.getDisplayRenderNodeType()) {
+ case ccs.DISPLAY_TYPE_SPRITE:
+ if (dirty) {
+ display._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ display.updateArmatureTransform();
+ }
+ break;
+ case ccs.DISPLAY_TYPE_PARTICLE:
+ this.updateParticleDisplay(bone, display, dt);
+ break;
+ case ccs.DISPLAY_TYPE_ARMATURE:
+ this.updateArmatureDisplay(bone, display, dt);
+ break;
+ default:
+ var transform = bone.getNodeToArmatureTransform();
+ display.setAdditionalTransform(transform);
+ break;
+ }
+ if (ccs.ENABLE_PHYSICS_CHIPMUNK_DETECT || ccs.ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX) {
+ if (dirty) {
+ var decoDisplay = bone.getDisplayManager().getCurrentDecorativeDisplay();
+ var detector = decoDisplay.getColliderDetector();
+ if (detector) {
+ var node = decoDisplay.getDisplay();
+ var displayTransform = node.getNodeToParentTransform();
+ var helpTransform = this._helpTransform;
+ helpTransform.a = displayTransform.a;
+ helpTransform.b = displayTransform.b;
+ helpTransform.c = displayTransform.c;
+ helpTransform.d = displayTransform.d;
+ helpTransform.tx = displayTransform.tx;
+ helpTransform.ty = displayTransform.ty;
+ var anchorPoint = cc.pointApplyAffineTransform(node.getAnchorPointInPoints(), helpTransform);
+ helpTransform.tx = anchorPoint.x;
+ helpTransform.ty = anchorPoint.y;
+ var t = cc.affineTransformConcat(helpTransform, bone.getArmature().getNodeToParentTransform());
+ detector.updateTransform(t);
+ }
+ }
+ }
+ },
+
+ addSpriteDisplay: function (bone, decoDisplay, displayData) {
+ var sdp = new ccs.SpriteDisplayData();
+ sdp.copy(displayData);
+ decoDisplay.setDisplayData(sdp);
+ this.createSpriteDisplay(bone, decoDisplay);
+ },
+
+ createSpriteDisplay: function (bone, decoDisplay) {
+ var skin = null;
+ var displayData = decoDisplay.getDisplayData();
+ //! remove .xxx
+ var textureName = displayData.displayName;
+ var startPos = textureName.lastIndexOf(".");
+ if (startPos !== -1)
+ textureName = textureName.substring(0, startPos);
+ //! create display
+ if (textureName === "")
+ skin = new ccs.Skin();
+ else
+ skin = new ccs.Skin("#" + textureName + ".png");
+
+ decoDisplay.setDisplay(skin);
+
+ skin.setBone(bone);
+ this.initSpriteDisplay(bone, decoDisplay, displayData.displayName, skin);
+
+ var armature = bone.getArmature();
+ if (armature) {
+ if (armature.getArmatureData().dataVersion >= ccs.CONST_VERSION_COMBINED)
+ skin.setSkinData(displayData.skinData);
+ else
+ skin.setSkinData(bone.boneData);
+ }
+ },
+
+ initSpriteDisplay: function (bone, decoDisplay, displayName, skin) {
+ //! remove .xxx
+ var textureName = displayName;
+ var startPos = textureName.lastIndexOf(".");
+
+ if (startPos !== -1)
+ textureName = textureName.substring(0, startPos);
+
+ var textureData = ccs.armatureDataManager.getTextureData(textureName);
+ if (textureData) {
+ //! Init display anchorPoint, every Texture have a anchor point
+ skin.setAnchorPoint(cc.p(textureData.pivotX, textureData.pivotY));
+ }
+
+ if (ccs.ENABLE_PHYSICS_CHIPMUNK_DETECT || ccs.ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX) {
+ if (textureData && textureData.contourDataList.length > 0) {
+ //! create ContourSprite
+ var colliderDetector = new ccs.ColliderDetector(bone);
+ colliderDetector.addContourDataList(textureData.contourDataList);
+ decoDisplay.setColliderDetector(colliderDetector);
+ }
+ }
+ },
+
+ addArmatureDisplay: function (bone, decoDisplay, displayData) {
+ var adp = new ccs.ArmatureDisplayData();
+ adp.copy(displayData);
+ decoDisplay.setDisplayData(adp);
+
+ this.createArmatureDisplay(bone, decoDisplay);
+ },
+
+ createArmatureDisplay: function (bone, decoDisplay) {
+ var displayData = decoDisplay.getDisplayData();
+ var armature = new ccs.Armature(displayData.displayName, bone);
+ decoDisplay.setDisplay(armature);
+ },
+
+ updateArmatureDisplay: function (bone, armature, dt) {
+ if (armature) {
+ armature.sortAllChildren();
+ armature.update(dt);
+ }
+ },
+
+ addParticleDisplay: function (bone, decoDisplay, displayData) {
+ var adp = new ccs.ParticleDisplayData();
+ adp.copy(displayData);
+ decoDisplay.setDisplayData(adp);
+ this.createParticleDisplay(bone, decoDisplay);
+ },
+
+ createParticleDisplay: function (bone, decoDisplay) {
+ var displayData = decoDisplay.getDisplayData();
+ var system = new cc.ParticleSystem(displayData.displayName);
+
+ system.removeFromParent();
+ system.cleanup();
+
+ var armature = bone.getArmature();
+ if (armature)
+ system.setParent(bone.getArmature());
+
+ decoDisplay.setDisplay(system);
+ },
+
+ updateParticleDisplay: function (bone, particleSystem, dt) {
+ var node = new ccs.BaseData();
+ ccs.TransformHelp.matrixToNode(bone.nodeToArmatureTransform(), node);
+ particleSystem.setPosition(node.x, node.y);
+ particleSystem.setScaleX(node.scaleX);
+ particleSystem.setScaleY(node.scaleY);
+ particleSystem.update(dt);
+ }
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCDisplayManager.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCDisplayManager.js
new file mode 100644
index 0000000..584f864
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCDisplayManager.js
@@ -0,0 +1,465 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The display manager for CocoStudio Armature bone.
+ * @Class ccs.DisplayManager
+ * @extend cc.Class
+ *
+ * @param {ccs.Bone} bone The bone for the display manager
+ */
+ccs.DisplayManager = ccs.Class.extend(/** @lends ccs.DisplayManager */{
+ _decoDisplayList: null,
+ _currentDecoDisplay: null,
+ _displayRenderNode: null,
+ _displayIndex: null,
+ _forceChangeDisplay: false,
+ _bone: null,
+ _visible: true,
+ _displayType: null,
+
+ ctor: function (bone) {
+ this._decoDisplayList = [];
+ this._currentDecoDisplay = null;
+ this._displayRenderNode = null;
+ this._displayIndex = null;
+ this._forceChangeDisplay = false;
+ this._bone = null;
+ this._visible = true;
+ this._displayType = ccs.DISPLAY_TYPE_MAX;
+
+ bone && ccs.DisplayManager.prototype.init.call(this, bone);
+ },
+
+ /**
+ * Initializes a ccs.DisplayManager.
+ * @param bone
+ * @returns {boolean}
+ */
+ init: function (bone) {
+ this._bone = bone;
+ this.initDisplayList(bone.getBoneData());
+ return true;
+ },
+
+ /**
+ *
+ * Add display and use _DisplayData init the display.
+ * If index already have a display, then replace it.
+ * If index is current display index, then also change display to _index
+ *
+ * @param {ccs.DisplayData|cc.Node} display it include the display information, like DisplayType. If you want to create a sprite display, then create a SpriteDisplayData param
+ * @param {Number} index the index of the display you want to replace or add to. -1 : append display from back
+ */
+ addDisplay: function (display, index) {
+ var decoDisplay, locDisplayList = this._decoDisplayList;
+ if ((index >= 0) && (index < locDisplayList.length))
+ decoDisplay = locDisplayList[index];
+ else {
+ decoDisplay = new ccs.DecorativeDisplay();
+ locDisplayList.push(decoDisplay);
+ }
+
+ if (display instanceof ccs.DisplayData) {
+ ccs.displayFactory.addDisplay(this._bone, decoDisplay, display);
+ //! if changed display index is current display index, then change current display to the new display
+ if (index === this._displayIndex) {
+ this._displayIndex = -1;
+ this.changeDisplayWithIndex(index, false);
+ }
+ return;
+ }
+
+ var displayData = null;
+ if (display instanceof ccs.Skin) {
+ display.setBone(this._bone);
+ displayData = new ccs.SpriteDisplayData();
+ ccs.displayFactory.initSpriteDisplay(this._bone, decoDisplay, display.getDisplayName(), display);
+
+ var spriteDisplayData = decoDisplay.getDisplayData();
+ if (spriteDisplayData instanceof ccs.SpriteDisplayData) {
+ display.setSkinData(spriteDisplayData.skinData);
+ displayData.skinData = spriteDisplayData.skinData;
+ } else {
+ var find = false;
+ for (var i = locDisplayList.length - 2; i >= 0; i--) {
+ var dd = locDisplayList[i];
+ var sdd = dd.getDisplayData();
+ if (sdd instanceof ccs.SpriteDisplayData) {
+ find = true;
+ display.setSkinData(sdd.skinData);
+ displayData.skinData = sdd.skinData;
+ break;
+ }
+ }
+ if (!find)
+ display.setSkinData(new ccs.BaseData());
+ }
+ } else if (display instanceof cc.ParticleSystem) {
+ displayData = new ccs.ParticleDisplayData();
+ display.removeFromParent();
+ display._performRecursive(cc.Node._stateCallbackType.cleanup);
+ var armature = this._bone.getArmature();
+ if (armature)
+ display.setParent(armature);
+ } else if (display instanceof ccs.Armature) {
+ displayData = new ccs.ArmatureDisplayData();
+ displayData.displayName = display.getName();
+ display.setParentBone(this._bone);
+ } else
+ displayData = new ccs.DisplayData();
+ decoDisplay.setDisplay(display);
+ decoDisplay.setDisplayData(displayData);
+
+ //! if changed display index is current display index, then change current display to the new display
+ if (index === this._displayIndex) {
+ this._displayIndex = -1;
+ this.changeDisplayWithIndex(index, false);
+ }
+ },
+
+ _addDisplayOther: function (decoDisplay, display) {
+ var displayData = null;
+ if (display instanceof ccs.Skin) {
+ var skin = display;
+ skin.setBone(this._bone);
+ displayData = new ccs.SpriteDisplayData();
+ displayData.displayName = skin.getDisplayName();
+ ccs.displayFactory.initSpriteDisplay(this._bone, decoDisplay, skin.getDisplayName(), skin);
+ var spriteDisplayData = decoDisplay.getDisplayData();
+ if (spriteDisplayData instanceof ccs.SpriteDisplayData)
+ skin.setSkinData(spriteDisplayData.skinData);
+ else {
+ var find = false;
+ for (var i = this._decoDisplayList.length - 2; i >= 0; i--) {
+ var dd = this._decoDisplayList[i];
+ var sdd = dd.getDisplayData();
+ if (sdd) {
+ find = true;
+ skin.setSkinData(sdd.skinData);
+ displayData.skinData = sdd.skinData;
+ break;
+ }
+ }
+ if (!find) {
+ skin.setSkinData(new ccs.BaseData());
+ }
+ skin.setSkinData(new ccs.BaseData());
+ }
+
+ }
+ else if (display instanceof cc.ParticleSystem) {
+ displayData = new ccs.ParticleDisplayData();
+ displayData.displayName = display._plistFile;
+ }
+ else if (display instanceof ccs.Armature) {
+ displayData = new ccs.ArmatureDisplayData();
+ displayData.displayName = display.getName();
+ display.setParentBone(this._bone);
+ }
+ else {
+ displayData = new ccs.DisplayData();
+ }
+ decoDisplay.setDisplay(display);
+ decoDisplay.setDisplayData(displayData);
+ },
+
+ /**
+ * Removes display node from list.
+ * @param {Number} index
+ */
+ removeDisplay: function (index) {
+ this._decoDisplayList.splice(index, 1);
+ if (index === this._displayIndex) {
+ this.setCurrentDecorativeDisplay(null);
+ this._displayIndex = -1;
+ }
+ },
+
+ /**
+ * Returns the display node list.
+ * @returns {Array}
+ */
+ getDecorativeDisplayList: function () {
+ return this._decoDisplayList;
+ },
+
+ /**
+ *
+ * Change display by index. You can just use this method to change display in the display list.
+ * The display list is just used for this bone, and it is the displays you may use in every frame.
+ * Note : if index is the same with prev index, the method will not effect
+ *
+ * @param {Number} index The index of the display you want to change
+ * @param {Boolean} force If true, then force change display to specified display, or current display will set to display index edit in the flash every key frame.
+ */
+ changeDisplayWithIndex: function (index, force) {
+ if (index >= this._decoDisplayList.length) {
+ cc.log("the index value is out of range");
+ return;
+ }
+ this._forceChangeDisplay = force;
+
+ //if index is equal to current display index,then do nothing
+ if (this._displayIndex === index)
+ return;
+
+ this._displayIndex = index;
+
+ //! If displayIndex < 0, it means you want to hide you display
+ if (index < 0) {
+ if (this._displayRenderNode) {
+ this._displayRenderNode.removeFromParent(true);
+ this.setCurrentDecorativeDisplay(null);
+ }
+ return;
+ }
+ this.setCurrentDecorativeDisplay(this._decoDisplayList[index]);
+ },
+
+ /**
+ * Change display by name. @see changeDisplayWithIndex.
+ * @param {String} name
+ * @param {Boolean} force
+ */
+ changeDisplayWithName: function (name, force) {
+ var locDisplayList = this._decoDisplayList;
+ for (var i = 0; i < locDisplayList.length; i++) {
+ if (locDisplayList[i].getDisplayData().displayName === name) {
+ this.changeDisplayWithIndex(i, force);
+ break;
+ }
+ }
+ },
+
+ /**
+ * Sets current decorative display.
+ * @param {ccs.DecorativeDisplay} decoDisplay
+ */
+ setCurrentDecorativeDisplay: function (decoDisplay) {
+ var locCurrentDecoDisplay = this._currentDecoDisplay;
+ if (ccs.ENABLE_PHYSICS_CHIPMUNK_DETECT || ccs.ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX) {
+ if (locCurrentDecoDisplay && locCurrentDecoDisplay.getColliderDetector())
+ locCurrentDecoDisplay.getColliderDetector().setActive(false);
+ }
+
+ this._currentDecoDisplay = decoDisplay;
+ locCurrentDecoDisplay = this._currentDecoDisplay;
+ if (ccs.ENABLE_PHYSICS_CHIPMUNK_DETECT || ccs.ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX) {
+ if (locCurrentDecoDisplay && locCurrentDecoDisplay.getColliderDetector())
+ locCurrentDecoDisplay.getColliderDetector().setActive(true);
+ }
+
+ var displayRenderNode = (!locCurrentDecoDisplay) ? null : locCurrentDecoDisplay.getDisplay();
+
+ var locRenderNode = this._displayRenderNode, locBone = this._bone;
+ if (locRenderNode) {
+ if (locRenderNode instanceof ccs.Armature)
+ locBone.setChildArmature(null);
+ locRenderNode.removeFromParent(true);
+ }
+ this._displayRenderNode = displayRenderNode;
+
+ if (displayRenderNode) {
+ if (displayRenderNode instanceof ccs.Armature) {
+ this._bone.setChildArmature(displayRenderNode);
+ displayRenderNode.setParentBone(this._bone);
+ } else if (displayRenderNode instanceof cc.ParticleSystem) {
+ if (displayRenderNode instanceof ccs.Armature) {
+ locBone.setChildArmature(displayRenderNode);
+ displayRenderNode.setParentBone(locBone);
+ } else if (displayRenderNode instanceof cc.ParticleSystem)
+ displayRenderNode.resetSystem();
+ }
+
+ displayRenderNode.setColor(locBone.getDisplayedColor());
+ displayRenderNode.setOpacity(locBone.getDisplayedOpacity());
+
+ this._displayRenderNode.setVisible(this._visible);
+ this._displayType = this._currentDecoDisplay.getDisplayData().displayType;
+ } else
+ this._displayType = ccs.DISPLAY_TYPE_MAX;
+
+
+ cc.renderer.childrenOrderDirty = true;
+ },
+
+ /**
+ * Returns the current display render node.
+ * @returns {cc.Node}
+ */
+ getDisplayRenderNode: function () {
+ return this._displayRenderNode;
+ },
+
+ /**
+ * Returns the type of display render node.
+ * @returns {Number}
+ */
+ getDisplayRenderNodeType: function () {
+ return this._displayType;
+ },
+
+ /**
+ * Returns the index of display render node.
+ * @returns {Number}
+ */
+ getCurrentDisplayIndex: function () {
+ return this._displayIndex;
+ },
+
+ /**
+ * Returns the current decorative display
+ * @returns {ccs.DecorativeDisplay}
+ */
+ getCurrentDecorativeDisplay: function () {
+ return this._currentDecoDisplay;
+ },
+
+ /**
+ * Gets a decorative display by index.
+ * @param index
+ * @returns {ccs.DecorativeDisplay}
+ */
+ getDecorativeDisplayByIndex: function (index) {
+ return this._decoDisplayList[index];
+ },
+
+ /**
+ *
+ * Use BoneData to init the display list.
+ * If display is a sprite, and it have texture info in the TextureData, then use TextureData to init the display node's anchor point
+ * If the display is a Armature, then create a new Armature
+ *
+ * @param {ccs.BoneData} boneData
+ */
+ initDisplayList: function (boneData) {
+ this._decoDisplayList.length = 0;
+ if (!boneData)
+ return;
+ var displayList = boneData.displayDataList, decoList = this._decoDisplayList, locBone = this._bone;
+ for (var i = 0; i < displayList.length; i++) {
+ var displayData = displayList[i];
+ var decoDisplay = new ccs.DecorativeDisplay();
+ decoDisplay.setDisplayData(displayData);
+ ccs.displayFactory.createDisplay(locBone, decoDisplay);
+ decoList.push(decoDisplay);
+ }
+ },
+
+ /**
+ * Check if the position is inside the bone.
+ * @param {cc.Point|Number} point
+ * @param {Number} [y]
+ * @returns {boolean}
+ */
+ containPoint: function (point, y) {
+ if (!this._visible || this._displayIndex < 0)
+ return false;
+
+ if (y !== undefined)
+ point = cc.p(point, y);
+
+ if (this._currentDecoDisplay.getDisplayData().displayType === ccs.DISPLAY_TYPE_SPRITE) {
+ /*
+ * First we first check if the point is in the sprite content rect. If false, then we continue to check
+ * the contour point. If this step is also false, then we can say the bone not contain this point.
+ *
+ */
+ var sprite = this._currentDecoDisplay.getDisplay();
+ sprite = sprite.getChildByTag(0);
+ return ccs.SPRITE_CONTAIN_POINT_WITH_RETURN(sprite, point);
+ }
+ return false;
+ },
+
+ /**
+ *
+ * Sets whether the display is visible
+ * The default value is true, a node is default to visible
+ *
+ * @param {boolean} visible
+ */
+ setVisible: function (visible) {
+ if (!this._displayRenderNode)
+ return;
+ this._visible = visible;
+ this._displayRenderNode.setVisible(visible);
+ },
+
+ /**
+ * Determines if the display is visible
+ * @returns {boolean} true if the node is visible, false if the node is hidden.
+ */
+ isVisible: function () {
+ return this._visible;
+ },
+
+ getContentSize: function () {
+ if (!this._displayRenderNode)
+ return cc.size(0, 0);
+ return this._displayRenderNode.getContentSize();
+ },
+
+ getBoundingBox: function () {
+ if (!this._displayRenderNode)
+ return cc.rect(0, 0, 0, 0);
+ return this._displayRenderNode.getBoundingBox();
+ },
+
+ getAnchorPoint: function () {
+ if (!this._displayRenderNode)
+ return cc.p(0, 0);
+ return this._displayRenderNode.getAnchorPoint();
+ },
+
+ getAnchorPointInPoints: function () {
+ if (!this._displayRenderNode)
+ return cc.p(0, 0);
+ return this._displayRenderNode.getAnchorPointInPoints();
+ },
+
+ getForceChangeDisplay: function () {
+ return this._forceChangeDisplay;
+ },
+
+ release: function () {
+ this._decoDisplayList = null;
+ if (this._displayRenderNode) {
+ this._displayRenderNode.removeFromParent(true);
+ this._displayRenderNode = null;
+ }
+ }
+});
+
+/**
+ * Allocates and initializes a display manager with ccs.Bone.
+ * @param {ccs.Bone} bone
+ * @returns {ccs.DisplayManager}
+ * @deprecated since v3.1, please use new construction instead
+ */
+ccs.DisplayManager.create = function (bone) {
+ return new ccs.DisplayManager(bone);
+};
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCSkin.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCSkin.js
new file mode 100644
index 0000000..9f75ceb
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCSkin.js
@@ -0,0 +1,207 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * ccs.Bone uses ccs.Skin to displays on screen.
+ * @class
+ * @extends ccs.Sprite
+ *
+ * @param {String} [fileName]
+ * @param {cc.Rect} [rect]
+ *
+ * @property {Object} skinData - The data of the skin
+ * @property {ccs.Bone} bone - The bone of the skin
+ * @property {String} displayName - <@readonly> The displayed name of skin
+ *
+ */
+ccs.Skin = ccs.Sprite.extend(/** @lends ccs.Skin# */{
+ _skinData: null,
+ bone: null,
+ _skinTransform: null,
+ _displayName: "",
+ _armature: null,
+ _className: "Skin",
+
+ ctor: function (fileName, rect) {
+ cc.Sprite.prototype.ctor.call(this);
+ this._skinData = null;
+ this.bone = null;
+ this._displayName = "";
+ this._skinTransform = cc.affineTransformIdentity();
+ this._armature = null;
+
+ if (fileName == null || fileName === "") {
+ ccs.Skin.prototype.init.call(this);
+ } else {
+ if(fileName[0] === "#"){
+ ccs.Skin.prototype.initWithSpriteFrameName.call(this, fileName.substr(1));
+ } else {
+ ccs.Skin.prototype.initWithFile.call(this, fileName, rect);
+ }
+ }
+ },
+
+ /**
+ * Initializes with sprite frame name
+ * @param {String} spriteFrameName
+ * @returns {Boolean}
+ */
+ initWithSpriteFrameName: function (spriteFrameName) {
+ if(spriteFrameName === "")
+ return false;
+ var pFrame = cc.spriteFrameCache.getSpriteFrame(spriteFrameName);
+ var ret = true;
+ if(pFrame)
+ this.initWithSpriteFrame(pFrame);
+ else{
+ cc.log("Can't find CCSpriteFrame with %s. Please check your .plist file", spriteFrameName);
+ ret = false;
+ }
+ this._displayName = spriteFrameName;
+ return ret;
+ },
+
+ /**
+ * Initializes with texture file name.
+ * @param {String} fileName
+ * @param {cc.Rect} rect
+ * @returns {Boolean}
+ */
+ initWithFile: function (fileName, rect) {
+ var ret = rect ? cc.Sprite.prototype.initWithFile.call(this, fileName, rect)
+ : cc.Sprite.prototype.initWithFile.call(this, fileName);
+ this._displayName = fileName;
+ return ret;
+ },
+
+ /**
+ * Sets skin data to ccs.Skin.
+ * @param {ccs.BaseData} skinData
+ */
+ setSkinData: function (skinData) {
+ this._skinData = skinData;
+ this.setScaleX(skinData.scaleX);
+ this.setScaleY(skinData.scaleY);
+ this.setRotationX(cc.radiansToDegrees(skinData.skewX));
+ this.setRotationY(cc.radiansToDegrees(-skinData.skewY));
+ this.setPosition(skinData.x, skinData.y);
+
+ this._renderCmd.transform();
+ },
+
+ /**
+ * Returns skin date of ccs.Skin.
+ * @returns {ccs.BaseData}
+ */
+ getSkinData: function () {
+ return this._skinData;
+ },
+
+ /**
+ * Updates armature skin's transform with skin transform and bone's transform.
+ */
+ updateArmatureTransform: function () {
+ this._renderCmd.transform();
+ },
+
+ /**
+ * Returns skin's world transform.
+ * @returns {cc.AffineTransform}
+ */
+ getNodeToWorldTransform: function(){
+ return this._renderCmd.getNodeToWorldTransform();
+ },
+
+ getNodeToWorldTransformAR: function(){
+ return this._renderCmd.getNodeToWorldTransformAR();
+ },
+
+ /**
+ * Sets the bone reference to ccs.Skin.
+ * @param bone
+ */
+ setBone: function (bone) {
+ this.bone = bone;
+ var armature = this.bone.getArmature();
+ if(armature)
+ this._armature = armature;
+ },
+
+ /**
+ * Returns the bone reference of ccs.Skin.
+ * @returns {null}
+ */
+ getBone: function () {
+ return this.bone;
+ },
+
+ /**
+ * display name getter
+ * @returns {String}
+ */
+ getDisplayName: function () {
+ return this._displayName;
+ },
+
+ _createRenderCmd: function(){
+ if(cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new ccs.Skin.CanvasRenderCmd(this);
+ else
+ return new ccs.Skin.WebGLRenderCmd(this);
+ }
+});
+
+var _p = ccs.Skin.prototype;
+
+// Extended properties
+/** @expose */
+_p.skinData;
+cc.defineGetterSetter(_p, "skinData", _p.getSkinData, _p.setSkinData);
+/** @expose */
+_p.displayName;
+cc.defineGetterSetter(_p, "displayName", _p.getDisplayName);
+
+_p = null;
+
+/**
+ * allocates and initializes a skin.
+ * @param {String} [fileName] fileName or sprite frame name
+ * @param {cc.Rect} [rect]
+ * @returns {ccs.Skin}
+ * @deprecated since v3.1, please use new construction instead
+ */
+ccs.Skin.create = function (fileName, rect) {
+ return new ccs.Skin(fileName, rect);
+};
+
+/**
+ * allocates and initializes a skin.
+ * @param {String} spriteFrameName
+ * @returns {ccs.Skin}
+ * @deprecated since v3.1, please use new construction instead
+ */
+ccs.Skin.createWithSpriteFrameName = function (spriteFrameName) {
+ return new ccs.Skin("#" + spriteFrameName);
+};
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCSkinRenderCmd.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCSkinRenderCmd.js
new file mode 100644
index 0000000..eabcd02
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/display/CCSkinRenderCmd.js
@@ -0,0 +1,126 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ ccs.Skin.RenderCmd = {
+ _realWorldTM: null,
+ transform: function (parentCmd, recursive) {
+ if (!this._transform) {
+ this._transform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ this._worldTransform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ }
+
+ var node = this._node,
+ pt = parentCmd ? parentCmd._worldTransform : null,
+ t = this._transform,
+ wt = this._worldTransform,
+ dirty = this._dirtyFlag & cc.Node._dirtyFlags.transformDirty;
+
+ if (dirty || pt) {
+ this.originTransform();
+ cc.affineTransformConcatIn(this._transform, node.bone.getNodeToArmatureTransform());
+ this._dirtyFlag &= ~cc.Node._dirtyFlags.transformDirty;
+ }
+
+ if (pt) {
+ wt.a = t.a * pt.a + t.b * pt.c;
+ wt.b = t.a * pt.b + t.b * pt.d;
+ wt.c = t.c * pt.a + t.d * pt.c;
+ wt.d = t.c * pt.b + t.d * pt.d;
+ wt.tx = t.tx * pt.a + t.ty * pt.c + pt.tx;
+ wt.ty = t.tx * pt.b + t.ty * pt.d + pt.ty;
+
+ var vertices = this._vertices;
+ if (vertices) {
+ var lx = node._offsetPosition.x, rx = lx + node._rect.width,
+ by = node._offsetPosition.y, ty = by + node._rect.height;
+
+ vertices[0].x = lx * wt.a + ty * wt.c + wt.tx; // tl
+ vertices[0].y = lx * wt.b + ty * wt.d + wt.ty;
+ vertices[1].x = lx * wt.a + by * wt.c + wt.tx; // bl
+ vertices[1].y = lx * wt.b + by * wt.d + wt.ty;
+ vertices[2].x = rx * wt.a + ty * wt.c + wt.tx; // tr
+ vertices[2].y = rx * wt.b + ty * wt.d + wt.ty;
+ vertices[3].x = rx * wt.a + by * wt.c + wt.tx; // br
+ vertices[3].y = rx * wt.b + by * wt.d + wt.ty;
+ }
+ }
+ else {
+ wt.a = t.a;
+ wt.b = t.b;
+ wt.c = t.c;
+ wt.d = t.d;
+ wt.tx = t.tx;
+ wt.ty = t.ty;
+ }
+ var rwtm = this._realWorldTM;
+ if (rwtm) {
+ rwtm.a = t.a; rwtm.b = t.b; rwtm.c = t.c; rwtm.d = t.d; rwtm.tx = t.tx; rwtm.ty = t.ty;
+ cc.affineTransformConcatIn(rwtm, this._node.bone.getArmature()._renderCmd._worldTransform);
+ }
+ },
+
+ getNodeToWorldTransform: function () {
+ return cc.affineTransformConcat(this._transform, this._node.bone.getArmature().getNodeToWorldTransform());
+ },
+
+ getNodeToWorldTransformAR: function () {
+ var displayTransform = this._transform, node = this._node;
+ this._anchorPointInPoints = cc.pointApplyAffineTransform(this._anchorPointInPoints, displayTransform);
+ displayTransform.tx = this._anchorPointInPoints.x;
+ displayTransform.ty = this._anchorPointInPoints.y;
+ return cc.affineTransformConcat(displayTransform, node.bone.getArmature().getNodeToWorldTransform());
+ }
+ };
+
+ ccs.Skin.CanvasRenderCmd = function (renderable) {
+ this._spriteCmdCtor(renderable);
+ this._realWorldTM = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
+ };
+
+ var proto = ccs.Skin.CanvasRenderCmd.prototype = Object.create(cc.Sprite.CanvasRenderCmd.prototype);
+ cc.inject(ccs.Skin.RenderCmd, proto);
+
+ proto.constructor = ccs.Skin.CanvasRenderCmd;
+
+ proto._updateCurrentRegions = function () {
+ var temp = this._currentRegion;
+ this._currentRegion = this._oldRegion;
+ this._oldRegion = temp;
+ //hittest will call the transform, and set region flag to DirtyDouble, and the changes need to be considered for rendering
+ if (cc.Node.CanvasRenderCmd.RegionStatus.DirtyDouble === this._regionFlag && (!this._currentRegion.isEmpty())) {
+ this._oldRegion.union(this._currentRegion);
+ }
+ this._currentRegion.updateRegion(this.getLocalBB(), this._realWorldTM);
+ };
+
+ ccs.Skin.WebGLRenderCmd = function (renderable) {
+ this._spriteCmdCtor(renderable);
+ };
+
+ proto = ccs.Skin.WebGLRenderCmd.prototype = Object.create(cc.Sprite.WebGLRenderCmd.prototype);
+ cc.inject(ccs.Skin.RenderCmd, proto);
+ proto.constructor = ccs.Skin.WebGLRenderCmd;
+})();
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/physics/CCColliderDetector.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/physics/CCColliderDetector.js
new file mode 100644
index 0000000..dccbe58
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/physics/CCColliderDetector.js
@@ -0,0 +1,397 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * @ignore
+ */
+ccs.PT_RATIO = 32;
+
+/**
+ * Base class for ccs.ColliderFilter
+ * @class
+ * @extends ccs.Class
+ */
+ccs.ColliderFilter = ccs.Class.extend(/** @lends ccs.ColliderFilter# */{
+ _collisionType: 0,
+ _group: 0,
+ _categoryBits: 0,
+ _groupIndex: 0,
+ _maskBits: 0,
+
+ ctor: function (collisionType, group) {
+ this._collisionType = collisionType || 0;
+ this._group = group || 0;
+ },
+
+ updateShape: function (shape) {
+ if(shape instanceof cp.Shape){
+ shape.collision_type = this._collisionType;
+ shape.group = this._group;
+ }else if(shape instanceof Box2D.b2FilterData){
+ var filter = new Box2D.b2FilterData();
+ filter.categoryBits = this._categoryBits;
+ filter.groupIndex = this._groupIndex;
+ filter.maskBits = this._maskBits;
+
+ shape.SetFilterData(filter);
+ }
+ }
+});
+
+/**
+ * Base class for ccs.ColliderBody
+ * @class
+ * @extends ccs.Class
+ *
+ * @property {ccs.ContourData} contourData - The contour data of collider body
+ * @property {ccs.Shape} shape - The shape of collider body
+ * @property {ccs.ColliderFilter} colliderFilter - The collider filter of collider body
+ *
+ */
+ccs.ColliderBody = ccs.Class.extend(/** @lends ccs.ColliderBody# */{
+ shape: null,
+ coutourData: null,
+ colliderFilter: null,
+ _calculatedVertexList: null,
+ ctor: function (contourData) {
+ this.shape = null;
+ this.coutourData = contourData;
+ this.colliderFilter = new ccs.ColliderFilter();
+ if (ccs.ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX) {
+ this._calculatedVertexList = [];
+ }
+ },
+
+ /**
+ * contourData getter
+ * @returns {ccs.ContourData}
+ */
+ getContourData: function () {
+ return this.coutourData;
+ },
+
+ /**
+ * colliderFilter setter
+ * @param {ccs.ColliderFilter} colliderFilter
+ */
+ setColliderFilter: function (colliderFilter) {
+ this.colliderFilter = colliderFilter;
+ },
+
+ /**
+ * get calculated vertex list
+ * @returns {Array}
+ */
+ getCalculatedVertexList: function () {
+ return this._calculatedVertexList;
+ },
+
+ setB2Fixture: function(fixture){
+ this._fixture = fixture;
+ },
+
+ getB2Fixture: function(){
+ return this._fixture;
+ },
+
+ /**
+ * shape getter
+ * @param {ccs.Shape} shape
+ */
+ setShape: function (shape) {
+ this.shape = shape;
+ },
+
+ /**
+ * shape setter
+ * @return {ccs.Shape}
+ */
+ getShape: function () {
+ return this.shape;
+ },
+
+ /**
+ * contourData setter
+ * @param {ccs.ContourData} contourData
+ */
+ setContourData: function (contourData) {
+ this.coutourData = contourData;
+ },
+
+ /**
+ * colliderFilter getter
+ * @returns {ccs.ColliderFilter}
+ */
+ getColliderFilter: function () {
+ return this.colliderFilter;
+ }
+});
+
+/**
+ * Base class for ccs.ColliderDetector
+ * @class
+ * @extends ccs.Class
+ *
+ * @param {ccs.Bone} [bone]
+ *
+ * @property {ccs.ColliderFilter} colliderFilter - The collider filter of the collider detector
+ * @property {Boolean} active - Indicate whether the collider detector is active
+ * @property {Object} body - The collider body
+ */
+ccs.ColliderDetector = ccs.Class.extend(/** @lends ccs.ColliderDetector# */{
+ _colliderBodyList: null,
+ _bone: null,
+ _body: null,
+ _active: false,
+ _filter: null,
+ helpPoint: cc.p(0, 0),
+
+ ctor: function (bone) {
+ this._colliderBodyList = [];
+ this._bone = null;
+ this._body = null;
+ this._active = false;
+ this._filter = null;
+
+ ccs.ColliderDetector.prototype.init.call(this, bone);
+ },
+ init: function (bone) {
+ this._colliderBodyList.length = 0;
+ if (bone)
+ this._bone = bone;
+ this._filter = new ccs.ColliderFilter();
+ return true;
+ },
+
+ /**
+ * add contourData
+ * @param {ccs.ContourData} contourData
+ */
+ addContourData: function (contourData) {
+ var colliderBody = new ccs.ColliderBody(contourData);
+ this._colliderBodyList.push(colliderBody);
+
+ if (ccs.ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX) {
+ var calculatedVertexList = colliderBody.getCalculatedVertexList();
+ var vertexList = contourData.vertexList;
+ for (var i = 0; i < vertexList.length; i++) {
+ var newVertex = new ccs.ContourVertex2(0, 0);
+ calculatedVertexList.push(newVertex);
+ }
+ }
+ },
+
+ /**
+ * add contourData
+ * @param {Array} contourDataList
+ */
+ addContourDataList: function (contourDataList) {
+ for (var i = 0; i < contourDataList.length; i++) {
+ this.addContourData(contourDataList[i]);
+ }
+ },
+
+ /**
+ * remove contourData
+ * @param contourData
+ */
+ removeContourData: function (contourData) {
+ var eraseList = [], i, locBodyList = this._colliderBodyList;
+ for (i = 0; i < locBodyList.length; i++) {
+ var body = locBodyList[i];
+ if (body && body.getContourData() === contourData)
+ eraseList.push(body);
+ }
+
+ for (i=0; igetB2Fixture()->GetShape();
+ shape = colliderBody.getShape();
+ }
+
+ var vs = contourData.vertexList;
+ var cvs = colliderBody.getCalculatedVertexList();
+
+ for (var j = 0; j < vs.length; j++) {
+ locHelpPoint.x = vs[j].x;
+ locHelpPoint.y = vs[j].y;
+ locHelpPoint = cc.pointApplyAffineTransform(locHelpPoint, t);
+
+ if (ccs.ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX) {
+ var v = cc.p(0, 0);
+ v.x = locHelpPoint.x;
+ v.y = locHelpPoint.y;
+ cvs[j] = v;
+ }
+
+ if (shape) {
+ shape.verts[j * 2] = locHelpPoint.x;
+ shape.verts[j * 2 + 1] = locHelpPoint.y;
+ }
+ }
+ if (shape) {
+ for (var j = 0; j < vs.length; j++) {
+ var b = shape.verts[(j + 1) % shape.verts.length];
+ var n = cp.v.normalize(cp.v.perp(cp.v.sub(b, shape.verts[j])));
+
+ if(shape.planes){
+ shape.planes[j].n = n;
+ shape.planes[j].d = cp.v.dot(n, shape.verts[j]);
+ }
+// var b = shape.verts[(i + 1) % shape.numVerts];
+// var n = cp.v.normalize(cp.v.perp(cp.v.sub(b, shape.verts[i])));
+//
+// shape.planes[i].n = n;
+// shape.planes[i].d = cp.v.dot(n, shape.verts[i]);
+ }
+ }
+ }
+ },
+
+ setBody: function (body) {
+ this._body = body;
+ var colliderBody, locBodyList = this._colliderBodyList;
+ for (var i = 0; i < locBodyList.length; i++) {
+ colliderBody = locBodyList[i];
+ var contourData = colliderBody.getContourData(), verts = [];
+ var vs = contourData.vertexList;
+ for (var j = 0; j < vs.length; j++) {
+ var v = vs[j];
+ verts.push(v.x);
+ verts.push(v.y);
+ }
+ var shape = new cp.PolyShape(this._body, verts, cp.vzero);
+ shape.sensor = true;
+ shape.data = this._bone;
+ if (this._active)
+ this._body.space.addShape(shape);
+ colliderBody.setShape(shape);
+ colliderBody.getColliderFilter().updateShape(shape);
+ }
+ },
+
+ getBody: function () {
+ return this._body;
+ }
+});
+
+var _p = ccs.ColliderDetector.prototype;
+
+// Extended properties
+/** @expose */
+_p.colliderFilter;
+cc.defineGetterSetter(_p, "colliderFilter", _p.getColliderFilter, _p.setColliderFilter);
+/** @expose */
+_p.active;
+cc.defineGetterSetter(_p, "active", _p.getActive, _p.setActive);
+/** @expose */
+_p.body;
+cc.defineGetterSetter(_p, "body", _p.getBody, _p.setBody);
+
+_p = null;
+
+ccs.ColliderDetector.create = function (bone) {
+ return new ccs.ColliderDetector(bone);
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCArmatureDataManager.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCArmatureDataManager.js
new file mode 100644
index 0000000..ca901bb
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCArmatureDataManager.js
@@ -0,0 +1,329 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * RelativeData uses to save plist files, armature files, animations and textures for armature data manager.
+ * @constructor
+ */
+ccs.RelativeData = function () {
+ this.plistFiles = [];
+ this.armatures = [];
+ this.animations = [];
+ this.textures = [];
+};
+
+/**
+ * ccs.armatureDataManager is a singleton object which format and manage armature configuration and armature animation
+ * @class
+ * @name ccs.armatureDataManager
+ */
+ccs.armatureDataManager = /** @lends ccs.armatureDataManager# */ {
+ _animationDatas: {},
+ _armatureDatas: {},
+ _textureDatas: {},
+ _autoLoadSpriteFile: false,
+ _relativeDatas: {},
+
+ s_sharedArmatureDataManager: null,
+
+ /**
+ * Removes armature cache data by configFilePath
+ * @param {String} configFilePath
+ */
+ removeArmatureFileInfo: function (configFilePath) {
+ var data = this.getRelativeData(configFilePath);
+ if (data) {
+ var i, obj;
+ for (i = 0; i < data.armatures.length; i++) {
+ obj = data.armatures[i];
+ this.removeArmatureData(obj);
+ }
+ for (i = 0; i < data.animations.length; i++) {
+ obj = data.animations[i];
+ this.removeAnimationData(obj);
+ }
+ for (i = 0; i < data.textures.length; i++) {
+ obj = data.textures[i];
+ this.removeTextureData(obj);
+ }
+ for (i = 0; i < data.plistFiles.length; i++) {
+ obj = data.plistFiles[i];
+ cc.spriteFrameCache.removeSpriteFramesFromFile(obj);
+ }
+ delete this._relativeDatas[configFilePath];
+ ccs.dataReaderHelper.removeConfigFile(configFilePath);
+ }
+ },
+
+ /**
+ * Adds armature data
+ * @param {string} id The id of the armature data
+ * @param {ccs.ArmatureData} armatureData
+ */
+ addArmatureData: function (id, armatureData, configFilePath) {
+ var data = this.getRelativeData(configFilePath);
+ if (data) {
+ data.armatures.push(id);
+ }
+ this._armatureDatas[id] = armatureData;
+ },
+
+ /**
+ * Gets armatureData by id
+ * @param {String} id
+ * @return {ccs.ArmatureData}
+ */
+ getArmatureData: function (id) {
+ var armatureData = null;
+ if (this._armatureDatas) {
+ armatureData = this._armatureDatas[id];
+ }
+ return armatureData;
+ },
+
+ /**
+ * Removes armature data from armature data manager.
+ * @param {string} id
+ */
+ removeArmatureData: function (id) {
+ if (this._armatureDatas[id])
+ delete this._armatureDatas[id];
+ },
+
+ /**
+ * Adds animation data to armature data manager.
+ * @param {String} id
+ * @param {ccs.AnimationData} animationData
+ */
+ addAnimationData: function (id, animationData, configFilePath) {
+ var data = this.getRelativeData(configFilePath);
+ if (data)
+ data.animations.push(id);
+ this._animationDatas[id] = animationData;
+ },
+
+ /**
+ * Gets animationData by id
+ * @param {String} id
+ * @return {ccs.AnimationData}
+ */
+ getAnimationData: function (id) {
+ var animationData = null;
+ if (this._animationDatas[id]) {
+ animationData = this._animationDatas[id];
+ }
+ return animationData;
+ },
+
+ /**
+ * Removes animation data
+ * @param {string} id
+ */
+ removeAnimationData: function (id) {
+ if (this._animationDatas[id])
+ delete this._animationDatas[id];
+ },
+
+ /**
+ * Adds texture data to Armature data manager.
+ * @param {String} id
+ * @param {ccs.TextureData} textureData
+ */
+ addTextureData: function (id, textureData, configFilePath) {
+ var data = this.getRelativeData(configFilePath);
+ if (data) {
+ data.textures.push(id);
+ }
+ this._textureDatas[id] = textureData;
+ },
+
+ /**
+ * Gets textureData by id
+ * @param {String} id
+ * @return {ccs.TextureData}
+ */
+ getTextureData: function (id) {
+ var textureData = null;
+ if (this._textureDatas) {
+ textureData = this._textureDatas[id];
+ }
+ return textureData;
+ },
+
+ /**
+ * Removes texture data by id
+ * @param {string} id
+ */
+ removeTextureData: function (id) {
+ if (this._textureDatas[id])
+ delete this._textureDatas[id];
+ },
+
+ /**
+ * Adds ArmatureFileInfo, it is managed by CCArmatureDataManager.
+ * @param {String} imagePath
+ * @param {String} plistPath
+ * @param {String} configFilePath
+ * @example
+ * //example1
+ * ccs.armatureDataManager.addArmatureFileInfo("res/test.json");
+ * //example2
+ * ccs.armatureDataManager.addArmatureFileInfo("res/test.png","res/test.plist","res/test.json");
+ */
+ addArmatureFileInfo: function ( /*imagePath, plistPath, configFilePath*/ ) {
+ var imagePath, plistPath, configFilePath;
+ switch (arguments.length) {
+ case 1:
+ configFilePath = arguments[0];
+
+ this.addRelativeData(configFilePath);
+
+ this._autoLoadSpriteFile = true;
+ ccs.dataReaderHelper.addDataFromFile(configFilePath);
+ break;
+ case 3:
+ imagePath = arguments[0];
+ plistPath = arguments[1];
+ configFilePath = arguments[2];
+
+ this.addRelativeData(configFilePath);
+
+ this._autoLoadSpriteFile = false;
+ ccs.dataReaderHelper.addDataFromFile(configFilePath);
+ this.addSpriteFrameFromFile(plistPath, imagePath);
+ }
+ },
+
+ /**
+ * Adds ArmatureFileInfo, it is managed by CCArmatureDataManager.
+ * @param {String} imagePath
+ * @param {String} plistPath
+ * @param {String} configFilePath
+ * @param {Function} selector
+ * @param {Object} target
+ */
+ addArmatureFileInfoAsync: function ( /*imagePath, plistPath, configFilePath, selector, target*/ ) {
+ var imagePath, plistPath, configFilePath, target, selector;
+ switch (arguments.length) {
+ case 3:
+ configFilePath = arguments[0];
+ target = arguments[2];
+ selector = arguments[1];
+ this.addRelativeData(configFilePath);
+ this._autoLoadSpriteFile = true;
+ ccs.dataReaderHelper.addDataFromFileAsync("", "", configFilePath, selector, target);
+ break;
+ case 5:
+ imagePath = arguments[0];
+ plistPath = arguments[1];
+ configFilePath = arguments[2];
+ target = arguments[4];
+ selector = arguments[3];
+ this.addRelativeData(configFilePath);
+
+ this._autoLoadSpriteFile = false;
+ ccs.dataReaderHelper.addDataFromFileAsync(imagePath, plistPath, configFilePath, selector, target);
+ this.addSpriteFrameFromFile(plistPath, imagePath);
+ }
+ },
+
+ /**
+ * Add sprite frame to CCSpriteFrameCache, it will save display name and it's relative image name
+ * @param {String} plistPath
+ * @param {String} imagePath
+ * @param {String} configFilePath
+ */
+ addSpriteFrameFromFile: function (plistPath, imagePath, configFilePath) {
+ var data = this.getRelativeData(configFilePath);
+ if (data)
+ data.plistFiles.push(plistPath);
+ ccs.spriteFrameCacheHelper.addSpriteFrameFromFile(plistPath, imagePath);
+ },
+
+ /**
+ * Returns whether or not need auto load sprite file
+ * @returns {boolean}
+ */
+ isAutoLoadSpriteFile: function () {
+ return this._autoLoadSpriteFile;
+ },
+
+ /**
+ * Returns armature Data of Armature data manager.
+ * @return {Object}
+ */
+ getArmatureDatas: function () {
+ return this._armatureDatas;
+ },
+
+ /**
+ * Returns animation data of Armature data manager.
+ * @return {Object}
+ */
+ getAnimationDatas: function () {
+ return this._animationDatas;
+ },
+
+ /**
+ * Returns texture data of Armature data manager.
+ * @return {Object}
+ */
+ getTextureDatas: function () {
+ return this._textureDatas;
+ },
+
+ /**
+ * Adds RelativeData of Armature data manager.
+ * @param {String} configFilePath
+ */
+ addRelativeData: function (configFilePath) {
+ if (!this._relativeDatas[configFilePath])
+ this._relativeDatas[configFilePath] = new ccs.RelativeData();
+ },
+
+ /**
+ * Gets RelativeData of Armature data manager.
+ * @param {String} configFilePath
+ * @returns {ccs.RelativeData}
+ */
+ getRelativeData: function (configFilePath) {
+ return this._relativeDatas[configFilePath];
+ },
+
+ /**
+ * Clear data
+ */
+ clear: function () {
+ for (var key in this._relativeDatas) {
+ this.removeArmatureFileInfo(key);
+ }
+ this._animationDatas = {};
+ this._armatureDatas = {};
+ this._textureDatas = {};
+ this._relativeDatas = {};
+ ccs.spriteFrameCacheHelper.clear();
+ ccs.dataReaderHelper.clear();
+ }
+};
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCArmatureDefine.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCArmatureDefine.js
new file mode 100644
index 0000000..a7db1b9
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCArmatureDefine.js
@@ -0,0 +1,45 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+/**
+ * @ignore
+ */
+ccs.VERSION_COMBINED = 0.30;
+ccs.VERSION_CHANGE_ROTATION_RANGE = 1.0;
+ccs.VERSION_COLOR_READING = 1.1;
+ccs.MAX_VERTEXZ_VALUE = 5000000.0;
+ccs.ARMATURE_MAX_CHILD = 50.0;
+ccs.ARMATURE_MAX_ZORDER = 100;
+ccs.ARMATURE_MAX_COUNT = ((ccs.MAX_VERTEXZ_VALUE) / (ccs.ARMATURE_MAX_CHILD) / ccs.ARMATURE_MAX_ZORDER);
+ccs.AUTO_ADD_SPRITE_FRAME_NAME_PREFIX = false;
+ccs.ENABLE_PHYSICS_CHIPMUNK_DETECT = false;
+ccs.ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX = false;
+
+/**
+ * Returns the version of Armature.
+ * @returns {string}
+ */
+ccs.armatureVersion = function(){
+ return "v1.1.0.0";
+};
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCDataReaderHelper.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCDataReaderHelper.js
new file mode 100644
index 0000000..b029fb2
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCDataReaderHelper.js
@@ -0,0 +1,1223 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * @ignore
+ */
+ccs.CONST_VERSION = "version";
+ccs.CONST_VERSION_2_0 = 2.0;
+ccs.CONST_VERSION_COMBINED = 0.3;
+
+ccs.CONST_ARMATURES = "armatures";
+ccs.CONST_ARMATURE = "armature";
+ccs.CONST_BONE = "b";
+ccs.CONST_DISPLAY = "d";
+
+ccs.CONST_ANIMATIONS = "animations";
+ccs.CONST_ANIMATION = "animation";
+ccs.CONST_MOVEMENT = "mov";
+ccs.CONST_FRAME = "f";
+
+ccs.CONST_TEXTURE_ATLAS = "TextureAtlas";
+ccs.CONST_SUB_TEXTURE = "SubTexture";
+
+ccs.CONST_SKELETON = "skeleton";
+
+ccs.CONST_A_NAME = "name";
+ccs.CONST_A_DURATION = "dr";
+ccs.CONST_A_FRAME_INDEX = "fi";
+ccs.CONST_A_DURATION_TO = "to";
+ccs.CONST_A_DURATION_TWEEN = "drTW";
+ccs.CONST_A_LOOP = "lp";
+ccs.CONST_A_MOVEMENT_SCALE = "sc";
+ccs.CONST_A_MOVEMENT_DELAY = "dl";
+ccs.CONST_A_DISPLAY_INDEX = "dI";
+
+ccs.CONST_A_PLIST = "plist";
+
+ccs.CONST_A_PARENT = "parent";
+ccs.CONST_A_SKEW_X = "kX";
+ccs.CONST_A_SKEW_Y = "kY";
+ccs.CONST_A_SCALE_X = "cX";
+ccs.CONST_A_SCALE_Y = "cY";
+ccs.CONST_A_Z = "z";
+ccs.CONST_A_EVENT = "evt";
+ccs.CONST_A_SOUND = "sd";
+ccs.CONST_A_SOUND_EFFECT = "sdE";
+ccs.CONST_A_TWEEN_EASING = "twE";
+ccs.CONST_A_EASING_PARAM = "twEP";
+ccs.CONST_A_TWEEN_ROTATE = "twR";
+ccs.CONST_A_IS_ARMATURE = "isArmature";
+ccs.CONST_A_DISPLAY_TYPE = "displayType";
+ccs.CONST_A_MOVEMENT = "mov";
+
+ccs.CONST_A_X = "x";
+ccs.CONST_A_Y = "y";
+
+ccs.CONST_A_COCOS2DX_X = "cocos2d_x";
+ccs.CONST_A_COCOS2DX_Y = "cocos2d_y";
+
+ccs.CONST_A_WIDTH = "width";
+ccs.CONST_A_HEIGHT = "height";
+ccs.CONST_A_PIVOT_X = "pX";
+ccs.CONST_A_PIVOT_Y = "pY";
+
+ccs.CONST_A_COCOS2D_PIVOT_X = "cocos2d_pX";
+ccs.CONST_A_COCOS2D_PIVOT_Y = "cocos2d_pY";
+
+ccs.CONST_A_BLEND_TYPE = "bd";
+ccs.CONST_A_BLEND_SRC = "bd_src";
+ccs.CONST_A_BLEND_DST = "bd_dst";
+
+ccs.CONST_A_ALPHA = "a";
+ccs.CONST_A_RED = "r";
+ccs.CONST_A_GREEN = "g";
+ccs.CONST_A_BLUE = "b";
+ccs.CONST_A_ALPHA_OFFSET = "aM";
+ccs.CONST_A_RED_OFFSET = "rM";
+ccs.CONST_A_GREEN_OFFSET = "gM";
+ccs.CONST_A_BLUE_OFFSET = "bM";
+ccs.CONST_A_COLOR_TRANSFORM = "colorTransform";
+ccs.CONST_A_TWEEN_FRAME = "tweenFrame";
+
+ccs.CONST_CONTOUR = "con";
+ccs.CONST_CONTOUR_VERTEX = "con_vt";
+
+ccs.CONST_FL_NAN = "NaN";
+
+ccs.CONST_FRAME_DATA = "frame_data";
+ccs.CONST_MOVEMENT_BONE_DATA = "mov_bone_data";
+ccs.CONST_MOVEMENT_DATA = "mov_data";
+ccs.CONST_ANIMATION_DATA = "animation_data";
+ccs.CONST_DISPLAY_DATA = "display_data";
+ccs.CONST_SKIN_DATA = "skin_data";
+ccs.CONST_BONE_DATA = "bone_data";
+ccs.CONST_ARMATURE_DATA = "armature_data";
+ccs.CONST_CONTOUR_DATA = "contour_data";
+ccs.CONST_TEXTURE_DATA = "texture_data";
+ccs.CONST_VERTEX_POINT = "vertex";
+ccs.CONST_COLOR_INFO = "color";
+
+ccs.CONST_CONFIG_FILE_PATH = "config_file_path";
+ccs.CONST_CONTENT_SCALE = "content_scale";
+
+/**
+ * @ignore
+ * @constructor
+ */
+ccs.DataInfo = function () {
+ this.asyncStruct = null;
+ this.configFileQueue = [];
+ this.contentScale = 1;
+ this.filename = "";
+ this.baseFilePath = "";
+ this.flashToolVersion = 0;
+ this.cocoStudioVersion = 0
+};
+
+/**
+ * ccs.dataReaderHelper is a singleton object for reading CocoStudio data
+ * @class
+ * @name ccs.dataReaderHelper
+ */
+ccs.dataReaderHelper = /** @lends ccs.dataReaderHelper# */{
+ ConfigType: {
+ DragonBone_XML: 0,
+ CocoStudio_JSON: 1,
+ CocoStudio_Binary: 2
+ },
+
+ _configFileList: [],
+ _flashToolVersion: ccs.CONST_VERSION_2_0,
+// _cocoStudioVersion: ccs.CONST_VERSION_COMBINED,
+ _positionReadScale: 1,
+ _asyncRefCount: 0,
+ _asyncRefTotalCount: 0,
+
+ _dataQueue: null,
+
+ //LoadData don't need
+
+ setPositionReadScale: function (scale) {
+ this._positionReadScale = scale;
+ },
+
+ getPositionReadScale: function () {
+ return this._positionReadScale;
+ },
+
+ /**
+ * Add armature data from file.
+ * @param {String} filePath
+ */
+ addDataFromFile: function (filePath) {
+ /*
+ * Check if file is already added to ArmatureDataManager, if then return.
+ */
+ if (this._configFileList.indexOf(filePath) !== -1)
+ return;
+ this._configFileList.push(filePath);
+
+ //! find the base file path
+ var basefilePath = this._initBaseFilePath(filePath);
+
+ // Read content from file
+ // Here the reader into the next process
+
+ var str = cc.path.extname(filePath).toLowerCase();
+
+ var dataInfo = new ccs.DataInfo();
+ dataInfo.filename = filePath;
+ dataInfo.basefilePath = basefilePath;
+ if (str === ".xml")
+ ccs.dataReaderHelper.addDataFromXML(filePath, dataInfo);
+ else if (str === ".json" || str === ".exportjson")
+ ccs.dataReaderHelper.addDataFromJson(filePath, dataInfo);
+ else if(str === ".csb")
+ ccs.dataReaderHelper.addDataFromBinaryCache(filePath, dataInfo);
+ },
+
+ /**
+ * Adds data from file with Async.
+ * @param {String} imagePath
+ * @param {String} plistPath
+ * @param {String} filePath
+ * @param {function} selector
+ * @param {Object} [target]
+ */
+ addDataFromFileAsync: function (imagePath, plistPath, filePath, selector, target) {
+ /*
+ * Check if file is already added to ArmatureDataManager, if then return.
+ */
+ if (this._configFileList.indexOf(filePath) !== -1) {
+ if (target && selector) {
+ if (this._asyncRefTotalCount === 0 && this._asyncRefCount === 0)
+ this._asyncCallBack(selector,target, 1);
+ else
+ this._asyncCallBack(selector, target, (this._asyncRefTotalCount - this._asyncRefCount) / this._asyncRefTotalCount);
+ }
+ return;
+ }
+// this._configFileList.push(filePath);
+
+ //! find the base file path
+// var basefilePath = this._initBaseFilePath(filePath);
+
+ this._asyncRefTotalCount++;
+ this._asyncRefCount++;
+ var self = this;
+ var fun = function () {
+ self.addDataFromFile(filePath);
+ self._asyncRefCount--;
+ self._asyncCallBack(selector,target, (self._asyncRefTotalCount - self._asyncRefCount) / self._asyncRefTotalCount);
+ };
+ cc.director.getScheduler().schedule(fun, this, 0.1, false, 0, false, "armatrueDataHelper");
+ },
+
+ /**
+ * Removes config file from config file list.
+ * @param {String} configFile
+ */
+ removeConfigFile: function (configFile) {
+// cc.arrayRemoveObject(this._configFileList, configFile);
+ var locFileList = this._configFileList;
+ var len = locFileList.length;
+ var it = locFileList[len];
+ for (var i = 0;i " + ccs.CONST_ARMATURES + " > " + ccs.CONST_ARMATURE + "");
+ var armatureDataManager = ccs.armatureDataManager, i;
+ for (i = 0; i < armaturesXML.length; i++) {
+ var armatureData = this.decodeArmature(armaturesXML[i], dataInfo);
+ armatureDataManager.addArmatureData(armatureData.name, armatureData, dataInfo.filename);
+ }
+
+ /*
+ * Begin decode animation data from xml
+ */
+ var animationsXML = skeleton.querySelectorAll(ccs.CONST_SKELETON + " > " + ccs.CONST_ANIMATIONS + " > " + ccs.CONST_ANIMATION + "");
+ for (i = 0; i < animationsXML.length; i++) {
+ var animationData = this.decodeAnimation(animationsXML[i], dataInfo);
+ armatureDataManager.addAnimationData(animationData.name, animationData, dataInfo.filename);
+ }
+
+ var texturesXML = skeleton.querySelectorAll(ccs.CONST_SKELETON + " > " + ccs.CONST_TEXTURE_ATLAS + " > " + ccs.CONST_SUB_TEXTURE + "");
+ for (i = 0; i < texturesXML.length; i++) {
+ var textureData = this.decodeTexture(texturesXML[i], dataInfo);
+ armatureDataManager.addTextureData(textureData.name, textureData, dataInfo.filename);
+ }
+ },
+
+ /**
+ * decode xml armature data.
+ * @param {XMLDocument} armatureXML
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.ArmatureData}
+ */
+ decodeArmature: function (armatureXML, dataInfo) {
+ var armatureData = new ccs.ArmatureData();
+ armatureData.init();
+ armatureData.name = armatureXML.getAttribute(ccs.CONST_A_NAME);
+
+ var bonesXML = armatureXML.querySelectorAll(ccs.CONST_ARMATURE + " > " + ccs.CONST_BONE);
+
+ for (var i = 0; i < bonesXML.length; i++) {
+ /*
+ * If this bone have parent, then get the parent bone xml
+ */
+ var boneXML = bonesXML[i];
+ var parentName = boneXML.getAttribute(ccs.CONST_A_PARENT);
+ var parentXML = null;
+ if (parentName) {
+ //parentXML = armatureXML.querySelectorAll(ccs.CONST_ARMATURE+" > "+ccs.CONST_BONE);
+ for (var j = 0; j < bonesXML.length; j++) {
+ parentXML = bonesXML[j];
+ if (parentName == bonesXML[j].getAttribute(ccs.CONST_A_NAME)) {
+ //todo
+ break;
+ }
+ }
+ }
+ var boneData = this.decodeBone(boneXML, parentXML, dataInfo);
+ armatureData.addBoneData(boneData);
+ }
+ return armatureData;
+ },
+
+ /**
+ * decode json armature data.
+ * @param {Object} json
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.ArmatureData}
+ */
+ decodeArmatureFromJSON: function (json, dataInfo) {
+ var armatureData = new ccs.ArmatureData();
+ armatureData.init();
+
+ var name = json[ccs.CONST_A_NAME];
+ if (name) {
+ armatureData.name = name;
+ }
+
+ dataInfo.cocoStudioVersion = armatureData.dataVersion = json[ccs.CONST_VERSION] || 0.1;
+
+ var boneDataList = json[ccs.CONST_BONE_DATA];
+ for (var i = 0; i < boneDataList.length; i++) {
+ var boneData = this.decodeBoneFromJson(boneDataList[i], dataInfo);
+ armatureData.addBoneData(boneData);
+ }
+ return armatureData;
+ },
+
+ /**
+ * decode xml bone data.
+ * @param {XMLDocument} boneXML
+ * @param {XMLDocument} parentXML
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.BoneData}
+ */
+ decodeBone: function (boneXML, parentXML, dataInfo) {
+ var boneData = new ccs.BoneData();
+ boneData.init();
+
+ boneData.name = boneXML.getAttribute(ccs.CONST_A_NAME);
+ boneData.parentName = boneXML.getAttribute(ccs.CONST_A_PARENT) || "";
+
+ boneData.zOrder = parseInt(boneXML.getAttribute(ccs.CONST_A_Z)) || 0;
+
+ var displaysXML = boneXML.querySelectorAll(ccs.CONST_BONE + " > " + ccs.CONST_DISPLAY);
+ for (var i = 0; i < displaysXML.length; i++) {
+ var displayXML = displaysXML[i];
+ var displayData = this.decodeBoneDisplay(displayXML, dataInfo);
+ boneData.addDisplayData(displayData);
+ }
+ return boneData;
+ },
+
+ /**
+ * decode json bone data.
+ * @param {Object} json json bone data.
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.BoneData}
+ */
+ decodeBoneFromJson: function (json, dataInfo) {
+ var boneData = new ccs.BoneData();
+ boneData.init();
+
+ this.decodeNodeFromJson(boneData, json, dataInfo);
+
+ boneData.name = json[ccs.CONST_A_NAME] || "";
+
+ boneData.parentName = json[ccs.CONST_A_PARENT] || "";
+ var displayDataList = json[ccs.CONST_DISPLAY_DATA] || [];
+ for (var i = 0; i < displayDataList.length; i++) {
+ var locDisplayData = this.decodeBoneDisplayFromJson(displayDataList[i], dataInfo);
+ boneData.addDisplayData(locDisplayData);
+ }
+ return boneData;
+ },
+
+ /**
+ * decode xml display data of bone
+ * @param {XMLDocument} displayXML
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.DisplayData}
+ */
+ decodeBoneDisplay: function (displayXML, dataInfo) {
+ var isArmature = parseFloat(displayXML.getAttribute(ccs.CONST_A_IS_ARMATURE)) || 0;
+ var displayData = null;
+
+ if (isArmature === 1) {
+ displayData = new ccs.ArmatureDisplayData();
+ displayData.displayType = ccs.DISPLAY_TYPE_ARMATURE;
+ } else {
+ displayData = new ccs.SpriteDisplayData();
+ displayData.displayType = ccs.DISPLAY_TYPE_SPRITE;
+ }
+
+ var displayName = displayXML.getAttribute(ccs.CONST_A_NAME) || "";
+ if (displayName) {
+ displayData.displayName = displayName;
+ }
+ return displayData;
+ },
+
+ /**
+ * Decodes json display data of bone.
+ * @param {Object} json
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.DisplayData}
+ */
+ decodeBoneDisplayFromJson: function (json, dataInfo) {
+ var displayType = json[ccs.CONST_A_DISPLAY_TYPE] || ccs.DISPLAY_TYPE_SPRITE;
+ var displayData = null;
+
+ switch (displayType) {
+ case ccs.DISPLAY_TYPE_SPRITE:
+ displayData = new ccs.SpriteDisplayData();
+
+ var name = json[ccs.CONST_A_NAME];
+ if(name != null){
+ displayData.displayName = name;
+ }
+
+ var dicArray = json[ccs.CONST_SKIN_DATA] || [];
+ var dic = dicArray[0];
+ if (dic) {
+ var skinData = displayData.skinData;
+ skinData.x = dic[ccs.CONST_A_X] * this._positionReadScale;
+ skinData.y = dic[ccs.CONST_A_Y] * this._positionReadScale;
+ skinData.scaleX = dic[ccs.CONST_A_SCALE_X] == null ? 1 : dic[ccs.CONST_A_SCALE_X];
+ skinData.scaleY = dic[ccs.CONST_A_SCALE_Y] == null ? 1 : dic[ccs.CONST_A_SCALE_Y];
+ skinData.skewX = dic[ccs.CONST_A_SKEW_X] == null ? 1 : dic[ccs.CONST_A_SKEW_X];
+ skinData.skewY = dic[ccs.CONST_A_SKEW_Y] == null ? 1 : dic[ccs.CONST_A_SKEW_Y];
+
+ skinData.x *= dataInfo.contentScale;
+ skinData.y *= dataInfo.contentScale;
+ }
+ break;
+ case ccs.DISPLAY_TYPE_ARMATURE:
+ displayData = new ccs.ArmatureDisplayData();
+ var name = json[ccs.CONST_A_NAME];
+ if(name != null){
+ displayData.displayName = json[ccs.CONST_A_NAME];
+ }
+ break;
+ case ccs.DISPLAY_TYPE_PARTICLE:
+ displayData = new ccs.ParticleDisplayData();
+ var plist = json[ccs.CONST_A_PLIST];
+ if(plist != null){
+ if(dataInfo.asyncStruct){
+ displayData.displayName = dataInfo.asyncStruct.basefilePath + plist;
+ }else{
+ displayData.displayName = dataInfo.basefilePath + plist;
+ }
+ }
+ break;
+ default:
+ displayData = new ccs.SpriteDisplayData();
+ break;
+ }
+ displayData.displayType = displayType;
+ return displayData;
+ },
+
+ /**
+ * Decodes xml animation data.
+ * @param {XMLDocument} animationXML
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.AnimationData}
+ */
+ decodeAnimation: function (animationXML, dataInfo) {
+ var aniData = new ccs.AnimationData();
+ var name = animationXML.getAttribute(ccs.CONST_A_NAME);
+ var armatureData = ccs.armatureDataManager.getArmatureData(name);
+ aniData.name = name;
+
+ var movementsXML = animationXML.querySelectorAll(ccs.CONST_ANIMATION + " > " + ccs.CONST_MOVEMENT);
+ var movementXML = null;
+
+ for (var i = 0; i < movementsXML.length; i++) {
+ movementXML = movementsXML[i];
+ var movementData = this.decodeMovement(movementXML, armatureData, dataInfo);
+ aniData.addMovement(movementData);
+ }
+ return aniData;
+ },
+
+ /**
+ * Decodes animation json data.
+ * @param {Object} json
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.AnimationData}
+ */
+ decodeAnimationFromJson: function (json, dataInfo) {
+ var aniData = new ccs.AnimationData();
+ var name = json[ccs.CONST_A_NAME];
+ if(name){
+ aniData.name = json[ccs.CONST_A_NAME];
+ }
+
+ var movementDataList = json[ccs.CONST_MOVEMENT_DATA] || [];
+ for (var i = 0; i < movementDataList.length; i++) {
+ var locMovementData = this.decodeMovementFromJson(movementDataList[i], dataInfo);
+ aniData.addMovement(locMovementData);
+ }
+ return aniData;
+ },
+
+ /**
+ * Decodes xml movement data.
+ * @param {XMLDocument} movementXML
+ * @param {ccs.ArmatureData} armatureData
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.MovementData}
+ */
+ decodeMovement: function (movementXML, armatureData, dataInfo) {
+ var movementData = new ccs.MovementData();
+ movementData.name = movementXML.getAttribute(ccs.CONST_A_NAME);
+
+ var duration, durationTo, durationTween, loop, tweenEasing = 0;
+
+ duration = movementXML.getAttribute(ccs.CONST_A_DURATION);
+ movementData.duration = duration == null ? 0 : parseFloat(duration);
+
+ durationTo = movementXML.getAttribute(ccs.CONST_A_DURATION_TO);
+ movementData.durationTo = durationTo == null ? 0 : parseFloat(durationTo);
+
+ durationTween = movementXML.getAttribute(ccs.CONST_A_DURATION_TWEEN);
+ movementData.durationTween = durationTween == null ? 0 : parseFloat(durationTween);
+
+ loop = movementXML.getAttribute(ccs.CONST_A_LOOP);
+ movementData.loop = loop ? Boolean(parseFloat(loop)) : true;
+
+ var easing = movementXML.getAttribute(ccs.CONST_A_TWEEN_EASING);
+ if (easing) {
+ if (easing != ccs.CONST_FL_NAN) {
+ tweenEasing = easing == null ? 0 : parseFloat(easing);
+ movementData.tweenEasing = tweenEasing === 2 ? ccs.TweenType.SINE_EASEINOUT : tweenEasing;
+ } else
+ movementData.tweenEasing = ccs.TweenType.LINEAR;
+ }
+
+ var movBonesXml = movementXML.querySelectorAll(ccs.CONST_MOVEMENT + " > " + ccs.CONST_BONE);
+ var movBoneXml = null;
+ for (var i = 0; i < movBonesXml.length; i++) {
+ movBoneXml = movBonesXml[i];
+ var boneName = movBoneXml.getAttribute(ccs.CONST_A_NAME);
+
+ if (movementData.getMovementBoneData(boneName))
+ continue;
+
+ var boneData = armatureData.getBoneData(boneName);
+ var parentName = boneData.parentName;
+
+ var parentXML = null;
+ if (parentName !== "") {
+ for (var j = 0; j < movBonesXml.length; j++) {
+ parentXML = movBonesXml[j];
+ if (parentName === parentXML.getAttribute(ccs.CONST_A_NAME))
+ break;
+ }
+ }
+ var moveBoneData = this.decodeMovementBone(movBoneXml, parentXML, boneData, dataInfo);
+ movementData.addMovementBoneData(moveBoneData);
+ }
+ return movementData;
+ },
+
+ /**
+ * Decodes json movement data.
+ * @param {Object} json
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.MovementData}
+ */
+ decodeMovementFromJson: function (json, dataInfo) {
+ var movementData = new ccs.MovementData();
+
+ movementData.loop = json[ccs.CONST_A_LOOP] == null ? false : json[ccs.CONST_A_LOOP];
+ movementData.durationTween = json[ccs.CONST_A_DURATION_TWEEN] || 0;
+ movementData.durationTo = json[ccs.CONST_A_DURATION_TO] || 0;
+ movementData.duration = json[ccs.CONST_A_DURATION] || 0;
+
+ if(json[ccs.CONST_A_DURATION] == null){
+ movementData.scale = 1;
+ }else{
+ movementData.scale = json[ccs.CONST_A_MOVEMENT_SCALE] == null ? 1 : json[ccs.CONST_A_MOVEMENT_SCALE];
+ }
+
+ movementData.tweenEasing = json[ccs.CONST_A_TWEEN_EASING] == null ? ccs.TweenType.LINEAR : json[ccs.CONST_A_TWEEN_EASING];
+ var name = json[ccs.CONST_A_NAME];
+ if(name)
+ movementData.name = name;
+
+ var movementBoneList = json[ccs.CONST_MOVEMENT_BONE_DATA] || [];
+ for (var i = 0; i < movementBoneList.length; i++) {
+ var locMovementBoneData = this.decodeMovementBoneFromJson(movementBoneList[i], dataInfo);
+ movementData.addMovementBoneData(locMovementBoneData);
+ }
+ return movementData;
+ },
+
+ /**
+ * Decodes xml data of bone's movement.
+ * @param {XMLDocument} movBoneXml
+ * @param {XMLDocument} parentXml
+ * @param {ccs.BoneData} boneData
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.MovementBoneData}
+ */
+ decodeMovementBone: function (movBoneXml, parentXml, boneData, dataInfo) {
+ var movBoneData = new ccs.MovementBoneData();
+ movBoneData.init();
+
+ var scale, delay;
+ if (movBoneXml) {
+ scale = parseFloat(movBoneXml.getAttribute(ccs.CONST_A_MOVEMENT_SCALE)) || 0;
+ movBoneData.scale = scale;
+
+ delay = parseFloat(movBoneXml.getAttribute(ccs.CONST_A_MOVEMENT_DELAY)) || 0;
+ if (delay > 0)
+ delay -= 1;
+ movBoneData.delay = delay;
+ }
+
+ var length = 0, parentTotalDuration = 0,currentDuration = 0;
+ var parentFrameXML = null,parentXMLList = [];
+
+ /*
+ * get the parent frame xml list, we need get the origin data
+ */
+ if (parentXml != null) {
+ var parentFramesXML = parentXml.querySelectorAll(ccs.CONST_BONE + " > " + ccs.CONST_FRAME);
+ for (var i = 0; i < parentFramesXML.length; i++)
+ parentXMLList.push(parentFramesXML[i]);
+ length = parentXMLList.length;
+ }
+
+ movBoneData.name = movBoneXml.getAttribute(ccs.CONST_A_NAME);
+
+ var framesXML = movBoneXml.querySelectorAll(ccs.CONST_BONE + " > " + ccs.CONST_FRAME);
+
+ var j = 0, totalDuration = 0;
+ for (var ii = 0; ii < framesXML.length; ii++) {
+ var frameXML = framesXML[ii];
+ if (parentXml) {
+ /*
+ * in this loop we get the corresponding parent frame xml
+ */
+ while (j < length && (parentFrameXML ? (totalDuration < parentTotalDuration || totalDuration >= parentTotalDuration + currentDuration) : true)) {
+ parentFrameXML = parentXMLList[j];
+ parentTotalDuration += currentDuration;
+ currentDuration = parseFloat(parentFrameXML.getAttribute(ccs.CONST_A_DURATION));
+ j++;
+ }
+ }
+ var boneFrameData = this.decodeFrame(frameXML, parentFrameXML, boneData, dataInfo);
+ movBoneData.addFrameData(boneFrameData);
+ boneFrameData.frameID = totalDuration;
+ totalDuration += boneFrameData.duration;
+ movBoneData.duration = totalDuration;
+ }
+
+ //Change rotation range from (-180 -- 180) to (-infinity -- infinity)
+ var frames = movBoneData.frameList, pi = Math.PI;
+ for (var i = frames.length - 1; i >= 0; i--) {
+ if (i > 0) {
+ var difSkewX = frames[i].skewX - frames[i - 1].skewX;
+ var difSkewY = frames[i].skewY - frames[i - 1].skewY;
+
+ if (difSkewX < -pi || difSkewX > pi) {
+ frames[i - 1].skewX = difSkewX < 0 ? frames[i - 1].skewX - 2 * pi : frames[i - 1].skewX + 2 * pi;
+ }
+
+ if (difSkewY < -pi || difSkewY > pi) {
+ frames[i - 1].skewY = difSkewY < 0 ? frames[i - 1].skewY - 2 * pi : frames[i - 1].skewY + 2 * pi;
+ }
+ }
+ }
+
+ var frameData = new ccs.FrameData();
+ frameData.copy(movBoneData.frameList[movBoneData.frameList.length - 1]);
+ frameData.frameID = movBoneData.duration;
+ movBoneData.addFrameData(frameData);
+ return movBoneData;
+ },
+
+ /**
+ * Decodes json data of bone's movement.
+ * @param {Object} json
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.MovementBoneData}
+ */
+ decodeMovementBoneFromJson: function (json, dataInfo) {
+ var movementBoneData = new ccs.MovementBoneData();
+ movementBoneData.init();
+ movementBoneData.delay = json[ccs.CONST_A_MOVEMENT_DELAY] || 0;
+
+ var name = json[ccs.CONST_A_NAME];
+ if(name)
+ movementBoneData.name = name;
+
+ var framesData = json[ccs.CONST_FRAME_DATA] || [];
+ var length = framesData.length;
+ for (var i = 0; i < length; i++) {
+ var dic = json[ccs.CONST_FRAME_DATA][i];
+ var frameData = this.decodeFrameFromJson(dic, dataInfo);
+ movementBoneData.addFrameData(frameData);
+
+ if (dataInfo.cocoStudioVersion < ccs.CONST_VERSION_COMBINED){
+ frameData.frameID = movementBoneData.duration;
+ movementBoneData.duration += frameData.duration;
+ }
+ }
+
+ if (dataInfo.cocoStudioVersion < ccs.VERSION_CHANGE_ROTATION_RANGE) {
+ //! Change rotation range from (-180 -- 180) to (-infinity -- infinity)
+ var frames = movementBoneData.frameList;
+ var pi = Math.PI;
+ for (var i = frames.length - 1; i >= 0; i--) {
+ if (i > 0) {
+ var difSkewX = frames[i].skewX - frames[i - 1].skewX;
+ var difSkewY = frames[i].skewY - frames[i - 1].skewY;
+
+ if (difSkewX < -pi || difSkewX > pi) {
+ frames[i - 1].skewX = difSkewX < 0 ? frames[i - 1].skewX - 2 * pi : frames[i - 1].skewX + 2 * pi;
+ }
+
+ if (difSkewY < -pi || difSkewY > pi) {
+ frames[i - 1].skewY = difSkewY < 0 ? frames[i - 1].skewY - 2 * pi : frames[i - 1].skewY + 2 * pi;
+ }
+ }
+ }
+ }
+
+ if (dataInfo.cocoStudioVersion < ccs.CONST_VERSION_COMBINED) {
+ if (movementBoneData.frameList.length > 0) {
+ var frameData = new ccs.FrameData();
+ frameData.copy(movementBoneData.frameList[movementBoneData.frameList.length - 1]);
+ movementBoneData.addFrameData(frameData);
+ frameData.frameID = movementBoneData.duration;
+ }
+ }
+ return movementBoneData;
+ },
+
+ /**
+ * Decodes xml data of frame.
+ * @param {XMLDocument} frameXML
+ * @param {XMLDocument} parentFrameXml
+ * @param {ccs.BoneData} boneData
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.FrameData}
+ */
+ decodeFrame: function (frameXML, parentFrameXml, boneData, dataInfo) {
+ var x = 0, y = 0, scale_x = 0, scale_y = 0, skew_x = 0, skew_y = 0, tweenRotate = 0;
+ var duration = 0, displayIndex = 0, zOrder = 0, tweenEasing = 0, blendType = 0;
+
+ var frameData = new ccs.FrameData();
+ frameData.strMovement = frameXML.getAttribute(ccs.CONST_A_MOVEMENT) || "";
+ frameData.movement = frameData.strMovement;
+ frameData.strEvent = frameXML.getAttribute(ccs.CONST_A_EVENT) || "";
+ frameData.event = frameData.strEvent;
+ frameData.strSound = frameXML.getAttribute(ccs.CONST_A_SOUND) || "";
+ frameData.sound = frameData.strSound;
+ frameData.strSoundEffect = frameXML.getAttribute(ccs.CONST_A_SOUND_EFFECT) || "";
+ frameData.soundEffect = frameData.strSoundEffect;
+
+ var isTween = frameXML.getAttribute(ccs.CONST_A_TWEEN_FRAME);
+ frameData.isTween = !(isTween !== undefined && (isTween === "false" || isTween === "0"));
+
+ if (dataInfo.flashToolVersion >= ccs.CONST_VERSION_2_0) {
+ x = frameXML.getAttribute(ccs.CONST_A_COCOS2DX_X);
+ if(x){
+ frameData.x = parseFloat(x);
+ frameData.x *= this._positionReadScale;
+ }
+ y = frameXML.getAttribute(ccs.CONST_A_COCOS2DX_Y);
+ if(y){
+ frameData.y = -parseFloat(y);
+ frameData.y *= this._positionReadScale;
+ }
+ } else {
+ x = frameXML.getAttribute(ccs.CONST_A_X);
+ if(x) {
+ frameData.x = parseFloat(x);
+ frameData.x *= this._positionReadScale;
+ }
+ y = frameXML.getAttribute(ccs.CONST_A_Y);
+ if(y) {
+ frameData.y = -parseFloat(y);
+ frameData.y *= this._positionReadScale;
+ }
+ }
+
+ scale_x = frameXML.getAttribute(ccs.CONST_A_SCALE_X);
+ if( scale_x != null )
+ frameData.scaleX = parseFloat(scale_x);
+ scale_y = frameXML.getAttribute(ccs.CONST_A_SCALE_Y);
+ if( scale_y != null )
+ frameData.scaleY = parseFloat(scale_y);
+ skew_x = frameXML.getAttribute(ccs.CONST_A_SKEW_X);
+ if( skew_x != null )
+ frameData.skewX = cc.degreesToRadians(parseFloat(skew_x));
+ skew_y = frameXML.getAttribute(ccs.CONST_A_SKEW_Y);
+ if( skew_y != null )
+ frameData.skewY = cc.degreesToRadians(-parseFloat(skew_y));
+
+ duration = frameXML.getAttribute(ccs.CONST_A_DURATION);
+ if( duration != null )
+ frameData.duration = parseFloat(duration);
+ displayIndex = frameXML.getAttribute(ccs.CONST_A_DISPLAY_INDEX);
+ if( displayIndex != null )
+ frameData.displayIndex = parseFloat(displayIndex);
+ zOrder = frameXML.getAttribute(ccs.CONST_A_Z);
+ if( zOrder != null )
+ frameData.zOrder = parseInt(zOrder);
+ tweenRotate = frameXML.getAttribute(ccs.CONST_A_TWEEN_ROTATE);
+ if( tweenRotate != null )
+ frameData.tweenRotate = parseFloat(tweenRotate);
+
+ blendType = frameXML.getAttribute(ccs.CONST_A_BLEND_TYPE);
+ if ( blendType != null ) {
+ var blendFunc = frameData.blendFunc;
+ switch (blendType) {
+ case ccs.BLEND_TYPE_NORMAL:
+ blendFunc.src = cc.BLEND_SRC;
+ blendFunc.dst = cc.BLEND_DST;
+ break;
+ case ccs.BLEND_TYPE_ADD:
+ blendFunc.src = cc.SRC_ALPHA;
+ blendFunc.dst = cc.ONE;
+ break;
+ case ccs.BLEND_TYPE_MULTIPLY:
+ blendFunc.src = cc.DST_COLOR;
+ blendFunc.dst = cc.ONE_MINUS_SRC_ALPHA;
+ break;
+ case ccs.BLEND_TYPE_SCREEN:
+ blendFunc.src = cc.ONE;
+ blendFunc.dst = cc.ONE_MINUS_DST_COLOR;
+ break;
+ default:
+ frameData.blendFunc.src = cc.BLEND_SRC;
+ frameData.blendFunc.dst = cc.BLEND_DST;
+ break;
+ }
+ }
+
+ var colorTransformXML = frameXML.querySelectorAll(ccs.CONST_FRAME + " > " + ccs.CONST_A_COLOR_TRANSFORM);
+ if (colorTransformXML && colorTransformXML.length > 0) {
+ colorTransformXML = colorTransformXML[0];
+ var alpha, red, green, blue;
+ var alphaOffset, redOffset, greenOffset, blueOffset;
+
+ alpha = parseFloat(colorTransformXML.getAttribute(ccs.CONST_A_ALPHA)) || 0;
+ red = parseFloat(colorTransformXML.getAttribute(ccs.CONST_A_RED)) || 0;
+ green = parseFloat(colorTransformXML.getAttribute(ccs.CONST_A_GREEN)) || 0;
+ blue = parseFloat(colorTransformXML.getAttribute(ccs.CONST_A_BLUE)) || 0;
+
+ alphaOffset = parseFloat(colorTransformXML.getAttribute(ccs.CONST_A_ALPHA_OFFSET)) || 0;
+ redOffset = parseFloat(colorTransformXML.getAttribute(ccs.CONST_A_RED_OFFSET)) || 0;
+ greenOffset = parseFloat(colorTransformXML.getAttribute(ccs.CONST_A_GREEN_OFFSET)) || 0;
+ blueOffset = parseFloat(colorTransformXML.getAttribute(ccs.CONST_A_BLUE_OFFSET)) || 0;
+
+ frameData.a = 2.55 * alphaOffset + alpha;
+ frameData.r = 2.55 * redOffset + red;
+ frameData.g = 2.55 * greenOffset + green;
+ frameData.b = 2.55 * blueOffset + blue;
+
+ frameData.isUseColorInfo = true;
+ }
+
+ var _easing = frameXML.getAttribute(ccs.CONST_A_TWEEN_EASING);
+ if(_easing != null) {
+ if(_easing != ccs.CONST_FL_NAN){
+ tweenEasing = frameXML.getAttribute(ccs.CONST_A_TWEEN_EASING);
+ if( tweenEasing )
+ frameData.tweenEasing = (tweenEasing === 2) ? ccs.TweenType.SINE_EASEINOUT : tweenEasing;
+ } else
+ frameData.tweenEasing = ccs.TweenType.LINEAR;
+ }
+
+ if (parentFrameXml) {
+ //* recalculate frame data from parent frame data, use for translate matrix
+ var helpNode = new ccs.BaseData();
+ if (dataInfo.flashToolVersion >= ccs.CONST_VERSION_2_0) {
+ helpNode.x = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_COCOS2DX_X));
+ helpNode.y = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_COCOS2DX_Y));
+ } else {
+ helpNode.x = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_X));
+ helpNode.y = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_Y));
+ }
+ helpNode.skewX = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_SKEW_X));
+ helpNode.skewY = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_SKEW_Y));
+
+ helpNode.y = -helpNode.y;
+ helpNode.skewX = cc.degreesToRadians(helpNode.skewX);
+ helpNode.skewY = cc.degreesToRadians(-helpNode.skewY);
+ ccs.TransformHelp.transformFromParent(frameData, helpNode);
+ }
+ return frameData;
+ },
+
+ /**
+ * Decodes json data of frame.
+ * @param {Object} json
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.FrameData}
+ */
+ decodeFrameFromJson: function (json, dataInfo) {
+ var frameData = new ccs.FrameData();
+
+ this.decodeNodeFromJson(frameData, json, dataInfo);
+
+ frameData.tweenEasing = json[ccs.CONST_A_TWEEN_EASING] || ccs.TweenType.LINEAR;
+ frameData.displayIndex = json[ccs.CONST_A_DISPLAY_INDEX];
+ var bd_src = json[ccs.CONST_A_BLEND_SRC] == null ? cc.BLEND_SRC : json[ccs.CONST_A_BLEND_SRC];
+ var bd_dst = json[ccs.CONST_A_BLEND_DST] == null ? cc.BLEND_DST : json[ccs.CONST_A_BLEND_DST];
+ frameData.blendFunc.src = bd_src;
+ frameData.blendFunc.dst = bd_dst;
+ frameData.isTween = json[ccs.CONST_A_TWEEN_FRAME] == null ? true : json[ccs.CONST_A_TWEEN_FRAME];
+
+ var event = json[ccs.CONST_A_EVENT];
+ if(event != null){
+ frameData.strEvent = event;
+ frameData.event = event;
+ }
+
+ if (dataInfo.cocoStudioVersion < ccs.CONST_VERSION_COMBINED)
+ frameData.duration = json[ccs.CONST_A_DURATION] == null ? 1 : json[ccs.CONST_A_DURATION];
+ else
+ frameData.frameID = json[ccs.CONST_A_FRAME_INDEX];
+
+ var twEPs = json[ccs.CONST_A_EASING_PARAM] || [];
+ for (var i = 0; i < twEPs.length; i++) {
+ frameData.easingParams[i] = twEPs[i];
+ }
+
+ return frameData;
+ },
+
+ /**
+ * Decodes xml data of texture
+ * @param {XMLDocument} textureXML
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.TextureData}
+ */
+ decodeTexture: function (textureXML, dataInfo) {
+ var textureData = new ccs.TextureData();
+ textureData.init();
+
+ if (textureXML.getAttribute(ccs.CONST_A_NAME)) {
+ textureData.name = textureXML.getAttribute(ccs.CONST_A_NAME);
+ }
+
+ var px, py;
+
+ if (dataInfo.flashToolVersion >= ccs.CONST_VERSION_2_0) {
+ px = parseFloat(textureXML.getAttribute(ccs.CONST_A_COCOS2D_PIVOT_X)) || 0;
+ py = parseFloat(textureXML.getAttribute(ccs.CONST_A_COCOS2D_PIVOT_Y)) || 0;
+ } else {
+ px = parseFloat(textureXML.getAttribute(ccs.CONST_A_PIVOT_X)) || 0;
+ py = parseFloat(textureXML.getAttribute(ccs.CONST_A_PIVOT_Y)) || 0;
+ }
+
+ var width = parseFloat(textureXML.getAttribute(ccs.CONST_A_WIDTH)) || 0;
+ var height = parseFloat(textureXML.getAttribute(ccs.CONST_A_HEIGHT)) || 0;
+
+ var anchorPointX = px / width;
+ var anchorPointY = (height - py) / height;
+
+ textureData.pivotX = anchorPointX;
+ textureData.pivotY = anchorPointY;
+
+ var contoursXML = textureXML.querySelectorAll(ccs.CONST_SUB_TEXTURE + " > " + ccs.CONST_CONTOUR);
+ for (var i = 0; i < contoursXML.length; i++) {
+ textureData.addContourData(this.decodeContour(contoursXML[i], dataInfo));
+ }
+ return textureData;
+ },
+
+ /**
+ * Decodes json data of Texture.
+ * @param json
+ * @returns {ccs.TextureData}
+ */
+ decodeTextureFromJson: function (json) {
+ var textureData = new ccs.TextureData();
+ textureData.init();
+
+ var name = json[ccs.CONST_A_NAME];
+ if(name != null)
+ textureData.name = name;
+
+ textureData.width = json[ccs.CONST_A_WIDTH] || 0;
+ textureData.height = json[ccs.CONST_A_HEIGHT] || 0;
+ textureData.pivotX = json[ccs.CONST_A_PIVOT_X] || 0;
+ textureData.pivotY = json[ccs.CONST_A_PIVOT_Y] || 0;
+
+ var contourDataList = json[ccs.CONST_CONTOUR_DATA] || [];
+ for (var i = 0; i < contourDataList.length; i++) {
+ textureData.contourDataList.push(this.decodeContourFromJson(contourDataList[i]));
+ }
+ return textureData;
+ },
+
+ /**
+ * Decodes xml data of contour.
+ * @param {XMLDocument} contourXML
+ * @param {ccs.DataInfo} dataInfo
+ * @returns {ccs.ContourData}
+ */
+ decodeContour: function (contourXML, dataInfo) {
+ var contourData = new ccs.ContourData();
+ contourData.init();
+
+ var vertexDatasXML = contourXML.querySelectorAll(ccs.CONST_CONTOUR + " > " + ccs.CONST_CONTOUR_VERTEX);
+ var vertexDataXML;
+ for (var i = 0; i < vertexDatasXML.length; i++) {
+ vertexDataXML = vertexDatasXML[i];
+ var vertex = cc.p(0, 0);
+ vertex.x = parseFloat(vertexDataXML.getAttribute(ccs.CONST_A_X)) || 0;
+ vertex.y = parseFloat(vertexDataXML.getAttribute(ccs.CONST_A_Y)) || 0;
+
+ vertex.y = - vertex.y;
+ contourData.vertexList.push(vertex);
+ }
+ return contourData;
+ },
+
+ /**
+ * Decodes json data of contour.
+ * @param {Object} json
+ * @returns {ccs.ContourData}
+ */
+ decodeContourFromJson: function (json) {
+ var contourData = new ccs.ContourData();
+ contourData.init();
+
+ var vertexPointList = json[ccs.CONST_VERTEX_POINT] || [];
+ var len = vertexPointList.length;
+ for (var i = 0; i < len; i++) {
+ var dic = vertexPointList[i];
+ var vertex = cc.p(0, 0);
+ vertex.x = dic[ccs.CONST_A_X] || 0;
+ vertex.y = dic[ccs.CONST_A_Y] || 0;
+ contourData.vertexList.push(vertex);
+ }
+ return contourData;
+ },
+
+ /**
+ * Adds json armature data to armature data manager.
+ * @param {Object} dic json armature data
+ * @param {ccs.DataInfo} dataInfo
+ */
+ addDataFromJsonCache: function (dic, dataInfo) {
+ dataInfo.contentScale = dic[ccs.CONST_CONTENT_SCALE] == null ? 1 : dic[ccs.CONST_CONTENT_SCALE];
+
+ // Decode armatures
+ var armatureDataArr = dic[ccs.CONST_ARMATURE_DATA] || [], i;
+ var armatureData;
+ for (i = 0; i < armatureDataArr.length; i++) {
+ armatureData = this.decodeArmatureFromJSON(armatureDataArr[i], dataInfo);
+ ccs.armatureDataManager.addArmatureData(armatureData.name, armatureData, dataInfo.filename);
+ }
+
+ // Decode animations
+ var animationDataArr = dic[ccs.CONST_ANIMATION_DATA] || [];
+ var animationData;
+ for (i = 0; i < animationDataArr.length; i++) {
+ animationData = this.decodeAnimationFromJson(animationDataArr[i], dataInfo);
+ ccs.armatureDataManager.addAnimationData(animationData.name, animationData, dataInfo.filename);
+ }
+
+ // Decode textures
+ var textureDataArr = dic[ccs.CONST_TEXTURE_DATA] || [];
+ var textureData;
+ for (i = 0; i < textureDataArr.length; i++) {
+ textureData = this.decodeTextureFromJson(textureDataArr[i], dataInfo);
+ ccs.armatureDataManager.addTextureData(textureData.name, textureData, dataInfo.filename);
+ }
+
+ // Auto load sprite file
+ var autoLoad = dataInfo.asyncStruct == null ? ccs.armatureDataManager.isAutoLoadSpriteFile() : dataInfo.asyncStruct.autoLoadSpriteFile;
+// if (isLoadSpriteFrame) {
+ if (autoLoad) {
+ var configFiles = dic[ccs.CONST_CONFIG_FILE_PATH] || [];
+ var locFilePath, locPos, locPlistPath, locImagePath;
+ for (i = 0; i < configFiles.length; i++) {
+ locFilePath = configFiles[i];
+ locPos = locFilePath.lastIndexOf(".");
+ locFilePath = locFilePath.substring(0, locPos);
+ locPlistPath = dataInfo.basefilePath + locFilePath + ".plist";
+ locImagePath = dataInfo.basefilePath + locFilePath + ".png";
+ ccs.armatureDataManager.addSpriteFrameFromFile(locPlistPath, locImagePath, dataInfo.filename);
+ }
+ }
+
+ armatureData = null;
+ animationData = null;
+ },
+
+ /**
+ * Decodes json data of node.
+ * @param node
+ * @param json
+ * @param dataInfo
+ */
+ decodeNodeFromJson: function (node, json, dataInfo) {
+ node.x = json[ccs.CONST_A_X] * this._positionReadScale;
+ node.y = json[ccs.CONST_A_Y] * this._positionReadScale;
+
+ node.x *= dataInfo.contentScale;
+ node.y *= dataInfo.contentScale;
+
+ node.zOrder = json[ccs.CONST_A_Z];
+
+ node.skewX = json[ccs.CONST_A_SKEW_X] || 0;
+ node.skewY = json[ccs.CONST_A_SKEW_Y] || 0;
+ node.scaleX = json[ccs.CONST_A_SCALE_X] == null ? 1 : json[ccs.CONST_A_SCALE_X];
+ node.scaleY = json[ccs.CONST_A_SCALE_Y] == null ? 1 : json[ccs.CONST_A_SCALE_Y];
+
+ var colorDic;
+ if (dataInfo.cocoStudioVersion < ccs.VERSION_COLOR_READING) {
+ colorDic = json[0];
+ if (colorDic){
+ node.a = colorDic[ccs.CONST_A_ALPHA] == null ? 255 : colorDic[ccs.CONST_A_ALPHA];
+ node.r = colorDic[ccs.CONST_A_RED] == null ? 255 : colorDic[ccs.CONST_A_RED];
+ node.g = colorDic[ccs.CONST_A_GREEN] == null ? 255 : colorDic[ccs.CONST_A_GREEN];
+ node.b = colorDic[ccs.CONST_A_BLUE] == null ? 255 : colorDic[ccs.CONST_A_BLUE];
+ node.isUseColorInfo = true;
+ }
+ } else {
+ colorDic = json[ccs.CONST_COLOR_INFO] || null;
+ if (colorDic){
+ node.a = colorDic[ccs.CONST_A_ALPHA] == null ? 255 : colorDic[ccs.CONST_A_ALPHA];
+ node.r = colorDic[ccs.CONST_A_RED] == null ? 255 : colorDic[ccs.CONST_A_RED];
+ node.g = colorDic[ccs.CONST_A_GREEN] == null ? 255 : colorDic[ccs.CONST_A_GREEN];
+ node.b = colorDic[ccs.CONST_A_BLUE] == null ? 255 : colorDic[ccs.CONST_A_BLUE];
+ node.isUseColorInfo = true;
+ }
+ }
+ },
+
+ clear: function () {
+ this._configFileList = [];
+ this._asyncRefCount = 0;
+ this._asyncRefTotalCount = 0;
+ },
+
+ _asyncCallBack: function (selector, target, percent) {
+ if(selector && cc.isFunction(selector))
+ selector.call(target, percent);
+ if(target && selector && typeof selector === 'string')
+ target[selector](percent);
+ },
+ /**
+ * find the base file path
+ * @param filePath
+ * @returns {String}
+ * @private
+ */
+ _initBaseFilePath: function (filePath) {
+ var path = filePath;
+ var pos = path.lastIndexOf("/");
+ if (pos > -1)
+ path = path.substr(0, pos + 1);
+ else
+ path = "";
+ return path;
+ },
+
+ /**
+ * Adds xml armature data to armature data manager.
+ * @param {XMLDocument} xml
+ * @param {ccs.DataInfo} dataInfo
+ */
+ addDataFromXML: function (xml, dataInfo) {
+ /*
+ * Need to get the full path of the xml file, or the Tiny XML can't find the xml at IOS
+ */
+ var xmlStr = cc.loader.getRes(xml);
+ if (!xmlStr) throw new Error("Please load the resource first : " + xml);
+ var skeletonXML = cc.saxParser.parse(xmlStr);
+ var skeleton = skeletonXML.documentElement;
+ if (skeleton)
+ this.addDataFromCache(skeleton, dataInfo);
+ },
+
+ /**
+ * Adds json armature data to armature data manager.
+ * @param {String} filePath
+ * @param {ccs.DataInfo} dataInfo
+ */
+ addDataFromJson: function (filePath, dataInfo) {
+ var fileContent = cc.loader.getRes(filePath);
+ this.addDataFromJsonCache(fileContent, dataInfo);
+ }
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCSpriteFrameCacheHelper.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCSpriteFrameCacheHelper.js
new file mode 100644
index 0000000..a0496e9
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCSpriteFrameCacheHelper.js
@@ -0,0 +1,68 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * ccs.spriteFrameCacheHelper is a singleton object, it's a sprite frame cache helper
+ * @class
+ * @name ccs.spriteFrameCacheHelper
+ */
+ccs.spriteFrameCacheHelper = /** @lends ccs.spriteFrameCacheHelper# */ {
+ _textureAtlasDic:{},
+ _imagePaths:[],
+
+ /**
+ * Adds sprite frame from file
+ * @param plistPath
+ * @param imagePath
+ */
+ addSpriteFrameFromFile:function (plistPath, imagePath) {
+ cc.spriteFrameCache.addSpriteFrames(plistPath, imagePath);
+ },
+
+ /**
+ * Returns texture atlas with texture.
+ * @param texture
+ * @returns {*}
+ */
+ getTextureAtlasWithTexture:function (texture) {
+ //todo
+ return null;
+ var textureName = texture.getName();
+ var atlas = this._textureAtlasDic[textureName];
+ if (atlas == null) {
+ atlas = new cc.TextureAtlas(texture, 20);
+ this._textureAtlasDic[textureName] = atlas;
+ }
+ return atlas;
+ },
+
+ /**
+ * Clear the sprite frame cache's data.
+ */
+ clear: function () {
+ this._textureAtlasDic = {};
+ this._imagePaths = [];
+ }
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCTransformHelp.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCTransformHelp.js
new file mode 100644
index 0000000..0d6228d
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCTransformHelp.js
@@ -0,0 +1,183 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * use to calculate the matrix of node from parent node
+ * @class ccs.TransformHelp
+ * @extend ccs.Class
+ */
+ccs.TransformHelp = ccs.TransformHelp || ccs.Class.extend({});
+
+ccs.TransformHelp.helpMatrix1 = cc.affineTransformMake(1, 0, 0, 1, 0, 0);
+ccs.TransformHelp.helpMatrix2 = cc.affineTransformMake(1, 0, 0, 1, 0, 0);
+ccs.TransformHelp.helpPoint1 = cc.p(0, 0);
+ccs.TransformHelp.helpPoint2 = cc.p(0, 0);
+ccs.TransformHelp.helpParentNode = {};
+
+/**
+ * Calculate a BaseData's transform matrix from parent node.
+ * @function
+ * @static
+ * @param {ccs.BaseData} bone
+ * Constructor
+ */
+ccs.TransformHelp.transformFromParent = function (bone, parentNode) {
+ this.nodeToMatrix(bone, this.helpMatrix1);
+ this.nodeToMatrix(parentNode, this.helpMatrix2);
+
+ this.helpMatrix2 = cc.affineTransformInvert(this.helpMatrix2);
+ this.helpMatrix1 = cc.affineTransformConcat(this.helpMatrix1, this.helpMatrix2);
+
+ this.matrixToNode(this.helpMatrix1, bone);
+};
+
+ccs.TransformHelp.transformToParent = function(node, parentNode){
+ this.nodeToMatrix(node, this.helpMatrix1);
+ this.nodeToMatrix(parentNode, this.helpMatrix2);
+
+ this.helpMatrix1 = cc.affineTransformConcat(this.helpMatrix1, this.helpMatrix2);
+
+ this.matrixToNode(this.helpMatrix1, node);
+};
+
+ccs.TransformHelp.transformFromParentWithoutScale = function(node, parentNode){
+// this.helpParentNode.copy(&parentNode);
+
+ for(var p in parentNode){
+ this.helpParentNode[p] = parentNode[p];
+ }
+ this.helpParentNode.scaleX = 1;
+ this.helpParentNode.scaleY = 1;
+
+ this.nodeToMatrix(node, this.helpMatrix1);
+ this.nodeToMatrix(this.helpParentNode, this.helpMatrix2);
+
+ this.helpMatrix2 = cc.affineTransformInvert(this.helpMatrix2);
+ this.helpMatrix1 = cc.affineTransformConcat(this.helpMatrix1, this.helpMatrix2);
+
+ this.matrixToNode(this.helpMatrix1, node);
+};
+
+ccs.TransformHelp.transformToParentWithoutScale = function(node, parentNode){
+ for(var p in parentNode){
+ this.helpParentNode[p] = parentNode[p];
+ }
+ this.helpParentNode.scaleX = 1;
+ this.helpParentNode.scaleY = 1;
+
+ this.nodeToMatrix(node, this.helpMatrix1);
+ this.nodeToMatrix(this.helpParentNode, this.helpMatrix2);
+
+ this.helpMatrix1 = cc.affineTransformConcat(this.helpMatrix1, this.helpMatrix2);
+
+ this.matrixToNode(this.helpMatrix1, node);
+
+};
+
+/**
+ * @function
+ * @static
+ * @param {ccs.BaseData} node
+ * @param {cc.AffineTransform} matrix
+ */
+ccs.TransformHelp.nodeToMatrix = function (node, matrix) {
+ if (node.skewX === -node.skewY) {
+ var sine = Math.sin(node.skewX);
+ var cosine = Math.cos(node.skewX);
+ matrix.a = node.scaleX * cosine;
+ matrix.b = node.scaleX * -sine;
+ matrix.c = node.scaleY * sine;
+ matrix.d = node.scaleY * cosine;
+ } else {
+ matrix.a = node.scaleX * Math.cos(node.skewY);
+ matrix.b = node.scaleX * Math.sin(node.skewY);
+ matrix.c = node.scaleY * Math.sin(node.skewX);
+ matrix.d = node.scaleY * Math.cos(node.skewX);
+ }
+ matrix.tx = node.x;
+ matrix.ty = node.y;
+};
+
+/**
+ * @function
+ * @static
+ * @param {cc.AffineTransform} matrix
+ * @param {ccs.BaseData} node
+ */
+ccs.TransformHelp.matrixToNode = function (matrix, node) {
+ /*
+ * In as3 language, there is a function called "deltaTransformPoint", it calculate a point used give Transform
+ * but not used the tx, ty value. we simulate the function here
+ */
+ this.helpPoint1.x = 0;
+ this.helpPoint1.y = 1;
+ this.helpPoint1 = cc.pointApplyAffineTransform(this.helpPoint1, matrix);
+ this.helpPoint1.x -= matrix.tx;
+ this.helpPoint1.y -= matrix.ty;
+
+ this.helpPoint2.x = 1;
+ this.helpPoint2.y = 0;
+ this.helpPoint2 = cc.pointApplyAffineTransform(this.helpPoint2, matrix);
+ this.helpPoint2.x -= matrix.tx;
+ this.helpPoint2.y -= matrix.ty;
+
+ node.skewX = -(Math.atan2(this.helpPoint1.y, this.helpPoint1.x) - 1.5707964); //todo
+ //node.skewX = -Math.atan2(this.helpPoint2.y, this.helpPoint2.x);
+ node.skewY = Math.atan2(this.helpPoint2.y, this.helpPoint2.x);
+ node.scaleX = Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b);
+ node.scaleY = Math.sqrt(matrix.c * matrix.c + matrix.d * matrix.d);
+ node.x = matrix.tx;
+ node.y = matrix.ty;
+};
+
+/**
+ * @function
+ * @static
+ * @param {ccs.BaseData} target
+ * @param {ccs.BaseData} source
+ */
+ccs.TransformHelp.nodeConcat = function (target, source) {
+ target.x += source.x;
+ target.y += source.y;
+ target.skewX += source.skewX;
+ target.skewY += source.skewY;
+ target.scaleX += source.scaleX;
+ target.scaleY += source.scaleY;
+};
+
+/**
+ * @function
+ * @static
+ * @param {ccs.BaseData} target
+ * @param {ccs.BaseData} source
+ */
+ccs.TransformHelp.nodeSub = function (target, source) {
+ target.x -= source.x;
+ target.y -= source.y;
+ target.skewX -= source.skewX;
+ target.skewY -= source.skewY;
+ target.scaleX -= source.scaleX;
+ target.scaleY -= source.scaleY;
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCTweenFunction.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCTweenFunction.js
new file mode 100644
index 0000000..7ced7fa
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCTweenFunction.js
@@ -0,0 +1,501 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * TweenType
+ * @type Object
+ */
+ccs.TweenType = {
+ CUSTOM_EASING: -1,
+ LINEAR: 0,
+
+ SINE_EASEIN: 1,
+ SINE_EASEOUT: 2,
+ SINE_EASEINOUT: 3,
+
+ QUAD_EASEIN: 4,
+ QUAD_EASEOUT: 5,
+ QUAD_EASEINOUT: 6,
+
+ CUBIC_EASEIN: 7,
+ CUBIC_EASEOUT: 8,
+ CUBIC_EASEINOUT: 9,
+
+ QUART_EASEIN: 10,
+ QUART_EASEOUT: 11,
+ QUART_EASEINOUT: 12,
+
+ QUINT_EASEIN: 13,
+ QUINT_EASEOUT: 14,
+ QUINT_EASEINOUT: 15,
+
+ EXPO_EASEIN: 16,
+ EXPO_EASEOUT: 17,
+ EXPO_EASEINOUT: 18,
+
+ CIRC_EASEIN: 19,
+ CIRC_EASEOUT: 20,
+ CIRC_EASEINOUT: 21,
+
+ ELASTIC_EASEIN: 22,
+ ELASTIC_EASEOUT: 23,
+ ELASTIC_EASEINOUT: 24,
+
+ BACK_EASEIN: 25,
+ BACK_EASEOUT: 26,
+ BACK_EASEINOUT: 27,
+
+ BOUNCE_EASEIN: 28,
+ BOUNCE_EASEOUT: 29,
+ BOUNCE_EASEINOUT: 30,
+
+ TWEEN_EASING_MAX: 10000
+};
+
+ccs.TweenFunction = ccs.TweenFunction || ccs.Class.extend({});
+
+ccs.DOUBLE_PI = ccs.M_PI_X_2 = Math.PI * 2;
+ccs.HALF_PI = ccs.M_PI_2 = Math.PI / 2;
+ccs.M_PI = Math.PI;
+
+ccs.TweenFunction.tweenTo = function (time, type, easingParam) {
+ var delta = 0;
+
+ switch (type) {
+ case ccs.TweenType.CUSTOM_EASING:
+ delta = this.customEase(time, easingParam);
+ break;
+ case ccs.TweenType.LINEAR:
+ delta = this.linear(time);
+ break;
+ case ccs.TweenType.SINE_EASEIN:
+ delta = this.sineEaseIn(time);
+ break;
+ case ccs.TweenType.SINE_EASEOUT:
+ delta = this.sineEaseOut(time);
+ break;
+ case ccs.TweenType.SINE_EASEINOUT:
+ delta = this.sineEaseInOut(time);
+ break;
+
+ case ccs.TweenType.QUAD_EASEIN:
+ delta = this.quadEaseIn(time);
+ break;
+ case ccs.TweenType.QUAD_EASEOUT:
+ delta = this.quadEaseOut(time);
+ break;
+ case ccs.TweenType.QUAD_EASEINOUT:
+ delta = this.quadEaseInOut(time);
+ break;
+
+ case ccs.TweenType.CUBIC_EASEIN:
+ delta = this.cubicEaseIn(time);
+ break;
+ case ccs.TweenType.CUBIC_EASEOUT:
+ delta = this.cubicEaseOut(time);
+ break;
+ case ccs.TweenType.CUBIC_EASEINOUT:
+ delta = this.cubicEaseInOut(time);
+ break;
+
+ case ccs.TweenType.QUART_EASEIN:
+ delta = this.quartEaseIn(time);
+ break;
+ case ccs.TweenType.QUART_EASEOUT:
+ delta = this.quartEaseOut(time);
+ break;
+ case ccs.TweenType.QUART_EASEINOUT:
+ delta = this.quartEaseInOut(time);
+ break;
+
+ case ccs.TweenType.QUINT_EASEIN:
+ delta = this.quintEaseIn(time);
+ break;
+ case ccs.TweenType.QUINT_EASEOUT:
+ delta = this.quintEaseOut(time);
+ break;
+ case ccs.TweenType.QUINT_EASEINOUT:
+ delta = this.quintEaseInOut(time);
+ break;
+
+ case ccs.TweenType.EXPO_EASEIN:
+ delta = this.expoEaseIn(time);
+ break;
+ case ccs.TweenType.EXPO_EASEOUT:
+ delta = this.expoEaseOut(time);
+ break;
+ case ccs.TweenType.EXPO_EASEINOUT:
+ delta = this.expoEaseInOut(time);
+ break;
+
+ case ccs.TweenType.CIRC_EASEIN:
+ delta = this.circEaseIn(time);
+ break;
+ case ccs.TweenType.CIRC_EASEOUT:
+ delta = this.circEaseOut(time);
+ break;
+ case ccs.TweenType.CIRC_EASEINOUT:
+ delta = this.circEaseInOut(time);
+ break;
+
+ case ccs.TweenType.ELASTIC_EASEIN:
+ var period = 0.3;
+ if(null != easingParam && easingParam.length > 0){
+ period = easingParam[0];
+ }
+ delta = this.elasticEaseIn(time, period);
+ break;
+ case ccs.TweenType.ELASTIC_EASEOUT:
+ var period = 0.3;
+ if(null != easingParam && easingParam.length > 0){
+ period = easingParam[0];
+ }
+ delta = this.elasticEaseOut(time, period);
+ break;
+ case ccs.TweenType.ELASTIC_EASEINOUT:
+ var period = 0.3;
+ if(null != easingParam && easingParam.length > 0){
+ period = easingParam[0];
+ }
+ delta = this.elasticEaseInOut(time, period);
+ break;
+
+ case ccs.TweenType.BACK_EASEIN:
+ delta = this.backEaseIn(time);
+ break;
+ case ccs.TweenType.BACK_EASEOUT:
+ delta = this.backEaseOut(time);
+ break;
+ case ccs.TweenType.BACK_EASEINOUT:
+ delta = this.backEaseInOut(time);
+ break;
+
+ case ccs.TweenType.BOUNCE_EASEIN:
+ delta = this.bounceEaseIn(time);
+ break;
+ case ccs.TweenType.BOUNCE_EASEOUT:
+ delta = this.bounceEaseOut(time);
+ break;
+ case ccs.TweenType.BOUNCE_EASEINOUT:
+ delta = this.bounceEaseInOut(time);
+ break;
+
+ default:
+ delta = this.sineEaseInOut(time);
+ break;
+ }
+
+ return delta;
+};
+
+
+// Linear
+ccs.TweenFunction.linear = function (time) {
+ return time;
+};
+
+
+// Sine Ease
+ccs.TweenFunction.sineEaseIn = function (time) {
+ return -1 * Math.cos(time * ccs.HALF_PI) + 1;
+};
+ccs.TweenFunction.sineEaseOut = function (time) {
+ return Math.sin(time * ccs.HALF_PI);
+};
+ccs.TweenFunction.sineEaseInOut = function (time) {
+ return -0.5 * (Math.cos(ccs.M_PI * time) - 1);
+};
+
+
+// Quad Ease
+ccs.TweenFunction.quadEaseIn = function (time) {
+ return time * time;
+};
+ccs.TweenFunction.quadEaseOut = function (time) {
+ return -1 * time * (time - 2);
+};
+ccs.TweenFunction.quadEaseInOut = function (time) {
+ time = time * 2;
+ if (time < 1)
+ return 0.5 * time * time;
+ --time;
+ return -0.5 * (time * (time - 2) - 1);
+};
+
+
+// Cubic Ease
+ccs.TweenFunction.cubicEaseIn = function (time) {
+ return time * time * time;
+};
+ccs.TweenFunction.cubicEaseOut = function (time) {
+ time -= 1;
+ return (time * time * time + 1);
+};
+ccs.TweenFunction.cubicEaseInOut = function (time) {
+ time = time * 2;
+ if (time < 1)
+ return 0.5 * time * time * time;
+ time -= 2;
+ return 0.5 * (time * time * time + 2);
+};
+
+
+// Quart Ease
+ccs.TweenFunction.quartEaseIn = function (time) {
+ return time * time * time * time;
+};
+ccs.TweenFunction.quartEaseOut = function (time) {
+ time -= 1;
+ return -(time * time * time * time - 1);
+};
+ccs.TweenFunction.quartEaseInOut = function (time) {
+ time = time * 2;
+ if (time < 1)
+ return 0.5 * time * time * time * time;
+ time -= 2;
+ return -0.5 * (time * time * time * time - 2);
+};
+
+
+// Quint Ease
+ccs.TweenFunction.quintEaseIn = function (time) {
+ return time * time * time * time * time;
+};
+ccs.TweenFunction.quintEaseOut = function (time) {
+ time -= 1;
+ return (time * time * time * time * time + 1);
+};
+ccs.TweenFunction.quintEaseInOut = function (time) {
+ time = time * 2;
+ if (time < 1)
+ return 0.5 * time * time * time * time * time;
+ time -= 2;
+ return 0.5 * (time * time * time * time * time + 2);
+};
+
+
+// Expo Ease
+ccs.TweenFunction.expoEaseIn = function (time) {
+ return time === 0 ? 0 : Math.pow(2, 10 * (time - 1)) - 0.001;
+};
+ccs.TweenFunction.expoEaseOut = function (time) {
+ return time === 1 ? 1 : (-Math.pow(2, -10 * time) + 1);
+};
+ccs.TweenFunction.expoEaseInOut = function (time) {
+ time /= 0.5;
+ if (time < 1) {
+ time = 0.5 * Math.pow(2, 10 * (time - 1));
+ }
+ else {
+ time = 0.5 * (-Math.pow(2, -10 * (time - 1)) + 2);
+ }
+
+ return time;
+};
+
+
+// Circ Ease
+ccs.TweenFunction.circEaseIn = function (time) {
+ return -1 * (Math.sqrt(1 - time * time) - 1);
+};
+ccs.TweenFunction.circEaseOut = function (time) {
+ time = time - 1;
+ return Math.sqrt(1 - time * time);
+};
+ccs.TweenFunction.circEaseInOut = function (time) {
+ time = time * 2;
+ if (time < 1)
+ return -0.5 * (Math.sqrt(1 - time * time) - 1);
+ time -= 2;
+ return 0.5 * (Math.sqrt(1 - time * time) + 1);
+};
+
+
+// Elastic Ease
+ccs.TweenFunction.elasticEaseIn = function (time, easingParam) {
+ var period = 0.3;
+
+ if (easingParam.length > 0) {
+ period = easingParam[0];
+ }
+
+ var newT = 0;
+ if (time === 0 || time === 1) {
+ newT = time;
+ }
+ else {
+ var s = period / 4;
+ time = time - 1;
+ newT = -Math.pow(2, 10 * time) * Math.sin((time - s) * ccs.DOUBLE_PI / period);
+ }
+
+ return newT;
+};
+ccs.TweenFunction.elasticEaseOut = function (time, easingParam) {
+ var period = 0.3;
+
+ if (easingParam.length > 0) {
+ period = easingParam[0];
+ }
+
+ var newT = 0;
+ if (time === 0 || time === 1) {
+ newT = time;
+ }
+ else {
+ var s = period / 4;
+ newT = Math.pow(2, -10 * time) * Math.sin((time - s) * ccs.DOUBLE_PI / period) + 1;
+ }
+
+ return newT;
+};
+ccs.TweenFunction.elasticEaseInOut = function (time, easingParam) {
+ var period = 0.3;
+
+ if (easingParam.length > 0) {
+ period = easingParam[0];
+ }
+
+ var newT = 0;
+ if (time === 0 || time === 1) {
+ newT = time;
+ }
+ else {
+ time = time * 2;
+ if (!period) {
+ period = 0.3 * 1.5;
+ }
+
+ var s = period / 4;
+
+ time = time - 1;
+ if (time < 0) {
+ newT = -0.5 * Math.pow(2, 10 * time) * Math.sin((time - s) * ccs.DOUBLE_PI / period);
+ } else {
+ newT = Math.pow(2, -10 * time) * Math.sin((time - s) * ccs.DOUBLE_PI / period) * 0.5 + 1;
+ }
+ }
+ return newT;
+};
+
+
+// Back Ease
+ccs.TweenFunction.backEaseIn = function (time) {
+ var overshoot = 1.70158;
+ return time * time * ((overshoot + 1) * time - overshoot);
+};
+ccs.TweenFunction.backEaseOut = function (time) {
+ var overshoot = 1.70158;
+
+ time = time - 1;
+ return time * time * ((overshoot + 1) * time + overshoot) + 1;
+};
+ccs.TweenFunction.backEaseInOut = function (time) {
+ var overshoot = 1.70158 * 1.525;
+
+ time = time * 2;
+ if (time < 1) {
+ return (time * time * ((overshoot + 1) * time - overshoot)) / 2;
+ }
+ else {
+ time = time - 2;
+ return (time * time * ((overshoot + 1) * time + overshoot)) / 2 + 1;
+ }
+};
+
+
+// Bounce Ease
+ccs.bounceTime = function (time) {
+ if (time < 1 / 2.75) {
+ return 7.5625 * time * time;
+ } else if (time < 2 / 2.75) {
+ time -= 1.5 / 2.75;
+ return 7.5625 * time * time + 0.75;
+ } else if (time < 2.5 / 2.75) {
+ time -= 2.25 / 2.75;
+ return 7.5625 * time * time + 0.9375;
+ }
+
+ time -= 2.625 / 2.75;
+ return 7.5625 * time * time + 0.984375;
+};
+ccs.TweenFunction.bounceEaseIn = function (time) {
+ return 1 - ccs.bounceTime(1 - time);
+};
+
+ccs.TweenFunction.bounceEaseOut = function (time) {
+ return ccs.bounceTime(time);
+};
+
+ccs.TweenFunction.bounceEaseInOut = function (time) {
+ var newT = 0;
+ if (time < 0.5) {
+ time = time * 2;
+ newT = (1 - ccs.bounceTime(1 - time)) * 0.5;
+ } else {
+ newT = ccs.bounceTime(time * 2 - 1) * 0.5 + 0.5;
+ }
+
+ return newT;
+};
+
+
+// Custom Ease
+ccs.TweenFunction.customEase = function (time, easingParam) {
+ if (easingParam.length > 0) {
+ var tt = 1 - time;
+ return easingParam[1] * tt * tt * tt + 3 * easingParam[3] * time * tt * tt + 3 * easingParam[5] * time * time * tt + easingParam[7] * time * time * time;
+ }
+ return time;
+};
+
+ccs.TweenFunction.easeIn = function(time, rate){
+ return Math.pow(time, rate);
+};
+
+ccs.TweenFunction.easeOut = function(time, rate){
+ return Math.pow(time, 1 / rate);
+};
+
+ccs.TweenFunction.easeInOut = function(time, rate){
+ time *= 2;
+ if(time < 1){
+ return 0.5 * Math.pow(time, rate);
+ }else{
+ return 1 - 0.5 * Math.pow(2 - time, rate);
+ }
+};
+
+ccs.TweenFunction.quadraticIn = function(time){
+ return Math.pow(time, 2);
+};
+
+ccs.TweenFunction.quadraticOut = function(time){
+ return -time * (time - 2);
+};
+
+ccs.TweenFunction.bezieratFunction = function(a, b, c, d, t){
+ return (Math.pow(1-t,3) * a + 3*t*(Math.pow(1-t,2))*b + 3*Math.pow(t,2)*(1-t)*c + Math.pow(t,3)*d );
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCUtilMath.js b/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCUtilMath.js
new file mode 100644
index 0000000..082ec35
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/armature/utils/CCUtilMath.js
@@ -0,0 +1,69 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+var ENABLE_PHYSICS_DETECT = false;
+ccs.fmodf = function (x, y) {
+ while (x > y) {
+ x -= y;
+ }
+ return x;
+};
+var CC_SAFE_RELEASE = function (obj) {
+ if (obj && obj.release) {
+ obj.release();
+ }
+};
+
+ccs.isSpriteContainPoint = function (sprite, point, outPoint) {
+ var p = sprite.convertToNodeSpace(point);
+ if (outPoint) {
+ outPoint.x = p.x;
+ outPoint.y = p.y;
+ }
+ var s = sprite.getContentSize();
+ return cc.rectContainsPoint(cc.rect(0, 0, s.width, s.height), p);
+};
+ccs.SPRITE_CONTAIN_POINT = ccs.isSpriteContainPoint;
+ccs.SPRITE_CONTAIN_POINT_WITH_RETURN = ccs.isSpriteContainPoint;
+
+ccs.extBezierTo = function (t, point1, point2, point3, point4) {
+ var p = cc.p(0, 0);
+ if (point3 && !point4) {
+ p.x = Math.pow((1 - t), 2) * point1.x + 2 * t * (1 - t) * point2.x + Math.pow(t, 2) * point3.x;
+ p.y = Math.pow((1 - t), 2) * point1.y + 2 * t * (1 - t) * point2.y + Math.pow(t, 2) * point3.y;
+ }
+ if (point4) {
+ p.x = point1.x * Math.pow((1 - t), 3) + 3 * t * point2.x * Math.pow((1 - t), 2) + 3 * point3.x * Math.pow(t, 2) * (1 - t) + point4.x * Math.pow(t, 3);
+ p.y = point1.y * Math.pow((1 - t), 3) + 3 * t * point2.y * Math.pow((1 - t), 2) + 3 * point3.y * Math.pow(t, 2) * (1 - t) + point4.y * Math.pow(t, 3);
+ }
+ return p;
+};
+
+ccs.extCircleTo = function (t, center, radius, fromRadian, radianDif) {
+ var p = cc.p(0, 0);
+ p.x = center.x + radius * Math.cos(fromRadian + radianDif * t);
+ p.y = center.y + radius * Math.sin(fromRadian + radianDif * t);
+ return p;
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComAttribute.js b/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComAttribute.js
new file mode 100644
index 0000000..0575b93
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComAttribute.js
@@ -0,0 +1,210 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The attribute component for Cocostudio.
+ * @class
+ * @extends ccs.Component
+ */
+ccs.ComAttribute = ccs.Component.extend(/** @lends ccs.ComAttribute# */{
+ _jsonDict: null,
+ _filePath: "",
+
+ /**
+ * Construction of ccs.ComAttribute
+ */
+ ctor: function () {
+ cc.Component.prototype.ctor.call(this);
+ this._jsonDict = {};
+ this._filePath = "";
+ this._name = "CCComAttribute";
+ ccs.ComAttribute.prototype.init.call(this);
+ },
+
+ /**
+ * Initializes a ccs.ComAttribute
+ * @returns {boolean}
+ */
+ init: function () {
+ this._jsonDict = {};
+ return true;
+ },
+
+ /**
+ * Sets int attribute
+ * @param {String} key
+ * @param {number} value
+ */
+ setInt: function (key, value) {
+ if (!key) {
+ cc.log("Argument must be non-nil");
+ return;
+ }
+ this._jsonDict[key] = value;
+ },
+
+ /**
+ * Sets double attribute
+ * @param {String} key
+ * @param {number} value
+ */
+ setDouble: function (key, value) {
+ if (!key) {
+ cc.log("Argument must be non-nil");
+ return;
+ }
+ this._jsonDict[key] = value;
+ },
+
+ /**
+ * Sets float attribute
+ * @param {String} key
+ * @param {number} value
+ */
+ setFloat: function (key, value) {
+ if (!key) {
+ cc.log("Argument must be non-nil");
+ return;
+ }
+ this._jsonDict[key] = value;
+ },
+
+ /**
+ * Sets boolean attribute
+ * @param {String} key
+ * @param {Boolean} value
+ */
+ setBool: function (key, value) {
+ if (!key) {
+ cc.log("Argument must be non-nil");
+ return;
+ }
+ this._jsonDict[key] = value;
+ },
+
+ /**
+ * Sets string attribute
+ * @param {String} key
+ * @param {Boolean} value
+ */
+ setString: function (key, value) {
+ if (!key) {
+ cc.log("Argument must be non-nil");
+ return;
+ }
+ this._jsonDict[key] = value;
+ },
+
+ /**
+ * Sets object attribute
+ * @param {String} key
+ * @param {Object} value
+ */
+ setObject: function (key, value) {
+ if (!key) {
+ cc.log("Argument must be non-nil");
+ return;
+ }
+ this._jsonDict[key] = value;
+ },
+
+ /**
+ * Returns int value from attribute
+ * @param {String} key
+ * @returns {Number}
+ */
+ getInt: function (key) {
+ var ret = this._jsonDict[key];
+ return parseInt(ret || 0);
+ },
+
+ /**
+ * Returns double value from attribute
+ * @param {String} key
+ * @returns {Number}
+ */
+ getDouble: function (key) {
+ var ret = this._jsonDict[key];
+ return parseFloat(ret || 0.0);
+ },
+
+ /**
+ * Returns float value from attribute
+ * @param {String} key
+ * @returns {Number}
+ */
+ getFloat: function (key) {
+ var ret = this._jsonDict[key];
+ return parseFloat(ret || 0.0);
+ },
+
+ /**
+ * Returns boolean value from attribute
+ * @param {String} key
+ * @returns {Boolean}
+ */
+ getBool: function (key) {
+ var ret = this._jsonDict[key];
+ return Boolean(ret || false);
+ },
+
+ /**
+ * Returns string value from attribute
+ * @param {String} key
+ * @returns {String}
+ */
+ getString: function (key) {
+ var ret = this._jsonDict[key];
+ return ret || "";
+ },
+
+ /**
+ * Returns object value from attribute
+ * @param {String} key
+ * @returns {Object}
+ */
+ getObject: function (key) {
+ return this._jsonDict[key];
+ },
+
+ /**
+ * Parses json file.
+ * @param filename
+ */
+ parse:function(filename){
+ this._jsonDict = cc.loader.getRes(filename);
+ }
+});
+/**
+ * allocates and initializes a ComAttribute.
+ * @deprecated since v3.0, please use new construction instead.
+ * @return {ccs.ComAttribute}
+ * @example
+ * // example
+ * var com = ccs.ComAttribute.create();
+ */
+ccs.ComAttribute.create = function () {
+ return new ccs.ComAttribute();
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComAudio.js b/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComAudio.js
new file mode 100644
index 0000000..0b15af0
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComAudio.js
@@ -0,0 +1,285 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The audio component for Cocostudio.
+ * @class
+ * @extends ccs.Component
+ */
+ccs.ComAudio = ccs.Component.extend(/** @lends ccs.ComAudio# */{
+ _filePath: "",
+ _loop: false,
+
+ /**
+ * Construction of ccs.ComAudio
+ */
+ ctor: function () {
+ cc.Component.prototype.ctor.call(this);
+ this._name = "Audio";
+ ccs.ComAudio.prototype.init.call(this);
+ },
+
+ /**
+ * Initializes a ccs.ComAudio.
+ * @returns {boolean}
+ */
+ init: function () {
+ return true;
+ },
+
+ /**
+ * The callback calls when a audio component enter stage.
+ * @override
+ */
+ onExit: function () {
+ this.stopBackgroundMusic(true);
+ this.stopAllEffects();
+ },
+
+ /**
+ * Stops all audios.
+ */
+ end: function () {
+ cc.audioEngine.end();
+ },
+
+ /**
+ * Preload background music resource
+ * @param {String} pszFilePath
+ */
+ preloadBackgroundMusic: function (pszFilePath) {
+ cc.loader.load(pszFilePath);
+ },
+
+ /**
+ * Play background music
+ * @param {String} [pszFilePath]
+ * @param {Boolean} [loop]
+ */
+ playBackgroundMusic: function (pszFilePath, loop) {
+ if(pszFilePath){
+ cc.audioEngine.playMusic(pszFilePath, loop);
+ }else{
+ cc.audioEngine.playMusic(this._filePath, this._loop);
+ }
+ },
+
+ /**
+ * Stop background music
+ * @param {String} releaseData
+ */
+ stopBackgroundMusic: function (releaseData) {
+ cc.audioEngine.stopMusic(releaseData);
+ },
+
+ /**
+ * Pause background music
+ */
+ pauseBackgroundMusic: function () {
+ cc.audioEngine.pauseMusic();
+ },
+
+ /**
+ * Resume background music
+ */
+ resumeBackgroundMusic: function () {
+ cc.audioEngine.resumeMusic();
+ },
+
+ /**
+ * Rewind background music
+ */
+ rewindBackgroundMusic: function () {
+ cc.audioEngine.rewindMusic();
+ },
+
+ /**
+ * Indicates whether any background music can be played or not.
+ * @returns {boolean}
+ */
+ willPlayBackgroundMusic: function () {
+ return cc.audioEngine.willPlayMusic();
+ },
+
+ /**
+ * Whether the music is playing.
+ * @returns {Boolean}
+ */
+ isBackgroundMusicPlaying: function () {
+ return cc.audioEngine.isMusicPlaying();
+ },
+
+ /**
+ * The volume of the music max value is 1.0,the min value is 0.0 .
+ * @returns {Number}
+ */
+ getBackgroundMusicVolume: function () {
+ return cc.audioEngine.getMusicVolume();
+ },
+
+ /**
+ * Set the volume of music.
+ * @param {Number} volume must be in 0.0~1.0 .
+ */
+ setBackgroundMusicVolume: function (volume) {
+ cc.audioEngine.setMusicVolume(volume);
+ },
+
+ /**
+ * The volume of the effects max value is 1.0,the min value is 0.0 .
+ * @returns {Number}
+ */
+ getEffectsVolume: function () {
+ return cc.audioEngine.getEffectsVolume();
+ },
+
+ /**
+ * Set the volume of sound effects.
+ * @param {Number} volume
+ */
+ setEffectsVolume: function (volume) {
+ cc.audioEngine.setEffectsVolume(volume);
+ },
+
+ /**
+ * Play sound effect.
+ * @param {String} [pszFilePath]
+ * @param {Boolean} [loop]
+ * @returns {Boolean}
+ */
+ playEffect: function (pszFilePath, loop) {
+ if (pszFilePath)
+ return cc.audioEngine.playEffect(pszFilePath, loop);
+ else
+ return cc.audioEngine.playEffect(this._filePath, this._loop);
+ },
+
+ /**
+ * Pause playing sound effect.
+ * @param {Number} soundId
+ */
+ pauseEffect: function (soundId) {
+ cc.audioEngine.pauseEffect(soundId);
+ },
+
+ /**
+ * Pause all effects
+ */
+ pauseAllEffects: function () {
+ cc.audioEngine.pauseAllEffects();
+ },
+
+ /**
+ * Resume effect
+ * @param {Number} soundId
+ */
+ resumeEffect: function (soundId) {
+ cc.audioEngine.resumeEffect(soundId);
+ },
+
+ /**
+ * Resume all effects
+ */
+ resumeAllEffects: function () {
+ cc.audioEngine.resumeAllEffects();
+ },
+
+ /**
+ * Stop effect
+ * @param {Number} soundId
+ */
+ stopEffect: function (soundId) {
+ cc.audioEngine.stopEffect(soundId);
+ },
+
+ /**
+ * stop all effects
+ */
+ stopAllEffects: function () {
+ cc.audioEngine.stopAllEffects();
+ },
+
+ /**
+ * Preload effect
+ * @param {String} pszFilePath
+ */
+ preloadEffect: function (pszFilePath) {
+ cc.loader.getRes(pszFilePath);
+ this.setFile(pszFilePath);
+ this.setLoop(false);
+ },
+
+ /**
+ * Unload effect
+ * @param {String} pszFilePath
+ */
+ unloadEffect: function (pszFilePath) {
+ cc.audioEngine.unloadEffect(pszFilePath);
+ },
+
+ /**
+ * File path setter
+ * @param {String} pszFilePath
+ */
+ setFile: function (pszFilePath) {
+ this._filePath = pszFilePath;
+ },
+
+ /**
+ * Sets audio component whether plays loop
+ * @param {Boolean} loop
+ */
+ setLoop: function (loop) {
+ this._loop = loop;
+ },
+
+ /**
+ * Returns the file path of audio component.
+ * @returns {string}
+ */
+ getFile: function () {
+ return this._filePath;
+ },
+
+ /**
+ * Returns audio component whether plays loop
+ * @returns {boolean}
+ */
+ isLoop: function () {
+ return this._loop;
+ }
+});
+
+/**
+ * allocates and initializes a ComAudio.
+ * @deprecated since v3.0, please use new construction instead.
+ * @return {ccs.ComAudio}
+ * @example
+ * // example
+ * var com = ccs.ComAudio.create();
+ */
+ccs.ComAudio.create = function () {
+ return new ccs.ComAudio();
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComController.js b/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComController.js
new file mode 100644
index 0000000..cdd85ee
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComController.js
@@ -0,0 +1,76 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The controller component for Cocostudio.
+ * @class
+ * @extends ccs.Component
+ */
+ccs.ComController = ccs.Component.extend(/** @lends ccs.ComController# */{
+ /**
+ * Construction of ccs.ComController.
+ */
+ ctor: function () {
+ cc.Component.prototype.ctor.call(this);
+ this._name = "ComController";
+ ccs.ComController.prototype.init.call(this);
+ },
+
+ /**
+ * The callback calls when controller component enter stage.
+ * @override
+ */
+ onEnter: function () {
+ if (this._owner !== null)
+ this._owner.scheduleUpdate();
+ },
+
+ /**
+ * Returns controller component whether is enabled
+ * @returns {Boolean}
+ */
+ isEnabled: function () {
+ return this._enabled;
+ },
+
+ /**
+ * Sets controller component whether is enabled
+ * @param {Boolean} bool
+ */
+ setEnabled: function (bool) {
+ this._enabled = bool;
+ }
+});
+/**
+ * Allocates and initializes a ComController.
+ * @deprecated since v3.0, please use new construction instead.
+ * @return {ccs.ComController}
+ * @example
+ * // example
+ * var com = ccs.ComController.create();
+ */
+ccs.ComController.create = function () {
+ return new ccs.ComController();
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComRender.js b/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComRender.js
new file mode 100644
index 0000000..960e096
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComRender.js
@@ -0,0 +1,91 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The render component for Cocostudio.
+ * @class
+ * @extends ccs.Component
+ */
+ccs.ComRender = ccs.Component.extend(/** @lends ccs.ComRender# */{
+ _render: null,
+ /**
+ * Construction of ccs.ComRender
+ * @param {cc.Node} node
+ * @param {String} comName
+ */
+ ctor: function (node, comName) {
+ cc.Component.prototype.ctor.call(this);
+ this._render = node;
+ this._name = comName;
+ this.isRenderer = true;
+ ccs.ComRender.prototype.init.call(this);
+ },
+
+ /**
+ * The callback calls when a render component enter stage.
+ */
+ onEnter: function () {
+ if (this._owner)
+ this._owner.addChild(this._render);
+ },
+
+ /**
+ * The callback calls when a render component exit stage.
+ */
+ onExit: function () {
+ if (this._owner) {
+ this._owner.removeChild(this._render, true);
+ this._render = null;
+ }
+ },
+
+ /**
+ * Returns a render node
+ * @returns {cc.Node}
+ */
+ getNode: function () {
+ return this._render;
+ },
+
+ /**
+ * Sets a render node to component.
+ * @param {cc.Node} node
+ */
+ setNode: function (node) {
+ this._render = node;
+ }
+});
+
+/**
+ * allocates and initializes a ComRender.
+ * @deprecated since v3.0, please use new construction instead.
+ * @return {ccs.ComRender}
+ * @example
+ * // example
+ * var com = ccs.ComRender.create();
+ */
+ccs.ComRender.create = function (node, comName) {
+ return new ccs.ComRender(node, comName);
+};
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComponent.js b/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComponent.js
new file mode 100644
index 0000000..5084a97
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComponent.js
@@ -0,0 +1,136 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The base class of component in CocoStudio
+ * @class
+ * @extends cc.Class
+ */
+cc.Component = cc.Class.extend(/** @lends cc.Component# */{
+ _owner: null,
+ _name: "",
+ _enabled: true,
+
+ /**
+ * Construction of cc.Component
+ */
+ ctor:function(){
+ this._owner = null;
+ this._name = "";
+ this._enabled = true;
+ },
+
+ /**
+ * Initializes a cc.Component.
+ * @returns {boolean}
+ */
+ init:function(){
+ return true;
+ },
+
+ /**
+ * The callback when a component enter stage.
+ */
+ onEnter:function(){
+ },
+
+ /**
+ * The callback when a component exit stage.
+ */
+ onExit:function(){
+ },
+
+ /**
+ * The callback per every frame if it schedules update.
+ * @param delta
+ */
+ update:function(delta){
+ },
+
+ /**
+ * Serialize a component object.
+ * @param reader
+ */
+ serialize:function( reader){
+ },
+
+ /**
+ * Returns component whether is enabled.
+ * @returns {boolean}
+ */
+ isEnabled:function(){
+ return this._enabled;
+ },
+
+ /**
+ * Sets component whether is enabled.
+ * @param enable
+ */
+ setEnabled:function(enable){
+ this._enabled = enable;
+ },
+
+ /**
+ * Returns the name of cc.Component.
+ * @returns {string}
+ */
+ getName:function(){
+ return this._name;
+ } ,
+
+ /**
+ * Sets the name to cc.Component.
+ * @param {String} name
+ */
+ setName:function(name){
+ this._name = name;
+ } ,
+
+ /**
+ * Sets the owner to cc.Component.
+ * @param owner
+ */
+ setOwner:function(owner){
+ this._owner = owner;
+ },
+
+ /**
+ * Returns the owner of cc.Component.
+ * @returns {*}
+ */
+ getOwner:function(){
+ return this._owner;
+ }
+});
+
+/**
+ * Allocates and initializes a component.
+ * @deprecated since v3.0, please use new construction instead.
+ * @return {cc.Component}
+ */
+cc.Component.create = function(){
+ return new cc.Component();
+};
+
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComponentContainer.js b/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComponentContainer.js
new file mode 100644
index 0000000..0b9b461
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/components/CCComponentContainer.js
@@ -0,0 +1,159 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The component container for Cocostudio, it has some components.
+ * @class
+ * @extends cc.Class
+ */
+cc.ComponentContainer = cc.Class.extend(/** @lends cc.ComponentContainer# */{
+ _components:null,
+ _owner:null,
+
+ /**
+ * Construction of cc.ComponentContainer
+ * @param node
+ */
+ ctor:function(node){
+ this._components = null;
+ this._owner = node;
+ },
+
+ /**
+ * Gets component by name.
+ * @param name
+ * @returns {*}
+ */
+ getComponent:function(name){
+ if(!name)
+ throw new Error("cc.ComponentContainer.getComponent(): name should be non-null");
+ name = name.trim();
+ if(!this._components){
+ this._components = {};
+ }
+ return this._components[name];
+ },
+
+ /**
+ * Adds a component to container
+ * @param {cc.Component} component
+ * @returns {boolean}
+ */
+ add:function(component){
+ if(!component)
+ throw new Error("cc.ComponentContainer.add(): component should be non-null");
+ if(component.getOwner()){
+ cc.log("cc.ComponentContainer.add(): Component already added. It can't be added again");
+ return false;
+ }
+
+ if(this._components == null){
+ this._components = {};
+ this._owner.scheduleUpdate();
+ }
+ var oldComponent = this._components[component.getName()];
+ if(oldComponent){
+ cc.log("cc.ComponentContainer.add(): Component already added. It can't be added again");
+ return false;
+ }
+ component.setOwner(this._owner);
+ this._components[component.getName()] = component;
+ component.onEnter();
+ return true;
+ },
+
+ /**
+ * Removes component from container by name or component object.
+ * @param {String|cc.Component} name component name or component object.
+ * @returns {boolean}
+ */
+ remove:function(name){
+ if(!name)
+ throw new Error("cc.ComponentContainer.remove(): name should be non-null");
+ if(!this._components)
+ return false;
+ if(name instanceof cc.Component)
+ return this._removeByComponent(name);
+ else {
+ name = name.trim();
+ return this._removeByComponent(this._components[name]);
+ }
+ },
+
+ _removeByComponent:function(component){
+ if(!component)
+ return false;
+ component.onExit();
+ component.setOwner(null);
+ delete this._components[component.getName()];
+ return true;
+ },
+
+ /**
+ * Removes all components of container.
+ */
+ removeAll:function(){
+ if(!this._components)
+ return;
+ var locComponents = this._components;
+ for(var selKey in locComponents){
+ var selComponent = locComponents[selKey];
+ selComponent.onExit();
+ selComponent.setOwner(null);
+ delete locComponents[selKey];
+ }
+ this._owner.unscheduleUpdate();
+ this._components = null;
+ },
+
+ _alloc:function(){
+ this._components = {};
+ },
+
+ /**
+ * Visit callback by director. it calls every frame.
+ * @param {Number} delta
+ */
+ visit:function(delta){
+ if(!this._components)
+ return;
+
+ var locComponents = this._components;
+ for(var selKey in locComponents)
+ locComponents[selKey].update(delta);
+ },
+
+ /**
+ * Returns the container whether is empty.
+ * @returns {boolean}
+ */
+ isEmpty: function () {
+ if (!this._components)
+ return true;
+ return this._components.length === 0;
+ }
+});
+
+
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/loader/load.js b/frameworks/cocos2d-html5/extensions/cocostudio/loader/load.js
new file mode 100644
index 0000000..bf75cce
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/loader/load.js
@@ -0,0 +1,280 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+ccs._load = (function () {
+
+ /**
+ * load file
+ * @param {String} file
+ * @param {String} [type=] - ccui|node|action
+ * @param {String} [path=] - Resource search path
+ * @returns {*}
+ */
+ var load = function (file, type, path) {
+
+ var json = cc.loader.getRes(file);
+
+ if (!json)
+ return cc.log("%s does not exist", file);
+ var ext = extname(file).toLocaleLowerCase();
+ if (ext !== "json" && ext !== "exportjson")
+ return cc.log("%s load error, must be json file", file);
+
+ var parse;
+ if (!type) {
+ if (json["widgetTree"])
+ parse = parser["ccui"];
+ else if (json["nodeTree"])
+ parse = parser["timeline"];
+ else if (json["Content"] && json["Content"]["Content"])
+ parse = parser["timeline"];
+ else if (json["gameobjects"])
+ parse = parser["scene"];
+ } else {
+ parse = parser[type];
+ }
+
+ if (!parse) {
+ cc.log("Can't find the parser : %s", file);
+ return new cc.Node();
+ }
+ var version = json["version"] || json["Version"];
+ if (!version && json["armature_data"]) {
+ cc.warn("%s is armature. please use:", file);
+ cc.warn(" ccs.armatureDataManager.addArmatureFileInfoAsync(%s);", file);
+ cc.warn(" var armature = new ccs.Armature('name');");
+ return new cc.Node();
+ }
+ var currentParser = getParser(parse, version);
+ if (!currentParser) {
+ cc.log("Can't find the parser : %s", file);
+ return new cc.Node();
+ }
+
+ return currentParser.parse(file, json, path) || null;
+ };
+
+ var parser = {
+ "ccui": {},
+ "timeline": {},
+ "action": {},
+ "scene": {}
+ };
+
+ load.registerParser = function (name, version, target) {
+ if (!name || !version || !target)
+ return cc.log("register parser error");
+ if (!parser[name])
+ parser[name] = {};
+ parser[name][version] = target;
+ };
+
+ load.getParser = function (name, version) {
+ if (name && version)
+ return parser[name] ? parser[name][version] : undefined;
+ if (name)
+ return parser[name];
+ return parser;
+ };
+
+ //Gets the file extension
+ var extname = function (fileName) {
+ var arr = fileName.match(extnameReg);
+ return ( arr && arr[1] ) ? arr[1] : null;
+ };
+ var extnameReg = /\.([^\.]+)$/;
+
+
+ var parserReg = /([^\.](\.\*)?)*$/;
+ var getParser = function (parser, version) {
+ if (parser[version])
+ return parser[version];
+ else if (version === "*")
+ return null;
+ else
+ return getParser(parser, version.replace(parserReg, "*"));
+ };
+
+ return load;
+
+})();
+
+ccs._parser = cc.Class.extend({
+
+ ctor: function () {
+ this.parsers = {};
+ },
+
+ _dirnameReg: /\S*\//,
+ _dirname: function (path) {
+ var arr = path.match(this._dirnameReg);
+ return (arr && arr[0]) ? arr[0] : "";
+ },
+
+ getClass: function (json) {
+ return json["classname"];
+ },
+
+ getNodeJson: function (json) {
+ return json["widgetTree"];
+ },
+
+ parse: function (file, json, resourcePath) {
+ resourcePath = resourcePath || this._dirname(file);
+ this.pretreatment(json, resourcePath);
+ var node = this.parseNode(this.getNodeJson(json), resourcePath, file);
+ node && this.deferred(json, resourcePath, node, file);
+ return node;
+ },
+
+ pretreatment: function (json, resourcePath, file) {
+ },
+
+ deferred: function (json, resourcePath, node, file) {
+ },
+
+ parseNode: function (json, resourcePath) {
+ var parser = this.parsers[this.getClass(json)];
+ var widget = null;
+ if (parser)
+ widget = parser.call(this, json, resourcePath);
+ else
+ cc.log("Can't find the parser : %s", this.getClass(json));
+
+ return widget;
+ },
+
+ registerParser: function (widget, parse) {
+ this.parsers[widget] = parse;
+ }
+});
+
+/**
+ * Analysis of studio JSON file
+ * The incoming file name, parse out the corresponding object
+ * Temporary support file list:
+ * ui 1.*
+ * node 1.* - 2.*
+ * action 1.* - 2.*
+ * scene 0.* - 1.*
+ * @param {String} file
+ * @param {String} [path=] Resource path
+ * @returns {{node: cc.Node, action: cc.Action}}
+ */
+ccs.load = function (file, path) {
+ var object = {
+ node: null,
+ action: null
+ };
+
+ object.node = ccs._load(file, null, path);
+ object.action = ccs._load(file, "action", path);
+ if (object.action && object.action.tag === -1 && object.node)
+ object.action.tag = object.node.tag;
+ return object;
+};
+ccs.load.validate = {};
+
+ccs.load.preload = true;
+
+/**
+ * Analysis of studio JSON file and layout ui widgets by visible size.
+ * The incoming file name, parse out the corresponding object
+ * Temporary support file list:
+ * ui 1.*
+ * node 1.* - 2.*
+ * action 1.* - 2.*
+ * scene 0.* - 1.*
+ * @param {String} file
+ * @param {String} [path=] Resource path
+ * @returns {{node: cc.Node, action: cc.Action}}
+ */
+ccs.loadWithVisibleSize = function (file, path) {
+ var object = ccs.load(file, path);
+ var size = cc.director.getVisibleSize();
+ if (object.node && size) {
+ object.node.setContentSize(size.width, size.height);
+ ccui.helper.doLayout(object.node);
+ }
+ return object;
+};
+
+//Forward compatible interface
+
+ccs.actionTimelineCache = {
+
+
+ //@deprecated This function will be deprecated sooner or later please use ccs.load
+ /**
+ * Create Timeline Action
+ * @param file
+ * @returns {*}
+ */
+ createAction: function (file) {
+ return ccs._load(file, "action");
+ }
+};
+
+ccs.csLoader = {
+
+ //@deprecated This function will be deprecated sooner or later please use ccs.load
+ /**
+ * Create Timeline Node
+ * @param file
+ * @returns {*}
+ */
+ createNode: function (file) {
+ return ccs._load(file);
+ }
+};
+
+cc.loader.register(["json"], {
+ load: function (realUrl, url, res, cb) {
+ cc.loader.loadJson(realUrl, function (error, data) {
+ var path = cc.path;
+ if (data && data["Content"] && data["Content"]["Content"]["UsedResources"]) {
+ var UsedResources = data["Content"]["Content"]["UsedResources"],
+ dirname = path.dirname(url),
+ list = [],
+ tmpUrl, normalUrl;
+ for (var i = 0; i < UsedResources.length; i++) {
+ if (!ccs.load.preload && /\.(png|jpg$)/.test(UsedResources[i]))
+ continue;
+ tmpUrl = path.join(dirname, UsedResources[i]);
+ normalUrl = path._normalize(tmpUrl);
+ if (!ccs.load.validate[normalUrl]) {
+ ccs.load.validate[normalUrl] = true;
+ list.push(normalUrl);
+ }
+ }
+ cc.loader.load(list, function () {
+ cb(error, data);
+ });
+ } else {
+ cb(error, data);
+ }
+
+ });
+ }
+});
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/action-1.x.js b/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/action-1.x.js
new file mode 100644
index 0000000..f3b6ff1
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/action-1.x.js
@@ -0,0 +1,233 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function(load, baseParser){
+
+ var Parser = baseParser.extend({
+
+ getNodeJson: function(json){
+ return json["action"];
+ },
+
+ parseNode: function(json, resourcePath, file){
+ if(!json)
+ return null;
+
+ var self = this,
+ action = new ccs.ActionTimeline();
+
+ action.setDuration(json["duration"]);
+ action.setTimeSpeed(json["speed"] || 1);
+ //The process of analysis
+ var timelines = json["timelines"];
+ timelines.forEach(function(timeline){
+ var parser = self.parsers[timeline["frameType"]];
+ var frame;
+ if(parser)
+ frame = parser.call(self, timeline, resourcePath);
+ else
+ cc.log("parser does not exist : %s", timeline["frameType"]);
+ if(frame)
+ action.addTimeline(frame);
+
+ if(timeline["frameType"] === "ColorFrame"){
+ action.addTimeline(
+ self.parsers["AlphaFrame"].call(self, timeline, resourcePath)
+ );
+ }
+ });
+
+ return action;
+ }
+
+ });
+
+ var parser = new Parser();
+
+ var frameList = [
+ {
+ name: "PositionFrame",
+ handle: function(options){
+ var frame = new ccs.PositionFrame();
+ var x = options["x"];
+ var y = options["y"];
+ frame.setPosition(cc.p(x,y));
+ return frame;
+ }
+ },
+ {
+ name: "VisibleFrame",
+ handle: function(options){
+ var frame = new ccs.VisibleFrame();
+ var visible = options["value"];
+ frame.setVisible(visible);
+ return frame;
+ }
+ },
+ {
+ name: "ScaleFrame",
+ handle: function(options){
+ var frame = new ccs.ScaleFrame();
+ var scalex = options["x"];
+ var scaley = options["y"];
+ frame.setScaleX(scalex);
+ frame.setScaleY(scaley);
+ return frame;
+ }
+ },
+ {
+ name: "RotationFrame",
+ handle: function(options){
+ var frame = new ccs.RotationFrame();
+ var rotation = options["rotation"];
+ frame.setRotation(rotation);
+ return frame;
+ }
+ },
+ {
+ name: "SkewFrame",
+ handle: function(options){
+ var frame = new ccs.SkewFrame();
+ var skewx = options["x"];
+ var skewy = options["y"];
+ frame.setSkewX(skewx);
+ frame.setSkewY(skewy);
+ return frame;
+ }
+ },
+ {
+ name: "RotationSkewFrame",
+ handle: function(options){
+ var frame = new ccs.RotationSkewFrame();
+ var skewx = options["x"];
+ var skewy = options["y"];
+ frame.setSkewX(skewx);
+ frame.setSkewY(skewy);
+ return frame;
+ }
+ },
+ {
+ name: "AnchorFrame",
+ handle: function(options){
+ var frame = new ccs.AnchorPointFrame();
+ var anchorx = options["x"];
+ var anchory = options["y"];
+ frame.setAnchorPoint(cc.p(anchorx, anchory));
+ return frame;
+ }
+ },
+ {
+ name: "InnerActionFrame",
+ handle: function(options){
+ var frame = new ccs.InnerActionFrame();
+ var type = options["innerActionType"];
+ var startFrame = options["startFrame"];
+ frame.setInnerActionType(type);
+ frame.setStartFrameIndex(startFrame);
+ return frame;
+ }
+ },
+ {
+ name: "ColorFrame",
+ handle: function(options){
+ var frame = new ccs.ColorFrame();
+ var red = options["red"];
+ var green = options["green"];
+ var blue = options["blue"];
+ frame.setColor(cc.color(red, green, blue));
+ var alphaFrame = new ccs.AlphaFrame();
+ var alpha = options["alpha"];
+ alphaFrame.setAlpha(alpha);
+ return frame;
+ }
+ },
+ {
+ name: "AlphaFrame",
+ handle: function(options){
+ var frame = new ccs.AlphaFrame();
+ var alpha = options["alpha"];
+ frame.setAlpha(alpha);
+ return frame;
+ }
+ },
+ {
+ name: "TextureFrame",
+ handle: function(options){
+ var frame = new ccs.TextureFrame();
+ var texture = options["value"];
+ if(texture != null) {
+ var path = texture;
+ var spriteFrame = cc.spriteFrameCache.getSpriteFrame(path);
+ if(spriteFrame == null){
+ var jsonPath = ccs.csLoader.getJsonPath();
+ path = jsonPath + texture;
+ }
+ frame.setTextureName(path);
+ }
+ return frame;
+ }
+ },
+ {
+ name: "EventFrame",
+ handle: function(options){
+ var frame = new ccs.EventFrame();
+ var evnt = options["value"];
+ if(evnt != null)
+ frame.setEvent(evnt);
+ return frame;
+ }
+ },
+ {
+ name: "ZOrderFrame",
+ handle: function(options){
+ var frame = new ccs.ZOrderFrame();
+ var zorder = options["value"];
+ frame.setZOrder(zorder);
+ return frame;
+ }
+ }
+ ];
+
+ frameList.forEach(function(item){
+ parser.registerParser(item.name, function(options, resourcePath){
+ var timeline = new ccs.Timeline();
+ timeline.setActionTag(options["actionTag"]);
+
+ var frames = options["frames"];
+ if(frames && frames.length){
+ frames.forEach(function(frameData){
+ var frame = item.handle(frameData);
+ frame.setFrameIndex(frameData["frameIndex"]);
+ frame.setTween(frameData["tween"]);
+ timeline.addFrame(frame);
+ });
+ }
+ return timeline;
+ });
+ });
+
+ load.registerParser("action", "0.*", parser);
+ load.registerParser("action", "1.*", parser);
+
+})(ccs._load, ccs._parser);
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/action-2.x.js b/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/action-2.x.js
new file mode 100644
index 0000000..febdad1
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/action-2.x.js
@@ -0,0 +1,310 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function(load, baseParser){
+
+ var Parser = baseParser.extend({
+
+ getNodeJson: function(json){
+ return json["Content"]["Content"]["Animation"];
+ },
+
+ parseNode: function(json, resourcePath, file){
+ if(!json)
+ return null;
+
+ var self = this,
+ action = new ccs.ActionTimeline();
+
+ action.setDuration(json["Duration"]);
+ action.setTimeSpeed(json["Speed"] || 1);
+
+ //The process of analysis
+ var timelines = json["Timelines"];
+ timelines.forEach(function(timeline){
+ var parser = self.parsers[timeline["Property"]];
+ var frame;
+ if(parser)
+ frame = parser.call(self, timeline, resourcePath);
+ else
+ cc.log("parser does not exist : %s", timeline["Property"]);
+ if(frame)
+ action.addTimeline(frame);
+ });
+
+ return action;
+ },
+
+ deferred: function(json, resourcePath, action, file){
+ var animationlist = json["Content"]["Content"]["AnimationList"];
+ var length = animationlist ? animationlist.length : 0;
+ for (var i = 0; i < length; i++){
+ var animationdata = animationlist[i];
+ var info = { name: null, startIndex: null, endIndex: null };
+ info.name = animationdata["Name"];
+ info.startIndex = animationdata["StartIndex"];
+ info.endIndex = animationdata["EndIndex"];
+ action.addAnimationInfo(info);
+ }
+ }
+
+ });
+ var parser = new Parser();
+
+ var frameList = [
+ {
+ name: "Position",
+ handle: function(options){
+ var frame = new ccs.PositionFrame();
+ var x = options["X"];
+ var y = options["Y"];
+ frame.setPosition(cc.p(x,y));
+ return frame;
+ }
+ },
+ {
+ name: "VisibleForFrame",
+ handle: function(options){
+ var frame = new ccs.VisibleFrame();
+ var visible = options["Value"];
+ frame.setVisible(visible);
+ return frame;
+ }
+ },
+ {
+ name: "Scale",
+ handle: function(options){
+ var frame = new ccs.ScaleFrame();
+ var scalex = options["X"];
+ var scaley = options["Y"];
+ frame.setScaleX(scalex);
+ frame.setScaleY(scaley);
+ return frame;
+ }
+ },
+ {
+ name: "Rotation",
+ handle: function(options){
+ var frame = new ccs.RotationFrame();
+ var rotation = options["Rotation"] || options["Value"] || 0;
+ frame.setRotation(rotation);
+ return frame;
+ }
+ },
+ {
+ name: "Skew",
+ handle: function(options){
+ var frame = new ccs.SkewFrame();
+ var skewx = options["X"];
+ var skewy = options["Y"];
+ frame.setSkewX(skewx);
+ frame.setSkewY(skewy);
+ return frame;
+ }
+ },
+ {
+ name: "RotationSkew",
+ handle: function(options){
+ var frame = new ccs.RotationSkewFrame();
+ var skewx = options["X"];
+ var skewy = options["Y"];
+ frame.setSkewX(skewx);
+ frame.setSkewY(skewy);
+ return frame;
+ }
+ },
+ {
+ name: "Anchor",
+ handle: function(options){
+ var frame = new ccs.AnchorPointFrame();
+ var anchorx = options["X"];
+ var anchory = options["Y"];
+ frame.setAnchorPoint(cc.p(anchorx, anchory));
+ return frame;
+ }
+ },{
+ name: "AnchorPoint",
+ handle: function(options){
+ var frame = new ccs.AnchorPointFrame();
+ var anchorx = options["X"];
+ var anchory = options["Y"];
+ frame.setAnchorPoint(cc.p(anchorx, anchory));
+ return frame;
+ }
+ },{
+ name: "InnerAction",
+ handle: function(options){
+ var frame = new ccs.InnerActionFrame();
+ var type = options["InnerActionType"];
+ var startFrame = options["StartFrame"];
+ frame.setInnerActionType(type);
+ frame.setStartFrameIndex(startFrame);
+ return frame;
+ }
+ },
+ {
+ name: "CColor",
+ handle: function(options){
+ var frame = new ccs.ColorFrame();
+ var color = options["Color"];
+ if(!color) color = {};
+ color["R"] = color["R"] === undefined ? 255 : color["R"];
+ color["G"] = color["G"] === undefined ? 255 : color["G"];
+ color["B"] = color["B"] === undefined ? 255 : color["B"];
+ frame.setColor(cc.color(color["R"], color["G"], color["B"]));
+ return frame;
+ }
+ },
+ {
+ name: "Alpha",
+ handle: function(options){
+ var frame = new ccs.AlphaFrame();
+ var alpha = options["Value"];
+ frame.setAlpha(alpha);
+ return frame;
+ }
+ },
+ {
+ name: "FileData",
+ handle: function(options, resourcePath){
+ var frame, texture, plist, path, spriteFrame;
+ frame = new ccs.TextureFrame();
+ texture = options["TextureFile"];
+ if(texture != null) {
+ plist = texture["Plist"];
+ path = texture["Path"];
+ spriteFrame = cc.spriteFrameCache.getSpriteFrame(path);
+ if(!spriteFrame && plist){
+ if(cc.loader.getRes(resourcePath + plist)){
+ cc.spriteFrameCache.addSpriteFrames(resourcePath + plist);
+ spriteFrame = cc.spriteFrameCache.getSpriteFrame(path);
+ }else{
+ cc.log("%s need to be preloaded", resourcePath + plist);
+ }
+ }
+ if(spriteFrame == null){
+ path = resourcePath + path;
+ }
+ frame.setTextureName(path);
+ }
+ return frame;
+ }
+ },
+ {
+ name: "FrameEvent",
+ handle: function(options){
+ var frame = new ccs.EventFrame();
+ var evnt = options["Value"];
+ if(evnt != null)
+ frame.setEvent(evnt);
+ return frame;
+ }
+ },
+ {
+ name: "ZOrder",
+ handle: function(options){
+ var frame = new ccs.ZOrderFrame();
+ var zorder = options["Value"];
+ frame.setZOrder(zorder);
+ return frame;
+ }
+ },
+ {
+ name: "ActionValue",
+ handle: function (options) {
+
+ var frame = new ccs.InnerActionFrame();
+ var innerActionType = options["InnerActionType"];
+
+ var currentAnimationFrame = options["CurrentAniamtionName"];
+
+ var singleFrameIndex = options["SingleFrameIndex"];
+
+ var frameIndex = options["FrameIndex"];
+ if(frameIndex !== undefined)
+ frame.setFrameIndex(frameIndex);
+
+ frame.setInnerActionType(ccs.InnerActionType[innerActionType]);
+ frame.setSingleFrameIndex(singleFrameIndex);
+
+ frame.setEnterWithName(true);
+ if (currentAnimationFrame)
+ frame.setAnimationName(currentAnimationFrame);
+
+ return frame;
+ }
+ },
+ {
+ name: "BlendFunc",
+ handle: function(options){
+ var frame = new ccs.BlendFuncFrame();
+ var blendFunc = options["BlendFunc"];
+ if(blendFunc && blendFunc["Src"] !== undefined && blendFunc["Dst"] !== undefined)
+ frame.setBlendFunc(new cc.BlendFunc(blendFunc["Src"], blendFunc["Dst"]));
+ return frame;
+ }
+ }
+ ];
+
+ var loadEasingDataWithFlatBuffers = function(frame, options){
+ var type = options["Type"];
+ frame.setTweenType(type);
+ var points = options["Points"];
+ var result = [];
+ if(points){
+ points.forEach(function(p){
+ result.push(p["X"]);
+ result.push(p["Y"]);
+ });
+ frame.setEasingParams(result);
+ }
+ };
+
+ frameList.forEach(function(item){
+ parser.registerParser(item.name, function(options, resourcePath){
+ var timeline = new ccs.Timeline();
+ timeline.setActionTag(options["ActionTag"]);
+
+ var frames = options["Frames"];
+ if(frames && frames.length){
+ frames.forEach(function(frameData){
+ var frame = item.handle(frameData, resourcePath);
+ frame.setFrameIndex(frameData["FrameIndex"]);
+ var tween = frameData["Tween"] != null ? frameData["Tween"] : true;
+ frame.setTween(tween);
+ //https://github.com/cocos2d/cocos2d-x/pull/11388/files
+ var easingData = frameData["EasingData"];
+ if(easingData)
+ loadEasingDataWithFlatBuffers(frame, easingData);
+ timeline.addFrame(frame);
+ });
+ }
+ return timeline;
+ });
+ });
+
+ load.registerParser("action", "2.*", parser);
+ load.registerParser("action", "*", parser);
+
+})(ccs._load, ccs._parser);
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/compatible.js b/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/compatible.js
new file mode 100644
index 0000000..9a73bdb
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/compatible.js
@@ -0,0 +1,253 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+
+/*
+ This file is for compatibility compatibility with older versions of GUIReader and SceneReader
+ todo: deprecated all
+ */
+
+(function () {
+
+ ccs.uiReader = {
+
+ _fileDesignSizes: {},
+
+ //@deprecated This function will be deprecated sooner or later please use ccs.load
+ /**
+ * Create CCUI Node
+ * @param file
+ * @returns {*}
+ */
+ widgetFromJsonFile: function (file) {
+ var json = cc.loader.getRes(file);
+ if (json)
+ this._fileDesignSizes[file] = cc.size(json["designWidth"] || 0, json["designHeight"] || 0);
+
+ var version = json["Version"] || json["version"];
+ var versionNum = ccs.uiReader.getVersionInteger(version);
+ if (!version || versionNum >= 1700) {
+ cc.warn("Not supported file types, Please try use the ccs.load");
+ return null;
+ }
+ return ccs._load(file, "ccui");
+ },
+
+ //@deprecated This function will be deprecated sooner or later please use parser.registerParser
+ /**
+ * Register a custom Widget reader
+ * @param classType
+ * @param ins
+ * @param object
+ * @param callback
+ * @deprecated This function will be deprecated sooner or later please use parser.registerParser
+ */
+ registerTypeAndCallBack: function (classType, ins, object, callback) {
+ var parser = ccs._load.getParser("ccui")["*"];
+ var func = callback.bind(object);
+ parser.registerParser(classType, function (options, resourcePath) {
+ var widget = new ins();
+ var uiOptions = options["options"];
+ object.setPropsFromJsonDictionary && object.setPropsFromJsonDictionary(widget, uiOptions);
+ this.generalAttributes(widget, uiOptions);
+ var customProperty = uiOptions["customProperty"];
+ if (customProperty)
+ customProperty = JSON.parse(customProperty);
+ else
+ customProperty = {};
+ func(classType, widget, customProperty);
+ this.colorAttributes(widget, uiOptions);
+ this.anchorPointAttributes(widget, uiOptions);
+ this.parseChild.call(this, widget, options, resourcePath);
+ return widget;
+ });
+ },
+
+ //@deprecated This function will be deprecated sooner or later
+ /**
+ * Gets the version number by version string.
+ * @param {String} version version string.
+ * @returns {Number}
+ */
+ getVersionInteger: function (version) {
+ if (!version || typeof version !== "string") return 0;
+ var arr = version.split(".");
+ if (arr.length !== 4)
+ return 0;
+ var num = 0;
+ arr.forEach(function (n, i) {
+ num += n * Math.pow(10, 3 - i);
+ });
+ return num;
+ },
+
+ //@deprecated This function will be deprecated sooner or later
+ /**
+ * stores the designSize of UI file.
+ * @param {String} fileName
+ * @param {cc.Size} size
+ */
+ storeFileDesignSize: function (fileName, size) {
+ this._fileDesignSizes[fileName] = size;
+ },
+
+ //@deprecated This function will be deprecated sooner or later
+ /**
+ * Gets the design size by filename.
+ * @param {String} fileName
+ * @returns {cc.Size}
+ */
+ getFileDesignSize: function (fileName) {
+ return this._fileDesignSizes[fileName];
+ },
+
+ //@deprecated This function will be deprecated sooner or later
+ /**
+ * Returns the file path
+ * @returns {string}
+ */
+ getFilePath: function () {
+ return this._filePath;
+ },
+
+ //@deprecated This function will be deprecated sooner or later
+ setFilePath: function (path) {
+ this._filePath = path;
+ },
+
+ //@deprecated This function will be deprecated sooner or later
+ /**
+ * Returns the parsed object map. (analytic function)
+ * @returns {Object}
+ */
+ getParseObjectMap: function () {
+ return ccs._load.getParser("ccui")["*"]["parsers"];
+ },
+
+ //@deprecated This function will be deprecated sooner or later
+ /**
+ * Returns the parsed callback map. (analytic function)
+ * @returns {*}
+ */
+ getParseCallBackMap: function () {
+ return ccs._load.getParser("ccui")["*"]["parsers"];
+ },
+
+ //@deprecated This function will be deprecated sooner or later
+ clear: function () {
+ }
+ };
+
+ var parser = ccs._load.getParser("ccui")["*"];
+ ccs.imageViewReader = {setPropsFromJsonDictionary: parser.ImageViewAttributes};
+ ccs.buttonReader = {setPropsFromJsonDictionary: parser.ButtonAttributes};
+ ccs.checkBoxReader = {setPropsFromJsonDictionary: parser.CheckBoxAttributes};
+ ccs.labelAtlasReader = {setPropsFromJsonDictionary: parser.TextAtlasAttributes};
+ ccs.labelBMFontReader = {setPropsFromJsonDictionary: parser.TextBMFontAttributes};
+ ccs.labelReader = {setPropsFromJsonDictionary: parser.TextAttributes};
+ ccs.layoutReader = {setPropsFromJsonDictionary: parser.LayoutAttributes};
+ ccs.listViewReader = {setPropsFromJsonDictionary: parser.ListViewAttributes};
+ ccs.loadingBarReader = {setPropsFromJsonDictionary: parser.LoadingBarAttributes};
+ ccs.pageViewReader = {setPropsFromJsonDictionary: parser.PageViewAttributes};
+ ccs.scrollViewReader = {setPropsFromJsonDictionary: parser.ScrollViewAttributes};
+ ccs.sliderReader = {setPropsFromJsonDictionary: parser.SliderAttributes};
+ ccs.textFieldReader = {setPropsFromJsonDictionary: parser.TextFieldAttributes};
+})();
+
+(function () {
+ ccs.sceneReader = {
+
+ _node: null,
+
+ //@deprecated This function will be deprecated sooner or later please use ccs.load
+ /**
+ * Create Scene Node
+ * @param file
+ * @returns {*}
+ */
+ createNodeWithSceneFile: function (file) {
+ var node = ccs._load(file, "scene");
+ this._node = node;
+ return node;
+ },
+
+ /**
+ * Get a node by tag.
+ * @param {Number} tag
+ * @returns {cc.Node|null}
+ */
+ getNodeByTag: function (tag) {
+ if (this._node == null)
+ return null;
+ if (this._node.getTag() === tag)
+ return this._node;
+ return this._nodeByTag(this._node, tag);
+ },
+
+ _nodeByTag: function (parent, tag) {
+ if (parent == null)
+ return null;
+ var retNode = null;
+ var children = parent.getChildren();
+ for (var i = 0; i < children.length; i++) {
+ var child = children[i];
+ if (child && child.getTag() === tag) {
+ retNode = child;
+ break;
+ } else {
+ retNode = this._nodeByTag(child, tag);
+ if (retNode)
+ break;
+ }
+ }
+ return retNode;
+ },
+
+ //@deprecated This function will be deprecated sooner or later
+ /**
+ * Returns the version of ccs.SceneReader.
+ * @returns {string}
+ */
+ version: function () {
+ return "*";
+ },
+
+ //@deprecated This function will be deprecated sooner or later
+ /**
+ * Sets the listener to reader.
+ * Cannot use
+ */
+ setTarget: function () {
+ },
+
+ //@deprecated This function will be deprecated sooner or later
+ /**
+ * Clear all triggers and stops all sounds.
+ */
+ clear: function () {
+ ccs.triggerManager.removeAll();
+ cc.audioEngine.end();
+ }
+ };
+})();
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/scene-1.x.js b/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/scene-1.x.js
new file mode 100644
index 0000000..8982f26
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/scene-1.x.js
@@ -0,0 +1,264 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function (load, baseParser) {
+
+ var Parser = baseParser.extend({
+
+ getNodeJson: function (json) {
+ return json;
+ },
+
+ parseNode: function (json, resourcePath) {
+ var parser = this.parsers[this.getClass(json)];
+ var node = null;
+ if (parser)
+ node = parser.call(this, json, resourcePath);
+ else
+ cc.log("Can't find the parser : %s", this.getClass(json));
+
+ return node;
+ },
+
+ deferred: function (json, resourcePath, node, file) {
+ ccs.triggerManager.parse(json["Triggers"] || []);
+ if (ccs.sceneReader)
+ ccs.sceneReader._node = node;
+ },
+
+ setPropertyFromJsonDict: function (node, json) {
+ var x = (cc.isUndefined(json["x"])) ? 0 : json["x"];
+ var y = (cc.isUndefined(json["y"])) ? 0 : json["y"];
+ node.setPosition(x, y);
+
+ var bVisible = Boolean((cc.isUndefined(json["visible"])) ? 1 : json["visible"]);
+ node.setVisible(bVisible);
+
+ var nTag = (cc.isUndefined(json["objecttag"])) ? -1 : json["objecttag"];
+ node.setTag(nTag);
+
+ var nZorder = (cc.isUndefined(json["zorder"])) ? 0 : json["zorder"];
+ node.setLocalZOrder(nZorder);
+
+ var fScaleX = (cc.isUndefined(json["scalex"])) ? 1 : json["scalex"];
+ var fScaleY = (cc.isUndefined(json["scaley"])) ? 1 : json["scaley"];
+ node.setScaleX(fScaleX);
+ node.setScaleY(fScaleY);
+
+ var fRotationZ = (cc.isUndefined(json["rotation"])) ? 0 : json["rotation"];
+ node.setRotation(fRotationZ);
+
+ var sName = json["name"] || "";
+ node.setName(sName);
+ }
+
+ });
+
+ var parser = new Parser();
+
+ parser.parseChild = function (node, objects, resourcePath) {
+ for (var i = 0; i < objects.length; i++) {
+ var child,
+ options = objects[i];
+ if (options)
+ child = this.parseNode(options, resourcePath);
+ if (child)
+ node.addChild(child);
+ }
+ };
+
+ var componentsParser = {
+ "CCSprite": function (node, component, resourcePath) {
+ var child = new cc.Sprite();
+ loadTexture(component["fileData"], resourcePath, function (path, type) {
+ if (type === 0)
+ child.setTexture(path);
+ else if (type === 1) {
+ var spriteFrame = cc.spriteFrameCache.getSpriteFrame(path);
+ child.setSpriteFrame(spriteFrame);
+ }
+ });
+ var render = new ccs.ComRender(child, "CCSprite");
+ node.addComponent(render);
+ return render;
+ },
+ "CCTMXTiledMap": function (node, component, resourcePath) {
+ var child = null;
+ loadTexture(component["fileData"], resourcePath, function (path, type) {
+ if (type === 0)
+ child = new cc.TMXTiledMap(path);
+ });
+ var render = new ccs.ComRender(child, "CCTMXTiledMap");
+ node.addComponent(render);
+ return render;
+ },
+ "CCParticleSystemQuad": function (node, component, resourcePath) {
+ var child = null;
+ loadTexture(component["fileData"], resourcePath, function (path, type) {
+ if (type === 0)
+ child = new cc.ParticleSystem(path);
+ else
+ cc.log("unknown resourcetype on CCParticleSystemQuad!");
+ child.setPosition(0, 0);
+ });
+ var render = new ccs.ComRender(child, "CCParticleSystemQuad");
+ node.addComponent(render);
+ return render;
+ },
+ "CCArmature": function (node, component, resourcePath) {
+ var child = null;
+ loadTexture(component["fileData"], resourcePath, function (path, type) {
+ if (type === 0) {
+ var jsonDict = cc.loader.getRes(path);
+ if (!jsonDict) cc.log("Please load the resource [%s] first!", path);
+ var armature_data = jsonDict["armature_data"];
+ var subData = armature_data[0];
+ var name = subData["name"];
+ ccs.armatureDataManager.addArmatureFileInfo(path);
+ child = new ccs.Armature(name);
+ }
+ });
+ if (child) {
+ var render = new ccs.ComRender(child, "CCArmature");
+ node.addComponent(render);
+ var actionName = component["selectedactionname"];
+ if (actionName && child.getAnimation())
+ child.getAnimation().play(actionName);
+
+ return render;
+ }
+
+ },
+ "CCComAudio": function (node, component, resourcePath) {
+ var audio = null;
+ loadTexture(component["fileData"], resourcePath, function (path, type) {
+ if (type === 0) {
+ audio = new ccs.ComAudio();
+ audio.preloadEffect(path);
+ var name = component["name"];
+ if (name)
+ audio.setName(name);
+ node.addComponent(audio);
+ }
+ });
+ },
+ "CCComAttribute": function (node, component, resourcePath) {
+ var attribute = null;
+ loadTexture(component["fileData"], resourcePath, function (path, type) {
+ if (type === 0) {
+ attribute = new ccs.ComAttribute();
+ if (path !== "")
+ attribute.parse(path);
+ node.addComponent(attribute);
+ } else
+ cc.log("unknown resourcetype on CCComAttribute!");
+ });
+ return attribute;
+ },
+ "CCBackgroundAudio": function (node, component, resourcePath) {
+ var audio = null;
+ loadTexture(component["fileData"], resourcePath, function (path, type) {
+ if (type === 0) {
+ audio = new ccs.ComAudio();
+ audio.preloadBackgroundMusic(path);
+ audio.setFile(path);
+ var bLoop = Boolean(component["loop"] || 0);
+ audio.setLoop(bLoop);
+ var name = component["name"];
+ if (name)
+ audio.setName(name);
+ node.addComponent(audio);
+ audio.playBackgroundMusic(path, bLoop);
+ }
+ });
+ },
+ "GUIComponent": function (node, component, resourcePath) {
+ var widget = null;
+ loadTexture(component["fileData"], resourcePath, function (path, type) {
+ widget = ccs._load(path, "ccui");
+ });
+ var render = new ccs.ComRender(widget, "GUIComponent");
+ node.addComponent(render);
+ return render;
+ },
+ "CCScene": function () {
+ }
+ };
+ var loadedPlist = {};
+ var loadTexture = function (json, resourcePath, cb) {
+ if (json != null) {
+ var path = json["path"];
+ var type = json["resourceType"];
+ var plist = json["plist"];
+ if (!path)
+ return;
+ if (plist) {
+ if (cc.loader.getRes(resourcePath + plist)) {
+ loadedPlist[resourcePath + plist] = true;
+ cc.spriteFrameCache.addSpriteFrames(resourcePath + plist);
+ } else {
+ if (!loadedPlist[resourcePath + plist])
+ cc.log("%s need to be preloaded", resourcePath + plist);
+ }
+ }
+ if (type !== 0)
+ cb(path, type);
+ else
+ cb(resourcePath + path, type);
+ }
+ };
+
+ parser.parseComponents = function (node, json, resourcePath) {
+ if (!node || !json)
+ return;
+ json.forEach(function (component) {
+ var parser = componentsParser[component["classname"]];
+ var render = null;
+ if (parser)
+ render = parser(node, component, resourcePath);
+ else
+ cc.log("Can't find the component parser : %s", component["classname"]);
+ var name = component["name"];
+ if (render && name) {
+ render.setName(name);
+ }
+ });
+ };
+
+ parser.registerParser("CCNode", function (options, resourcePath) {
+ var node = new cc.Node();
+ this.setPropertyFromJsonDict(node, options);
+ this.parseChild.call(this, node, options["gameobjects"], resourcePath);
+ this.parseComponents(node, options["components"], resourcePath);
+ var size = options["CanvasSize"];
+ if (size)
+ node.setContentSize(cc.size(size["_width"], size["_height"]));
+
+ return node;
+ });
+
+ load.registerParser("scene", "*", parser);
+
+
+})(ccs._load, ccs._parser);
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/timelineParser-1.x.js b/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/timelineParser-1.x.js
new file mode 100644
index 0000000..1e9d907
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/timelineParser-1.x.js
@@ -0,0 +1,291 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function (load, baseParser) {
+
+ var loadedPlist = {};
+
+ var Parser = baseParser.extend({
+
+ getNodeJson: function (json) {
+ return json["nodeTree"];
+ },
+
+ addSpriteFrame: function (plists, pngs, resourcePath) {
+ if (!plists || !pngs || plists.length !== pngs.length)
+ return;
+ for (var i = 0; i < plists.length; i++) {
+ var plist = resourcePath + plists[i];
+ if (!cc.loader.getRes(plist) && !loadedPlist[plist])
+ cc.log("%s need to be preloaded", plist);
+ else
+ loadedPlist[plist] = true;
+ cc.spriteFrameCache.addSpriteFrames(
+ plist,
+ resourcePath + pngs[i]
+ );
+ }
+ },
+
+ pretreatment: function (json, resourcePath, file) {
+ this.addSpriteFrame(json["textures"], json["texturesPng"], resourcePath);
+ }
+
+ });
+ var parser = new Parser();
+
+ parser.generalAttributes = function (node, options) {
+ var width = options["width"] != null ? options["width"] : 0;
+ var height = options["height"] != null ? options["height"] : 0;
+ var x = options["x"] != null ? options["x"] : 0;
+ var y = options["y"] != null ? options["y"] : 0;
+ var scalex = options["scaleX"] != null ? options["scaleX"] : 1;
+ var scaley = options["scaleY"] != null ? options["scaleY"] : 1;
+ var rotation = options["rotation"] != null ? options["rotation"] : 0;
+ var rotationSkewX = options["rotationSkewX"] != null ? options["rotationSkewX"] : 0;
+ var rotationSkewY = options["rotationSkewY"] != null ? options["rotationSkewY"] : 0;
+ var skewx = options["skewX"] != null ? options["skewX"] : 0;
+ var skewy = options["skewY"] != null ? options["skewY"] : 0;
+ var anchorx = options["anchorPointX"] != null ? options["anchorPointX"] : 0.5;
+ var anchory = options["anchorPointY"] != null ? options["anchorPointY"] : 0.5;
+ var alpha = options["opacity"] != null ? options["opacity"] : 255;
+ var red = options["colorR"] != null ? options["colorR"] : 255;
+ var green = options["colorG"] != null ? options["colorG"] : 255;
+ var blue = options["colorB"] != null ? options["colorB"] : 255;
+ var zorder = options["colorR"] != null ? options["colorR"] : 0;
+ var tag = options["tag"] != null ? options["tag"] : 0;
+ var actionTag = options["actionTag"] != null ? options["actionTag"] : 0;
+ var visible = options["visible"] != null ? options["visible"] : true;
+
+ if (x != 0 || y != 0)
+ node.setPosition(cc.p(x, y));
+ if (scalex != 1)
+ node.setScaleX(scalex);
+ if (scaley != 1)
+ node.setScaleY(scaley);
+ if (rotation != 0)
+ node.setRotation(rotation);
+ if (rotationSkewX != 0)
+ node.setRotationX(rotationSkewX);
+ if (rotationSkewY != 0)
+ node.setRotationY(rotationSkewY);
+ if (skewx != 0)
+ node.setSkewX(skewx);
+ if (skewy != 0)
+ node.setSkewY(skewy);
+ if (anchorx != 0.5 || anchory != 0.5)
+ node.setAnchorPoint(cc.p(anchorx, anchory));
+ if (width != 0 || height != 0)
+ node.setContentSize(cc.size(width, height));
+ if (zorder != 0)
+ node.setLocalZOrder(zorder);
+ if (visible != true)
+ node.setVisible(visible);
+
+ if (alpha != 255) {
+ node.setOpacity(alpha);
+ }
+ if (red != 255 || green != 255 || blue != 255) {
+ node.setColor(cc.color(red, green, blue));
+ }
+
+
+ node.setTag(tag);
+ node.setUserObject(new ccs.ActionTimelineData(actionTag));
+ };
+
+ parser.parseComponent = function (node, options) {
+ if (!options) return;
+ for (var i = 0; i < options.length; ++i) {
+ var dic = options[i];
+ var component = this.loadComponent(dic);
+ if (component) {
+ node.addComponent(component);
+ }
+ }
+ };
+
+ parser.parseChild = function (parse, widget, options, resourcePath) {
+ var children = options["children"];
+ for (var i = 0; i < children.length; i++) {
+ var child = this.parseNode(children[i], resourcePath);
+ if (child) {
+ if (widget instanceof ccui.PageView) {
+ if (child instanceof ccui.Layout)
+ widget.addPage(child);
+ } else {
+ if (widget instanceof ccui.ListView) {
+ if (child instanceof ccui.Widget)
+ widget.pushBackCustomItem(child);
+ } else {
+ if (!(widget instanceof ccui.Layout) && child instanceof ccui.Widget) {
+ if (child.getPositionType() === ccui.Widget.POSITION_PERCENT) {
+ var position = child.getPositionPercent();
+ var anchor = widget.getAnchorPoint();
+ child.setPositionPercent(cc.p(position.x + anchor.x, position.y + anchor.y));
+ }
+ //To make up for the studio positioning error problem
+ var AnchorPointIn = widget.getAnchorPointInPoints();
+ child.setPosition(cc.p(child.getPositionX() + AnchorPointIn.x, child.getPositionY() + AnchorPointIn.y));
+ }
+ widget.addChild(child);
+ }
+ }
+ }
+ }
+ };
+
+ parser.initNode = function (options) {
+ var node = new cc.Node();
+ this.generalAttributes(node, options);
+ return node;
+ };
+ parser.initSubGraph = function (options) {
+ var filePath = options["fileName"];
+
+ var node;
+ if (filePath && "" !== filePath) {
+ node = this.createNode(filePath);
+ } else {
+ node = new ccs.Node();
+ }
+ this.generalAttributes(node, options);
+ return node;
+ };
+ parser.initSprite = function (options, resourcePath) {
+ var path = options["fileName"];
+ var sprite;
+ if (path != null) {
+ var spriteFrame = cc.spriteFrameCache.getSpriteFrame(path);
+ if (!spriteFrame) {
+ path = resourcePath + path;
+ sprite = new ccs.Sprite(path);
+ } else {
+ sprite = ccs.Sprite.createWithSpriteFrame(spriteFrame);
+ }
+
+ if (!sprite) {
+ sprite = new cc.Sprite();
+ cc.log("filePath is empty. Create a sprite with no texture");
+ }
+ } else {
+ sprite = new ccs.Sprite();
+ }
+ this.generalAttributes(sprite, options);
+ var flipX = options["flipX"];
+ var flipY = options["flipY"];
+
+ if (flipX != false)
+ sprite.setFlippedX(flipX);
+ if (flipY != false)
+ sprite.setFlippedY(flipY);
+ return sprite;
+ };
+ parser.initParticle = function (options, resourcePath) {
+ var filePath = options["plistFile"];
+ var num = options["tmxFile"];
+ var particle = new cc.ParticleSystemQuad(filePath);
+ particle.setTotalParticles(num);
+ this.generalAttributes(particle, options);
+ return particle;
+ };
+ parser.initTMXTiledMap = function (options, resourcePath) {
+ var tmxFile = options["tmxFile"];
+ var tmxString = options["tmxString"];
+ //todo check path and resourcePath
+ var path = options["resourcePath"];
+
+ var tmx = null;
+ if (tmxFile && "" !== tmxFile) {
+ tmx = new cc.TMXTiledMap(tmxFile);
+ } else if (tmxString && "" !== tmxString && path && "" !== path) {
+ tmx = new cc.TMXTiledMap(tmxString, path);
+ }
+ return tmx;
+ };
+ var uiParser = load.getParser("ccui")["*"];
+ parser.initWidget = function (options, resourcePath) {
+ var type = options["classname"];
+
+ var parser = uiParser.parsers[type];
+ if (!parser)
+ return cc.log("%s parser is not found", type);
+
+ var node = parser.call(uiParser, options, resourcePath);
+ if (node) {
+ var rotationSkewX = options["rotationSkewX"];
+ var rotationSkewY = options["rotationSkewY"];
+ var skewx = options["skewX"];
+ var skewy = options["skewY"];
+ if (rotationSkewX != 0)
+ node.setRotationX(rotationSkewX);
+ if (rotationSkewY != 0)
+ node.setRotationY(rotationSkewY);
+ if (skewx != 0)
+ node.setSkewX(skewx);
+ if (skewy != 0)
+ node.setSkewY(skewy);
+
+ var actionTag = options["actionTag"];
+ node.setUserObject(new ccs.ActionTimelineData(actionTag));
+ }
+ return node;
+ };
+
+ var register = [
+ {name: "Node", handle: parser.initNode},
+ {name: "SubGraph", handle: parser.initSubGraph},
+ {name: "Sprite", handle: parser.initSprite},
+ {name: "Particle", handle: parser.initParticle},
+ {name: "TMXTiledMap", handle: parser.initTMXTiledMap},
+
+ {name: "Widget", handle: parser.initWidget},
+ {name: "Panel", handle: parser.initWidget},
+ {name: "Button", handle: parser.initWidget},
+ {name: "CheckBox", handle: parser.initWidget},
+ {name: "ImageView", handle: parser.initWidget},
+ {name: "LabelAtlas", handle: parser.initWidget},
+ {name: "LabelBMFont", handle: parser.initWidget},
+ {name: "Label", handle: parser.initWidget},
+ {name: "ListView", handle: parser.initWidget},
+ {name: "LoadingBar", handle: parser.initWidget},
+ {name: "PageView", handle: parser.initWidget},
+ {name: "ScrollView", handle: parser.initWidget},
+ {name: "Slider", handle: parser.initWidget},
+ {name: "TextField", handle: parser.initWidget}
+ ];
+
+ register.forEach(function (item) {
+ parser.registerParser(item.name, function (options, parse, resourcePath) {
+ var node = item.handle.call(this, options["options"]);
+ this.parseComponent(node, options["components"]);
+ this.parseChild(parse, node, options, resourcePath);
+ return node;
+ });
+ });
+
+ load.registerParser("timeline", "0.*", parser);
+ load.registerParser("timeline", "1.*", parser);
+
+})(ccs._load, ccs._parser);
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/timelineParser-2.x.js b/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/timelineParser-2.x.js
new file mode 100644
index 0000000..c823ce8
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/timelineParser-2.x.js
@@ -0,0 +1,1409 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function (load, baseParser) {
+
+ var DEBUG = false;
+
+ var Parser = baseParser.extend({
+
+ parse: function (file, json, path) {
+ var resourcePath;
+ if (path !== undefined)
+ resourcePath = path;
+ else
+ resourcePath = this._dirname(file);
+ this.pretreatment(json, resourcePath, file);
+ var node = this.parseNode(this.getNodeJson(json), resourcePath);
+ this.deferred(json, resourcePath, node, file);
+ return node;
+ },
+
+ getNodeJson: function (json) {
+ var content = json["Content"];
+ if (content["ObjectData"])
+ return content["ObjectData"];
+
+ return content["Content"]["ObjectData"];
+ },
+
+ getClass: function (json) {
+ return json["ctype"];
+ }
+
+ });
+ var parser = new Parser();
+
+
+ var getParam = function (value, dValue) {
+ if (value === undefined)
+ return dValue;
+ else
+ return value;
+ };
+
+ //////////
+ // NODE //
+ //////////
+
+ parser.generalAttributes = function (node, json) {
+ if (json["Name"] != null)
+ node.setName(json["Name"]);
+
+ var position = json["Position"];
+ if (position != null && (position["X"] != null || position["Y"] != null))
+ node.setPosition(cc.p(position["X"] || 0, position["Y"] || 0));
+
+ var scale = json["Scale"];
+ if (scale != null) {
+ if (scale["ScaleX"] != null)
+ node.setScaleX(scale["ScaleX"]);
+ if (scale["ScaleY"] != null)
+ node.setScaleY(scale["ScaleY"]);
+ }
+
+ var rotationSkewX = json["RotationSkewX"];
+ if (rotationSkewX != null)
+ node.setRotationX(rotationSkewX);
+
+ var rotationSkewY = json["RotationSkewY"];
+ if (json["RotationSkewY"] != null)
+ node.setRotationY(rotationSkewY);
+
+
+ var anchor = json["AnchorPoint"];
+ if (anchor != null) {
+ if (anchor["ScaleX"] == null)
+ anchor["ScaleX"] = 0;
+ if (anchor["ScaleY"] == null)
+ anchor["ScaleY"] = 0;
+ if (anchor["ScaleX"] != 0.5 || anchor["ScaleY"] != 0.5)
+ node.setAnchorPoint(cc.p(anchor["ScaleX"], anchor["ScaleY"]));
+ }
+
+ if (json["ZOrder"] != null)
+ node.setLocalZOrder(json["ZOrder"]);
+
+ var visible = getParam(json["VisibleForFrame"], true);
+ node.setVisible(visible);
+
+ var size = json["Size"];
+ if (size)
+ setContentSize(node, size);
+
+ if (json["Alpha"] != null)
+ node.setOpacity(json["Alpha"]);
+
+ node.setTag(json["Tag"] || 0);
+
+ var actionTag = json["ActionTag"] || 0;
+ var extensionData = new ccs.ComExtensionData();
+ var customProperty = json["UserData"];
+ if (customProperty !== undefined)
+ extensionData.setCustomProperty(customProperty);
+ extensionData.setActionTag(actionTag);
+ if (node.getComponent("ComExtensionData"))
+ node.removeComponent("ComExtensionData");
+ node.addComponent(extensionData);
+
+ node.setCascadeColorEnabled(true);
+ node.setCascadeOpacityEnabled(true);
+
+ setLayoutComponent(node, json);
+ };
+
+ parser.parseChild = function (node, children, resourcePath) {
+ if (!node || !children) return;
+ for (var i = 0; i < children.length; i++) {
+ var child = this.parseNode(children[i], resourcePath);
+ if (child) {
+ if (node instanceof ccui.PageView) {
+ if (child instanceof ccui.Layout)
+ node.addPage(child);
+ } else {
+ if (node instanceof ccui.ListView) {
+ if (child instanceof ccui.Widget)
+ node.pushBackCustomItem(child);
+ } else {
+ if (!(node instanceof ccui.Layout) && child instanceof ccui.Widget) {
+ if (child.getPositionType() === ccui.Widget.POSITION_PERCENT) {
+ var position = child.getPositionPercent();
+ var anchor = node.getAnchorPoint();
+ child.setPositionPercent(cc.p(position.x + anchor.x, position.y + anchor.y));
+ }
+ }
+ node.addChild(child);
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * SingleNode
+ * @param json
+ * @returns {cc.Node}
+ */
+ parser.initSingleNode = function (json) {
+ var node = new cc.Node();
+
+ this.generalAttributes(node, json);
+ var color = json["CColor"];
+ if (color != null)
+ node.setColor(getColor(color));
+
+ return node;
+ };
+
+ /**
+ * Sprite
+ * @param json
+ * @param resourcePath
+ * @returns {cc.Sprite}
+ */
+ parser.initSprite = function (json, resourcePath) {
+ var node = new cc.Sprite();
+
+ loadTexture(json["FileData"], resourcePath, function (path, type) {
+ if (type === 0)
+ node.setTexture(path);
+ else if (type === 1) {
+ var spriteFrame = cc.spriteFrameCache.getSpriteFrame(path);
+ if (spriteFrame)
+ node.setSpriteFrame(spriteFrame);
+ }
+ });
+
+ var blendData = json["BlendFunc"];
+ if (json["BlendFunc"]) {
+ var blendFunc = cc.BlendFunc.ALPHA_PREMULTIPLIED;
+ if (blendData["Src"] !== undefined)
+ blendFunc.src = blendData["Src"];
+ if (blendData["Dst"] !== undefined)
+ blendFunc.dst = blendData["Dst"];
+ node.setBlendFunc(blendFunc);
+ }
+
+ if (json["FlipX"])
+ node.setFlippedX(true);
+ if (json["FlipY"])
+ node.setFlippedY(true);
+
+ this.generalAttributes(node, json);
+ var color = json["CColor"];
+ if (color != null)
+ node.setColor(getColor(color));
+
+ return node;
+ };
+
+ /**
+ * Particle
+ * @param json
+ * @param resourcePath
+ * @returns {*}
+ */
+ parser.initParticle = function (json, resourcePath) {
+ var node,
+ self = this;
+ loadTexture(json["FileData"], resourcePath, function (path, type) {
+ if (!cc.loader.getRes(path))
+ cc.log("%s need to be preloaded", path);
+ node = new cc.ParticleSystem(path);
+ self.generalAttributes(node, json);
+ node.setPositionType(cc.ParticleSystem.TYPE_GROUPED);
+ !cc.sys.isNative && node.setDrawMode(cc.ParticleSystem.TEXTURE_MODE);
+
+ var blendData = json["BlendFunc"];
+ if (json["BlendFunc"]) {
+ var blendFunc = cc.BlendFunc.ALPHA_PREMULTIPLIED;
+ if (blendData["Src"] !== undefined)
+ blendFunc.src = blendData["Src"];
+ if (blendData["Dst"] !== undefined)
+ blendFunc.dst = blendData["Dst"];
+ node.setBlendFunc(blendFunc);
+ }
+ });
+ return node;
+ };
+
+
+ ////////////
+ // WIDGET //
+ ////////////
+
+ parser.widgetAttributes = function (widget, json, enableContent) {
+ widget.setCascadeColorEnabled(true);
+ widget.setCascadeOpacityEnabled(true);
+
+ widget.setUnifySizeEnabled(false);
+ //widget.setLayoutComponentEnabled(true);
+ widget.ignoreContentAdaptWithSize(false);
+ !enableContent && setContentSize(widget, json["Size"]);
+
+ var name = json["Name"];
+ if (name)
+ widget.setName(name);
+
+ var actionTag = json["ActionTag"] || 0;
+ widget.setActionTag(actionTag);
+ var extensionData = new ccs.ComExtensionData();
+ var customProperty = json["UserData"];
+ if (customProperty !== undefined)
+ extensionData.setCustomProperty(customProperty);
+ extensionData.setActionTag(actionTag);
+ if (widget.getComponent("ComExtensionData"))
+ widget.removeComponent("ComExtensionData");
+ widget.addComponent(extensionData);
+
+ var rotationSkewX = json["RotationSkewX"];
+ if (rotationSkewX)
+ widget.setRotationX(rotationSkewX);
+
+ var rotationSkewY = json["RotationSkewY"];
+ if (rotationSkewY)
+ widget.setRotationY(rotationSkewY);
+
+ //var rotation = json["Rotation"];
+
+ var flipX = json["FlipX"];
+ if (flipX)
+ widget.setFlippedX(true);
+
+ var flipY = json["FlipY"];
+ if (flipY)
+ widget.setFlippedY(true);
+
+ var zOrder = json["zOrder"];
+ if (zOrder != null)
+ widget.setLocalZOrder(zOrder);
+
+ //var visible = json["Visible"];
+
+ var visible = getParam(json["VisibleForFrame"], true);
+ widget.setVisible(visible);
+
+ var alpha = json["Alpha"];
+ if (alpha != null)
+ widget.setOpacity(alpha);
+
+ widget.setTag(json["Tag"] || 0);
+
+ var touchEnabled = json["TouchEnable"] || false;
+ widget.setTouchEnabled(touchEnabled);
+
+ // -- var frameEvent = json["FrameEvent"];
+
+ var callBackType = json["CallBackType"];
+ if (callBackType != null)
+ widget.setCallbackType(callBackType);
+
+ var callBackName = json["CallBackName"];
+ if (callBackName)
+ widget.setCallbackName(callBackName);
+
+ var position = json["Position"];
+ if (position != null)
+ widget.setPosition(position["X"] || 0, position["Y"] || 0);
+
+ var scale = json["Scale"];
+ if (scale != null) {
+ var scaleX = getParam(scale["ScaleX"], 1);
+ var scaleY = getParam(scale["ScaleY"], 1);
+ widget.setScaleX(scaleX);
+ widget.setScaleY(scaleY);
+ }
+
+ var anchorPoint = json["AnchorPoint"];
+ if (anchorPoint != null)
+ widget.setAnchorPoint(anchorPoint["ScaleX"] || 0, anchorPoint["ScaleY"] || 0);
+
+ var color = json["CColor"];
+ if (color != null)
+ widget.setColor(getColor(color));
+
+ setLayoutComponent(widget, json);
+ bindCallback(widget, json);
+ };
+
+ var bindCallback = function (widget, json) {
+ var callBackType = json["CallBackType"];
+ var callBackName = json["CallBackName"];
+ var callBack = function (e) {
+ if (typeof widget[callBackName] === "function")
+ widget[callBackName](e);
+ };
+ if (callBackType === "Click") {
+ widget.addClickEventListener(callBack);
+ } else if (callBackType === "Touch") {
+ widget.addTouchEventListener(callBack);
+ } else if (callBackType === "Event") {
+ widget.addCCSEventListener(callBack);
+ }
+ };
+
+ var setLayoutComponent = function (widget, json) {
+
+ var layoutComponent = ccui.LayoutComponent.bindLayoutComponent(widget);
+ if (!layoutComponent)
+ return;
+
+ var positionXPercentEnabled = json["PositionPercentXEnable"] || json["PositionPercentXEnabled"] || false;
+ var positionYPercentEnabled = json["PositionPercentYEnable"] || json["PositionPercentYEnabled"] || false;
+ var positionXPercent = 0,
+ positionYPercent = 0,
+ PrePosition = json["PrePosition"];
+ if (PrePosition != null) {
+ positionXPercent = PrePosition["X"] || 0;
+ positionYPercent = PrePosition["Y"] || 0;
+ }
+ var sizeXPercentEnable = json["PercentWidthEnable"] || json["PercentWidthEnabled"] || false;
+ var sizeYPercentEnable = json["PercentHeightEnable"] || json["PercentHeightEnabled"] || false;
+ var sizeXPercent = 0,
+ sizeYPercent = 0,
+ PreSize = json["PreSize"];
+ if (PrePosition != null) {
+ sizeXPercent = PreSize["X"] || 0;
+ sizeYPercent = PreSize["Y"] || 0;
+ }
+ var stretchHorizontalEnabled = json["StretchWidthEnable"] || false;
+ var stretchVerticalEnabled = json["StretchHeightEnable"] || false;
+ var horizontalEdge = json["HorizontalEdge"];// = ccui.LayoutComponent.horizontalEdge.LEFT;
+ var verticalEdge = json["VerticalEdge"]; // = ccui.LayoutComponent.verticalEdge.TOP;
+ var leftMargin = json["LeftMargin"] || 0;
+ var rightMargin = json["RightMargin"] || 0;
+ var topMargin = json["TopMargin"] || 0;
+ var bottomMargin = json["BottomMargin"] || 0;
+
+ layoutComponent.setPositionPercentXEnabled(positionXPercentEnabled);
+ layoutComponent.setPositionPercentYEnabled(positionYPercentEnabled);
+ layoutComponent.setPositionPercentX(positionXPercent);
+ layoutComponent.setPositionPercentY(positionYPercent);
+ layoutComponent.setPercentWidthEnabled(sizeXPercentEnable);
+ layoutComponent.setPercentHeightEnabled(sizeYPercentEnable);
+ layoutComponent.setPercentWidth(sizeXPercent);
+ layoutComponent.setPercentHeight(sizeYPercent);
+ layoutComponent.setPercentWidthEnabled(sizeXPercentEnable || sizeYPercentEnable);
+ layoutComponent.setStretchWidthEnabled(stretchHorizontalEnabled);
+ layoutComponent.setStretchHeightEnabled(stretchVerticalEnabled);
+
+ var horizontalEdgeType = ccui.LayoutComponent.horizontalEdge.NONE;
+ if (horizontalEdge === "LeftEdge") {
+ horizontalEdgeType = ccui.LayoutComponent.horizontalEdge.LEFT;
+ } else if (horizontalEdge === "RightEdge") {
+ horizontalEdgeType = ccui.LayoutComponent.horizontalEdge.RIGHT;
+ } else if (horizontalEdge === "BothEdge") {
+ horizontalEdgeType = ccui.LayoutComponent.horizontalEdge.CENTER;
+ }
+ layoutComponent.setHorizontalEdge(horizontalEdgeType);
+
+ var verticalEdgeType = ccui.LayoutComponent.verticalEdge.NONE;
+ if (verticalEdge === "TopEdge") {
+ verticalEdgeType = ccui.LayoutComponent.verticalEdge.TOP;
+ } else if (verticalEdge === "BottomEdge") {
+ verticalEdgeType = ccui.LayoutComponent.verticalEdge.BOTTOM;
+ } else if (verticalEdge === "BothEdge") {
+ verticalEdgeType = ccui.LayoutComponent.verticalEdge.CENTER;
+ }
+ layoutComponent.setVerticalEdge(verticalEdgeType);
+
+ layoutComponent.setTopMargin(topMargin);
+ layoutComponent.setBottomMargin(bottomMargin);
+ layoutComponent.setLeftMargin(leftMargin);
+ layoutComponent.setRightMargin(rightMargin);
+
+ layoutComponent.setVerticalEdge(verticalEdgeType);
+
+ layoutComponent.setTopMargin(topMargin);
+ layoutComponent.setBottomMargin(bottomMargin);
+ layoutComponent.setLeftMargin(leftMargin);
+ layoutComponent.setRightMargin(rightMargin);
+ };
+
+ var setLayoutBackground = function (layout, single, first, end) {
+ if (layout.getBackGroundColorType() === 2) {
+ first = first || {};
+ end = end || {};
+ layout.setBackGroundColor(getColor(first), getColor(end));
+ } else {
+ single = single || {};
+ layout.setBackGroundColor(getColor(single));
+ }
+ };
+
+ var setLayoutBackgroundVector = function (widget, vector) {
+ var x = vector["ScaleX"] || 0;
+ var y = vector["ScaleY"] || 0;
+ widget.setBackGroundColorVector(cc.p(x, y));
+ };
+
+ /**
+ * Layout
+ * @param json
+ * @param resourcePath
+ * @returns {ccui.Layout}
+ */
+ parser.initPanel = function (json, resourcePath) {
+ var widget = new ccui.Layout();
+
+ this.widgetAttributes(widget, json);
+
+ var clipEnabled = json["ClipAble"] || false;
+ if (clipEnabled != null)
+ widget.setClippingEnabled(clipEnabled);
+
+ var colorType = getParam(json["ComboBoxIndex"], 0);
+ widget.setBackGroundColorType(colorType);
+
+ var bgColorOpacity = getParam(json["BackColorAlpha"], 255);
+ if (bgColorOpacity != null)
+ widget.setBackGroundColorOpacity(bgColorOpacity);
+
+ var backGroundScale9Enabled = json["Scale9Enable"];
+ if (backGroundScale9Enabled != null)
+ widget.setBackGroundImageScale9Enabled(backGroundScale9Enabled);
+
+ var opacity = getParam(json["Alpha"], 255);
+ widget.setOpacity(opacity);
+
+ loadTexture(json["FileData"], resourcePath, function (path, type) {
+ widget.setBackGroundImage(path, type);
+ });
+
+ if (backGroundScale9Enabled) {
+ var scale9OriginX = json["Scale9OriginX"] || 0;
+ var scale9OriginY = json["Scale9OriginY"] || 0;
+
+ var scale9Width = json["Scale9Width"] || 0;
+ var scale9Height = json["Scale9Height"] || 0;
+
+ widget.setBackGroundImageCapInsets(cc.rect(
+ scale9OriginX, scale9OriginY, scale9Width, scale9Height
+ ));
+
+ setContentSize(widget, json["Size"]);
+ } else {
+ if (!widget.isIgnoreContentAdaptWithSize()) {
+ setContentSize(widget, json["Size"]);
+ }
+
+ }
+
+ setLayoutBackground(widget, json["SingleColor"], json["FirstColor"], json["EndColor"]);
+ setLayoutBackgroundVector(widget, json["ColorVector"]);
+
+ return widget;
+ };
+
+ /**
+ * Text
+ * @param json
+ * @param resourcePath
+ */
+ parser.initText = function (json, resourcePath) {
+
+ var widget = new ccui.Text();
+
+ var touchScaleEnabled = json["TouchScaleChangeAble"];
+ if (touchScaleEnabled != null)
+ widget.setTouchScaleChangeEnabled(touchScaleEnabled);
+
+ var text = json["LabelText"];
+ if (text != null)
+ widget.setString(text);
+
+ var fontSize = json["FontSize"];
+ if (fontSize != null)
+ widget.setFontSize(fontSize);
+
+ var fontName = json["FontName"];
+ if (fontName != null)
+ widget.setFontName(fontName);
+
+ var areaWidth = json["AreaWidth"];
+ var areaHeight = json["areaHeight"];
+ if (areaWidth && areaHeight)
+ widget.setTextAreaSize(cc.size(areaWidth, areaHeight));
+
+ var h_alignment = json["HorizontalAlignmentType"] || "HT_Left";
+ switch (h_alignment) {
+ case "HT_Right":
+ h_alignment = 2;
+ break;
+ case "HT_Center":
+ h_alignment = 1;
+ break;
+ case "HT_Left":
+ default:
+ h_alignment = 0;
+ }
+ widget.setTextHorizontalAlignment(h_alignment);
+
+ var v_alignment = json["VerticalAlignmentType"] || "VT_Top";
+ switch (v_alignment) {
+ case "VT_Bottom":
+ v_alignment = 2;
+ break;
+ case "VT_Center":
+ v_alignment = 1;
+ break;
+ case "VT_Top":
+ default:
+ v_alignment = 0;
+ }
+ widget.setTextVerticalAlignment(v_alignment);
+
+ var fontResource = json["FontResource"];
+ if (fontResource != null) {
+ var path = fontResource["Path"];
+ //resoutceType = fontResource["Type"];
+ if (path != null) {
+ if (cc.sys.isNative) {
+ fontName = cc.path.join(cc.loader.resPath, resourcePath, path);
+ } else {
+ fontName = path.match(/([^\/]+)\.(\S+)/);
+ fontName = fontName ? fontName[1] : "";
+ }
+ widget.setFontName(fontName);
+ }
+ }
+
+ if (json["OutlineEnabled"] && json["OutlineColor"] && widget.enableOutline)
+ widget.enableOutline(getColor(json["OutlineColor"]), getParam(json["OutlineSize"], 1));
+
+ if (json["ShadowEnabled"] && json["ShadowColor"] && widget.enableShadow)
+ widget.enableShadow(
+ getColor(json["ShadowColor"]),
+ cc.size(getParam(json["ShadowOffsetX"], 2), getParam(json["ShadowOffsetY"], -2)),
+ json["ShadowBlurRadius"] || 0
+ );
+
+ var isCustomSize = json["IsCustomSize"];
+ if (isCustomSize != null)
+ widget.ignoreContentAdaptWithSize(!isCustomSize);
+
+ widget.setUnifySizeEnabled(false);
+
+ var color = json["CColor"];
+ json["CColor"] = null;
+ widget.setTextColor(getColor(color));
+ this.widgetAttributes(widget, json, widget.isIgnoreContentAdaptWithSize());
+ json["CColor"] = color;
+ return widget;
+
+ };
+
+ /**
+ * Button
+ * @param json
+ * @param resourcePath
+ */
+ parser.initButton = function (json, resourcePath) {
+
+ var widget = new ccui.Button();
+
+ loadTexture(json["NormalFileData"], resourcePath, function (path, type) {
+ widget.loadTextureNormal(path, type);
+ });
+ loadTexture(json["PressedFileData"], resourcePath, function (path, type) {
+ widget.loadTexturePressed(path, type);
+ });
+ loadTexture(json["DisabledFileData"], resourcePath, function (path, type) {
+ widget.loadTextureDisabled(path, type);
+ });
+
+ var scale9Enabled = getParam(json["Scale9Enable"], false);
+ if (scale9Enabled) {
+ widget.setScale9Enabled(scale9Enabled);
+ }
+
+ var text = json["ButtonText"];
+ if (text != null)
+ widget.setTitleText(text);
+
+ var fontSize = json["FontSize"];
+ if (fontSize != null)
+ widget.setTitleFontSize(fontSize);
+
+ var fontName = json["FontName"];
+ if (fontName != null)
+ widget.setTitleFontName(fontName);
+
+ var textColor = json["TextColor"];
+ if (textColor != null)
+ widget.setTitleColor(getColor(textColor));
+
+ var displaystate = getParam(json["DisplayState"], true);
+ widget.setBright(displaystate);
+ widget.setEnabled(displaystate);
+
+ var fontResource = json["FontResource"];
+ if (fontResource != null) {
+ var path = fontResource["Path"];
+ //resoutceType = fontResource["Type"];
+ if (path != null) {
+ if (cc.sys.isNative) {
+ fontName = cc.path.join(cc.loader.resPath, resourcePath, path);
+ } else {
+ fontName = path.match(/([^\/]+)\.(\S+)/);
+ fontName = fontName ? fontName[1] : "";
+ }
+ widget.setTitleFontName(fontName);
+ }
+ }
+
+ var label = widget.getTitleRenderer();
+ if (label && json["ShadowEnabled"] && json["ShadowColor"] && label.enableShadow) {
+ label.enableShadow(
+ getColor(json["ShadowColor"]),
+ cc.size(getParam(json["ShadowOffsetX"], 2), getParam(json["ShadowOffsetY"], -2)),
+ json["ShadowBlurRadius"] || 0
+ );
+ }
+ if (label && json["OutlineEnabled"] && json["OutlineColor"] && label.enableStroke)
+ label.enableStroke(getColor(json["OutlineColor"]), getParam(json["OutlineSize"], 1));
+
+ this.widgetAttributes(widget, json);
+
+ if (scale9Enabled) {
+ widget.setUnifySizeEnabled(false);
+ widget.ignoreContentAdaptWithSize(false);
+ var capInsets = cc.rect(
+ json["Scale9OriginX"] || 0,
+ json["Scale9OriginY"] || 0,
+ json["Scale9Width"] || 0,
+ json["Scale9Height"] || 0
+ );
+ widget.setCapInsets(capInsets);
+
+ }
+
+ setContentSize(widget, json["Size"]);
+
+ return widget;
+
+ };
+
+ /**
+ * CheckBox
+ * @param json
+ * @param resourcePath
+ */
+ parser.initCheckBox = function (json, resourcePath) {
+
+ var widget = new ccui.CheckBox();
+
+ this.widgetAttributes(widget, json);
+
+ var dataList = [
+ {name: "NormalBackFileData", handle: widget.loadTextureBackGround},
+ {name: "PressedBackFileData", handle: widget.loadTextureBackGroundSelected},
+ {name: "NodeNormalFileData", handle: widget.loadTextureFrontCross},
+ {name: "DisableBackFileData", handle: widget.loadTextureBackGroundDisabled},
+ {name: "NodeDisableFileData", handle: widget.loadTextureFrontCrossDisabled}
+ ];
+
+ dataList.forEach(function (item) {
+ loadTexture(json[item.name], resourcePath, function (path, type) {
+ item.handle.call(widget, path, type);
+ });
+ });
+
+ var selectedState = getParam(json["CheckedState"], false);
+ widget.setSelected(selectedState);
+
+ var displaystate = getParam(json["DisplayState"], true);
+ widget.setBright(displaystate);
+ widget.setEnabled(displaystate);
+
+ return widget;
+ };
+
+ /**
+ * ScrollView
+ * @param json
+ * @param resourcePath
+ */
+ parser.initScrollView = function (json, resourcePath) {
+ var widget = new ccui.ScrollView();
+
+ this.widgetAttributes(widget, json);
+
+ loadTexture(json["FileData"], resourcePath, function (path, type) {
+ widget.setBackGroundImage(path, type);
+ });
+
+ var clipEnabled = json["ClipAble"] || false;
+ widget.setClippingEnabled(clipEnabled);
+
+ var colorType = getParam(json["ComboBoxIndex"], 0);
+ widget.setBackGroundColorType(colorType);
+
+ var bgColorOpacity = json["BackColorAlpha"];
+ if (bgColorOpacity != null)
+ widget.setBackGroundColorOpacity(bgColorOpacity);
+
+ var backGroundScale9Enabled = json["Scale9Enable"];
+ if (backGroundScale9Enabled) {
+ widget.setBackGroundImageScale9Enabled(true);
+
+
+ var scale9OriginX = json["Scale9OriginX"] || 0;
+ var scale9OriginY = json["Scale9OriginY"] || 0;
+ var scale9Width = json["Scale9Width"] || 0;
+ var scale9Height = json["Scale9Height"] || 0;
+ widget.setBackGroundImageCapInsets(cc.rect(
+ scale9OriginX, scale9OriginY, scale9Width, scale9Height
+ ));
+ setContentSize(widget, json["Size"]);
+ } else if (!widget.isIgnoreContentAdaptWithSize()) {
+ setContentSize(widget, json["Size"]);
+ }
+
+ setLayoutBackground(widget, json["SingleColor"], json["FirstColor"], json["EndColor"]);
+ setLayoutBackgroundVector(widget, json["ColorVector"]);
+
+ var innerNodeSize = json["InnerNodeSize"];
+ var innerSize = cc.size(
+ innerNodeSize["Width"] || 0,
+ innerNodeSize["Height"] || 0
+ );
+ widget.setInnerContainerSize(innerSize);
+
+ var direction = 0;
+ if (json["ScrollDirectionType"] === "Vertical") direction = 1;
+ if (json["ScrollDirectionType"] === "Horizontal") direction = 2;
+ if (json["ScrollDirectionType"] === "Vertical_Horizontal") direction = 3;
+ widget.setDirection(direction);
+
+ var bounceEnabled = getParam(json["IsBounceEnabled"], false);
+ widget.setBounceEnabled(bounceEnabled);
+
+ return widget;
+ };
+
+ /**
+ * ImageView
+ * @param json
+ * @param resourcePath
+ */
+ parser.initImageView = function (json, resourcePath) {
+
+ var widget = new ccui.ImageView();
+
+ loadTexture(json["FileData"], resourcePath, function (path, type) {
+ widget.loadTexture(path, type);
+ });
+ loadTexture(json["ImageFileData"], resourcePath, function (path, type) {
+ widget.loadTexture(path, type);
+ });
+
+ var scale9Enabled = json["Scale9Enable"];
+ if (scale9Enabled) {
+ widget.setScale9Enabled(true);
+ widget.setUnifySizeEnabled(false);
+ widget.ignoreContentAdaptWithSize(false);
+
+ var scale9OriginX = json["Scale9OriginX"] || 0;
+ var scale9OriginY = json["Scale9OriginY"] || 0;
+ var scale9Width = json["Scale9Width"] || 0;
+ var scale9Height = json["Scale9Height"] || 0;
+ widget.setCapInsets(cc.rect(
+ scale9OriginX,
+ scale9OriginY,
+ scale9Width,
+ scale9Height
+ ));
+ } else
+ setContentSize(widget, json["Size"]);
+
+ this.widgetAttributes(widget, json);
+
+ return widget;
+ };
+
+ /**
+ * LoadingBar
+ * @param json
+ * @param resourcePath
+ * @returns {ccui.LoadingBar}
+ */
+ parser.initLoadingBar = function (json, resourcePath) {
+
+ var widget = new ccui.LoadingBar();
+
+ this.widgetAttributes(widget, json);
+
+ loadTexture(json["ImageFileData"], resourcePath, function (path, type) {
+ widget.loadTexture(path, type);
+ });
+
+ var direction = json["ProgressType"] === "Right_To_Left" ? 1 : 0;
+ widget.setDirection(direction);
+
+ var percent = getParam(json["ProgressInfo"], 80);
+ if (percent != null)
+ widget.setPercent(percent);
+
+ return widget;
+
+ };
+
+ /**
+ * Slider
+ * @param json
+ * @param resourcePath
+ */
+ parser.initSlider = function (json, resourcePath) {
+
+ var widget = new ccui.Slider();
+ var loader = cc.loader;
+
+ this.widgetAttributes(widget, json);
+
+ var textureList = [
+ {name: "BackGroundData", handle: widget.loadBarTexture},
+ {name: "BallNormalData", handle: widget.loadSlidBallTextureNormal},
+ {name: "BallPressedData", handle: widget.loadSlidBallTexturePressed},
+ {name: "BallDisabledData", handle: widget.loadSlidBallTextureDisabled},
+ {name: "ProgressBarData", handle: widget.loadProgressBarTexture}
+ ];
+ textureList.forEach(function (item) {
+ loadTexture(json[item.name], resourcePath, function (path, type) {
+ if (type === 0 && !loader.getRes(path))
+ cc.log("%s need to be preloaded", path);
+ item.handle.call(widget, path, type);
+ });
+ });
+
+ var percent = json["PercentInfo"] || 0;
+ widget.setPercent(percent);
+
+ var displaystate = getParam(json["DisplayState"], true);
+ widget.setBright(displaystate);
+ widget.setEnabled(displaystate);
+
+ return widget;
+ };
+
+ /**
+ * PageView
+ * @param json
+ * @param resourcePath
+ */
+ parser.initPageView = function (json, resourcePath) {
+
+ var widget = new ccui.PageView();
+
+ this.widgetAttributes(widget, json);
+
+ loadTexture(json["FileData"], resourcePath, function (path, type) {
+ widget.setBackGroundImage(path, type);
+ });
+
+ var clipEnabled = json["ClipAble"] || false;
+ widget.setClippingEnabled(clipEnabled);
+
+ var backGroundScale9Enabled = json["Scale9Enable"];
+ if (backGroundScale9Enabled) {
+ widget.setBackGroundImageScale9Enabled(true);
+
+ var scale9OriginX = json["Scale9OriginX"] || 0;
+ var scale9OriginY = json["Scale9OriginY"] || 0;
+ var scale9Width = json["Scale9Width"] || 0;
+ var scale9Height = json["Scale9Height"] || 0;
+ widget.setBackGroundImageCapInsets(cc.rect(
+ scale9OriginX,
+ scale9OriginY,
+ scale9Width,
+ scale9Height
+ ));
+ }
+
+ var colorType = getParam(json["ComboBoxIndex"], 0);
+ widget.setBackGroundColorType(colorType);
+
+ setLayoutBackground(widget, json["SingleColor"], json["FirstColor"], json["EndColor"]);
+ setLayoutBackgroundVector(widget, json["ColorVector"]);
+
+ var bgColorOpacity = json["BackColorAlpha"];
+ if (bgColorOpacity != null)
+ widget.setBackGroundColorOpacity(bgColorOpacity);
+
+ setContentSize(widget, json["Size"]);
+
+ return widget;
+
+ };
+
+ /**
+ * ListView
+ * @param json
+ * @param resourcePath
+ * @returns {ccui.ListView}
+ */
+ parser.initListView = function (json, resourcePath) {
+
+ var widget = new ccui.ListView();
+
+ this.widgetAttributes(widget, json);
+
+ loadTexture(json["FileData"], resourcePath, function (path, type) {
+ widget.setBackGroundImage(path, type);
+ });
+
+ var clipEnabled = json["ClipAble"] || false;
+ widget.setClippingEnabled(clipEnabled);
+
+ var colorType = getParam(json["ComboBoxIndex"], 0);
+ widget.setBackGroundColorType(colorType);
+
+ var bgColorOpacity = getParam(json["BackColorAlpha"], 255);
+ var backGroundScale9Enabled = json["Scale9Enable"];
+ if (backGroundScale9Enabled) {
+ widget.setBackGroundImageScale9Enabled(true);
+
+ var scale9OriginX = json["Scale9OriginX"] || 0;
+ var scale9OriginY = json["Scale9OriginY"] || 0;
+ var scale9Width = json["Scale9Width"] || 0;
+ var scale9Height = json["Scale9Height"] || 0;
+ widget.setBackGroundImageCapInsets(cc.rect(
+ scale9OriginX,
+ scale9OriginY,
+ scale9Width,
+ scale9Height
+ ));
+ }
+
+ var directionType = getParam(json["DirectionType"], ccui.ListView.DIR_HORIZONTAL);
+ var verticalType = getParam(json["VerticalType"], "Align_Left");
+ var horizontalType = getParam(json["HorizontalType"], "Align_Top");
+ if (!directionType) {
+ widget.setDirection(ccui.ScrollView.DIR_HORIZONTAL);
+ if (verticalType === "Align_Bottom")
+ widget.setGravity(ccui.ListView.GRAVITY_BOTTOM);
+ else if (verticalType === "Align_VerticalCenter")
+ widget.setGravity(ccui.ListView.GRAVITY_CENTER_VERTICAL);
+ else
+ widget.setGravity(ccui.ListView.GRAVITY_TOP);
+ } else if (directionType === "Vertical") {
+ widget.setDirection(ccui.ScrollView.DIR_VERTICAL);
+ if (horizontalType === "")
+ widget.setGravity(ccui.ListView.GRAVITY_LEFT);
+ else if (horizontalType === "Align_Right")
+ widget.setGravity(ccui.ListView.GRAVITY_RIGHT);
+ else if (horizontalType === "Align_HorizontalCenter")
+ widget.setGravity(ccui.ListView.GRAVITY_CENTER_HORIZONTAL);
+ }
+
+
+ var bounceEnabled = getParam(json["IsBounceEnabled"], false);
+ widget.setBounceEnabled(bounceEnabled);
+
+ var itemMargin = json["ItemMargin"] || 0;
+ widget.setItemsMargin(itemMargin);
+
+ var innerSize = json["InnerNodeSize"];
+ //Width
+ if (innerSize != null)
+ widget.setInnerContainerSize(cc.size(innerSize["Widget"] || 0, innerSize["Height"] || 0));
+
+ setLayoutBackground(widget, json["SingleColor"], json["FirstColor"], json["EndColor"]);
+ setLayoutBackgroundVector(widget, json["ColorVector"]);
+
+ if (bgColorOpacity != null)
+ widget.setBackGroundColorOpacity(bgColorOpacity);
+
+ setContentSize(widget, json["Size"]);
+
+ return widget;
+ };
+
+ /**
+ * TextAtlas
+ * @param json
+ * @param resourcePath
+ * @returns {ccui.TextAtlas}
+ */
+ parser.initTextAtlas = function (json, resourcePath) {
+
+ var widget = new ccui.TextAtlas();
+
+ var stringValue = json["LabelText"];
+ var itemWidth = json["CharWidth"];
+ var itemHeight = json["CharHeight"];
+
+ var startCharMap = json["StartChar"];
+
+ loadTexture(json["LabelAtlasFileImage_CNB"], resourcePath, function (path, type) {
+ if (!cc.loader.getRes(path))
+ cc.log("%s need to be preloaded", path);
+ if (type === 0) {
+ widget.setProperty(stringValue, path, itemWidth, itemHeight, startCharMap);
+ }
+ });
+ this.widgetAttributes(widget, json);
+
+ // the TextAtlas must be ignore ContentSize[Size] in the ccs file.
+ widget.ignoreContentAdaptWithSize(true);
+
+ return widget;
+ };
+
+ /**
+ * TextBMFont
+ * @param json
+ * @param resourcePath
+ * @returns {ccui.TextBMFont}
+ */
+ parser.initTextBMFont = function (json, resourcePath) {
+ var widget = new ccui.TextBMFont();
+ this.widgetAttributes(widget, json);
+
+ loadTexture(json["LabelBMFontFile_CNB"], resourcePath, function (path, type) {
+ if (!cc.loader.getRes(path))
+ cc.log("%s need to be pre loaded", path);
+ widget.setFntFile(path);
+ });
+
+ var text = json["LabelText"];
+ widget.setString(text);
+
+ widget.ignoreContentAdaptWithSize(true);
+ return widget;
+ };
+
+ /**
+ * TextField
+ * @param json
+ * @param resourcePath
+ * @returns {ccui.TextField}
+ */
+ parser.initTextField = function (json, resourcePath) {
+ var widget = new ccui.TextField();
+
+ var passwordEnabled = json["PasswordEnable"];
+ if (passwordEnabled) {
+ widget.setPasswordEnabled(true);
+ var passwordStyleText = json["PasswordStyleText"] || "*";
+ widget.setPasswordStyleText(passwordStyleText);
+ }
+
+ var placeHolder = json["PlaceHolderText"];
+ if (placeHolder != null)
+ widget.setPlaceHolder(placeHolder);
+
+ var fontSize = json["FontSize"];
+ if (fontSize != null)
+ widget.setFontSize(fontSize);
+
+ var fontName = json["FontName"];
+ if (fontName != null)
+ widget.setFontName(fontName);
+
+ var maxLengthEnabled = json["MaxLengthEnable"];
+ if (maxLengthEnabled) {
+ widget.setMaxLengthEnabled(true);
+ var maxLength = json["MaxLengthText"] || 0;
+ widget.setMaxLength(maxLength);
+ }
+
+ //var isCustomSize = json["IsCustomSize"];
+ this.widgetAttributes(widget, json);
+
+ var text = json["LabelText"];
+ if (text != null)
+ widget.setString(text);
+
+ var fontResource = json["FontResource"];
+ if (fontResource != null) {
+ var path = fontResource["Path"];
+ //resoutceType = fontResource["Type"];
+ if (path != null) {
+ if (cc.sys.isNative) {
+ fontName = cc.path.join(cc.loader.resPath, resourcePath, path);
+ } else {
+ fontName = path.match(/([^\/]+)\.(\S+)/);
+ fontName = fontName ? fontName[1] : "";
+ }
+ widget.setFontName(fontName);
+ }
+ }
+
+ widget.setUnifySizeEnabled(false);
+ widget.ignoreContentAdaptWithSize(false);
+
+ var color = json["CColor"];
+ if (color != null)
+ widget.setTextColor(getColor(color));
+
+ if (!widget.isIgnoreContentAdaptWithSize()) {
+ setContentSize(widget, json["Size"]);
+ if (cc.sys.isNative)
+ widget.getVirtualRenderer().setLineBreakWithoutSpace(true);
+ }
+
+
+ return widget;
+
+ };
+
+ /**
+ * SimpleAudio
+ * @param json
+ * @param resourcePath
+ */
+ parser.initSimpleAudio = function (json, resourcePath) {
+
+ var node = new ccs.ComAudio();
+ var loop = json["Loop"] || false;
+ //var volume = json["Volume"] || 0;
+ //cc.audioEngine.setMusicVolume(volume);
+ node.setLoop(loop);
+ loadTexture(json["FileData"], resourcePath, function (path, type) {
+ node.setFile(path);
+ });
+
+ };
+
+ /**
+ * GameMap
+ * @param json
+ * @param resourcePath
+ * @returns {*}
+ */
+ parser.initGameMap = function (json, resourcePath) {
+
+ var node = null;
+
+ loadTexture(json["FileData"], resourcePath, function (path, type) {
+ if (type === 0)
+ node = new cc.TMXTiledMap(path);
+
+ parser.generalAttributes(node, json);
+ });
+
+ return node;
+ };
+
+ /**
+ * ProjectNode
+ * @param json
+ * @param resourcePath
+ * @returns {*}
+ */
+ parser.initProjectNode = function (json, resourcePath) {
+ var projectFile = json["FileData"];
+ if (projectFile != null && projectFile["Path"]) {
+ var file = resourcePath + projectFile["Path"];
+ if (cc.loader.getRes(file)) {
+ var obj = ccs.load(file, resourcePath);
+ parser.generalAttributes(obj.node, json);
+ if (obj.action && obj.node) {
+ obj.action.tag = obj.node.tag;
+ var InnerActionSpeed = json["InnerActionSpeed"];
+ if (InnerActionSpeed !== undefined)
+ obj.action.setTimeSpeed(InnerActionSpeed);
+ obj.node.runAction(obj.action);
+ obj.action.gotoFrameAndPause(0);
+ }
+ return obj.node;
+ } else
+ cc.log("%s need to be preloaded", file);
+ }
+ };
+
+ var getFileName = function (name) {
+ if (!name) return "";
+ var arr = name.match(/([^\/]+)\.[^\/]+$/);
+ if (arr && arr[1])
+ return arr[1];
+ else
+ return "";
+ };
+
+ /**
+ * Armature
+ * @param json
+ * @param resourcePath
+ */
+ parser.initArmature = function (json, resourcePath) {
+
+ var node = new ccs.Armature();
+
+ var isLoop = json["IsLoop"];
+
+ var isAutoPlay = json["IsAutoPlay"];
+
+ var currentAnimationName = json["CurrentAnimationName"];
+
+ loadTexture(json["FileData"], resourcePath, function (path, type) {
+ var plists, pngs;
+ var armJson = cc.loader.getRes(path);
+ if (!armJson)
+ cc.log("%s need to be preloaded", path);
+ else {
+ plists = armJson["config_file_path"];
+ pngs = armJson["config_png_path"];
+ plists.forEach(function (plist, index) {
+ if (pngs[index])
+ cc.spriteFrameCache.addSpriteFrames(plist, pngs[index]);
+ });
+ }
+ ccs.armatureDataManager.addArmatureFileInfo(path);
+ node.init(getFileName(path));
+ if (isAutoPlay)
+ node.getAnimation().play(currentAnimationName, -1, isLoop);
+ else {
+ node.getAnimation().play(currentAnimationName);
+ node.getAnimation().gotoAndPause(0);
+ }
+
+ });
+
+ delete json["AnchorPoint"];
+ delete json["Size"];
+ parser.generalAttributes(node, json);
+
+ node.setColor(getColor(json["CColor"]));
+ return node;
+ };
+
+ parser.initBoneNode = function (json, resourcePath) {
+
+ var node = new ccs.BoneNode();
+
+ var length = json["Length"];
+ if (length !== undefined)
+ node.setDebugDrawLength(length);
+
+ var blendFunc = json["BlendFunc"];
+ if (blendFunc && blendFunc["Src"] !== undefined && blendFunc["Dst"] !== undefined)
+ node.setBlendFunc(new cc.BlendFunc(blendFunc["Src"], blendFunc["Dst"]));
+
+ parser.generalAttributes(node, json);
+ var color = json["CColor"];
+ if (color && (color["R"] !== undefined || color["G"] !== undefined || color["B"] !== undefined))
+ node.setColor(getColor(color));
+ return node;
+ };
+
+ parser.initSkeletonNode = function (json) {
+ var node = new ccs.SkeletonNode();
+ parser.generalAttributes(node, json);
+ var color = json["CColor"];
+ if (color && (color["R"] !== undefined || color["G"] !== undefined || color["B"] !== undefined))
+ node.setColor(getColor(color));
+ return node;
+ };
+
+ var loadedPlist = {};
+ var loadTexture = function (json, resourcePath, cb) {
+ if (json != null) {
+ var path = json["Path"];
+ var type;
+ if (json["Type"] === "Default" || json["Type"] === "Normal")
+ type = 0;
+ else
+ type = 1;
+ var plist = json["Plist"];
+ if (plist) {
+ if (cc.loader.getRes(resourcePath + plist)) {
+ loadedPlist[resourcePath + plist] = true;
+ cc.spriteFrameCache.addSpriteFrames(resourcePath + plist);
+ } else {
+ if (!loadedPlist[resourcePath + plist] && !cc.spriteFrameCache.getSpriteFrame(path))
+ cc.log("%s need to be preloaded", resourcePath + plist);
+ }
+ }
+ if (type !== 0) {
+ if (cc.spriteFrameCache.getSpriteFrame(path))
+ cb(path, type);
+ else
+ cc.log("failed to get spriteFrame: %s", path);
+ } else
+ cb(resourcePath + path, type);
+ }
+ };
+
+ var getColor = function (json) {
+ if (!json) return;
+ var r = json["R"] != null ? json["R"] : 255;
+ var g = json["G"] != null ? json["G"] : 255;
+ var b = json["B"] != null ? json["B"] : 255;
+ var a = json["A"] != null ? json["A"] : 255;
+ return cc.color(r, g, b, a);
+ };
+
+ var setContentSize = function (node, size) {
+ var x = size["X"] || 0;
+ var y = size["Y"] || 0;
+ if (size)
+ node.setContentSize(cc.size(x, y));
+ };
+
+ var register = [
+ {name: "SingleNodeObjectData", handle: parser.initSingleNode},
+ {name: "NodeObjectData", handle: parser.initSingleNode},
+ {name: "LayerObjectData", handle: parser.initSingleNode},
+ {name: "GameNodeObjectData", handle: parser.initSingleNode},
+ {name: "GameLayerObjectData", handle: parser.initSingleNode},
+ {name: "SpriteObjectData", handle: parser.initSprite},
+ {name: "ParticleObjectData", handle: parser.initParticle},
+ {name: "PanelObjectData", handle: parser.initPanel},
+ {name: "TextObjectData", handle: parser.initText},
+ {name: "ButtonObjectData", handle: parser.initButton},
+ {name: "CheckBoxObjectData", handle: parser.initCheckBox},
+ {name: "ScrollViewObjectData", handle: parser.initScrollView},
+ {name: "ImageViewObjectData", handle: parser.initImageView},
+ {name: "LoadingBarObjectData", handle: parser.initLoadingBar},
+ {name: "SliderObjectData", handle: parser.initSlider},
+ {name: "PageViewObjectData", handle: parser.initPageView},
+ {name: "ListViewObjectData", handle: parser.initListView},
+ {name: "TextAtlasObjectData", handle: parser.initTextAtlas},
+ {name: "TextBMFontObjectData", handle: parser.initTextBMFont},
+ {name: "TextFieldObjectData", handle: parser.initTextField},
+ {name: "SimpleAudioObjectData", handle: parser.initSimpleAudio},
+ {name: "GameMapObjectData", handle: parser.initGameMap},
+ {name: "ProjectNodeObjectData", handle: parser.initProjectNode},
+ {name: "ArmatureNodeObjectData", handle: parser.initArmature},
+ {name: "BoneNodeObjectData", handle: parser.initBoneNode},
+ {name: "SkeletonNodeObjectData", handle: parser.initSkeletonNode}
+ ];
+
+ register.forEach(function (item) {
+ parser.registerParser(item.name, function (options, resourcePath) {
+ var node = item.handle.call(this, options, resourcePath);
+ this.parseChild(node, options["Children"], resourcePath);
+ DEBUG && node && (node.__parserName = item.name);
+ return node;
+ });
+ });
+
+
+ load.registerParser("timeline", "2.*", parser);
+ load.registerParser("timeline", "*", parser);
+
+
+})(ccs._load, ccs._parser);
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/uiParser-1.x.js b/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/uiParser-1.x.js
new file mode 100644
index 0000000..e6904df
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/loader/parsers/uiParser-1.x.js
@@ -0,0 +1,710 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function (load, baseParser) {
+
+ var _stack = new Array(50);
+
+ var Parser = baseParser.extend({
+
+ addSpriteFrame: function (textures, resourcePath) {
+ if (!textures) return;
+ for (var i = 0; i < textures.length; i++) {
+ cc.spriteFrameCache.addSpriteFrames(resourcePath + textures[i]);
+ }
+ },
+
+ pretreatment: function (json, resourcePath) {
+ this.addSpriteFrame(json["textures"], resourcePath);
+ },
+
+ parseRecursive: function (json, resourcePath) {
+ var index = 1;
+ var rootNode = null;
+ var parser, curr, className, options, position, anchor, anchorPP,
+ node, parent, child, children;
+ _stack[0] = json;
+ while (index > 0) {
+ index--;
+ curr = _stack[index];
+ // Avoid memory leak
+ _stack[index] = null;
+ if (!curr) continue;
+
+ // Parse node
+ className = curr["classname"];
+ parser = this.parsers[className];
+ if (!parser) {
+ cc.log("Can't find the parser : %s", className);
+ continue;
+ }
+ node = new parser.object();
+ if (!node) continue;
+ if (!rootNode) {
+ rootNode = node;
+ }
+
+ // Parse attributes
+ options = curr["options"];
+ this.generalAttributes(node, options);
+ parser.handle(node, options, resourcePath);
+ this.colorAttributes(node, options);
+
+ parent = curr.parent;
+ curr.parent = null;
+ if (parent instanceof ccui.PageView) {
+ parent.addPage(node);
+ }
+ else if (parent instanceof ccui.ListView) {
+ parent.pushBackCustomItem(node);
+ }
+ else if (parent) {
+ if (!(parent instanceof ccui.Layout)) {
+ if (node.getPositionType() === ccui.Widget.POSITION_PERCENT) {
+ position = node._positionPercent;
+ anchor = parent._anchorPoint;
+ node._positionPercent.x = position.x + anchor.x;
+ node._positionPercent.y = position.y + anchor.y;
+ }
+ anchorPP = parent._renderCmd._anchorPointInPoints;
+ node._position.x += anchorPP.x;
+ node._position.y += anchorPP.y;
+ node.setNodeDirty();
+ }
+ parent.addChild(node);
+ }
+
+ children = curr["children"];
+ if (children && children.length > 0) {
+ for (var i = children.length - 1; i >= 0; i--) {
+ _stack[index] = children[i];
+ _stack[index].parent = node;
+ index++;
+ }
+ }
+ }
+ return rootNode;
+ },
+
+ parse: function (file, json, resourcePath) {
+ resourcePath = resourcePath || this._dirname(file);
+ this.pretreatment(json, resourcePath);
+
+ var node = this.parseRecursive(json["widgetTree"], resourcePath);
+
+ node && this.deferred(json, resourcePath, node, file);
+ return node;
+ },
+
+ deferred: function (json, resourcePath, node, file) {
+ if (node) {
+ ccs.actionManager.initWithDictionary(file, json["animation"], node);
+ node.setContentSize(json["designWidth"], json["designHeight"]);
+ }
+ }
+
+ });
+ var parser = new Parser();
+
+ parser.generalAttributes = function (widget, options) {
+ widget._ignoreSize = options["ignoreSize"] || true;
+ widget._sizeType = options["sizeType"] || 0;
+ widget._positionType = options["positionType"] || 0;
+
+ widget._sizePercent.x = options["sizePercentX"] || 0;
+ widget._sizePercent.y = options["sizePercentY"] || 0;
+ widget._positionPercent.x = options["positionPercentX"] || 0;
+ widget._positionPercent.y = options["positionPercentY"] || 0;
+
+ /* adapt screen */
+ var w = 0, h = 0;
+ var adaptScreen = options["adaptScreen"];
+ if (adaptScreen) {
+ var screenSize = cc.director.getWinSize();
+ w = screenSize.width;
+ h = screenSize.height;
+ } else {
+ w = options["width"] || 0;
+ h = options["height"] || 0;
+ }
+
+ var anchorPointX = options["anchorPointX"];
+ var anchorPointY = options["anchorPointY"];
+
+ widget._anchorPoint.x = isNaN(anchorPointX) ? 0.5 : anchorPointX;
+ widget._anchorPoint.y = isNaN(anchorPointY) ? 0.5 : anchorPointY;
+
+ widget.setContentSize(w, h);
+
+ widget.setTag(options["tag"]);
+ widget.setActionTag(options["actiontag"]);
+ widget.setTouchEnabled(options["touchAble"]);
+
+ widget._name = options["name"] || "default";
+
+ widget._position.x = options["x"] || 0;
+ widget._position.y = options["y"] || 0;
+ widget._scaleX = options["scaleX"] || 1;
+ widget._scaleY = options["scaleY"] || 1;
+ widget._rotationX = widget._rotationY = options["rotation"] || 0;
+
+ widget._visible = options["visible"] || false;
+ widget._localZOrder = options["ZOrder"] || 0;
+
+ var layout = options["layoutParameter"];
+ if (layout != null) {
+ var layoutParameterDic = options["layoutParameter"];
+ var paramType = isNaN(layoutParameterDic["type"]) ? 2 : layoutParameterDic["type"];
+ var parameter = null;
+
+ switch (paramType) {
+ case 0:
+ break;
+ case 1:
+ parameter = new ccui.LinearLayoutParameter();
+ parameter._linearGravity = layoutParameterDic["gravity"] || 0;
+ break;
+ case 2:
+ parameter = new ccui.RelativeLayoutParameter();
+ parameter._relativeLayoutName = layoutParameterDic["relativeName"];
+ parameter._relativeWidgetName = layoutParameterDic["relativeToName"];
+ parameter._relativeAlign = layoutParameterDic["align"] || 0;
+ break;
+ default:
+ break;
+ }
+ if (parameter != null) {
+ var margin = parameter._margin;
+ margin.left = layoutParameterDic["marginLeft"] || 0;
+ margin.top = layoutParameterDic["marginTop"] || 0;
+ margin.right = layoutParameterDic["marginRight"] || 0;
+ margin.bottom = layoutParameterDic["marginDown"] || 0;
+ widget.setLayoutParameter(parameter);
+ }
+ }
+ };
+
+ parser.colorAttributes = function (widget, options) {
+ var op = options["opacity"] !== null ? options["opacity"] : 255;
+ if (op != null)
+ widget.setOpacity(op);
+ var colorR = options["colorR"];
+ var colorG = options["colorG"];
+ var colorB = options["colorB"];
+ widget.setColor(cc.color((colorR == null) ? 255 : colorR, (colorG == null) ? 255 : colorG, (colorB == null) ? 255 : colorB));
+
+ widget.setFlippedX(options["flipX"]);
+ widget.setFlippedY(options["flipY"]);
+ };
+
+ var getPath = function (res, type, path, cb) {
+ if (path) {
+ if (type === 0)
+ cb(res + path, type);
+ else
+ cb(path, type);
+ }
+ };
+
+ /**
+ * Panel parser (UILayout)
+ */
+ parser.LayoutAttributes = function (widget, options, resourcePath) {
+ var w = 0, h = 0;
+ var adaptScreen = options["adaptScreen"];
+ if (adaptScreen) {
+ var screenSize = cc.director.getWinSize();
+ w = screenSize.width;
+ h = screenSize.height;
+ } else {
+ w = options["width"] || 0;
+ h = options["height"] || 0;
+ }
+ widget.setSize(cc.size(w, h));
+
+ widget.setClippingEnabled(options["clipAble"]);
+
+ var backGroundScale9Enable = options["backGroundScale9Enable"];
+ widget.setBackGroundImageScale9Enabled(backGroundScale9Enable);
+ var cr = options["bgColorR"] || 0;
+ var cg = options["bgColorG"] || 0;
+ var cb = options["bgColorB"] || 0;
+
+ var scr = isNaN(options["bgStartColorR"]) ? 255 : options["bgStartColorR"];
+ var scg = isNaN(options["bgStartColorG"]) ? 255 : options["bgStartColorG"];
+ var scb = isNaN(options["bgStartColorB"]) ? 255 : options["bgStartColorB"];
+
+ var ecr = isNaN(options["bgEndColorR"]) ? 255 : options["bgEndColorR"];
+ var ecg = isNaN(options["bgEndColorG"]) ? 255 : options["bgEndColorG"];
+ var ecb = isNaN(options["bgEndColorB"]) ? 255 : options["bgEndColorB"];
+
+ var bgcv1 = options["vectorX"] || 0;
+ var bgcv2 = options["vectorY"] || 0;
+ widget.setBackGroundColorVector(cc.p(bgcv1, bgcv2));
+
+ var co = options["bgColorOpacity"] || 0;
+
+ var colorType = options["colorType"] || 0;
+ widget.setBackGroundColorType(colorType/*ui.LayoutBackGroundColorType(colorType)*/);
+ widget.setBackGroundColor(cc.color(scr, scg, scb), cc.color(ecr, ecg, ecb));
+ widget.setBackGroundColor(cc.color(cr, cg, cb));
+ widget.setBackGroundColorOpacity(co);
+
+
+ var imageFileNameDic = options["backGroundImageData"];
+ if (imageFileNameDic) {
+ getPath(resourcePath, imageFileNameDic["resourceType"] || 0, imageFileNameDic["path"], function (path, type) {
+ widget.setBackGroundImage(path, type);
+ });
+ }
+
+ if (backGroundScale9Enable) {
+ var cx = options["capInsetsX"] || 0;
+ var cy = options["capInsetsY"] || 0;
+ var cw = isNaN(options["capInsetsWidth"]) ? 1 : options["capInsetsWidth"];
+ var ch = isNaN(options["capInsetsHeight"]) ? 1 : options["capInsetsHeight"];
+ widget.setBackGroundImageCapInsets(cc.rect(cx, cy, cw, ch));
+ }
+ if (options["layoutType"]) {
+ widget.setLayoutType(options["layoutType"]);
+ }
+ };
+ /**
+ * Button parser (UIButton)
+ */
+ parser.ButtonAttributes = function (widget, options, resourcePath) {
+ var button = widget;
+ var scale9Enable = options["scale9Enable"];
+ button.setScale9Enabled(scale9Enable);
+
+ var normalDic = options["normalData"];
+ getPath(resourcePath, normalDic["resourceType"] || 0, normalDic["path"], function (path, type) {
+ button.loadTextureNormal(path, type);
+ });
+ var pressedDic = options["pressedData"];
+ getPath(resourcePath, pressedDic["resourceType"] || 0, pressedDic["path"], function (path, type) {
+ button.loadTexturePressed(path, type);
+ });
+ var disabledDic = options["disabledData"];
+ getPath(resourcePath, disabledDic["resourceType"] || 0, disabledDic["path"], function (path, type) {
+ button.loadTextureDisabled(path, type);
+ });
+ if (scale9Enable) {
+ var cx = options["capInsetsX"] || 0;
+ var cy = options["capInsetsY"] || 0;
+ var cw = isNaN(options["capInsetsWidth"]) ? 1 : options["capInsetsWidth"];
+ var ch = isNaN(options["capInsetsHeight"]) ? 1 : options["capInsetsHeight"];
+
+ button.setCapInsets(cc.rect(cx, cy, cw, ch));
+ var sw = options["scale9Width"] || 0;
+ var sh = options["scale9Height"] || 0;
+ if (sw != null && sh != null)
+ button.setSize(cc.size(sw, sh));
+ }
+ var text = options["text"] || "";
+ if (text) {
+ button.setTitleText(text);
+
+ var cr = options["textColorR"];
+ var cg = options["textColorG"];
+ var cb = options["textColorB"];
+ var cri = (cr !== null) ? options["textColorR"] : 255;
+ var cgi = (cg !== null) ? options["textColorG"] : 255;
+ var cbi = (cb !== null) ? options["textColorB"] : 255;
+
+ button.setTitleColor(cc.color(cri, cgi, cbi));
+ var fs = options["fontSize"];
+ if (fs != null)
+ button.setTitleFontSize(options["fontSize"]);
+ var fn = options["fontName"];
+ if (fn)
+ button.setTitleFontName(options["fontName"]);
+ }
+ };
+ /**
+ * CheckBox parser (UICheckBox)
+ */
+ parser.CheckBoxAttributes = function (widget, options, resourcePath) {
+ //load background image
+ var backGroundDic = options["backGroundBoxData"];
+ getPath(resourcePath, backGroundDic["resourceType"] || 0, backGroundDic["path"], function (path, type) {
+ widget.loadTextureBackGround(path, type);
+ });
+
+ //load background selected image
+ var backGroundSelectedDic = options["backGroundBoxSelectedData"];
+ getPath(
+ resourcePath,
+ backGroundSelectedDic["resourceType"] || backGroundDic["resourceType"],
+ backGroundSelectedDic["path"] || backGroundDic["path"],
+ function (path, type) {
+ widget.loadTextureBackGroundSelected(path, type);
+ });
+
+ //load frontCross image
+ var frontCrossDic = options["frontCrossData"];
+ getPath(resourcePath, frontCrossDic["resourceType"] || 0, frontCrossDic["path"], function (path, type) {
+ widget.loadTextureFrontCross(path, type);
+ });
+
+ //load backGroundBoxDisabledData
+ var backGroundDisabledDic = options["backGroundBoxDisabledData"];
+ getPath(
+ resourcePath,
+ backGroundDisabledDic["resourceType"] || frontCrossDic["resourceType"],
+ backGroundDisabledDic["path"] || frontCrossDic["path"],
+ function (path, type) {
+ widget.loadTextureBackGroundDisabled(path, type);
+ });
+
+ ///load frontCrossDisabledData
+ var frontCrossDisabledDic = options["frontCrossDisabledData"];
+ getPath(resourcePath, frontCrossDisabledDic["resourceType"] || 0, frontCrossDisabledDic["path"], function (path, type) {
+ widget.loadTextureFrontCrossDisabled(path, type);
+ });
+
+ if (options["selectedState"])
+ widget.setSelected(options["selectedState"]);
+ };
+ /**
+ * ImageView parser (UIImageView)
+ */
+ parser.ImageViewAttributes = function (widget, options, resourcePath) {
+ var imageFileNameDic = options["fileNameData"]
+ getPath(resourcePath, imageFileNameDic["resourceType"] || 0, imageFileNameDic["path"], function (path, type) {
+ widget.loadTexture(path, type);
+ });
+
+ var scale9EnableExist = options["scale9Enable"];
+ var scale9Enable = false;
+ if (scale9EnableExist) {
+ scale9Enable = options["scale9Enable"];
+ }
+ widget.setScale9Enabled(scale9Enable);
+
+ if (scale9Enable) {
+ var sw = options["scale9Width"] || 0;
+ var sh = options["scale9Height"] || 0;
+ if (sw && sh) {
+ var swf = options["scale9Width"] || 0;
+ var shf = options["scale9Height"] || 0;
+ widget.setSize(cc.size(swf, shf));
+ }
+
+ var cx = options["capInsetsX"] || 0;
+ var cy = options["capInsetsY"] || 0;
+ var cw = isNaN(options["capInsetsWidth"]) ? 1 : options["capInsetsWidth"];
+ var ch = isNaN(options["capInsetsHeight"]) ? 1 : options["capInsetsHeight"];
+
+ widget.setCapInsets(cc.rect(cx, cy, cw, ch));
+
+ }
+ };
+ /**
+ * TextAtlas parser (UITextAtlas)
+ */
+ parser.TextAtlasAttributes = function (widget, options, resourcePath) {
+ var sv = options["stringValue"];
+ var cmf = options["charMapFileData"]; // || options["charMapFile"];
+ var iw = options["itemWidth"];
+ var ih = options["itemHeight"];
+ var scm = options["startCharMap"];
+ if (sv != null && cmf && iw != null && ih != null && scm != null) {
+ var cmftDic = options["charMapFileData"];
+ var cmfType = cmftDic["resourceType"] || 0;
+ switch (cmfType) {
+ case 0:
+ var tp_c = resourcePath;
+ var cmfPath = cmftDic["path"];
+ var cmf_tp = tp_c + cmfPath;
+ widget.setProperty(sv, cmf_tp, iw, ih, scm);
+ break;
+ case 1:
+ cc.log("Wrong res type of LabelAtlas!");
+ break;
+ default:
+ break;
+ }
+ }
+ };
+ /**
+ * TextBMFont parser (UITextBMFont)
+ */
+ parser.TextBMFontAttributes = function (widget, options, resourcePath) {
+ var cmftDic = options["fileNameData"];
+ var cmfType = cmftDic["resourceType"] || 0;
+ switch (cmfType) {
+ case 0:
+ var tp_c = resourcePath;
+ var cmfPath = cmftDic["path"];
+ var cmf_tp = tp_c + cmfPath;
+ widget.setFntFile(cmf_tp);
+ break;
+ case 1:
+ cc.log("Wrong res type of LabelAtlas!");
+ break;
+ default:
+ break;
+ }
+
+ var text = options["text"] || "";
+ widget.setString(text);
+ };
+ /**
+ * Text parser (UIText)
+ */
+ var regTTF = /\.ttf$/;
+ parser.TextAttributes = function (widget, options, resourcePath) {
+ var touchScaleChangeAble = options["touchScaleEnable"];
+ widget.setTouchScaleChangeEnabled(touchScaleChangeAble);
+ var text = options["text"] || "";
+ if(text) {
+ widget._setString(text);
+ }
+
+ var fs = options["fontSize"];
+ if (fs != null) {
+ widget._setFontSize(options["fontSize"]);
+ }
+ var fn = options["fontName"];
+ if (fn != null) {
+ if (cc.sys.isNative) {
+ if (regTTF.test(fn)) {
+ widget.setFontName(cc.path.join(cc.loader.resPath, resourcePath, fn));
+ } else {
+ widget.setFontName(fn);
+ }
+ } else {
+ widget._setFontName(fn.replace(regTTF, ''));
+ }
+ }
+ var aw = options["areaWidth"] || 0;
+ var ah = options["areaHeight"] || 0;
+ if (aw && ah) {
+ var size = cc.size(options["areaWidth"], options["areaHeight"]);
+ widget._setTextAreaSize(size);
+ }
+ var ha = options["hAlignment"] || 0;
+ if (ha != null) {
+ widget._setTextHorizontalAlignment(ha);
+ }
+ var va = options["vAlignment"] || 0;
+ if (va != null) {
+ widget._setTextVerticalAlignment(va);
+ }
+ widget._updateUITextContentSize();
+ };
+ /**
+ * ListView parser (UIListView)
+ */
+ parser.ListViewAttributes = function (widget, options, resoutcePath) {
+ parser.ScrollViewAttributes(widget, options, resoutcePath);
+ var direction = options["direction"] || 1;
+ widget.setDirection(direction);
+ var gravity = options["gravity"] || 0;
+ widget.setGravity(gravity);
+ var itemMargin = options["itemMargin"] || 0;
+ widget.setItemsMargin(itemMargin);
+ };
+ /**
+ * LoadingBar parser (UILoadingBar)
+ */
+ parser.LoadingBarAttributes = function (widget, options, resourcePath) {
+ var imageFileNameDic = options["textureData"];
+ getPath(resourcePath, imageFileNameDic["resourceType"] || 0, imageFileNameDic["path"], function (path, type) {
+ widget.loadTexture(path, type);
+ });
+
+ var scale9Enable = options["scale9Enable"];
+ widget.setScale9Enabled(scale9Enable);
+
+ if (scale9Enable) {
+ var cx = options["capInsetsX"] || 0;
+ var cy = options["capInsetsY"] || 0;
+ var cw = isNaN(options["capInsetsWidth"]) ? 1 : options["capInsetsWidth"];
+ var ch = isNaN(options["capInsetsHeight"]) ? 1 : options["capInsetsHeight"];
+
+ widget.setCapInsets(cc.rect(cx, cy, cw, ch));
+
+ var width = options["width"] || 0;
+ var height = options["height"] || 0;
+ widget.setSize(cc.size(width, height));
+ }
+
+ widget.setDirection(options["direction"] || 0);
+ widget.setPercent(options["percent"] || 0);
+ };
+ /**
+ * PageView parser (UIPageView)
+ */
+ parser.PageViewAttributes = parser.LayoutAttributes;
+ /**
+ * ScrollView parser (UIScrollView)
+ */
+ parser.ScrollViewAttributes = function (widget, options, resoutcePath) {
+ parser.LayoutAttributes(widget, options, resoutcePath);
+ var innerWidth = options["innerWidth"] != null ? options["innerWidth"] : 200;
+ var innerHeight = options["innerHeight"] != null ? options["innerHeight"] : 200;
+ widget.setInnerContainerSize(cc.size(innerWidth, innerHeight));
+
+ var direction = options["direction"] != null ? options["direction"] : 1;
+ widget.setDirection(direction);
+ widget.setBounceEnabled(options["bounceEnable"]);
+ };
+ /**
+ * Slider parser (UISlider)
+ */
+ parser.SliderAttributes = function (widget, options, resourcePath) {
+
+ var slider = widget;
+
+ var barTextureScale9Enable = options["scale9Enable"];
+ slider.setScale9Enabled(barTextureScale9Enable);
+ var bt = options["barFileName"];
+ var barLength = options["length"];
+
+ var imageFileNameDic = options["barFileNameData"];
+ var imageFileType = imageFileNameDic["resourceType"] || 0;
+ var imageFileName = imageFileNameDic["path"];
+
+ if (bt != null) {
+ if (barTextureScale9Enable) {
+ getPath(resourcePath, imageFileType, imageFileName, function (path, type) {
+ slider.loadBarTexture(path, type);
+ });
+ slider.setSize(cc.size(barLength, slider.getContentSize().height));
+ }
+ } else {
+ getPath(resourcePath, imageFileType, imageFileName, function (path, type) {
+ slider.loadBarTexture(path, type);
+ });
+ }
+
+ var normalDic = options["ballNormalData"];
+ getPath(resourcePath, normalDic["resourceType"] || 0, normalDic["path"], function (path, type) {
+ slider.loadSlidBallTextureNormal(path, type);
+ });
+
+ var pressedDic = options["ballPressedData"];
+ getPath(
+ resourcePath,
+ pressedDic["resourceType"] || normalDic["resourceType"],
+ pressedDic["path"] || normalDic["path"],
+ function (path, type) {
+ slider.loadSlidBallTexturePressed(path, type);
+ });
+
+ var disabledDic = options["ballDisabledData"];
+ getPath(resourcePath, disabledDic["resourceType"] || 0, disabledDic["path"], function (path, type) {
+ slider.loadSlidBallTextureDisabled(path, type);
+ });
+
+ var progressBarDic = options["progressBarData"];
+ getPath(resourcePath, progressBarDic["resourceType"] || 0, progressBarDic["path"], function (path, type) {
+ slider.loadProgressBarTexture(path, type);
+ });
+ };
+ /**
+ * TextField parser (UITextField)
+ */
+ parser.TextFieldAttributes = function (widget, options, resourcePath) {
+ var ph = options["placeHolder"] || "";
+ if (ph)
+ widget.setPlaceHolder(ph);
+ widget.setString(options["text"] || "");
+ var fs = options["fontSize"];
+ if (fs)
+ widget.setFontSize(fs);
+ var fn = options["fontName"];
+ if (fn != null) {
+ if (cc.sys.isNative) {
+ if (regTTF.test(fn)) {
+ widget.setFontName(cc.path.join(cc.loader.resPath, resourcePath, fn));
+ } else {
+ widget.setFontName(fn);
+ }
+ } else {
+ widget.setFontName(fn.replace(regTTF, ''));
+ }
+ }
+ var tsw = options["touchSizeWidth"] || 0;
+ var tsh = options["touchSizeHeight"] || 0;
+ if (tsw != null && tsh != null)
+ widget.setTouchSize(tsw, tsh);
+
+ var dw = options["width"] || 0;
+ var dh = options["height"] || 0;
+ if (dw > 0 || dh > 0) {
+ //textField.setSize(cc.size(dw, dh));
+ }
+ var maxLengthEnable = options["maxLengthEnable"];
+ widget.setMaxLengthEnabled(maxLengthEnable);
+
+ if (maxLengthEnable) {
+ var maxLength = options["maxLength"];
+ widget.setMaxLength(maxLength);
+ }
+ var passwordEnable = options["passwordEnable"];
+ widget.setPasswordEnabled(passwordEnable);
+ if (passwordEnable)
+ widget.setPasswordStyleText(options["passwordStyleText"]);
+
+ var aw = options["areaWidth"] || 0;
+ var ah = options["areaHeight"] || 0;
+ if (aw && ah) {
+ var size = cc.size(aw, ah);
+ widget.setTextAreaSize(size);
+ }
+ var ha = options["hAlignment"] || 0;
+ if (ha)
+ widget.setTextHorizontalAlignment(ha);
+ var va = options["vAlignment"] || 0;
+ if (va)
+ widget.setTextVerticalAlignment(va);
+
+ var r = isNaN(options["colorR"]) ? 255 : options["colorR"];
+ var g = isNaN(options["colorG"]) ? 255 : options["colorG"];
+ var b = isNaN(options["colorB"]) ? 255 : options["colorB"];
+ widget.setTextColor(cc.color(r, g, b));
+ };
+
+ parser.parsers = {
+ "Panel": {object: ccui.Layout, handle: parser.LayoutAttributes},
+ "Button": {object: ccui.Button, handle: parser.ButtonAttributes},
+ "CheckBox": {object: ccui.CheckBox, handle: parser.CheckBoxAttributes},
+ "ImageView": {object: ccui.ImageView, handle: parser.ImageViewAttributes},
+ "LabelAtlas": {object: ccui.TextAtlas, handle: parser.TextAtlasAttributes},
+ "LabelBMFont": {object: ccui.TextBMFont, handle: parser.TextBMFontAttributes},
+ "Label": {object: ccui.Text, handle: parser.TextAttributes},
+ "ListView": {object: ccui.ListView, handle: parser.ListViewAttributes},
+ "LoadingBar": {object: ccui.LoadingBar, handle: parser.LoadingBarAttributes},
+ "PageView": {object: ccui.PageView, handle: parser.PageViewAttributes},
+ "ScrollView": {object: ccui.ScrollView, handle: parser.ScrollViewAttributes},
+ "Slider": {object: ccui.Slider, handle: parser.SliderAttributes},
+ "TextField": {object: ccui.TextField, handle: parser.TextFieldAttributes}
+ };
+
+ load.registerParser("ccui", "*", parser);
+
+})(ccs._load, ccs._parser);
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/timeline/ActionTimeline.js b/frameworks/cocos2d-html5/extensions/cocostudio/timeline/ActionTimeline.js
new file mode 100644
index 0000000..fd899ae
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/timeline/ActionTimeline.js
@@ -0,0 +1,537 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+
+/**
+ * ActionTimelineData
+ * @name ccs.ActionTimelineData
+ * @extend ccs.Class
+ * @class
+ *
+ */
+ccs.ActionTimelineData = ccs.Class.extend({
+
+ _actionTag: 0,
+
+ ctor: function (actionTag) {
+ this._init(actionTag);
+ },
+
+ _init: function (actionTag) {
+ this._actionTag = actionTag;
+ return true;
+ },
+
+ /**
+ * Set the action tag.
+ * @param {number} actionTag
+ */
+ setActionTag: function (actionTag) {
+ this._actionTag = actionTag;
+ },
+
+ /**
+ * Gets the action tag.
+ */
+ getActionTag: function () {
+ return this._actionTag;
+ }
+
+});
+
+ccs.AnimationInfo = function (name, start, end) {
+ this.name = name;
+ this.startIndex = start;
+ this.endIndex = end;
+};
+
+ccs.ComExtensionData = ccs.Component.extend({
+
+ _customProperty: null,
+ _timelineData: null,
+ _name: "ComExtensionData",
+
+ ctor: function(){
+ this._customProperty = "";
+ this._timelineData = new ccs.ActionTimelineData(0);
+ return true;
+ },
+
+ setActionTag: function(actionTag){
+ this._timelineData.setActionTag(actionTag);
+ },
+
+ getActionTag: function(){
+ return this._timelineData.getActionTag();
+ },
+
+ setCustomProperty: function(customProperty){
+ this._customProperty = customProperty;
+ },
+
+ getCustomProperty: function(){
+ return this._customProperty;
+ }
+
+});
+
+ccs.ComExtensionData.create = function(){
+ return new ccs.ComExtensionData();
+};
+
+/**
+ * Create new ActionTimelineData.
+ *
+ * @deprecated v3.0, please use new ccs.ActionTimelineData() instead.
+ *
+ * @name ccs.ActionTimelineData.create
+ * @function
+ * @param actionTag
+ * @returns {ccs.ActionTimelineData}
+ */
+ccs.ActionTimelineData.create = function (actionTag) {
+ return new ccs.ActionTimelineData(actionTag);
+};
+
+
+/**
+ * ActionTimeline
+ * @class
+ * @extend cc.Action
+ *
+ * @property gotoFrameAndPlay
+ * @property gotoFrameAndPause
+ */
+ccs.ActionTimeline = cc.Action.extend({
+
+ _timelineMap: null,
+ _timelineList: null,
+ _duration: 0,
+ _time: null,
+ _timeSpeed: 1,
+ _frameInternal: 1 / 60,
+ _playing: false,
+ _currentFrame: 0,
+ _startFrame: 0,
+ _endFrame: 0,
+ _loop: null,
+ _frameEventListener: null,
+ _animationInfos: null,
+ _lastFrameListener: null,
+
+ ctor: function () {
+ cc.Action.prototype.ctor.call(this);
+ this._timelineMap = {};
+ this._timelineList = [];
+ this._animationInfos = {};
+ this.init();
+ },
+
+ _gotoFrame: function (frameIndex) {
+ var size = this._timelineList.length;
+ for (var i = 0; i < size; i++) {
+ this._timelineList[i]._gotoFrame(frameIndex);
+ }
+ },
+
+ _stepToFrame: function (frameIndex) {
+ var size = this._timelineList.length;
+ for (var i = 0; i < size; i++) {
+ this._timelineList[i]._stepToFrame(frameIndex);
+ }
+ },
+
+ //emit frame event, call it when enter a frame
+ _emitFrameEvent: function (frame) {
+ if (this._frameEventListener) {
+ this._frameEventListener(frame);
+ }
+ },
+
+ init: function () {
+ return true;
+ },
+
+ /**
+ * Goto the specified frame index, and start playing from this index.
+ * @param startIndex The animation will play from this index.
+ * @param [endIndex=] The animation will end at this index.
+ * @param [currentFrameIndex=] set current frame index.
+ * @param [loop=] Whether or not the animation need loop.
+ */
+ gotoFrameAndPlay: function (startIndex, endIndex, currentFrameIndex, loop) {
+ //Consolidation parameters
+ var i = 0,
+ argLen = arguments.length;
+ var num = [],
+ bool;
+ for (i; i < argLen; i++) {
+ if (typeof arguments[i] === "boolean") {
+ bool = arguments[i];
+ } else {
+ num.push(arguments[i]);
+ }
+ }
+ startIndex = num[0];
+ endIndex = num[1] !== undefined ? num[1] : this._duration;
+ currentFrameIndex = num[2] || startIndex;
+ loop = bool != null ? bool : true;
+
+ this._startFrame = startIndex;
+ this._endFrame = endIndex;
+ this._currentFrame = currentFrameIndex;
+ this._loop = loop;
+ this._time = this._currentFrame * this._frameInternal;
+
+ this.resume();
+ this._gotoFrame(this._currentFrame);
+ },
+
+ /**
+ * Goto the specified frame index, and pause at this index.
+ * @param startIndex The animation will pause at this index.
+ */
+ gotoFrameAndPause: function (startIndex) {
+ this._startFrame = this._currentFrame = startIndex;
+ this._time = this._currentFrame * this._frameInternal;
+
+ this.pause();
+ this._gotoFrame(this._currentFrame);
+ },
+
+ /**
+ * Pause the animation.
+ */
+ pause: function () {
+ this._playing = false;
+ },
+
+ /**
+ * Resume the animation.
+ */
+ resume: function () {
+ this._playing = true;
+ },
+
+ /**
+ * Whether or not Action is playing.
+ */
+ isPlaying: function () {
+ return this._playing;
+ },
+
+ /**
+ * Set the animation speed, this will speed up or slow down the speed.
+ * @param {number} speed
+ */
+ setTimeSpeed: function (speed) {
+ this._timeSpeed = speed;
+ },
+
+ /**
+ * Get current animation speed.
+ * @returns {number}
+ */
+ getTimeSpeed: function () {
+ return this._timeSpeed;
+ },
+
+ /**
+ * duration of the whole action
+ * @param {number} duration
+ */
+ setDuration: function (duration) {
+ this._duration = duration;
+ },
+
+ /**
+ * Get current animation duration.
+ * @returns {number}
+ */
+ getDuration: function () {
+ return this._duration;
+ },
+
+ /**
+ * Start frame index of this action
+ * @returns {number}
+ */
+ getStartFrame: function () {
+ return this._startFrame;
+ },
+
+ /**
+ * End frame of this action.
+ * When action play to this frame, if action is not loop, then it will stop,
+ * or it will play from start frame again.
+ * @returns {number}
+ */
+ getEndFrame: function () {
+ return this._endFrame;
+ },
+
+ /**
+ * Set current frame index, this will cause action plays to this frame.
+ */
+ setCurrentFrame: function (frameIndex) {
+ if (frameIndex >= this._startFrame && frameIndex <= this._endFrame) {
+ this._currentFrame = frameIndex;
+ this._time = this._currentFrame * this._frameInternal;
+ } else {
+ cc.log("frame index is not between start frame and end frame");
+ }
+
+ },
+
+ /**
+ * Get current frame.
+ * @returns {number}
+ */
+ getCurrentFrame: function () {
+ return this._currentFrame;
+ },
+
+ /**
+ * add Timeline to ActionTimeline
+ * @param {ccs.Timeline} timeline
+ */
+ addTimeline: function (timeline) {
+ var tag = timeline.getActionTag();
+ if (!this._timelineMap[tag]) {
+ this._timelineMap[tag] = [];
+ }
+
+ if (this._timelineMap[tag].indexOf(timeline) === -1) {
+ this._timelineList.push(timeline);
+ this._timelineMap[tag].push(timeline);
+ timeline.setActionTimeline(this);
+ }
+
+ },
+
+ /**
+ * remove Timeline to ActionTimeline
+ * @param {ccs.Timeline} timeline
+ */
+ removeTimeline: function (timeline) {
+ var tag = timeline.getActionTag();
+ if (this._timelineMap[tag]) {
+ if (this._timelineMap[tag].some(function (item) {
+ if (item === timeline)
+ return true;
+ })) {
+ cc.arrayRemoveObject(this._timelineMap[tag], timeline);
+ cc.arrayRemoveObject(this._timelineList, timeline);
+ timeline.setActionTimeline(null);
+ }
+ }
+ },
+
+ /**
+ * Gets the timeline list
+ * @returns {array | null}
+ */
+ getTimelines: function () {
+ return this._timelineList;
+ },
+
+ /**
+ * Set the Frame event
+ * @param {function} listener
+ */
+ setFrameEventCallFunc: function (listener) {
+ this._frameEventListener = listener;
+ },
+
+ /**
+ * remove event
+ */
+ clearFrameEventCallFunc: function () {
+ this._frameEventListener = null;
+ },
+
+ /**
+ * Clone this timeline
+ * @returns {ccs.ActionTimeline}
+ */
+ clone: function () {
+ var newAction = new ccs.ActionTimeline();
+ newAction.setDuration(this._duration);
+ newAction.setTimeSpeed(this._timeSpeed);
+
+ for (var a in this._timelineMap) {
+ var timelines = this._timelineMap[a];
+ for (var b in timelines) {
+ var timeline = timelines[b];
+ var newTimeline = timeline.clone();
+ newAction.addTimeline(newTimeline);
+ }
+ }
+
+ return newAction;
+
+ },
+
+ /**
+ * Reverse is not defined;
+ * @returns {null}
+ */
+ reverse: function () {
+ return null;
+ },
+
+ /**
+ * Stepping of this time line.
+ * @param {number} delta
+ */
+ step: function (delta) {
+ if (!this._playing || this._timelineMap.length === 0 || this._duration === 0) {
+ return;
+ }
+
+ this._time += delta * this._timeSpeed;
+ var endoffset = this._time - this._endFrame * this._frameInternal;
+
+ if (endoffset < this._frameInternal) {
+ this._currentFrame = Math.floor(this._time / this._frameInternal);
+ this._stepToFrame(this._currentFrame);
+ if (endoffset >= 0 && this._lastFrameListener)
+ this._lastFrameListener();
+ } else {
+ this._playing = this._loop;
+ if (!this._playing) {
+ this._time = this._endFrame * this._frameInternal;
+ if (this._currentFrame != this._endFrame) {
+ this._currentFrame = this._endFrame;
+ this._stepToFrame(this._currentFrame);
+ if (this._lastFrameListener)
+ this._lastFrameListener();
+ }
+ } else
+ this.gotoFrameAndPlay(this._startFrame, this._endFrame, this._loop);
+ }
+
+ },
+
+ _foreachNodeDescendant: function (parent, callback) {
+ callback(parent);
+
+ var children = parent.getChildren();
+ for (var i = 0; i < children.length; i++) {
+ var child = children[i];
+ this._foreachNodeDescendant(child, callback);
+ }
+ },
+
+ /**
+ * start with node.
+ * @param {cc.Node} target
+ */
+ startWithTarget: function(target){
+ cc.Action.prototype.startWithTarget.call(this, target);
+
+ var self = this;
+ var callback = function(child){
+ var data = child.getComponent("ComExtensionData");
+
+ if(data) {
+ var actionTag = data.getActionTag();
+ if(self._timelineMap[actionTag]) {
+ var timelines = self._timelineMap[actionTag];
+ for (var i=0; i _renderCmd._debug
+ if (this._squareVertices === null)
+ this._squareVertices = [
+ {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}
+ ];
+
+ this._rackColor = cc.color.WHITE;
+ this._blendFunc = BlendFunc.ALPHA_NON_PREMULTIPLIED;
+
+ this._childBones = [];
+ this._boneSkins = [];
+
+ this._rackLength = length === undefined ? 50 : length;
+ this._rackWidth = 20;
+ this._updateVertices();
+ //this._updateColor();
+ },
+
+ visit: function (parent) {
+ this._visit && this._visit(parent && parent._renderCmd);
+ },
+
+ addSkin: function (skin, display, hideOthers/*false*/) {
+ // skin, display
+ // skin, display, hideOthers
+ var boneSkins = this._boneSkins;
+ debug.assert(skin != null, "Argument must be non-nil");
+ if (hideOthers) {
+ for (var i = 0; i < boneSkins.length; i++) {
+ boneSkins[i].setVisible(false);
+ }
+ }
+ Node.prototype.addChild.call(this, skin);
+ this._boneSkins.push(skin);
+ skin.setVisible(display);
+ },
+
+ getChildBones: function () {
+ return this._childBones;
+ },
+
+ getSkins: function () {
+ return this._boneSkins;
+ },
+
+ displaySkin: function (skin, hideOthers) {
+ var boneSkins = this._boneSkins;
+ var boneSkin, i;
+ if (typeof skin === "string") {
+ for (i = 0; i < boneSkins.length; i++) {
+ boneSkin = boneSkins[i];
+ if (skin == boneSkin.getName()) {
+ boneSkin.setVisible(true);
+ } else if (hideOthers) {
+ boneSkin.setVisible(false);
+ }
+ }
+ } else {
+ for (i = 0; i < boneSkins.length; i++) {
+ boneSkin = boneSkins[i];
+ if (boneSkin == skin) {
+ boneSkin.setVisible(true);
+ } else if (hideOthers) {
+ boneSkin.setVisible(false);
+ }
+ }
+ }
+ },
+
+ getVisibleSkins: function () {
+ var displayingSkins = [];
+ var boneSkins = this._boneSkins;
+ for (var boneSkin, i = 0; i < boneSkins.length; i++) {
+ boneSkin = boneSkins[i];
+ if (boneSkin.isVisible()) {
+ displayingSkins.push(boneSkin);
+ }
+ }
+ return displayingSkins;
+ },
+
+ getRootSkeletonNode: function () {
+ return this._rootSkeleton;
+ },
+
+ getAllSubBones: function () {
+ var allBones = [];
+ var boneStack = []; // for avoid recursive
+ var childBones = this._childBones;
+ for (var i = 0; i < childBones.length; i++) {
+ boneStack.push(childBones[i]);
+ }
+
+ while (boneStack.length > 0) {
+ var top = boneStack.pop();
+ allBones.push(top);
+ var topChildren = top.getChildBones();
+ for (var j = 0; j < topChildren; j++) {
+ boneStack.push(topChildren[j]);
+ }
+ }
+ return allBones;
+ },
+
+ getAllSubSkins: function () {
+ var allBones = this.getAllSubBones();
+ var allSkins = [];
+ for (var i = 0; i < allBones.length; i++) {
+ var skins = allBones[i].getSkins();
+ for (var j = 0; j < skins.length; j++) {
+ allSkins.push(skins[i]);
+ }
+ }
+ return allSkins;
+ },
+
+ addChild: function (child, localZOrder, tag) {
+ //child, localZOrder, tag
+ //child, localZOrder, name
+ Node.prototype.addChild.call(this, child, localZOrder, tag);
+ this._addToChildrenListHelper(child);
+ },
+
+ removeChild: function (child, cleanup) {
+ if (this._children.indexOf(child) !== -1) {
+ Node.prototype.removeChild.call(this, child, cleanup);
+ this._removeFromChildrenListHelper(child);
+ }
+ },
+
+ setBlendFunc: function (blendFunc) {
+ var ob = this._blendFunc;
+ if (blendFunc && ob.src !== blendFunc.src && ob.dst !== blendFunc.dst) {
+ this._blendFunc = blendFunc;
+ var boneSkins = this._boneSkins;
+ for (var boneSkin, i = 0; i < boneSkins.length; i++) {
+ boneSkin = boneSkins[i];
+ boneSkin.setBlendFunc(blendFunc);
+ }
+ }
+ },
+
+ getBlendFunc: function () {
+ return this._blendFunc;
+ },
+
+ setDebugDrawLength: function (length) {
+ this._rackLength = length;
+ this._updateVertices();
+ },
+
+ getDebugDrawLength: function () {
+ return this._rackLength;
+ },
+
+ setDebugDrawWidth: function (width) {
+ this._rackWidth = width;
+ this._updateVertices();
+ },
+
+ getDebugDrawWidth: function () {
+ return this._rackWidth;
+ },
+
+ setDebugDrawEnabled: function (isDebugDraw) {
+ var renderCmd = this._renderCmd;
+ if (renderCmd._debug === isDebugDraw)
+ return;
+
+ renderCmd._debug = isDebugDraw;
+ cc.renderer.childrenOrderDirty = true;
+
+ if (this._visible && null != this._rootSkeleton) {
+ this._rootSkeleton._subBonesDirty = true;
+ this._rootSkeleton._subBonesOrderDirty = true;
+ }
+ },
+
+ isDebugDrawEnabled: function () {
+ return this._renderCmd._debug;
+ },
+
+ setDebugDrawColor: function (color) {
+ this._rackColor = color;
+ },
+
+ getDebugDrawColor: function () {
+ return this._rackColor;
+ },
+
+ getVisibleSkinsRect: function () {
+ var minx, miny, maxx, maxy = 0;
+ minx = miny = maxx = maxy;
+ var first = true;
+
+ var displayRect = type.rect(0, 0, 0, 0);
+ if (this._renderCmd._debug && this._rootSkeleton != null && this._rootSkeleton._renderCmd._debug) {
+ maxx = this._rackWidth;
+ maxy = this._rackLength;
+ first = false;
+ }
+
+ var boneSkins = this._boneSkins;
+ for (var skin, i = 0; i < boneSkins.length; i++) {
+ skin = boneSkins[i];
+ var r = skin.getBoundingBox();
+ if (!skin.isVisible() || (r.x === 0 && r.y === 0 && r.width === 0 && r.height === 0))
+ continue;
+
+ if (first) {
+ minx = cc.rectGetMinX(r);
+ miny = cc.rectGetMinY(r);
+ maxx = cc.rectGetMaxX(r);
+ maxy = cc.rectGetMaxY(r);
+
+ first = false;
+ } else {
+ minx = Math.min(cc.rectGetMinX(r), minx);
+ miny = Math.min(cc.rectGetMinY(r), miny);
+ maxx = Math.max(cc.rectGetMaxX(r), maxx);
+ maxy = Math.max(cc.rectGetMaxY(r), maxy);
+ }
+ displayRect.setRect(minx, miny, maxx - minx, maxy - miny);
+ }
+ return displayRect;
+ },
+
+ getBoundingBox: function () {
+ var boundingBox = this.getVisibleSkinsRect();
+ return cc.rectApplyAffineTransform(boundingBox, this.getNodeToParentAffineTransform());
+ },
+
+ batchBoneDrawToSkeleton: function (bone) {
+ },
+
+ setLocalZOrder: function (localZOrder) {
+ Node.prototype.setLocalZOrder.call(this, localZOrder);
+ if (this._rootSkeleton != null)
+ this._rootSkeleton._subBonesOrderDirty = true;
+ },
+
+ setName: function (name) {
+ var rootSkeleton = this._rootSkeleton;
+ var oldName = this.getName();
+ Node.prototype.setName.call(this, name);
+ if (rootSkeleton != null) {
+ var oIter = rootSkeleton._subBonesMap[oldName];
+ var nIter = rootSkeleton._subBonesMap[name];
+ if (oIter && !nIter) {
+ delete rootSkeleton._subBonesMap[oIter];
+ rootSkeleton._subBonesMap[name] = oIter;
+ }
+ }
+ },
+
+ setContentSize: function (contentSize) {
+ Node.prototype.setContentSize.call(this, contentSize);
+ this._updateVertices();
+ },
+
+ setAnchorPoint: function (anchorPoint) {
+ Node.prototype.setAnchorPoint.call(this, anchorPoint);
+ this._updateVertices();
+ },
+
+ setVisible: function (visible) {
+ if (this._visible == visible)
+ return;
+ Node.prototype.setVisible.call(this, visible);
+ if (this._rootSkeleton != null) {
+ this._rootSkeleton._subBonesDirty = true;
+ this._rootSkeleton._subBonesOrderDirty = true;
+ }
+ },
+
+ _addToChildrenListHelper: function (child) {
+ if (child instanceof BoneNode) {
+ this._addToBoneList(child);
+ } else {
+ //if (child instanceof SkinNode) {
+ this._addToSkinList(child);
+ //}
+ }
+ },
+
+ _removeFromChildrenListHelper: function (child) {
+ if (child instanceof BoneNode) {
+ this._removeFromBoneList(child);
+ } else {
+ if (child instanceof SkinNode)
+ this._removeFromSkinList(skin);
+ }
+ },
+
+ _removeFromBoneList: function (bone) {
+ if (
+ this._rootSkeleton != null &&
+ bone instanceof ccs.SkeletonNode &&
+ bone._rootSkeleton === this._rootSkeleton
+ ) {
+ bone._rootSkeleton = null;
+ var subBones = bone.getAllSubBones();
+ subBones.push(bone);
+ for (var subBone, i = 0; i < subBones.length; i++) {
+ subBone = subBones[i];
+ subBone._rootSkeleton = null;
+ delete this._rootSkeleton._subBonesMap[subBone.getName()];
+ this._rootSkeleton._subBonesDirty = true;
+ this._rootSkeleton._subBonesOrderDirty = true;
+ }
+ } else {
+ this._rootSkeleton._subBonesDirty = true;
+ this._rootSkeleton._subBonesOrderDirty = true;
+ }
+ cc.arrayRemoveObject(this._childBones, bone);
+ },
+
+ _setRootSkeleton: function (rootSkeleton) {
+ this._rootSkeleton = rootSkeleton;
+ var subBones = this.getAllSubBones();
+ for (var i = 0; i < subBones.length; i++) {
+ this._addToBoneList(subBones[i]);
+ }
+ },
+
+ _addToBoneList: function (bone) {
+ if (this._childBones.indexOf(bone) === -1)
+ this._childBones.push(bone);
+ if (this._rootSkeleton != null) {
+ var skeletonNode = bone;
+ if (!(skeletonNode instanceof SkinNode) && !bone._rootSkeleton) {// not nest skeleton
+ var subBones = bone.getAllSubBones();
+ subBones.push(bone);
+ for (var subBone, i = 0; i < subBones.length; i++) {
+ subBone = subBones[i];
+ subBone._setRootSkeleton(this._rootSkeleton);
+ var bonename = subBone.getName();
+ if (!this._rootSkeleton._subBonesMap[bonename]) {
+ this._rootSkeleton._subBonesMap[subBone.getName()] = subBone;
+ this._rootSkeleton._subBonesDirty = true;
+ this._rootSkeleton._subBonesOrderDirty = true;
+ } else {
+ cc.log("already has a bone named %s in skeleton %s", bonename, this._rootSkeleton.getName());
+ this._rootSkeleton._subBonesDirty = true;
+ this._rootSkeleton._subBonesOrderDirty = true;
+ }
+ }
+ }
+ }
+ },
+
+ _visitSkins: function () {
+ var cmd = this._renderCmd;
+ // quick return if not visible
+ if (!this._visible)
+ return;
+
+ var parentCmd = cmd.getParentRenderCmd();
+ if (parentCmd)
+ cmd._curLevel = parentCmd._curLevel + 1;
+
+ //visit for canvas
+ var i, children = this._boneSkins, child;
+ //var i, children = this._children, child;
+ cmd._syncStatus(parentCmd);
+ var len = children.length;
+ if (len > 0) {
+ this.sortAllChildren();
+ // draw children zOrder < 0
+ for (i = 0; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder < 0)
+ child.visit(this);
+ else
+ break;
+ }
+ for (; i < len; i++)
+ children[i].visit(this);
+ }
+ cmd._dirtyFlag = 0;
+ },
+
+ _addToSkinList: function (skin) {
+ this._boneSkins.push(skin);
+ if (skin.getBlendFunc) {
+ var blendFunc = skin.getBlendFunc();
+ if (this._blendFunc.src !== blendFunc.src && this._blendFunc.dst !== blendFunc.dst)
+ skin.setBlendFunc(this._blendFunc);
+ }
+ },
+
+ _removeFromSkinList: function (skin) {
+ cc.arrayRemoveObject(this._boneSkins, skin);
+ },
+
+ sortAllChildren: function () {
+ this._sortArray(this._childBones);
+ this._sortArray(this._boneSkins);
+ Node.prototype.sortAllChildren.call(this);
+ },
+
+ _sortArray: function (array) {
+ if (!array)
+ return;
+ var len = array.length, i, j, tmp;
+ for (i = 1; i < len; i++) {
+ tmp = array[i];
+ j = i - 1;
+ while (j >= 0) {
+ if (tmp._localZOrder < array[j]._localZOrder) {
+ array[j + 1] = array[j];
+ } else if (tmp._localZOrder === array[j]._localZOrder && tmp.arrivalOrder < array[j].arrivalOrder) {
+ array[j + 1] = array[j];
+ } else {
+ break;
+ }
+ j--;
+ }
+ array[j + 1] = tmp;
+ }
+ },
+
+ _updateVertices: function () {
+ var squareVertices = this._squareVertices,
+ anchorPointInPoints = this._renderCmd._anchorPointInPoints;
+ if (this._rackLength != squareVertices[2].x - anchorPointInPoints.x ||
+ squareVertices[3].y != this._rackWidth / 2 - anchorPointInPoints.y) {
+
+ squareVertices[1].x = squareVertices[1].y = squareVertices[3].y = 0;
+ squareVertices[0].x = squareVertices[2].x = this._rackLength * .1;
+ squareVertices[2].y = this._rackWidth * .5;
+ squareVertices[0].y = -squareVertices[2].y;
+ squareVertices[3].x = this._rackLength;
+
+ for (var i = 0; i < squareVertices.length; i++) {
+ squareVertices[i].x += anchorPointInPoints.x;
+ squareVertices[i].y += anchorPointInPoints.y;
+ }
+
+ this._renderCmd.updateDebugPoint(squareVertices);
+ }
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new BoneNodeCanvasCmd(this);
+ else
+ return new BoneNodeWebGLCmd(this);
+ }
+ });
+
+ BoneNode.create = function (length, color) {
+ // null
+ // length
+ // length, color
+ return new ccui.BoneNode(length, color);
+ };
+
+ var BoneNodeCanvasCmd = (function () {
+
+ var BoneNodeCanvasCmd = function (node) {
+ this._rootCtor(node);
+ this._debug = false;
+ this._color = cc.color.WHITE;
+ this._drawNode = new cc.DrawNode();
+ };
+
+ var proto = BoneNodeCanvasCmd.prototype = Object.create(Node.CanvasRenderCmd.prototype);
+ proto.constructor = BoneNodeCanvasCmd;
+
+ proto.updateDebugPoint = function (points) {
+ this._drawNode.clear();
+ this._drawNode.drawPoly(points, this._color, 0, this._color);
+ };
+
+ proto.transform = function (parentCmd, recursive) {
+ var rootSkeleton = this._node._rootSkeleton;
+ this.originTransform(parentCmd, recursive);
+ if (rootSkeleton && rootSkeleton._renderCmd._debug) {
+ this._drawNode._renderCmd.transform(this);
+ }
+ };
+
+ return BoneNodeCanvasCmd;
+
+ })();
+
+ var BoneNodeWebGLCmd = (function () {
+
+ var BoneNodeWebGLCmd = function (node) {
+ this._rootCtor(node);
+ this._debug = false;
+ this._color = cc.color.WHITE;
+ this._drawNode = new cc.DrawNode();
+ };
+
+ var proto = BoneNodeWebGLCmd.prototype = Object.create(Node.WebGLRenderCmd.prototype);
+ proto.constructor = BoneNodeWebGLCmd;
+
+ proto.updateDebugPoint = function (points) {
+ this._drawNode.clear();
+ this._drawNode.drawPoly(points, this._color, 0, this._color);
+ };
+
+ proto.transform = function (parentCmd, recursive) {
+ var rootSkeleton = this._node._rootSkeleton;
+ this.originTransform(parentCmd, recursive);
+ if (rootSkeleton && rootSkeleton._renderCmd._debug) {
+ this._drawNode._renderCmd.transform(this);
+ }
+ };
+
+ return BoneNodeWebGLCmd;
+
+ })();
+
+ return BoneNode;
+
+})();
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/timeline/CCSkeletonNode.js b/frameworks/cocos2d-html5/extensions/cocostudio/timeline/CCSkeletonNode.js
new file mode 100644
index 0000000..2bd075f
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/timeline/CCSkeletonNode.js
@@ -0,0 +1,266 @@
+/****************************************************************************
+ Copyright (c) 2015-2016 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+//9980397
+
+/**
+ * SkeletonNode
+ * base class
+ * @class
+ */
+ccs.SkeletonNode = (function () {
+
+ var BoneNode = ccs.BoneNode;
+
+ var type = {
+ p: cc.p,
+ size: cc.size,
+ rect: cc.rect
+ };
+
+ var SkeletonNode = BoneNode.extend(/** @lends ccs.SkeletonNode# */{
+ _subBonesMap: null,
+
+ _squareVertices: null,
+ _squareColors: null,
+ _noMVPVertices: null,
+ _skinGroupMap: null,
+
+ _sortedAllBonesDirty: false,
+ _sortedAllBones: null,
+ _batchedBoneVetices: null,
+ _batchedBoneColors: null,
+ _batchedVeticesCount: null,
+ _batchBoneCommand: null,
+ _subOrderedAllBones: null,
+
+ ctor: function () {
+ this._squareVertices = [
+ {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0},
+ {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}
+ ];
+ this._rootSkeleton = this;
+ BoneNode.prototype.ctor.call(this);
+ this._subBonesMap = {};
+ this._subOrderedAllBones = [];
+
+ this._skinGroupMap = {};
+
+ this._rackLength = this._rackWidth = 20;
+ this._updateVertices();
+ },
+
+ getBoneNode: function (boneName) {
+ var item = this._subBonesMap[boneName];
+ if (item)
+ return item;
+ return null;
+ },
+
+ getAllSubBonesMap: function () {
+ return this._subBonesMap;
+ },
+
+ changeSkins: function (boneSkinNameMap) {
+ //boneSkinNameMap
+ //suitName
+ if (typeof boneSkinNameMap === "object") {
+ var boneSkin;
+ for (var name in boneSkinNameMap) {
+ boneSkin = boneSkinNameMap[name];
+ var bone = this.getBoneNode(name);
+ if (null !== bone)
+ bone.displaySkin(boneSkin, true);
+ }
+ } else {
+ var suit = this._suitMap[boneSkinNameMap/*suitName*/];
+ if (suit)
+ this.changeSkins(suit, true);
+ }
+ },
+
+ addSkinGroup: function (groupName, boneSkinNameMap) {
+ this._skinGroupMap[groupName] = boneSkinNameMap;
+ },
+
+ getBoundingBox: function () {
+ var minx, miny, maxx, maxy = 0;
+ minx = miny = maxx = maxy;
+ var boundingBox = this.getVisibleSkinsRect();
+ var first = true;
+ if (boundingBox.x !== 0 || boundingBox.y !== 0 || boundingBox.width !== 0 || boundingBox.height !== 0) {
+ minx = cc.rectGetMinX(boundingBox);
+ miny = cc.rectGetMinY(boundingBox);
+ maxx = cc.rectGetMaxX(boundingBox);
+ maxy = cc.rectGetMaxY(boundingBox);
+ first = false;
+ }
+ var allBones = this.getAllSubBones();
+ for (var bone, i = 0; i < allBones.length; i++) {
+ bone = allBones[i];
+ var r = cc.rectApplyAffineTransform(bone.getVisibleSkinsRect(), bone.getNodeToParentTransform(bone.getRootSkeletonNode()));
+ if (r.x === 0 && r.y === 0 && r.width === 0 && r.height === 0)
+ continue;
+
+ if (first) {
+ minx = cc.rectGetMinX(r);
+ miny = cc.rectGetMinY(r);
+ maxx = cc.rectGetMaxX(r);
+ maxy = cc.rectGetMaxY(r);
+
+ first = false;
+ } else {
+ minx = Math.min(cc.rectGetMinX(r), minx);
+ miny = Math.min(cc.rectGetMinY(r), miny);
+ maxx = Math.max(cc.rectGetMaxX(r), maxx);
+ maxy = Math.max(cc.rectGetMaxY(r), maxy);
+ }
+ }
+ boundingBox.x = minx;
+ boundingBox.y = miny;
+ boundingBox.width = maxx - minx;
+ boundingBox.height = maxy - miny;
+ return cc.rectApplyAffineTransform(boundingBox, this.getNodeToParentTransform());
+ },
+
+ _visit: function (parentCmd) {
+ var cmd = this._renderCmd;
+ parentCmd = parentCmd || cmd.getParentRenderCmd();
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
+ cmd._syncStatus(parentCmd);
+
+ var i, node;
+ if (this._children.length !== 0) {
+ for (i = 0; i < this._children.length; i++) {
+ node = this._children[i];
+ node.visit(this);
+ }
+ }
+
+ this._checkSubBonesDirty();
+ var subOrderedAllBones = this._subOrderedAllBones,
+ subOrderedBone, subOrderedBoneCmd;
+ for (i = 0; i < subOrderedAllBones.length; i++) {
+ subOrderedBone = subOrderedAllBones[i];
+ subOrderedBone._visitSkins();
+ }
+
+ if (cmd._debug)
+ for (i = 0; i < subOrderedAllBones.length; i++) {
+ subOrderedBoneCmd = subOrderedAllBones[i]._renderCmd;
+ cc.renderer.pushRenderCommand(subOrderedBoneCmd._drawNode._renderCmd);
+ }
+ cmd._dirtyFlag = 0;
+ },
+
+ _checkSubBonesDirty: function () {
+ if (this._subBonesDirty) {
+ this._updateOrderedAllbones();
+ this._subBonesDirty = false;
+ }
+ if (this._subBonesOrderDirty) {
+ this._sortOrderedAllBones();
+ this._subBonesOrderDirty = false;
+ }
+ },
+
+ _updateOrderedAllbones: function () {
+ this._subOrderedAllBones.length = 0;
+ // update sub bones, get All Visible SubBones
+ // get all sub bones as visit with visible
+ var boneStack = [];
+ var childBones = this._childBones;
+ for (var bone, i = 0; i < childBones.length; i++) {
+ bone = childBones[i];
+ if (bone.isVisible())
+ boneStack.push(bone);
+ }
+ while (boneStack.length > 0) {
+ var top = boneStack.pop();
+ var topCmd = top._renderCmd;
+ topCmd._syncStatus(topCmd.getParentRenderCmd());
+ this._subOrderedAllBones.push(top);
+
+ var topChildren = top.getChildBones();
+
+ for (var childbone, i = 0; i < topChildren.length; i++) {
+ childbone = topChildren[i];
+ if (childbone.isVisible())
+ boneStack.push(childbone);
+ }
+ }
+ },
+
+ _sortOrderedAllBones: function () {
+ this._sortArray(this._subOrderedAllBones);
+ },
+
+ // protected
+ _updateVertices: function () {
+ var squareVertices = this._squareVertices,
+ anchorPointInPoints = this._renderCmd._anchorPointInPoints;
+ if (this._rackLength != squareVertices[6].x - anchorPointInPoints.x ||
+ this._rackWidth != squareVertices[3].y - anchorPointInPoints.y) {
+ var radiusl = this._rackLength * .5;
+ var radiusw = this._rackWidth * .5;
+ var radiusl_2 = radiusl * .25;
+ var radiusw_2 = radiusw * .25;
+ squareVertices[5].y = squareVertices[2].y = squareVertices[1].y = squareVertices[6].y
+ = squareVertices[0].x = squareVertices[4].x = squareVertices[7].x = squareVertices[3].x = .0;
+ squareVertices[5].x = -radiusl; squareVertices[0].y = -radiusw;
+ squareVertices[6].x = radiusl; squareVertices[3].y = radiusw;
+ squareVertices[1].x = radiusl_2; squareVertices[7].y = radiusw_2;
+ squareVertices[2].x = -radiusl_2; squareVertices[4].y = -radiusw_2;
+ for (var i = 0; i < squareVertices.length; i++) {
+ squareVertices[i].x += anchorPointInPoints.x;
+ squareVertices[i].y += anchorPointInPoints.y;
+ }
+ }
+ },
+
+ _updateAllDrawBones: function () {
+ this._subDrawBones = {}; //.clear()
+ for (var name in this._subBonesMap) {
+ var bone = this._subBonesMap[name];
+ if (bone.isVisible() && bone.isDebugDrawEnabled())
+ this._subDrawBones.push(bone);
+ }
+ this._sortArray(this._sortedAllBones);
+ this._subDrawBones = false;
+ }
+
+ });
+
+ SkeletonNode.create = function () {
+ return new SkeletonNode;
+ };
+
+ return SkeletonNode;
+
+})();
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/timeline/CCSkinNode.js b/frameworks/cocos2d-html5/extensions/cocostudio/timeline/CCSkinNode.js
new file mode 100644
index 0000000..310af38
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/timeline/CCSkinNode.js
@@ -0,0 +1,14 @@
+ccs.SkinNode = (function () {
+
+ var Node = cc.Node;
+
+ var proto = {};
+
+ var SkinNode = Node.extend(proto);
+
+ SkinNode.create = function () {
+ };
+
+ return SkinNode;
+
+})();
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/timeline/Frame.js b/frameworks/cocos2d-html5/extensions/cocostudio/timeline/Frame.js
new file mode 100644
index 0000000..b935fce
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/timeline/Frame.js
@@ -0,0 +1,1430 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Timeline Frame.
+ * base class
+ * @class
+ */
+ccs.Frame = ccs.Class.extend({
+
+ _frameIndex: null,
+ _tween: null,
+ _timeline: null,
+ _node: null,
+ _tweenType: null,
+ _easingParam: null,
+ _enterWhenPassed: null,
+
+ ctor: function () {
+ this._frameIndex = 0;
+ this._tween = true;
+ this._timeline = null;
+ this._node = null;
+ this._enterWhenPassed = false;
+ this._easingParam = [];
+ },
+
+ _emitEvent: function () {
+ if (this._timeline) {
+ this._timeline.getActionTimeline()._emitFrameEvent(this);
+ }
+ },
+
+ _cloneProperty: function (frame) {
+ this._frameIndex = frame.getFrameIndex();
+ this._tween = frame.isTween();
+ this._tweenType = frame.getTweenType();
+ this.setEasingParams(frame.getEasingParams());
+ },
+
+ /**
+ * Set the frame index
+ * @param {number} frameIndex
+ */
+ setFrameIndex: function (frameIndex) {
+ this._frameIndex = frameIndex;
+ },
+
+ /**
+ * Get the frame index
+ * @returns {null}
+ */
+ getFrameIndex: function () {
+ return this._frameIndex;
+ },
+
+ /**
+ * Set timeline
+ * @param timeline
+ */
+ setTimeline: function (timeline) {
+ this._timeline = timeline;
+ },
+
+ /**
+ * Get timeline
+ * @param timeline
+ * @returns {ccs.timeline}
+ */
+ getTimeline: function (timeline) {
+ return this._timeline;
+ },
+
+ /**
+ * Set Node
+ * @param {cc.Node} node
+ */
+ setNode: function (node) {
+ this._node = node;
+ },
+
+ /**
+ * gets the Node
+ * @return node
+ */
+ getNode: function () {
+ return this._node;
+ },
+
+ /**
+ * set tween
+ * @param tween
+ */
+ setTween: function (tween) {
+ this._tween = tween;
+ },
+
+ /**
+ * Gets the tween
+ * @returns {boolean | null}
+ */
+ isTween: function () {
+ return this._tween;
+ },
+
+ /**
+ * the execution of the callback
+ * @override
+ * @param {ccs.Frame} nextFrame
+ */
+ onEnter: function (nextFrame) { // = 0
+ },
+
+ /**
+ * Each frame logic
+ * @override
+ * @param {number} percent
+ */
+ apply: function (percent) {
+ if (!this._tween)
+ return;
+ if (this._tweenType !== ccs.FrameEaseType.TWEEN_EASING_MAX && this._tweenType !== ccs.FrameEaseType.LINEAR)
+ percent = this.tweenPercent(percent);
+ this._onApply(percent);
+ },
+
+ _onApply: function (percent) {
+
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ * @override
+ * @return {ccs.Frame}
+ */
+ clone: function () { // = 0
+ },
+
+ tweenPercent: function (percent) {
+ var func = ccs.Frame.tweenToMap[this._tweenType];
+ if (func)
+ return func(percent, this._easingParam);
+ else
+ return percent;
+ },
+
+ setEasingParams: function (easingParams) {
+ if (easingParams) {
+ this._easingParam.length = 0;
+ for (var i = 0; i < easingParams.length; i++)
+ this._easingParam[i] = easingParams[i];
+ }
+ },
+
+ getEasingParams: function () {
+ return this._easingParam;
+ },
+
+ setTweenType: function (tweenType) {
+ this._tweenType = tweenType;
+ },
+
+ getTweenType: function () {
+ return this._tweenType;
+ },
+
+ isEnterWhenPassed: function () {
+ return this._enterWhenPassed;
+ }
+});
+
+ccs.Frame.tweenToMap = {
+ "-1": function (time, easingParam) {
+ if (easingParam) {
+ var tt = 1 - time;
+ return easingParam[1] * tt * tt * tt + 3 * easingParam[3] * time * tt * tt + 3 * easingParam[5] * time * time * tt + easingParam[7] * time * time * time;
+ }
+ return time;
+ },
+ 1: cc._easeSineInObj.easing,//Sine_EaseIn
+ 2: cc._easeSineOutObj.easing,//Sine_EaseOut
+ 3: cc._easeSineInOutObj.easing,//Sine_EaseInOut
+
+ 4: cc._easeQuadraticActionIn.easing,//Quad_EaseIn
+ 5: cc._easeQuadraticActionOut.easing,//Quad_EaseOut
+ 6: cc._easeQuadraticActionInOut.easing,//Quad_EaseInOut
+
+ 7: cc._easeCubicActionIn.easing, //Cubic_EaseIn
+ 8: cc._easeCubicActionOut.easing,//Cubic_EaseOut
+ 9: cc._easeCubicActionInOut.easing,//Cubic_EaseInOut
+
+ 10: cc._easeCubicActionIn.easing,//Cubic_EaseIn
+ 11: cc._easeCubicActionOut.easing,//Cubic_EaseOut
+ 12: cc._easeCubicActionInOut.easing,//Cubic_EaseInOut
+
+ 13: cc._easeQuinticActionIn.easing,//Quint_EaseIn
+ 14: cc._easeQuinticActionOut.easing,//Quint_EaseOut
+ 15: cc._easeQuinticActionInOut.easing,//Quint_EaseInOut
+
+ 16: cc._easeExponentialInObj.easing,//Expo_EaseIn
+ 17: cc._easeExponentialOutObj.easing,//Expo_EaseOut
+ 18: cc._easeExponentialInOutObj.easing,//Expo_EaseInOut
+
+ 19: cc._easeCircleActionIn.easing,//Circ_EaseIn
+ 20: cc._easeCircleActionOut.easing,//Circ_EaseOut
+ 21: cc._easeCircleActionInOut.easing,//Circ_EaseInOut
+
+ 22: function (time, easingParam) {
+ var period = 0.3;
+ easingParam != null && ( period = easingParam[0] );
+ return cc.easeElasticIn(period).easing(time);
+ },//Elastic_EaesIn
+ 23: function (time, easingParam) {
+ var period = 0.3;
+ easingParam != null && ( period = easingParam[0] );
+ return cc.easeElasticOut(period).easing(time);
+ },//Elastic_EaesOut
+ 24: function (time, easingParam) {
+ var period = 0.3;
+ easingParam != null && ( period = easingParam[0] );
+ return cc.easeElasticInOut(period).easing(time);
+ },//Elastic_EaesInOut
+
+ 25: cc._easeBackInObj.easing, //Back_EaseIn
+ 26: cc._easeBackOutObj.easing, //Back_EaseOut
+ 27: cc._easeBackInOutObj.easing, //Back_EaseInOut
+
+ 28: cc._easeBounceInObj.easing, //Bounce_EaseIn
+ 29: cc._easeBounceOutObj.easing, //Bounce_EaseOut
+ 30: cc._easeBounceInOutObj.easing //Bounce_EaseInOut
+};
+
+/**
+ * Visible frame
+ * To control the display state
+ * @class
+ * @extend ccs.Frame
+ */
+ccs.VisibleFrame = ccs.Frame.extend({
+
+ _visible: true,
+
+ ctor: function () {
+ ccs.Frame.prototype.ctor.call(this);
+ this._visible = true;
+ },
+
+ /**
+ * the execution of the callback
+ * @param {ccs.Frame} nextFrame
+ */
+ onEnter: function (nextFrame) {
+ if (this._node)
+ this._node.setVisible(this._visible);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ * @return {ccs.VisibleFrame}
+ */
+ clone: function () {
+ var frame = new ccs.VisibleFrame();
+ frame.setVisible(this._visible);
+
+ frame._cloneProperty(this);
+
+ return frame;
+ },
+
+ /**
+ * Set display state
+ * @param {Boolean} visible
+ */
+ setVisible: function (visible) {
+ this._visible = visible;
+ },
+
+ /**
+ * Get the display state
+ * @returns {Boolean}
+ */
+ isVisible: function () {
+ return this._visible;
+ }
+
+});
+
+/**
+ * Create the visible frame
+ *
+ * @deprecated v3.0, please use new ccs.VisibleFrame() instead.
+ * @returns {ccs.VisibleFrame}
+ */
+ccs.VisibleFrame.create = function () {
+ return new ccs.VisibleFrame();
+};
+
+/**
+ * Texture frame
+ * @class
+ * @extend ccs.Frame
+ */
+ccs.TextureFrame = ccs.Frame.extend({
+
+ _sprite: null,
+ _textureName: null,
+
+ ctor: function () {
+ ccs.Frame.prototype.ctor.call(this);
+
+ this._textureName = "";
+ },
+
+ /**
+ * Set the node element to draw texture
+ * @param {cc.Node} node
+ */
+ setNode: function (node) {
+ ccs.Frame.prototype.setNode.call(this, node);
+ this._sprite = node;
+ },
+
+ /**
+ * the execution of the callback
+ * @param {ccs.Frame} nextFrame
+ */
+ onEnter: function (nextFrame) {
+ if (this._sprite) {
+ var spriteBlendFunc = this._sprite.getBlendFunc();
+ var spriteFrame = cc.spriteFrameCache._spriteFrames[this._textureName];
+ if (spriteFrame != null)
+ this._sprite.setSpriteFrame(spriteFrame);
+ else
+ this._sprite.setTexture(this._textureName);
+
+ if (this._sprite.getBlendFunc() !== spriteBlendFunc)
+ this._sprite.setBlendFunc(spriteBlendFunc);
+ }
+
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ * @return {ccs.TextureFrame}
+ */
+ clone: function () {
+ var frame = new ccs.TextureFrame();
+ frame.setTextureName(this._textureName);
+ frame._cloneProperty(this);
+ return frame;
+ },
+
+ /**
+ * Set the texture name
+ * @param {string} textureName
+ */
+ setTextureName: function (textureName) {
+ this._textureName = textureName;
+ },
+
+ /**
+ * Gets the Texture name
+ * @returns {null}
+ */
+ getTextureName: function () {
+ return this._textureName;
+ }
+
+});
+
+/**
+ * Create the Texture frame
+ *
+ * @deprecated v3.0, please use new ccs.TextureFrame() instead.
+ * @returns {ccs.TextureFrame}
+ */
+ccs.TextureFrame.create = function () {
+ return new ccs.TextureFrame();
+};
+
+/**
+ * Rotation Frame
+ * @class
+ * @extend ccs.Frame
+ */
+ccs.RotationFrame = ccs.Frame.extend({
+
+ _rotation: null,
+ _betwennRotation: null,
+
+ ctor: function () {
+ ccs.Frame.prototype.ctor.call(this);
+ this._rotation = 0;
+ },
+
+ /**
+ * the execution of the callback
+ * @param {ccs.Frame} nextFrame
+ */
+ onEnter: function (nextFrame) {
+ if (!this._node)
+ return;
+ this._node.setRotation(this._rotation);
+
+ if (this._tween) {
+ this._betwennRotation = nextFrame._rotation - this._rotation;
+ }
+ },
+
+ /**
+ * Each frame logic
+ * @param {number} percent
+ */
+ _onApply: function (percent) {
+ if (this._betwennRotation !== 0) {
+ var rotation = this._rotation + percent * this._betwennRotation;
+ this._node.setRotation(rotation);
+ }
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ * @return {ccs.RotationFrame}
+ */
+ clone: function () {
+ var frame = new ccs.RotationFrame();
+ frame.setRotation(this._rotation);
+
+ frame._cloneProperty(this);
+
+ return frame;
+ },
+
+ /**
+ * Set the rotation
+ * @param {Number} rotation
+ */
+ setRotation: function (rotation) {
+ this._rotation = rotation;
+ },
+
+ /**
+ * Gets the rotation
+ * @returns {Number}
+ */
+ getRotation: function () {
+ return this._rotation;
+ }
+
+});
+
+/**
+ * Create the Rotation frame
+ *
+ * @deprecated v3.0, please use new ccs.RotationFrame() instead.
+ * @returns {ccs.RotationFrame}
+ */
+ccs.RotationFrame.create = function () {
+ return new ccs.RotationFrame();
+};
+
+/**
+ * Skew frame
+ * @class
+ * @extend ccs.Frame
+ */
+ccs.SkewFrame = ccs.Frame.extend({
+
+ _skewX: null,
+ _skewY: null,
+ _betweenSkewX: null,
+ _betweenSkewY: null,
+
+ ctor: function () {
+ ccs.Frame.prototype.ctor.call(this);
+ this._skewX = 0;
+ this._skewY = 0;
+ },
+
+ /**
+ * the execution of the callback
+ * @param {ccs.Frame} nextFrame
+ */
+ onEnter: function (nextFrame) {
+ if (!this._node)
+ return;
+ this._node.setSkewX(this._skewX);
+ this._node.setSkewY(this._skewY);
+
+ if (this._tween) {
+ this._betweenSkewX = nextFrame._skewX - this._skewX;
+ this._betweenSkewY = nextFrame._skewY - this._skewY;
+ }
+
+ },
+
+ /**
+ * Each frame logic
+ * @param {number} percent
+ */
+ _onApply: function (percent) {
+ if (this._betweenSkewX !== 0 || this._betweenSkewY !== 0) {
+ var skewx = this._skewX + percent * this._betweenSkewX;
+ var skewy = this._skewY + percent * this._betweenSkewY;
+
+ this._node.setSkewX(skewx);
+ this._node.setSkewY(skewy);
+ }
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ * @return {ccs.SkewFrame}
+ */
+ clone: function () {
+ var frame = new ccs.SkewFrame();
+ frame.setSkewX(this._skewX);
+ frame.setSkewY(this._skewY);
+
+ frame._cloneProperty(this);
+
+ return frame;
+ },
+
+ /**
+ * Set the skew x
+ * @param {Number} skewx
+ */
+ setSkewX: function (skewx) {
+ this._skewX = skewx;
+ },
+
+ /**
+ * Gets the skew x
+ * @returns {Number}
+ */
+ getSkewX: function () {
+ return this._skewX;
+ },
+
+ /**
+ * Set the skew y
+ * @param {Number} skewy
+ */
+ setSkewY: function (skewy) {
+ this._skewY = skewy;
+ },
+
+ /**
+ * Gets the skew y
+ * @returns {Number}
+ */
+ getSkewY: function () {
+ return this._skewY;
+ }
+
+});
+
+/**
+ * Create the Skew frame
+ *
+ * @deprecated v3.0, please use new ccs.SkewFrame() instead.
+ * @returns {ccs.SkewFrame}
+ */
+ccs.SkewFrame.create = function () {
+ return new ccs.SkewFrame();
+};
+
+/**
+ * Rotation skew frame
+ * @class
+ * @extend ccs.SkewFrame
+ */
+ccs.RotationSkewFrame = ccs.SkewFrame.extend({
+
+ /**
+ * the execution of the callback
+ * @param {ccs.Frame} nextFrame
+ */
+ onEnter: function (nextFrame) {
+ if (!this._node)
+ return;
+ this._node.setRotationX(this._skewX);
+ this._node.setRotationY(this._skewY);
+
+ if (this._tween) {
+ this._betweenSkewX = nextFrame._skewX - this._skewX;
+ this._betweenSkewY = nextFrame._skewY - this._skewY;
+ }
+
+ },
+
+ /**
+ * Each frame logic
+ * @param {number} percent
+ */
+ _onApply: function (percent) {
+ if (this._node && (this._betweenSkewX !== 0 || this._betweenSkewY !== 0)) {
+ var skewx = this._skewX + percent * this._betweenSkewX;
+ var skewy = this._skewY + percent * this._betweenSkewY;
+
+ this._node.setRotationX(skewx);
+ this._node.setRotationY(skewy);
+ }
+
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ * @return {ccs.RotationSkewFrame}
+ */
+ clone: function () {
+ var frame = new ccs.RotationSkewFrame();
+ frame.setSkewX(this._skewX);
+ frame.setSkewY(this._skewY);
+
+ frame._cloneProperty(this);
+
+ return frame;
+
+ }
+
+});
+
+/**
+ * Create the RotationSkew frame
+ *
+ * @deprecated v3.0, please use new ccs.RotationSkewFrame() instead.
+ * @returns {ccs.RotationSkewFrame}
+ */
+ccs.RotationSkewFrame.create = function () {
+ return new ccs.RotationSkewFrame();
+};
+
+/**
+ * Position frame
+ * @class
+ * @extend ccs.Frame
+ */
+ccs.PositionFrame = ccs.Frame.extend({
+
+ _position: null,
+ _betweenX: null,
+ _betweenY: null,
+
+ ctor: function () {
+ ccs.Frame.prototype.ctor.call(this);
+ this._position = cc.p(0, 0);
+ },
+
+ /**
+ * the execution of the callback
+ * @param {ccs.Frame} nextFrame
+ */
+ onEnter: function (nextFrame) {
+ if (!this._node)
+ return;
+
+ this._node.setPosition(this._position);
+
+ if (this._tween) {
+ this._betweenX = nextFrame._position.x - this._position.x;
+ this._betweenY = nextFrame._position.y - this._position.y;
+ }
+ },
+
+ /**
+ * Each frame logic
+ * @param {number} percent
+ */
+ _onApply: function (percent) {
+ if (this._node && (this._betweenX !== 0 || this._betweenY !== 0)) {
+ var p = cc.p(0, 0);
+ p.x = this._position.x + this._betweenX * percent;
+ p.y = this._position.y + this._betweenY * percent;
+
+ this._node.setPosition(p);
+ }
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ * @return {ccs.PositionFrame}
+ */
+ clone: function () {
+ var frame = new ccs.PositionFrame();
+ frame.setPosition(this._position);
+
+ frame._cloneProperty(this);
+
+ return frame;
+ },
+
+ /**
+ * Set the position
+ * @param {cc.p} position
+ */
+ setPosition: function (position) {
+ this._position = position;
+ },
+
+ /**
+ * gets the position
+ * @returns {cc.p}
+ */
+ getPosition: function () {
+ return this._position;
+ },
+
+ /**
+ * Set the position x
+ * @param {Number} x
+ */
+ setX: function (x) {
+ this._position.x = x;
+ },
+
+ /**
+ * Gets the position x
+ * @returns {Number}
+ */
+ getX: function () {
+ return this._position.x;
+ },
+
+ /**
+ * Set the position y
+ * @param {Number} y
+ */
+ setY: function (y) {
+ this._position.y = y;
+ },
+
+ /**
+ * Gets the position y
+ * @returns {Number}
+ */
+ getY: function () {
+ return this._position.y;
+ }
+
+});
+
+/**
+ * Create the Position frame
+ *
+ * @deprecated v3.0, please use new ccs.PositionFrame() instead.
+ * @returns {ccs.PositionFrame}
+ */
+ccs.PositionFrame.create = function () {
+ return new ccs.PositionFrame();
+};
+
+/**
+ * Scale frame
+ * @class
+ * @xtend ccs.Frame
+ */
+ccs.ScaleFrame = ccs.Frame.extend({
+
+ _scaleX: null,
+ _scaleY: null,
+ _betweenScaleX: null,
+ _betweenScaleY: null,
+
+ ctor: function () {
+ ccs.Frame.prototype.ctor.call(this);
+ this._scaleX = 1;
+ this._scaleY = 1;
+ },
+
+ /**
+ * the execution of the callback
+ * @param {ccs.Frame} nextFrame
+ */
+ onEnter: function (nextFrame) {
+ if (!this._node)
+ return;
+ this._node.setScaleX(this._scaleX);
+ this._node.setScaleY(this._scaleY);
+
+ if (this._tween) {
+ this._betweenScaleX = nextFrame._scaleX - this._scaleX;
+ this._betweenScaleY = nextFrame._scaleY - this._scaleY;
+ }
+
+ },
+
+ /**
+ * Each frame logic
+ * @param {number} percent
+ */
+ _onApply: function (percent) {
+ if (this._node && (this._betweenScaleX !== 0 || this._betweenScaleY !== 0)) {
+ var scaleX = this._scaleX + this._betweenScaleX * percent;
+ var scaleY = this._scaleY + this._betweenScaleY * percent;
+
+ this._node.setScaleX(scaleX);
+ this._node.setScaleY(scaleY);
+ }
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ * @return {ccs.ScaleFrame}
+ */
+ clone: function () {
+ var frame = new ccs.ScaleFrame();
+ frame.setScaleX(this._scaleX);
+ frame.setScaleY(this._scaleY);
+
+ frame._cloneProperty(this);
+
+ return frame;
+
+ },
+
+ /**
+ * Set the scale
+ * @param {Number} scale
+ */
+ setScale: function (scale) {
+ this._scaleX = scale;
+ this._scaleY = scale;
+ },
+
+ /**
+ * Set the scale x
+ * @param {Number} scaleX
+ */
+ setScaleX: function (scaleX) {
+ this._scaleX = scaleX;
+ },
+
+ /**
+ * Gets the scale x
+ * @returns {Number}
+ */
+ getScaleX: function () {
+ return this._scaleX;
+ },
+
+ /**
+ * Set the scale y
+ * @param {Number} scaleY
+ */
+ setScaleY: function (scaleY) {
+ this._scaleY = scaleY;
+ },
+
+ /**
+ * Gets the scale y
+ * @returns {Number}
+ */
+ getScaleY: function () {
+ return this._scaleY;
+ }
+
+});
+
+/**
+ * Create the Scale frame
+ *
+ * @deprecated v3.0, please use new ccs.ScaleFrame() instead.
+ * @returns {ccs.ScaleFrame}
+ */
+ccs.ScaleFrame.create = function () {
+ return new ccs.ScaleFrame();
+};
+
+/**
+ * AnchorPoint frame
+ * @class
+ * @extend ccs.Frame
+ */
+ccs.AnchorPointFrame = ccs.Frame.extend({
+
+ _anchorPoint: null,
+
+ ctor: function () {
+ ccs.Frame.prototype.ctor.call(this);
+ this._anchorPoint = cc.p(0, 0);
+ },
+
+ /**
+ * the execution of the callback
+ * @param {ccs.Frame} nextFrame
+ */
+ onEnter: function (nextFrame) {
+ if (this._node)
+ this._node.setAnchorPoint(this._anchorPoint);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ * @return {ccs.AnchorPointFrame}
+ */
+ clone: function () {
+ var frame = new ccs.AnchorPointFrame();
+ frame.setAnchorPoint(this._anchorPoint);
+
+ frame._cloneProperty(this);
+
+ return frame;
+ },
+
+ /**
+ * Set the anchor point
+ * @param {cc.p} point
+ */
+ setAnchorPoint: function (point) {
+ this._anchorPoint = point;
+ },
+
+ /**
+ * Gets the anchor point
+ * @returns {cc.p}
+ */
+ getAnchorPoint: function () {
+ return this._anchorPoint;
+ }
+
+});
+
+/**
+ * Create the AnchorPoint frame
+ *
+ * @deprecated v3.0, please use new ccs.AnchorPointFrame() instead.
+ * @returns {ccs.AnchorPointFrame}
+ */
+ccs.AnchorPointFrame.create = function () {
+ return new ccs.AnchorPointFrame();
+};
+
+/**
+ * Static param
+ * @namespace
+ */
+ccs.InnerActionType = {
+ LoopAction: 0,
+ NoLoopAction: 1,
+ SingleFrame: 2
+};
+
+/**
+ * Inner action frame
+ * @class
+ * @extend ccs.Frame
+ */
+ccs.InnerActionFrame = ccs.Frame.extend({
+
+ _innerActionType: null,
+ _startFrameIndex: null,
+
+ _endFrameIndex: 0,
+ _singleFrameIndex: 0,
+ _enterWithName: null,
+ _animationName: "",
+
+ ctor: function () {
+ ccs.Frame.prototype.ctor.call(this);
+
+ this._enterWithName = false;
+ this._innerActionType = ccs.InnerActionType.LoopAction;
+ this._startFrameIndex = 0;
+ },
+
+ /**
+ * the execution of the callback
+ * @param {ccs.Frame} nextFrame
+ */
+ onEnter: function (nextFrame) {
+ if (!this._node) return;
+ var innerActiontimeline = this._node.getActionByTag(this._node.getTag());
+ if (!innerActiontimeline) return;
+ if (ccs.InnerActionType.SingleFrame === this._innerActionType) {
+ innerActiontimeline.gotoFrameAndPause(this._singleFrameIndex);
+ return;
+ }
+
+ var innerStart = this._startFrameIndex;
+ var innerEnd = this._endFrameIndex;
+ if (this._enterWithName) {
+ if (this._animationName === "-- ALL --") {
+ innerStart = 0;
+ innerEnd = innerActiontimeline.getDuration();
+ } else if (innerActiontimeline.isAnimationInfoExists(this._animationName)) {
+ var info = innerActiontimeline.getAnimationInfo(this._animationName);
+ innerStart = info.startIndex;
+ innerEnd = info.endIndex;
+ } else {
+ cc.log("Animation %s not exists!", this._animationName);
+ }
+ }
+
+ var duration = this._timeline.getActionTimeline().getDuration();
+ var odddiff = duration - this._frameIndex - innerEnd + innerStart;
+ if (odddiff < 0) {
+ innerEnd += odddiff;
+ }
+
+ if (ccs.InnerActionType.NoLoopAction === this._innerActionType) {
+ innerActiontimeline.gotoFrameAndPlay(innerStart, innerEnd, false);
+ } else if (ccs.InnerActionType.LoopAction === this._innerActionType) {
+ innerActiontimeline.gotoFrameAndPlay(innerStart, innerEnd, true);
+ }
+ },
+
+ setAnimationName: function (animationName) {
+ this._animationName = animationName;
+ },
+
+ setSingleFrameIndex: function (frameIndex) {
+ this._singleFrameIndex = frameIndex;
+ },
+
+ getSingleFrameIndex: function () {
+ return this._startFrameIndex;
+ },
+
+ setEnterWithName: function (isEnterWithName) {
+ this._enterWithName = isEnterWithName;
+ },
+
+ getEnterWithName: function () {
+ return this._enterWithName;
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ * @return {ccs.InnerActionFrame}
+ */
+ clone: function () {
+ var frame = new ccs.InnerActionFrame();
+ frame.setInnerActionType(this._innerActionType);
+ frame.setStartFrameIndex(this._startFrameIndex);
+ frame.setEnterWithName(this._enterWithName);
+ frame.setAnimationName(this._animationName);
+ frame.setSingleFrameIndex(this._singleFrameIndex);
+
+ frame._cloneProperty(this);
+
+ return frame;
+
+ },
+
+ /**
+ * Set the inner action type
+ * @param {ccs.InnerActionType} type
+ */
+ setInnerActionType: function (type) {
+ this._innerActionType = type;
+ },
+
+ /**
+ * Gets the inner action type
+ * @returns {ccs.InnerActionType}
+ */
+ getInnerActionType: function () {
+ return this._innerActionType;
+ },
+
+ /**
+ * Set the start frame index
+ * @param {Number} frameIndex
+ */
+ setStartFrameIndex: function (frameIndex) {
+ this._startFrameIndex = frameIndex;
+ },
+
+ /**
+ * Get the start frame index
+ * @returns {Number}
+ */
+ getStartFrameIndex: function () {
+ return this._startFrameIndex;
+ }
+
+});
+
+/**
+ * Create the InnerAction frame
+ *
+ * @deprecated v3.0, please use new ccs.InnerActionFrame() instead.
+ * @returns {ccs.InnerActionFrame}
+ */
+ccs.InnerActionFrame.create = function () {
+ return new ccs.InnerActionFrame();
+};
+
+/**
+ * Color frame
+ * @class
+ * @extend ccs.Frame
+ */
+ccs.ColorFrame = ccs.Frame.extend({
+
+ _alpha: null,
+ _color: null,
+
+ _betweenAlpha: null,
+ _betweenRed: null,
+ _betweenGreen: null,
+ _betweenBlue: null,
+
+ ctor: function () {
+ ccs.Frame.prototype.ctor.call(this);
+ this._color = cc.color(255, 255, 255);
+ },
+
+ /**
+ * the execution of the callback
+ * @param {ccs.ColorFrame} nextFrame
+ */
+ onEnter: function (nextFrame) {
+ if (!this._node)
+ return;
+ this._node.setColor(this._color);
+ if (this._tween) {
+ var color = nextFrame._color;
+ this._betweenRed = color.r - this._color.r;
+ this._betweenGreen = color.g - this._color.g;
+ this._betweenBlue = color.b - this._color.b;
+ }
+
+ },
+
+ /**
+ * Each frame logic
+ * @param {number} percent
+ */
+ _onApply: function (percent) {
+ if (this._node && this._tween && (this._betweenAlpha !== 0 || this._betweenRed !== 0 || this._betweenGreen !== 0 || this._betweenBlue !== 0)) {
+
+ var color = cc.color(255, 255, 255);
+ color.r = this._color.r + this._betweenRed * percent;
+ color.g = this._color.g + this._betweenGreen * percent;
+ color.b = this._color.b + this._betweenBlue * percent;
+
+ this._node.setColor(color);
+ if (this._alpha !== null) {
+ var alpha = this._alpha + this._betweenAlpha * percent;
+ this._node.setOpacity(alpha);
+ }
+
+ }
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ * @return {ccs.ColorFrame}
+ */
+ clone: function () {
+ var frame = new ccs.ColorFrame();
+ frame.setColor(this._color);
+ frame._cloneProperty(this);
+ return frame;
+ },
+
+ /**
+ * Set the color
+ * @param {cc.color} color
+ */
+ setColor: function (color) {
+ this._color = color;
+ },
+
+ /**
+ * Gets the color
+ * @returns {cc.color}
+ */
+ getColor: function () {
+ return this._color;
+ }
+
+});
+
+/**
+ * Create the Color frame
+ *
+ * @deprecated v3.0, please use new ccs.ColorFrame() instead.
+ * @returns {ccs.ColorFrame}
+ */
+ccs.ColorFrame.create = function () {
+ return new ccs.ColorFrame();
+};
+
+/**
+ * Alpha frame
+ * @class
+ * @extend ccs.Frame
+ */
+ccs.AlphaFrame = ccs.Frame.extend({
+
+ _alpha: null,
+ _betweenAlpha: null,
+
+ ctor: function () {
+ ccs.Frame.prototype.ctor.call(this);
+ this._alpha = 255;
+ },
+
+ onEnter: function (nextFrame) {
+ if (!this._node)
+ return;
+ this._node.setOpacity(this._alpha);
+ if (this._tween) {
+ this._betweenAlpha = nextFrame._alpha - this._alpha;
+ }
+ },
+
+ _onApply: function (percent) {
+ if (!this._node)
+ return;
+ var alpha = this._alpha + this._betweenAlpha * percent;
+ this._node.setOpacity(alpha);
+ },
+
+ /**
+ * Set the alpha
+ * @param {Number} alpha
+ */
+ setAlpha: function (alpha) {
+ this._alpha = alpha;
+ },
+
+ /**
+ * Gets the alpha
+ * @returns {Number}
+ */
+ getAlpha: function () {
+ return this._alpha;
+ },
+
+ clone: function () {
+ var frame = new ccs.AlphaFrame();
+ frame.setAlpha(this._alpha);
+ frame._cloneProperty(this);
+ return frame;
+ }
+});
+
+/**
+ * Event frame
+ * @class
+ * @extend ccs.Frame
+ */
+ccs.EventFrame = ccs.Frame.extend({
+
+ _event: null,
+
+ ctor: function () {
+ ccs.Frame.prototype.ctor.call(this);
+ this._event = "";
+ this._enterWhenPassed = true;
+ },
+
+ /**
+ * the execution of the callback
+ * @param {ccs.Frame} nextFrame
+ */
+ onEnter: function (nextFrame) {
+ this._emitEvent();
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ * @return {ccs.EventFrame}
+ */
+ clone: function () {
+ var frame = new ccs.EventFrame();
+ frame.setEvent(this._event);
+
+ frame._cloneProperty(this);
+
+ return frame;
+ },
+
+ /**
+ * Set the event
+ * @param event
+ */
+ setEvent: function (event) {
+ this._event = event;
+ },
+
+ /**
+ * Gets the event
+ * @returns {null}
+ */
+ getEvent: function () {
+ return this._event;
+ }
+
+});
+
+/**
+ * Create the Event frame
+ *
+ * @deprecated v3.0, please use new ccs.EventFrame() instead.
+ * @returns {ccs.EventFrame}
+ */
+ccs.EventFrame.create = function () {
+ return new ccs.EventFrame();
+};
+
+/**
+ * zOrder frame
+ * @class
+ * @extend ccs.Frame
+ */
+ccs.ZOrderFrame = ccs.Frame.extend({
+
+ _zorder: 0,
+
+ /**
+ * the execution of the callback
+ * @param {ccs.Frame} nextFrame
+ */
+ onEnter: function (nextFrame) {
+ if (this._node)
+ this._node.setLocalZOrder(this._zorder);
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ * @return {ccs.ZOrderFrame}
+ */
+ clone: function () {
+ var frame = new ccs.ZOrderFrame();
+ frame.setZOrder(this._zorder);
+
+ frame._cloneProperty(this);
+
+ return frame;
+ },
+
+ /**
+ * Set the zOrder
+ * @param {Number} zorder
+ */
+ setZOrder: function (zorder) {
+ this._zorder = zorder;
+ },
+
+ /**
+ * Gets the zOrder
+ * @returns {Number}
+ */
+ getZOrder: function () {
+ return this._zorder;
+ }
+
+});
+
+/**
+ * Create the ZOrder frame
+ *
+ * @deprecated v3.0, please use new ccs.ZOrderFrame() instead.
+ * @returns {ccs.ZOrderFrame}
+ */
+ccs.ZOrderFrame.create = function () {
+ return new ccs.ZOrderFrame();
+};
+
+ccs.BlendFuncFrame = ccs.Frame.extend({
+ ctor: function () {
+ this._super();
+ this._blendFunc = null;
+ },
+
+ onEnter: function (nextFrame, currentFrameIndex) {
+ if (this._node && this._blendFunc)
+ this._node.setBlendFunc(this._blendFunc);
+ },
+
+ clone: function () {
+ var frame = new ccs.BlendFuncFrame();
+ frame.setBlendFunc(this._blendFunc);
+ frame._cloneProperty(this);
+ return frame;
+ },
+
+ setBlendFunc: function (blendFunc) {
+ if (blendFunc && blendFunc.src && blendFunc.dst)
+ this._blendFunc = blendFunc;
+ },
+
+ getBlendFunc: function () {
+ return this._blendFunc;
+ }
+});
+
+ccs.BlendFuncFrame.create = function () {
+ return new ccs.BlendFuncFrame();
+};
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/timeline/Timeline.js b/frameworks/cocos2d-html5/extensions/cocostudio/timeline/Timeline.js
new file mode 100644
index 0000000..fe2818c
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/timeline/Timeline.js
@@ -0,0 +1,329 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * timeline object
+ * @class
+ * @extend ccs.Class
+ */
+ccs.Timeline = ccs.Class.extend({
+
+ //{ccs.Frame}
+ _frames: null,
+ //{ccs.Frame}
+ _currentKeyFrame: null,
+ //{Number}
+ _currentKeyFrameIndex: null,
+ //{Number}
+ _fromIndex: null,
+ //{Number}
+ _toIndex: null,
+ //{Number}
+ _betweenDuration: null,
+ //{Number}
+ _actionTag: null,
+ //{ccs.ActionTimeline}
+ _ActionTimeline: null,
+ //{cc.Node}
+ _node: null,
+
+ ctor: function () {
+ this._frames = [];
+ this._currentKeyFrame = null;
+ this._currentKeyFrameIndex = 0;
+ this._fromIndex = 0;
+ this._toIndex = 0;
+ this._betweenDuration = 0;
+ this._actionTag = 0;
+ this._ActionTimeline = null;
+ this._node = null;
+ },
+
+ _gotoFrame: function (frameIndex) {
+ if (this._frames.length === 0)
+ return;
+
+ this._binarySearchKeyFrame(frameIndex);
+ this._apply(frameIndex);
+ },
+
+ _stepToFrame: function (frameIndex) {
+ if (this._frames.length === 0)
+ return;
+
+ this._updateCurrentKeyFrame(frameIndex);
+ this._apply(frameIndex);
+ },
+
+ /**
+ * Get the frame list
+ * @returns {ccs.Frame}
+ */
+ getFrames: function () {
+ return this._frames;
+ },
+
+ /**
+ * push frame to frame list
+ * @param {ccs.Frame} frame
+ */
+ addFrame: function (frame) {
+ this._frames.push(frame);
+ frame.setTimeline(this)
+ },
+
+ /**
+ * insert the frame to frame list
+ * @param {ccs.Frame} frame
+ * @param {Number} index
+ */
+ insertFrame: function (frame, index) {
+ this._frames.splice(index, 0, frame);
+ frame.setTimeline(this);
+
+ },
+
+ /**
+ * remove frame
+ * @param {ccs.Frame} frame
+ */
+ removeFrame: function (frame) {
+ cc.arrayRemoveObject(this._frames, frame);
+ frame.setTimeline(null);
+ },
+
+ /**
+ * Set the action tag
+ * @param {Number} tag
+ */
+ setActionTag: function (tag) {
+ this._actionTag = tag;
+ },
+
+ /**
+ * Gets the action tag
+ * return {Number}
+ */
+ getActionTag: function () {
+ return this._actionTag;
+ },
+
+ /**
+ * Set the node
+ * @param {cc.Node} node
+ */
+ setNode: function (node) {
+ for (var i = 0; i < this._frames.length; i++) {
+ var frame = this._frames[i];
+ frame.setNode(node);
+ }
+ },
+
+ /**
+ * Gets the node
+ * return {cc.Node}
+ */
+ getNode: function () {
+ return this._node;
+ },
+
+ /**
+ * Set the action timeline
+ * @param {ccs.ActionTimeline} action
+ */
+ setActionTimeline: function (action) {
+ this._ActionTimeline = action;
+ },
+
+ /**
+ * get the action timeline
+ * return {cc.Action}
+ */
+ getActionTimeline: function () {
+ return this._ActionTimeline;
+ },
+
+ /**
+ * to copy object with deep copy.
+ * returns a clone of action.
+ * @return {ccs.Timeline}
+ */
+ clone: function () {
+ var timeline = new ccs.Timeline();
+ timeline._actionTag = this._actionTag;
+
+ for (var i = 0; i < this._frames.length; i++) {
+ var frame = this._frames[i];
+ var newFrame = frame.clone();
+ timeline.addFrame(newFrame);
+ }
+
+ return timeline;
+
+ },
+
+ _apply: function (frameIndex) {
+ if (this._currentKeyFrame) {
+ var currentPercent = this._betweenDuration <= 0 ? 0 : (frameIndex - this._currentKeyFrameIndex) / this._betweenDuration;
+ this._currentKeyFrame.apply(currentPercent);
+ }
+ },
+
+ _binarySearchKeyFrame: function (frameIndex) {
+ var from = null;
+ var to = null;
+
+ var length = this._frames.length;
+ var needEnterFrame = false;
+
+ do {
+ if (frameIndex < this._frames[0].getFrameIndex()) {
+ if (this._currentKeyFrameIndex >= this._frames[0].getFrameIndex())
+ needEnterFrame = true;
+
+ this._fromIndex = 0;
+ this._toIndex = 0;
+
+ from = to = this._frames[0];
+ this._currentKeyFrameIndex = 0;
+ this._betweenDuration = this._frames[0].getFrameIndex();
+ break;
+ } else if (frameIndex >= this._frames[length - 1].getFrameIndex()) {
+ this._fromIndex = length - 1;
+ this._toIndex = 0;
+
+ from = to = this._frames[length - 1];
+ this._currentKeyFrameIndex = this._frames[length - 1].getFrameIndex();
+ this._betweenDuration = 0;
+ break;
+ }
+
+ var target = -1;
+ var low = 0,
+ high = length - 1,
+ mid = 0;
+ while (low <= high) {
+ mid = Math.ceil(( low + high ) / 2);
+ if (frameIndex >= this._frames[mid].getFrameIndex() && frameIndex < this._frames[mid + 1].getFrameIndex()) {
+ target = mid;
+ break;
+ }
+ if (this._frames[mid].getFrameIndex() > frameIndex)
+ high = mid - 1;
+ else
+ low = mid + 1;
+ }
+
+ this._fromIndex = target;
+
+ if (length > 1)
+ this._toIndex = (target + 1) | 0;
+ else
+ this._toIndex = (target) | 0;
+
+ from = this._frames[this._fromIndex];
+ to = this._frames[this._toIndex];
+
+ from = this._frames[target];
+ to = this._frames[target + 1];
+
+ if (target === 0 && this._currentKeyFrameIndex < from.getFrameIndex())
+ needEnterFrame = true;
+
+ this._currentKeyFrameIndex = from.getFrameIndex();
+ this._betweenDuration = to.getFrameIndex() - from.getFrameIndex();
+ } while (0);
+
+ if (needEnterFrame || this._currentKeyFrame != from) {
+ this._currentKeyFrame = from;
+ this._currentKeyFrame.onEnter(to);
+ }
+
+ },
+
+ _updateCurrentKeyFrame: function (frameIndex) {
+ if (frameIndex > 60)
+ var a = 0;
+ //! If play to current frame's front or back, then find current frame again
+ if (frameIndex < this._currentKeyFrameIndex || frameIndex >= this._currentKeyFrameIndex + this._betweenDuration) {
+ var from = null;
+ var to = null;
+
+ do
+ {
+ var length = this._frames.length;
+
+ if (frameIndex < this._frames[0].getFrameIndex()) {
+ from = to = this._frames[0];
+ this._currentKeyFrameIndex = 0;
+ this._betweenDuration = this._frames[0].getFrameIndex();
+ break;
+ }
+ else if (frameIndex >= this._frames[length - 1].getFrameIndex()) {
+ var lastFrameIndex = this._frames[length - 1].getFrameIndex();
+ if (this._currentKeyFrameIndex >= lastFrameIndex)
+ return;
+ frameIndex = lastFrameIndex;
+ }
+
+ do {
+ this._fromIndex = this._toIndex;
+ from = this._frames[this._fromIndex];
+ this._currentKeyFrameIndex = from.getFrameIndex();
+
+ this._toIndex = this._fromIndex + 1;
+ if (this._toIndex >= length) {
+ this._toIndex = 0;
+ }
+
+ to = this._frames[this._toIndex];
+
+ if (frameIndex === from.getFrameIndex())
+ break;
+ if (frameIndex > from.getFrameIndex() && frameIndex < to.getFrameIndex())
+ break;
+ if (from.isEnterWhenPassed())
+ from.onEnter(to);
+ } while (true);
+
+ this._betweenDuration = to.getFrameIndex() - from.getFrameIndex();
+
+ } while (0);
+
+ this._currentKeyFrame = from;
+ this._currentKeyFrame.onEnter(to);
+ }
+ }
+
+});
+
+/**
+ * Create the Timeline
+ *
+ * @deprecated v3.0, please use new ccs.Timeline() instead.
+ * @returns {ccs.Timeline}
+ */
+ccs.Timeline.create = function () {
+ return new ccs.Timeline();
+};
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/trigger/ObjectFactory.js b/frameworks/cocos2d-html5/extensions/cocostudio/trigger/ObjectFactory.js
new file mode 100644
index 0000000..c2bc197
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/trigger/ObjectFactory.js
@@ -0,0 +1,99 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The singleton object that creating object factory, it creates object with class name, and manager the type mapping.
+ * @class
+ * @name ccs.objectFactory
+ */
+ccs.objectFactory = /** @lends ccs.objectFactory# */{
+ _typeMap: {},
+
+ /**
+ * Creates object with class name. if the the class name without register in type map, it returns null.
+ * @param {String} className
+ * @returns {*}
+ */
+ createObject: function (className) {
+ var o = null;
+ var t = this._typeMap[className];
+ if (t) {
+ if(cc.isFunction(t._fun))
+ o = new t._fun();
+ else
+ o = t._fun;
+ }
+ return o;
+ },
+
+ /**
+ * Registers class type in type map.
+ * @param {ccs.TInfo} t
+ */
+ registerType: function (t) {
+ this._typeMap[t._className] = t;
+ },
+
+ /**
+ * Creates ccui widget object.
+ * @param {String} name widget name
+ * @returns {ccui.Widget|null}
+ */
+ createGUI: function(name){
+ var object = null;
+ if(name === "Panel")
+ name = "Layout";
+ else if(name === "TextArea")
+ name = "Label";
+ else if(name === "TextButton")
+ name = "Button";
+
+ var t = this._typeMap[name];
+ if(t && t._fun)
+ object = t._fun;
+
+ return object;
+ },
+
+ removeAll: function(){
+ this._typeMap = {};
+ }
+};
+
+ccs.TInfo = ccs.Class.extend({
+ _className: "",
+ _fun: null,
+
+ ctor: function (c, f) {
+ if (f) {
+ this._className = c;
+ this._fun = f;
+ } else {
+ this._className = c._className;
+ this._fun = c._fun;
+ }
+ ccs.objectFactory.registerType(this);
+ }
+});
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/trigger/TriggerBase.js b/frameworks/cocos2d-html5/extensions/cocostudio/trigger/TriggerBase.js
new file mode 100644
index 0000000..4c773e4
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/trigger/TriggerBase.js
@@ -0,0 +1,49 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Sends event by trigger manager.
+ * @function
+ * @param {Number} event
+ */
+ccs.sendEvent = function (event) {
+ var triggerObjArr = ccs.triggerManager.get(event);
+ if (triggerObjArr == null)
+ return;
+ for (var i = 0; i < triggerObjArr.length; i++) {
+ var triObj = triggerObjArr[i];
+ if (triObj != null && triObj.detect())
+ triObj.done();
+ }
+};
+
+/**
+ * Registers a trigger class to objectFactory type map.
+ * @param {String} className
+ * @param {function} func
+ */
+ccs.registerTriggerClass = function (className, func) {
+ new ccs.TInfo(className, func);
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/trigger/TriggerMng.js b/frameworks/cocos2d-html5/extensions/cocostudio/trigger/TriggerMng.js
new file mode 100644
index 0000000..e0167a1
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/trigger/TriggerMng.js
@@ -0,0 +1,301 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The trigger manager of Cocostudio
+ * @class
+ * @name ccs.triggerManager
+ */
+ccs.triggerManager = /** @lends ccs.triggerManager# */{
+ _eventTriggers: {},
+ _triggerObjs: {},
+ _movementDispatches: [],
+
+ /**
+ * Parses the triggers.
+ * @param {Array} triggers
+ */
+ parse: function (triggers) {
+ for (var i = 0; i < triggers.length; ++i) {
+ var subDict = triggers[i];
+ var triggerObj = new ccs.TriggerObj();
+ triggerObj.serialize(subDict);
+ var events = triggerObj.getEvents();
+ for (var j = 0; j < events.length; j++) {
+ var event = events[j];
+ this.add(event, triggerObj);
+ }
+ this._triggerObjs[triggerObj.getId()] = triggerObj;
+ }
+ },
+
+ /**
+ * Returns the event triggers by event id.
+ * @param {Number} event
+ * @returns {Array}
+ */
+ get: function (event) {
+ return this._eventTriggers[event];
+ },
+
+ /**
+ * Returns the trigger object by id
+ * @param {Number} id
+ * @returns {ccs.TriggerObj}
+ */
+ getTriggerObj: function (id) {
+ return this._triggerObjs[id];
+ },
+
+ /**
+ * Adds event and trigger object to trigger manager.
+ * @param event
+ * @param triggerObj
+ */
+ add: function (event, triggerObj) {
+ var eventTriggers = this._eventTriggers[event];
+ if (!eventTriggers)
+ eventTriggers = [];
+ if (eventTriggers.indexOf(triggerObj) === -1) {
+ eventTriggers.push(triggerObj);
+ this._eventTriggers[event] = eventTriggers;
+ }
+ },
+
+ /**
+ * Removes all event triggers from manager.
+ */
+ removeAll: function () {
+ for (var key in this._eventTriggers) {
+ var triObjArr = this._eventTriggers[key];
+ for (var j = 0; j < triObjArr.length; j++) {
+ var obj = triObjArr[j];
+ obj.removeAll();
+ }
+ }
+ this._eventTriggers = {};
+ },
+
+ /**
+ * Removes event object from trigger manager.
+ * @param {*} event
+ * @param {*} Obj
+ * @returns {Boolean}
+ */
+ remove: function (event, Obj) {
+ if (Obj)
+ return this._removeObj(event, Obj);
+
+ var bRet = false;
+ do {
+ var triObjects = this._eventTriggers[event];
+ if (!triObjects)
+ break;
+ for (var i = 0; i < triObjects.length; i++) {
+ var triObject = triObjects[i];
+ if (triObject)
+ triObject.removeAll();
+ }
+ delete this._eventTriggers[event];
+ bRet = true;
+ } while (0);
+ return bRet;
+ },
+
+ _removeObj: function (event, Obj) {
+ var bRet = false;
+ do
+ {
+ var triObjects = this._eventTriggers[event];
+ if (!triObjects) break;
+ for (var i = 0; i < triObjects.length; i++) {
+ var triObject = triObjects[i];
+ if (triObject && triObject == Obj) {
+ triObject.removeAll();
+ triObjects.splice(i, 1);
+ break;
+ }
+ }
+ bRet = true;
+ } while (0);
+ return bRet;
+ },
+
+ /**
+ * Removes trigger object from manager
+ * @param {Number} id
+ * @returns {boolean}
+ */
+ removeTriggerObj: function (id) {
+ var obj = this.getTriggerObj(id);
+ if (!obj)
+ return false;
+ var events = obj.getEvents();
+ for (var i = 0; i < events.length; i++) {
+ var event = events[i];
+ this.remove(event, obj);
+ }
+ return true;
+ },
+
+ /**
+ * Returns the event triggers whether is empty.
+ * @returns {boolean}
+ */
+ isEmpty: function () {
+ return !this._eventTriggers || this._eventTriggers.length <= 0;
+ },
+
+ /**
+ * Adds an armature movement callback to manager.
+ * @param {ccs.Armature} armature
+ * @param {function} callFunc
+ * @param {Object} target
+ */
+ addArmatureMovementCallBack: function (armature, callFunc, target) {
+ if (armature == null || target == null || callFunc == null)
+ return;
+ var locAmd, hasADD = false;
+ for (var i = 0; i < this._movementDispatches.length; i++) {
+ locAmd = this._movementDispatches[i];
+ if (locAmd && locAmd[0] === armature) {
+ locAmd.addAnimationEventCallBack(callFunc, target);
+ hasADD = true;
+ }
+ }
+ if (!hasADD) {
+ var newAmd = new ccs.ArmatureMovementDispatcher();
+ armature.getAnimation().setMovementEventCallFunc(newAmd.animationEvent, newAmd);
+ newAmd.addAnimationEventCallBack(callFunc, target);
+ this._movementDispatches.push([armature, newAmd]);
+ }
+ },
+
+ /**
+ * Removes armature movement callback from manager.
+ * @param {ccs.Armature} armature
+ * @param {Object} target
+ * @param {function} callFunc
+ */
+ removeArmatureMovementCallBack: function (armature, target, callFunc) {
+ if (armature == null || target == null || callFunc == null)
+ return;
+ var locAmd;
+ for (var i = 0; i < this._movementDispatches.length; i++) {
+ locAmd = this._movementDispatches[i];
+ if (locAmd && locAmd[0] === armature)
+ locAmd.removeAnimationEventCallBack(callFunc, target);
+ }
+ },
+
+ /**
+ * Removes an armature's all movement callbacks.
+ * @param {ccs.Armature} armature
+ */
+ removeArmatureAllMovementCallBack: function (armature) {
+ if (armature == null)
+ return;
+ var locAmd;
+ for (var i = 0; i < this._movementDispatches.length; i++) {
+ locAmd = this._movementDispatches[i];
+ if (locAmd && locAmd[0] === armature) {
+ this._movementDispatches.splice(i, 1);
+ break;
+ }
+ }
+ },
+
+ /**
+ * Removes all armature movement callbacks from ccs.triggerManager.
+ */
+ removeAllArmatureMovementCallBack: function () {
+ this._movementDispatches.length = 0;
+ },
+
+ /**
+ * Returns the version of ccs.triggerManager
+ * @returns {string}
+ */
+ version: function () {
+ return "1.2.0.0";
+ }
+};
+
+/**
+ * The armature movement dispatcher for trigger manager.
+ * @class
+ * @extends ccs.Class
+ */
+ccs.ArmatureMovementDispatcher = ccs.Class.extend(/** @lends ccs.ArmatureMovementDispatcher# */{
+ _mapEventAnimation: null,
+
+ /**
+ * Constructor of ArmatureMovementDispatcher.
+ */
+ ctor: function () {
+ this._mapEventAnimation = [];
+ },
+
+ /**
+ * Calls armature movement events.
+ * @param {ccs.Armature} armature
+ * @param {Number} movementType
+ * @param {String} movementID
+ */
+ animationEvent: function (armature, movementType, movementID) {
+ var locEventAni, locTarget, locFunc;
+ for (var i = 0; i < this._mapEventAnimation.length; i++) {
+ locEventAni = this._mapEventAnimation[i];
+ locTarget = locEventAni[0];
+ locFunc = locEventAni[1];
+ if (locFunc)
+ locFunc.call(locTarget, armature, movementType, movementID);
+ }
+ },
+
+ /**
+ * Adds animation event callback to event animation list
+ * @param {function} callFunc
+ * @param {Object|null} [target]
+ */
+ addAnimationEventCallBack: function (callFunc, target) {
+ this._mapEventAnimation.push([target, callFunc]);
+ },
+
+ /**
+ * Removes animation event callback from trigger manager.
+ * @param {function} callFunc
+ * @param {Object|null} [target]
+ */
+ removeAnimationEventCallBack: function (callFunc, target) {
+ var locEventAni;
+ for (var i = 0; i < this._mapEventAnimation.length; i++) {
+ locEventAni = this._mapEventAnimation[i];
+ if (locEventAni[0] === target) {
+ this._mapEventAnimation.splice(i, 1);
+ }
+ }
+ }
+});
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/cocostudio/trigger/TriggerObj.js b/frameworks/cocos2d-html5/extensions/cocostudio/trigger/TriggerObj.js
new file mode 100644
index 0000000..6a8e3c1
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/cocostudio/trigger/TriggerObj.js
@@ -0,0 +1,263 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The base class of trigger condition.
+ * @class
+ * @extends ccs.Class
+ */
+ccs.BaseTriggerCondition = ccs.Class.extend(/** @lends ccs.BaseTriggerCondition# */{
+ /**
+ * Construction of ccs.BaseTriggerCondition
+ */
+ ctor:function(){
+ },
+
+ /**
+ * initializes a BaseTriggerCondition class.
+ * @returns {boolean}
+ */
+ init: function () {
+ return true;
+ },
+
+ /**
+ * Detects trigger condition
+ * @returns {boolean}
+ */
+ detect: function () {
+ return true;
+ },
+
+ /**
+ * Serialize a BaseTriggerCondition object.
+ * @param jsonVal
+ */
+ serialize: function (jsonVal) {
+ },
+
+ /**
+ * Removes all condition
+ */
+ removeAll: function () {
+ }
+});
+
+/**
+ * The base class of trigger action
+ * @class
+ * @extends ccs.Class
+ */
+ccs.BaseTriggerAction = ccs.Class.extend(/** @lends ccs.BaseTriggerAction# */{
+ /**
+ * Construction of ccs.BaseTriggerAction
+ */
+ ctor:function(){
+ },
+
+ /**
+ * Initializes a BaseTriggerAction object.
+ * @returns {boolean}
+ */
+ init: function () {
+ return true;
+ },
+
+ /**
+ * Sets the action to done.
+ */
+ done: function () {
+ },
+
+ /**
+ * Serializes a ccs.BaseTriggerAction object.
+ * @param jsonVal
+ */
+ serialize: function (jsonVal) {
+ },
+
+ /**
+ * Removes all actions.
+ */
+ removeAll: function () {
+ }
+});
+
+/**
+ * The trigger object of Cocostudio.
+ * @class
+ * @extends ccs.Class
+ */
+ccs.TriggerObj = ccs.Class.extend(/** @lends ccs.TriggerObj# */{
+ _cons: null,
+ _acts: null,
+ _id: 0,
+ _enable: true,
+ _vInt: null,
+
+ ctor: function () {
+ this._id = 0;
+ this._enable = true;
+
+ ccs.TriggerObj.prototype.init.call(this);
+ },
+
+ /**
+ * Initializes a ccs.TriggerObj
+ * @returns {boolean}
+ */
+ init: function () {
+ this._cons = [];
+ this._acts = [];
+ this._vInt = [];
+ return true;
+ },
+
+ /**
+ * Detects trigger's conditions.
+ * @returns {boolean}
+ */
+ detect: function () {
+ if (!this._enable || this._cons.length === 0) {
+ return true;
+ }
+ var ret = true;
+ var obj = null;
+ for (var i = 0; i < this._cons.length; i++) {
+ obj = this._cons[i];
+ if (obj && obj.detect)
+ ret = ret && obj.detect();
+ }
+ return ret;
+ },
+
+ /**
+ * Sets trigger's actions to done.
+ */
+ done: function () {
+ if (!this._enable || this._acts.length === 0)
+ return;
+ var obj;
+ for (var i = 0; i < this._acts.length; i++) {
+ obj = this._acts[i];
+ if (obj && obj.done)
+ obj.done();
+ }
+ },
+
+ /**
+ * Removes all condition and actions from ccs.TriggerObj.
+ */
+ removeAll: function () {
+ var obj = null;
+ for (var i = 0; i < this._cons.length; i++) {
+ obj = this._cons[i];
+ if (obj)
+ obj.removeAll();
+ }
+ this._cons = [];
+ for (var i = 0; i < this._acts.length; i++) {
+ obj = this._acts[i];
+ if (obj)
+ obj.removeAll();
+ }
+ this._acts = [];
+ },
+
+ /**
+ * Serializes ccs.TriggerObj
+ * @param jsonVal
+ */
+ serialize: function (jsonVal) {
+ this._id = jsonVal["id"] || 0;
+ var conditions = jsonVal["conditions"] || [];
+ for (var i = 0; i < conditions.length; i++) {
+ var subDict = conditions[i];
+ var classname = subDict["classname"];
+ var con = ccs.objectFactory.createObject(classname);
+ if (!con) {
+ cc.log("class named classname(" + classname + ") can not implement!");
+ continue;
+ }
+
+ con.serialize(subDict);
+ con.init();
+ this._cons.push(con);
+ }
+
+ var actions = jsonVal["actions"] || [];
+ for (var i = 0; i < actions.length; i++) {
+ var subDict = actions[i];
+ var classname = subDict["classname"];
+ var act = ccs.objectFactory.createObject(classname);
+ if (!act) {
+ cc.log("class named classname(" + classname + ") can not implement!");
+ continue;
+ }
+
+ act.serialize(subDict);
+ act.init();
+ this._acts.push(act);
+ }
+
+ var events = jsonVal["events"] || [];
+ for (var i = 0; i < events.length; i++) {
+ var subDict = events[i];
+ var event = subDict["id"];
+ if (event < 0) {
+ continue;
+ }
+ this._vInt.push(event);
+ }
+ },
+
+ /**
+ * Returns the id of ccs.TriggerObj.
+ * @returns {number}
+ */
+ getId: function () {
+ return this._id;
+ },
+
+ /**
+ * Sets enable value.
+ * @param {Boolean} enable
+ */
+ setEnable: function (enable) {
+ this._enable = enable;
+ },
+
+ /**
+ * Returns the events of ccs.TriggerObj.
+ * @returns {null|Array}
+ */
+ getEvents: function () {
+ return this._vInt;
+ }
+});
+
+ccs.TriggerObj.create = function () {
+ return new ccs.TriggerObj();
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/editbox/CCEditBox.js b/frameworks/cocos2d-html5/extensions/editbox/CCEditBox.js
new file mode 100644
index 0000000..3a53543
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/editbox/CCEditBox.js
@@ -0,0 +1,1420 @@
+/****************************************************************************
+ Copyright (c) 2013-2016 Chukong Technologies Inc.
+ Copyright (c) 2012 James Chen
+ Copyright (c) 2011-2012 cocos2d-x.org
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.KEYBOARD_RETURNTYPE_DEFAULT = 0;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.KEYBOARD_RETURNTYPE_DONE = 1;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.KEYBOARD_RETURNTYPE_SEND = 2;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.KEYBOARD_RETURNTYPE_SEARCH = 3;
+
+/**
+ * @constant
+ * @type Number
+ */
+cc.KEYBOARD_RETURNTYPE_GO = 4;
+
+/**
+ * The EditBoxInputMode defines the type of text that the user is allowed * to enter.
+ * @constant
+ * @type Number
+ */
+cc.EDITBOX_INPUT_MODE_ANY = 0;
+
+/**
+ * The user is allowed to enter an e-mail address.
+ * @constant
+ * @type Number
+ */
+cc.EDITBOX_INPUT_MODE_EMAILADDR = 1;
+
+/**
+ * The user is allowed to enter an integer value.
+ * @constant
+ * @type Number
+ */
+cc.EDITBOX_INPUT_MODE_NUMERIC = 2;
+
+/**
+ * The user is allowed to enter a phone number.
+ * @constant
+ * @type Number
+ */
+cc.EDITBOX_INPUT_MODE_PHONENUMBER = 3;
+
+/**
+ * The user is allowed to enter a URL.
+ * @constant
+ * @type Number
+ */
+cc.EDITBOX_INPUT_MODE_URL = 4;
+
+/**
+ * The user is allowed to enter a real number value.
+ * This extends kEditBoxInputModeNumeric by allowing a decimal point.
+ * @constant
+ * @type Number
+ */
+cc.EDITBOX_INPUT_MODE_DECIMAL = 5;
+
+/**
+ * The user is allowed to enter any text, except for line breaks.
+ * @constant
+ * @type Number
+ */
+cc.EDITBOX_INPUT_MODE_SINGLELINE = 6;
+
+/**
+ * Indicates that the text entered is confidential data that should be
+ * obscured whenever possible. This implies EDIT_BOX_INPUT_FLAG_SENSITIVE.
+ * @constant
+ * @type Number
+ */
+cc.EDITBOX_INPUT_FLAG_PASSWORD = 0;
+
+/**
+ * Indicates that the text entered is sensitive data that the
+ * implementation must never store into a dictionary or table for use
+ * in predictive, auto-completing, or other accelerated input schemes.
+ * A credit card number is an example of sensitive data.
+ * @constant
+ * @type Number
+ */
+cc.EDITBOX_INPUT_FLAG_SENSITIVE = 1;
+
+/**
+ * This flag is a hint to the implementation that during text editing,
+ * the initial letter of each word should be capitalized.
+ * @constant
+ * @type Number
+ */
+cc.EDITBOX_INPUT_FLAG_INITIAL_CAPS_WORD = 2;
+
+/**
+ * This flag is a hint to the implementation that during text editing,
+ * the initial letter of each sentence should be capitalized.
+ * @constant
+ * @type Number
+ */
+cc.EDITBOX_INPUT_FLAG_INITIAL_CAPS_SENTENCE = 3;
+
+/**
+ * Capitalize all characters automatically.
+ * @constant
+ * @type Number
+ */
+cc.EDITBOX_INPUT_FLAG_INITIAL_CAPS_ALL_CHARACTERS = 4;
+
+/**
+ * @class
+ * @extends cc.Class
+ */
+cc.EditBoxDelegate = cc.Class.extend({
+ /**
+ * This method is called when an edit box gains focus after keyboard is shown.
+ * @param {cc.EditBox} sender
+ */
+ editBoxEditingDidBegin: function (sender) {
+ },
+
+ /**
+ * This method is called when an edit box loses focus after keyboard is hidden.
+ * @param {cc.EditBox} sender
+ */
+ editBoxEditingDidEnd: function (sender) {
+ },
+
+ /**
+ * This method is called when the edit box text was changed.
+ * @param {cc.EditBox} sender
+ * @param {String} text
+ */
+ editBoxTextChanged: function (sender, text) {
+ },
+
+ /**
+ * This method is called when the return button was pressed.
+ * @param {cc.EditBox} sender
+ */
+ editBoxReturn: function (sender) {
+ }
+});
+
+
+/**
+ * cc.EditBox is a brief Class for edit box.
+ * You can use this widget to gather small amounts of text from the user.
+ *
+ * @class
+ * @extends cc.Node
+ *
+ * @property {String} string - Content string of edit box
+ * @property {String} maxLength - Max length of the content string
+ * @property {String} font - <@writeonly> Config font of edit box
+ * @property {String} fontName - <@writeonly> Config font name of edit box
+ * @property {Number} fontSize - <@writeonly> Config font size of edit box
+ * @property {cc.Color} fontColor - <@writeonly> Config font color of edit box
+ * @property {String} placeHolder - Place holder of edit box
+ * @property {String} placeHolderFont - <@writeonly> Config font of place holder
+ * @property {String} placeHolderFontName - <@writeonly> Config font name of place holder
+ * @property {Number} placeHolderFontSize - <@writeonly> Config font size of place holder
+ * @property {cc.Color} placeHolderFontColor - <@writeonly> Config font color of place holder
+ * @property {Number} inputFlag - <@writeonly> Input flag of edit box, one of the EditBoxInputFlag constants. e.g.cc.EDITBOX_INPUT_FLAG_PASSWORD
+ * @property {Object} delegate - <@writeonly> Delegate of edit box
+ * @property {Number} inputMode - <@writeonly> Input mode of the edit box. Value should be one of the EditBoxInputMode constants.
+ * @property {Number} returnType - <@writeonly> Return type of edit box, value should be one of the KeyboardReturnType constants.
+ *
+ */
+cc.EditBox = cc.Node.extend({
+ _backgroundSprite: null,
+ _delegate: null,
+ _editBoxInputMode: cc.EDITBOX_INPUT_MODE_ANY,
+ _editBoxInputFlag: cc.EDITBOX_INPUT_FLAG_SENSITIVE,
+ _keyboardReturnType: cc.KEYBOARD_RETURNTYPE_DEFAULT,
+ _maxLength: 50,
+ _text: '',
+ _textColor: null,
+ _placeholderText: '',
+ _placeholderFontName: '',
+ _placeholderFontSize: 14,
+ _placeholderColor: null,
+ _className: 'EditBox',
+ _touchListener: null,
+ _touchEnabled: true,
+
+ /**
+ * constructor of cc.EditBox
+ * @param {cc.Size} size
+ * @param {cc.Scale9Sprite} normal9SpriteBg
+ * @param {cc.Scale9Sprite} press9SpriteBg
+ * @param {cc.Scale9Sprite} disabled9SpriteBg
+ */
+ ctor: function (size, normal9SpriteBg) {
+ cc.Node.prototype.ctor.call(this);
+
+ this._anchorPoint = cc.p(0.5, 0.5);
+ this._textColor = cc.color.WHITE;
+ this._placeholderColor = cc.color.GRAY;
+
+ this._renderCmd._createLabels();
+ this.createDomElementIfNeeded();
+ this.initWithSizeAndBackgroundSprite(size, normal9SpriteBg);
+
+ this._touchListener = cc.EventListener.create({
+ event: cc.EventListener.TOUCH_ONE_BY_ONE,
+ swallowTouches: true,
+ onTouchBegan: this._onTouchBegan.bind(this),
+ onTouchEnded: this._onTouchEnded.bind(this)
+ });
+ cc.eventManager.addListener(this._touchListener, this);
+
+ this.setInputFlag(this._editBoxInputFlag);
+ },
+
+ setTouchEnabled: function (enable) {
+ if (this._touchEnabled === enable) {
+ return;
+ }
+ this._touchEnabled = enable;
+ if (this._touchEnabled) {
+ cc.eventManager.addListener(this._touchListener, this);
+ } else {
+ cc.eventManager.removeListener(this._touchListener);
+ }
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
+ return new cc.EditBox.CanvasRenderCmd(this);
+ } else {
+ return new cc.EditBox.WebGLRenderCmd(this);
+ }
+ },
+
+ setContentSize: function (width, height) {
+ if (width.width !== undefined && width.height !== undefined) {
+ height = width.height;
+ width = width.width;
+ }
+ cc.Node.prototype.setContentSize.call(this, width, height);
+ this._updateEditBoxSize(width, height);
+ },
+
+ setVisible: function (visible) {
+ cc.Node.prototype.setVisible.call(this, visible);
+ this._renderCmd.updateVisibility();
+ },
+
+ createDomElementIfNeeded: function () {
+ if (!this._renderCmd._edTxt) {
+ this._renderCmd._createDomTextArea();
+ }
+ },
+
+ setTabIndex: function (index) {
+ if (this._renderCmd._edTxt) {
+ this._renderCmd._edTxt.tabIndex = index;
+ }
+ },
+
+ getTabIndex: function () {
+ if (this._renderCmd._edTxt) {
+ return this._renderCmd._edTxt.tabIndex;
+ }
+ cc.warn('The dom control is not created!');
+ return -1;
+ },
+
+ setFocus: function () {
+ if (this._renderCmd._edTxt) {
+ this._renderCmd._edTxt.focus();
+ }
+ },
+
+ isFocused: function () {
+ if (this._renderCmd._edTxt) {
+ return document.activeElement === this._renderCmd._edTxt;
+ }
+ cc.warn('The dom control is not created!');
+ return false;
+ },
+
+ stayOnTop: function (flag) {
+ if (this._alwaysOnTop === flag) return;
+
+ this._alwaysOnTop = flag;
+ this._renderCmd.stayOnTop(this._alwaysOnTop);
+ },
+
+ cleanup: function () {
+ this._super();
+
+ this._renderCmd._removeDomFromGameContainer();
+ },
+
+ _isAncestorsVisible: function (node) {
+ if (null == node)
+ return true;
+
+ var parent = node.getParent();
+
+ if (parent && !parent.isVisible())
+ return false;
+ return this._isAncestorsVisible(parent);
+ },
+
+ _onTouchBegan: function (touch) {
+ if (!this.isVisible() || !this._isAncestorsVisible(this)) {
+ return;
+ }
+ var touchPoint = touch.getLocation();
+ var bb = cc.rect(0, 0, this._contentSize.width, this._contentSize.height);
+ var hitted = cc.rectContainsPoint(bb, this.convertToNodeSpace(touchPoint));
+ if (hitted) {
+ return true;
+ }
+ else {
+ this._renderCmd._endEditing();
+ return false;
+ }
+ },
+
+ _onTouchEnded: function () {
+ if (!this.isVisible() || !this._isAncestorsVisible(this)) {
+ return;
+ }
+ this._renderCmd._beginEditing();
+ },
+
+ _updateBackgroundSpriteSize: function (width, height) {
+ if (this._backgroundSprite) {
+ this._backgroundSprite.setContentSize(width, height);
+ }
+ },
+
+ _updateEditBoxSize: function (size, height) {
+ var newWidth = (typeof size.width === 'number') ? size.width : size;
+ var newHeight = (typeof size.height === 'number') ? size.height : height;
+
+ this._updateBackgroundSpriteSize(newWidth, newHeight);
+ this._renderCmd.updateSize(newWidth, newHeight);
+ },
+
+ setLineHeight: function (lineHeight) {
+ this._renderCmd.setLineHeight(lineHeight);
+ },
+
+ /**
+ * Sets the font.
+ * @param {String} fontName The font name.
+ * @param {Number} fontSize The font size.
+ */
+ setFont: function (fontName, fontSize) {
+ this._renderCmd.setFont(fontName, fontSize);
+ },
+
+ _setFont: function (fontStyle) {
+ this._renderCmd._setFont(fontStyle);
+ },
+
+ getBackgroundSprite: function () {
+ return this._backgroundSprite;
+ },
+
+ /**
+ * Sets fontName
+ * @param {String} fontName
+ */
+ setFontName: function (fontName) {
+ this._renderCmd.setFontName(fontName);
+ },
+
+ /**
+ * Sets fontSize
+ * @param {Number} fontSize
+ */
+ setFontSize: function (fontSize) {
+ this._renderCmd.setFontSize(fontSize);
+ },
+
+ /**
+ * Sets the text entered in the edit box.
+ * @param {string} text The given text.
+ */
+ setString: function (text) {
+ if (text.length >= this._maxLength) {
+ text = text.slice(0, this._maxLength);
+ }
+ this._text = text;
+ this._renderCmd.setString(text);
+ },
+
+ /**
+ * Sets the font color of the widget's text.
+ * @param {cc.Color} color
+ */
+ setFontColor: function (color) {
+ this._textColor = color;
+ this._renderCmd.setFontColor(color);
+ },
+
+ /**
+ * Sets the maximum input length of the edit box.
+ * Setting this value enables multiline input mode by default.
+ * @param {Number} maxLength The maximum length.
+ */
+ setMaxLength: function (maxLength) {
+ if (!isNaN(maxLength)) {
+ if (maxLength < 0) {
+ //we can't set Number.MAX_VALUE to input's maxLength property
+ //so we use a magic number here, it should works at most use cases.
+ maxLength = 65535;
+ }
+ this._maxLength = maxLength;
+ this._renderCmd.setMaxLength(maxLength);
+ }
+ },
+
+ /**
+ * Gets the maximum input length of the edit box.
+ * @return {Number} Maximum input length.
+ */
+ getMaxLength: function () {
+ return this._maxLength;
+ },
+
+ /**
+ * Sets a text in the edit box that acts as a placeholder when an edit box is empty.
+ * @param {string} text The given text.
+ */
+ setPlaceHolder: function (text) {
+ if (text !== null) {
+ this._renderCmd.setPlaceHolder(text);
+ this._placeholderText = text;
+ }
+ },
+
+ /**
+ * Sets the placeholder's font.
+ * @param {String} fontName
+ * @param {Number} fontSize
+ */
+ setPlaceholderFont: function (fontName, fontSize) {
+ this._placeholderFontName = fontName;
+ this._placeholderFontSize = fontSize;
+ this._renderCmd._updateDOMPlaceholderFontStyle();
+ },
+
+ _setPlaceholderFont: function (fontStyle) {
+ var res = cc.LabelTTF._fontStyleRE.exec(fontStyle);
+ if (res) {
+ this._placeholderFontName = res[2];
+ this._placeholderFontSize = parseInt(res[1]);
+ this._renderCmd._updateDOMPlaceholderFontStyle();
+ }
+ },
+
+ /**
+ * Sets the placeholder's fontName.
+ * @param {String} fontName
+ */
+ setPlaceholderFontName: function (fontName) {
+ this._placeholderFontName = fontName;
+ this._renderCmd._updateDOMPlaceholderFontStyle();
+ },
+
+ /**
+ * Sets the placeholder's fontSize.
+ * @param {Number} fontSize
+ */
+ setPlaceholderFontSize: function (fontSize) {
+ this._placeholderFontSize = fontSize;
+ this._renderCmd._updateDOMPlaceholderFontStyle();
+ },
+
+ /**
+ * Sets the font color of the placeholder text when the edit box is empty.
+ * @param {cc.Color} color
+ */
+ setPlaceholderFontColor: function (color) {
+ this._placeholderColor = color;
+ this._renderCmd.setPlaceholderFontColor(color);
+ },
+
+ /**
+ * Sets the input flags that are to be applied to the edit box.
+ * @param {Number} inputFlag One of the EditBoxInputFlag constants.
+ * e.g.cc.EDITBOX_INPUT_FLAG_PASSWORD
+ */
+ setInputFlag: function (inputFlag) {
+ this._editBoxInputFlag = inputFlag;
+ this._renderCmd.setInputFlag(inputFlag);
+ },
+
+ /**
+ * Gets the input string of the edit box.
+ * @return {string}
+ */
+ getString: function () {
+ return this._text;
+ },
+
+ /**
+ * Init edit box with specified size.
+ * @param {cc.Size} size
+ * @param {cc.Color | cc.Scale9Sprite} normal9SpriteBg
+ */
+ initWithSizeAndBackgroundSprite: function (size, normal9SpriteBg) {
+ if (this._backgroundSprite) {
+ this._backgroundSprite.removeFromParent();
+ }
+ this._backgroundSprite = normal9SpriteBg;
+ this.setContentSize(size);
+
+ if (this._backgroundSprite && !this._backgroundSprite.parent) {
+ this._backgroundSprite.setAnchorPoint(cc.p(0, 0));
+ this.addChild(this._backgroundSprite);
+
+ this._updateBackgroundSpriteSize(size.width, size.height);
+ }
+
+ this.x = 0;
+ this.y = 0;
+ return true;
+ },
+
+ /**
+ * Sets the delegate for edit box.
+ * @param {cc.EditBoxDelegate} delegate
+ */
+ setDelegate: function (delegate) {
+ this._delegate = delegate;
+ },
+
+ /**
+ * Gets the text in the edit box that acts as a placeholder when an
+ * edit box is empty.
+ * @return {String}
+ */
+ getPlaceHolder: function () {
+ return this._placeholderText;
+ },
+
+ /**
+ * Sets the input mode of the edit box.
+ * @param {Number} inputMode One of the EditBoxInputMode constants.
+ */
+ setInputMode: function (inputMode) {
+ if (this._editBoxInputMode === inputMode) return;
+
+ var oldText = this.getString();
+ this._editBoxInputMode = inputMode;
+
+ this._renderCmd.setInputMode(inputMode);
+ this._renderCmd.transform();
+
+ this.setString(oldText);
+ this._renderCmd._updateLabelPosition(this.getContentSize());
+ },
+
+ /**
+ * Sets the return type that are to be applied to the edit box.
+ * @param {Number} returnType One of the CCKeyboardReturnType constants.
+ */
+ setReturnType: function (returnType) {
+ this._keyboardReturnType = returnType;
+ this._renderCmd._updateDomInputType();
+ },
+
+ /**
+ * @warning HTML5 Only
+ * @param {cc.Size} size
+ * @param {cc.color} bgColor
+ */
+ initWithBackgroundColor: function (size, bgColor) {
+ this._edWidth = size.width;
+ this.dom.style.width = this._edWidth.toString() + 'px';
+ this._edHeight = size.height;
+ this.dom.style.height = this._edHeight.toString() + 'px';
+ this.dom.style.backgroundColor = cc.colorToHex(bgColor);
+ }
+});
+
+var _p = cc.EditBox.prototype;
+
+// Extended properties
+/** @expose */
+_p.font;
+cc.defineGetterSetter(_p, 'font', null, _p._setFont);
+/** @expose */
+_p.fontName;
+cc.defineGetterSetter(_p, 'fontName', null, _p.setFontName);
+/** @expose */
+_p.fontSize;
+cc.defineGetterSetter(_p, 'fontSize', null, _p.setFontSize);
+/** @expose */
+_p.fontColor;
+cc.defineGetterSetter(_p, 'fontColor', null, _p.setFontColor);
+/** @expose */
+_p.string;
+cc.defineGetterSetter(_p, 'string', _p.getString, _p.setString);
+/** @expose */
+_p.maxLength;
+cc.defineGetterSetter(_p, 'maxLength', _p.getMaxLength, _p.setMaxLength);
+/** @expose */
+_p.placeHolder;
+cc.defineGetterSetter(_p, 'placeholder', _p.getPlaceHolder, _p.setPlaceHolder);
+/** @expose */
+_p.placeHolderFont;
+cc.defineGetterSetter(_p, 'placeholderFont', null, _p._setPlaceholderFont);
+/** @expose */
+_p.placeHolderFontName;
+cc.defineGetterSetter(_p, 'placeholderFontName', null, _p.setPlaceholderFontName);
+/** @expose */
+_p.placeHolderFontSize;
+cc.defineGetterSetter(_p, 'placeholderFontSize', null, _p.setPlaceholderFontSize);
+/** @expose */
+_p.placeHolderFontColor;
+cc.defineGetterSetter(_p, 'placeholderFontColor', null, _p.setPlaceholderFontColor);
+/** @expose */
+_p.inputFlag;
+cc.defineGetterSetter(_p, 'inputFlag', null, _p.setInputFlag);
+/** @expose */
+_p.delegate;
+cc.defineGetterSetter(_p, 'delegate', null, _p.setDelegate);
+/** @expose */
+_p.inputMode;
+cc.defineGetterSetter(_p, 'inputMode', null, _p.setInputMode);
+/** @expose */
+_p.returnType;
+cc.defineGetterSetter(_p, 'returnType', null, _p.setReturnType);
+
+_p = null;
+
+/**
+ * create a edit box with size and background-color or
+ * @deprecated since v3.0, please use new cc.EditBox(size, normal9SpriteBg, press9SpriteBg, disabled9SpriteBg) instead
+ * @param {cc.Size} size
+ * @param {cc.Scale9Sprite } normal9SpriteBg
+ * @param {cc.Scale9Sprite } [press9SpriteBg]
+ * @param {cc.Scale9Sprite } [disabled9SpriteBg]
+ * @return {cc.EditBox}
+ */
+cc.EditBox.create = function (size, normal9SpriteBg, press9SpriteBg, disabled9SpriteBg) {
+ return new cc.EditBox(size, normal9SpriteBg, press9SpriteBg, disabled9SpriteBg);
+};
+
+
+(function (editbox) {
+ editbox._polyfill = {
+ zoomInvalid: false
+ };
+
+ if (cc.sys.OS_ANDROID === cc.sys.os
+ && (cc.sys.browserType === cc.sys.BROWSER_TYPE_SOUGOU
+ || cc.sys.browserType === cc.sys.BROWSER_TYPE_360)) {
+ editbox._polyfill.zoomInvalid = true;
+ }
+})(cc.EditBox);
+
+(function (polyfill) {
+ // https://segmentfault.com/q/1010000002914610
+ var SCROLLY = 40;
+ var TIMER_NAME = 400;
+ var LEFT_PADDING = 2;
+
+ function adjustEditBoxPosition (editBox) {
+ var worldPos = editBox.convertToWorldSpace(cc.p(0,0));
+ var windowHeight = cc.visibleRect.height;
+ var windowWidth = cc.visibleRect.width;
+ var factor = 0.5;
+ if(windowWidth > windowHeight) {
+ factor = 0.7;
+ }
+ setTimeout(function() {
+ if(window.scrollY < SCROLLY && worldPos.y < windowHeight * factor) {
+ var scrollOffset = windowHeight * factor - worldPos.y - window.scrollY;
+ if (scrollOffset < 35) scrollOffset = 35;
+ if (scrollOffset > 320) scrollOffset = 320;
+ window.scrollTo(scrollOffset, scrollOffset);
+ }
+ }, TIMER_NAME);
+ }
+
+ var capitalize = function(string) {
+ return string.replace(/(?:^|\s)\S/g, function(a) { return a.toUpperCase(); });
+ };
+
+ function capitalizeFirstLetter(string) {
+ return string.charAt(0).toUpperCase() + string.slice(1);
+ }
+
+ var EditBoxImpl = function () {
+ };
+ var proto = EditBoxImpl.prototype = Object.create(Object.prototype);
+
+ proto.updateMatrix = function () {
+ if (!this._edTxt) return;
+
+ var node = this._node, scaleX = cc.view._scaleX, scaleY = cc.view._scaleY;
+ var dpr = cc.view._devicePixelRatio;
+ var t = this._worldTransform;
+
+ scaleX /= dpr;
+ scaleY /= dpr;
+
+ var container = cc.game.container;
+ var a = t.a * scaleX, b = t.b, c = t.c, d = t.d * scaleY;
+
+ var offsetX = container && container.style.paddingLeft && parseInt(container.style.paddingLeft);
+ var offsetY = container && container.style.paddingBottom && parseInt(container.style.paddingBottom);
+ var tx = t.tx * scaleX + offsetX, ty = t.ty * scaleY + offsetY;
+
+ if (polyfill.zoomInvalid) {
+ this.updateSize(node._contentSize.width * a, node._contentSize.height * d);
+ a = 1;
+ d = 1;
+ }
+
+ var matrix = "matrix(" + a + "," + -b + "," + -c + "," + d + "," + tx + "," + -ty + ")";
+ this._edTxt.style['transform'] = matrix;
+ this._edTxt.style['-webkit-transform'] = matrix;
+ this._edTxt.style['transform-origin'] = '0px 100% 0px';
+ this._edTxt.style['-webkit-transform-origin'] = '0px 100% 0px';
+ };
+
+ proto.updateVisibility = function () {
+ if (!this._edTxt) return;
+
+ if (this._node.visible) {
+ this._edTxt.style.visibility = 'visible';
+ } else {
+ this._edTxt.style.visibility = 'hidden';
+ }
+ };
+
+ proto.stayOnTop = function (flag) {
+ if (flag) {
+ this._removeLabels();
+ this._edTxt.style.display = '';
+ } else {
+ this._createLabels();
+ this._edTxt.style.display = 'none';
+ this._showLabels();
+ }
+ };
+
+ // Called before editbox focus to register cc.view status
+ proto._beginEditingOnMobile = function (editBox) {
+ this.__orientationChanged = function () {
+ adjustEditBoxPosition(editBox);
+ };
+
+ window.addEventListener('orientationchange', this.__orientationChanged);
+
+ if (cc.view.isAutoFullScreenEnabled()) {
+ this.__fullscreen = true;
+ cc.view.enableAutoFullScreen(false);
+ cc.screen.exitFullScreen();
+ } else {
+ this.__fullscreen = false;
+ }
+ this.__autoResize = cc.view.__resizeWithBrowserSize;
+ cc.view.resizeWithBrowserSize(false);
+ };
+ // Called after keyboard disappeared to readapte the game view
+ proto._endEditingOnMobile = function () {
+ if (this.__rotateScreen) {
+ var containerStyle = cc.game.container.style;
+ containerStyle['-webkit-transform'] = 'rotate(90deg)';
+ containerStyle.transform = 'rotate(90deg)';
+
+ var view = cc.view;
+ var width = view._originalDesignResolutionSize.width;
+ var height = view._originalDesignResolutionSize.height;
+ if (width > 0) {
+ view.setDesignResolutionSize(width, height, view._resolutionPolicy);
+ }
+ this.__rotateScreen = false;
+ }
+
+ window.removeEventListener('orientationchange', this.__orientationChanged);
+
+ window.scrollTo(0, 0);
+ if (this.__fullscreen) {
+ cc.view.enableAutoFullScreen(true);
+ }
+ if (this.__autoResize) {
+ cc.view.resizeWithBrowserSize(true);
+ }
+ };
+ // Called after editbox focus to readapte the game view
+ proto._onFocusOnMobile = function (editBox) {
+ if (cc.view._isRotated) {
+ var containerStyle = cc.game.container.style;
+ containerStyle['-webkit-transform'] = 'rotate(0deg)';
+ containerStyle.transform = 'rotate(0deg)';
+ containerStyle.margin = '0px';
+ // cc.view._isRotated = false;
+ // var policy = cc.view.getResolutionPolicy();
+ // policy.apply(cc.view, cc.view.getDesignResolutionSize());
+ // cc.view._isRotated = true;
+ //use window scrollTo to adjust the input area
+ window.scrollTo(35, 35);
+ this.__rotateScreen = true;
+ } else {
+ this.__rotateScreen = false;
+ }
+ adjustEditBoxPosition(editBox);
+ };
+
+
+ proto._createDomInput = function () {
+ this._removeDomFromGameContainer();
+ var thisPointer = this;
+ var tmpEdTxt = this._edTxt = document.createElement('input');
+ tmpEdTxt.type = 'text';
+ tmpEdTxt.style.fontFamily = this._edFontName;
+ tmpEdTxt.style.fontSize = this._edFontSize + 'px';
+ tmpEdTxt.style.color = '#000000';
+ tmpEdTxt.style.border = 0;
+ tmpEdTxt.style.background = 'transparent';
+ tmpEdTxt.style.width = '100%';
+ tmpEdTxt.style.height = '100%';
+ tmpEdTxt.style.active = 0;
+ tmpEdTxt.style.outline = 'medium';
+ tmpEdTxt.style.padding = '0';
+ tmpEdTxt.style.textTransform = 'uppercase';
+ tmpEdTxt.style.display = 'none';
+
+ tmpEdTxt.style.position = "absolute";
+ tmpEdTxt.style.bottom = "0px";
+ tmpEdTxt.style.left = LEFT_PADDING + "px";
+ tmpEdTxt.style.className = "cocosEditBox";
+ this.setMaxLength(thisPointer._editBox._maxLength);
+
+ tmpEdTxt.addEventListener('input', function () {
+ var editBox = thisPointer._editBox;
+
+
+ if (this.value.length > this.maxLength) {
+ this.value = this.value.slice(0, this.maxLength);
+ }
+
+ if (editBox._delegate && editBox._delegate.editBoxTextChanged) {
+ if (editBox._text !== this.value) {
+ editBox._text = this.value;
+ thisPointer._updateDomTextCases();
+ editBox._delegate.editBoxTextChanged(editBox, editBox._text);
+ }
+ }
+ });
+ tmpEdTxt.addEventListener('keypress', function (e) {
+ var editBox = thisPointer._editBox;
+
+ if (e.keyCode === cc.KEY.enter) {
+ e.stopPropagation();
+ e.preventDefault();
+ if (this.value === '') {
+ this.style.fontSize = editBox._placeholderFontSize + 'px';
+ this.style.color = cc.colorToHex(editBox._placeholderColor);
+ }
+
+ editBox._text = this.value;
+ thisPointer._updateDomTextCases();
+
+ thisPointer._endEditing();
+ if (editBox._delegate && editBox._delegate.editBoxReturn) {
+ editBox._delegate.editBoxReturn(editBox);
+ }
+ cc._canvas.focus();
+ }
+ });
+
+ tmpEdTxt.addEventListener('focus', function () {
+ var editBox = thisPointer._editBox;
+ this.style.fontSize = thisPointer._edFontSize + 'px';
+ this.style.color = cc.colorToHex(editBox._textColor);
+ thisPointer._hiddenLabels();
+
+ if (cc.sys.isMobile) {
+ thisPointer._onFocusOnMobile(editBox);
+ }
+
+ if (editBox._delegate && editBox._delegate.editBoxEditingDidBegin) {
+ editBox._delegate.editBoxEditingDidBegin(editBox);
+ }
+ });
+ tmpEdTxt.addEventListener('blur', function () {
+ var editBox = thisPointer._editBox;
+ editBox._text = this.value;
+ thisPointer._updateDomTextCases();
+
+ if (editBox._delegate && editBox._delegate.editBoxEditingDidEnd) {
+ editBox._delegate.editBoxEditingDidEnd(editBox);
+ }
+
+ if (this.value === '') {
+ this.style.fontSize = editBox._placeholderFontSize + 'px';
+ this.style.color = cc.colorToHex(editBox._placeholderColor);
+ }
+ thisPointer._endEditing();
+ });
+
+ this._addDomToGameContainer();
+ return tmpEdTxt;
+ };
+
+ proto._createDomTextArea = function () {
+ this._removeDomFromGameContainer();
+ var thisPointer = this;
+ var tmpEdTxt = this._edTxt = document.createElement('textarea');
+ tmpEdTxt.type = 'text';
+ tmpEdTxt.style.fontFamily = this._edFontName;
+ tmpEdTxt.style.fontSize = this._edFontSize + 'px';
+ tmpEdTxt.style.color = '#000000';
+ tmpEdTxt.style.border = 0;
+ tmpEdTxt.style.background = 'transparent';
+ tmpEdTxt.style.width = '100%';
+ tmpEdTxt.style.height = '100%';
+ tmpEdTxt.style.active = 0;
+ tmpEdTxt.style.outline = 'medium';
+ tmpEdTxt.style.padding = '0';
+ tmpEdTxt.style.resize = 'none';
+ tmpEdTxt.style.textTransform = 'uppercase';
+ tmpEdTxt.style.overflow_y = 'scroll';
+ tmpEdTxt.style.display = 'none';
+ tmpEdTxt.style.position = "absolute";
+ tmpEdTxt.style.bottom = "0px";
+ tmpEdTxt.style.left = LEFT_PADDING + "px";
+ tmpEdTxt.style.className = "cocosEditBox";
+ this.setMaxLength(thisPointer._editBox._maxLength);
+
+ tmpEdTxt.addEventListener('input', function () {
+ if (this.value.length > this.maxLength) {
+ this.value = this.value.slice(0, this.maxLength);
+ }
+
+ var editBox = thisPointer._editBox;
+ if (editBox._delegate && editBox._delegate.editBoxTextChanged) {
+ if (editBox._text.toLowerCase() !== this.value.toLowerCase()) {
+ editBox._text = this.value;
+ thisPointer._updateDomTextCases();
+ editBox._delegate.editBoxTextChanged(editBox, editBox._text);
+ }
+ }
+ });
+
+ tmpEdTxt.addEventListener('focus', function () {
+ var editBox = thisPointer._editBox;
+ thisPointer._hiddenLabels();
+
+ this.style.fontSize = thisPointer._edFontSize + 'px';
+ this.style.color = cc.colorToHex(editBox._textColor);
+
+ if (cc.sys.isMobile) {
+ thisPointer._onFocusOnMobile(editBox);
+ }
+
+ if (editBox._delegate && editBox._delegate.editBoxEditingDidBegin) {
+ editBox._delegate.editBoxEditingDidBegin(editBox);
+ }
+
+ });
+ tmpEdTxt.addEventListener('keypress', function (e) {
+ var editBox = thisPointer._editBox;
+
+ if (e.keyCode === cc.KEY.enter) {
+ e.stopPropagation();
+
+ if (editBox._delegate && editBox._delegate.editBoxReturn) {
+ editBox._delegate.editBoxReturn(editBox);
+ }
+ }
+ });
+ tmpEdTxt.addEventListener('blur', function () {
+ var editBox = thisPointer._editBox;
+ editBox._text = this.value;
+ thisPointer._updateDomTextCases();
+
+ if (editBox._delegate && editBox._delegate.editBoxEditingDidEnd) {
+ editBox._delegate.editBoxEditingDidEnd(editBox);
+ }
+
+ if (this.value === '') {
+ this.style.fontSize = editBox._placeholderFontSize + 'px';
+ this.style.color = cc.colorToHex(editBox._placeholderColor);
+ }
+
+ thisPointer._endEditing();
+ });
+
+ this._addDomToGameContainer();
+ return tmpEdTxt;
+ };
+
+ proto._createLabels = function () {
+ var editBoxSize = this._editBox.getContentSize();
+ if (!this._textLabel) {
+ this._textLabel = new cc.LabelTTF();
+ this._textLabel.setAnchorPoint(cc.p(0, 1));
+ this._editBox.addChild(this._textLabel, 100);
+ }
+
+ if (!this._placeholderLabel) {
+ this._placeholderLabel = new cc.LabelTTF();
+ this._placeholderLabel.setAnchorPoint(cc.p(0, 1));
+ this._placeholderLabel.setColor(cc.color.GRAY);
+ this._editBox.addChild(this._placeholderLabel, 100);
+ }
+
+ this._updateLabelPosition(editBoxSize);
+ };
+
+ proto._removeLabels = function () {
+ if (!this._textLabel) return;
+
+ this._editBox.removeChild(this._textLabel);
+ this._textLabel = null;
+ };
+
+ proto._updateLabelPosition = function (editBoxSize) {
+ if (!this._textLabel || !this._placeholderLabel) return;
+
+ var labelContentSize = cc.size(editBoxSize.width - LEFT_PADDING, editBoxSize.height);
+ this._textLabel.setContentSize(labelContentSize);
+ this._textLabel.setDimensions(labelContentSize);
+ this._placeholderLabel.setLineHeight(editBoxSize.height);
+ var placeholderLabelSize = this._placeholderLabel.getContentSize();
+
+ if (this._editBox._editBoxInputMode === cc.EDITBOX_INPUT_MODE_ANY) {
+ this._textLabel.setPosition(LEFT_PADDING, editBoxSize.height);
+ this._placeholderLabel.setPosition(LEFT_PADDING, editBoxSize.height);
+ this._placeholderLabel.setVerticalAlignment(cc.VERTICAL_TEXT_ALIGNMENT_TOP);
+ this._textLabel.setVerticalAlignment(cc.VERTICAL_TEXT_ALIGNMENT_TOP);
+ // this._textLabel.enableWrapText(true);
+ }
+ else {
+ // this._textLabel.enableWrapText(false);
+ this._textLabel.setPosition(LEFT_PADDING, editBoxSize.height);
+ this._placeholderLabel.setPosition(LEFT_PADDING, (editBoxSize.height + placeholderLabelSize.height) / 2);
+ this._placeholderLabel.setVerticalAlignment(cc.VERTICAL_TEXT_ALIGNMENT_CENTER);
+ this._textLabel.setVerticalAlignment(cc.VERTICAL_TEXT_ALIGNMENT_CENTER);
+ }
+
+ };
+
+ proto.setLineHeight = function (lineHeight) {
+ if (this._textLabel) {
+ this._textLabel.setLineHeight(lineHeight);
+ }
+ };
+
+ proto._hiddenLabels = function () {
+ if (this._textLabel) {
+ this._textLabel.setVisible(false);
+ }
+
+ if (this._placeholderLabel) {
+ this._placeholderLabel.setVisible(false);
+ }
+ };
+
+ proto._updateDomTextCases = function () {
+ var inputFlag = this._editBox._editBoxInputFlag;
+ if (inputFlag === cc.EDITBOX_INPUT_FLAG_INITIAL_CAPS_ALL_CHARACTERS) {
+ this._editBox._text = this._editBox._text.toUpperCase();
+ }
+ else if (inputFlag === cc.EDITBOX_INPUT_FLAG_INITIAL_CAPS_WORD) {
+ this._editBox._text = capitalize(this._editBox._text);
+ }
+ else if (inputFlag === cc.EDITBOX_INPUT_FLAG_INITIAL_CAPS_SENTENCE) {
+ this._editBox._text = capitalizeFirstLetter(this._editBox._text);
+ }
+ };
+
+ proto._updateLabelStringStyle = function () {
+ if (this._edTxt.type === 'password') {
+ var passwordString = '';
+ var len = this._editBox._text.length;
+ for (var i = 0; i < len; ++i) {
+ passwordString += '\u25CF';
+ }
+ if (this._textLabel) {
+ this._textLabel.setString(passwordString);
+ }
+ } else {
+ this._updateDomTextCases();
+ if (this._textLabel) {
+ this._textLabel.setString(this._editBox._text);
+ }
+ }
+ };
+
+ proto._showLabels = function () {
+ this._hiddenLabels();
+ if (this._edTxt.value === '') {
+ if (this._placeholderLabel) {
+ this._placeholderLabel.setVisible(true);
+ this._placeholderLabel.setString(this._editBox._placeholderText);
+ }
+ }
+ else {
+ if (this._textLabel) {
+ this._textLabel.setVisible(true);
+ this._textLabel.setString(this._editBox._text);
+ }
+ }
+ this._updateLabelStringStyle();
+ };
+
+ proto._beginEditing = function () {
+ if (!this._editBox._alwaysOnTop) {
+ if (this._edTxt.style.display === 'none') {
+ this._edTxt.style.display = '';
+ this._edTxt.focus();
+ }
+ }
+
+ if (cc.sys.isMobile && !this._editingMode) {
+ // Pre adaptation and
+ this._beginEditingOnMobile(this._editBox);
+ }
+ this._editingMode = true;
+ };
+
+ proto._endEditing = function () {
+ if (!this._editBox._alwaysOnTop) {
+ this._edTxt.style.display = 'none';
+ }
+ this._showLabels();
+ if (cc.sys.isMobile && this._editingMode) {
+ var self = this;
+ // Delay end editing adaptation to ensure virtual keyboard is disapeared
+ setTimeout(function () {
+ self._endEditingOnMobile();
+ }, TIMER_NAME);
+ }
+ this._editingMode = false;
+ };
+
+ proto._setFont = function (fontStyle) {
+ var res = cc.LabelTTF._fontStyleRE.exec(fontStyle);
+ var textFontName = res[2];
+ var textFontSize = parseInt(res[1]);
+ if (res) {
+ this.setFont(textFontName, textFontSize);
+ }
+ };
+
+ proto.setFont = function (fontName, fontSize) {
+ this._edFontName = fontName || this._edFontName;
+ this._edFontSize = fontSize || this._edFontSize;
+ this._updateDOMFontStyle();
+ };
+
+ proto.setFontName = function (fontName) {
+ this._edFontName = fontName || this._edFontName;
+ this._updateDOMFontStyle();
+ };
+
+ proto.setFontSize = function (fontSize) {
+ this._edFontSize = fontSize || this._edFontSize;
+ this._updateDOMFontStyle();
+ };
+
+ proto.setFontColor = function (color) {
+ if (!this._edTxt) return;
+
+ if (this._edTxt.value !== this._editBox._placeholderText) {
+ this._edTxt.style.color = cc.colorToHex(color);
+ }
+ if (this._textLabel) {
+ this._textLabel.setColor(color);
+ }
+ };
+
+ proto.setPlaceHolder = function (text) {
+ this._placeholderLabel.setString(text);
+ };
+
+ proto.setMaxLength = function (maxLength) {
+ if (!this._edTxt) return;
+ this._edTxt.maxLength = maxLength;
+ };
+
+ proto._updateDOMPlaceholderFontStyle = function () {
+ this._placeholderLabel.setFontName(this._editBox._placeholderFontName);
+ this._placeholderLabel.setFontSize(this._editBox._placeholderFontSize);
+ };
+
+ proto.setPlaceholderFontColor = function (color) {
+ this._placeholderLabel.setColor(color);
+ };
+
+ proto._updateDomInputType = function () {
+ var inputMode = this._editBox._editBoxInputMode;
+ if (inputMode === cc.EDITBOX_INPUT_MODE_EMAILADDR) {
+ this._edTxt.type = 'email';
+ } else if (inputMode === cc.EDITBOX_INPUT_MODE_DECIMAL ||
+ inputMode === cc.EDITBOX_INPUT_MODE_NUMERIC) {
+ this._edTxt.type = 'number';
+ } else if (inputMode === cc.EDITBOX_INPUT_MODE_PHONENUMBER) {
+ this._edTxt.type = 'number';
+ this._edTxt.pattern = '[0-9]*';
+ } else if (inputMode === cc.EDITBOX_INPUT_MODE_URL) {
+ this._edTxt.type = 'url';
+ } else {
+ this._edTxt.type = 'text';
+
+ if (this._editBox._keyboardReturnType === cc.KEYBOARD_RETURNTYPE_SEARCH) {
+ this._edTxt.type = 'search';
+ }
+ }
+
+ if (this._editBox._editBoxInputFlag === cc.EDITBOX_INPUT_FLAG_PASSWORD) {
+ this._edTxt.type = 'password';
+ }
+ };
+
+ proto.setInputFlag = function (inputFlag) {
+ if (!this._edTxt) return;
+
+ this._updateDomInputType();
+
+ this._edTxt.style.textTransform = 'none';
+
+ if (inputFlag === cc.EDITBOX_INPUT_FLAG_INITIAL_CAPS_ALL_CHARACTERS) {
+ this._edTxt.style.textTransform = 'uppercase';
+ }
+ else if (inputFlag === cc.EDITBOX_INPUT_FLAG_INITIAL_CAPS_WORD) {
+ this._edTxt.style.textTransform = 'capitalize';
+ }
+ this._updateLabelStringStyle();
+ };
+
+ proto.setInputMode = function (inputMode) {
+ if (inputMode === cc.EDITBOX_INPUT_MODE_ANY) {
+ this._createDomTextArea();
+ }
+ else {
+ this._createDomInput();
+ }
+
+ this._updateDomInputType();
+ var contentSize = this._node.getContentSize();
+ this.updateSize(contentSize.width, contentSize.height);
+ };
+
+ proto.setString = function (text) {
+ if (!this._edTxt) return;
+
+ if (text !== null) {
+ this._edTxt.value = text;
+
+ if (text === '') {
+ if (this._placeholderLabel) {
+ this._placeholderLabel.setString(this._editBox._placeholderText);
+ this._placeholderLabel.setColor(this._editBox._placeholderColor);
+ }
+ if (!this._editingMode) {
+ if (this._placeholderLabel) {
+ this._placeholderLabel.setVisible(true);
+ }
+
+ if (this._textLabel) {
+ this._textLabel.setVisible(false);
+ }
+ }
+ }
+ else {
+ this._edTxt.style.color = cc.colorToHex(this._editBox._textColor);
+ if (this._textLabel) {
+ this._textLabel.setColor(this._editBox._textColor);
+ }
+ if (!this._editingMode) {
+ if (this._placeholderLabel) {
+ this._placeholderLabel.setVisible(false);
+ }
+ if (this._textLabel) {
+ this._textLabel.setVisible(true);
+ }
+ }
+
+ this._updateLabelStringStyle();
+ }
+ }
+ };
+
+ proto._updateDOMFontStyle = function () {
+ if (!this._edTxt) return;
+
+ if (this._edTxt.value !== '') {
+ this._edTxt.style.fontFamily = this._edFontName;
+ this._edTxt.style.fontSize = this._edFontSize + 'px';
+ }
+ if (this._textLabel) {
+ this._textLabel.setFontSize(this._edFontSize);
+ this._textLabel.setFontName(this._edFontName);
+ }
+ };
+
+
+ proto.updateSize = function (newWidth, newHeight) {
+ var editboxDomNode = this._edTxt;
+ if (!editboxDomNode) return;
+
+ editboxDomNode.style['width'] = newWidth + 'px';
+ editboxDomNode.style['height'] = newHeight + 'px';
+
+ this._updateLabelPosition(cc.size(newWidth, newHeight));
+ };
+
+ proto._addDomToGameContainer = function () {
+ cc.game.container.appendChild(this._edTxt);
+ };
+
+ proto._removeDomFromGameContainer = function () {
+ var editBox = this._edTxt;
+ if (editBox) {
+ var hasChild = false;
+ if ('contains' in cc.game.container) {
+ hasChild = cc.game.container.contains(editBox);
+ } else {
+ hasChild = cc.game.container.compareDocumentPosition(editBox) % 16;
+ }
+ if (hasChild)
+ cc.game.container.removeChild(editBox);
+ }
+ this._edTxt = null;
+ };
+
+ proto.initializeRenderCmd = function (node) {
+ this._editBox = node;
+
+ //it's a dom node, may be assigned with Input or TextArea.
+ this._edFontSize = 14;
+ this._edFontName = 'Arial';
+ this._textLabel = null;
+ this._placeholderLabel = null;
+ this._editingMode = false;
+
+ this.__fullscreen = false;
+ this.__autoResize = false;
+ this.__rotateScreen = false;
+ this.__orientationChanged = null;
+ };
+
+ //define the canvas render command
+ cc.EditBox.CanvasRenderCmd = function (node) {
+ this._rootCtor(node);
+ this.initializeRenderCmd(node);
+ };
+
+ var canvasRenderCmdProto = cc.EditBox.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+
+ cc.inject(proto, canvasRenderCmdProto);
+ canvasRenderCmdProto.constructor = cc.EditBox.CanvasRenderCmd;
+
+ canvasRenderCmdProto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
+ this.updateMatrix();
+ };
+
+
+ //define the webgl render command
+ cc.EditBox.WebGLRenderCmd = function (node) {
+ this._rootCtor(node);
+ this.initializeRenderCmd(node);
+ };
+
+ var webGLRenderCmdProto = cc.EditBox.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+ cc.inject(proto, webGLRenderCmdProto);
+ webGLRenderCmdProto.constructor = cc.EditBox.WebGLRenderCmd;
+
+ webGLRenderCmdProto.transform = function (parentCmd, recursive) {
+ this.originTransform(parentCmd, recursive);
+ this.updateMatrix();
+ };
+
+}(cc.EditBox._polyfill));
diff --git a/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControl.js b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControl.js
new file mode 100644
index 0000000..e4071a3
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControl.js
@@ -0,0 +1,378 @@
+/**
+ * Copyright (c) 2008-2010 Ricardo Quesada
+ * Copyright (c) 2011-2012 cocos2d-x.org
+ * Copyright (c) 2013-2014 Chukong Technologies Inc.
+ * Copyright 2011 Yannick Loriot.
+ * http://yannickloriot.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+/** Number of kinds of control event. */
+cc.CONTROL_EVENT_TOTAL_NUMBER = 9;
+
+/** Kinds of possible events for the control objects. */
+cc.CONTROL_EVENT_TOUCH_DOWN = 1 << 0; // A touch-down event in the control.
+cc.CONTROL_EVENT_TOUCH_DRAG_INSIDE = 1 << 1; // An event where a finger is dragged inside the bounds of the control.
+cc.CONTROL_EVENT_TOUCH_DRAG_OUTSIDE = 1 << 2; // An event where a finger is dragged just outside the bounds of the control.
+cc.CONTROL_EVENT_TOUCH_DRAG_ENTER = 1 << 3; // An event where a finger is dragged into the bounds of the control.
+cc.CONTROL_EVENT_TOUCH_DRAG_EXIT = 1 << 4; // An event where a finger is dragged from within a control to outside its bounds.
+cc.CONTROL_EVENT_TOUCH_UP_INSIDE = 1 << 5; // A touch-up event in the control where the finger is inside the bounds of the control.
+cc.CONTROL_EVENT_TOUCH_UP_OUTSIDE = 1 << 6; // A touch-up event in the control where the finger is outside the bounds of the control.
+cc.CONTROL_EVENT_TOUCH_CANCEL = 1 << 7; // A system event canceling the current touches for the control.
+cc.CONTROL_EVENT_VALUECHANGED = 1 << 8; // A touch dragging or otherwise manipulating a control; causing it to emit a series of different values.
+
+/** The possible state for a control. */
+cc.CONTROL_STATE_NORMAL = 1 << 0; // The normal; or default state of a control梩hat is; enabled but neither selected nor highlighted.
+cc.CONTROL_STATE_HIGHLIGHTED = 1 << 1; // Highlighted state of a control. A control enters this state when a touch down; drag inside or drag enter is performed. You can retrieve and set this value through the highlighted property.
+cc.CONTROL_STATE_DISABLED = 1 << 2; // Disabled state of a control. This state indicates that the control is currently disabled. You can retrieve and set this value through the enabled property.
+cc.CONTROL_STATE_SELECTED = 1 << 3; // Selected state of a control. This state indicates that the control is currently selected. You can retrieve and set this value through the selected property.
+cc.CONTROL_STATE_INITIAL = 1 << 3;
+
+/**
+ * CCControl is inspired by the UIControl API class from the UIKit library of
+ * CocoaTouch. It provides a base class for control CCSprites such as CCButton
+ * or CCSlider that convey user intent to the application.
+ * The goal of CCControl is to define an interface and base implementation for
+ * preparing action messages and initially dispatching them to their targets when
+ * certain events occur.
+ * To use the CCControl you have to subclass it.
+ * @class
+ * @extends cc.Layer
+ *
+ * @property {Number} state - <@readonly> The current control state: cc.CONTROL_STATE_NORMAL | cc.CONTROL_STATE_HIGHLIGHTED | cc.CONTROL_STATE_DISABLED | cc.CONTROL_STATE_SELECTED | cc.CONTROL_STATE_INITIAL
+ * @property {Boolean} enabled - Indicate whether the control node is enbaled
+ * @property {Boolean} selected - Indicate whether the control node is selected
+ * @property {Boolean} highlighted - Indicate whether the control node is highlighted
+ */
+cc.Control = cc.Layer.extend(/** @lends cc.Control# */{
+ _isOpacityModifyRGB: false,
+ _hasVisibleParents: false,
+ _touchListener: null,
+ _className: "Control",
+
+ isOpacityModifyRGB: function () {
+ return this._isOpacityModifyRGB;
+ },
+ setOpacityModifyRGB: function (opacityModifyRGB) {
+ this._isOpacityModifyRGB = opacityModifyRGB;
+
+ var children = this.getChildren();
+ for (var i = 0, len = children.length; i < len; i++) {
+ var selNode = children[i];
+ if (selNode)
+ selNode.setOpacityModifyRGB(opacityModifyRGB);
+ }
+ },
+
+ /** The current control state constant. */
+ _state: cc.CONTROL_STATE_NORMAL,
+ getState: function () {
+ return this._state;
+ },
+
+ _enabled: false,
+ _selected: false,
+ _highlighted: false,
+
+ _dispatchTable: null,
+
+ /**
+ * Tells whether the control is enabled
+ * @param {Boolean} enabled
+ */
+ setEnabled: function (enabled) {
+ this._enabled = enabled;
+ this._state = enabled ? cc.CONTROL_STATE_NORMAL : cc.CONTROL_STATE_DISABLED;
+
+ this.needsLayout();
+ },
+ isEnabled: function () {
+ return this._enabled;
+ },
+
+ /**
+ * A Boolean value that determines the control selected state.
+ * @param {Boolean} selected
+ */
+ setSelected: function (selected) {
+ this._selected = selected;
+ this.needsLayout();
+ },
+ isSelected: function () {
+ return this._selected;
+ },
+
+ /**
+ * A Boolean value that determines whether the control is highlighted.
+ * @param {Boolean} highlighted
+ */
+ setHighlighted: function (highlighted) {
+ this._highlighted = highlighted;
+ this.needsLayout();
+ },
+ isHighlighted: function () {
+ return this._highlighted;
+ },
+
+ hasVisibleParents: function () {
+ var parent = this.getParent();
+ for (var c = parent; c != null; c = c.getParent()) {
+ if (!c.isVisible())
+ return false;
+ }
+ return true;
+ },
+
+ ctor: function () {
+ cc.Layer.prototype.ctor.call(this);
+ this._dispatchTable = {};
+ this._color = cc.color.WHITE;
+ },
+
+ init: function () {
+ // Initialise instance variables
+ this._state = cc.CONTROL_STATE_NORMAL;
+ this._enabled = true;
+ this._selected = false;
+ this._highlighted = false;
+
+ var listener = cc.EventListener.create({
+ event: cc.EventListener.TOUCH_ONE_BY_ONE,
+ swallowTouches: true
+ });
+ if (this.onTouchBegan)
+ listener.onTouchBegan = this.onTouchBegan.bind(this);
+ if (this.onTouchMoved)
+ listener.onTouchMoved = this.onTouchMoved.bind(this);
+ if (this.onTouchEnded)
+ listener.onTouchEnded = this.onTouchEnded.bind(this);
+ if (this.onTouchCancelled)
+ listener.onTouchCancelled = this.onTouchCancelled.bind(this);
+ this._touchListener = listener;
+ return true;
+ },
+
+ onEnter: function () {
+ var locListener = this._touchListener;
+ if (!locListener._isRegistered())
+ cc.eventManager.addListener(locListener, this);
+ cc.Node.prototype.onEnter.call(this);
+ },
+
+ /**
+ * Sends action messages for the given control events.
+ * which action messages are sent. See "CCControlEvent" for bitmask constants.
+ * @param {Number} controlEvents A bitmask whose set flags specify the control events for
+ */
+ sendActionsForControlEvents: function (controlEvents) {
+ // For each control events
+ for (var i = 0, len = cc.CONTROL_EVENT_TOTAL_NUMBER; i < len; i++) {
+ // If the given controlEvents bitmask contains the curent event
+ if ((controlEvents & (1 << i))) {
+ // Call invocations
+ //
+ var invocationList = this._dispatchListforControlEvent(1 << i);
+ for (var j = 0, inLen = invocationList.length; j < inLen; j++) {
+ invocationList[j].invoke(this);
+ }
+ }
+ }
+ },
+
+ /**
+ *
+ * Adds a target and action for a particular event (or events) to an internal
+ * dispatch table.
+ * The action message may optionally include the sender and the event as
+ * parameters, in that order.
+ * When you call this method, target is not retained.
+ *
+ * @param {Object} target The target object that is, the object to which the action message is sent. It cannot be nil. The target is not retained.
+ * @param {function} action A selector identifying an action message. It cannot be NULL.
+ * @param {Number} controlEvents A bitmask specifying the control events for which the action message is sent. See "CCControlEvent" for bitmask constants.
+ */
+ addTargetWithActionForControlEvents: function (target, action, controlEvents) {
+ // For each control events
+ for (var i = 0, len = cc.CONTROL_EVENT_TOTAL_NUMBER; i < len; i++) {
+ // If the given controlEvents bit mask contains the current event
+ if ((controlEvents & (1 << i)))
+ this._addTargetWithActionForControlEvent(target, action, 1 << i);
+ }
+ },
+
+ /**
+ * Removes a target and action for a particular event (or events) from an internal dispatch table.
+ *
+ * @param {Object} target The target object that is, the object to which the action message is sent. Pass nil to remove all targets paired with action and the specified control events.
+ * @param {function} action A selector identifying an action message. Pass NULL to remove all action messages paired with target.
+ * @param {Number} controlEvents A bitmask specifying the control events associated with target and action. See "CCControlEvent" for bitmask constants.
+ */
+ removeTargetWithActionForControlEvents: function (target, action, controlEvents) {
+ // For each control events
+ for (var i = 0, len = cc.CONTROL_EVENT_TOTAL_NUMBER; i < len; i++) {
+ // If the given controlEvents bitmask contains the current event
+ if ((controlEvents & (1 << i)))
+ this._removeTargetWithActionForControlEvent(target, action, 1 << i);
+ }
+ },
+
+ /**
+ * Returns a point corresponding to the touh location converted into the
+ * control space coordinates.
+ * @param {cc.Touch} touch A CCTouch object that represents a touch.
+ */
+ getTouchLocation: function (touch) {
+ var touchLocation = touch.getLocation(); // Get the touch position
+ return this.convertToNodeSpace(touchLocation); // Convert to the node space of this class
+ },
+
+ /**
+ * Returns a boolean value that indicates whether a touch is inside the bounds of the receiver. The given touch must be relative to the world.
+ *
+ * @param {cc.Touch} touch A cc.Touch object that represents a touch.
+ * @return {Boolean} YES whether a touch is inside the receiver's rect.
+ */
+ isTouchInside: function (touch) {
+ var touchLocation = touch.getLocation(); // Get the touch position
+ touchLocation = this.getParent().convertToNodeSpace(touchLocation);
+ return cc.rectContainsPoint(this.getBoundingBox(), touchLocation);
+ },
+
+ /**
+ *
+ * Returns an cc.Invocation object able to construct messages using a given
+ * target-action pair. (The invocation may optionally include the sender and
+ * the event as parameters, in that order)
+ *
+ * @param {Object} target The target object.
+ * @param {function} action A selector identifying an action message.
+ * @param {Number} controlEvent A control events for which the action message is sent. See "CCControlEvent" for constants.
+ *
+ * @return {cc.Invocation} an CCInvocation object able to construct messages using a given target-action pair.
+ */
+ _invocationWithTargetAndActionForControlEvent: function (target, action, controlEvent) {
+ return null;
+ },
+
+ /**
+ * Returns the cc.Invocation list for the given control event. If the list does not exist, it'll create an empty array before returning it.
+ *
+ * @param {Number} controlEvent A control events for which the action message is sent. See "CCControlEvent" for constants.
+ * @return {cc.Invocation} the cc.Invocation list for the given control event.
+ */
+ _dispatchListforControlEvent: function (controlEvent) {
+ controlEvent = controlEvent.toString();
+ // If the invocation list does not exist for the dispatch table, we create it
+ if (!this._dispatchTable[controlEvent])
+ this._dispatchTable[controlEvent] = [];
+ return this._dispatchTable[controlEvent];
+ },
+
+ /**
+ * Adds a target and action for a particular event to an internal dispatch
+ * table.
+ * The action message may optionally include the sender and the event as
+ * parameters, in that order.
+ * When you call this method, target is not retained.
+ *
+ * @param target The target object that is, the object to which the action
+ * message is sent. It cannot be nil. The target is not retained.
+ * @param action A selector identifying an action message. It cannot be NULL.
+ * @param controlEvent A control event for which the action message is sent.
+ * See "CCControlEvent" for constants.
+ */
+ _addTargetWithActionForControlEvent: function (target, action, controlEvent) {
+ // Create the invocation object
+ var invocation = new cc.Invocation(target, action, controlEvent);
+
+ // Add the invocation into the dispatch list for the given control event
+ var eventInvocationList = this._dispatchListforControlEvent(controlEvent);
+ eventInvocationList.push(invocation);
+ },
+
+ /**
+ * Removes a target and action for a particular event from an internal dispatch table.
+ *
+ * @param {Object} target The target object that is, the object to which the action message is sent. Pass nil to remove all targets paired with action and the specified control events.
+ * @param {function} action A selector identifying an action message. Pass NULL to remove all action messages paired with target.
+ * @param {Number} controlEvent A control event for which the action message is sent. See "CCControlEvent" for constants.
+ */
+ _removeTargetWithActionForControlEvent: function (target, action, controlEvent) {
+ // Retrieve all invocations for the given control event
+ //
+ var eventInvocationList = this._dispatchListforControlEvent(controlEvent);
+
+ //remove all invocations if the target and action are null
+ //TODO: should the invocations be deleted, or just removed from the array? Won't that cause issues if you add a single invocation for multiple events?
+ var bDeleteObjects = true;
+ if (!target && !action) {
+ //remove objects
+ eventInvocationList.length = 0;
+ } else {
+ //normally we would use a predicate, but this won't work here. Have to do it manually
+ for (var i = 0; i < eventInvocationList.length;) {
+ var invocation = eventInvocationList[i];
+ var shouldBeRemoved = true;
+ if (target)
+ shouldBeRemoved = (target === invocation.getTarget());
+ if (action)
+ shouldBeRemoved = (shouldBeRemoved && (action === invocation.getAction()));
+ // Remove the corresponding invocation object
+ if (shouldBeRemoved)
+ cc.arrayRemoveObject(eventInvocationList, invocation);
+ else
+ i++;
+ }
+ }
+ },
+
+ /**
+ * Updates the control layout using its current internal state.
+ */
+ needsLayout: function () {
+ }
+});
+
+var _p = cc.Control.prototype;
+
+// Extended properties
+/** @expose */
+_p.state;
+cc.defineGetterSetter(_p, "state", _p.getState);
+/** @expose */
+_p.enabled;
+cc.defineGetterSetter(_p, "enabled", _p.isEnabled, _p.setEnabled);
+/** @expose */
+_p.selected;
+cc.defineGetterSetter(_p, "selected", _p.isSelected, _p.setSelected);
+/** @expose */
+_p.highlighted;
+cc.defineGetterSetter(_p, "highlighted", _p.isHighlighted, _p.setHighlighted);
+
+_p = null;
+
+cc.Control.create = function () {
+ var retControl = new cc.Control();
+ if (retControl && retControl.init())
+ return retControl;
+ return null;
+};
+
diff --git a/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlButton.js b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlButton.js
new file mode 100644
index 0000000..9e70ef2
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlButton.js
@@ -0,0 +1,688 @@
+/**
+ * CCControlButton.m
+ *
+ * Copyright (c) 2008-2010 Ricardo Quesada
+ * Copyright (c) 2011-2012 cocos2d-x.org
+ * Copyright (c) 2013-2014 Chukong Technologies Inc.
+ * Copyright 2011 Yannick Loriot.
+ * http://yannickloriot.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @ignore
+ */
+cc.CONTROL_ZOOM_ACTION_TAG = 0xCCCB0001;
+
+/**
+ * CCControlButton: Button control for Cocos2D.
+ * @class
+ * @extends cc.Control
+ *
+ * @property {Boolean} adjustBackgroundImage - Indicate whether the background image will be adjusted
+ * @property {Boolean} zoomOnTouchDown - Indicate whether the button will be zoomed while touch down
+ * @property {cc.Size} preferredSize - The preferred size of the control button
+ * @property {Boolean} labelAnchor - The anchor point for the label of the control button
+ */
+cc.ControlButton = cc.Control.extend(/** @lends cc.ControlButton# */{
+ _doesAdjustBackgroundImage: false,
+ zoomOnTouchDown: false,
+ _preferredSize: null,
+ _labelAnchorPoint: null,
+ _currentTitle: null,
+ _currentTitleColor: null,
+ _titleLabel: null,
+ _backgroundSprite: null,
+ _opacity: 0,
+ _isPushed: false,
+ _titleDispatchTable: null,
+ _titleColorDispatchTable: null,
+ _titleLabelDispatchTable: null,
+ _backgroundSpriteDispatchTable: null,
+ _parentInited: false,
+
+ _marginV: 0,
+ _marginH: 0,
+ _className: "ControlButton",
+
+ ctor: function (label, backgroundSprite, fontSize) {
+ cc.Control.prototype.ctor.call(this);
+ this._preferredSize = cc.size(0, 0);
+ this._labelAnchorPoint = cc.p(0, 0);
+ this._currentTitle = "";
+ this._currentTitleColor = cc.color.WHITE;
+ this._titleDispatchTable = {};
+ this._titleColorDispatchTable = {};
+ this._titleLabelDispatchTable = {};
+ this._backgroundSpriteDispatchTable = {};
+
+ if(fontSize != undefined)
+ this.initWithTitleAndFontNameAndFontSize(label, backgroundSprite, fontSize);
+ else if(backgroundSprite != undefined)
+ this.initWithLabelAndBackgroundSprite(label, backgroundSprite);
+ else if(label != undefined)
+ this.initWithBackgroundSprite(label);
+ else
+ this.init();
+ },
+
+ init: function () {
+ return this.initWithLabelAndBackgroundSprite(new cc.LabelTTF("", "Arial", 12), new cc.Scale9Sprite());
+ },
+
+ needsLayout: function () {
+ if (!this._parentInited) {
+ return;
+ }
+ // Hide the background and the label
+ if (this._titleLabel)
+ this._titleLabel.setVisible(false);
+ if (this._backgroundSprite)
+ this._backgroundSprite.setVisible(false);
+
+ // Update anchor of all labels
+ this.setLabelAnchorPoint(this._labelAnchorPoint);
+
+ // Update the label to match with the current state
+ //CC_SAFE_RELEASE(this._currentTitle)
+ var locState = this._state;
+
+ this._currentTitle = this.getTitleForState(locState);
+ this._currentTitleColor = this.getTitleColorForState(locState);
+ this._titleLabel = this.getTitleLabelForState(locState);
+
+ var label = this._titleLabel;
+ if (label && label.setString)
+ label.setString(this._currentTitle);
+ if (label)
+ label.setColor(this._currentTitleColor);
+
+ var locContentSize = this.getContentSize();
+ if (label)
+ label.setPosition(locContentSize.width / 2, locContentSize.height / 2);
+
+ // Update the background sprite
+ this._backgroundSprite = this.getBackgroundSpriteForState(locState);
+ var locBackgroundSprite = this._backgroundSprite;
+ if (locBackgroundSprite)
+ locBackgroundSprite.setPosition(locContentSize.width / 2, locContentSize.height / 2);
+
+ // Get the title label size
+ var titleLabelSize = cc.size(0, 0);
+ if (label) {
+ var boundingBox = label.getBoundingBox();
+ titleLabelSize.width = boundingBox.width;
+ titleLabelSize.height = boundingBox.height;
+ }
+ // Adjust the background image if necessary
+ if (this._doesAdjustBackgroundImage) {
+ // Add the margins
+ if (locBackgroundSprite)
+ locBackgroundSprite.setContentSize(titleLabelSize.width + this._marginH * 2, titleLabelSize.height + this._marginV * 2);
+ } else {
+ //TODO: should this also have margins if one of the preferred sizes is relaxed?
+ if (locBackgroundSprite) {
+ var preferredSize = locBackgroundSprite.getPreferredSize();
+ preferredSize = cc.size(preferredSize.width, preferredSize.height);
+ if (preferredSize.width <= 0)
+ preferredSize.width = titleLabelSize.width;
+ if (preferredSize.height <= 0)
+ preferredSize.height = titleLabelSize.height;
+
+ locBackgroundSprite.setContentSize(preferredSize);
+ }
+ }
+
+ // Set the content size
+ var rectTitle = label ? label.getBoundingBox() : cc.rect(0, 0, 0, 0);
+ var rectBackground = locBackgroundSprite ? locBackgroundSprite.getBoundingBox() : cc.rect(0, 0, 0, 0);
+ var maxRect = cc.rectUnion(rectTitle, rectBackground);
+ this.setContentSize(maxRect.width, maxRect.height);
+ locContentSize = this.getContentSize();
+ if (label) {
+ label.setPosition(locContentSize.width / 2, locContentSize.height / 2);
+ label.setVisible(true);
+ }
+ if (locBackgroundSprite) {
+ locBackgroundSprite.setPosition(locContentSize.width / 2, locContentSize.height / 2);
+ locBackgroundSprite.setVisible(true);
+ }
+ },
+
+ initWithLabelAndBackgroundSprite: function (label, backgroundSprite) {
+ if (!label)
+ throw new Error("cc.ControlButton.initWithLabelAndBackgroundSprite(): label should be non-null");
+ if (!backgroundSprite)
+ throw new Error("cc.ControlButton.initWithLabelAndBackgroundSprite(): backgroundSprite should be non-null");
+ if (cc.Control.prototype.init.call(this, true)) {
+ this._parentInited = true;
+
+ // Initialize the button state tables
+ this._titleDispatchTable = {};
+ this._titleColorDispatchTable = {};
+ this._titleLabelDispatchTable = {};
+ this._backgroundSpriteDispatchTable = {};
+
+ this._isPushed = false;
+ this.zoomOnTouchDown = true;
+
+ this._currentTitle = null;
+
+ // Adjust the background image by default
+ this.setAdjustBackgroundImage(true);
+ this.setPreferredSize(cc.size(0, 0));
+
+ // Zooming button by default
+ this.zoomOnTouchDown = true;
+
+ // Set the default anchor point
+ this.ignoreAnchorPointForPosition(false);
+ this.setAnchorPoint(0.5, 0.5);
+
+ // Set the nodes
+ this._titleLabel = label;
+ this._backgroundSprite = backgroundSprite;
+
+ // Set the default color and opacity
+ this.setOpacity(255);
+ this.setOpacityModifyRGB(true);
+
+ // Initialize the dispatch table
+ var tempString = label.getString();
+ //tempString.autorelease();
+ this.setTitleForState(tempString, cc.CONTROL_STATE_NORMAL);
+ this.setTitleColorForState(label.getColor(), cc.CONTROL_STATE_NORMAL);
+ this.setTitleLabelForState(label, cc.CONTROL_STATE_NORMAL);
+ this.setBackgroundSpriteForState(backgroundSprite, cc.CONTROL_STATE_NORMAL);
+
+ this._state = cc.CONTROL_STATE_NORMAL;
+
+ //default margins
+ this._marginH = 24;
+ this._marginV = 12;
+
+ this._labelAnchorPoint = cc.p(0.5, 0.5);
+
+ this.setPreferredSize(cc.size(0, 0));
+
+ // Layout update
+ this.needsLayout();
+ return true;
+ }//couldn't init the CCControl
+ else
+ return false;
+ },
+
+ initWithTitleAndFontNameAndFontSize: function (title, fontName, fontSize) {
+ var label = new cc.LabelTTF(title, fontName, fontSize);
+ return this.initWithLabelAndBackgroundSprite(label, new cc.Scale9Sprite());
+ },
+
+ initWithBackgroundSprite: function (sprite) {
+ var label = new cc.LabelTTF("", "Arial", 30);//
+ return this.initWithLabelAndBackgroundSprite(label, sprite);
+ },
+
+ /**
+ * Adjust the background image. YES by default. If the property is set to NO, the background will use the preferred size of the background image.
+ * @return {Boolean}
+ */
+ doesAdjustBackgroundImage: function () {
+ return this._doesAdjustBackgroundImage;
+ },
+
+ setAdjustBackgroundImage: function (adjustBackgroundImage) {
+ this._doesAdjustBackgroundImage = adjustBackgroundImage;
+ this.needsLayout();
+ },
+
+ /** Adjust the button zooming on touchdown. Default value is YES. */
+ getZoomOnTouchDown: function () {
+ return this.zoomOnTouchDown;
+ },
+
+ setZoomOnTouchDown: function (zoomOnTouchDown) {
+ return this.zoomOnTouchDown = zoomOnTouchDown;
+ },
+
+ /** The preferred size of the button, if label is larger it will be expanded. */
+ getPreferredSize: function () {
+ return this._preferredSize;
+ },
+
+ setPreferredSize: function (size) {
+ if (size.width === 0 && size.height === 0) {
+ this._doesAdjustBackgroundImage = true;
+ } else {
+ this._doesAdjustBackgroundImage = false;
+ var locTable = this._backgroundSpriteDispatchTable;
+ for (var itemKey in locTable)
+ locTable[itemKey].setPreferredSize(size);
+ }
+ this._preferredSize = size;
+ this.needsLayout();
+ },
+
+ getLabelAnchorPoint: function () {
+ return this._labelAnchorPoint;
+ },
+ setLabelAnchorPoint: function (labelAnchorPoint) {
+ this._labelAnchorPoint = labelAnchorPoint;
+ if (this._titleLabel)
+ this._titleLabel.setAnchorPoint(labelAnchorPoint);
+ },
+
+ /**
+ * The current title that is displayed on the button.
+ * @return {string}
+ */
+ _getCurrentTitle: function () {
+ return this._currentTitle;
+ },
+
+ /** The current color used to display the title. */
+ _getCurrentTitleColor: function () {
+ return this._currentTitleColor;
+ },
+
+ /* Override setter to affect a background sprite too */
+ getOpacity: function () {
+ return this._opacity;
+ },
+
+ setOpacity: function (opacity) {
+ // XXX fixed me if not correct
+ cc.Control.prototype.setOpacity.call(this, opacity);
+ /*this._opacity = opacity;
+ var controlChildren = this.getChildren();
+ for (var i = 0; i < controlChildren.length; i++) {
+ var selChild = controlChildren[i];
+ if (selChild)
+ selChild.setOpacity(opacity);
+ }*/
+ var locTable = this._backgroundSpriteDispatchTable;
+ for (var itemKey in locTable)
+ locTable[itemKey].setOpacity(opacity);
+ },
+
+ setColor: function (color) {
+ cc.Control.prototype.setColor.call(this, color);
+ var locTable = this._backgroundSpriteDispatchTable;
+ for (var key in locTable)
+ locTable[key].setColor(color);
+ },
+
+ getColor: function () {
+ var locRealColor = this._realColor;
+ return cc.color(locRealColor.r, locRealColor.g, locRealColor.b, locRealColor.a);
+ },
+
+
+ /** Flag to know if the button is currently pushed. */
+ isPushed: function () {
+ return this._isPushed;
+ },
+
+ /* Define the button margin for Top/Bottom edge */
+ _getVerticalMargin: function () {
+ return this._marginV;
+ },
+ /* Define the button margin for Left/Right edge */
+ _getHorizontalOrigin: function () {
+ return this._marginH;
+ },
+
+ /**
+ * set the margins at once (so we only have to do one call of needsLayout)
+ * @param {Number} marginH
+ * @param {Number} marginV
+ */
+ setMargins: function (marginH, marginV) {
+ this._marginV = marginV;
+ this._marginH = marginH;
+ this.needsLayout();
+ },
+
+ setEnabled: function (enabled) {
+ cc.Control.prototype.setEnabled.call(this, enabled);
+ this.needsLayout();
+ },
+ setSelected: function (enabled) {
+ cc.Control.prototype.setSelected.call(this, enabled);
+ this.needsLayout();
+ },
+
+ setHighlighted: function (enabled) {
+ this._state = enabled ? cc.CONTROL_STATE_HIGHLIGHTED : cc.CONTROL_STATE_NORMAL;
+
+ cc.Control.prototype.setHighlighted.call(this, enabled);
+ var action = this.getActionByTag(cc.CONTROL_ZOOM_ACTION_TAG);
+ if (action)
+ this.stopAction(action);
+
+ //this.needsLayout();// needn't
+ if (this.zoomOnTouchDown) {
+ var scaleValue = (this.isHighlighted() && this.isEnabled() && !this.isSelected()) ? 1.1 : 1.0;
+ var zoomAction = cc.scaleTo(0.05, scaleValue);
+ zoomAction.setTag(cc.CONTROL_ZOOM_ACTION_TAG);
+ this.runAction(zoomAction);
+ }
+ },
+
+ onTouchBegan: function (touch, event) {
+ if (!this.isTouchInside(touch) || !this.isEnabled() || !this.isVisible() || !this.hasVisibleParents())
+ return false;
+
+ this._isPushed = true;
+ this.setHighlighted(true);
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_DOWN);
+ return true;
+ },
+
+ onTouchMoved: function (touch, event) {
+ if (!this._enabled || !this._isPushed || this._selected) {
+ if (this._highlighted)
+ this.setHighlighted(false);
+ return;
+ }
+
+ var isTouchMoveInside = this.isTouchInside(touch);
+ if (isTouchMoveInside && !this._highlighted) {
+ this.setHighlighted(true);
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_DRAG_ENTER);
+ } else if (isTouchMoveInside && this._highlighted) {
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_DRAG_INSIDE);
+ } else if (!isTouchMoveInside && this._highlighted) {
+ this.setHighlighted(false);
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_DRAG_EXIT);
+ } else if (!isTouchMoveInside && !this._highlighted) {
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_DRAG_OUTSIDE);
+ }
+ },
+ onTouchEnded: function (touch, event) {
+ this._isPushed = false;
+ this.setHighlighted(false);
+
+ if (this.isTouchInside(touch)) {
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_UP_INSIDE);
+ } else {
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_UP_OUTSIDE);
+ }
+ },
+
+ onTouchCancelled: function (touch, event) {
+ this._isPushed = false;
+ this.setHighlighted(false);
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_CANCEL);
+ },
+
+ /**
+ * Returns the title used for a state.
+ *
+ * @param {Number} state The state that uses the title. Possible values are described in "CCControlState".
+ * @return {string} The title for the specified state.
+ */
+ getTitleForState: function (state) {
+ var locTable = this._titleDispatchTable;
+ if (locTable) {
+ if (locTable[state])
+ return locTable[state];
+ return locTable[cc.CONTROL_STATE_NORMAL];
+ }
+ return "";
+ },
+
+ /**
+ *
+ * Sets the title string to use for the specified state.
+ * If a property is not specified for a state, the default is to use the CCButtonStateNormal value.
+ *
+ * @param {string} title The title string to use for the specified state.
+ * @param {Number} state The state that uses the specified title. The values are described in "CCControlState".
+ */
+ setTitleForState: function (title, state) {
+ this._titleDispatchTable[state] = title || "";
+
+ // If the current state if equal to the given state we update the layout
+ if (this.getState() === state)
+ this.needsLayout();
+ },
+
+ /**
+ * Returns the title color used for a state.
+ *
+ * @param {Number} state The state that uses the specified color. The values are described in "CCControlState".
+ * @return {cc.Color} The color of the title for the specified state.
+ */
+ getTitleColorForState: function (state) {
+ var colorObject = this._titleColorDispatchTable[state];
+ if (colorObject)
+ return colorObject;
+ colorObject = this._titleColorDispatchTable[cc.CONTROL_STATE_NORMAL];
+ if (colorObject)
+ return colorObject;
+ return cc.color.WHITE;
+ },
+
+ /**
+ * Sets the color of the title to use for the specified state.
+ *
+ * @param {cc.Color} color The color of the title to use for the specified state.
+ * @param {Number} state The state that uses the specified color. The values are described in "CCControlState".
+ */
+ setTitleColorForState: function (color, state) {
+ //ccColor3B* colorValue=&color;
+ this._titleColorDispatchTable[state] = color;
+
+ // If the current state if equal to the given state we update the layout
+ if (this.getState() === state)
+ this.needsLayout();
+ },
+
+ /**
+ * Returns the title label used for a state.
+ *
+ * @param state The state that uses the title label. Possible values are described in "CCControlState".
+ * @return {cc.Node} the title label used for a state.
+ */
+ getTitleLabelForState: function (state) {
+ var locTable = this._titleLabelDispatchTable;
+ if (locTable[state])
+ return locTable[state];
+
+ return locTable[cc.CONTROL_STATE_NORMAL];
+ },
+
+ /**
+ * Sets the title label to use for the specified state.
+ * If a property is not specified for a state, the default is to use the CCButtonStateNormal value.
+ *
+ * @param {cc.Node} titleLabel The title label to use for the specified state.
+ * @param {Number} state The state that uses the specified title. The values are described in "CCControlState".
+ */
+ setTitleLabelForState: function (titleLabel, state) {
+ var locTable = this._titleLabelDispatchTable;
+ if (locTable[state]) {
+ var previousLabel = locTable[state];
+ if (previousLabel)
+ this.removeChild(previousLabel, true);
+ }
+
+ locTable[state] = titleLabel;
+ titleLabel.setVisible(false);
+ titleLabel.setAnchorPoint(0.5, 0.5);
+ this.addChild(titleLabel, 1);
+
+ // If the current state if equal to the given state we update the layout
+ if (this.getState() === state)
+ this.needsLayout();
+ },
+
+ /**
+ * Sets the title TTF filename to use for the specified state.
+ * @param {string} fntFile
+ * @param {Number} state
+ */
+ setTitleTTFForState: function (fntFile, state) {
+ var title = this.getTitleForState(state);
+ if (!title)
+ title = "";
+ this.setTitleLabelForState(new cc.LabelTTF(title, fntFile, 12), state);
+ },
+
+ /**
+ * return the title TTF filename to use for the specified state.
+ * @param {Number} state
+ * @returns {string}
+ */
+ getTitleTTFForState: function (state) {
+ var labelTTF = this.getTitleLabelForState(state);
+ if ((labelTTF != null) && (labelTTF instanceof cc.LabelTTF)) {
+ return labelTTF.getFontName();
+ } else {
+ return "";
+ }
+ },
+
+ /**
+ * @param {Number} size
+ * @param {Number} state
+ */
+ setTitleTTFSizeForState: function (size, state) {
+ var labelTTF = this.getTitleLabelForState(state);
+ if ((labelTTF != null) && (labelTTF instanceof cc.LabelTTF)) {
+ labelTTF.setFontSize(size);
+ }
+ },
+
+ /**
+ * return the font size of LabelTTF to use for the specified state
+ * @param {Number} state
+ * @returns {Number}
+ */
+ getTitleTTFSizeForState: function (state) {
+ var labelTTF = this.getTitleLabelForState(state);
+ if ((labelTTF != null) && (labelTTF instanceof cc.LabelTTF)) {
+ return labelTTF.getFontSize();
+ }
+ return 0;
+ },
+
+ /**
+ * Sets the font of the label, changes the label to a CCLabelBMFont if necessary.
+ * @param {string} fntFile The name of the font to change to
+ * @param {Number} state The state that uses the specified fntFile. The values are described in "CCControlState".
+ */
+ setTitleBMFontForState: function (fntFile, state) {
+ var title = this.getTitleForState(state);
+ if (!title)
+ title = "";
+ this.setTitleLabelForState(new cc.LabelBMFont(title, fntFile), state);
+ },
+
+ getTitleBMFontForState: function (state) {
+ var labelBMFont = this.getTitleLabelForState(state);
+ if ((labelBMFont != null) && (labelBMFont instanceof cc.LabelBMFont)) {
+ return labelBMFont.getFntFile();
+ }
+ return "";
+ },
+
+ /**
+ * Returns the background sprite used for a state.
+ *
+ * @param {Number} state The state that uses the background sprite. Possible values are described in "CCControlState".
+ */
+ getBackgroundSpriteForState: function (state) {
+ var locTable = this._backgroundSpriteDispatchTable;
+ if (locTable[state]) {
+ return locTable[state];
+ }
+ return locTable[cc.CONTROL_STATE_NORMAL];
+ },
+
+ /**
+ * Sets the background sprite to use for the specified button state.
+ *
+ * @param {Scale9Sprite} sprite The background sprite to use for the specified state.
+ * @param {Number} state The state that uses the specified image. The values are described in "CCControlState".
+ */
+ setBackgroundSpriteForState: function (sprite, state) {
+ var locTable = this._backgroundSpriteDispatchTable;
+ if (locTable[state]) {
+ var previousSprite = locTable[state];
+ if (previousSprite)
+ this.removeChild(previousSprite, true);
+ }
+
+ locTable[state] = sprite;
+ sprite.setVisible(false);
+ sprite.setAnchorPoint(0.5, 0.5);
+ this.addChild(sprite);
+
+ var locPreferredSize = this._preferredSize;
+ if (locPreferredSize.width !== 0 || locPreferredSize.height !== 0) {
+ sprite.setPreferredSize(locPreferredSize);
+ }
+
+ // If the current state if equal to the given state we update the layout
+ if (this._state === state)
+ this.needsLayout();
+ },
+
+ /**
+ * Sets the background spriteFrame to use for the specified button state.
+ *
+ * @param {SpriteFrame} spriteFrame The background spriteFrame to use for the specified state.
+ * @param {Number} state The state that uses the specified image. The values are described in "CCControlState".
+ */
+ setBackgroundSpriteFrameForState: function (spriteFrame, state) {
+ var sprite = cc.Scale9Sprite.createWithSpriteFrame(spriteFrame);
+ this.setBackgroundSpriteForState(sprite, state);
+ }
+});
+
+var _p = cc.ControlButton.prototype;
+
+// Extended properties
+/** @expose */
+_p.adjustBackground;
+cc.defineGetterSetter(_p, "adjustBackground", _p.getAdjustBackgroundImage, _p.setAdjustBackgroundImage);
+/** @expose */
+_p.preferredSize;
+cc.defineGetterSetter(_p, "preferredSize", _p.getPreferredSize, _p.setPreferredSize);
+/** @expose */
+_p.labelAnchor;
+cc.defineGetterSetter(_p, "labelAnchor", _p.getLabelAnchorPoint, _p.setLabelAnchorPoint);
+
+_p = null;
+
+/**
+ * @deprecated
+ * @param label
+ * @param backgroundSprite
+ * @param fontSize
+ * @returns {ControlButton}
+ */
+cc.ControlButton.create = function (label, backgroundSprite, fontSize) {
+ return new cc.ControlButton(label, backgroundSprite, fontSize);
+};
+
+
diff --git a/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlColourPicker.js b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlColourPicker.js
new file mode 100644
index 0000000..6cdfd6b
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlColourPicker.js
@@ -0,0 +1,187 @@
+/**
+ *
+ * Copyright (c) 2008-2010 Ricardo Quesada
+ * Copyright (c) 2011-2012 cocos2d-x.org
+ * Copyright (c) 2013-2014 Chukong Technologies Inc.
+ *
+ * Copyright 2012 Stewart Hamilton-Arrandale.
+ * http://creativewax.co.uk
+ *
+ * Modified by Yannick Loriot.
+ * http://yannickloriot.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE. *
+ *
+ */
+
+/**
+ * ControlColourPicker: color picker ui component.
+ * @class
+ * @extends cc.Control
+ *
+ * @property {cc.Sprite} background - <@readonly> The background sprite
+ */
+cc.ControlColourPicker = cc.Control.extend(/** @lends cc.ControlColourPicker# */{
+ _hsv:null,
+ _colourPicker:null,
+ _huePicker:null,
+
+ _background:null,
+ _className:"ControlColourPicker",
+ ctor:function () {
+ cc.Control.prototype.ctor.call(this);
+ this.init();
+ },
+ hueSliderValueChanged:function (sender, controlEvent) {
+ this._hsv.h = sender.getHue();
+
+ // Update the value
+ var rgb = cc.ControlUtils.RGBfromHSV(this._hsv);
+ cc.Control.prototype.setColor.call(this,cc.color(0 | (rgb.r * 255), 0 | (rgb.g * 255), 0 | (rgb.b * 255)));
+
+ // Send CCControl callback
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED);
+ this._updateControlPicker();
+ },
+
+ colourSliderValueChanged:function (sender, controlEvent) {
+ this._hsv.s = sender.getSaturation();
+ this._hsv.v = sender.getBrightness();
+
+
+ // Update the value
+ var rgb = cc.ControlUtils.RGBfromHSV(this._hsv);
+ cc.Control.prototype.setColor.call(this,cc.color(0 | (rgb.r * 255), 0 | (rgb.g * 255), 0 | (rgb.b * 255)));
+
+ // Send CCControl callback
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED);
+ },
+
+ setColor:function (color) {
+ cc.Control.prototype.setColor.call(this,color);
+ //this._colorValue = color;
+ var rgba = new cc.RGBA();
+ rgba.r = color.r / 255.0;
+ rgba.g = color.g / 255.0;
+ rgba.b = color.b / 255.0;
+ rgba.a = 1.0;
+
+ this._hsv = cc.ControlUtils.HSVfromRGB(rgba);
+ this._updateHueAndControlPicker();
+ },
+
+ getBackground:function () {
+ return this._background;
+ },
+
+ init:function () {
+ if (cc.Control.prototype.init.call(this)) {
+ // Cache the sprites
+ cc.spriteFrameCache.addSpriteFrames(res.CCControlColourPickerSpriteSheet_plist);
+
+ // Create the sprite batch node
+ var spriteSheet = new cc.SpriteBatchNode(res.CCControlColourPickerSpriteSheet_png);
+ this.addChild(spriteSheet);
+
+ /*// MIPMAP
+ //TODO WebGL code
+ var params = [gl.LINEAR_MIPMAP_NEAREST, gl.LINEAR, gl.REPEAT, gl.CLAMP_TO_EDGE];
+ spriteSheet.getTexture().setAliasTexParameters();
+ spriteSheet.getTexture().setTexParameters(params);
+ spriteSheet.getTexture().generateMipmap();*/
+
+ // Init default color
+ this._hsv = new cc.HSV(0, 0, 0);
+
+ // Add image
+ this._background = cc.ControlUtils.addSpriteToTargetWithPosAndAnchor("menuColourPanelBackground.png", spriteSheet, cc.p(0,0), cc.p(0.5, 0.5));
+
+ var backgroundPointZero = cc.pSub(this._background.getPosition(),
+ cc.p(this._background.getContentSize().width / 2, this._background.getContentSize().height / 2));
+
+ // Setup panels . currently hard-coded...
+ var hueShift = 8;
+ var colourShift = 28;
+
+ this._huePicker = new cc.ControlHuePicker(spriteSheet, cc.p(backgroundPointZero.x + hueShift, backgroundPointZero.y + hueShift));
+ this._colourPicker = new cc.ControlSaturationBrightnessPicker(spriteSheet, cc.p(backgroundPointZero.x + colourShift, backgroundPointZero.y + colourShift));
+
+ // Setup events
+ this._huePicker.addTargetWithActionForControlEvents(this, this.hueSliderValueChanged, cc.CONTROL_EVENT_VALUECHANGED);
+ this._colourPicker.addTargetWithActionForControlEvents(this, this.colourSliderValueChanged, cc.CONTROL_EVENT_VALUECHANGED);
+
+ // Set defaults
+ this._updateHueAndControlPicker();
+ this.addChild(this._huePicker);
+ this.addChild(this._colourPicker);
+
+ // Set content size
+ this.setContentSize(this._background.getContentSize());
+ return true;
+ }
+ else
+ return false;
+ },
+
+ _updateControlPicker:function () {
+ this._huePicker.setHue(this._hsv.h);
+ this._colourPicker.updateWithHSV(this._hsv);
+ },
+
+ _updateHueAndControlPicker:function () {
+ this._huePicker.setHue(this._hsv.h);
+ this._colourPicker.updateWithHSV(this._hsv);
+ this._colourPicker.updateDraggerWithHSV(this._hsv);
+ },
+ setEnabled:function (enabled) {
+ cc.Control.prototype.setEnabled.call(this, enabled);
+ if (this._huePicker !== null) {
+ this._huePicker.setEnabled(enabled);
+ }
+ if (this._colourPicker) {
+ this._colourPicker.setEnabled(enabled);
+ }
+ },
+ onTouchBegan:function () {
+ //ignore all touches, handled by children
+ return false;
+ }
+});
+
+var _p = cc.ControlColourPicker.prototype;
+
+// Extended properties
+/** @expose */
+_p.background;
+cc.defineGetterSetter(_p, "background", _p.getBackground);
+
+_p = null;
+
+/**
+ * @deprecated
+ * @returns {ControlColourPicker}
+ */
+cc.ControlColourPicker.create = function () {
+ return new cc.ControlColourPicker();
+};
+
+// compatible with NPM
+var res = res || {};
+res.CCControlColourPickerSpriteSheet_plist = res.CCControlColourPickerSpriteSheet_plist || "res/extensions/CCControlColourPickerSpriteSheet.plist";
+res.CCControlColourPickerSpriteSheet_png = res.CCControlColourPickerSpriteSheet_png || "res/extensions/CCControlColourPickerSpriteSheet.png";
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlHuePicker.js b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlHuePicker.js
new file mode 100644
index 0000000..9c00274
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlHuePicker.js
@@ -0,0 +1,218 @@
+/**
+ *
+ * Copyright (c) 2008-2010 Ricardo Quesada
+ * Copyright (c) 2011-2012 cocos2d-x.org
+ * Copyright (c) 2013-2014 Chukong Technologies Inc.
+ *
+ * Copyright 2012 Stewart Hamilton-Arrandale.
+ * http://creativewax.co.uk
+ *
+ * Modified by Yannick Loriot.
+ * http://yannickloriot.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *
+ * converted to Javascript / cocos2d-x by Angus C
+ */
+
+/**
+ * ControlHuePicker: HUE picker ui component.
+ * @class
+ * @extends cc.Control
+ *
+ * @property {Number} hue - The hue value
+ * @property {Number} huePercent - The hue value in percentage
+ * @property {cc.Sprite} background - <@readonly> The background sprite
+ * @property {cc.Sprite} slider - <@readonly> The slider sprite
+ * @property {cc.Point} startPos - <@readonly> The start position of the picker
+ */
+cc.ControlHuePicker = cc.Control.extend(/** @lends cc.ControlHuePicker# */{
+ _hue:0,
+ _huePercentage:0,
+ _background:null,
+ _slider:null,
+ _startPos:null,
+ _className:"ControlHuePicker",
+
+ /**
+ * The constructor of cc.ControlHuePicker
+ * @param {cc.Node} target
+ * @param {cc.Point} pos position
+ */
+ ctor:function(target, pos) {
+ cc.Control.prototype.ctor.call(this);
+ pos && this.initWithTargetAndPos(target, pos);
+ },
+
+ //maunally put in the setters
+ getHue:function () {
+ return this._hue;
+ },
+ setHue:function (hueValue) {
+ this._hue = hueValue;
+ this.setHuePercentage(this._hue / 360.0);
+ },
+
+ getHuePercentage:function () {
+ return this._huePercentage;
+ },
+ setHuePercentage:function (hueValueInPercent) {
+ this._huePercentage = hueValueInPercent;
+ this._hue = this._huePercentage * 360.0;
+
+ // Clamp the position of the icon within the circle
+ var backgroundBox = this._background.getBoundingBox();
+
+ // Get the center point of the background image
+ var centerX = this._startPos.x + backgroundBox.width * 0.5;
+ var centerY = this._startPos.y + backgroundBox.height * 0.5;
+
+ // Work out the limit to the distance of the picker when moving around the hue bar
+ var limit = backgroundBox.width * 0.5 - 15.0;
+
+ // Update angle
+ var angleDeg = this._huePercentage * 360.0 - 180.0;
+ var angle = cc.degreesToRadians(angleDeg);
+
+ // Set new position of the slider
+ var x = centerX + limit * Math.cos(angle);
+ var y = centerY + limit * Math.sin(angle);
+ this._slider.setPosition(x, y);
+ },
+
+ setEnabled:function (enabled) {
+ cc.Control.prototype.setEnabled.call(this, enabled);
+ if (this._slider) {
+ this._slider.setOpacity(enabled ? 255 : 128);
+ }
+ },
+
+ getBackground:function () {
+ return this._background;
+ },
+ getSlider:function () {
+ return this._slider;
+ },
+ getStartPos:function () {
+ return this._startPos;
+ },
+
+ initWithTargetAndPos:function (target, pos) {
+ if (cc.Control.prototype.init.call(this)) {
+ // Add background and slider sprites
+ this._background = cc.ControlUtils.addSpriteToTargetWithPosAndAnchor("huePickerBackground.png", target, pos, cc.p(0.0, 0.0));
+ this._slider = cc.ControlUtils.addSpriteToTargetWithPosAndAnchor("colourPicker.png", target, pos, cc.p(0.5, 0.5));
+
+ this._slider.setPosition(pos.x, pos.y + this._background.getBoundingBox().height * 0.5);
+ this._startPos = pos;
+
+ // Sets the default value
+ this._hue = 0.0;
+ this._huePercentage = 0.0;
+ return true;
+ } else
+ return false;
+ },
+
+ _updateSliderPosition:function (location) {
+ // Clamp the position of the icon within the circle
+ var backgroundBox = this._background.getBoundingBox();
+
+ // Get the center point of the background image
+ var centerX = this._startPos.x + backgroundBox.width * 0.5;
+ var centerY = this._startPos.y + backgroundBox.height * 0.5;
+
+ // Work out the distance difference between the location and center
+ var dx = location.x - centerX;
+ var dy = location.y - centerY;
+
+ // Update angle by using the direction of the location
+ var angle = Math.atan2(dy, dx);
+ var angleDeg = cc.radiansToDegrees(angle) + 180.0;
+
+ // use the position / slider width to determin the percentage the dragger is at
+ this.setHue(angleDeg);
+
+ // send CCControl callback
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED);
+ },
+ _checkSliderPosition:function (location) {
+ // compute the distance between the current location and the center
+ var distance = Math.sqrt(Math.pow(location.x + 10, 2) + Math.pow(location.y, 2));
+
+ // check that the touch location is within the circle
+ if (80 > distance && distance > 59) {
+ this._updateSliderPosition(location);
+ return true;
+ }
+ return false;
+ },
+
+ onTouchBegan:function (touch, event) {
+ if (!this.isEnabled() || !this.isVisible()) {
+ return false;
+ }
+ var touchLocation = this.getTouchLocation(touch);
+
+ // Check the touch position on the slider
+ return this._checkSliderPosition(touchLocation);
+ },
+ onTouchMoved:function (touch, event) {
+ // Get the touch location
+ var touchLocation = this.getTouchLocation(touch);
+
+ //small modification: this allows changing of the colour, even if the touch leaves the bounding area
+ //this._updateSliderPosition(touchLocation);
+ //this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED);
+ // Check the touch position on the slider
+ this._checkSliderPosition(touchLocation);
+ }
+});
+
+var _p = cc.ControlHuePicker.prototype;
+
+// Extended properties
+/** @expose */
+_p.hue;
+cc.defineGetterSetter(_p, "hue", _p.getHue, _p.setHue);
+/** @expose */
+_p.huePercent;
+cc.defineGetterSetter(_p, "huePercent", _p.getHuePercentage, _p.setHuePercentage);
+/** @expose */
+_p.background;
+cc.defineGetterSetter(_p, "background", _p.getBackground);
+/** @expose */
+_p.slider;
+cc.defineGetterSetter(_p, "slider", _p.getSlider);
+/** @expose */
+_p.startPos;
+cc.defineGetterSetter(_p, "startPos", _p.getStartPos);
+
+_p = null;
+
+/**
+ * @deprecated
+ * @param target
+ * @param pos
+ * @returns {ControlHuePicker}
+ */
+cc.ControlHuePicker.create = function (target, pos) {
+ return new cc.ControlHuePicker(target, pos);
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlPotentiometer.js b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlPotentiometer.js
new file mode 100644
index 0000000..7c035ef
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlPotentiometer.js
@@ -0,0 +1,300 @@
+/**
+ * Copyright (c) 2008-2010 Ricardo Quesada
+ * Copyright (c) 2011-2012 cocos2d-x.org
+ * Copyright (c) 2013-2014 Chukong Technologies Inc.
+ *
+ * http://www.cocos2d-x.org
+ *
+ * Copyright 2012 Yannick Loriot. All rights reserved.
+ * http://yannickloriot.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+/**
+ * CCControlPotentiometer: Potentiometer control for Cocos2D.
+ * @class
+ * @extends cc.Control
+ *
+ * @property {Number} value - The current value of the potentionmeter
+ * @property {Number} minValue - The minimum value of the potentionmeter
+ * @property {Number} maxValue - The maximum value of the potentionmeter
+ * @property {cc.ProgressTimer} progressTimer - The progress timer of the potentionmeter
+ * @property {cc.Sprite} thumbSprite - The thumb sprite of the potentionmeter
+ * @property {cc.Point} prevLocation - The previous location of the potentionmeter
+ */
+cc.ControlPotentiometer = cc.Control.extend(/** @lends cc.ControlPotentiometer# */{
+ _thumbSprite:null,
+ _progressTimer:null,
+ _previousLocation:null,
+ /** Contains the receiver’s current value. */
+ _value:0,
+ /** Contains the minimum value of the receiver.
+ * The default value of this property is 0.0. */
+ _minimumValue:0,
+ /** Contains the maximum value of the receiver.
+ * The default value of this property is 1.0. */
+ _maximumValue:1,
+ _className:"ControlPotentiometer",
+
+ ctor:function (backgroundFile, progressFile, thumbFile) {
+ cc.Control.prototype.ctor.call(this);
+ if (thumbFile != undefined) {
+ // Prepare track for potentiometer
+ var backgroundSprite = new cc.Sprite(backgroundFile);
+
+ // Prepare thumb for potentiometer
+ var thumbSprite = new cc.Sprite(thumbFile);
+
+ // Prepare progress for potentiometer
+ var progressTimer = new cc.ProgressTimer(new cc.Sprite(progressFile));
+ this.initWithTrackSprite_ProgressTimer_ThumbSprite(backgroundSprite, progressTimer, thumbSprite);
+ }
+ },
+
+ /**
+ *
+ * @param {cc.Sprite} trackSprite
+ * @param {cc.ProgressTimer} progressTimer
+ * @param {cc.Sprite} thumbSprite
+ * @return {Boolean}
+ */
+ initWithTrackSprite_ProgressTimer_ThumbSprite:function (trackSprite, progressTimer, thumbSprite) {
+ if (this.init()) {
+ this.setProgressTimer(progressTimer);
+ this.setThumbSprite(thumbSprite);
+ this._thumbSprite.setPosition(progressTimer.getPosition());
+
+ this.addChild(thumbSprite, 2);
+ this.addChild(progressTimer, 1);
+ this.addChild(trackSprite);
+
+ this.setContentSize(trackSprite.getContentSize());
+
+ // Init default values
+ this._minimumValue = 0.0;
+ this._maximumValue = 1.0;
+ this.setValue(this._minimumValue);
+ return true;
+ }
+ return false;
+ },
+
+ setEnabled:function (enabled) {
+ this.setEnabled(enabled);
+ if (this._thumbSprite !== null) {
+ this._thumbSprite.setOpacity((enabled) ? 255 : 128);
+ }
+ },
+
+ setValue:function (value) {
+ // set new value with sentinel
+ if (value < this._minimumValue) {
+ value = this._minimumValue;
+ }
+
+ if (value > this._maximumValue) {
+ value = this._maximumValue;
+ }
+
+ this._value = value;
+
+ // Update thumb and progress position for new value
+ var percent = (value - this._minimumValue) / (this._maximumValue - this._minimumValue);
+ this._progressTimer.setPercentage(percent * 100.0);
+ this._thumbSprite.setRotation(percent * 360.0);
+
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED);
+ },
+
+ getValue:function () {
+ return this._value;
+ },
+
+ setMinimumValue:function (minimumValue) {
+ this._minimumValue = minimumValue;
+
+ if (this._minimumValue >= this._maximumValue) {
+ this._maximumValue = this._minimumValue + 1.0;
+ }
+
+ this.setValue(this._maximumValue);
+ },
+
+ getMinimumValue:function () {
+ return this._minimumValue;
+ },
+
+ setMaximumValue:function (maximumValue) {
+ this._maximumValue = maximumValue;
+
+ if (this._maximumValue <= this._minimumValue) {
+ this._minimumValue = this._maximumValue - 1.0;
+ }
+
+ this.setValue(this._minimumValue);
+ },
+
+ getMaximumValue:function () {
+ return this._maximumValue;
+ },
+
+ isTouchInside:function (touch) {
+ var touchLocation = this.getTouchLocation(touch);
+
+ var distance = this.distanceBetweenPointAndPoint(this._progressTimer.getPosition(), touchLocation);
+
+ return distance < Math.min(this.getContentSize().width / 2, this.getContentSize().height / 2);
+ },
+
+ onTouchBegan:function (touch, event) {
+ if (!this.isTouchInside(touch) || !this.isEnabled() || !this.isVisible()) {
+ return false;
+ }
+
+ this._previousLocation = this.getTouchLocation(touch);
+
+ this.potentiometerBegan(this._previousLocation);
+
+ return true;
+ },
+
+ onTouchMoved:function (touch, event) {
+ var location = this.getTouchLocation(touch);
+
+ this.potentiometerMoved(location);
+ },
+
+ onTouchEnded:function (touch, event) {
+ this.potentiometerEnded(cc.p(0, 0));
+ },
+
+ /**
+ * the distance between the point1 and point2
+ * @param {cc.Point} point1
+ * @param {cc.Point} point2
+ * @return {Number}
+ */
+ distanceBetweenPointAndPoint:function (point1, point2) {
+ var dx = point1.x - point2.x;
+ var dy = point1.y - point2.y;
+ return Math.sqrt(dx * dx + dy * dy);
+ },
+
+ /**
+ * the angle in degree between line1 and line2.
+ * @param {cc.Point} beginLineA
+ * @param {cc.Point} endLineA
+ * @param {cc.Point} beginLineB
+ * @param {cc.Point} endLineB
+ * @return {Number}
+ */
+ angleInDegreesBetweenLineFromPoint_toPoint_toLineFromPoint_toPoint:function (beginLineA, endLineA, beginLineB, endLineB) {
+ var a = endLineA.x - beginLineA.x;
+ var b = endLineA.y - beginLineA.y;
+ var c = endLineB.x - beginLineB.x;
+ var d = endLineB.y - beginLineB.y;
+
+ var atanA = Math.atan2(a, b);
+ var atanB = Math.atan2(c, d);
+
+ // convert radiants to degrees
+ return (atanA - atanB) * 180 / Math.PI;
+ },
+
+ potentiometerBegan:function (location) {
+ this.setSelected(true);
+ this.getThumbSprite().setColor(cc.color.GRAY);
+ },
+
+ potentiometerMoved:function (location) {
+ var angle = this.angleInDegreesBetweenLineFromPoint_toPoint_toLineFromPoint_toPoint(this._progressTimer.getPosition(), location, this._progressTimer.getPosition(), this._previousLocation);
+
+ // fix value, if the 12 o'clock position is between location and previousLocation
+ if (angle > 180) {
+ angle -= 360;
+ }
+ else if (angle < -180) {
+ angle += 360;
+ }
+
+ this.setValue(this._value + angle / 360.0 * (this._maximumValue - this._minimumValue));
+
+ this._previousLocation = location;
+ },
+
+ potentiometerEnded:function (location) {
+ this.getThumbSprite().setColor(cc.color.WHITE);
+ this.setSelected(false);
+ },
+ setThumbSprite:function (sprite) {
+ this._thumbSprite = sprite;
+ },
+ getThumbSprite:function () {
+ return this._thumbSprite;
+ },
+ setProgressTimer:function (sprite) {
+ this._progressTimer = sprite;
+ },
+ getProgressTimer:function () {
+ return this._progressTimer;
+ },
+ setPreviousLocation:function (point) {
+ this._previousLocation = point;
+ },
+ getPreviousLocation:function () {
+ return this._previousLocation;
+ }
+});
+
+var _p = cc.ControlPotentiometer.prototype;
+
+// Extended properties
+/** @expose */
+_p.value;
+cc.defineGetterSetter(_p, "value", _p.getValue, _p.setValue);
+/** @expose */
+_p.minValue;
+cc.defineGetterSetter(_p, "minValue", _p.getMinimumValue, _p.setMinimumValue);
+/** @expose */
+_p.maxValue;
+cc.defineGetterSetter(_p, "maxValue", _p.getMaximumValue, _p.setMaximumValue);
+/** @expose */
+_p.progressTimer;
+cc.defineGetterSetter(_p, "progressTimer", _p.getProgressTimer, _p.setProgressTimer);
+/** @expose */
+_p.thumbSprite;
+cc.defineGetterSetter(_p, "thumbSprite", _p.getThumbSprite, _p.setThumbSprite);
+/** @expose */
+_p.prevLocation;
+cc.defineGetterSetter(_p, "prevLocation", _p.getPreviousLocation, _p.setPreviousLocation);
+
+_p = null;
+
+/**
+ * @deprecated
+ * @param backgroundFile
+ * @param progressFile
+ * @param thumbFile
+ * @returns {ControlPotentiometer}
+ */
+cc.ControlPotentiometer.create = function (backgroundFile, progressFile, thumbFile) {
+ return new cc.ControlPotentiometer(backgroundFile, progressFile, thumbFile);
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlSaturationBrightnessPicker.js b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlSaturationBrightnessPicker.js
new file mode 100644
index 0000000..a9045c4
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlSaturationBrightnessPicker.js
@@ -0,0 +1,257 @@
+/**
+ *
+ * Copyright (c) 2008-2010 Ricardo Quesada
+ * Copyright (c) 2011-2012 cocos2d-x.org
+ * Copyright (c) 2013-2014 Chukong Technologies Inc.
+ *
+ * Copyright 2012 Stewart Hamilton-Arrandale.
+ * http://creativewax.co.uk
+ *
+ * Modified by Yannick Loriot.
+ * http://yannickloriot.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *
+ * converted to Javascript / cocos2d-x by Angus C
+ */
+
+/**
+ * ControlSaturationBrightnessPicker: Saturation brightness picker ui component.
+ * @class
+ * @extends cc.Control
+ *
+ * @property {Number} saturation - <@readonly> Saturation value of the picker
+ * @property {Number} brightness - <@readonly> Brightness value of the picker
+ * @property {cc.Sprite} background - <@readonly> The background sprite
+ * @property {cc.Sprite} overlay - <@readonly> The overlay sprite
+ * @property {cc.Sprite} shadow - <@readonly> The shadow sprite
+ * @property {cc.Sprite} slider - <@readonly> The slider sprite
+ * @property {cc.Point} startPos - <@readonly> The start position of the picker
+ */
+cc.ControlSaturationBrightnessPicker = cc.Control.extend(/** @lends cc.ControlSaturationBrightnessPicker# */{
+ _saturation:0,
+ _brightness:0,
+
+ _background:null,
+ _overlay:null,
+ _shadow:null,
+ _slider:null,
+ _startPos:null,
+
+ _boxPos:0,
+ _boxSize:0,
+ _className:"ControlSaturationBrightnessPicker",
+
+ /**
+ * The constructor of cc.ControlSaturationBrightnessPicker
+ * @param {cc.Node} target
+ * @param {cc.Point} pos position
+ */
+ ctor:function (target, pos) {
+ cc.Control.prototype.ctor.call(this);
+ pos && this.initWithTargetAndPos(target, pos);
+ },
+ getSaturation:function () {
+ return this._saturation;
+ },
+ getBrightness:function () {
+ return this._brightness;
+ },
+
+ //not sure if these need to be there actually. I suppose someone might want to access the sprite?
+ getBackground:function () {
+ return this._background;
+ },
+ getOverlay:function () {
+ return this._brightness;
+ },
+ getShadow:function () {
+ return this._shadow;
+ },
+ getSlider:function () {
+ return this._slider;
+ },
+ getStartPos:function () {
+ return this._startPos;
+ },
+
+ initWithTargetAndPos:function (target, pos) {
+ if (cc.Control.prototype.init.call(this)) {
+ // Add background and slider sprites
+ this._background = cc.ControlUtils.addSpriteToTargetWithPosAndAnchor("colourPickerBackground.png", target, pos, cc.p(0.0, 0.0));
+ this._overlay = cc.ControlUtils.addSpriteToTargetWithPosAndAnchor("colourPickerOverlay.png", target, pos, cc.p(0.0, 0.0));
+ this._shadow = cc.ControlUtils.addSpriteToTargetWithPosAndAnchor("colourPickerShadow.png", target, pos, cc.p(0.0, 0.0));
+ this._slider = cc.ControlUtils.addSpriteToTargetWithPosAndAnchor("colourPicker.png", target, pos, cc.p(0.5, 0.5));
+
+ this._startPos = pos; // starting position of the colour picker
+ this._boxPos = 35; // starting position of the virtual box area for picking a colour
+ this._boxSize = this._background.getContentSize().width / 2; // the size (width and height) of the virtual box for picking a colour from
+ return true;
+ } else
+ return false;
+ },
+
+ setEnabled:function (enabled) {
+ cc.Control.prototype.setEnabled.call(this, enabled);
+ if (this._slider) {
+ this._slider.setOpacity(enabled ? 255 : 128);
+ }
+ },
+
+ updateWithHSV:function (hsv) {
+ var hsvTemp = new cc.HSV();
+ hsvTemp.s = 1;
+ hsvTemp.h = hsv.h;
+ hsvTemp.v = 1;
+
+ var rgb = cc.ControlUtils.RGBfromHSV(hsvTemp);
+ this._background.setColor(cc.color(0 | (rgb.r * 255), 0 | (rgb.g * 255), 0 | (rgb.b * 255)));
+ },
+ updateDraggerWithHSV:function (hsv) {
+ // Set the position of the slider to the correct saturation and brightness
+ var pos = cc.p(this._startPos.x + this._boxPos + (this._boxSize * (1 - hsv.s)),
+ this._startPos.y + this._boxPos + (this._boxSize * hsv.v));
+
+ // update
+ this._updateSliderPosition(pos);
+ },
+
+ _updateSliderPosition:function (sliderPosition) {
+ // Clamp the position of the icon within the circle
+
+ // Get the center point of the bkgd image
+ var centerX = this._startPos.x + this._background.getBoundingBox().width * 0.5;
+ var centerY = this._startPos.y + this._background.getBoundingBox().height * 0.5;
+
+ // Work out the distance difference between the location and center
+ var dx = sliderPosition.x - centerX;
+ var dy = sliderPosition.y - centerY;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+
+ // Update angle by using the direction of the location
+ var angle = Math.atan2(dy, dx);
+
+ // Set the limit to the slider movement within the colour picker
+ var limit = this._background.getBoundingBox().width * 0.5;
+
+ // Check distance doesn't exceed the bounds of the circle
+ if (dist > limit) {
+ sliderPosition.x = centerX + limit * Math.cos(angle);
+ sliderPosition.y = centerY + limit * Math.sin(angle);
+ }
+
+ // Set the position of the dragger
+ this._slider.setPosition(sliderPosition);
+
+
+ // Clamp the position within the virtual box for colour selection
+ if (sliderPosition.x < this._startPos.x + this._boxPos)
+ sliderPosition.x = this._startPos.x + this._boxPos;
+ else if (sliderPosition.x > this._startPos.x + this._boxPos + this._boxSize - 1)
+ sliderPosition.x = this._startPos.x + this._boxPos + this._boxSize - 1;
+ if (sliderPosition.y < this._startPos.y + this._boxPos)
+ sliderPosition.y = this._startPos.y + this._boxPos;
+ else if (sliderPosition.y > this._startPos.y + this._boxPos + this._boxSize)
+ sliderPosition.y = this._startPos.y + this._boxPos + this._boxSize;
+
+ // Use the position / slider width to determin the percentage the dragger is at
+ this._saturation = 1.0 - Math.abs((this._startPos.x + this._boxPos - sliderPosition.x) / this._boxSize);
+ this._brightness = Math.abs((this._startPos.y + this._boxPos - sliderPosition.y) / this._boxSize);
+ },
+
+ _checkSliderPosition:function (location) {
+ // Clamp the position of the icon within the circle
+ // get the center point of the bkgd image
+ var centerX = this._startPos.x + this._background.getBoundingBox().width * 0.5;
+ var centerY = this._startPos.y + this._background.getBoundingBox().height * 0.5;
+
+ // work out the distance difference between the location and center
+ var dx = location.x - centerX;
+ var dy = location.y - centerY;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+
+ // check that the touch location is within the bounding rectangle before sending updates
+ if (dist <= this._background.getBoundingBox().width * 0.5) {
+ this._updateSliderPosition(location);
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED);
+ return true;
+ }
+ return false;
+ },
+
+ onTouchBegan:function (touch, event) {
+ if (!this.isEnabled() || !this.isVisible()) {
+ return false;
+ }
+ // Get the touch location
+ var touchLocation = this.getTouchLocation(touch);
+
+ // Check the touch position on the slider
+ return this._checkSliderPosition(touchLocation);
+ },
+
+ onTouchMoved:function (touch, event) {
+ // Get the touch location
+ var touchLocation = this.getTouchLocation(touch);
+
+ //small modification: this allows changing of the colour, even if the touch leaves the bounding area
+ //this._updateSliderPosition(touchLocation);
+ //this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED);
+ // Check the touch position on the slider
+ this._checkSliderPosition(touchLocation);
+ }
+});
+
+var _p = cc.ControlSaturationBrightnessPicker.prototype;
+
+// Extended properties
+/** @expose */
+_p.saturation;
+cc.defineGetterSetter(_p, "saturation", _p.getSaturation);
+/** @expose */
+_p.brightness;
+cc.defineGetterSetter(_p, "brightness", _p.getBrightness);
+/** @expose */
+_p.background;
+cc.defineGetterSetter(_p, "background", _p.getBackground);
+/** @expose */
+_p.overlay;
+cc.defineGetterSetter(_p, "overlay", _p.getOverlay);
+/** @expose */
+_p.shadow;
+cc.defineGetterSetter(_p, "shadow", _p.getShadow);
+/** @expose */
+_p.slider;
+cc.defineGetterSetter(_p, "slider", _p.getSlider);
+/** @expose */
+_p.startPos;
+cc.defineGetterSetter(_p, "startPos", _p.getStartPos);
+
+_p = null;
+
+/**
+ * Creates a cc.ControlSaturationBrightnessPicker
+ * @param {cc.Node} target
+ * @param {cc.Point} pos position
+ * @returns {ControlSaturationBrightnessPicker}
+ */
+cc.ControlSaturationBrightnessPicker.create = function (target, pos) {
+ return new cc.ControlSaturationBrightnessPicker(target, pos);
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlSlider.js b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlSlider.js
new file mode 100644
index 0000000..e4a757b
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlSlider.js
@@ -0,0 +1,308 @@
+/**
+ *
+ * Copyright (c) 2008-2010 Ricardo Quesada
+ * Copyright (c) 2011-2012 cocos2d-x.org
+ * Copyright (c) 2013-2014 Chukong Technologies Inc.
+ *
+ * Copyright 2011 Yannick Loriot. All rights reserved.
+ * http://yannickloriot.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *
+ * converted to Javascript / cocos2d-x by Angus C
+ */
+
+/**
+ * @ignore
+ */
+cc.SLIDER_MARGIN_H = 24;
+cc.SLIDER_MARGIN_V = 8;
+
+/**
+ * ControlSlider: Slider ui component.
+ * @class
+ * @extends cc.Control
+ *
+ * @property {Number} value - The value of the slider
+ * @property {Number} minValue - The minimum value of the slider
+ * @property {Number} maxValue - The maximum value of the slider
+ * @property {Number} minAllowedValue - The minimum allowed value of the slider
+ * @property {Number} maxAllowedValue - The maximum allowed value of the slider
+ * @property {Number} thumbSprite - <@readonly> Brightness value of the picker
+ * @property {cc.Sprite} progressSprite - <@readonly> The background sprite
+ * @property {cc.Sprite} backgroundSprite - <@readonly> The overlay sprite
+ */
+cc.ControlSlider = cc.Control.extend(/** @lends cc.ControlSlider# */{
+ _value:0,
+ _minimumValue:0,
+ _maximumValue:0,
+ _minimumAllowedValue:0,
+ _maximumAllowedValue:0,
+
+ _thumbSprite:null,
+ _progressSprite:null,
+ _backgroundSprite:null,
+ _className:"ControlSlider",
+
+ ctor:function (bgFile, progressFile, thumbFile) {
+ cc.Control.prototype.ctor.call(this);
+ if (thumbFile != undefined) {
+ // Prepare background for slider
+ var bgSprite = new cc.Sprite(bgFile);
+
+ // Prepare progress for slider
+ var progressSprite = new cc.Sprite(progressFile);
+
+ // Prepare thumb (menuItem) for slider
+ var thumbSprite = new cc.Sprite(thumbFile);
+
+ this.initWithSprites(bgSprite, progressSprite, thumbSprite);
+ }
+ },
+
+ getValue:function () {
+ return this._value;
+ },
+ setValue:function (value) {
+ //clamp between the two bounds
+ value = Math.max(value, this._minimumValue);
+ value = Math.min(value, this._maximumValue);
+ this._value = value;
+ this.needsLayout();
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED);
+ },
+
+ getMinimumValue:function () {
+ return this._minimumValue;
+ },
+ setMinimumValue:function (minimumValue) {
+ this._minimumValue = minimumValue;
+ this._minimumAllowedValue = minimumValue;
+ if (this._minimumValue >= this._maximumValue)
+ this._maximumValue = this._minimumValue + 1.0;
+ this.setValue(this._value);
+ },
+
+ getMaximumValue:function () {
+ return this._maximumValue;
+ },
+ setMaximumValue:function (maximumValue) {
+ this._maximumValue = maximumValue;
+ this._maximumAllowedValue = maximumValue;
+ if (this._maximumValue <= this._minimumValue)
+ this._minimumValue = this._maximumValue - 1.0;
+ this.setValue(this._value);
+ },
+ isTouchInside:function (touch) {
+ var touchLocation = touch.getLocation();
+ touchLocation = this.getParent().convertToNodeSpace(touchLocation);
+
+ var rect = this.getBoundingBox();
+ rect.width += this._thumbSprite.getContentSize().width;
+ rect.x -= this._thumbSprite.getContentSize().width / 2;
+
+ return cc.rectContainsPoint(rect, touchLocation);
+ },
+ locationFromTouch:function (touch) {
+ var touchLocation = touch.getLocation(); // Get the touch position
+ touchLocation = this.convertToNodeSpace(touchLocation); // Convert to the node space of this class
+
+ if (touchLocation.x < 0) {
+ touchLocation.x = 0;
+ } else if (touchLocation.x > this._backgroundSprite.getContentSize().width) {
+ touchLocation.x = this._backgroundSprite.getContentSize().width;
+ }
+
+ return touchLocation;
+ },
+ getMinimumAllowedValue:function () {
+ return this._minimumAllowedValue;
+ },
+ setMinimumAllowedValue:function (val) {
+ this._minimumAllowedValue = val;
+ },
+
+ getMaximumAllowedValue:function () {
+ return this._maximumAllowedValue;
+ },
+
+ setMaximumAllowedValue:function (val) {
+ this._maximumAllowedValue = val;
+ },
+
+ getThumbSprite:function () {
+ return this._thumbSprite;
+ },
+ getProgressSprite:function () {
+ return this._progressSprite;
+ },
+ getBackgroundSprite:function () {
+ return this._backgroundSprite;
+ },
+
+ /**
+ * Initializes a slider with a background sprite, a progress bar and a thumb
+ * item.
+ *
+ * @param {cc.Sprite} backgroundSprite CCSprite, that is used as a background.
+ * @param {cc.Sprite} progressSprite CCSprite, that is used as a progress bar.
+ * @param {cc.Sprite} thumbSprite CCMenuItem, that is used as a thumb.
+ */
+ initWithSprites:function (backgroundSprite, progressSprite, thumbSprite) {
+ if (cc.Control.prototype.init.call(this)) {
+ this.ignoreAnchorPointForPosition(false);
+
+ this._backgroundSprite = backgroundSprite;
+ this._progressSprite = progressSprite;
+ this._thumbSprite = thumbSprite;
+
+ // Defines the content size
+ var maxRect = cc.ControlUtils.CCRectUnion(backgroundSprite.getBoundingBox(), thumbSprite.getBoundingBox());
+ this.setContentSize(maxRect.width, maxRect.height);
+
+ // Add the slider background
+ this._backgroundSprite.setAnchorPoint(0.5, 0.5);
+ this._backgroundSprite.setPosition(maxRect.width / 2, maxRect.height / 2);
+ this.addChild(this._backgroundSprite);
+
+ // Add the progress bar
+ this._progressSprite.setAnchorPoint(0.0, 0.5);
+ this._progressSprite.setPosition(0, maxRect.height / 2);
+ this.addChild(this._progressSprite);
+
+ // Add the slider thumb
+ this._thumbSprite.setPosition(0, maxRect.height / 2);
+ this.addChild(this._thumbSprite);
+
+ // Init default values
+ this._minimumValue = 0.0;
+ this._maximumValue = 1.0;
+ this.setValue(this._minimumValue);
+ return true;
+ } else
+ return false;
+ },
+
+ setEnabled:function (enabled) {
+ cc.Control.prototype.setEnabled.call(this, enabled);
+ if (this._thumbSprite) {
+ this._thumbSprite.setOpacity(enabled ? 255 : 128);
+ }
+ },
+
+ sliderBegan:function (location) {
+ this.setSelected(true);
+ this._thumbSprite.setColor(cc.color.GRAY);
+ this.setValue(this.valueForLocation(location));
+ },
+ sliderMoved:function (location) {
+ this.setValue(this.valueForLocation(location));
+ },
+ sliderEnded:function (location) {
+ if (this.isSelected()) {
+ this.setValue(this.valueForLocation(this._thumbSprite.getPosition()));
+ }
+ this._thumbSprite.setColor(cc.color.WHITE);
+ this.setSelected(false);
+ },
+
+ getTouchLocationInControl:function (touch) {
+ var touchLocation = touch.getLocation(); // Get the touch position
+ touchLocation = this.convertToNodeSpace(touchLocation); // Convert to the node space of this class
+
+ if (touchLocation.x < 0) {
+ touchLocation.x = 0;
+ } else if (touchLocation.x > this._backgroundSprite.getContentSize().width + cc.SLIDER_MARGIN_H) {
+ touchLocation.x = this._backgroundSprite.getContentSize().width + cc.SLIDER_MARGIN_H;
+ }
+ return touchLocation;
+ },
+
+ onTouchBegan:function (touch, event) {
+ if (!this.isTouchInside(touch)|| !this.isEnabled() || !this.isVisible())
+ return false;
+
+ var location = this.locationFromTouch(touch);
+ this.sliderBegan(location);
+ return true;
+ },
+ onTouchMoved:function (touch, event) {
+ var location = this.locationFromTouch(touch);
+ this.sliderMoved(location);
+ },
+ onTouchEnded:function (touch, event) {
+ this.sliderEnded(cc.p(0,0));
+ },
+ needsLayout:function(){
+ var percent = (this._value - this._minimumValue) / (this._maximumValue - this._minimumValue);
+ this._thumbSprite.setPositionX(percent * this._backgroundSprite.getContentSize().width);
+
+ // Stretches content proportional to newLevel
+ var textureRect = this._progressSprite.getTextureRect();
+ textureRect = cc.rect(textureRect.x, textureRect.y, this._thumbSprite.getPositionX(), textureRect.height);
+ this._progressSprite.setTextureRect(textureRect, this._progressSprite.isTextureRectRotated());
+ this._thumbSprite._renderCmd.transform(this._renderCmd);
+ },
+ /** Returns the value for the given location. */
+ valueForLocation:function (location) {
+ var percent = location.x / this._backgroundSprite.getContentSize().width;
+ return Math.max(Math.min(this._minimumValue + percent * (this._maximumValue - this._minimumValue), this._maximumAllowedValue), this._minimumAllowedValue);
+ }
+});
+
+var _p = cc.ControlSlider.prototype;
+
+// Extended properties
+/** @expose */
+_p.value;
+cc.defineGetterSetter(_p, "value", _p.getValue, _p.setValue);
+/** @expose */
+_p.minValue;
+cc.defineGetterSetter(_p, "minValue", _p.getMinimumValue, _p.setMinimumValue);
+/** @expose */
+_p.maxValue;
+cc.defineGetterSetter(_p, "maxValue", _p.getMaximumValue, _p.setMaximumValue);
+/** @expose */
+_p.minAllowedValue;
+cc.defineGetterSetter(_p, "minAllowedValue", _p.getMinimumAllowedValue, _p.setMinimumAllowedValue);
+/** @expose */
+_p.maxAllowedValue;
+cc.defineGetterSetter(_p, "maxAllowedValue", _p.getMaximumAllowedValue, _p.setMaximumAllowedValue);
+/** @expose */
+_p.thumbSprite;
+cc.defineGetterSetter(_p, "thumbSprite", _p.getThumbSprite);
+/** @expose */
+_p.progressSprite;
+cc.defineGetterSetter(_p, "progressSprite", _p.getProgressSprite);
+/** @expose */
+_p.backgroundSprite;
+cc.defineGetterSetter(_p, "backgroundSprite", _p.getBackgroundSprite);
+
+_p = null;
+
+/**
+ * Creates a slider with a given background sprite and a progress bar and a
+ * thumb item.
+ * @deprecated
+ * @see cc.ControlSlider
+ */
+cc.ControlSlider.create = function (bgFile, progressFile, thumbFile) {
+ return new cc.ControlSlider(bgFile, progressFile, thumbFile);
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlStepper.js b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlStepper.js
new file mode 100644
index 0000000..6ac29fb
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlStepper.js
@@ -0,0 +1,390 @@
+/**
+ * Copyright (c) 2008-2010 Ricardo Quesada
+ * Copyright (c) 2011-2012 cocos2d-x.org
+ * Copyright (c) 2013-2014 Chukong Technologies Inc.
+ *
+ * http://www.cocos2d-x.org
+ *
+ * Copyright 2012 Yannick Loriot. All rights reserved.
+ * http://yannickloriot.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+/**
+ * @ignore
+ */
+cc.CONTROL_STEPPER_PARTMINUS = 0;
+cc.CONTROL_STEPPER_PARTPLUS = 1;
+cc.CONTROL_STEPPER_PARTNONE = 2;
+cc.CONTROL_STEPPER_LABELCOLOR_ENABLED = cc.color(55, 55, 55);
+cc.CONTROL_STEPPER_LABELCOLOR_DISABLED = cc.color(147, 147, 147);
+cc.CONTROL_STEPPER_LABELFONT = "CourierNewPSMT";
+cc.AUTOREPEAT_DELTATIME = 0.15;
+cc.AUTOREPEAT_INCREASETIME_INCREMENT = 12;
+
+/**
+ * ControlStepper: Stepper ui component.
+ * @class
+ * @extends cc.Control
+ *
+ * @property {Boolean} wraps - Indicate whether the stepper wraps
+ * @property {Number} value - The value of the stepper control
+ * @property {Number} minValue - The minimum value of the stepper control
+ * @property {Number} maxValue - The maximum value of the stepper control
+ * @property {Number} stepValue - The interval value for each step of the stepper control
+ * @property {Boolean} continuous - <@readonly> Indicate whether the stepper value is continuous
+ * @property {cc.Sprite} minusSprite - The sprite for minus button of the stepper control
+ * @property {cc.Sprite} plusSprite - The sprite for plus button of the stepper control
+ * @property {cc.LabelTTF} minusLabel - The label for minus button of the stepper control
+ * @property {cc.LabelTTF} plusSLabel - The label for plus button of the stepper control
+ */
+cc.ControlStepper = cc.Control.extend(/** @lends cc.ControlStepper# */{
+ _minusSprite:null,
+ _plusSprite:null,
+ _minusLabel:null,
+ _plusLabel:null,
+ _value:0,
+ _continuous:false,
+ _autorepeat:false,
+ _wraps:false,
+ _minimumValue:0,
+ _maximumValue:0,
+ _stepValue:0,
+ _touchInsideFlag:false,
+ _touchedPart:cc.CONTROL_STEPPER_PARTNONE,
+ _autorepeatCount:0,
+ _className:"ControlStepper",
+ ctor:function (minusSprite, plusSprite) {
+ cc.Control.prototype.ctor.call(this);
+ this._minusSprite = null;
+ this._plusSprite = null;
+ this._minusLabel = null;
+ this._plusLabel = null;
+ this._value = 0;
+ this._continuous = false;
+ this._autorepeat = false;
+ this._wraps = false;
+ this._minimumValue = 0;
+ this._maximumValue = 0;
+ this._stepValue = 0;
+ this._touchInsideFlag = false;
+ this._touchedPart = cc.CONTROL_STEPPER_PARTNONE;
+ this._autorepeatCount = 0;
+
+ plusSprite && this.initWithMinusSpriteAndPlusSprite(minusSprite, plusSprite);
+
+ },
+
+ initWithMinusSpriteAndPlusSprite:function (minusSprite, plusSprite) {
+ if(!minusSprite)
+ throw new Error("cc.ControlStepper.initWithMinusSpriteAndPlusSprite(): Minus sprite should be non-null.");
+ if(!plusSprite)
+ throw new Error("cc.ControlStepper.initWithMinusSpriteAndPlusSprite(): Plus sprite should be non-null.");
+
+ if (this.init()) {
+ // Set the default values
+ this._autorepeat = true;
+ this._continuous = true;
+ this._minimumValue = 0;
+ this._maximumValue = 100;
+ this._value = 0;
+ this._stepValue = 1;
+ this._wraps = false;
+ this.ignoreAnchorPointForPosition(false);
+
+ // Add the minus components
+ this.setMinusSprite(minusSprite);
+ this._minusSprite.setPosition(minusSprite.getContentSize().width / 2, minusSprite.getContentSize().height / 2);
+ this.addChild(this._minusSprite);
+
+ this.setMinusLabel(new cc.LabelTTF("-", cc.CONTROL_STEPPER_LABELFONT, 40, cc.size(40, 40), cc.TEXT_ALIGNMENT_CENTER, cc.VERTICAL_TEXT_ALIGNMENT_CENTER));
+ this._minusLabel.setColor(cc.CONTROL_STEPPER_LABELCOLOR_DISABLED);
+ this._minusLabel.setPosition(this._minusSprite.getContentSize().width / 2, this._minusSprite.getContentSize().height / 2);
+ this._minusSprite.addChild(this._minusLabel);
+
+ // Add the plus components
+ this.setPlusSprite(plusSprite);
+ this._plusSprite.setPosition(minusSprite.getContentSize().width + plusSprite.getContentSize().width / 2,
+ minusSprite.getContentSize().height / 2);
+ this.addChild(this._plusSprite);
+
+ this.setPlusLabel(new cc.LabelTTF("+", cc.CONTROL_STEPPER_LABELFONT, 40, cc.size(40, 40), cc.TEXT_ALIGNMENT_CENTER, cc.VERTICAL_TEXT_ALIGNMENT_CENTER));
+ this._plusLabel.setColor(cc.CONTROL_STEPPER_LABELCOLOR_ENABLED);
+ this._plusLabel.setPosition(this._plusSprite.getContentSize().width / 2, this._plusSprite.getContentSize().height / 2);
+ this._plusSprite.addChild(this._plusLabel);
+
+ // Defines the content size
+ var maxRect = cc.ControlUtils.CCRectUnion(this._minusSprite.getBoundingBox(), this._plusSprite.getBoundingBox());
+ this.setContentSize(this._minusSprite.getContentSize().width + this._plusSprite.getContentSize().height, maxRect.height);
+ return true;
+ }
+ return false;
+ },
+
+//#pragma mark Properties
+
+ setWraps: function (wraps) {
+ this._wraps = wraps;
+
+ if (this._wraps) {
+ this._minusLabel.setColor(cc.CONTROL_STEPPER_LABELCOLOR_ENABLED);
+ this._plusLabel.setColor(cc.CONTROL_STEPPER_LABELCOLOR_ENABLED);
+ }
+
+ this.setValue(this._value);
+ },
+
+ getWraps: function () {
+ return this._wraps;
+ },
+
+ setMinimumValue:function (minimumValue) {
+ if (minimumValue >= this._maximumValue)
+ throw new Error("cc.ControlStepper.setMinimumValue(): minimumValue should be numerically less than maximumValue.");
+
+ this._minimumValue = minimumValue;
+ this.setValue(this._value);
+ },
+ getMinimumValue: function () {
+ return this._minimumValue;
+ },
+
+ setMaximumValue:function (maximumValue) {
+ if (maximumValue <= this._minimumValue)
+ throw new Error("cc.ControlStepper.setMaximumValue(): maximumValue should be numerically less than maximumValue.");
+
+ this._maximumValue = maximumValue;
+ this.setValue(this._value);
+ },
+ getMaximumValue: function () {
+ return this._maximumValue;
+ },
+
+ setValue:function (value) {
+ this.setValueWithSendingEvent(value, true);
+ },
+
+ getValue:function () {
+ return this._value;
+ },
+
+ setStepValue:function (stepValue) {
+ if (stepValue <= 0)
+ throw new Error("cc.ControlStepper.setMaximumValue(): stepValue should be numerically greater than 0.");
+ this._stepValue = stepValue;
+ },
+
+ getStepValue:function () {
+ return this._stepValue;
+ },
+
+ isContinuous:function () {
+ return this._continuous;
+ },
+
+ setValueWithSendingEvent:function (value, send) {
+ if (value < this._minimumValue) {
+ value = this._wraps ? this._maximumValue : this._minimumValue;
+ } else if (value > this._maximumValue) {
+ value = this._wraps ? this._minimumValue : this._maximumValue;
+ }
+
+ this._value = value;
+
+ if (!this._wraps) {
+ this._minusLabel.setColor((value === this._minimumValue) ? cc.CONTROL_STEPPER_LABELCOLOR_DISABLED : cc.CONTROL_STEPPER_LABELCOLOR_ENABLED);
+ this._plusLabel.setColor((value === this._maximumValue) ? cc.CONTROL_STEPPER_LABELCOLOR_DISABLED : cc.CONTROL_STEPPER_LABELCOLOR_ENABLED);
+ }
+
+ if (send) {
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED);
+ }
+ },
+
+ startAutorepeat:function () {
+ this._autorepeatCount = -1;
+ this.schedule(this.update, cc.AUTOREPEAT_DELTATIME, cc.REPEAT_FOREVER, cc.AUTOREPEAT_DELTATIME * 3);
+ },
+
+ /** Stop the autorepeat. */
+ stopAutorepeat:function () {
+ this.unschedule(this.update);
+ },
+
+ update:function (dt) {
+ this._autorepeatCount++;
+
+ if ((this._autorepeatCount < cc.AUTOREPEAT_INCREASETIME_INCREMENT) && (this._autorepeatCount % 3) !== 0)
+ return;
+
+ if (this._touchedPart === cc.CONTROL_STEPPER_PARTMINUS) {
+ this.setValueWithSendingEvent(this._value - this._stepValue, this._continuous);
+ } else if (this._touchedPart === cc.CONTROL_STEPPER_PARTPLUS) {
+ this.setValueWithSendingEvent(this._value + this._stepValue, this._continuous);
+ }
+ },
+
+//#pragma mark CCControlStepper Private Methods
+
+ updateLayoutUsingTouchLocation:function (location) {
+ if (location.x < this._minusSprite.getContentSize().width
+ && this._value > this._minimumValue) {
+ this._touchedPart = cc.CONTROL_STEPPER_PARTMINUS;
+ this._minusSprite.setColor(cc.color.GRAY);
+ this._plusSprite.setColor(cc.color.WHITE);
+
+ } else if (location.x >= this._minusSprite.getContentSize().width
+ && this._value < this._maximumValue) {
+ this._touchedPart = cc.CONTROL_STEPPER_PARTPLUS;
+ this._minusSprite.setColor(cc.color.WHITE);
+ this._plusSprite.setColor(cc.color.GRAY);
+
+ } else {
+ this._touchedPart = cc.CONTROL_STEPPER_PARTNONE;
+ this._minusSprite.setColor(cc.color.WHITE);
+ this._plusSprite.setColor(cc.color.WHITE);
+ }
+ },
+
+
+ onTouchBegan:function (touch, event) {
+ if (!this.isTouchInside(touch) || !this.isEnabled() || !this.isVisible()) {
+ return false;
+ }
+
+ var location = this.getTouchLocation(touch);
+ this.updateLayoutUsingTouchLocation(location);
+ this._touchInsideFlag = true;
+
+ if (this._autorepeat) {
+ this.startAutorepeat();
+ }
+
+ return true;
+ },
+
+ onTouchMoved:function (touch, event) {
+ if (this.isTouchInside(touch)) {
+ var location = this.getTouchLocation(touch);
+ this.updateLayoutUsingTouchLocation(location);
+
+ if (!this._touchInsideFlag) {
+ this._touchInsideFlag = true;
+
+ if (this._autorepeat) {
+ this.startAutorepeat();
+ }
+ }
+ } else {
+ this._touchInsideFlag = false;
+ this._touchedPart = cc.CONTROL_STEPPER_PARTNONE;
+ this._minusSprite.setColor(cc.color.WHITE);
+ this._plusSprite.setColor(cc.color.WHITE);
+ if (this._autorepeat) {
+ this.stopAutorepeat();
+ }
+ }
+ },
+
+ onTouchEnded:function (touch, event) {
+ this._minusSprite.setColor(cc.color.WHITE);
+ this._plusSprite.setColor(cc.color.WHITE);
+
+ if (this._autorepeat) {
+ this.stopAutorepeat();
+ }
+
+ if (this.isTouchInside(touch)) {
+ var location = this.getTouchLocation(touch);
+ this.setValue(this._value + ((location.x < this._minusSprite.getContentSize().width) ? (0.0 - this._stepValue) : this._stepValue));
+ }
+ },
+ setMinusSprite:function (sprite) {
+ this._minusSprite = sprite;
+ },
+ getMinusSprite:function () {
+ return this._minusSprite;
+ },
+ setPlusSprite:function (sprite) {
+ this._plusSprite = sprite;
+ },
+ getPlusSprite:function () {
+ return this._plusSprite;
+ },
+ setMinusLabel:function (sprite) {
+ this._minusLabel = sprite;
+ },
+ getMinusLabel:function () {
+ return this._minusLabel;
+ },
+ setPlusLabel:function (sprite) {
+ this._plusLabel = sprite;
+ },
+ getPlusLabel:function () {
+ return this._plusLabel;
+ }
+});
+
+var _p = cc.ControlStepper.prototype;
+
+// Extedned properties
+/** @expose */
+_p.wraps;
+cc.defineGetterSetter(_p, "wraps", _p.getWraps, _p.setWraps);
+/** @expose */
+_p.value;
+cc.defineGetterSetter(_p, "value", _p.getValue, _p.setValue);
+/** @expose */
+_p.minValue;
+cc.defineGetterSetter(_p, "minValue", _p.getMinimumValue, _p.setMinimumValue);
+/** @expose */
+_p.maxValue;
+cc.defineGetterSetter(_p, "maxValue", _p.getMaximumValue, _p.setMaximumValue);
+/** @expose */
+_p.stepValue;
+cc.defineGetterSetter(_p, "stepValue", _p.getStepValue, _p.setStepValue);
+/** @expose */
+_p.continuous;
+cc.defineGetterSetter(_p, "continuous", _p.isContinuous);
+/** @expose */
+_p.minusSprite;
+cc.defineGetterSetter(_p, "minusSprite", _p.getMinusSprite, _p.setMinusSprite);
+/** @expose */
+_p.plusSprite;
+cc.defineGetterSetter(_p, "plusSprite", _p.getPlusSprite, _p.setPlusSprite);
+/** @expose */
+_p.minusLabel;
+cc.defineGetterSetter(_p, "minusLabel", _p.getMinusLabel, _p.setMinusLabel);
+/** @expose */
+_p.plusLabel;
+cc.defineGetterSetter(_p, "plusLabel", _p.getPlusLabel, _p.setPlusLabel);
+
+_p = null;
+
+/**
+ * Creates a cc.ControlStepper
+ * @param {cc.Sprite} minusSprite
+ * @param {cc.Sprite} plusSprite
+ * @returns {ControlStepper}
+ */
+cc.ControlStepper.create = function (minusSprite, plusSprite) {
+ return new cc.ControlStepper(minusSprite, plusSprite);
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlSwitch.js b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlSwitch.js
new file mode 100644
index 0000000..99b7368
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlSwitch.js
@@ -0,0 +1,425 @@
+/**
+ *
+ * Copyright (c) 2008-2010 Ricardo Quesada
+ * Copyright (c) 2011-2012 cocos2d-x.org
+ * Copyright (c) 2013-2014 Chukong Technologies Inc.
+ *
+ * Copyright 2011 Yannick Loriot. All rights reserved.
+ * http://yannickloriot.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * CCControlSwitch: Switch control ui component
+ * @class
+ * @extends cc.Control
+ */
+cc.ControlSwitch = cc.Control.extend(/** @lends cc.ControlSwitch# */{
+ /** Sprite which represents the view. */
+ _switchSprite:null,
+ _initialTouchXPosition:0,
+
+ _moved:false,
+ /** A Boolean value that determines the off/on state of the switch. */
+ _on:false,
+ _className:"ControlSwitch",
+ ctor:function (maskSprite, onSprite, offSprite, thumbSprite, onLabel, offLabel) {
+ cc.Control.prototype.ctor.call(this);
+
+ offLabel && this.initWithMaskSprite(maskSprite, onSprite, offSprite, thumbSprite, onLabel, offLabel);
+ },
+
+ /** Creates a switch with a mask sprite, on/off sprites for on/off states, a thumb sprite and an on/off labels. */
+ initWithMaskSprite:function (maskSprite, onSprite, offSprite, thumbSprite, onLabel, offLabel) {
+ if(!maskSprite)
+ throw new Error("cc.ControlSwitch.initWithMaskSprite(): maskSprite should be non-null.");
+ if(!onSprite)
+ throw new Error("cc.ControlSwitch.initWithMaskSprite(): onSprite should be non-null.");
+ if(!offSprite)
+ throw new Error("cc.ControlSwitch.initWithMaskSprite(): offSprite should be non-null.");
+ if(!thumbSprite)
+ throw new Error("cc.ControlSwitch.initWithMaskSprite(): thumbSprite should be non-null.");
+ if (this.init()) {
+ this._on = true;
+
+ this._switchSprite = new cc.ControlSwitchSprite();
+ this._switchSprite.initWithMaskSprite(maskSprite, onSprite, offSprite, thumbSprite, onLabel, offLabel);
+ this._switchSprite.setPosition(this._switchSprite.getContentSize().width / 2, this._switchSprite.getContentSize().height / 2);
+ this.addChild(this._switchSprite);
+
+ this.ignoreAnchorPointForPosition(false);
+ this.setAnchorPoint(0.5, 0.5);
+ this.setContentSize(this._switchSprite.getContentSize());
+ return true;
+ }
+ return false;
+ },
+
+ setOn:function (isOn, animated) {
+ animated = animated || false;
+ this._on = isOn;
+ var xPosition = (this._on) ? this._switchSprite.getOnPosition() : this._switchSprite.getOffPosition();
+ if(animated){
+ this._switchSprite.runAction(new cc.ActionTween(0.2, "sliderXPosition", this._switchSprite.getSliderXPosition(),xPosition));
+ }else{
+ this._switchSprite.setSliderXPosition(xPosition);
+ }
+ this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED);
+ },
+
+ isOn:function () {
+ return this._on;
+ },
+
+ hasMoved:function () {
+ return this._moved;
+ },
+
+ setEnabled:function (enabled) {
+ this._enabled = enabled;
+
+ this._switchSprite.setOpacity((enabled) ? 255 : 128);
+ },
+
+ locationFromTouch:function (touch) {
+ var touchLocation = touch.getLocation(); // Get the touch position
+ touchLocation = this.convertToNodeSpace(touchLocation); // Convert to the node space of this class
+
+ return touchLocation;
+ },
+
+ onTouchBegan:function (touch, event) {
+ if (!this.isTouchInside(touch) || !this.isEnabled()|| !this.isVisible()) {
+ return false;
+ }
+
+ this._moved = false;
+
+ var location = this.locationFromTouch(touch);
+
+ this._initialTouchXPosition = location.x - this._switchSprite.getSliderXPosition();
+
+ this._switchSprite.getThumbSprite().setColor(cc.color.GRAY);
+ this._switchSprite.needsLayout();
+
+ return true;
+ },
+
+ onTouchMoved:function (touch, event) {
+ var location = this.locationFromTouch(touch);
+ location = cc.p(location.x - this._initialTouchXPosition, 0);
+
+ this._moved = true;
+
+ this._switchSprite.setSliderXPosition(location.x);
+ },
+
+ onTouchEnded:function (touch, event) {
+ var location = this.locationFromTouch(touch);
+
+ this._switchSprite.getThumbSprite().setColor(cc.color.WHITE);
+
+ if (this.hasMoved()) {
+ this.setOn(!(location.x < this._switchSprite.getContentSize().width / 2), true);
+ } else {
+ this.setOn(!this._on, true);
+ }
+ },
+
+ onTouchCancelled:function (touch, event) {
+ var location = this.locationFromTouch(touch);
+
+ this._switchSprite.getThumbSprite().setColor(cc.color.WHITE);
+
+ if (this.hasMoved()) {
+ this.setOn(!(location.x < this._switchSprite.getContentSize().width / 2), true);
+ } else {
+ this.setOn(!this._on, true);
+ }
+ }
+});
+
+/** Creates a switch with a mask sprite, on/off sprites for on/off states and a thumb sprite.
+ * @deprecated
+ */
+cc.ControlSwitch.create = function (maskSprite, onSprite, offSprite, thumbSprite, onLabel, offLabel) {
+ return new cc.ControlSwitch(maskSprite, onSprite, offSprite, thumbSprite, onLabel, offLabel);
+};
+
+/**
+ * ControlSwitchSprite: Sprite switch control ui component
+ * @class
+ * @extends cc.Sprite
+ *
+ * @property {Number} sliderX - Slider's x position
+ * @property {cc.Point} onPos - The position of slider when switch is on
+ * @property {cc.Point} offPos - The position of slider when switch is off
+ * @property {cc.Texture2D} maskTexture - The texture of the mask
+ * @property {cc.Point} texturePos - The position of the texture
+ * @property {cc.Point} maskPos - The position of the mask
+ * @property {cc.Sprite} onSprite - The sprite of switch on
+ * @property {cc.Sprite} offSprite - The sprite of switch off
+ * @property {cc.Sprite} thumbSprite - The thumb sprite of the switch control
+ * @property {cc.LabelTTF} onLabel - The sprite of switch on
+ * @property {cc.LabelTTF} offLabel - The sprite of switch off
+ * @property {Number} onSideWidth - <@readonly> The width of the on side of the switch control
+ * @property {Number} offSideWidth - <@readonly> The width of the off side of the switch control
+ */
+cc.ControlSwitchSprite = cc.Sprite.extend({
+ _sliderXPosition:0,
+ _onPosition:0,
+ _offPosition:0,
+
+ _textureLocation:0,
+ _maskLocation:0,
+ _maskSize:null,
+
+ _onSprite:null,
+ _offSprite:null,
+ _thumbSprite:null,
+ _onLabel:null,
+ _offLabel:null,
+ _clipper:null,
+ _stencil:null,
+ _backRT:null,
+
+ ctor:function () {
+ cc.Sprite.prototype.ctor.call(this);
+ this._sliderXPosition = 0;
+ this._onPosition = 0;
+ this._offPosition = 0;
+ this._maskLocation = 0;
+ this._maskSize = cc.size(0, 0);
+ this._onSprite = null;
+ this._offSprite = null;
+ this._thumbSprite = null;
+ this._onLabel = null;
+ this._offLabel = null;
+ },
+
+ initWithMaskSprite:function (maskSprite, onSprite, offSprite, thumbSprite, onLabel, offLabel) {
+ if (cc.Sprite.prototype.init.call(this)) {
+ this.setSpriteFrame(maskSprite.displayFrame());
+ // Sets the default values
+ this._onPosition = 0;
+ this._offPosition = -onSprite.getContentSize().width + thumbSprite.getContentSize().width / 2;
+ this._sliderXPosition = this._onPosition;
+
+ this.setOnSprite(onSprite);
+ this.setOffSprite(offSprite);
+ this.setThumbSprite(thumbSprite);
+ this.setOnLabel(onLabel);
+ this.setOffLabel(offLabel);
+
+ // Set up the mask with the Mask shader
+ this._stencil = maskSprite;
+ var maskSize = this._maskSize = this._stencil.getContentSize();
+ this._stencil.setPosition(0, 0);
+
+ // Init clipper for mask
+ this._clipper = new cc.ClippingNode();
+ this._clipper.setAnchorPoint(0.5, 0.5);
+ this._clipper.setPosition(maskSize.width / 2, maskSize.height / 2);
+ this._clipper.setStencil(this._stencil);
+ this.addChild(this._clipper);
+
+ this._clipper.addChild(onSprite);
+ this._clipper.addChild(offSprite);
+ this._clipper.addChild(onLabel);
+ this._clipper.addChild(offLabel);
+
+ this.addChild(this._thumbSprite);
+
+ this.needsLayout();
+ return true;
+ }
+ return false;
+ },
+
+ needsLayout:function () {
+ var maskSize = this._maskSize;
+ this._onSprite.setPosition(
+ this._onSprite.getContentSize().width / 2 + this._sliderXPosition - maskSize.width / 2,
+ this._onSprite.getContentSize().height / 2 - maskSize.height / 2
+ );
+ this._offSprite.setPosition(
+ this._onSprite.getContentSize().width + this._offSprite.getContentSize().width / 2 + this._sliderXPosition - maskSize.width / 2,
+ this._offSprite.getContentSize().height / 2 - maskSize.height / 2
+ );
+
+ if (this._onLabel) {
+ this._onLabel.setPosition(
+ this._onSprite.getPositionX() - this._thumbSprite.getContentSize().width / 6,
+ this._onSprite.getContentSize().height / 2 - maskSize.height / 2
+ );
+ }
+ if (this._offLabel) {
+ this._offLabel.setPosition(
+ this._offSprite.getPositionX() + this._thumbSprite.getContentSize().width / 6,
+ this._offSprite.getContentSize().height / 2 - maskSize.height / 2
+ );
+ }
+ this._thumbSprite.setPosition(
+ this._onSprite.getContentSize().width + this._sliderXPosition,
+ this._maskSize.height / 2
+ );
+ },
+
+ setSliderXPosition:function (sliderXPosition) {
+ if (sliderXPosition <= this._offPosition) {
+ // Off
+ sliderXPosition = this._offPosition;
+ } else if (sliderXPosition >= this._onPosition) {
+ // On
+ sliderXPosition = this._onPosition;
+ }
+
+ this._sliderXPosition = sliderXPosition;
+
+ this.needsLayout();
+ },
+ getSliderXPosition:function () {
+ return this._sliderXPosition;
+ },
+
+ _getOnSideWidth:function () {
+ return this._onSprite.getContentSize().width;
+ },
+
+ _getOffSideWidth:function () {
+ return this._offSprite.getContentSize().height;
+ },
+
+ updateTweenAction:function (value, key) {
+ if (key === "sliderXPosition")
+ this.setSliderXPosition(value);
+ },
+
+ setOnPosition:function (onPosition) {
+ this._onPosition = onPosition;
+ },
+ getOnPosition:function () {
+ return this._onPosition;
+ },
+
+ setOffPosition:function (offPosition) {
+ this._offPosition = offPosition;
+ },
+ getOffPosition:function () {
+ return this._offPosition;
+ },
+
+ setMaskTexture:function (maskTexture) {
+ this._stencil.setTexture(maskTexture);
+ },
+ getMaskTexture:function () {
+ return this._stencil.getTexture();
+ },
+
+ setTextureLocation:function (textureLocation) {
+ this._textureLocation = textureLocation;
+ },
+ getTextureLocation:function () {
+ return this._textureLocation;
+ },
+
+ setMaskLocation:function (maskLocation) {
+ this._maskLocation = maskLocation;
+ },
+ getMaskLocation:function () {
+ return this._maskLocation;
+ },
+
+ setOnSprite:function (onSprite) {
+ this._onSprite = onSprite;
+ },
+ getOnSprite:function () {
+ return this._onSprite;
+ },
+
+ setOffSprite:function (offSprite) {
+ this._offSprite = offSprite;
+ },
+ getOffSprite:function () {
+ return this._offSprite;
+ },
+
+ setThumbSprite:function (thumbSprite) {
+ this._thumbSprite = thumbSprite;
+ },
+ getThumbSprite:function () {
+ return this._thumbSprite;
+ },
+
+ setOnLabel:function (onLabel) {
+ this._onLabel = onLabel;
+ },
+ getOnLabel:function () {
+ return this._onLabel;
+ },
+
+ setOffLabel:function (offLabel) {
+ this._offLabel = offLabel;
+ },
+ getOffLabel:function () {
+ return this._offLabel;
+ }
+});
+
+var _p = cc.ControlSwitchSprite.prototype;
+
+/** @expose */
+_p.sliderX;
+cc.defineGetterSetter(_p, "sliderX", _p.getSliderXPosition, _p.setSliderXPosition);
+/** @expose */
+_p.onPos;
+cc.defineGetterSetter(_p, "onPos", _p.getOnPosition, _p.setOnPosition);
+/** @expose */
+_p.offPos;
+cc.defineGetterSetter(_p, "offPos", _p.getOffPosition, _p.setOffPosition);
+/** @expose */
+_p.maskTexture;
+cc.defineGetterSetter(_p, "maskTexture", _p.getMaskTexture, _p.setMaskTexture);
+/** @expose */
+_p.maskPos;
+cc.defineGetterSetter(_p, "maskPos", _p.getMaskLocation, _p.setMaskLocation);
+/** @expose */
+_p.onSprite;
+cc.defineGetterSetter(_p, "onSprite", _p.getOnSprite, _p.setOnSprite);
+/** @expose */
+_p.offSprite;
+cc.defineGetterSetter(_p, "offSprite", _p.getOffSprite, _p.setOffSprite);
+/** @expose */
+_p.thumbSprite;
+cc.defineGetterSetter(_p, "thumbSprite", _p.getThumbSprite, _p.setThumbSprite);
+/** @expose */
+_p.onLabel;
+cc.defineGetterSetter(_p, "onLabel", _p.getOnLabel, _p.setOnLabel);
+/** @expose */
+_p.offLabel;
+cc.defineGetterSetter(_p, "offLabel", _p.getOffLabel, _p.setOffLabel);
+/** @expose */
+_p.onSideWidth;
+cc.defineGetterSetter(_p, "onSideWidth", _p._getOnSideWidth);
+/** @expose */
+_p.offSideWidth;
+cc.defineGetterSetter(_p, "offSideWidth", _p._getOffSideWidth);
+
+_p = null;
diff --git a/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlUtils.js b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlUtils.js
new file mode 100644
index 0000000..5e803bd
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCControlUtils.js
@@ -0,0 +1,177 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ Copyright 2012 Stewart Hamilton-Arrandale.
+ http://creativewax.co.uk
+
+ Modified by Yannick Loriot.
+ http://yannickloriot.com
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * An RGBA color class, its value present as percent
+ * @param {Number} r
+ * @param {Number} g
+ * @param {Number} b
+ * @param {Number} a
+ * @constructor
+ */
+cc.RGBA = function(r,g,b,a){
+ this.r = r ; // percent
+ this.g = g ; // percent
+ this.b = b ; // percent
+ this.a = a ; // percent
+};
+
+cc.HSV = function(h,s,v){
+ this.h = h ; // angle in degrees
+ this.s = s ; // percent
+ this.v = v ; // percent
+};
+
+cc.ControlUtils = {};
+
+cc.ControlUtils.addSpriteToTargetWithPosAndAnchor = function(spriteName,target,pos,anchor){
+ var sprite = new cc.Sprite("#" + spriteName);
+
+ if (!sprite)
+ return null;
+
+ sprite.setPosition(pos);
+ sprite.setAnchorPoint(anchor);
+ target.addChild(sprite);
+ return sprite;
+};
+
+cc.ControlUtils.HSVfromRGB = function(rgbaValue){
+ var out = new cc.HSV();
+ var min, max, delta;
+
+ min = rgbaValue.r < rgbaValue.g ? rgbaValue.r : rgbaValue.g;
+ min = min < rgbaValue.b ? min : rgbaValue.b;
+
+ max = rgbaValue.r > rgbaValue.g ? rgbaValue.r : rgbaValue.g;
+ max = max > rgbaValue.b ? max : rgbaValue.b;
+
+ out.v = max; // v
+ delta = max - min;
+ if( max > 0.0 ){
+ out.s = (delta / max); // s
+ } else {
+ // r = g = b = 0 // s = 0, v is undefined
+ out.s = 0.0;
+ out.h = -1; // its now undefined (don't know if setting to NAN is a good idea)
+ return out;
+ }
+
+ if( rgbaValue.r >= max ){ // > is bogus, just keeps compilor happy
+ out.h = ( rgbaValue.g - rgbaValue.b ) / delta; // between yellow & magenta
+ } else {
+ if( rgbaValue.g >= max )
+ out.h = 2.0 + ( rgbaValue.b - rgbaValue.r ) / delta; // between cyan & yellow
+ else
+ out.h = 4.0 + ( rgbaValue.r - rgbaValue.g ) / delta; // between magenta & cyan
+ }
+
+ out.h *= 60.0; // degrees
+
+ if( out.h < 0.0 )
+ out.h += 360.0;
+
+ return out;
+};
+
+cc.ControlUtils.RGBfromHSV = function(hsvValue){
+ var hh, p, q, t, ff;
+ var i;
+ var out = new cc.RGBA();
+ out.a = 1;
+
+ if (hsvValue.s <= 0.0){ // < is bogus, just shuts up warnings
+
+ if (!hsvValue.h){ // value.h == NAN
+ out.r = hsvValue.v;
+ out.g = hsvValue.v;
+ out.b = hsvValue.v;
+ return out;
+ }
+
+ // error - should never happen
+ out.r = 0.0;
+ out.g = 0.0;
+ out.b = 0.0;
+ return out;
+ }
+
+ hh = hsvValue.h;
+ if(hh >= 360.0)
+ hh = 0.0;
+ hh /= 60.0;
+
+ i = 0 | hh;
+ ff = hh - i;
+ p = hsvValue.v * (1.0 - hsvValue.s);
+ q = hsvValue.v * (1.0 - (hsvValue.s * ff));
+ t = hsvValue.v * (1.0 - (hsvValue.s * (1.0 - ff)));
+
+ switch(i) {
+ case 0:
+ out.r = hsvValue.v;
+ out.g = t;
+ out.b = p;
+ break;
+ case 1:
+ out.r = q;
+ out.g = hsvValue.v;
+ out.b = p;
+ break;
+ case 2:
+ out.r = p;
+ out.g = hsvValue.v;
+ out.b = t;
+ break;
+
+ case 3:
+ out.r = p;
+ out.g = q;
+ out.b = hsvValue.v;
+ break;
+ case 4:
+ out.r = t;
+ out.g = p;
+ out.b = hsvValue.v;
+ break;
+ default:
+ out.r = hsvValue.v;
+ out.g = p;
+ out.b = q;
+ break;
+ }
+ return out;
+};
+
+cc.ControlUtils.CCRectUnion = function(rect1, rect2){
+ return cc.rectUnion(rect1,rect2);
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/gui/control-extension/CCInvocation.js b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCInvocation.js
new file mode 100644
index 0000000..82b0189
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCInvocation.js
@@ -0,0 +1,65 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * An Invocation class
+ * @class
+ * @extends cc.Class
+ */
+cc.Invocation = cc.Class.extend(/** @lends cc.Invocation# */{
+ _action:null,
+ _target:null,
+ _controlEvent:null,
+
+ ctor:function(target,action,controlEvent){
+ this._target=target;
+ this._action=action;
+ this._controlEvent=controlEvent;
+ },
+
+ getAction:function(){
+ return this._action;
+ },
+
+ getTarget:function(){
+ return this._target ;
+ },
+
+ getControlEvent:function(){
+ return this._controlEvent;
+ },
+
+ invoke:function(sender){
+ if (this._target && this._action) {
+ if (cc.isString(this._action)) {
+ this._target[this._action](sender, this._controlEvent);
+ } else{
+ this._action.call(this._target, sender, this._controlEvent);
+ }
+ }
+ }
+});
+
diff --git a/frameworks/cocos2d-html5/extensions/gui/control-extension/CCMenuPassive.js b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCMenuPassive.js
new file mode 100644
index 0000000..82a3fd3
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/control-extension/CCMenuPassive.js
@@ -0,0 +1,415 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The Spacer class
+ * @class
+ * @extends cc.Layer
+ */
+cc.Spacer = cc.Layer.extend(/** @lends cc.Spacer */{});
+
+cc.Spacer.verticalSpacer = function (space) {
+ var pRet = new cc.Spacer();
+ pRet.init();
+ pRet.setContentSize(0, space);
+ return pRet;
+};
+
+cc.Spacer.horizontalSpacer = function (space) {
+ var pRet = new cc.Spacer();
+ pRet.init();
+ pRet.setContentSize(space, 0);
+ return pRet;
+};
+
+/**
+ * MenuPassive: The menu passive ui component
+ * @class
+ * @extends cc.Layer
+ */
+cc.MenuPassive = cc.Layer.extend(/** @lends cc.MenuPassive# */{
+
+ _color:null,
+ _opacity:0,
+ _className:"MenuPassive",
+
+ ctor:function () {
+ },
+
+ /** Color: conforms with CCRGBAProtocol protocol */
+ getColor:function () {
+ var locColor = this._color;
+ return cc.color(locColor.r, locColor.g, locColor.b, locColor.a);
+ },
+ setColor:function (color) {
+ var locColor = this._color;
+ locColor.r = color.r;
+ locColor.g = color.g;
+ locColor.b = color.b;
+
+ if (this._children && this._children.length > 0) {
+ for (var i = 0; i < this._children.length; i++) {
+ if (this._children[i]) {
+ this._children[i].setColor(color);
+ }
+ }
+ }
+ if (color.a !== undefined && !color.a_undefined) {
+ this.setOpacity(color.a);
+ }
+ },
+
+ /** Opacity: conforms with CCRGBAProtocol protocol */
+ getOpacity:function () {
+ return this._opacity;
+ },
+
+ setOpacity:function (opacity) {
+ this._opacity = opacity;
+
+ if (this._children && this._children.length > 0) {
+ for (var i = 0; i < this._children.length; i++) {
+ if (this._children[i]) {
+ this._children[i].setOpacity(opacity);
+ }
+ }
+ }
+
+ this._color.a = opacity;
+ },
+
+ /** initializes a CCMenu with it's items */
+ initWithItems:function (item, args) {
+ if (this.init()) {
+ //this.m_bIsTouchEnabled = false;
+
+ // menu in the center of the screen
+ var winSize = cc.director.getWinSize();
+
+ // Set the default anchor point
+ this.ignoreAnchorPointForPosition(true);
+ this.setAnchorPoint(0.5, 0.5);
+ this.setContentSize(winSize);
+
+ this.setPosition(winSize.width / 2, winSize.height / 2);
+ var z = 0;
+
+ if (item) {
+ this.addChild(item, z);
+ for (var i = 0; i < args.length; i++) {
+ if (args[i]) {
+ z++;
+ this.addChild(args[i], z);
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ },
+
+ /** align items vertically */
+ alignItemsVertically:function () {
+ this.alignItemsVerticallyWithPadding(cc.DEFAULT_PADDING);
+ },
+
+ /** align items vertically with padding
+ @since v0.7.2
+ */
+ alignItemsVerticallyWithPadding:function (padding) {
+ var height = -padding;
+
+ var i;
+ if (this._children && this._children.length > 0) {
+ for (i = 0; i < this._children.length; i++) {
+ if (this._children[i]) {
+ height += this._children[i].getContentSize().height * this._children[i].getScaleY() + padding;
+ }
+ }
+ }
+
+ var width = 0;
+ var y = height / 2.0;
+ if (this._children && this._children.length > 0) {
+ for (i = 0; i < this._children.length; i++) {
+ if (this._children[i]) {
+ width = Math.max(width, this._children[i].getContentSize().width);
+ this._children[i].setPosition(0, y - this._children[i].getContentSize().height * this._children[i].getScaleY() / 2.0);
+ y -= this._children[i].getContentSize().height * this._children[i].getScaleY() + padding;
+ }
+ }
+ }
+ this.setContentSize(width, height);
+ },
+
+ /** align items horizontally */
+ alignItemsHorizontally:function () {
+ this.alignItemsHorizontallyWithPadding(cc.DEFAULT_PADDING);
+ },
+
+ /** align items horizontally with padding
+ @since v0.7.2
+ */
+ alignItemsHorizontallyWithPadding:function (padding) {
+ var width = -padding;
+ var i;
+ if (this._children && this._children.length > 0) {
+ for (i = 0; i < this._children.length; i++) {
+ if (this._children[i]) {
+ width += this._children[i].getContentSize().width * this._children[i].getScaleX() + padding;
+ }
+ }
+ }
+
+ var height = 0;
+ var x = -width / 2.0;
+ if (this._children && this._children.length > 0) {
+ for (i = 0; i < this._children.length; i++) {
+ if (this._children[i]) {
+ height = Math.max(height, this._children[i].getContentSize().height);
+ this._children[i].setPosition(x + this._children[i].getContentSize().width * this._children[i].getScaleX() / 2.0, 0);
+ x += this._children[i].getContentSize().width * this._children[i].getScaleX() + padding;
+ }
+ }
+ }
+ this.setContentSize(width, height);
+ },
+
+ /** align items in rows of columns */
+ alignItemsInColumns:function (columns) {
+ var rows = [];
+ var i;
+ for (i = 1; i < arguments.length; i++) {
+ rows.push(arguments[i]);
+ }
+
+ var height = -5;
+ var row = 0;
+ var rowHeight = 0;
+ var columnsOccupied = 0;
+ var rowColumns;
+
+ var tmp;
+ if (this._children && this._children.length > 0) {
+ for (i = 0; i < this._children.length; i++) {
+ if (this._children[i]) {
+ if(row >= rows.length){
+ cc.log("cc.MenuPassive.alignItemsInColumns(): invalid row index");
+ continue;
+ }
+
+ rowColumns = rows[row];
+ // can not have zero columns on a row
+ if(!rowColumns) {
+ cc.log("cc.MenuPassive.alignItemsInColumns(): can not have zero columns on a row");
+ continue;
+ }
+
+ tmp = this._children[i].getContentSize().height;
+ rowHeight = 0 | ((rowHeight >= tmp || (tmp == null)) ? rowHeight : tmp);
+
+ ++columnsOccupied;
+ if (columnsOccupied >= rowColumns) {
+ height += rowHeight + 5;
+
+ columnsOccupied = 0;
+ rowHeight = 0;
+ ++row;
+ }
+ }
+ }
+ }
+
+ // check if too many rows/columns for available menu items
+ //cc.assert(!columnsOccupied, ""); //?
+
+ var winSize = cc.director.getWinSize();
+
+ row = 0;
+ rowHeight = 0;
+ rowColumns = 0;
+ var w = 0.0;
+ var x = 0.0;
+ var y = (height / 2);
+ if (this._children && this._children.length > 0) {
+ for (i = 0; i < this._children.length; i++) {
+ if (this._children[i]) {
+ if (rowColumns === 0) {
+ rowColumns = rows[row];
+ w = winSize.width / (1 + rowColumns);
+ x = w;
+ }
+
+ tmp = this._children[i].getContentSize().height;
+ rowHeight = 0 | ((rowHeight >= tmp || (tmp == null)) ? rowHeight : tmp);
+
+ this._children[i].setPosition(x - winSize.width / 2,
+ y - this._children[i].getContentSize().height / 2);
+
+ x += w;
+ ++columnsOccupied;
+
+ if (columnsOccupied >= rowColumns) {
+ y -= rowHeight + 5;
+
+ columnsOccupied = 0;
+ rowColumns = 0;
+ rowHeight = 0;
+ ++row;
+ }
+ }
+ }
+ }
+ },
+
+ /** align items in columns of rows */
+ alignItemsInRows:function (rows) {
+ var columns = [];
+ var i;
+ for (i = 1; i < arguments.length; i++) {
+ columns.push(arguments[i]);
+ }
+
+ var columnWidths = [];
+ var columnHeights = [];
+
+ var width = -10;
+ var columnHeight = -5;
+ var column = 0;
+ var columnWidth = 0;
+ var rowsOccupied = 0;
+ var columnRows;
+
+ var tmp;
+ if (this._children && this._children.length > 0) {
+ for (i = 0; i < this._children.length; i++) {
+ if (this._children[i]) {
+ // check if too many menu items for the amount of rows/columns
+ if(column >= columns.length){
+ cc.log("cc.MenuPassive.alignItemsInRows(): invalid row index");
+ continue;
+ }
+
+ columnRows = columns[column];
+ // can't have zero rows on a column
+ if(!columnRows) {
+ cc.log("cc.MenuPassive.alignItemsInColumns(): can't have zero rows on a column");
+ continue;
+ }
+
+ // columnWidth = fmaxf(columnWidth, [item contentSize].width);
+ tmp = this._children[i].getContentSize().width;
+ columnWidth = 0 | ((columnWidth >= tmp || (tmp == null)) ? columnWidth : tmp);
+
+ columnHeight += 0 | (this._children[i].getContentSize().height + 5);
+ ++rowsOccupied;
+
+ if (rowsOccupied >= columnRows) {
+ columnWidths.push(columnWidth);
+ columnHeights.push(columnHeight);
+ width += columnWidth + 10;
+
+ rowsOccupied = 0;
+ columnWidth = 0;
+ columnHeight = -5;
+ ++column;
+ }
+ }
+ }
+ }
+
+ // check if too many rows/columns for available menu items.
+ //cc.assert(!rowsOccupied, ""); //?
+
+ var winSize = cc.director.getWinSize();
+
+ column = 0;
+ columnWidth = 0;
+ columnRows = null;
+ var x = (-width / 2);
+ var y = 0.0;
+ if (this._children && this._children.length > 0) {
+ for (i = 0; i < this._children.length; i++) {
+ if (this._children[i]) {
+ if (columnRows == null) {
+ columnRows = columns[column];
+ y = columnHeights[column];
+ }
+
+ // columnWidth = fmaxf(columnWidth, [item contentSize].width);
+ tmp = this._children[i].getContentSize().width;
+ columnWidth = 0 | ((columnWidth >= tmp || (tmp == null)) ? columnWidth : tmp);
+
+ this._children[i].setPosition(x + columnWidths[column] / 2, y - winSize.height / 2);
+
+ y -= this._children[i].getContentSize().height + 10;
+ ++rowsOccupied;
+
+ if (rowsOccupied >= columnRows) {
+ x += columnWidth + 5;
+ rowsOccupied = 0;
+ columnRows = 0;
+ columnWidth = 0;
+ ++column;
+ }
+ }
+ }
+ }
+ },
+
+ //RGBA protocol
+ setOpacityModifyRGB:function (bValue) {
+ },
+ isOpacityModifyRGB:function () {
+ return false;
+ }
+});
+
+/** creates an empty CCMenu */
+cc.MenuPassive.create = function (item) {
+ if (!item) {
+ item = null;
+ }
+
+ var argArr = [];
+ for (var i = 1; i < arguments.length; i++) {
+ argArr.push(arguments[i]);
+ }
+
+ var pRet = new cc.MenuPassive();
+ if (pRet && pRet.initWithItems(item, argArr)) {
+ return pRet;
+ }
+ return null;
+};
+
+/** creates a CCMenu with it's item, then use addChild() to add
+ * other items. It is used for script, it can't init with undetermined
+ * number of variables.
+ */
+cc.MenuPassive.createWithItem = function (item) {
+ return cc.MenuPassive.create(item, null);
+};
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/gui/scrollview/CCScrollView.js b/frameworks/cocos2d-html5/extensions/gui/scrollview/CCScrollView.js
new file mode 100644
index 0000000..bedba0a
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/scrollview/CCScrollView.js
@@ -0,0 +1,850 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2010 Sangwoo Im
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * @ignore
+ */
+cc.SCROLLVIEW_DIRECTION_NONE = -1;
+
+cc.SCROLLVIEW_DIRECTION_HORIZONTAL = 0;
+
+cc.SCROLLVIEW_DIRECTION_VERTICAL = 1;
+
+cc.SCROLLVIEW_DIRECTION_BOTH = 2;
+
+var SCROLL_DEACCEL_RATE = 0.95;
+var SCROLL_DEACCEL_DIST = 1.0;
+var BOUNCE_DURATION = 0.15;
+var INSET_RATIO = 0.2;
+var MOVE_INCH = 7.0 / 160.0;
+var BOUNCE_BACK_FACTOR = 0.35;
+
+cc.convertDistanceFromPointToInch = function (pointDis) {
+ var eglViewer = cc.view;
+ var factor = (eglViewer.getScaleX() + eglViewer.getScaleY()) / 2;
+ return (pointDis * factor) / 160; // CCDevice::getDPI() default value
+};
+
+cc.ScrollViewDelegate = cc.Class.extend({
+ scrollViewDidScroll: function (view) {
+ },
+ scrollViewDidZoom: function (view) {
+ }
+});
+
+/**
+ * ScrollView support for cocos2d -x.
+ * It provides scroll view functionalities to cocos2d projects natively.
+ * @class
+ * @extends cc.Layer
+ *
+ * @property {cc.Point} minOffset - <@readonly> The current container's minimum offset
+ * @property {cc.Point} maxOffset - <@readonly> The current container's maximum offset
+ * @property {Boolean} bounceable - Indicate whether the scroll view is bounceable
+ * @property {cc.Size} viewSize - The size of the scroll view
+ * @property {cc.Layer} container - The inside container of the scroll view
+ * @property {Number} direction - The direction allowed to scroll: cc.SCROLLVIEW_DIRECTION_BOTH by default, or cc.SCROLLVIEW_DIRECTION_NONE | cc.SCROLLVIEW_DIRECTION_HORIZONTAL | cc.SCROLLVIEW_DIRECTION_VERTICAL
+ * @property {cc.ScrollViewDelegate} delegate - The inside container of the scroll view
+ * @property {Boolean} clippingToBounds - Indicate whether the scroll view clips its children
+ */
+cc.ScrollView = cc.Layer.extend(/** @lends cc.ScrollView# */{
+ _zoomScale: 0,
+ _minZoomScale: 0,
+ _maxZoomScale: 0,
+ _delegate: null,
+ _direction: cc.SCROLLVIEW_DIRECTION_BOTH,
+ _dragging: false,
+ _contentOffset: null,
+ _container: null,
+ _touchMoved: false,
+ _maxInset: null,
+ _minInset: null,
+ _bounceable: false,
+ _clippingToBounds: false,
+ _scrollDistance: null,
+ _touchPoint: null,
+ _touchLength: 0,
+ _touches: null,
+ _viewSize: null,
+ _minScale: 0,
+ _maxScale: 0,
+
+ //scissor rect for parent, just for restoring GL_SCISSOR_BOX
+ _parentScissorRect: null,
+ _scissorRestored: false,
+
+ // cache object
+ _tmpViewRect: null,
+ _touchListener: null,
+ _className: "ScrollView",
+
+ /**
+ * @contructor
+ * @param size
+ * @param container
+ * @returns {ScrollView}
+ */
+ ctor: function (size, container) {
+ cc.Layer.prototype.ctor.call(this);
+ this._contentOffset = cc.p(0, 0);
+ this._maxInset = cc.p(0, 0);
+ this._minInset = cc.p(0, 0);
+ this._scrollDistance = cc.p(0, 0);
+ this._touchPoint = cc.p(0, 0);
+ this._touches = [];
+ this._viewSize = cc.size(0, 0);
+ this._parentScissorRect = new cc.Rect(0, 0, 0, 0);
+ this._tmpViewRect = new cc.Rect(0, 0, 0, 0);
+
+ if (container != undefined)
+ this.initWithViewSize(size, container);
+ else
+ this.initWithViewSize(cc.size(200, 200), null);
+
+ },
+
+ init: function () {
+ return this.initWithViewSize(cc.size(200, 200), null);
+ },
+
+ /**
+ * initialized whether success or fail
+ * @param {cc.Size} size
+ * @param {cc.Node} container
+ * @return {Boolean}
+ */
+ initWithViewSize: function (size, container) {
+ var pZero = cc.p(0, 0);
+ if (cc.Layer.prototype.init.call(this)) {
+ if (!container && !this._container) {
+ container = new cc.Layer();
+ }
+ if (container) {
+ this.setContainer(container);
+ }
+ this.setViewSize(size);
+
+ this.setTouchEnabled(true);
+ this._touches.length = 0;
+ this._delegate = null;
+ this._bounceable = true;
+ this._clippingToBounds = true;
+
+ //this._container.setContentSize(CCSizeZero);
+ this._direction = cc.SCROLLVIEW_DIRECTION_BOTH;
+ this._container.setPosition(pZero);
+ this._touchLength = 0.0;
+
+ this._minScale = this._maxScale = 1.0;
+ return true;
+ }
+ return false;
+ },
+
+ visit: function (parent) {
+ var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null;
+
+ // quick return if not visible
+ if (!this._visible) {
+ cmd._propagateFlagsDown(parentCmd);
+ return;
+ }
+
+ var renderer = cc.renderer;
+ cmd.visit(parentCmd);
+
+ if (this._clippingToBounds) {
+ renderer.pushRenderCommand(cmd.startCmd);
+ }
+
+ var i, children = this._children, len = children.length;
+ if (len > 0) {
+ if (this._reorderChildDirty) {
+ this.sortAllChildren();
+ }
+ for (i = 0; i < len; i++) {
+ children[i].visit(this);
+ }
+ }
+
+ if (this._clippingToBounds) {
+ renderer.pushRenderCommand(cmd.endCmd);
+ }
+ cmd._dirtyFlag = 0;
+ },
+
+ /**
+ * Sets a new content offset. It ignores max/min offset. It just sets what's given. (just like UIKit's UIScrollView)
+ *
+ * @param {cc.Point} offset new offset
+ * @param {Number} [animated=] If true, the view will scroll to the new offset
+ */
+ setContentOffset: function (offset, animated) {
+ if (animated) { //animate scrolling
+ this.setContentOffsetInDuration(offset, BOUNCE_DURATION);
+ return;
+ }
+ if (!this._bounceable) {
+ var minOffset = this.minContainerOffset();
+ var maxOffset = this.maxContainerOffset();
+
+ offset.x = Math.max(minOffset.x, Math.min(maxOffset.x, offset.x));
+ offset.y = Math.max(minOffset.y, Math.min(maxOffset.y, offset.y));
+ }
+
+ this._container.setPosition(offset);
+ var locDelegate = this._delegate;
+ if (locDelegate != null && locDelegate.scrollViewDidScroll) {
+ locDelegate.scrollViewDidScroll(this);
+ }
+
+ },
+
+ getContentOffset: function () {
+ var locPos = this._container.getPosition();
+ return cc.p(locPos.x, locPos.y);
+ },
+
+ /**
+ * Sets a new content offset. It ignores max/min offset. It just sets what's given. (just like UIKit's UIScrollView)
+ * You can override the animation duration with this method.
+ *
+ * @param {cc.Point} offset new offset
+ * @param {Number} dt animation duration
+ */
+ setContentOffsetInDuration: function (offset, dt) {
+ var scroll = cc.moveTo(dt, offset);
+ var expire = cc.callFunc(this._stoppedAnimatedScroll, this);
+ this._container.runAction(cc.sequence(scroll, expire));
+ this.schedule(this._performedAnimatedScroll);
+ },
+
+ /**
+ * Sets a new scale and does that for a predefined duration.
+ *
+ * @param {Number} scale a new scale vale
+ * @param {Boolean} [animated=null] if YES, scaling is animated
+ */
+ setZoomScale: function (scale, animated) {
+ if (animated) {
+ this.setZoomScaleInDuration(scale, BOUNCE_DURATION);
+ return;
+ }
+
+ var locContainer = this._container;
+ if (locContainer.getScale() !== scale) {
+ var oldCenter, newCenter;
+ var center;
+
+ if (this._touchLength === 0.0) {
+ var locViewSize = this._viewSize;
+ center = cc.p(locViewSize.width * 0.5, locViewSize.height * 0.5);
+ center = this.convertToWorldSpace(center);
+ } else
+ center = this._touchPoint;
+
+ oldCenter = locContainer.convertToNodeSpace(center);
+ locContainer.setScale(Math.max(this._minScale, Math.min(this._maxScale, scale)));
+ newCenter = locContainer.convertToWorldSpace(oldCenter);
+
+ var offset = cc.pSub(center, newCenter);
+ if (this._delegate && this._delegate.scrollViewDidZoom)
+ this._delegate.scrollViewDidZoom(this);
+ this.setContentOffset(cc.pAdd(locContainer.getPosition(), offset));
+ }
+ },
+
+ getZoomScale: function () {
+ return this._container.getScale();
+ },
+
+ /**
+ * Sets a new scale for container in a given duration.
+ *
+ * @param {Number} s a new scale value
+ * @param {Number} dt animation duration
+ */
+ setZoomScaleInDuration: function (s, dt) {
+ if (dt > 0) {
+ var locScale = this._container.getScale();
+ if (locScale !== s) {
+ var scaleAction = cc.actionTween(dt, "zoomScale", locScale, s);
+ this.runAction(scaleAction);
+ }
+ } else {
+ this.setZoomScale(s);
+ }
+ },
+
+ /**
+ * Returns the current container's minimum offset. You may want this while you animate scrolling by yourself
+ * @return {cc.Point} Returns the current container's minimum offset.
+ */
+ minContainerOffset: function () {
+ var locContainer = this._container;
+ var locContentSize = locContainer.getContentSize(), locViewSize = this._viewSize;
+ return cc.p(locViewSize.width - locContentSize.width * locContainer.getScaleX(),
+ locViewSize.height - locContentSize.height * locContainer.getScaleY());
+ },
+
+ /**
+ * Returns the current container's maximum offset. You may want this while you animate scrolling by yourself
+ * @return {cc.Point} Returns the current container's maximum offset.
+ */
+ maxContainerOffset: function () {
+ return cc.p(0.0, 0.0);
+ },
+
+ /**
+ * Determines if a given node's bounding box is in visible bounds
+ * @param {cc.Node} node
+ * @return {Boolean} YES if it is in visible bounds
+ */
+ isNodeVisible: function (node) {
+ var offset = this.getContentOffset();
+ var size = this.getViewSize();
+ var scale = this.getZoomScale();
+
+ var viewRect = cc.rect(-offset.x / scale, -offset.y / scale, size.width / scale, size.height / scale);
+
+ return cc.rectIntersectsRect(viewRect, node.getBoundingBox());
+ },
+
+ /**
+ * Provided to make scroll view compatible with SWLayer's pause method
+ */
+ pause: function (sender) {
+ this._container.pause();
+ var selChildren = this._container.getChildren();
+ for (var i = 0; i < selChildren.length; i++) {
+ selChildren[i].pause();
+ }
+ this._super();
+ },
+
+ /**
+ * Provided to make scroll view compatible with SWLayer's resume method
+ */
+ resume: function (sender) {
+ var selChildren = this._container.getChildren();
+ for (var i = 0, len = selChildren.length; i < len; i++) {
+ selChildren[i].resume();
+ }
+ this._container.resume();
+ this._super();
+ },
+
+ isDragging: function () {
+ return this._dragging;
+ },
+ isTouchMoved: function () {
+ return this._touchMoved;
+ },
+ isBounceable: function () {
+ return this._bounceable;
+ },
+ setBounceable: function (bounceable) {
+ this._bounceable = bounceable;
+ },
+
+ /**
+ *
+ * size to clip. CCNode boundingBox uses contentSize directly.
+ * It's semantically different what it actually means to common scroll views.
+ * Hence, this scroll view will use a separate size property.
+ *
+ */
+ getViewSize: function () {
+ return this._viewSize;
+ },
+
+ setViewSize: function (size) {
+ this._viewSize = size;
+ cc.Node.prototype.setContentSize.call(this, size);
+ },
+
+ getContainer: function () {
+ return this._container;
+ },
+
+ setContainer: function (container) {
+ // Make sure that 'm_pContainer' has a non-NULL value since there are
+ // lots of logic that use 'm_pContainer'.
+ if (!container)
+ return;
+
+ this.removeAllChildren(true);
+
+ this._container = container;
+ container.ignoreAnchorPointForPosition(false);
+ container.setAnchorPoint(0, 0);
+
+ this.addChild(container);
+ this.setViewSize(this._viewSize);
+ },
+
+ /**
+ * direction allowed to scroll. CCScrollViewDirectionBoth by default.
+ */
+ getDirection: function () {
+ return this._direction;
+ },
+ setDirection: function (direction) {
+ this._direction = direction;
+ },
+
+ getDelegate: function () {
+ return this._delegate;
+ },
+ setDelegate: function (delegate) {
+ this._delegate = delegate;
+ },
+
+ /** override functions */
+ // optional
+ onTouchBegan: function (touch, event) {
+ for (var c = this; c != null; c = c.parent) {
+ if (!c.isVisible())
+ return false;
+ }
+ //var frameOriginal = this.getParent().convertToWorldSpace(this.getPosition());
+ //var frame = cc.rect(frameOriginal.x, frameOriginal.y, this._viewSize.width, this._viewSize.height);
+ var frame = this._getViewRect();
+
+ //dispatcher does not know about clipping. reject touches outside visible bounds.
+ var locContainer = this._container;
+ var locPoint = locContainer.convertToWorldSpace(locContainer.convertTouchToNodeSpace(touch));
+ var locTouches = this._touches;
+ if (locTouches.length > 2 || this._touchMoved || !cc.rectContainsPoint(frame, locPoint))
+ return false;
+
+ locTouches.push(touch);
+ //}
+
+ if (locTouches.length === 1) { // scrolling
+ this._touchPoint = this.convertTouchToNodeSpace(touch);
+ this._touchMoved = false;
+ this._dragging = true; //dragging started
+ this._scrollDistance.x = 0;
+ this._scrollDistance.y = 0;
+ this._touchLength = 0.0;
+ } else if (locTouches.length === 2) {
+ this._touchPoint = cc.pMidpoint(this.convertTouchToNodeSpace(locTouches[0]),
+ this.convertTouchToNodeSpace(locTouches[1]));
+ this._touchLength = cc.pDistance(locContainer.convertTouchToNodeSpace(locTouches[0]),
+ locContainer.convertTouchToNodeSpace(locTouches[1]));
+ this._dragging = false;
+ }
+ return true;
+ },
+
+ onTouchMoved: function (touch, event) {
+ if (!this.isVisible())
+ return;
+
+ this.setNodeDirty();
+
+ if (this._touches.length === 1 && this._dragging) { // scrolling
+ this._touchMoved = true;
+ //var frameOriginal = this.getParent().convertToWorldSpace(this.getPosition());
+ //var frame = cc.rect(frameOriginal.x, frameOriginal.y, this._viewSize.width, this._viewSize.height);
+ var frame = this._getViewRect();
+
+ //var newPoint = this.convertTouchToNodeSpace(this._touches[0]);
+ var newPoint = this.convertTouchToNodeSpace(touch);
+ var moveDistance = cc.pSub(newPoint, this._touchPoint);
+
+ var dis = 0.0, locDirection = this._direction, pos;
+ if (locDirection === cc.SCROLLVIEW_DIRECTION_VERTICAL) {
+ dis = moveDistance.y;
+ pos = this._container.getPositionY();
+ if (!(this.minContainerOffset().y <= pos && pos <= this.maxContainerOffset().y))
+ moveDistance.y *= BOUNCE_BACK_FACTOR;
+ } else if (locDirection === cc.SCROLLVIEW_DIRECTION_HORIZONTAL) {
+ dis = moveDistance.x;
+ pos = this._container.getPositionX();
+ if (!(this.minContainerOffset().x <= pos && pos <= this.maxContainerOffset().x))
+ moveDistance.x *= BOUNCE_BACK_FACTOR;
+ } else {
+ dis = Math.sqrt(moveDistance.x * moveDistance.x + moveDistance.y * moveDistance.y);
+
+ pos = this._container.getPositionY();
+ var _minOffset = this.minContainerOffset(), _maxOffset = this.maxContainerOffset();
+ if (!(_minOffset.y <= pos && pos <= _maxOffset.y))
+ moveDistance.y *= BOUNCE_BACK_FACTOR;
+
+ pos = this._container.getPositionX();
+ if (!(_minOffset.x <= pos && pos <= _maxOffset.x))
+ moveDistance.x *= BOUNCE_BACK_FACTOR;
+ }
+
+ if (!this._touchMoved && Math.abs(cc.convertDistanceFromPointToInch(dis)) < MOVE_INCH) {
+ //CCLOG("Invalid movement, distance = [%f, %f], disInch = %f", moveDistance.x, moveDistance.y);
+ return;
+ }
+
+ if (!this._touchMoved) {
+ moveDistance.x = 0;
+ moveDistance.y = 0;
+ }
+
+ this._touchPoint = newPoint;
+ this._touchMoved = true;
+
+ if (this._dragging) {
+ switch (locDirection) {
+ case cc.SCROLLVIEW_DIRECTION_VERTICAL:
+ moveDistance.x = 0.0;
+ break;
+ case cc.SCROLLVIEW_DIRECTION_HORIZONTAL:
+ moveDistance.y = 0.0;
+ break;
+ default:
+ break;
+ }
+
+ var locPosition = this._container.getPosition();
+ var newX = locPosition.x + moveDistance.x;
+ var newY = locPosition.y + moveDistance.y;
+
+ this._scrollDistance = moveDistance;
+ this.setContentOffset(cc.p(newX, newY));
+ }
+ } else if (this._touches.length === 2 && !this._dragging) {
+ var len = cc.pDistance(this._container.convertTouchToNodeSpace(this._touches[0]),
+ this._container.convertTouchToNodeSpace(this._touches[1]));
+ this.setZoomScale(this.getZoomScale() * len / this._touchLength);
+ }
+ },
+
+ onTouchEnded: function (touch, event) {
+ if (!this.isVisible())
+ return;
+
+ if (this._touches.length === 1 && this._touchMoved)
+ this.schedule(this._deaccelerateScrolling);
+
+ this._touches.length = 0;
+ this._dragging = false;
+ this._touchMoved = false;
+ },
+
+ onTouchCancelled: function (touch, event) {
+ if (!this.isVisible())
+ return;
+
+ this._touches.length = 0;
+ this._dragging = false;
+ this._touchMoved = false;
+ },
+
+ setContentSize: function (size, height) {
+ if (this.getContainer() !== null) {
+ if (height === undefined)
+ this.getContainer().setContentSize(size);
+ else
+ this.getContainer().setContentSize(size, height);
+ this.updateInset();
+ }
+ },
+ _setWidth: function (value) {
+ var container = this.getContainer();
+ if (container !== null) {
+ container._setWidth(value);
+ this.updateInset();
+ }
+ },
+ _setHeight: function (value) {
+ var container = this.getContainer();
+ if (container !== null) {
+ container._setHeight(value);
+ this.updateInset();
+ }
+ },
+
+ getContentSize: function () {
+ return this._container.getContentSize();
+ },
+
+ updateInset: function () {
+ if (this.getContainer() !== null) {
+ var locViewSize = this._viewSize;
+ var tempOffset = this.maxContainerOffset();
+ this._maxInset.x = tempOffset.x + locViewSize.width * INSET_RATIO;
+ this._maxInset.y = tempOffset.y + locViewSize.height * INSET_RATIO;
+ tempOffset = this.minContainerOffset();
+ this._minInset.x = tempOffset.x - locViewSize.width * INSET_RATIO;
+ this._minInset.y = tempOffset.y - locViewSize.height * INSET_RATIO;
+ }
+ },
+
+ /**
+ * Determines whether it clips its children or not.
+ */
+ isClippingToBounds: function () {
+ return this._clippingToBounds;
+ },
+
+ setClippingToBounds: function (clippingToBounds) {
+ this._clippingToBounds = clippingToBounds;
+ },
+
+ addChild: function (child, zOrder, tag) {
+ if (!child)
+ throw new Error("child must not nil!");
+
+ zOrder = zOrder || child.getLocalZOrder();
+ tag = tag || child.getTag();
+
+ //child.ignoreAnchorPointForPosition(false);
+ //child.setAnchorPoint(0, 0);
+ if (this._container !== child) {
+ this._container.addChild(child, zOrder, tag);
+ } else {
+ cc.Layer.prototype.addChild.call(this, child, zOrder, tag);
+ }
+ },
+
+ isTouchEnabled: function () {
+ return this._touchListener !== null;
+ },
+
+ setTouchEnabled: function (e) {
+ if (this._touchListener)
+ cc.eventManager.removeListener(this._touchListener);
+ this._touchListener = null;
+ if (!e) {
+ this._dragging = false;
+ this._touchMoved = false;
+ this._touches.length = 0;
+ } else {
+ var listener = cc.EventListener.create({
+ event: cc.EventListener.TOUCH_ONE_BY_ONE
+ });
+ if (this.onTouchBegan)
+ listener.onTouchBegan = this.onTouchBegan.bind(this);
+ if (this.onTouchMoved)
+ listener.onTouchMoved = this.onTouchMoved.bind(this);
+ if (this.onTouchEnded)
+ listener.onTouchEnded = this.onTouchEnded.bind(this);
+ if (this.onTouchCancelled)
+ listener.onTouchCancelled = this.onTouchCancelled.bind(this);
+ this._touchListener = listener;
+ cc.eventManager.addListener(listener, this);
+ }
+ },
+
+ /**
+ * Init this object with a given size to clip its content.
+ *
+ * @param size view size
+ * @return initialized scroll view object
+ */
+ _initWithViewSize: function (size) {
+ return null;
+ },
+
+ /**
+ * Relocates the container at the proper offset, in bounds of max/min offsets.
+ *
+ * @param animated If YES, relocation is animated
+ */
+ _relocateContainer: function (animated) {
+ var min = this.minContainerOffset();
+ var max = this.maxContainerOffset();
+ var locDirection = this._direction;
+
+ var oldPoint = this._container.getPosition();
+ var newX = oldPoint.x;
+ var newY = oldPoint.y;
+ if (locDirection === cc.SCROLLVIEW_DIRECTION_BOTH || locDirection === cc.SCROLLVIEW_DIRECTION_HORIZONTAL) {
+ newX = Math.max(newX, min.x);
+ newX = Math.min(newX, max.x);
+ }
+
+ if (locDirection === cc.SCROLLVIEW_DIRECTION_BOTH || locDirection === cc.SCROLLVIEW_DIRECTION_VERTICAL) {
+ newY = Math.min(newY, max.y);
+ newY = Math.max(newY, min.y);
+ }
+
+ if (newY !== oldPoint.y || newX !== oldPoint.x) {
+ this.setContentOffset(cc.p(newX, newY), animated);
+ }
+ },
+ /**
+ * implements auto-scrolling behavior. change SCROLL_DEACCEL_RATE as needed to choose
+ * deacceleration speed. it must be less than 1.0.
+ *
+ * @param {Number} dt delta
+ */
+ _deaccelerateScrolling: function (dt) {
+ if (this._dragging) {
+ this.unschedule(this._deaccelerateScrolling);
+ return;
+ }
+
+ var maxInset, minInset;
+ var oldPosition = this._container.getPosition();
+ var locScrollDistance = this._scrollDistance;
+ this._container.setPosition(oldPosition.x + locScrollDistance.x, oldPosition.y + locScrollDistance.y);
+ if (this._bounceable) {
+ maxInset = this._maxInset;
+ minInset = this._minInset;
+ } else {
+ maxInset = this.maxContainerOffset();
+ minInset = this.minContainerOffset();
+ }
+
+ //check to see if offset lies within the inset bounds
+ var newX = this._container.getPositionX();
+ var newY = this._container.getPositionY();
+
+ locScrollDistance.x = locScrollDistance.x * SCROLL_DEACCEL_RATE;
+ locScrollDistance.y = locScrollDistance.y * SCROLL_DEACCEL_RATE;
+
+ this.setContentOffset(cc.p(newX, newY));
+
+ if ((Math.abs(locScrollDistance.x) <= SCROLL_DEACCEL_DIST &&
+ Math.abs(locScrollDistance.y) <= SCROLL_DEACCEL_DIST) ||
+ newY > maxInset.y || newY < minInset.y ||
+ newX > maxInset.x || newX < minInset.x ||
+ newX === maxInset.x || newX === minInset.x ||
+ newY === maxInset.y || newY === minInset.y) {
+ this.unschedule(this._deaccelerateScrolling);
+ this._relocateContainer(true);
+ }
+ },
+ /**
+ * This method makes sure auto scrolling causes delegate to invoke its method
+ */
+ _performedAnimatedScroll: function (dt) {
+ if (this._dragging) {
+ this.unschedule(this._performedAnimatedScroll);
+ return;
+ }
+
+ if (this._delegate && this._delegate.scrollViewDidScroll)
+ this._delegate.scrollViewDidScroll(this);
+ },
+ /**
+ * Expire animated scroll delegate calls
+ */
+ _stoppedAnimatedScroll: function (node) {
+ this.unschedule(this._performedAnimatedScroll);
+ // After the animation stopped, "scrollViewDidScroll" should be invoked, this could fix the bug of lack of tableview cells.
+ if (this._delegate && this._delegate.scrollViewDidScroll) {
+ this._delegate.scrollViewDidScroll(this);
+ }
+ },
+
+ /**
+ * Zoom handling
+ */
+ _handleZoom: function () {
+ },
+
+ _getViewRect: function () {
+ var screenPos = this.convertToWorldSpace(cc.p(0, 0));
+ var locViewSize = this._viewSize;
+
+ var scaleX = this.getScaleX();
+ var scaleY = this.getScaleY();
+
+ for (var p = this._parent; p != null; p = p.getParent()) {
+ scaleX *= p.getScaleX();
+ scaleY *= p.getScaleY();
+ }
+
+ // Support negative scaling. Not doing so causes intersectsRect calls
+ // (eg: to check if the touch was within the bounds) to return false.
+ // Note, CCNode::getScale will assert if X and Y scales are different.
+ if (scaleX < 0) {
+ screenPos.x += locViewSize.width * scaleX;
+ scaleX = -scaleX;
+ }
+ if (scaleY < 0) {
+ screenPos.y += locViewSize.height * scaleY;
+ scaleY = -scaleY;
+ }
+
+ var locViewRect = this._tmpViewRect;
+ locViewRect.x = screenPos.x;
+ locViewRect.y = screenPos.y;
+ locViewRect.width = locViewSize.width * scaleX;
+ locViewRect.height = locViewSize.height * scaleY;
+ return locViewRect;
+ },
+
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) {
+ return new cc.ScrollView.CanvasRenderCmd(this);
+ } else {
+ return new cc.ScrollView.WebGLRenderCmd(this);
+ }
+ }
+});
+
+var _p = cc.ScrollView.prototype;
+
+// Extended properties
+/** @expose */
+_p.minOffset;
+cc.defineGetterSetter(_p, "minOffset", _p.minContainerOffset);
+/** @expose */
+_p.maxOffset;
+cc.defineGetterSetter(_p, "maxOffset", _p.maxContainerOffset);
+/** @expose */
+_p.bounceable;
+cc.defineGetterSetter(_p, "bounceable", _p.isBounceable, _p.setBounceable);
+/** @expose */
+_p.viewSize;
+cc.defineGetterSetter(_p, "viewSize", _p.getViewSize, _p.setViewSize);
+/** @expose */
+_p.container;
+cc.defineGetterSetter(_p, "container", _p.getContainer, _p.setContainer);
+/** @expose */
+_p.direction;
+cc.defineGetterSetter(_p, "direction", _p.getDirection, _p.setDirection);
+/** @expose */
+_p.delegate;
+cc.defineGetterSetter(_p, "delegate", _p.getDelegate, _p.setDelegate);
+/** @expose */
+_p.clippingToBounds;
+cc.defineGetterSetter(_p, "clippingToBounds", _p.isClippingToBounds, _p.setClippingToBounds);
+
+_p = null;
+
+/**
+ * Returns an autoreleased scroll view object.
+ * @deprecated
+ * @param {cc.Size} size view size
+ * @param {cc.Node} container parent object
+ * @return {cc.ScrollView} scroll view object
+ */
+cc.ScrollView.create = function (size, container) {
+ return new cc.ScrollView(size, container);
+};
diff --git a/frameworks/cocos2d-html5/extensions/gui/scrollview/CCScrollViewCanvasRenderCmd.js b/frameworks/cocos2d-html5/extensions/gui/scrollview/CCScrollViewCanvasRenderCmd.js
new file mode 100644
index 0000000..0cc063f
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/scrollview/CCScrollViewCanvasRenderCmd.js
@@ -0,0 +1,64 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ cc.ScrollView.CanvasRenderCmd = function (renderable) {
+ this._layerCmdCtor(renderable);
+ this._needDraw = false;
+
+ this.startCmd = new cc.CustomRenderCmd(this, this._startCmd);
+ this.startCmd._canUseDirtyRegion = true;
+ this.endCmd = new cc.CustomRenderCmd(this, this._endCmd);
+ this.endCmd._canUseDirtyRegion = true;
+ };
+
+ var proto = cc.ScrollView.CanvasRenderCmd.prototype = Object.create(cc.Layer.CanvasRenderCmd.prototype);
+ proto.constructor = cc.ScrollView.CanvasRenderCmd;
+
+ proto._startCmd = function (ctx, scaleX, scaleY) {
+ var node = this._node;
+ var wrapper = ctx || cc._renderContext, context = wrapper.getContext();
+ wrapper.save();
+
+ if (node._clippingToBounds) {
+ this._scissorRestored = false;
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+
+ var locScaleX = node.getScaleX(), locScaleY = node.getScaleY();
+
+ var getWidth = (node._viewSize.width * locScaleX);
+ var getHeight = (node._viewSize.height * locScaleY);
+
+ context.beginPath();
+ context.rect(0, 0, getWidth, -getHeight);
+ context.closePath();
+ context.clip();
+ }
+ };
+
+ proto._endCmd = function (wrapper) {
+ wrapper = wrapper || cc._renderContext;
+ wrapper.restore();
+ };
+})();
diff --git a/frameworks/cocos2d-html5/extensions/gui/scrollview/CCScrollViewWebGLRenderCmd.js b/frameworks/cocos2d-html5/extensions/gui/scrollview/CCScrollViewWebGLRenderCmd.js
new file mode 100644
index 0000000..3d837db
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/scrollview/CCScrollViewWebGLRenderCmd.js
@@ -0,0 +1,71 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+ cc.ScrollView.WebGLRenderCmd = function (renderable) {
+ this._layerCmdCtor(renderable);
+ this._needDraw = false;
+
+ this.startCmd = new cc.CustomRenderCmd(this, this._startCmd);
+ this.endCmd = new cc.CustomRenderCmd(this, this._endCmd);
+ };
+
+ var proto = cc.ScrollView.WebGLRenderCmd.prototype = Object.create(cc.Layer.WebGLRenderCmd.prototype);
+ proto.constructor = cc.ScrollView.WebGLRenderCmd;
+
+ proto._startCmd = function () {
+ var node = this._node;
+ var EGLViewer = cc.view;
+ var frame = node._getViewRect();
+ if (EGLViewer.isScissorEnabled()) {
+ node._scissorRestored = true;
+ node._parentScissorRect = EGLViewer.getScissorRect();
+ //set the intersection of m_tParentScissorRect and frame as the new scissor rect
+ if (cc.rectIntersection(frame, node._parentScissorRect)) {
+ var locPSRect = node._parentScissorRect;
+ var x = Math.max(frame.x, locPSRect.x);
+ var y = Math.max(frame.y, locPSRect.y);
+ var xx = Math.min(frame.x + frame.width, locPSRect.x + locPSRect.width);
+ var yy = Math.min(frame.y + frame.height, locPSRect.y + locPSRect.height);
+ EGLViewer.setScissorInPoints(x, y, xx - x, yy - y);
+ }
+ } else {
+ var ctx = cc._renderContext;
+ ctx.enable(ctx.SCISSOR_TEST);
+ //clip
+ EGLViewer.setScissorInPoints(frame.x, frame.y, frame.width, frame.height);
+ }
+ };
+
+ proto._endCmd = function () {
+ var node = this._node;
+ if (node._scissorRestored) { //restore the parent's scissor rect
+ var rect = node._parentScissorRect;
+ cc.view.setScissorInPoints(rect.x, rect.y, rect.width, rect.height);
+ } else {
+ var ctx = cc._renderContext;
+ ctx.disable(ctx.SCISSOR_TEST);
+ }
+ };
+})();
diff --git a/frameworks/cocos2d-html5/extensions/gui/scrollview/CCSorting.js b/frameworks/cocos2d-html5/extensions/gui/scrollview/CCSorting.js
new file mode 100644
index 0000000..cda5fba
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/scrollview/CCSorting.js
@@ -0,0 +1,239 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2010 Sangwoo Im
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The sortable object interface
+ * @class
+ * @extends cc.Class
+ */
+cc.SortableObject = cc.Class.extend(/** @lends cc.SortableObject */{
+ setObjectID:function (objectId) {
+ },
+ getObjectID:function () {
+ return 0;
+ }
+});
+
+/**
+ * The SortedObject class
+ * @class
+ * @extends cc.SortableObject
+ */
+cc.SortedObject = cc.SortableObject.extend(/** @lends cc.SortedObject */{
+ _objectID:0,
+
+ ctor:function () {
+ this._objectID = 0;
+ },
+
+ setObjectID:function (objectID) {
+ this._objectID = objectID;
+ },
+
+ getObjectID:function () {
+ return this._objectID;
+ }
+});
+
+var _compareObject = function (val1, val2) {
+ return (val1.getObjectID() - val2.getObjectID());
+};
+
+/**
+ * Array for object sorting utils
+ * @class
+ * @extend cc.Class
+ */
+cc.ArrayForObjectSorting = cc.Class.extend(/** @lends cc.ArrayForObjectSorting# */{
+ _saveObjectArr:null,
+
+ ctor:function () {
+ this._saveObjectArr = [];
+ },
+ /**
+ * Inserts a given object into array.
+ *
+ * Inserts a given object into array with key and value that are used in
+ * sorting. "value" must respond to message, compare:, which returns
+ * (NSComparisonResult). If it does not respond to the message, it is appended.
+ * If the compare message does not result NSComparisonResult, sorting behavior
+ * is not defined. It ignores duplicate entries and inserts next to it.
+ *
+ * @function
+ * @param {Object} addObject Object to insert
+ */
+ insertSortedObject:function (addObject) {
+ if(!addObject)
+ throw new Error("cc.ArrayForObjectSorting.insertSortedObject(): addObject should be non-null.");
+ var idx = this.indexOfSortedObject(addObject);
+ this.insertObject(addObject, idx);
+ },
+
+ /*!
+ * Removes an object in array.
+ *
+ * Removes an object with given key and value. If no object is found in array
+ * with the key and value, no action is taken.
+ *
+ * @function
+ * @param {Object} delObject Object to remove
+ */
+ removeSortedObject:function (delObject) {
+ if (this.count() === 0) {
+ return;
+ }
+
+ var idx = this.indexOfSortedObject(delObject);
+ if (idx < this.count() && idx !== cc.INVALID_INDEX) {
+ var foundObj = this.objectAtIndex(idx);
+ if (foundObj.getObjectID() === delObject.getObjectID()) {
+ this.removeObjectAtIndex(idx);
+ }
+ }
+ },
+
+ /*!
+ * Sets a new value of the key for the given object.
+ *
+ * In case where sorting value must be changed, this message must be sent to
+ * keep consistency of being sorted. If it is changed externally, it must be
+ * sorted completely again.
+ *
+ * @function
+ * @param {Number} tag Tag to set
+ * @param {Object} setObject The object which would be set
+ */
+ setObjectID_ofSortedObject:function (tag, setObject) {
+ var idx = this.indexOfSortedObject(setObject);
+ if (idx < this.count() && idx !== cc.INVALID_INDEX) {
+ var foundObj = this.objectAtIndex(idx);
+ if (foundObj.getObjectID() === setObject.getObjectID()) {
+ this.removeObjectAtIndex(idx);
+ foundObj.setObjectID(tag);
+ this.insertSortedObject(foundObj);
+ }
+ }
+ },
+
+ objectWithObjectID:function (tag) {
+ if (this.count() === 0) {
+ return null;
+ }
+ var foundObj = new cc.SortedObject();
+ foundObj.setObjectID(tag);
+
+ var idx = this.indexOfSortedObject(foundObj);
+ if (idx < this.count() && idx !== cc.INVALID_INDEX) {
+ foundObj = this.objectAtIndex(idx);
+ if (foundObj.getObjectID() !== tag)
+ foundObj = null;
+ }
+ return foundObj;
+ },
+
+ /*!
+ * Returns an object with given key and value.
+ *
+ * Returns an object with given key and value. If no object is found,
+ * it returns nil.
+ *
+ * @function
+ * @param {Number} tag Tag to locate object
+ * @return {Object|null}
+ */
+ getObjectWithObjectID:function (tag) {
+ return null;
+ },
+
+ /*!
+ * Returns an index of the object with given key and value.
+ *
+ * Returns the index of an object with given key and value.
+ * If no object is found, it returns an index at which the given object value
+ * would have been located. If object must be located at the end of array,
+ * it returns the length of the array, which is out of bound.
+ *
+ * @function
+ * @param {Number} idxObj Id to locate object
+ * @return {Number} index of an object found
+ */
+ indexOfSortedObject:function (idxObj) {
+ var idx = 0;
+ if (idxObj) {
+ // CCObject* pObj = (CCObject*)bsearch((CCObject*)&object, data.arr, data.num, sizeof(CCObject*), _compareObject);
+ // FIXME: need to use binary search to improve performance
+ var uPrevObjectID = 0;
+ var uOfSortObjectID = idxObj.getObjectID();
+
+ var locObjectArr = this._saveObjectArr;
+ for (var i = 0; i < locObjectArr.length; i++) {
+ var pSortableObj = locObjectArr[i];
+ var curObjectID = pSortableObj.getObjectID();
+ if ((uOfSortObjectID === curObjectID) ||
+ (uOfSortObjectID >= uPrevObjectID && uOfSortObjectID < curObjectID)) {
+ break;
+ }
+ uPrevObjectID = curObjectID;
+ idx++;
+ }
+ } else {
+ idx = cc.INVALID_INDEX;
+ }
+ return idx;
+ },
+
+ //implement array method
+ count:function () {
+ return this._saveObjectArr.length;
+ },
+
+ lastObject:function () {
+ var locObjectArr = this._saveObjectArr;
+ if (locObjectArr.length === 0)
+ return null;
+ return locObjectArr[locObjectArr.length - 1];
+ },
+
+ objectAtIndex:function (idx) {
+ return this._saveObjectArr[idx];
+ },
+
+ addObject:function (addObj) {
+ this._saveObjectArr.push(addObj);
+ this._saveObjectArr.sort(_compareObject);
+ },
+
+ removeObjectAtIndex:function (idx) {
+ this._saveObjectArr.splice(idx, 1);
+ this._saveObjectArr.sort(_compareObject);
+ },
+
+ insertObject:function (addObj, idx) {
+ this._saveObjectArr.splice(idx, 0, addObj);
+ this._saveObjectArr.sort(_compareObject);
+ }
+});
diff --git a/frameworks/cocos2d-html5/extensions/gui/scrollview/CCTableView.js b/frameworks/cocos2d-html5/extensions/gui/scrollview/CCTableView.js
new file mode 100644
index 0000000..a197ada
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/gui/scrollview/CCTableView.js
@@ -0,0 +1,724 @@
+/****************************************************************************
+ Copyright (c) 2008-2010 Ricardo Quesada
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2010 Sangwoo Im
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The constant value of the fill style from top to bottom for cc.TableView
+ * @constant
+ * @type {number}
+ */
+cc.TABLEVIEW_FILL_TOPDOWN = 0;
+
+/**
+ * The constant value of the fill style from bottom to top for cc.TableView
+ * @constant
+ * @type {number}
+ */
+cc.TABLEVIEW_FILL_BOTTOMUP = 1;
+
+/**
+ * Abstract class for SWTableView cell node
+ * @class
+ * @abstract
+ * @extends cc.Node
+ *
+ * @property {Number} objectId - The index used internally by SWTableView and its subclasses
+ */
+cc.TableViewCell = cc.Node.extend(/** @lends cc.TableViewCell# */{
+ _idx: 0,
+ _className: "TableViewCell",
+
+ /**
+ * The index used internally by SWTableView and its subclasses
+ */
+ getIdx: function () {
+ return this._idx;
+ },
+ setIdx: function (idx) {
+ this._idx = idx;
+ },
+
+ /**
+ * Cleans up any resources linked to this cell and resets idx property.
+ */
+ reset: function () {
+ this._idx = cc.INVALID_INDEX;
+ },
+
+ setObjectID: function (idx) {
+ this._idx = idx;
+ },
+ getObjectID: function () {
+ return this._idx;
+ }
+});
+
+var _p = cc.TableViewCell.prototype;
+
+/** @expose */
+_p.objectId;
+cc.defineGetterSetter(_p, "objectId", _p.getObjectID, _p.setObjectID);
+
+_p = null;
+
+/**
+ * Sole purpose of this delegate is to single touch event in this version.
+ */
+cc.TableViewDelegate = cc.ScrollViewDelegate.extend(/** @lends cc.TableViewDelegate# */{
+ /**
+ * Delegate to respond touch event
+ *
+ * @param {cc.TableView} table table contains the given cell
+ * @param {cc.TableViewCell} cell cell that is touched
+ */
+ tableCellTouched: function (table, cell) {
+ },
+
+ /**
+ * Delegate to respond a table cell press event.
+ *
+ * @param {cc.TableView} table table contains the given cell
+ * @param {cc.TableViewCell} cell cell that is pressed
+ */
+ tableCellHighlight: function (table, cell) {
+ },
+
+ /**
+ * Delegate to respond a table cell release event
+ *
+ * @param {cc.TableView} table table contains the given cell
+ * @param {cc.TableViewCell} cell cell that is pressed
+ */
+ tableCellUnhighlight: function (table, cell) {
+
+ },
+
+ /**
+ *
+ * Delegate called when the cell is about to be recycled. Immediately
+ * after this call the cell will be removed from the scene graph and
+ * recycled.
+ *
+ * @param table table contains the given cell
+ * @param cell cell that is pressed
+ */
+ tableCellWillRecycle: function (table, cell) {
+
+ }
+});
+
+/**
+ * Data source that governs table backend data.
+ */
+cc.TableViewDataSource = cc.Class.extend(/** @lends cc.TableViewDataSource# */{
+ /**
+ * cell size for a given index
+ * @param {cc.TableView} table table to hold the instances of Class
+ * @param {Number} idx the index of a cell to get a size
+ * @return {cc.Size} size of a cell at given index
+ */
+ tableCellSizeForIndex: function (table, idx) {
+ return this.cellSizeForTable(table);
+ },
+ /**
+ * cell height for a given table.
+ *
+ * @param {cc.TableView} table table to hold the instances of Class
+ * @return {cc.Size} cell size
+ */
+ cellSizeForTable: function (table) {
+ return cc.size(0, 0);
+ },
+
+ /**
+ * a cell instance at a given index
+ * @param {cc.TableView} table table to hold the instances of Class
+ * @param idx index to search for a cell
+ * @return {cc.TableView} cell found at idx
+ */
+ tableCellAtIndex: function (table, idx) {
+ return null;
+ },
+
+ /**
+ * Returns number of cells in a given table view.
+ * @param {cc.TableView} table table to hold the instances of Class
+ * @return {Number} number of cells
+ */
+ numberOfCellsInTableView: function (table) {
+ return 0;
+ }
+});
+
+/**
+ * UITableView counterpart for cocos2d for iphone.
+ * this is a very basic, minimal implementation to bring UITableView-like component into cocos2d world.
+ *
+ * @class
+ * @extends cc.ScrollView
+ *
+ * @property {cc.TableViewDataSource} dataSource - The data source of the table view
+ * @property {cc.TableViewDelegate} delegate - The event delegate of the table view
+ * @property {Number} verticalFillOrder - The index to determine how cell is ordered and filled in the view
+ *
+ */
+cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
+ _vOrdering: null,
+ _indices: null,
+ _cellsFreed: null,
+ _dataSource: null,
+ _tableViewDelegate: null,
+ _oldDirection: null,
+ _cellsPositions: null, //vector with all cell positions
+ _touchedCell: null,
+
+ /**
+ * The
+ * @param dataSource
+ * @param size
+ * @param container
+ */
+ ctor: function (dataSource, size, container) {
+ cc.ScrollView.prototype.ctor.call(this);
+ this._oldDirection = cc.SCROLLVIEW_DIRECTION_NONE;
+ this._cellsPositions = [];
+
+ this.initWithViewSize(size, container);
+ this.setDataSource(dataSource);
+ this._updateCellPositions();
+ this._updateContentSize();
+ },
+
+ __indexFromOffset: function (offset) {
+ var low = 0;
+ var high = this._dataSource.numberOfCellsInTableView(this) - 1;
+ var search;
+ switch (this.getDirection()) {
+ case cc.SCROLLVIEW_DIRECTION_HORIZONTAL:
+ search = offset.x;
+ break;
+ default:
+ search = offset.y;
+ break;
+ }
+
+ var locCellsPositions = this._cellsPositions;
+ while (high >= low) {
+ var index = 0 | (low + (high - low) / 2);
+ var cellStart = locCellsPositions[index];
+ var cellEnd = locCellsPositions[index + 1];
+
+ if (search >= cellStart && search <= cellEnd) {
+ return index;
+ } else if (search < cellStart) {
+ high = index - 1;
+ } else {
+ low = index + 1;
+ }
+ }
+
+ if (low <= 0)
+ return 0;
+ return -1;
+ },
+
+ _indexFromOffset: function (offset) {
+ var locOffset = {x: offset.x, y: offset.y};
+ var locDataSource = this._dataSource;
+ var maxIdx = locDataSource.numberOfCellsInTableView(this) - 1;
+
+ if (this._vOrdering === cc.TABLEVIEW_FILL_TOPDOWN)
+ locOffset.y = this.getContainer().getContentSize().height - locOffset.y;
+
+ var index = this.__indexFromOffset(locOffset);
+ if (index !== -1) {
+ index = Math.max(0, index);
+ if (index > maxIdx)
+ index = cc.INVALID_INDEX;
+ }
+ return index;
+ },
+
+ __offsetFromIndex: function (index) {
+ var offset;
+ switch (this.getDirection()) {
+ case cc.SCROLLVIEW_DIRECTION_HORIZONTAL:
+ offset = cc.p(this._cellsPositions[index], 0);
+ break;
+ default:
+ offset = cc.p(0, this._cellsPositions[index]);
+ break;
+ }
+
+ return offset;
+ },
+
+ _offsetFromIndex: function (index) {
+ var offset = this.__offsetFromIndex(index);
+
+ var cellSize = this._dataSource.tableCellSizeForIndex(this, index);
+ if (this._vOrdering === cc.TABLEVIEW_FILL_TOPDOWN)
+ offset.y = this.getContainer().getContentSize().height - offset.y - cellSize.height;
+
+ return offset;
+ },
+
+ _updateCellPositions: function () {
+ var cellsCount = this._dataSource.numberOfCellsInTableView(this);
+ var locCellsPositions = this._cellsPositions;
+
+ if (cellsCount > 0) {
+ var currentPos = 0;
+ var cellSize, locDataSource = this._dataSource;
+ for (var i = 0; i < cellsCount; i++) {
+ locCellsPositions[i] = currentPos;
+ cellSize = locDataSource.tableCellSizeForIndex(this, i);
+ switch (this.getDirection()) {
+ case cc.SCROLLVIEW_DIRECTION_HORIZONTAL:
+ currentPos += cellSize.width;
+ break;
+ default:
+ currentPos += cellSize.height;
+ break;
+ }
+ }
+ this._cellsPositions[cellsCount] = currentPos;//1 extra value allows us to get right/bottom of the last cell
+ }
+ },
+
+ _updateContentSize: function () {
+ var size = cc.size(0, 0);
+
+ var cellsCount = this._dataSource.numberOfCellsInTableView(this);
+
+ if (cellsCount > 0) {
+ var maxPosition = this._cellsPositions[cellsCount];
+ switch (this.getDirection()) {
+ case cc.SCROLLVIEW_DIRECTION_HORIZONTAL:
+ size = cc.size(maxPosition, this._viewSize.height);
+ break;
+ default:
+ size = cc.size(this._viewSize.width, maxPosition);
+ break;
+ }
+ }
+
+ this.setContentSize(size);
+
+ if (this._oldDirection !== this._direction) {
+ if (this._direction === cc.SCROLLVIEW_DIRECTION_HORIZONTAL) {
+ this.setContentOffset(cc.p(0, 0));
+ } else {
+ this.setContentOffset(cc.p(0, this.minContainerOffset().y));
+ }
+ this._oldDirection = this._direction;
+ }
+ },
+
+ _moveCellOutOfSight: function (cell) {
+ if (this._tableViewDelegate && this._tableViewDelegate.tableCellWillRecycle)
+ this._tableViewDelegate.tableCellWillRecycle(this, cell);
+
+ this._cellsFreed.addObject(cell);
+ this._cellsUsed.removeSortedObject(cell);
+ cc.arrayRemoveObject(this._indices, cell.getIdx());
+
+ cell.reset();
+ if (cell.getParent() === this.getContainer()) {
+ this.getContainer().removeChild(cell, true);
+ }
+ },
+
+ _setIndexForCell: function (index, cell) {
+ cell.setAnchorPoint(0, 0);
+ cell.setPosition(this._offsetFromIndex(index));
+ cell.setIdx(index);
+ },
+
+ _addCellIfNecessary: function (cell) {
+ if (cell.getParent() !== this.getContainer()) {
+ this.getContainer().addChild(cell);
+ }
+ this._cellsUsed.insertSortedObject(cell);
+ var locIndices = this._indices, addIdx = cell.getIdx();
+ if (locIndices.indexOf(addIdx) === -1) {
+ locIndices.push(addIdx);
+ //sort
+ locIndices.sort(function (a, b) {
+ return a - b;
+ });
+ }
+ },
+
+ /**
+ * data source
+ */
+ getDataSource: function () {
+ return this._dataSource;
+ },
+ setDataSource: function (source) {
+ this._dataSource = source;
+ },
+
+ /**
+ * delegate
+ */
+ getDelegate: function () {
+ return this._tableViewDelegate;
+ },
+
+ setDelegate: function (delegate) {
+ this._tableViewDelegate = delegate;
+ },
+
+ /**
+ * determines how cell is ordered and filled in the view.
+ */
+ setVerticalFillOrder: function (fillOrder) {
+ if (this._vOrdering !== fillOrder) {
+ this._vOrdering = fillOrder;
+ if (this._cellsUsed.count() > 0) {
+ this.reloadData();
+ }
+ }
+ },
+ getVerticalFillOrder: function () {
+ return this._vOrdering;
+ },
+
+ initWithViewSize: function (size, container) {
+ if (cc.ScrollView.prototype.initWithViewSize.call(this, size, container)) {
+ this._cellsUsed = new cc.ArrayForObjectSorting();
+ this._cellsFreed = new cc.ArrayForObjectSorting();
+ this._indices = [];
+ this._tableViewDelegate = null;
+ this._vOrdering = cc.TABLEVIEW_FILL_BOTTOMUP;
+ this.setDirection(cc.SCROLLVIEW_DIRECTION_VERTICAL);
+
+ cc.ScrollView.prototype.setDelegate.call(this, this);
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Updates the content of the cell at a given index.
+ *
+ * @param idx index to find a cell
+ */
+ updateCellAtIndex: function (idx) {
+ if (idx === cc.INVALID_INDEX || idx > this._dataSource.numberOfCellsInTableView(this) - 1)
+ return;
+
+ var cell = this.cellAtIndex(idx);
+ if (cell)
+ this._moveCellOutOfSight(cell);
+
+ cell = this._dataSource.tableCellAtIndex(this, idx);
+ this._setIndexForCell(idx, cell);
+ this._addCellIfNecessary(cell);
+ },
+
+ /**
+ * Inserts a new cell at a given index
+ *
+ * @param idx location to insert
+ */
+ insertCellAtIndex: function (idx) {
+ if (idx === cc.INVALID_INDEX || idx > this._dataSource.numberOfCellsInTableView(this) - 1)
+ return;
+
+ var newIdx, locCellsUsed = this._cellsUsed;
+ var cell = locCellsUsed.objectWithObjectID(idx);
+ if (cell) {
+ newIdx = locCellsUsed.indexOfSortedObject(cell);
+ for (var i = newIdx; i < locCellsUsed.count(); i++) {
+ cell = locCellsUsed.objectAtIndex(i);
+ this._setIndexForCell(cell.getIdx() + 1, cell);
+ }
+ }
+
+ //insert a new cell
+ cell = this._dataSource.tableCellAtIndex(this, idx);
+ this._setIndexForCell(idx, cell);
+ this._addCellIfNecessary(cell);
+
+ this._updateCellPositions();
+ this._updateContentSize();
+ },
+
+ /**
+ * Removes a cell at a given index
+ *
+ * @param idx index to find a cell
+ */
+ removeCellAtIndex: function (idx) {
+ if (idx === cc.INVALID_INDEX || idx > this._dataSource.numberOfCellsInTableView(this) - 1)
+ return;
+
+ var cell = this.cellAtIndex(idx);
+ if (!cell)
+ return;
+
+ var locCellsUsed = this._cellsUsed;
+ var newIdx = locCellsUsed.indexOfSortedObject(cell);
+
+ //remove first
+ this._moveCellOutOfSight(cell);
+ cc.arrayRemoveObject(this._indices, idx);
+ this._updateCellPositions();
+
+ for (var i = locCellsUsed.count() - 1; i > newIdx; i--) {
+ cell = locCellsUsed.objectAtIndex(i);
+ this._setIndexForCell(cell.getIdx() - 1, cell);
+ }
+ },
+
+ /**
+ * reloads data from data source. the view will be refreshed.
+ */
+ reloadData: function () {
+ this._oldDirection = cc.SCROLLVIEW_DIRECTION_NONE;
+ var locCellsUsed = this._cellsUsed, locCellsFreed = this._cellsFreed, locContainer = this.getContainer();
+ for (var i = 0, len = locCellsUsed.count(); i < len; i++) {
+ var cell = locCellsUsed.objectAtIndex(i);
+
+ if (this._tableViewDelegate && this._tableViewDelegate.tableCellWillRecycle)
+ this._tableViewDelegate.tableCellWillRecycle(this, cell);
+
+ locCellsFreed.addObject(cell);
+ cell.reset();
+ if (cell.getParent() === locContainer)
+ locContainer.removeChild(cell, true);
+ }
+
+ this._indices = [];
+ this._cellsUsed = new cc.ArrayForObjectSorting();
+
+ this._updateCellPositions();
+ this._updateContentSize();
+ if (this._dataSource.numberOfCellsInTableView(this) > 0)
+ this.scrollViewDidScroll(this);
+
+ this.setNodeDirty();
+ },
+
+ /**
+ * Dequeues a free cell if available. nil if not.
+ *
+ * @return {TableViewCell} free cell
+ */
+ dequeueCell: function () {
+ if (this._cellsFreed.count() === 0) {
+ return null;
+ } else {
+ var cell = this._cellsFreed.objectAtIndex(0);
+ this._cellsFreed.removeObjectAtIndex(0);
+ return cell;
+ }
+ },
+
+ /**
+ * Returns an existing cell at a given index. Returns nil if a cell is nonexistent at the moment of query.
+ *
+ * @param idx index
+ * @return {cc.TableViewCell} a cell at a given index
+ */
+ cellAtIndex: function (idx) {
+ var i = this._indices.indexOf(idx);
+ if (i === -1)
+ return null;
+ return this._cellsUsed.objectWithObjectID(idx);
+ },
+
+ scrollViewDidScroll: function (view) {
+ var locDataSource = this._dataSource;
+ var countOfItems = locDataSource.numberOfCellsInTableView(this);
+ if (0 === countOfItems)
+ return;
+
+ if (this._tableViewDelegate !== null && this._tableViewDelegate.scrollViewDidScroll)
+ this._tableViewDelegate.scrollViewDidScroll(this);
+
+ var idx = 0, locViewSize = this._viewSize, locContainer = this.getContainer();
+ var offset = this.getContentOffset();
+ offset.x *= -1;
+ offset.y *= -1;
+
+ var maxIdx = Math.max(countOfItems - 1, 0);
+
+ if (this._vOrdering === cc.TABLEVIEW_FILL_TOPDOWN)
+ offset.y = offset.y + locViewSize.height / locContainer.getScaleY();
+ var startIdx = this._indexFromOffset(offset);
+ if (startIdx === cc.INVALID_INDEX)
+ startIdx = countOfItems - 1;
+
+ if (this._vOrdering === cc.TABLEVIEW_FILL_TOPDOWN)
+ offset.y -= locViewSize.height / locContainer.getScaleY();
+ else
+ offset.y += locViewSize.height / locContainer.getScaleY();
+ offset.x += locViewSize.width / locContainer.getScaleX();
+
+ var endIdx = this._indexFromOffset(offset);
+ if (endIdx === cc.INVALID_INDEX)
+ endIdx = countOfItems - 1;
+
+ var cell, locCellsUsed = this._cellsUsed;
+ if (locCellsUsed.count() > 0) {
+ cell = locCellsUsed.objectAtIndex(0);
+ idx = cell.getIdx();
+ while (idx < startIdx) {
+ this._moveCellOutOfSight(cell);
+ if (locCellsUsed.count() > 0) {
+ cell = locCellsUsed.objectAtIndex(0);
+ idx = cell.getIdx();
+ } else
+ break;
+ }
+ }
+
+ if (locCellsUsed.count() > 0) {
+ cell = locCellsUsed.lastObject();
+ idx = cell.getIdx();
+ while (idx <= maxIdx && idx > endIdx) {
+ this._moveCellOutOfSight(cell);
+ if (locCellsUsed.count() > 0) {
+ cell = locCellsUsed.lastObject();
+ idx = cell.getIdx();
+ } else
+ break;
+ }
+ }
+
+ var locIndices = this._indices;
+ for (var i = startIdx; i <= endIdx; i++) {
+ if (locIndices.indexOf(i) !== -1)
+ continue;
+ this.updateCellAtIndex(i);
+ }
+ },
+
+ scrollViewDidZoom: function (view) {
+ },
+
+ onTouchEnded: function (touch, event) {
+ if (!this.isVisible())
+ return;
+
+ if (this._touchedCell) {
+ var bb = this.getBoundingBox();
+ var tmpOrigin = cc.p(bb.x, bb.y);
+ tmpOrigin = this._parent.convertToWorldSpace(tmpOrigin);
+ bb.x = tmpOrigin.x;
+ bb.y = tmpOrigin.y;
+ var locTableViewDelegate = this._tableViewDelegate;
+ if (cc.rectContainsPoint(bb, touch.getLocation()) && locTableViewDelegate !== null) {
+ if (locTableViewDelegate.tableCellUnhighlight)
+ locTableViewDelegate.tableCellUnhighlight(this, this._touchedCell);
+ if (locTableViewDelegate.tableCellTouched)
+ locTableViewDelegate.tableCellTouched(this, this._touchedCell);
+ }
+ this._touchedCell = null;
+ }
+ cc.ScrollView.prototype.onTouchEnded.call(this, touch, event);
+ },
+
+ onTouchBegan: function (touch, event) {
+ for (var c = this; c != null; c = c.parent) {
+ if (!c.isVisible())
+ return false;
+ }
+
+ var touchResult = cc.ScrollView.prototype.onTouchBegan.call(this, touch, event);
+
+ if (this._touches.length === 1) {
+ var index, point;
+
+ point = this.getContainer().convertTouchToNodeSpace(touch);
+
+ index = this._indexFromOffset(point);
+ if (index === cc.INVALID_INDEX)
+ this._touchedCell = null;
+ else
+ this._touchedCell = this.cellAtIndex(index);
+
+ if (this._touchedCell && this._tableViewDelegate !== null && this._tableViewDelegate.tableCellHighlight)
+ this._tableViewDelegate.tableCellHighlight(this, this._touchedCell);
+ } else if (this._touchedCell) {
+ if (this._tableViewDelegate !== null && this._tableViewDelegate.tableCellUnhighlight)
+ this._tableViewDelegate.tableCellUnhighlight(this, this._touchedCell);
+ this._touchedCell = null;
+ }
+
+ return touchResult;
+ },
+
+ onTouchMoved: function (touch, event) {
+ cc.ScrollView.prototype.onTouchMoved.call(this, touch, event);
+
+ if (this._touchedCell && this.isTouchMoved()) {
+ if (this._tableViewDelegate !== null && this._tableViewDelegate.tableCellUnhighlight)
+ this._tableViewDelegate.tableCellUnhighlight(this, this._touchedCell);
+ this._touchedCell = null;
+ }
+ },
+
+ onTouchCancelled: function (touch, event) {
+ cc.ScrollView.prototype.onTouchCancelled.call(this, touch, event);
+
+ if (this._touchedCell) {
+ if (this._tableViewDelegate !== null && this._tableViewDelegate.tableCellUnhighlight)
+ this._tableViewDelegate.tableCellUnhighlight(this, this._touchedCell);
+ this._touchedCell = null;
+ }
+ }
+});
+
+var _p = cc.TableView.prototype;
+
+/** @expose */
+_p.dataSource;
+cc.defineGetterSetter(_p, "dataSource", _p.getDataSource, _p.setDataSource);
+/** @expose */
+_p.delegate;
+cc.defineGetterSetter(_p, "delegate", _p.getDelegate, _p.setDelegate);
+/** @expose */
+_p.verticalFillOrder;
+cc.defineGetterSetter(_p, "verticalFillOrder", _p.getVerticalFillOrder, _p.setVerticalFillOrder);
+
+_p = null;
+
+/**
+ * An initialized table view object
+ * @deprecated
+ * @param {cc.TableViewDataSource} dataSource data source;
+ * @param {cc.Size} size view size
+ * @param {cc.Node} [container] parent object for cells
+ * @return {cc.TableView} table view
+ */
+cc.TableView.create = function (dataSource, size, container) {
+ return new cc.TableView(dataSource, size, container);
+};
diff --git a/frameworks/cocos2d-html5/extensions/runtime/CCLoaderLayer.js b/frameworks/cocos2d-html5/extensions/runtime/CCLoaderLayer.js
new file mode 100644
index 0000000..5877918
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/runtime/CCLoaderLayer.js
@@ -0,0 +1,988 @@
+/****************************************************************************
+ Copyright (c) 2014-2015 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+(function () {
+
+var INT_MAX = Number.MAX_VALUE;
+var GROUP_JSON_PATH = "group.json";
+
+cc.LoaderLayer = cc.Layer.extend({
+ _backgroundSprite: null,
+ _progressBackgroundSprite: null,
+ _progressBarSprite: null,
+ _logoSprite: null,
+ _titleSprite: null,
+ _groupname: null,
+ _callback: null,
+ _selector: null,
+ _preloadCount: 0,
+ _isPreloadFromFailed: false,
+ _progressOriginalWidth: 0,
+ _isLandScape: false,
+ _scaleFactor: null,
+
+ ctor: function (config) {
+ this._super();
+ if (config) {
+ cc.LoaderLayer.setConfig(config);
+ }
+ },
+ onEnter: function () {
+ this._super();
+ this.initView();
+ var config = cc.LoaderLayer._finalConfig;
+ if (config.onEnter) {
+ config.onEnter(this);
+ }
+ },
+ onExit: function () {
+ this._super();
+ var config = cc.LoaderLayer._finalConfig;
+ if (config.logo.action) {
+ config.logo.action.release();
+ }
+ if(config.title.action){
+ config.title.action.release();
+ }
+ if (config.onExit) {
+ config.onExit(this);
+ }
+ },
+ initView: function () {
+ var config = cc.LoaderLayer._finalConfig;
+ this._contentLayer = new cc.Layer();
+ this._isLandScape = cc.winSize.width > cc.winSize.height;
+ this._scaleFactor = !cc.LoaderLayer._useDefaultSource ? 1 : cc.winSize.width > cc.winSize.height ? cc.winSize.width / 720 : cc.winSize.width / 480;
+
+ //background
+ this.backgroundSprite = new cc.Sprite(config.background.res);
+ this.addChild(this.backgroundSprite);
+ this.backgroundSprite.x = 0, this.backgroundSprite.y = 0, this.backgroundSprite.anchorX = 0, this.backgroundSprite.anchorY = 0;
+ if (cc.LoaderLayer._useDefaultSource) {
+ this.backgroundSprite.scaleX = cc.winSize.width / this.backgroundSprite.width;
+ this.backgroundSprite.scaleY = cc.winSize.height / this.backgroundSprite.height;
+ }
+
+ //title
+ if (config.title.show) {
+ this.titleSprite = new cc.Sprite(config.title.res);
+ var defaultTitlePosition = cc.pAdd(cc.visibleRect.center, cc.p(0, this._scaleFactor < 1 ? 0 : this._isLandScape ? -80 : 30));
+ this.titleSprite.setPosition(config.title.position ? config.title.position : defaultTitlePosition);
+ this._contentLayer.addChild(this.titleSprite);
+ if (config.title.action) {
+ this.titleSprite.runAction(config.title.action);
+ }
+ }
+
+ //logo
+ if (config.logo.show) {
+ this.logoSprite = new cc.Sprite(config.logo.res);
+ var defaultLogoPosition = cc.pAdd(cc.visibleRect.top, cc.p(0, this._scaleFactor < 1 ? 0 : -this.logoSprite.height / 2 - (this._isLandScape ? 56 : 76)));
+ this.logoSprite.setPosition(config.logo.position ? config.logo.position : defaultLogoPosition);
+ this._contentLayer.addChild(this.logoSprite);
+ if (config.logo.action) {
+ this.logoSprite.runAction(config.logo.action);
+ }
+ }
+
+ //progressbar
+ if (config.progressBar.show) {
+ this.progressBarSprite = new cc.Sprite(config.progressBar.res);
+ this._progressOriginalWidth = this.progressBarSprite.width;
+ this.progressBackgroundSprite = new cc.Sprite(config.progressBar.barBackgroundRes);
+ this.progressBarSprite.anchorX = 0;
+ this.progressBarSprite.anchorY = 0;
+ if (cc.LoaderLayer._isDefaultProgress) {
+ this._barPoint = new cc.Sprite(config.progressBar.barPoint);
+ this.progressBarSprite.addChild(this._barPoint);
+ }
+ if (config.progressBar.barBackgroundRes == null) {
+ this.progressBackgroundSprite.setTextureRect(cc.rect(0, 0, this.progressBarSprite.width, this.progressBarSprite.height));
+ }
+ if (config.progressBar.offset == null) {
+ var deltaProgressWithX = (this.progressBackgroundSprite.width - this.progressBarSprite.width) / 2;
+ var deltaProgressWithY = (this.progressBackgroundSprite.height - this.progressBarSprite.height) / 2;
+ config.progressBar.offset = cc.p(deltaProgressWithX, deltaProgressWithY);
+ }
+ this.progressBarSprite.setPosition(config.progressBar.offset);
+ this.progressBackgroundSprite.addChild(this.progressBarSprite);
+ var defaultProgressPosition = cc.pAdd(cc.visibleRect.bottom, cc.p(0, this.progressBarSprite.height / 2 + this._isLandScape ? 60 : 80));
+ this.progressBackgroundSprite.setPosition(config.progressBar.position ? config.progressBar.position : defaultProgressPosition);
+ this._contentLayer.addChild(this.progressBackgroundSprite);
+ this._setProgress(0);
+ }
+
+ //tips
+ if (config.tips.show) {
+ this.tipsLabel = new cc.LabelTTF("100%", "Arial", config.tips.fontSize);
+ this.tipsLabel.setColor(config.tips.color ? config.tips.color : cc.color(255, 255, 255));
+ this.tipsLabel.setPosition(config.tips.position ? config.tips.position : this.progressBackgroundSprite ? cc.p(this.progressBackgroundSprite.x, this.progressBackgroundSprite.y + this.progressBackgroundSprite.height / 2 + 20) : cc.pAdd(cc.visibleRect.bottom, cc.p(0, 100)));
+ this._contentLayer.addChild(this.tipsLabel);
+ }
+ this.addChild(this._contentLayer);
+ if (this._scaleFactor < 1) {
+ this._contentLayer.setScale(this._scaleFactor);
+ this._contentLayer.setPosition(cc.pAdd(this._contentLayer.getPosition(), cc.p(0, -50)));
+ }
+
+ },
+ _setProgress: function (percent) {
+ if (this.progressBarSprite) {
+ percent < 1 ? percent : 1;
+ var width = percent * this._progressOriginalWidth;
+ this.progressBarSprite.setTextureRect(cc.rect(0, 0, width, this.progressBarSprite.height));
+ if (cc.LoaderLayer._isDefaultProgress) {
+ this._barPoint.setPosition(cc.p(this.progressBarSprite.width, this.progressBarSprite.height / 2));
+ }
+ }
+ },
+ setTipsString: function (str) {
+ if (this.tipsLabel != null) {
+ this.tipsLabel.setString(str);
+ }
+ },
+ getProgressBar: function () {
+ return this.progressBarSprite;
+ },
+ getTipsLabel: function () {
+ return this.tipsLabel;
+ },
+ getLogoSprite: function () {
+ return this.logoSprite;
+ },
+ getTitleSprite: function () {
+ return this.titleSprite;
+ },
+ updateGroup: function (groupname, callback, target) {
+ this._groupname = groupname;
+ this._callback = callback;
+ this._selector = target;
+ },
+ _resetLoadingLabel: function () {
+ this.setTipsString("");
+ this._setProgress(0);
+ },
+ _preloadSource: function () {
+ cc.log("cc.LoaderLayer is preloading resource group: " + this._groupname);
+ this._resetLoadingLabel();
+ if (cc.sys.isNative) {
+ cc.Loader.preload(this._groupname, this._preload_native, this);
+ } else {
+ this._preload_html5();
+ }
+ },
+ _preload_html5: function () {
+ var res = "";
+ var groupIndex = [];
+ var config = cc.LoaderLayer._finalConfig;
+ var groups = cc.LoaderLayer.groups;
+ if (cc.isString(this._groupname)) {
+ if (this._groupname.indexOf(".") != -1) {
+ res = [this._groupname];
+ } else {
+ res = groups[this._groupname];
+ }
+ } else if (cc.isArray(this._groupname)) {
+ res = [];
+ for (var i = 0; i < this._groupname.length; i++) {
+ var group = groups[this._groupname[i]];
+ var files = group && group.files;
+ var preCount = i > 0 ? groupIndex[i - 1] : 0;
+ groupIndex.push(preCount + files ? files.length : 0);
+ res = res.concat(files);
+ }
+ }
+ var self = this;
+ //var progressFunction = self.config.progressCallback ? self.config.progressCallback : null;
+ cc.loader.load(res, function (result, count, loadedCount) {
+ var checkGroupName = function (loadedCount) {
+ for (var i = 0; i < groupIndex.length; i++) {
+ if (groupIndex[i] >= loadedCount) {
+ return self._groupname[i];
+ }
+ }
+ };
+ var groupName = checkGroupName(loadedCount);
+ var status = {
+ groupName: groupName,
+ isCompleted: false,
+ percent: (loadedCount / count * 100) | 0,//(float),
+ stage: 1, //(1 download,2 unzip)
+ isFailed: false
+ }
+ if (status.percent != 0) {
+ self._setProgress(status.percent / 100);
+ }
+ config.tips.tipsProgress(status, self);
+ }, function () {
+ self.removeFromParent();
+ self._preloadCount--;
+ if (self._callback) {
+ if (self._selector) {
+ self._callback(self._selector, true);
+ } else {
+ self._callback(true);
+ }
+ }
+ });
+ },
+ _preload_native: function (status) {
+ cc.log(JSON.stringify(status));
+ var config = cc.LoaderLayer._finalConfig;
+ if (status.percent) {
+ this._setProgress(status.percent / 100);
+ }
+ if (config.tips.tipsProgress) {
+ config.tips.tipsProgress(status, this);
+ }
+ if (status.isCompleted || status.isFailed) {
+ this._preloadCount--;
+
+ if (status.isCompleted) {
+ cc.log("preload finish!");
+ this._isPreloadFromFailed = false;
+ }
+ if (status.isFailed) {
+ cc.log("preload failed!");
+ this._isPreloadFromFailed = true;
+ }
+
+ // Remove loading layer from scene after loading was done.
+ if (this._preloadCount == 0 && !this._isPreloadFromFailed) {
+ this.removeFromParent();
+ if (cc.LoaderLayer._useDefaultSource) {
+ var _config = cc.runtime.config.design_resolution || {width: 480, height: 720, policy: "SHOW_ALL"};
+ cc.view.setDesignResolutionSize(_config.width, _config.height, cc.ResolutionPolicy[_config.policy]);
+ }
+ }
+
+ // Callback must be invoked after removeFromParent.
+ this._callback.call(this._target, status);
+ }
+ },
+ _addToScene: function () {
+ if (this._preloadCount == 0 && !this._isPreloadFromFailed) {
+ if (cc.sys.isNative && cc.LoaderLayer._useDefaultSource) {
+ var config = cc.runtime.config.design_resolution;
+ var isLandscape = false;
+ var isLargeThanResource = false;
+ if (config) {
+ var orientation = cc.runtime.config.orientation;
+ cc.log("_addToScene orientation is " + orientation);
+ if (orientation == "landscape") {
+ isLandscape = true;
+ isLargeThanResource = config.width > 720 || config.height > 480;
+ } else {
+ isLargeThanResource = config.width > 480 || config.height > 720;
+ }
+ }
+ cc.log("isLargeThanResource is " + isLargeThanResource);
+ cc.view.setDesignResolutionSize(isLargeThanResource ? config.width : isLandscape ? 720 : 480, isLargeThanResource ? config.height : isLandscape ? 480 : 720, cc.ResolutionPolicy["FIXED_HEIGHT"]);
+ }
+ cc.director.getRunningScene().addChild(this, INT_MAX - 1);
+ }
+ this._preloadCount++;
+ }
+});
+cc.LoaderLayer._config = {//default setting for loaderlayer
+ background: {
+ res: "res_engine/preload_bg.jpg"
+ },
+ title: {
+ show: true,
+ res: "res_engine/preload_title.png",
+ position: null,
+ action: null
+ },
+ logo: {
+ res: "res_engine/preload_logo.png",
+ show: true,
+ position: null
+ },
+ progressBar: {
+ show: true,
+ res: "res_engine/progress_bar.png",
+ offset: null,
+ position: null,
+ barBackgroundRes: "res_engine/progress_bg.png",
+ barPoint: "res_engine/progress_light.png",
+ barShadow: "res_engine/shadow.png"
+ },
+ tips: {
+ show: true,
+ fontSize: 22,
+ position: null,
+ color: null,
+ tipsProgress: function (status, loaderlayer) {
+ if(loaderlayer.getTipsLabel()){
+ var statusStr = "正在";
+ if (status.stage == cc.network.preloadstatus.DOWNLOAD) {
+ statusStr += "下载";
+ } else if (status.stage == cc.network.preloadstatus.UNZIP) {
+ statusStr += "解压";
+ }
+ if (status.groupName) {
+ statusStr += status.groupName;
+ }
+ statusStr += "进度:" + status.percent.toFixed(2) + "%";
+ loaderlayer.getTipsLabel().setString(statusStr);
+ }
+ }
+ },
+ progressCallback: function (progress) {
+
+ },
+ onEnter: function (layer) {
+ cc.log("LoaderLayer onEnter");
+ },
+ onExit: function (layer) {
+ cc.log("LoaderLayer onExit");
+ }
+}
+
+var res_engine_loaded = false;
+
+cc.LoaderLayer.preload = function (groupname, callback, target) {
+ var loaderLayer = new cc.LoaderLayer();
+ var preloadCb = function (status) {
+ if (status.isFailed) {
+ var tips, conirmfunc, cancelfunc;
+ switch (status.errorCode) {
+ case "err_no_space":
+ {
+ tips = "空间不足,请清理磁盘空间";
+ conirmfunc = function () {
+ callPreload();
+ };
+ cancelfunc = function () {
+ cc.director.end();
+ };
+ break;
+ }
+ case "err_verify":
+ {
+ tips = "校验失败,是否重新下载?";
+ conirmfunc = function () {
+ callPreload();
+ }
+ cancelfunc = function () {
+ cc.director.end();
+ }
+ break;
+ }
+ case "err_network":
+ {
+ tips = "网络异常是否重新下载";
+ conirmfunc = function () {
+ callPreload();
+ }
+ cancelfunc = function () {
+ cc.director.end();
+ }
+ break;
+ }
+ default :
+ {
+ conirmfunc = cancelfunc = function () {
+
+ }
+ }
+ }
+ cc._NetworkErrorDialog._show(status.errorCode, tips, conirmfunc, cancelfunc);
+ } else {
+ if (callback) {
+ if (target) {
+ callback.call(target, !status.isFailed);
+ } else {
+ callback(!status.isFailed)
+ }
+ }
+ }
+ }
+ var callPreload = function () {
+ loaderLayer.updateGroup(groupname, preloadCb, target);
+ loaderLayer._addToScene();
+ loaderLayer._preloadSource();
+ };
+
+ if (res_engine_loaded) {
+ callPreload();
+ return;
+ }
+
+ if (!cc.director.getRunningScene()) {
+ cc.director.runScene(new cc.Scene());
+ }
+
+ // Res engine not loaded, load them
+ cc.loader.load([
+ GROUP_JSON_PATH,
+ cc.LoaderLayer._finalConfig.background.res,
+ cc.LoaderLayer._finalConfig.title.res,
+ cc.LoaderLayer._finalConfig.logo.res,
+ cc.LoaderLayer._finalConfig.progressBar.res,
+ cc.LoaderLayer._finalConfig.progressBar.barBackgroundRes,
+ cc.LoaderLayer._finalConfig.progressBar.barPoint,
+ cc.LoaderLayer._finalConfig.progressBar.barShadow,
+ cc.Dialog._finalConfig.background.res,
+ cc.Dialog._finalConfig.confirmBtn.normalRes,
+ cc.Dialog._finalConfig.confirmBtn.pressRes,
+ cc.Dialog._finalConfig.cancelBtn.normalRes,
+ cc.Dialog._finalConfig.cancelBtn.pressRes
+ ],
+ function (result, count, loadedCount) {
+ var percent = (loadedCount / count * 100) | 0;
+ percent = Math.min(percent, 100);
+ cc.log("Preloading engine resources... " + percent + "%");
+ }, function () {
+ var groups = cc.loader.getRes(GROUP_JSON_PATH);
+ if (groups) {
+ cc.LoaderLayer.groups = groups;
+ }
+ else {
+ cc.warn("Group versions haven't been loaded, you can also set group data with 'cc.LoaderLayer.groups'");
+ }
+ res_engine_loaded = true;
+ callPreload();
+ });
+};
+
+cc.LoaderLayer._useDefaultSource = true;
+cc.LoaderLayer._isDefaultProgress = true;
+cc.LoaderLayer._finalConfig = cc.LoaderLayer._config;
+cc.LoaderLayer.groups = {};
+cc.LoaderLayer.setUseDefaultSource = function (status) {
+ cc.LoaderLayer._useDefaultSource = status;
+};
+cc.LoaderLayer.setConfig = function (config) {
+ if(config.title && config.title.action){
+ config.title.action.retain();
+ }
+ if(config.logo && config.logo.action){
+ config.logo.action.retain();
+ }
+ this._initData(config);
+};
+cc.LoaderLayer._initData = function (uConfig) {
+ this._finalConfig = cc.clone(this._config);
+ var config = this._finalConfig;
+ if (uConfig != null) {
+ if (uConfig.background && uConfig.background.res) {
+ config.background.res = uConfig.background.res;
+ }
+ if (uConfig.title) {
+ var uTitle = uConfig.title;
+ var title = config.title;
+ title.show = typeof uTitle.show != "undefined" ? uTitle.show : title.show;
+ title.res = uTitle.res ? uTitle.res : title.res;
+ title.position = uTitle.position ? uTitle.position : title.position;
+ title.action = uTitle.action ? uTitle.action : title.action;
+ if (title.action) {
+ title.action = uTitle.action;
+ title.action.retain();
+ }
+ }
+ if (uConfig.logo) {
+ var uLogo = uConfig.logo;
+ var logo = config.logo;
+ logo.show = typeof uLogo.show != "undefined" ? uLogo.show : logo.show;
+ logo.res = uLogo.res ? uLogo.res : logo.res;
+ logo.position = uLogo.position ? uLogo.position : logo.position;
+ if (typeof uLogo.action != "undefined") {
+ logo.action = uLogo.action;
+ if (logo.action) {
+ logo.action.retain();
+ }
+ }
+ }
+ if (uConfig.progressBar) {
+ var uProgress = uConfig.progressBar;
+ var progress = config.progressBar;
+ progress.show = typeof uProgress.show != "undefined" ? uProgress.show : progress.show;
+ if (uProgress.res) {
+ progress.res = uProgress.res;
+ this._isDefaultProgress = false;
+ }
+ progress.offset = uProgress.offset ? uProgress.offset : progress.offset;
+ progress.position = uProgress.position ? uProgress.position : progress.position;
+ progress.barBackgroundRes = uProgress.barBackgroundRes ? uProgress.barBackgroundRes : progress.barBackgroundRes;
+ }
+ if (uConfig.tips) {
+ var uTips = uConfig.tips;
+ var tips = config.tips;
+ tips.show = typeof uTips.show != "undefined" ? uTips.show : tips.show;
+ tips.res = uTips.res ? uTips.res : tips.res;
+ tips.offset = uTips.offset ? uTips.offset : tips.offset;
+ tips.fontSize = uTips.fontSize ? uTips.fontSize : tips.fontSize;
+ tips.position = uTips.position ? uTips.position : tips.position;
+ tips.color = uTips.color ? uTips.color : tips.color;
+ if (uConfig.tips.tipsProgress && typeof uConfig.tips.tipsProgress == "function") {
+ tips.tipsProgress = uConfig.tips.tipsProgress;
+ }
+ }
+ if (typeof uConfig.onEnter == "function") {
+ config.onEnter = uConfig.onEnter;
+ }
+ if (typeof uConfig.onExit == "function") {
+ config.onExit = uConfig.onExit;
+ }
+ }
+
+ if (typeof config.logo.action == "undefined" && this._useDefaultSource) {
+ config.logo.action = cc.sequence(
+ cc.spawn(cc.moveBy(0.4, cc.p(0, 40)).easing(cc.easeIn(0.5)), cc.scaleTo(0.4, 0.95, 1.05).easing(cc.easeIn(0.5))),
+ cc.delayTime(0.08),
+ cc.spawn(cc.moveBy(0.4, cc.p(0, -40)).easing(cc.easeOut(0.5)), cc.scaleTo(0.4, 1.05, 0.95).easing(cc.easeOut(0.5)))
+ ).repeatForever();
+ config.logo.action.retain();
+ }
+ if (!config.tips.color) {
+ config.tips.color = cc.color(255, 255, 255);
+ }
+};
+
+cc.Dialog = cc.Layer.extend({
+ _defaultConfig: null,
+ backgroundSprite: null,
+ _menuItemConfirm: null,
+ _menuItemCancel: null,
+ _messageLabel: null,
+ _eventListener: null,
+ _scaleFactor: null,
+
+ ctor: function (config) {
+ this._super();
+ this.setConfig(config);
+ },
+ setConfig: function (config) {
+ this.removeAllChildren();
+ if (config) {
+ cc.Dialog.setConfig(config);
+ }
+ },
+ initView: function () {
+ var useDefaultSource = cc.Dialog._useDefaultSource;
+ var winSize = cc.director.getWinSize();
+ this._scaleFactor = !useDefaultSource ? 1 : winSize.width > winSize.height ? winSize.width / 720 : winSize.width / 480;
+ var config = cc.Dialog._finalConfig;
+
+ //bg
+ this.backgroundSprite = new cc.Scale9Sprite(config.background.res);
+ this._setScale(this.backgroundSprite);
+ if (this._scaleFactor < 1) {
+ this.backgroundSprite.setScale(this._scaleFactor);
+ }
+ this.backgroundSprite.setPosition(config.position ? config.position : cc.p(winSize.width / 2, winSize.height / 2));
+
+ //menu
+ this.menuItemConfirm = this._createMenuItemSprite(config.confirmBtn, this._confirmCallback);
+ this.menuItemCancel = this._createMenuItemSprite(config.cancelBtn, this._cancelCallback);
+ this.menuItemCancel.setPosition(config.cancelBtn.position ? config.cancelBtn.position : cc.p(this.backgroundSprite.width / 2 - this.menuItemCancel.width / 2 - 20, this.menuItemCancel.height + 20));
+ this.menuItemConfirm.setPosition(config.confirmBtn.position ? config.confirmBtn.position : cc.p(this.backgroundSprite.width / 2 + this.menuItemConfirm.width / 2 + 20, this.menuItemConfirm.height + 20));
+ var menu = new cc.Menu(this.menuItemConfirm, this.menuItemCancel);
+ menu.setPosition(cc.p(0, 0));
+ this.backgroundSprite.addChild(menu);
+
+ //message
+ var fontSize = config.messageLabel.fontSize ? config.messageLabel.fontSize : this._scaleFactor > 1 ? 16 * this._scaleFactor : 16;
+ this.messageLabel = new cc.LabelTTF(config.messageLabel.text, "Arial", fontSize);
+ this.messageLabel.setDimensions(config.messageLabel.dimensions ? config.messageLabel.dimensions : cc.size(this.backgroundSprite.width - 30, this.backgroundSprite.height - this.menuItemConfirm.y - 10));
+ this.messageLabel.setColor(config.messageLabel.color ? config.messageLabel.color : cc.color(255, 255, 255));
+ this.messageLabel.setPosition(config.messageLabel.position ? config.messageLabel.position : cc.p(this.backgroundSprite.width / 2, this.backgroundSprite.height - this.messageLabel.height / 2 - 20));
+ this.backgroundSprite.addChild(this.messageLabel);
+ if (!config.action) {
+ var action = cc.sequence(cc.EaseIn.create(cc.scaleTo(0.1, this.backgroundSprite.scale + 0.02), 0.4), cc.EaseOut.create(cc.scaleTo(0.1, this.backgroundSprite.scale), 0.3));
+ this.backgroundSprite.runAction(action);
+ } else {
+ this.backgroundSprite.runAction(config.action);
+ }
+ this.addChild(this.backgroundSprite);
+
+ },
+ _createMenuItemSprite: function (res, callback) {
+ var spriteNormal = new cc.Scale9Sprite(res.normalRes);
+ var spritePress = new cc.Scale9Sprite(res.pressRes);
+ this._setScale(spriteNormal);
+ this._setScale(spritePress);
+ var fontSize = res.fontSize ? res.fontSize : this._scaleFactor > 1 ? 16 * this._scaleFactor : 16;
+ var menuLabel = new cc.LabelTTF(res.text, "Arial", fontSize);
+ menuLabel.setColor(res.textColor);
+ var menuItem = new cc.MenuItemSprite(spriteNormal, spritePress, callback, this);
+ menuLabel.setPosition(cc.p(menuItem.width / 2, menuItem.height / 2));
+ menuItem.addChild(menuLabel);
+ return menuItem;
+ },
+ _setScale: function (s9Sprite) {
+ if (this._scaleFactor > 1) {
+ s9Sprite.setContentSize(cc.size(this._scaleFactor * s9Sprite.width, this._scaleFactor * s9Sprite.height));
+ }
+ },
+ _confirmCallback: function () {
+ var config = cc.Dialog._finalConfig;
+ if (config.confirmBtn.callback) {
+ if (config.target) {
+ config.confirmBtn.callback.call(config.target, this);
+ } else {
+ config.confirmBtn.callback(this);
+ }
+ }
+ this.removeFromParent();
+ },
+ _cancelCallback: function () {
+ var config = cc.Dialog._finalConfig;
+ if (config.cancelBtn.callback) {
+ if (config.target) {
+ config.cancelBtn.callback.call(config.target, this);
+ } else {
+ config.cancelBtn.callback(this);
+ }
+ }
+ this.removeFromParent();
+ },
+ onEnter: function () {
+ this._super();
+ var config = cc.Dialog._finalConfig;
+ this.initView();
+ config.onEnter(this);
+ var self = this;
+ self._eventListener = cc.EventListener.create({
+ event: cc.EventListener.TOUCH_ONE_BY_ONE,
+ swallowTouches: true,
+ onTouchBegan: function (touch, event) {
+ return true;
+ }
+ });
+ cc.eventManager.addListener(self._eventListener, self);
+ },
+ onExit: function () {
+ this._super();
+ var config = cc.Dialog._finalConfig;
+ config.onExit(this);
+ this.removeAllChildren();
+ cc.Dialog._dialog = null;
+ cc.eventManager.removeListener(this._eventListener);
+ }
+});
+
+cc.Dialog._dialog = null;
+cc.Dialog._clearDialog = function () {
+ if (cc.Dialog._dialog != null) {
+ cc.Dialog._dialog.removeFromParent();
+ cc.Dialog._dialog = null;
+ }
+}
+
+cc.Dialog.show = function (tips, confirmCb, cancelCb) {
+ if (cc.Dialog._dialog != null) {
+ cc.log("other dialog is on the screen,this dialog can't show now");
+ return;
+ }
+
+ var conf;
+ if (typeof tips == "string") {
+ conf = {
+ messageLabel: {
+ text: tips
+ },
+ confirmBtn: {
+ callback: confirmCb
+ },
+ cancelBtn: {
+ callback: cancelCb
+ }
+ }
+ } else if (typeof tips == "object") {
+ conf = tips;
+ } else {
+ cc.log("tips is invalid");
+ return;
+ }
+
+ cc.Dialog._dialog = new cc.Dialog(conf);
+ if (cc.director.getRunningScene()) {
+ cc.director.getRunningScene().addChild(cc.Dialog._dialog, INT_MAX);
+ } else {
+ cc.log("Current scene is null we can't show dialog");
+ }
+};
+cc.Dialog._useDefaultSource = true;
+cc.Dialog.setUseDefaultSource = function (status) {
+ cc.Dialog._useDefaultSource = status;
+}
+cc.Dialog._defaultConfig = {
+ position: null,
+ target: null,
+ action: null,
+ background: {
+ res: "res_engine/dialog_bg.png"
+ },
+ confirmBtn: {
+ normalRes: "res_engine/dialog_confirm_normal.png",
+ pressRes: "res_engine/dialog_confirm_press.png",
+ text: "确定",
+ textColor: null,
+ fontSize: null,
+ position: null,
+ callback: function () {
+ cc.log("this is confirm callback");
+ }
+ },
+ cancelBtn: {
+ normalRes: "res_engine/dialog_cancel_normal.png",
+ pressRes: "res_engine/dialog_cancel_press.png",
+ text: "取消",
+ textColor: null,
+ position: null,
+ fontSize: null,
+ callback: function () {
+ cc.log("this is cancel callback");
+ }
+ },
+ messageLabel: {
+ text: "",
+ color: null,
+ dimensions: null,
+ fontSize: null,
+ position: null
+ },
+ onEnter: function (dialog) {
+ cc.log("dialog call onEnter");
+ },
+ onExit: function (dialog) {
+ cc.log("dialog call onExit");
+ }
+};
+cc.Dialog._finalConfig = cc.Dialog._defaultConfig;
+cc.Dialog.setConfig = function (config) {
+ this._initData(config);
+};
+cc.Dialog._initData = function (uConfig) {
+ this._finalConfig = cc.clone(this._defaultConfig);
+ var config = this._finalConfig;
+ if (uConfig != null) {
+ if (uConfig.position) {
+ config.position = uConfig.position;
+ }
+ if (uConfig.action) {
+ config.action = uConfig.action;
+ }
+ if (uConfig.background && uConfig.background.res) {
+ config.background = uConfig.background;
+ }
+ if (uConfig.confirmBtn) {
+ var uConfirmBtn = uConfig.confirmBtn;
+ var confirmBtn = config.confirmBtn;
+ confirmBtn.normalRes = uConfirmBtn.normalRes ? uConfirmBtn.normalRes : confirmBtn.normalRes;
+ confirmBtn.pressRes = uConfirmBtn.pressRes ? uConfirmBtn.pressRes : confirmBtn.pressRes;
+ confirmBtn.text = typeof uConfirmBtn.text != "undefined" ? uConfirmBtn.text : confirmBtn.text;
+ confirmBtn.textColor = uConfirmBtn.textColor ? uConfirmBtn.textColor : confirmBtn.textColor;
+ confirmBtn.fontSize = uConfirmBtn.fontSize ? uConfirmBtn.fontSize : confirmBtn.fontSize;
+ confirmBtn.position = uConfirmBtn.position ? uConfirmBtn.position : confirmBtn.position;
+ confirmBtn.callback = uConfirmBtn.callback ? uConfirmBtn.callback : confirmBtn.callback;
+ }
+ if (uConfig.cancelBtn) {
+ var uCancelBtn = uConfig.cancelBtn;
+ var cancelBtn = config.cancelBtn;
+ cancelBtn.normalRes = uCancelBtn.normalRes ? uCancelBtn.normalRes : cancelBtn.normalRes;
+ cancelBtn.pressRes = uCancelBtn.pressRes ? uCancelBtn.pressRes : cancelBtn.pressRes;
+ cancelBtn.text = typeof uCancelBtn.text != "undefined" ? uCancelBtn.text : cancelBtn.text;
+ cancelBtn.textColor = uCancelBtn.textColor ? uCancelBtn.textColor : cancelBtn.textColor;
+ cancelBtn.fontSize = uCancelBtn.fontSize ? uCancelBtn.fontSize : cancelBtn.fontSize;
+ cancelBtn.position = uCancelBtn.position ? uCancelBtn.position : cancelBtn.position;
+ cancelBtn.callback = uCancelBtn.callback ? uCancelBtn.callback : cancelBtn.callback;
+ }
+ if (uConfig.messageLabel) {
+ var uMessageLabel = uConfig.messageLabel;
+ var messageLabel = config.messageLabel;
+ messageLabel.text = typeof uMessageLabel.text != "undefined" ? uMessageLabel.text : messageLabel.text;
+ messageLabel.color = uMessageLabel.color ? uMessageLabel.color : messageLabel.color;
+ messageLabel.fontSize = uMessageLabel.fontSize ? uMessageLabel.fontSize : messageLabel.fontSize;
+ messageLabel.position = uMessageLabel.position ? uMessageLabel.position : messageLabel.position;
+ messageLabel.dimensions = uMessageLabel.dimensions ? uMessageLabel.dimensions : messageLabel.dimensions;
+ }
+ if (uConfig.target) {
+ config.target = uConfig.target;
+ }
+ if (typeof uConfig.onEnter == "function") {
+ config.onEnter = uConfig.onEnter;
+ }
+ if (typeof uConfig.onExit == "function") {
+ config.onExit = uConfig.onExit;
+ }
+ }
+
+ if (!config.cancelBtn.textColor) {
+ config.cancelBtn.textColor = cc.color(255, 255, 255);
+ }
+ if (!config.confirmBtn.textColor) {
+ config.confirmBtn.textColor = cc.color(255, 255, 255);
+ }
+};
+
+cc._NetworkErrorDialog = function () {
+ cc.Dialog._clearDialog();
+ cc.Dialog._dialog = new cc.Dialog(cc._NetworkErrorDialog._config);
+ return cc.Dialog._dialog;
+}
+cc._NetworkErrorDialog._config = {
+ networkError: {},
+ spaceError: {},
+ verifyError: {}
+};
+cc._NetworkErrorDialog._show = function (type, tips, confirmCb, cancelCb) {
+ var networkDialog = cc._NetworkErrorDialog();
+ var config;
+ switch (type) {
+ case "err_network":
+ {
+ config = cc._NetworkErrorDialog._config.networkError;
+ break;
+ }
+ case "err_no_space":
+ {
+ config = cc._NetworkErrorDialog._config.spaceError;
+ break;
+ }
+ case "err_verify":
+ {
+ config = cc._NetworkErrorDialog._config.verifyError;
+ break;
+ }
+ default:
+ {
+ cc.log("type is not found");
+ return;
+ }
+ }
+ if (!networkDialog.getParent()) {
+
+ config.confirmBtn = config.confirmBtn || {};
+ config.confirmBtn.callback = function () {
+ if (confirmCb)
+ confirmCb();
+ }
+
+ config.cancelBtn = config.cancelBtn || {};
+ config.cancelBtn.callback = function () {
+ if (cancelCb)
+ cancelCb();
+ }
+
+ config.messageLabel = config.messageLabel || {};
+ if (typeof config.messageLabel.text == "undefined") {
+ config.messageLabel.text = tips;
+ }
+
+ networkDialog.setConfig(config);
+ if (cc.director.getRunningScene()) {
+ cc.director.getRunningScene().addChild(networkDialog, INT_MAX);
+ } else {
+ cc.log("Current scene is null we can't show dialog");
+ }
+ }
+}
+
+cc._NetworkErrorDialog._setConfig = function (key, config) {
+ if (key && config) {
+ switch (key) {
+ case "err_network":
+ {
+ cc._NetworkErrorDialog._config.networkError = config;
+ break;
+ }
+ case "err_no_space":
+ {
+ cc._NetworkErrorDialog._config.spaceError = config;
+ break;
+ }
+ case "err_verify":
+ {
+ cc._NetworkErrorDialog._config.verifyError = config;
+ break;
+ }
+ }
+ }
+}
+
+cc.runtime = cc.runtime || {};
+
+cc.runtime.setOption = function (promptype, config) {
+ if (config) {
+ switch (promptype) {
+ case "network_error_dialog":
+ {
+ cc._NetworkErrorDialog._setConfig("err_network", config);
+ break;
+ }
+ case "no_space_error_dialog":
+ {
+ cc._NetworkErrorDialog._setConfig("err_no_space", config);
+ break;
+ }
+ case "verify_error_dialog":
+ {
+ cc._NetworkErrorDialog._setConfig("err_verify", config);
+ break;
+ }
+ default :
+ {
+ cc.log("promptype not found please check your promptype");
+ }
+ }
+ } else {
+ cc.log("config is null please check your config");
+ }
+}
+
+/**
+ * only use in JSB get network type
+ * @type {{}|*|cc.network}
+ */
+cc.network = cc.network || {};
+cc.network.type = {
+ NO_NETWORK: -1,
+ MOBILE: 0,
+ WIFI: 1
+}
+cc.network.preloadstatus = {
+ DOWNLOAD: 1,
+ UNZIP: 2
+}
+cc.runtime.network = cc.network;
+
+})();
+
+cc.LoaderScene._preload = cc.LoaderScene.preload;
+cc.LoaderScene.preload = function (arr, cb, target) {
+ // No extension
+ var isGroups = (arr[0] && arr[0].indexOf('.') === -1);
+ if (isGroups) {
+ if (arr.indexOf('boot') === -1) {
+ arr.splice(0, 0, 'boot');
+ }
+ cc.LoaderLayer.preload(arr, cb, target);
+ }
+ else {
+ cc.LoaderScene._preload(arr, cb, target);
+ }
+}
diff --git a/frameworks/cocos2d-html5/extensions/spine/CCSkeleton.js b/frameworks/cocos2d-html5/extensions/spine/CCSkeleton.js
new file mode 100644
index 0000000..97a99f4
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/spine/CCSkeleton.js
@@ -0,0 +1,381 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2014 Shengxiang Chen (Nero Chan)
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * The main namespace of Spine, all classes, functions, properties and constants of Spine are defined in this namespace
+ * @namespace
+ * @name sp
+ */
+var sp = sp || {};
+
+var spine = sp.spine;
+
+/**
+ *
+ * The skeleton of Spine.
+ * Skeleton has a reference to a SkeletonData and stores the state for skeleton instance,
+ * which consists of the current pose's bone SRT, slot colors, and which slot attachments are visible.
+ * Multiple skeletons can use the same SkeletonData (which includes all animations, skins, and attachments).
+ *
+ * @class
+ * @extends cc.Node
+ */
+sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
+ _skeleton: null,
+ _rootBone: null,
+ _timeScale: 1,
+ _debugSlots: false,
+ _debugBones: false,
+ _premultipliedAlpha: false,
+ _ownsSkeletonData: null,
+ _atlas: null,
+
+ /**
+ * The constructor of sp.Skeleton. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
+ */
+ ctor:function(skeletonDataFile, atlasFile, scale){
+ cc.Node.prototype.ctor.call(this);
+
+ if(arguments.length === 0)
+ this.init();
+ else
+ this.initWithArgs(skeletonDataFile, atlasFile, scale);
+ },
+
+ _createRenderCmd:function () {
+ if(cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new sp.Skeleton.CanvasRenderCmd(this);
+ else
+ return new sp.Skeleton.WebGLRenderCmd(this);
+ },
+
+ /**
+ * Initializes a sp.Skeleton. please do not call this function by yourself, you should pass the parameters to constructor to initialize it.
+ */
+ init: function () {
+ cc.Node.prototype.init.call(this);
+ this._premultipliedAlpha = (cc._renderType === cc.game.RENDER_TYPE_WEBGL && cc.OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA);
+ },
+
+ onEnter: function () {
+ cc.Node.prototype.onEnter.call(this);
+ this.scheduleUpdate();
+ },
+
+ onExit: function () {
+ this.unscheduleUpdate();
+ cc.Node.prototype.onExit.call(this);
+ },
+
+ /**
+ * Sets whether open debug slots.
+ * @param {boolean} enable true to open, false to close.
+ */
+ setDebugSolots:function(enable){
+ this._debugSlots = enable;
+ },
+
+ /**
+ * Sets whether open debug bones.
+ * @param {boolean} enable
+ */
+ setDebugBones:function(enable){
+ this._debugBones = enable;
+ },
+
+ /**
+ * Sets whether open debug slots.
+ * @param {boolean} enabled true to open, false to close.
+ */
+ setDebugSlotsEnabled: function(enabled) {
+ this._debugSlots = enabled;
+ },
+
+ /**
+ * Gets whether open debug slots.
+ * @returns {boolean} true to open, false to close.
+ */
+ getDebugSlotsEnabled: function() {
+ return this._debugSlots;
+ },
+
+ /**
+ * Sets whether open debug bones.
+ * @param {boolean} enabled
+ */
+ setDebugBonesEnabled: function(enabled) {
+ this._debugBones = enabled;
+ },
+
+ /**
+ * Gets whether open debug bones.
+ * @returns {boolean} true to open, false to close.
+ */
+ getDebugBonesEnabled: function() {
+ return this._debugBones;
+ },
+
+ /**
+ * Sets the time scale of sp.Skeleton.
+ * @param {Number} scale
+ */
+ setTimeScale:function(scale){
+ this._timeScale = scale;
+ },
+
+ getTimeScale: function(){
+ return this._timeScale;
+ },
+
+ /**
+ * Initializes sp.Skeleton with Data.
+ * @param {sp.spine.SkeletonData|String} skeletonDataFile
+ * @param {String|spine.Atlas|spine.SkeletonData} atlasFile atlas filename or atlas data or owns SkeletonData
+ * @param {Number} [scale] scale can be specified on the JSON or binary loader which will scale the bone positions, image sizes, and animation translations.
+ */
+ initWithArgs: function (skeletonDataFile, atlasFile, scale) {
+ var argSkeletonFile = skeletonDataFile, argAtlasFile = atlasFile,
+ skeletonData, atlas, ownsSkeletonData;
+
+ if (cc.isString(argSkeletonFile)) {
+ if (cc.isString(argAtlasFile)) {
+ var data = cc.loader.getRes(argAtlasFile);
+ sp._atlasLoader.setAtlasFile(argAtlasFile);
+ atlas = new spine.TextureAtlas(data, sp._atlasLoader.load.bind(sp._atlasLoader));
+ } else {
+ atlas = atlasFile;
+ }
+ scale = scale || 1 / cc.director.getContentScaleFactor();
+
+ var attachmentLoader = new spine.AtlasAttachmentLoader(atlas);
+ var skeletonJsonReader = new spine.SkeletonJson(attachmentLoader);
+ skeletonJsonReader.scale = scale;
+
+ var skeletonJson = cc.loader.getRes(argSkeletonFile);
+ skeletonData = skeletonJsonReader.readSkeletonData(skeletonJson);
+ atlas.dispose(skeletonJsonReader);
+ ownsSkeletonData = true;
+ } else {
+ skeletonData = skeletonDataFile;
+ ownsSkeletonData = atlasFile;
+ }
+ this.setSkeletonData(skeletonData, ownsSkeletonData);
+ this.init();
+ },
+
+ /**
+ * Returns the bounding box of sp.Skeleton.
+ * @returns {cc.Rect}
+ */
+ getBoundingBox: function () {
+ var minX = cc.FLT_MAX, minY = cc.FLT_MAX, maxX = cc.FLT_MIN, maxY = cc.FLT_MIN;
+ var scaleX = this.getScaleX(), scaleY = this.getScaleY(), vertices,
+ slots = this._skeleton.slots, VERTEX = spine.RegionAttachment;
+
+ for (var i = 0, slotCount = slots.length; i < slotCount; ++i) {
+ var slot = slots[i];
+ var attachment = slot.attachment;
+ if (!attachment || !(attachment instanceof spine.RegionAttachment))
+ continue;
+ vertices = spine.Utils.setArraySize(new Array(), 8, 0);
+ attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
+ minX = Math.min(minX, vertices[VERTEX.OX1] * scaleX, vertices[VERTEX.OX4] * scaleX, vertices[VERTEX.OX2] * scaleX, vertices[VERTEX.OX3] * scaleX);
+ minY = Math.min(minY, vertices[VERTEX.OY1] * scaleY, vertices[VERTEX.OY4] * scaleY, vertices[VERTEX.OY2] * scaleY, vertices[VERTEX.OY3] * scaleY);
+ maxX = Math.max(maxX, vertices[VERTEX.OX1] * scaleX, vertices[VERTEX.OX4] * scaleX, vertices[VERTEX.OX2] * scaleX, vertices[VERTEX.OX3] * scaleX);
+ maxY = Math.max(maxY, vertices[VERTEX.OY1] * scaleY, vertices[VERTEX.OY4] * scaleY, vertices[VERTEX.OY2] * scaleY, vertices[VERTEX.OY3] * scaleY);
+ }
+ var position = this.getPosition();
+ return cc.rect(position.x + minX, position.y + minY, maxX - minX, maxY - minY);
+ },
+
+ /**
+ * Computes the world SRT from the local SRT for each bone.
+ */
+ updateWorldTransform: function () {
+ this._skeleton.updateWorldTransform();
+ },
+
+ /**
+ * Sets the bones and slots to the setup pose.
+ */
+ setToSetupPose: function () {
+ this._skeleton.setToSetupPose();
+ },
+
+ /**
+ * Sets the bones to the setup pose, using the values from the `BoneData` list in the `SkeletonData`.
+ */
+ setBonesToSetupPose: function () {
+ this._skeleton.setBonesToSetupPose();
+ },
+
+ /**
+ * Sets the slots to the setup pose, using the values from the `SlotData` list in the `SkeletonData`.
+ */
+ setSlotsToSetupPose: function () {
+ this._skeleton.setSlotsToSetupPose();
+ },
+
+ /**
+ * Finds a bone by name. This does a string comparison for every bone.
+ * @param {String} boneName
+ * @returns {sp.spine.Bone}
+ */
+ findBone: function (boneName) {
+ return this._skeleton.findBone(boneName);
+ },
+
+ /**
+ * Finds a slot by name. This does a string comparison for every slot.
+ * @param {String} slotName
+ * @returns {sp.spine.Slot}
+ */
+ findSlot: function (slotName) {
+ return this._skeleton.findSlot(slotName);
+ },
+
+ /**
+ * Finds a skin by name and makes it the active skin. This does a string comparison for every skin. Note that setting the skin does not change which attachments are visible.
+ * @param {string} skinName
+ * @returns {sp.spine.Skin}
+ */
+ setSkin: function (skinName) {
+ return this._skeleton.setSkinByName(skinName);
+ },
+
+ /**
+ * Returns the attachment for the slot and attachment name. The skeleton looks first in its skin, then in the skeleton data’s default skin.
+ * @param {String} slotName
+ * @param {String} attachmentName
+ * @returns {sp.spine.Attachment}
+ */
+ getAttachment: function (slotName, attachmentName) {
+ return this._skeleton.getAttachmentByName(slotName, attachmentName);
+ },
+
+ /**
+ * Sets the attachment for the slot and attachment name. The skeleton looks first in its skin, then in the skeleton data’s default skin.
+ * @param {String} slotName
+ * @param {String} attachmentName
+ */
+ setAttachment: function (slotName, attachmentName) {
+ this._skeleton.setAttachment(slotName, attachmentName);
+ },
+
+ /**
+ * Sets the premultiplied alpha value to sp.Skeleton.
+ * @param {Number} alpha
+ */
+ setPremultipliedAlpha: function (premultiplied) {
+ this._premultipliedAlpha = premultiplied;
+ },
+
+ /**
+ * Returns whether to enable premultiplied alpha.
+ * @returns {boolean}
+ */
+ isPremultipliedAlpha: function () {
+ return this._premultipliedAlpha;
+ },
+
+ /**
+ * Sets skeleton data to sp.Skeleton.
+ * @param {sp.spine.SkeletonData} skeletonData
+ * @param {sp.spine.SkeletonData} ownsSkeletonData
+ */
+ setSkeletonData: function (skeletonData, ownsSkeletonData) {
+ if(skeletonData.width != null && skeletonData.height != null)
+ this.setContentSize(skeletonData.width / cc.director.getContentScaleFactor(), skeletonData.height / cc.director.getContentScaleFactor());
+
+ this._skeleton = new spine.Skeleton(skeletonData);
+ this._skeleton.updateWorldTransform();
+ this._rootBone = this._skeleton.getRootBone();
+ this._ownsSkeletonData = ownsSkeletonData;
+
+ this._renderCmd._createChildFormSkeletonData();
+ },
+
+ /**
+ * Return the renderer of attachment.
+ * @param {sp.spine.RegionAttachment|sp.spine.BoundingBoxAttachment} regionAttachment
+ * @returns {sp.spine.TextureAtlasRegion}
+ */
+ getTextureAtlas: function (regionAttachment) {
+ return regionAttachment.region;
+ },
+
+ /**
+ * Returns the blendFunc of sp.Skeleton.
+ * @returns {cc.BlendFunc}
+ */
+ getBlendFunc: function () {
+ var slot = this._skeleton.drawOrder[0];
+ if (slot) {
+ var blend = this._renderCmd._getBlendFunc(slot.data.blendMode, this._premultipliedAlpha);
+ return blend;
+ }
+ else {
+ return {};
+ }
+ },
+
+ /**
+ * Sets the blendFunc of sp.Skeleton, it won't have any effect for skeleton, skeleton is using slot's data to determine the blend function.
+ * @param {cc.BlendFunc|Number} src
+ * @param {Number} [dst]
+ */
+ setBlendFunc: function (src, dst) {
+ return;
+ },
+
+ /**
+ * Update will be called automatically every frame if "scheduleUpdate" is called when the node is "live".
+ * @param {Number} dt Delta time since last update
+ */
+ update: function (dt) {
+ this._skeleton.update(dt);
+ }
+});
+
+cc.defineGetterSetter(sp.Skeleton.prototype, "opacityModifyRGB", sp.Skeleton.prototype.isOpacityModifyRGB);
+
+// For renderer webgl to identify skeleton's default texture and blend function
+cc.defineGetterSetter(sp.Skeleton.prototype, "_blendFunc", sp.Skeleton.prototype.getBlendFunc);
+cc.defineGetterSetter(sp.Skeleton.prototype, '_texture', function () {
+ return this._renderCmd._currTexture;
+});
+
+/**
+ * Creates a skeleton object.
+ * @deprecated since v3.0, please use new sp.Skeleton(skeletonDataFile, atlasFile, scale) instead.
+ * @param {spine.SkeletonData|String} skeletonDataFile
+ * @param {String|spine.Atlas|spine.SkeletonData} atlasFile atlas filename or atlas data or owns SkeletonData
+ * @param {Number} [scale] scale can be specified on the JSON or binary loader which will scale the bone positions, image sizes, and animation translations.
+ * @returns {sp.Skeleton}
+ */
+sp.Skeleton.create = function (skeletonDataFile, atlasFile/* or atlas*/, scale) {
+ return new sp.Skeleton(skeletonDataFile, atlasFile, scale);
+};
diff --git a/frameworks/cocos2d-html5/extensions/spine/CCSkeletonAnimation.js b/frameworks/cocos2d-html5/extensions/spine/CCSkeletonAnimation.js
new file mode 100644
index 0000000..17f0f25
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/spine/CCSkeletonAnimation.js
@@ -0,0 +1,351 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2014 Shengxiang Chen (Nero Chan)
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+sp._atlasLoader = {
+ spAtlasFile:null,
+ setAtlasFile:function(spAtlasFile){
+ this.spAtlasFile = spAtlasFile;
+ },
+ load:function(line){
+ var texturePath = cc.path.join(cc.path.dirname(this.spAtlasFile), line);
+ var texture = cc.textureCache.addImage(texturePath);
+ var tex = new sp.SkeletonTexture({ width: texture.getPixelsWide(), height: texture.getPixelsHigh() });
+ tex.setRealTexture(texture);
+ return tex;
+ },
+ unload:function(obj){
+ }
+};
+
+/**
+ * The event type of spine skeleton animation. It contains event types: START(0), END(1), COMPLETE(2), EVENT(3).
+ * @constant
+ * @type {{START: number, END: number, COMPLETE: number, EVENT: number}}
+ */
+sp.ANIMATION_EVENT_TYPE = {
+ START: 0,
+ INTERRUPT: 1,
+ END: 2,
+ DISPOSE: 3,
+ COMPLETE: 4,
+ EVENT: 5
+};
+
+sp.TrackEntryListeners = function (startListener, endListener, completeListener, eventListener, interruptListener, disposeListener) {
+ this.startListener = startListener || null;
+ this.endListener = endListener || null;
+ this.completeListener = completeListener || null;
+ this.eventListener = eventListener || null;
+ this.interruptListener = interruptListener || null;
+ this.disposeListener = disposeListener || null;
+ this.callback = null;
+ this.callbackTarget = null;
+ this.skeletonNode = null;
+};
+
+var proto = sp.TrackEntryListeners.prototype;
+proto.start = function(trackEntry) {
+ if (this.startListener) {
+ this.startListener(trackEntry);
+ }
+ if (this.callback) {
+ this.callback.call(this.callbackTarget, this.skeletonNode, trackEntry, sp.ANIMATION_EVENT_TYPE.START, null, 0);
+ }
+};
+
+proto.interrupt = function(trackEntry) {
+ if (this.interruptListener) {
+ this.interruptListener(trackEntry);
+ }
+ if (this.callback) {
+ this.callback.call(this.callbackTarget, this.skeletonNode, trackEntry, sp.ANIMATION_EVENT_TYPE.INTERRUPT, null, 0);
+ }
+};
+
+proto.end = function (trackEntry) {
+ if (this.endListener) {
+ this.endListener(trackEntry);
+ }
+ if (this.callback) {
+ this.callback.call(this.callbackTarget, this.skeletonNode, trackEntry, sp.ANIMATION_EVENT_TYPE.END, null, 0);
+ }
+};
+
+proto.dispose = function (trackEntry) {
+ if (this.disposeListener) {
+ this.disposeListener(trackEntry);
+ }
+ if (this.callback) {
+ this.callback.call(this.callbackTarget, this.skeletonNode, trackEntry, sp.ANIMATION_EVENT_TYPE.DISPOSE, null, 0);
+ }
+};
+
+proto.complete = function (trackEntry) {
+ var loopCount = Math.floor(trackEntry.trackTime / trackEntry.animationEnd);
+ if (this.completeListener) {
+ this.completeListener(trackEntry, loopCount);
+ }
+ if (this.callback) {
+ this.callback.call(this.callbackTarget, this.skeletonNode, trackEntry, sp.ANIMATION_EVENT_TYPE.COMPLETE, null, loopCount);
+ }
+};
+
+proto.event = function (trackEntry, event) {
+ if (this.eventListener) {
+ this.eventListener(trackEntry, event);
+ }
+ if (this.callback) {
+ this.callback.call(this.callbackTarget, this.skeletonNode, trackEntry, sp.ANIMATION_EVENT_TYPE.EVENT, event, 0);
+ }
+};
+
+sp.TrackEntryListeners.getListeners = function(entry){
+ if(!entry.listener){
+ entry.listener = new sp.TrackEntryListeners();
+ }
+ return entry.listener;
+};
+
+/**
+ * The skeleton animation of spine. It updates animation's state and skeleton's world transform.
+ * @class
+ * @extends sp.Skeleton
+ * @example
+ * var spineBoy = new sp.SkeletonAnimation('res/skeletons/spineboy.json', 'res/skeletons/spineboy.atlas');
+ * this.addChild(spineBoy, 4);
+ */
+sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
+ _state: null,
+
+ _ownsAnimationStateData: false,
+ _listener: null,
+
+ /**
+ * Initializes a sp.SkeletonAnimation. please do not call this function by yourself, you should pass the parameters to constructor to initialize it.
+ * @override
+ */
+ init: function () {
+ sp.Skeleton.prototype.init.call(this);
+ this._ownsAnimationStateData = true;
+ this.setAnimationStateData(new spine.AnimationStateData(this._skeleton.data));
+ },
+
+ /**
+ * Sets animation state data to sp.SkeletonAnimation.
+ * @param {sp.spine.AnimationStateData} stateData
+ */
+ setAnimationStateData: function (stateData) {
+ var state = new spine.AnimationState(stateData);
+ this._listener = new sp.TrackEntryListeners();
+ state.rendererObject = this;
+ state.addListener(this._listener);
+ this._state = state;
+ },
+
+ /**
+ * Mix applies all keyframe values, interpolated for the specified time and mixed with the current values.
+ * @param {String} fromAnimation
+ * @param {String} toAnimation
+ * @param {Number} duration
+ */
+ setMix: function (fromAnimation, toAnimation, duration) {
+ this._state.data.setMixWith(fromAnimation, toAnimation, duration);
+ },
+
+ /**
+ * Sets event listener of sp.SkeletonAnimation.
+ * @param {Object} target
+ * @param {Function} callback
+ */
+ setAnimationListener: function (target, callback) {
+ this._listener.callbackTarget = target;
+ this._listener.callback = callback;
+ this._listener.skeletonNode = this;
+ },
+
+ /**
+ * Set the current animation. Any queued animations are cleared.
+ * @param {Number} trackIndex
+ * @param {String} name
+ * @param {Boolean} loop
+ * @returns {sp.spine.TrackEntry|null}
+ */
+ setAnimation: function (trackIndex, name, loop) {
+ var animation = this._skeleton.data.findAnimation(name);
+ if (!animation) {
+ cc.log("Spine: Animation not found: " + name);
+ return null;
+ }
+ return this._state.setAnimationWith(trackIndex, animation, loop);
+ },
+
+ /**
+ * Adds an animation to be played delay seconds after the current or last queued animation.
+ * @param {Number} trackIndex
+ * @param {String} name
+ * @param {Boolean} loop
+ * @param {Number} [delay=0]
+ * @returns {sp.spine.TrackEntry|null}
+ */
+ addAnimation: function (trackIndex, name, loop, delay) {
+ delay = delay == null ? 0 : delay;
+ var animation = this._skeleton.data.findAnimation(name);
+ if (!animation) {
+ cc.log("Spine: Animation not found:" + name);
+ return null;
+ }
+ return this._state.addAnimationWith(trackIndex, animation, loop, delay);
+ },
+
+ /**
+ * Find animation with specified name
+ * @param {String} name
+ * @returns {sp.spine.Animation|null}
+ */
+ findAnimation: function (name) {
+ return this._skeleton.data.findAnimation(name);
+ },
+
+ /**
+ * Returns track entry by trackIndex.
+ * @param trackIndex
+ * @returns {sp.spine.TrackEntry|null}
+ */
+ getCurrent: function (trackIndex) {
+ return this._state.getCurrent(trackIndex);
+ },
+
+ /**
+ * Clears all tracks of animation state.
+ */
+ clearTracks: function () {
+ this._state.clearTracks();
+ },
+
+ /**
+ * Clears track of animation state by trackIndex.
+ * @param {Number} trackIndex
+ */
+ clearTrack: function (trackIndex) {
+ this._state.clearTrack(trackIndex);
+ },
+
+ /**
+ * Update will be called automatically every frame if "scheduleUpdate" is called when the node is "live".
+ * It updates animation's state and skeleton's world transform.
+ * @param {Number} dt Delta time since last update
+ * @override
+ */
+ update: function (dt) {
+ this._super(dt);
+ dt *= this._timeScale;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.contentDirty);
+ this._state.update(dt);
+ this._state.apply(this._skeleton);
+ this._skeleton.updateWorldTransform();
+ this._renderCmd._updateChild();
+ },
+
+ /**
+ * Set the start event listener.
+ * @param {function} listener
+ */
+ setStartListener: function(listener){
+ this._listener.startListener = listener;
+ },
+
+ /**
+ * Set the interrupt listener
+ * @param {function} listener
+ */
+ setInterruptListener: function(listener) {
+ this._listener.interruptListener = listener;
+ },
+
+ /**
+ * Set the end event listener.
+ * @param {function} listener
+ */
+ setEndListener: function(listener) {
+ this._listener.endListener = listener;
+ },
+
+ /**
+ * Set the dispose listener
+ * @param {function} listener
+ */
+ setDisposeListener: function(listener) {
+ this._listener.disposeListener = listener;
+ },
+
+ setCompleteListener: function(listener) {
+ this._listener.completeListener = listener;
+ },
+
+ setEventListener: function(listener){
+ this._listener.eventListener = listener;
+ },
+
+ setTrackStartListener: function(entry, listener){
+ sp.TrackEntryListeners.getListeners(entry).startListener = listener;
+ },
+
+ setTrackInterruptListener: function(entry, listener){
+ sp.TrackEntryListeners.getListeners(entry).interruptListener = listener;
+ },
+
+ setTrackEndListener: function(entry, listener){
+ sp.TrackEntryListeners.getListeners(entry).endListener = listener;
+ },
+
+ setTrackDisposeListener: function(entry, listener){
+ sp.TrackEntryListeners.getListeners(entry).disposeListener = listener;
+ },
+
+ setTrackCompleteListener: function(entry, listener){
+ sp.TrackEntryListeners.getListeners(entry).completeListener = listener;
+ },
+
+ setTrackEventListener: function(entry, listener){
+ sp.TrackEntryListeners.getListeners(entry).eventListener = listener;
+ },
+
+ getState: function(){
+ return this._state;
+ }
+});
+
+/**
+ * Creates a skeleton animation object.
+ * @deprecated since v3.0, please use new sp.SkeletonAnimation(skeletonDataFile, atlasFile, scale) instead.
+ * @param {spine.SkeletonData|String} skeletonDataFile
+ * @param {String|spine.Atlas|spine.SkeletonData} atlasFile atlas filename or atlas data or owns SkeletonData
+ * @param {Number} [scale] scale can be specified on the JSON or binary loader which will scale the bone positions, image sizes, and animation translations.
+ * @returns {sp.Skeleton}
+ */
+sp.SkeletonAnimation.createWithJsonFile = sp.SkeletonAnimation.create = function (skeletonDataFile, atlasFile/* or atlas*/, scale) {
+ return new sp.SkeletonAnimation(skeletonDataFile, atlasFile, scale);
+};
diff --git a/frameworks/cocos2d-html5/extensions/spine/CCSkeletonCanvasRenderCmd.js b/frameworks/cocos2d-html5/extensions/spine/CCSkeletonCanvasRenderCmd.js
new file mode 100644
index 0000000..f31924e
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/spine/CCSkeletonCanvasRenderCmd.js
@@ -0,0 +1,247 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+
+var spine = sp.spine;
+
+sp.Skeleton.CanvasRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+};
+
+var proto = sp.Skeleton.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+proto.constructor = sp.Skeleton.CanvasRenderCmd;
+
+proto.rendering = function (wrapper, scaleX, scaleY) {
+ var node = this._node, i, n, slot, slotNode;
+ wrapper = wrapper || cc._renderContext;
+
+ var locSkeleton = node._skeleton, drawOrder = locSkeleton.drawOrder;
+ for (i = 0, n = drawOrder.length; i < n; i++) {
+ slot = drawOrder[i];
+ slotNode = slot._slotNode;
+ if (slotNode._visible && slotNode._renderCmd && slot.currentSprite) {
+ slotNode._renderCmd.transform(this, true);
+ slot.currentSprite._renderCmd.rendering(wrapper, scaleX, scaleY);
+ slotNode._renderCmd._dirtyFlag = slot.currentSprite._renderCmd._dirtyFlag = 0;
+ }
+ }
+
+ if (!node._debugSlots && !node._debugBones)
+ return;
+
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+ wrapper.setGlobalAlpha(1);
+ var attachment, drawingUtil = cc._drawingUtil;
+ if (node._debugSlots) {
+ // Slots.
+ drawingUtil.setDrawColor(0, 0, 255, 255);
+ drawingUtil.setLineWidth(1);
+
+ var points = [];
+ for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
+ slot = locSkeleton.drawOrder[i];
+ if (!slot.attachment || !(slot.attachment instanceof spine.RegionAttachment))
+ continue;
+ attachment = slot.attachment;
+ this._updateRegionAttachmentSlot(attachment, slot, points);
+ drawingUtil.drawPoly(points, 4, true);
+ }
+ }
+
+ if (node._debugBones) {
+ // Bone lengths.
+ var bone;
+ drawingUtil.setLineWidth(2);
+ drawingUtil.setDrawColor(255, 0, 0, 255);
+
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ var x = bone.data.length * bone.a + bone.worldX;
+ var y = bone.data.length * bone.c + bone.worldY;
+ drawingUtil.drawLine(
+ {x: bone.worldX, y: bone.worldY},
+ {x: x, y: y});
+ }
+
+ // Bone origins.
+ var pointSize = 4;
+ drawingUtil.setDrawColor(0, 0, 255, 255); // Root bone is blue.
+
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ drawingUtil.drawPoint({x: bone.worldX, y: bone.worldY}, pointSize);
+ if (i === 0)
+ drawingUtil.setDrawColor(0, 255, 0, 255);
+ }
+ }
+};
+
+proto.updateStatus = function() {
+ this.originUpdateStatus();
+ this._updateCurrentRegions();
+ this._regionFlag = cc.Node.CanvasRenderCmd.RegionStatus.DirtyDouble;
+ this._dirtyFlag &= ~cc.Node._dirtyFlags.contentDirty;
+};
+
+proto.getLocalBB = function() {
+ return this._node.getBoundingBox();
+};
+
+proto._updateRegionAttachmentSlot = function (attachment, slot, points) {
+ if (!points)
+ return;
+
+ var vertices = spine.Utils.setArraySize(new Array(), 8, 0);
+ attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
+ var VERTEX = spine.RegionAttachment;
+ points.length = 0;
+ points.push(cc.p(vertices[VERTEX.OX1], vertices[VERTEX.OY1]));
+ points.push(cc.p(vertices[VERTEX.OX4], vertices[VERTEX.OY4]));
+ points.push(cc.p(vertices[VERTEX.OX3], vertices[VERTEX.OY3]));
+ points.push(cc.p(vertices[VERTEX.OX2], vertices[VERTEX.OY2]));
+};
+
+proto._createChildFormSkeletonData = function () {
+ var node = this._node;
+ var locSkeleton = node._skeleton, spriteName, sprite;
+ for (var i = 0, n = locSkeleton.slots.length; i < n; i++) {
+ var slot = locSkeleton.slots[i], attachment = slot.attachment;
+ var slotNode = new cc.Node();
+ slot._slotNode = slotNode;
+
+ if (attachment instanceof spine.RegionAttachment) {
+ spriteName = attachment.region.name;
+ sprite = this._createSprite(slot, attachment);
+ slot.currentSprite = sprite;
+ slot.currentSpriteName = spriteName;
+ slotNode.addChild(sprite);
+ } else if (attachment instanceof spine.MeshAttachment) {
+ //todo for mesh
+ }
+ }
+};
+
+var loaded = function (sprite, texture, attachment) {
+ var rendererObject = attachment.region;
+ var rect = new cc.Rect(rendererObject.x, rendererObject.y, rendererObject.width, rendererObject.height);
+ sprite.initWithTexture(texture, rect, rendererObject.rotate, false);
+ sprite._rect.width = attachment.width;
+ sprite._rect.height = attachment.height;
+ sprite.setContentSize(attachment.width, attachment.height);
+ sprite.setRotation(-attachment.rotation);
+ sprite.setScale(rendererObject.width / rendererObject.originalWidth * attachment.scaleX,
+ rendererObject.height / rendererObject.originalHeight * attachment.scaleY);
+};
+
+proto._createSprite = function (slot, attachment) {
+ var rendererObject = attachment.region;
+ var texture = rendererObject.texture.getRealTexture();
+ var sprite = new cc.Sprite();
+ if (texture.isLoaded()) {
+ loaded(sprite, texture, attachment);
+ } else {
+ texture.addEventListener('load', function () {
+ loaded(sprite, texture, attachment);
+ }, this);
+ }
+ slot.sprites = slot.sprites || {};
+ slot.sprites[rendererObject.name] = sprite;
+ return sprite;
+};
+
+proto._updateChild = function () {
+ var locSkeleton = this._node._skeleton, slots = locSkeleton.slots;
+ var color = this._displayedColor, opacity = this._displayedOpacity;
+ var i, n, selSprite, ax, ay;
+
+ var slot, attachment, slotNode;
+ for (i = 0, n = slots.length; i < n; i++) {
+ slot = slots[i];
+ attachment = slot.attachment;
+ slotNode = slot._slotNode;
+ if (!attachment) {
+ slotNode.setVisible(false);
+ continue;
+ }
+ if (attachment instanceof spine.RegionAttachment) {
+ if (attachment.region) {
+ if (!slot.currentSpriteName || slot.currentSpriteName !== attachment.name) {
+ var spriteName = attachment.region.name;
+ if (slot.currentSprite !== undefined)
+ slot.currentSprite.setVisible(false);
+ slot.sprites = slot.sprites || {};
+ if (slot.sprites[spriteName] !== undefined)
+ slot.sprites[spriteName].setVisible(true);
+ else {
+ var sprite = this._createSprite(slot, attachment);
+ slotNode.addChild(sprite);
+ }
+ slot.currentSprite = slot.sprites[spriteName];
+ slot.currentSpriteName = spriteName;
+ }
+ }
+ var bone = slot.bone;
+ if (attachment.region.offsetX === 0 && attachment.region.offsetY === 0) {
+ ax = attachment.x;
+ ay = attachment.y;
+ }
+ else {
+ //var regionScaleX = attachment.width / attachment.regionOriginalWidth * attachment.scaleX;
+ //ax = attachment.x + attachment.regionOffsetX * regionScaleX - (attachment.width * attachment.scaleX - attachment.regionWidth * regionScaleX) / 2;
+ ax = (attachment.offset[0] + attachment.offset[4]) * 0.5;
+ ay = (attachment.offset[1] + attachment.offset[5]) * 0.5;
+ }
+ slotNode.setPosition(bone.worldX + ax * bone.a + ay * bone.b, bone.worldY + ax * bone.c + ay * bone.d);
+ slotNode.setScale(bone.getWorldScaleX(), bone.getWorldScaleY());
+
+ //set the color and opacity
+ selSprite = slot.currentSprite;
+ selSprite._flippedX = bone.skeleton.flipX;
+ selSprite._flippedY = bone.skeleton.flipY;
+ if (selSprite._flippedY || selSprite._flippedX) {
+ slotNode.setRotation(bone.getWorldRotationX());
+ selSprite.setRotation(attachment.rotation);
+ } else {
+ slotNode.setRotation(-bone.getWorldRotationX());
+ selSprite.setRotation(-attachment.rotation);
+ }
+
+ //hack for sprite
+ selSprite._renderCmd._displayedOpacity = 0 | (opacity * slot.color.a);
+ var r = 0 | (color.r * slot.color.r), g = 0 | (color.g * slot.color.g), b = 0 | (color.b * slot.color.b);
+ selSprite.setColor(cc.color(r, g, b));
+ selSprite._renderCmd._updateColor();
+ } else if (attachment instanceof spine.MeshAttachment) {
+ // Can not render mesh
+ } else {
+ slotNode.setVisible(false);
+ continue;
+ }
+ slotNode.setVisible(true);
+ }
+};
+
+})();
diff --git a/frameworks/cocos2d-html5/extensions/spine/CCSkeletonTexture.js b/frameworks/cocos2d-html5/extensions/spine/CCSkeletonTexture.js
new file mode 100644
index 0000000..9250369
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/spine/CCSkeletonTexture.js
@@ -0,0 +1,67 @@
+/****************************************************************************
+ Copyright (c) 2017 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+sp.SkeletonTexture = function (image) {
+ sp.spine.Texture.call(this, image);
+};
+cc.inherits(sp.SkeletonTexture, sp.spine.Texture);
+cc.extend(sp.SkeletonTexture.prototype, {
+ name: 'sp.SkeletonTexture',
+ _texture: null,
+
+ setRealTexture: function(tex) {
+ this._texture = tex;
+ },
+
+ getRealTexture: function() {
+ return this._texture;
+ },
+
+ setFilters: function(minFilter, magFilter) {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ var gl = cc._renderContext;
+ this.bind();
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
+ }
+ },
+
+ setWraps: function(uWrap, vWrap) {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ var gl = cc._renderContext;
+ this.bind();
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, uWrap);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, vWrap);
+ }
+ },
+
+ dispose: function() {
+ },
+
+ bind: function() {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ cc.glBindTexture2D(this._texture);
+ }
+ }
+});
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/spine/CCSkeletonWebGLRenderCmd.js b/frameworks/cocos2d-html5/extensions/spine/CCSkeletonWebGLRenderCmd.js
new file mode 100644
index 0000000..535e4c0
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/spine/CCSkeletonWebGLRenderCmd.js
@@ -0,0 +1,347 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+(function () {
+
+var spine = sp.spine;
+
+sp.Skeleton.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+ this._currTexture = null;
+ this._currBlendFunc = {};
+ this.vertexType = cc.renderer.VertexType.CUSTOM;
+ this.setShaderProgram(cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR));
+};
+
+var proto = sp.Skeleton.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+proto.constructor = sp.Skeleton.WebGLRenderCmd;
+
+proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset){
+ var node = this._node;
+ var color = this._displayedColor, locSkeleton = node._skeleton;
+
+ var attachment, slot, i, n;
+ var premultiAlpha = node._premultipliedAlpha;
+
+ locSkeleton.r = color.r / 255;
+ locSkeleton.g = color.g / 255;
+ locSkeleton.b = color.b / 255;
+ locSkeleton.a = this._displayedOpacity / 255;
+ if (premultiAlpha) {
+ locSkeleton.r *= locSkeleton.a;
+ locSkeleton.g *= locSkeleton.a;
+ locSkeleton.b *= locSkeleton.a;
+ }
+
+ var debugSlotsInfo = null;
+ if (this._node._debugSlots) {
+ debugSlotsInfo = [];
+ }
+
+ for (i = 0, n = locSkeleton.drawOrder.length; i < n; i++) {
+ slot = locSkeleton.drawOrder[i];
+ if (!slot.attachment)
+ continue;
+ attachment = slot.attachment;
+
+ // get the vertices length
+ var vertCount = 0;
+ if (attachment instanceof spine.RegionAttachment) {
+ vertCount = 6; // a quad = two triangles = six vertices
+ }
+ else if (attachment instanceof spine.MeshAttachment) {
+ vertCount = attachment.regionUVs.length / 2;
+ }
+ else {
+ continue;
+ }
+
+ // no vertices to render
+ if (vertCount === 0) {
+ continue;
+ }
+
+ var regionTextureAtlas = node.getTextureAtlas(attachment);
+
+ // Broken for changing batch info
+ this._currTexture = regionTextureAtlas.texture.getRealTexture();
+ var batchBroken = cc.renderer._updateBatchedInfo(this._currTexture, this._getBlendFunc(slot.data.blendMode, premultiAlpha), this._glProgramState);
+
+ // keep the same logic with RendererWebGL.js, avoid vertex data overflow
+ var uploadAll = vertexDataOffset / 6 + vertCount > (cc.BATCH_VERTEX_COUNT - 200) * 0.5;
+ // Broken for vertex data overflow
+ if (!batchBroken && uploadAll) {
+ // render the cached data
+ cc.renderer._batchRendering();
+ batchBroken = true;
+ }
+ if (batchBroken) {
+ vertexDataOffset = 0;
+ }
+
+ // update the vertex buffer
+ var slotDebugPoints = null;
+ if (attachment instanceof spine.RegionAttachment) {
+ slotDebugPoints = this._uploadRegionAttachmentData(attachment, slot, premultiAlpha, f32buffer, ui32buffer, vertexDataOffset);
+ }
+ else if (attachment instanceof spine.MeshAttachment) {
+ this._uploadMeshAttachmentData(attachment, slot, premultiAlpha, f32buffer, ui32buffer, vertexDataOffset);
+ }
+ else {
+ continue;
+ }
+
+ if (this._node._debugSlots) {
+ debugSlotsInfo[i] = slotDebugPoints;
+ }
+
+ // update the index buffer
+ if (attachment instanceof spine.RegionAttachment) {
+ cc.renderer._increaseBatchingSize(vertCount, cc.renderer.VertexType.TRIANGLE);
+ } else {
+ cc.renderer._increaseBatchingSize(vertCount, cc.renderer.VertexType.CUSTOM, attachment.triangles);
+ }
+
+ // update the index data
+ vertexDataOffset += vertCount * 6;
+ }
+
+ if (node._debugBones || node._debugSlots) {
+ // flush previous vertices
+ cc.renderer._batchRendering();
+
+ var wt = this._worldTransform, mat = this._matrix.mat;
+ mat[0] = wt.a;
+ mat[4] = wt.c;
+ mat[12] = wt.tx;
+ mat[1] = wt.b;
+ mat[5] = wt.d;
+ mat[13] = wt.ty;
+ cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
+ cc.current_stack.stack.push(cc.current_stack.top);
+ cc.current_stack.top = this._matrix;
+ var drawingUtil = cc._drawingUtil;
+
+ if (node._debugSlots && debugSlotsInfo && debugSlotsInfo.length > 0) {
+ // Slots.
+ drawingUtil.setDrawColor(0, 0, 255, 255);
+ drawingUtil.setLineWidth(1);
+
+ for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
+ var points = debugSlotsInfo[i];
+ if (points) {
+ drawingUtil.drawPoly(points, 4, true);
+ }
+ }
+ }
+
+ if (node._debugBones) {
+ // Bone lengths.
+ var bone;
+ drawingUtil.setLineWidth(2);
+ drawingUtil.setDrawColor(255, 0, 0, 255);
+
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ var x = bone.data.length * bone.a + bone.worldX;
+ var y = bone.data.length * bone.c + bone.worldY;
+ drawingUtil.drawLine(cc.p(bone.worldX, bone.worldY), cc.p(x, y));
+ }
+
+ // Bone origins.
+ drawingUtil.setPointSize(4);
+ drawingUtil.setDrawColor(0, 0, 255, 255); // Root bone is blue.
+
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ drawingUtil.drawPoint(cc.p(bone.worldX, bone.worldY));
+ if (i == 0) {
+ drawingUtil.setDrawColor(0, 255, 0, 255);
+ }
+ }
+ }
+ cc.kmGLPopMatrix();
+ }
+
+ return 0;
+};
+
+proto._getBlendFunc = function (blendMode, premultiAlpha) {
+ var ret = this._currBlendFunc;
+ switch (blendMode) {
+ case spine.BlendMode.Normal:
+ ret.src = premultiAlpha ? cc.ONE : cc.SRC_ALPHA;
+ ret.dst = cc.ONE_MINUS_SRC_ALPHA;
+ break;
+ case spine.BlendMode.Additive:
+ ret.src = premultiAlpha ? cc.ONE : cc.SRC_ALPHA;
+ ret.dst = cc.ONE;
+ break;
+ case spine.BlendMode.Multiply:
+ ret.src = cc.DST_COLOR;
+ ret.dst = cc.ONE_MINUS_SRC_ALPHA;
+ break;
+ case spine.BlendMode.Screen:
+ ret.src = cc.ONE;
+ ret.dst = cc.ONE_MINUS_SRC_COLOR;
+ break;
+ default:
+ ret = this._node._blendFunc;
+ break;
+ }
+
+ return ret;
+};
+
+proto._createChildFormSkeletonData = function(){};
+
+proto._updateChild = function(){};
+
+proto._uploadRegionAttachmentData = function(attachment, slot, premultipliedAlpha, f32buffer, ui32buffer, vertexDataOffset) {
+ // the vertices in format:
+ // [
+ // X1, Y1, C1R, C1G, C1B, C1A, U1, V1, // bottom left
+ // X2, Y2, C2R, C2G, C2B, C2A, U2, V2, // top left
+ // X3, Y3, C3R, C3G, C3B, C3A, U3, V3, // top right
+ // X4, Y4, C4R, C4G, C4B, C4A, U4, V4 // bottom right
+ // ]
+ //
+ var nodeColor = this._displayedColor;
+ var nodeR = nodeColor.r,
+ nodeG = nodeColor.g,
+ nodeB = nodeColor.b,
+ nodeA = this._displayedOpacity;
+
+ var vertices = spine.Utils.setArraySize(new Array(), 8, 0);
+ attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
+
+ var uvs = attachment.uvs;
+
+ // get the colors data
+ var skeleton = slot.bone.skeleton;
+ var skeletonColor = skeleton.color;
+ var slotColor = slot.color;
+ var regionColor = attachment.color;
+ var alpha = skeletonColor.a * slotColor.a * regionColor.a;
+ var multiplier = premultipliedAlpha ? alpha : 1;
+ var colors = attachment.tempColor;
+ colors.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
+ skeletonColor.g * slotColor.g * regionColor.g * multiplier,
+ skeletonColor.b * slotColor.b * regionColor.b * multiplier,
+ alpha);
+
+ var wt = this._worldTransform,
+ wa = wt.a, wb = wt.b, wc = wt.c, wd = wt.d,
+ wx = wt.tx, wy = wt.ty,
+ z = this._node.vertexZ;
+
+ var offset = vertexDataOffset;
+ // generate 6 vertices data (two triangles) from the quad vertices
+ // using two angles : (0, 1, 2) & (0, 2, 3)
+ for (var i = 0; i < 6; i++) {
+ var srcIdx = i < 4 ? i % 3 : i - 2;
+ var vx = vertices[srcIdx * 2],
+ vy = vertices[srcIdx * 2 + 1];
+ var x = vx * wa + vy * wc + wx,
+ y = vx * wb + vy * wd + wy;
+ var r = colors.r * nodeR,
+ g = colors.g * nodeG,
+ b = colors.b * nodeB,
+ a = colors.a * nodeA;
+ var color = ((a<<24) | (b<<16) | (g<<8) | r);
+ f32buffer[offset] = x;
+ f32buffer[offset + 1] = y;
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = color;
+ f32buffer[offset + 4] = uvs[srcIdx * 2];
+ f32buffer[offset + 5] = uvs[srcIdx * 2 + 1];
+ offset += 6;
+ }
+
+ if (this._node._debugSlots) {
+ // return the quad points info if debug slot enabled
+ var VERTEX = spine.RegionAttachment;
+ return [
+ cc.p(vertices[VERTEX.OX1], vertices[VERTEX.OY1]),
+ cc.p(vertices[VERTEX.OX2], vertices[VERTEX.OY2]),
+ cc.p(vertices[VERTEX.OX3], vertices[VERTEX.OY3]),
+ cc.p(vertices[VERTEX.OX4], vertices[VERTEX.OY4])
+ ];
+ }
+};
+
+proto._uploadMeshAttachmentData = function(attachment, slot, premultipliedAlpha, f32buffer, ui32buffer, vertexDataOffset) {
+ var wt = this._worldTransform,
+ wa = wt.a, wb = wt.b, wc = wt.c, wd = wt.d,
+ wx = wt.tx, wy = wt.ty,
+ z = this._node.vertexZ;
+ // get the vertex data
+ var verticesLength = attachment.worldVerticesLength;
+ var vertices = spine.Utils.setArraySize(new Array(), verticesLength, 0);
+ attachment.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2);
+
+ var uvs = attachment.uvs;
+
+ // get the colors data
+ var skeleton = slot.bone.skeleton;
+ var skeletonColor = skeleton.color, slotColor = slot.color, meshColor = attachment.color;
+ var alpha = skeletonColor.a * slotColor.a * meshColor.a;
+ var multiplier = premultipliedAlpha ? alpha : 1;
+ var colors = attachment.tempColor;
+ colors.set(skeletonColor.r * slotColor.r * meshColor.r * multiplier,
+ skeletonColor.g * slotColor.g * meshColor.g * multiplier,
+ skeletonColor.b * slotColor.b * meshColor.b * multiplier,
+ alpha);
+
+ var offset = vertexDataOffset;
+ var nodeColor = this._displayedColor;
+ var nodeR = nodeColor.r,
+ nodeG = nodeColor.g,
+ nodeB = nodeColor.b,
+ nodeA = this._displayedOpacity;
+ for (var i = 0, n = vertices.length; i < n; i += 2) {
+ var vx = vertices[i],
+ vy = vertices[i + 1];
+ var x = vx * wa + vy * wb + wx,
+ y = vx * wc + vy * wd + wy;
+ var r = colors.r * nodeR,
+ g = colors.g * nodeG,
+ b = colors.b * nodeB,
+ a = colors.a * nodeA;
+ var color = ((a<<24) | (b<<16) | (g<<8) | r);
+
+ f32buffer[offset] = x;
+ f32buffer[offset + 1] = y;
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = color;
+ f32buffer[offset + 4] = uvs[i];
+ f32buffer[offset + 5] = uvs[i + 1];
+ offset += 6;
+ }
+};
+
+})();
diff --git a/frameworks/cocos2d-html5/extensions/spine/LICENSE b/frameworks/cocos2d-html5/extensions/spine/LICENSE
new file mode 100644
index 0000000..daceab9
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/spine/LICENSE
@@ -0,0 +1,27 @@
+Spine Runtimes Software License v2.5
+
+Copyright (c) 2013-2016, Esoteric Software
+All rights reserved.
+
+You are granted a perpetual, non-exclusive, non-sublicensable, and
+non-transferable license to use, install, execute, and perform the Spine
+Runtimes software and derivative works solely for personal or internal
+use. Without the written permission of Esoteric Software (see Section 2 of
+the Spine Software License Agreement), you may not (a) modify, translate,
+adapt, or develop new applications using the Spine Runtimes or otherwise
+create derivative works or improvements of the Spine Runtimes or (b) remove,
+delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+or other intellectual property or proprietary rights notices on or in the
+Software, including any copy thereof. Redistributions in binary or source
+form must include this license and terms.
+
+THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/extensions/spine/Spine.js b/frameworks/cocos2d-html5/extensions/spine/Spine.js
new file mode 100644
index 0000000..e7c0d89
--- /dev/null
+++ b/frameworks/cocos2d-html5/extensions/spine/Spine.js
@@ -0,0 +1,6458 @@
+// Spine runtime version 3.6.39
+
+var __extends = (this && this.__extends) || (function () {
+ var extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+var spine;
+(function (spine) {
+ var Animation = (function () {
+ function Animation(name, timelines, duration) {
+ if (name == null)
+ throw new Error("name cannot be null.");
+ if (timelines == null)
+ throw new Error("timelines cannot be null.");
+ this.name = name;
+ this.timelines = timelines;
+ this.duration = duration;
+ }
+ Animation.prototype.apply = function (skeleton, lastTime, time, loop, events, alpha, pose, direction) {
+ if (skeleton == null)
+ throw new Error("skeleton cannot be null.");
+ if (loop && this.duration != 0) {
+ time %= this.duration;
+ if (lastTime > 0)
+ lastTime %= this.duration;
+ }
+ var timelines = this.timelines;
+ for (var i = 0, n = timelines.length; i < n; i++)
+ timelines[i].apply(skeleton, lastTime, time, events, alpha, pose, direction);
+ };
+ Animation.binarySearch = function (values, target, step) {
+ if (step === void 0) { step = 1; }
+ var low = 0;
+ var high = values.length / step - 2;
+ if (high == 0)
+ return step;
+ var current = high >>> 1;
+ while (true) {
+ if (values[(current + 1) * step] <= target)
+ low = current + 1;
+ else
+ high = current;
+ if (low == high)
+ return (low + 1) * step;
+ current = (low + high) >>> 1;
+ }
+ };
+ Animation.linearSearch = function (values, target, step) {
+ for (var i = 0, last = values.length - step; i <= last; i += step)
+ if (values[i] > target)
+ return i;
+ return -1;
+ };
+ return Animation;
+ }());
+ spine.Animation = Animation;
+ var MixPose;
+ (function (MixPose) {
+ MixPose[MixPose["setup"] = 0] = "setup";
+ MixPose[MixPose["current"] = 1] = "current";
+ MixPose[MixPose["currentLayered"] = 2] = "currentLayered";
+ })(MixPose = spine.MixPose || (spine.MixPose = {}));
+ var MixDirection;
+ (function (MixDirection) {
+ MixDirection[MixDirection["in"] = 0] = "in";
+ MixDirection[MixDirection["out"] = 1] = "out";
+ })(MixDirection = spine.MixDirection || (spine.MixDirection = {}));
+ var TimelineType;
+ (function (TimelineType) {
+ TimelineType[TimelineType["rotate"] = 0] = "rotate";
+ TimelineType[TimelineType["translate"] = 1] = "translate";
+ TimelineType[TimelineType["scale"] = 2] = "scale";
+ TimelineType[TimelineType["shear"] = 3] = "shear";
+ TimelineType[TimelineType["attachment"] = 4] = "attachment";
+ TimelineType[TimelineType["color"] = 5] = "color";
+ TimelineType[TimelineType["deform"] = 6] = "deform";
+ TimelineType[TimelineType["event"] = 7] = "event";
+ TimelineType[TimelineType["drawOrder"] = 8] = "drawOrder";
+ TimelineType[TimelineType["ikConstraint"] = 9] = "ikConstraint";
+ TimelineType[TimelineType["transformConstraint"] = 10] = "transformConstraint";
+ TimelineType[TimelineType["pathConstraintPosition"] = 11] = "pathConstraintPosition";
+ TimelineType[TimelineType["pathConstraintSpacing"] = 12] = "pathConstraintSpacing";
+ TimelineType[TimelineType["pathConstraintMix"] = 13] = "pathConstraintMix";
+ TimelineType[TimelineType["twoColor"] = 14] = "twoColor";
+ })(TimelineType = spine.TimelineType || (spine.TimelineType = {}));
+ var CurveTimeline = (function () {
+ function CurveTimeline(frameCount) {
+ if (frameCount <= 0)
+ throw new Error("frameCount must be > 0: " + frameCount);
+ this.curves = spine.Utils.newFloatArray((frameCount - 1) * CurveTimeline.BEZIER_SIZE);
+ }
+ CurveTimeline.prototype.getFrameCount = function () {
+ return this.curves.length / CurveTimeline.BEZIER_SIZE + 1;
+ };
+ CurveTimeline.prototype.setLinear = function (frameIndex) {
+ this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.LINEAR;
+ };
+ CurveTimeline.prototype.setStepped = function (frameIndex) {
+ this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.STEPPED;
+ };
+ CurveTimeline.prototype.getCurveType = function (frameIndex) {
+ var index = frameIndex * CurveTimeline.BEZIER_SIZE;
+ if (index == this.curves.length)
+ return CurveTimeline.LINEAR;
+ var type = this.curves[index];
+ if (type == CurveTimeline.LINEAR)
+ return CurveTimeline.LINEAR;
+ if (type == CurveTimeline.STEPPED)
+ return CurveTimeline.STEPPED;
+ return CurveTimeline.BEZIER;
+ };
+ CurveTimeline.prototype.setCurve = function (frameIndex, cx1, cy1, cx2, cy2) {
+ var tmpx = (-cx1 * 2 + cx2) * 0.03, tmpy = (-cy1 * 2 + cy2) * 0.03;
+ var dddfx = ((cx1 - cx2) * 3 + 1) * 0.006, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006;
+ var ddfx = tmpx * 2 + dddfx, ddfy = tmpy * 2 + dddfy;
+ var dfx = cx1 * 0.3 + tmpx + dddfx * 0.16666667, dfy = cy1 * 0.3 + tmpy + dddfy * 0.16666667;
+ var i = frameIndex * CurveTimeline.BEZIER_SIZE;
+ var curves = this.curves;
+ curves[i++] = CurveTimeline.BEZIER;
+ var x = dfx, y = dfy;
+ for (var n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) {
+ curves[i] = x;
+ curves[i + 1] = y;
+ dfx += ddfx;
+ dfy += ddfy;
+ ddfx += dddfx;
+ ddfy += dddfy;
+ x += dfx;
+ y += dfy;
+ }
+ };
+ CurveTimeline.prototype.getCurvePercent = function (frameIndex, percent) {
+ percent = spine.MathUtils.clamp(percent, 0, 1);
+ var curves = this.curves;
+ var i = frameIndex * CurveTimeline.BEZIER_SIZE;
+ var type = curves[i];
+ if (type == CurveTimeline.LINEAR)
+ return percent;
+ if (type == CurveTimeline.STEPPED)
+ return 0;
+ i++;
+ var x = 0;
+ for (var start = i, n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) {
+ x = curves[i];
+ if (x >= percent) {
+ var prevX = void 0, prevY = void 0;
+ if (i == start) {
+ prevX = 0;
+ prevY = 0;
+ }
+ else {
+ prevX = curves[i - 2];
+ prevY = curves[i - 1];
+ }
+ return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX);
+ }
+ }
+ var y = curves[i - 1];
+ return y + (1 - y) * (percent - x) / (1 - x);
+ };
+ return CurveTimeline;
+ }());
+ CurveTimeline.LINEAR = 0;
+ CurveTimeline.STEPPED = 1;
+ CurveTimeline.BEZIER = 2;
+ CurveTimeline.BEZIER_SIZE = 10 * 2 - 1;
+ spine.CurveTimeline = CurveTimeline;
+ var RotateTimeline = (function (_super) {
+ __extends(RotateTimeline, _super);
+ function RotateTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount << 1);
+ return _this;
+ }
+ RotateTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.rotate << 24) + this.boneIndex;
+ };
+ RotateTimeline.prototype.setFrame = function (frameIndex, time, degrees) {
+ frameIndex <<= 1;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + RotateTimeline.ROTATION] = degrees;
+ };
+ RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var frames = this.frames;
+ var bone = skeleton.bones[this.boneIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ bone.rotation = bone.data.rotation;
+ return;
+ case MixPose.current:
+ var r_1 = bone.data.rotation - bone.rotation;
+ r_1 -= (16384 - ((16384.499999999996 - r_1 / 360) | 0)) * 360;
+ bone.rotation += r_1 * alpha;
+ }
+ return;
+ }
+ if (time >= frames[frames.length - RotateTimeline.ENTRIES]) {
+ if (pose == MixPose.setup)
+ bone.rotation = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] * alpha;
+ else {
+ var r_2 = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] - bone.rotation;
+ r_2 -= (16384 - ((16384.499999999996 - r_2 / 360) | 0)) * 360;
+ bone.rotation += r_2 * alpha;
+ }
+ return;
+ }
+ var frame = Animation.binarySearch(frames, time, RotateTimeline.ENTRIES);
+ var prevRotation = frames[frame + RotateTimeline.PREV_ROTATION];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime));
+ var r = frames[frame + RotateTimeline.ROTATION] - prevRotation;
+ r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
+ r = prevRotation + r * percent;
+ if (pose == MixPose.setup) {
+ r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
+ bone.rotation = bone.data.rotation + r * alpha;
+ }
+ else {
+ r = bone.data.rotation + r - bone.rotation;
+ r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
+ bone.rotation += r * alpha;
+ }
+ };
+ return RotateTimeline;
+ }(CurveTimeline));
+ RotateTimeline.ENTRIES = 2;
+ RotateTimeline.PREV_TIME = -2;
+ RotateTimeline.PREV_ROTATION = -1;
+ RotateTimeline.ROTATION = 1;
+ spine.RotateTimeline = RotateTimeline;
+ var TranslateTimeline = (function (_super) {
+ __extends(TranslateTimeline, _super);
+ function TranslateTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES);
+ return _this;
+ }
+ TranslateTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.translate << 24) + this.boneIndex;
+ };
+ TranslateTimeline.prototype.setFrame = function (frameIndex, time, x, y) {
+ frameIndex *= TranslateTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + TranslateTimeline.X] = x;
+ this.frames[frameIndex + TranslateTimeline.Y] = y;
+ };
+ TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var frames = this.frames;
+ var bone = skeleton.bones[this.boneIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ bone.x = bone.data.x;
+ bone.y = bone.data.y;
+ return;
+ case MixPose.current:
+ bone.x += (bone.data.x - bone.x) * alpha;
+ bone.y += (bone.data.y - bone.y) * alpha;
+ }
+ return;
+ }
+ var x = 0, y = 0;
+ if (time >= frames[frames.length - TranslateTimeline.ENTRIES]) {
+ x = frames[frames.length + TranslateTimeline.PREV_X];
+ y = frames[frames.length + TranslateTimeline.PREV_Y];
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, TranslateTimeline.ENTRIES);
+ x = frames[frame + TranslateTimeline.PREV_X];
+ y = frames[frame + TranslateTimeline.PREV_Y];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / TranslateTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TranslateTimeline.PREV_TIME] - frameTime));
+ x += (frames[frame + TranslateTimeline.X] - x) * percent;
+ y += (frames[frame + TranslateTimeline.Y] - y) * percent;
+ }
+ if (pose == MixPose.setup) {
+ bone.x = bone.data.x + x * alpha;
+ bone.y = bone.data.y + y * alpha;
+ }
+ else {
+ bone.x += (bone.data.x + x - bone.x) * alpha;
+ bone.y += (bone.data.y + y - bone.y) * alpha;
+ }
+ };
+ return TranslateTimeline;
+ }(CurveTimeline));
+ TranslateTimeline.ENTRIES = 3;
+ TranslateTimeline.PREV_TIME = -3;
+ TranslateTimeline.PREV_X = -2;
+ TranslateTimeline.PREV_Y = -1;
+ TranslateTimeline.X = 1;
+ TranslateTimeline.Y = 2;
+ spine.TranslateTimeline = TranslateTimeline;
+ var ScaleTimeline = (function (_super) {
+ __extends(ScaleTimeline, _super);
+ function ScaleTimeline(frameCount) {
+ return _super.call(this, frameCount) || this;
+ }
+ ScaleTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.scale << 24) + this.boneIndex;
+ };
+ ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var frames = this.frames;
+ var bone = skeleton.bones[this.boneIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ bone.scaleX = bone.data.scaleX;
+ bone.scaleY = bone.data.scaleY;
+ return;
+ case MixPose.current:
+ bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha;
+ bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha;
+ }
+ return;
+ }
+ var x = 0, y = 0;
+ if (time >= frames[frames.length - ScaleTimeline.ENTRIES]) {
+ x = frames[frames.length + ScaleTimeline.PREV_X] * bone.data.scaleX;
+ y = frames[frames.length + ScaleTimeline.PREV_Y] * bone.data.scaleY;
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, ScaleTimeline.ENTRIES);
+ x = frames[frame + ScaleTimeline.PREV_X];
+ y = frames[frame + ScaleTimeline.PREV_Y];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / ScaleTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ScaleTimeline.PREV_TIME] - frameTime));
+ x = (x + (frames[frame + ScaleTimeline.X] - x) * percent) * bone.data.scaleX;
+ y = (y + (frames[frame + ScaleTimeline.Y] - y) * percent) * bone.data.scaleY;
+ }
+ if (alpha == 1) {
+ bone.scaleX = x;
+ bone.scaleY = y;
+ }
+ else {
+ var bx = 0, by = 0;
+ if (pose == MixPose.setup) {
+ bx = bone.data.scaleX;
+ by = bone.data.scaleY;
+ }
+ else {
+ bx = bone.scaleX;
+ by = bone.scaleY;
+ }
+ if (direction == MixDirection.out) {
+ x = Math.abs(x) * spine.MathUtils.signum(bx);
+ y = Math.abs(y) * spine.MathUtils.signum(by);
+ }
+ else {
+ bx = Math.abs(bx) * spine.MathUtils.signum(x);
+ by = Math.abs(by) * spine.MathUtils.signum(y);
+ }
+ bone.scaleX = bx + (x - bx) * alpha;
+ bone.scaleY = by + (y - by) * alpha;
+ }
+ };
+ return ScaleTimeline;
+ }(TranslateTimeline));
+ spine.ScaleTimeline = ScaleTimeline;
+ var ShearTimeline = (function (_super) {
+ __extends(ShearTimeline, _super);
+ function ShearTimeline(frameCount) {
+ return _super.call(this, frameCount) || this;
+ }
+ ShearTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.shear << 24) + this.boneIndex;
+ };
+ ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var frames = this.frames;
+ var bone = skeleton.bones[this.boneIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ bone.shearX = bone.data.shearX;
+ bone.shearY = bone.data.shearY;
+ return;
+ case MixPose.current:
+ bone.shearX += (bone.data.shearX - bone.shearX) * alpha;
+ bone.shearY += (bone.data.shearY - bone.shearY) * alpha;
+ }
+ return;
+ }
+ var x = 0, y = 0;
+ if (time >= frames[frames.length - ShearTimeline.ENTRIES]) {
+ x = frames[frames.length + ShearTimeline.PREV_X];
+ y = frames[frames.length + ShearTimeline.PREV_Y];
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, ShearTimeline.ENTRIES);
+ x = frames[frame + ShearTimeline.PREV_X];
+ y = frames[frame + ShearTimeline.PREV_Y];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / ShearTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ShearTimeline.PREV_TIME] - frameTime));
+ x = x + (frames[frame + ShearTimeline.X] - x) * percent;
+ y = y + (frames[frame + ShearTimeline.Y] - y) * percent;
+ }
+ if (pose == MixPose.setup) {
+ bone.shearX = bone.data.shearX + x * alpha;
+ bone.shearY = bone.data.shearY + y * alpha;
+ }
+ else {
+ bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha;
+ bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha;
+ }
+ };
+ return ShearTimeline;
+ }(TranslateTimeline));
+ spine.ShearTimeline = ShearTimeline;
+ var ColorTimeline = (function (_super) {
+ __extends(ColorTimeline, _super);
+ function ColorTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES);
+ return _this;
+ }
+ ColorTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.color << 24) + this.slotIndex;
+ };
+ ColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a) {
+ frameIndex *= ColorTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + ColorTimeline.R] = r;
+ this.frames[frameIndex + ColorTimeline.G] = g;
+ this.frames[frameIndex + ColorTimeline.B] = b;
+ this.frames[frameIndex + ColorTimeline.A] = a;
+ };
+ ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var slot = skeleton.slots[this.slotIndex];
+ var frames = this.frames;
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ slot.color.setFromColor(slot.data.color);
+ return;
+ case MixPose.current:
+ var color = slot.color, setup = slot.data.color;
+ color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, (setup.a - color.a) * alpha);
+ }
+ return;
+ }
+ var r = 0, g = 0, b = 0, a = 0;
+ if (time >= frames[frames.length - ColorTimeline.ENTRIES]) {
+ var i = frames.length;
+ r = frames[i + ColorTimeline.PREV_R];
+ g = frames[i + ColorTimeline.PREV_G];
+ b = frames[i + ColorTimeline.PREV_B];
+ a = frames[i + ColorTimeline.PREV_A];
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, ColorTimeline.ENTRIES);
+ r = frames[frame + ColorTimeline.PREV_R];
+ g = frames[frame + ColorTimeline.PREV_G];
+ b = frames[frame + ColorTimeline.PREV_B];
+ a = frames[frame + ColorTimeline.PREV_A];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / ColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ColorTimeline.PREV_TIME] - frameTime));
+ r += (frames[frame + ColorTimeline.R] - r) * percent;
+ g += (frames[frame + ColorTimeline.G] - g) * percent;
+ b += (frames[frame + ColorTimeline.B] - b) * percent;
+ a += (frames[frame + ColorTimeline.A] - a) * percent;
+ }
+ if (alpha == 1)
+ slot.color.set(r, g, b, a);
+ else {
+ var color = slot.color;
+ if (pose == MixPose.setup)
+ color.setFromColor(slot.data.color);
+ color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha);
+ }
+ };
+ return ColorTimeline;
+ }(CurveTimeline));
+ ColorTimeline.ENTRIES = 5;
+ ColorTimeline.PREV_TIME = -5;
+ ColorTimeline.PREV_R = -4;
+ ColorTimeline.PREV_G = -3;
+ ColorTimeline.PREV_B = -2;
+ ColorTimeline.PREV_A = -1;
+ ColorTimeline.R = 1;
+ ColorTimeline.G = 2;
+ ColorTimeline.B = 3;
+ ColorTimeline.A = 4;
+ spine.ColorTimeline = ColorTimeline;
+ var TwoColorTimeline = (function (_super) {
+ __extends(TwoColorTimeline, _super);
+ function TwoColorTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * TwoColorTimeline.ENTRIES);
+ return _this;
+ }
+ TwoColorTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.twoColor << 24) + this.slotIndex;
+ };
+ TwoColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a, r2, g2, b2) {
+ frameIndex *= TwoColorTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + TwoColorTimeline.R] = r;
+ this.frames[frameIndex + TwoColorTimeline.G] = g;
+ this.frames[frameIndex + TwoColorTimeline.B] = b;
+ this.frames[frameIndex + TwoColorTimeline.A] = a;
+ this.frames[frameIndex + TwoColorTimeline.R2] = r2;
+ this.frames[frameIndex + TwoColorTimeline.G2] = g2;
+ this.frames[frameIndex + TwoColorTimeline.B2] = b2;
+ };
+ TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var slot = skeleton.slots[this.slotIndex];
+ var frames = this.frames;
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ slot.color.setFromColor(slot.data.color);
+ slot.darkColor.setFromColor(slot.data.darkColor);
+ return;
+ case MixPose.current:
+ var light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor;
+ light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, (setupLight.a - light.a) * alpha);
+ dark.add((setupDark.r - dark.r) * alpha, (setupDark.g - dark.g) * alpha, (setupDark.b - dark.b) * alpha, 0);
+ }
+ return;
+ }
+ var r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0;
+ if (time >= frames[frames.length - TwoColorTimeline.ENTRIES]) {
+ var i = frames.length;
+ r = frames[i + TwoColorTimeline.PREV_R];
+ g = frames[i + TwoColorTimeline.PREV_G];
+ b = frames[i + TwoColorTimeline.PREV_B];
+ a = frames[i + TwoColorTimeline.PREV_A];
+ r2 = frames[i + TwoColorTimeline.PREV_R2];
+ g2 = frames[i + TwoColorTimeline.PREV_G2];
+ b2 = frames[i + TwoColorTimeline.PREV_B2];
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, TwoColorTimeline.ENTRIES);
+ r = frames[frame + TwoColorTimeline.PREV_R];
+ g = frames[frame + TwoColorTimeline.PREV_G];
+ b = frames[frame + TwoColorTimeline.PREV_B];
+ a = frames[frame + TwoColorTimeline.PREV_A];
+ r2 = frames[frame + TwoColorTimeline.PREV_R2];
+ g2 = frames[frame + TwoColorTimeline.PREV_G2];
+ b2 = frames[frame + TwoColorTimeline.PREV_B2];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / TwoColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TwoColorTimeline.PREV_TIME] - frameTime));
+ r += (frames[frame + TwoColorTimeline.R] - r) * percent;
+ g += (frames[frame + TwoColorTimeline.G] - g) * percent;
+ b += (frames[frame + TwoColorTimeline.B] - b) * percent;
+ a += (frames[frame + TwoColorTimeline.A] - a) * percent;
+ r2 += (frames[frame + TwoColorTimeline.R2] - r2) * percent;
+ g2 += (frames[frame + TwoColorTimeline.G2] - g2) * percent;
+ b2 += (frames[frame + TwoColorTimeline.B2] - b2) * percent;
+ }
+ if (alpha == 1) {
+ slot.color.set(r, g, b, a);
+ slot.darkColor.set(r2, g2, b2, 1);
+ }
+ else {
+ var light = slot.color, dark = slot.darkColor;
+ if (pose == MixPose.setup) {
+ light.setFromColor(slot.data.color);
+ dark.setFromColor(slot.data.darkColor);
+ }
+ light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha);
+ dark.add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0);
+ }
+ };
+ return TwoColorTimeline;
+ }(CurveTimeline));
+ TwoColorTimeline.ENTRIES = 8;
+ TwoColorTimeline.PREV_TIME = -8;
+ TwoColorTimeline.PREV_R = -7;
+ TwoColorTimeline.PREV_G = -6;
+ TwoColorTimeline.PREV_B = -5;
+ TwoColorTimeline.PREV_A = -4;
+ TwoColorTimeline.PREV_R2 = -3;
+ TwoColorTimeline.PREV_G2 = -2;
+ TwoColorTimeline.PREV_B2 = -1;
+ TwoColorTimeline.R = 1;
+ TwoColorTimeline.G = 2;
+ TwoColorTimeline.B = 3;
+ TwoColorTimeline.A = 4;
+ TwoColorTimeline.R2 = 5;
+ TwoColorTimeline.G2 = 6;
+ TwoColorTimeline.B2 = 7;
+ spine.TwoColorTimeline = TwoColorTimeline;
+ var AttachmentTimeline = (function () {
+ function AttachmentTimeline(frameCount) {
+ this.frames = spine.Utils.newFloatArray(frameCount);
+ this.attachmentNames = new Array(frameCount);
+ }
+ AttachmentTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.attachment << 24) + this.slotIndex;
+ };
+ AttachmentTimeline.prototype.getFrameCount = function () {
+ return this.frames.length;
+ };
+ AttachmentTimeline.prototype.setFrame = function (frameIndex, time, attachmentName) {
+ this.frames[frameIndex] = time;
+ this.attachmentNames[frameIndex] = attachmentName;
+ };
+ AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var slot = skeleton.slots[this.slotIndex];
+ if (direction == MixDirection.out && pose == MixPose.setup) {
+ var attachmentName_1 = slot.data.attachmentName;
+ slot.setAttachment(attachmentName_1 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_1));
+ return;
+ }
+ var frames = this.frames;
+ if (time < frames[0]) {
+ if (pose == MixPose.setup) {
+ var attachmentName_2 = slot.data.attachmentName;
+ slot.setAttachment(attachmentName_2 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_2));
+ }
+ return;
+ }
+ var frameIndex = 0;
+ if (time >= frames[frames.length - 1])
+ frameIndex = frames.length - 1;
+ else
+ frameIndex = Animation.binarySearch(frames, time, 1) - 1;
+ var attachmentName = this.attachmentNames[frameIndex];
+ skeleton.slots[this.slotIndex]
+ .setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName));
+ };
+ return AttachmentTimeline;
+ }());
+ spine.AttachmentTimeline = AttachmentTimeline;
+ var zeros = null;
+ var DeformTimeline = (function (_super) {
+ __extends(DeformTimeline, _super);
+ function DeformTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount);
+ _this.frameVertices = new Array(frameCount);
+ if (zeros == null)
+ zeros = spine.Utils.newFloatArray(64);
+ return _this;
+ }
+ DeformTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.deform << 27) + +this.attachment.id + this.slotIndex;
+ };
+ DeformTimeline.prototype.setFrame = function (frameIndex, time, vertices) {
+ this.frames[frameIndex] = time;
+ this.frameVertices[frameIndex] = vertices;
+ };
+ DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ var slot = skeleton.slots[this.slotIndex];
+ var slotAttachment = slot.getAttachment();
+ if (!(slotAttachment instanceof spine.VertexAttachment) || !slotAttachment.applyDeform(this.attachment))
+ return;
+ var verticesArray = slot.attachmentVertices;
+ var frameVertices = this.frameVertices;
+ var vertexCount = frameVertices[0].length;
+ var vertices = spine.Utils.setArraySize(verticesArray, vertexCount);
+ var frames = this.frames;
+ if (time < frames[0]) {
+ var vertexAttachment = slotAttachment;
+ switch (pose) {
+ case MixPose.setup:
+ var zeroVertices;
+ if (vertexAttachment.bones == null) {
+ zeroVertices = vertexAttachment.vertices;
+ }
+ else {
+ zeroVertices = zeros;
+ if (zeroVertices.length < vertexCount)
+ zeros = zeroVertices = spine.Utils.newFloatArray(vertexCount);
+ }
+ spine.Utils.arrayCopy(zeroVertices, 0, vertices, 0, vertexCount);
+ return;
+ case MixPose.current:
+ if (alpha == 1)
+ break;
+ if (vertexAttachment.bones == null) {
+ var setupVertices = vertexAttachment.vertices;
+ for (var i = 0; i < vertexCount; i++)
+ vertices[i] += (setupVertices[i] - vertices[i]) * alpha;
+ }
+ else {
+ alpha = 1 - alpha;
+ for (var i = 0; i < vertexCount; i++)
+ vertices[i] *= alpha;
+ }
+ }
+ return;
+ }
+ if (time >= frames[frames.length - 1]) {
+ var lastVertices = frameVertices[frames.length - 1];
+ if (alpha == 1) {
+ spine.Utils.arrayCopy(lastVertices, 0, vertices, 0, vertexCount);
+ }
+ else if (pose == MixPose.setup) {
+ var vertexAttachment = slotAttachment;
+ if (vertexAttachment.bones == null) {
+ var setupVertices_1 = vertexAttachment.vertices;
+ for (var i_1 = 0; i_1 < vertexCount; i_1++) {
+ var setup = setupVertices_1[i_1];
+ vertices[i_1] = setup + (lastVertices[i_1] - setup) * alpha;
+ }
+ }
+ else {
+ for (var i_2 = 0; i_2 < vertexCount; i_2++)
+ vertices[i_2] = lastVertices[i_2] * alpha;
+ }
+ }
+ else {
+ for (var i_3 = 0; i_3 < vertexCount; i_3++)
+ vertices[i_3] += (lastVertices[i_3] - vertices[i_3]) * alpha;
+ }
+ return;
+ }
+ var frame = Animation.binarySearch(frames, time);
+ var prevVertices = frameVertices[frame - 1];
+ var nextVertices = frameVertices[frame];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));
+ if (alpha == 1) {
+ for (var i_4 = 0; i_4 < vertexCount; i_4++) {
+ var prev = prevVertices[i_4];
+ vertices[i_4] = prev + (nextVertices[i_4] - prev) * percent;
+ }
+ }
+ else if (pose == MixPose.setup) {
+ var vertexAttachment = slotAttachment;
+ if (vertexAttachment.bones == null) {
+ var setupVertices_2 = vertexAttachment.vertices;
+ for (var i_5 = 0; i_5 < vertexCount; i_5++) {
+ var prev = prevVertices[i_5], setup = setupVertices_2[i_5];
+ vertices[i_5] = setup + (prev + (nextVertices[i_5] - prev) * percent - setup) * alpha;
+ }
+ }
+ else {
+ for (var i_6 = 0; i_6 < vertexCount; i_6++) {
+ var prev = prevVertices[i_6];
+ vertices[i_6] = (prev + (nextVertices[i_6] - prev) * percent) * alpha;
+ }
+ }
+ }
+ else {
+ for (var i_7 = 0; i_7 < vertexCount; i_7++) {
+ var prev = prevVertices[i_7];
+ vertices[i_7] += (prev + (nextVertices[i_7] - prev) * percent - vertices[i_7]) * alpha;
+ }
+ }
+ };
+ return DeformTimeline;
+ }(CurveTimeline));
+ spine.DeformTimeline = DeformTimeline;
+ var EventTimeline = (function () {
+ function EventTimeline(frameCount) {
+ this.frames = spine.Utils.newFloatArray(frameCount);
+ this.events = new Array(frameCount);
+ }
+ EventTimeline.prototype.getPropertyId = function () {
+ return TimelineType.event << 24;
+ };
+ EventTimeline.prototype.getFrameCount = function () {
+ return this.frames.length;
+ };
+ EventTimeline.prototype.setFrame = function (frameIndex, event) {
+ this.frames[frameIndex] = event.time;
+ this.events[frameIndex] = event;
+ };
+ EventTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ if (firedEvents == null)
+ return;
+ var frames = this.frames;
+ var frameCount = this.frames.length;
+ if (lastTime > time) {
+ this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, pose, direction);
+ lastTime = -1;
+ }
+ else if (lastTime >= frames[frameCount - 1])
+ return;
+ if (time < frames[0])
+ return;
+ var frame = 0;
+ if (lastTime < frames[0])
+ frame = 0;
+ else {
+ frame = Animation.binarySearch(frames, lastTime);
+ var frameTime = frames[frame];
+ while (frame > 0) {
+ if (frames[frame - 1] != frameTime)
+ break;
+ frame--;
+ }
+ }
+ for (; frame < frameCount && time >= frames[frame]; frame++)
+ firedEvents.push(this.events[frame]);
+ };
+ return EventTimeline;
+ }());
+ spine.EventTimeline = EventTimeline;
+ var DrawOrderTimeline = (function () {
+ function DrawOrderTimeline(frameCount) {
+ this.frames = spine.Utils.newFloatArray(frameCount);
+ this.drawOrders = new Array(frameCount);
+ }
+ DrawOrderTimeline.prototype.getPropertyId = function () {
+ return TimelineType.drawOrder << 24;
+ };
+ DrawOrderTimeline.prototype.getFrameCount = function () {
+ return this.frames.length;
+ };
+ DrawOrderTimeline.prototype.setFrame = function (frameIndex, time, drawOrder) {
+ this.frames[frameIndex] = time;
+ this.drawOrders[frameIndex] = drawOrder;
+ };
+ DrawOrderTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ var drawOrder = skeleton.drawOrder;
+ var slots = skeleton.slots;
+ if (direction == MixDirection.out && pose == MixPose.setup) {
+ spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
+ return;
+ }
+ var frames = this.frames;
+ if (time < frames[0]) {
+ if (pose == MixPose.setup)
+ spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
+ return;
+ }
+ var frame = 0;
+ if (time >= frames[frames.length - 1])
+ frame = frames.length - 1;
+ else
+ frame = Animation.binarySearch(frames, time) - 1;
+ var drawOrderToSetupIndex = this.drawOrders[frame];
+ if (drawOrderToSetupIndex == null)
+ spine.Utils.arrayCopy(slots, 0, drawOrder, 0, slots.length);
+ else {
+ for (var i = 0, n = drawOrderToSetupIndex.length; i < n; i++)
+ drawOrder[i] = slots[drawOrderToSetupIndex[i]];
+ }
+ };
+ return DrawOrderTimeline;
+ }());
+ spine.DrawOrderTimeline = DrawOrderTimeline;
+ var IkConstraintTimeline = (function (_super) {
+ __extends(IkConstraintTimeline, _super);
+ function IkConstraintTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES);
+ return _this;
+ }
+ IkConstraintTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex;
+ };
+ IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection) {
+ frameIndex *= IkConstraintTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + IkConstraintTimeline.MIX] = mix;
+ this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
+ };
+ IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ var frames = this.frames;
+ var constraint = skeleton.ikConstraints[this.ikConstraintIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ constraint.mix = constraint.data.mix;
+ constraint.bendDirection = constraint.data.bendDirection;
+ return;
+ case MixPose.current:
+ constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
+ constraint.bendDirection = constraint.data.bendDirection;
+ }
+ return;
+ }
+ if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) {
+ if (pose == MixPose.setup) {
+ constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
+ constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection
+ : frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
+ }
+ else {
+ constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
+ if (direction == MixDirection["in"])
+ constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
+ }
+ return;
+ }
+ var frame = Animation.binarySearch(frames, time, IkConstraintTimeline.ENTRIES);
+ var mix = frames[frame + IkConstraintTimeline.PREV_MIX];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime));
+ if (pose == MixPose.setup) {
+ constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
+ constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
+ }
+ else {
+ constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
+ if (direction == MixDirection["in"])
+ constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
+ }
+ };
+ return IkConstraintTimeline;
+ }(CurveTimeline));
+ IkConstraintTimeline.ENTRIES = 3;
+ IkConstraintTimeline.PREV_TIME = -3;
+ IkConstraintTimeline.PREV_MIX = -2;
+ IkConstraintTimeline.PREV_BEND_DIRECTION = -1;
+ IkConstraintTimeline.MIX = 1;
+ IkConstraintTimeline.BEND_DIRECTION = 2;
+ spine.IkConstraintTimeline = IkConstraintTimeline;
+ var TransformConstraintTimeline = (function (_super) {
+ __extends(TransformConstraintTimeline, _super);
+ function TransformConstraintTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES);
+ return _this;
+ }
+ TransformConstraintTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.transformConstraint << 24) + this.transformConstraintIndex;
+ };
+ TransformConstraintTimeline.prototype.setFrame = function (frameIndex, time, rotateMix, translateMix, scaleMix, shearMix) {
+ frameIndex *= TransformConstraintTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + TransformConstraintTimeline.ROTATE] = rotateMix;
+ this.frames[frameIndex + TransformConstraintTimeline.TRANSLATE] = translateMix;
+ this.frames[frameIndex + TransformConstraintTimeline.SCALE] = scaleMix;
+ this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix;
+ };
+ TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ var frames = this.frames;
+ var constraint = skeleton.transformConstraints[this.transformConstraintIndex];
+ if (time < frames[0]) {
+ var data = constraint.data;
+ switch (pose) {
+ case MixPose.setup:
+ constraint.rotateMix = data.rotateMix;
+ constraint.translateMix = data.translateMix;
+ constraint.scaleMix = data.scaleMix;
+ constraint.shearMix = data.shearMix;
+ return;
+ case MixPose.current:
+ constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha;
+ constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha;
+ constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha;
+ constraint.shearMix += (data.shearMix - constraint.shearMix) * alpha;
+ }
+ return;
+ }
+ var rotate = 0, translate = 0, scale = 0, shear = 0;
+ if (time >= frames[frames.length - TransformConstraintTimeline.ENTRIES]) {
+ var i = frames.length;
+ rotate = frames[i + TransformConstraintTimeline.PREV_ROTATE];
+ translate = frames[i + TransformConstraintTimeline.PREV_TRANSLATE];
+ scale = frames[i + TransformConstraintTimeline.PREV_SCALE];
+ shear = frames[i + TransformConstraintTimeline.PREV_SHEAR];
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, TransformConstraintTimeline.ENTRIES);
+ rotate = frames[frame + TransformConstraintTimeline.PREV_ROTATE];
+ translate = frames[frame + TransformConstraintTimeline.PREV_TRANSLATE];
+ scale = frames[frame + TransformConstraintTimeline.PREV_SCALE];
+ shear = frames[frame + TransformConstraintTimeline.PREV_SHEAR];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / TransformConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TransformConstraintTimeline.PREV_TIME] - frameTime));
+ rotate += (frames[frame + TransformConstraintTimeline.ROTATE] - rotate) * percent;
+ translate += (frames[frame + TransformConstraintTimeline.TRANSLATE] - translate) * percent;
+ scale += (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent;
+ shear += (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent;
+ }
+ if (pose == MixPose.setup) {
+ var data = constraint.data;
+ constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha;
+ constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha;
+ constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha;
+ constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha;
+ }
+ else {
+ constraint.rotateMix += (rotate - constraint.rotateMix) * alpha;
+ constraint.translateMix += (translate - constraint.translateMix) * alpha;
+ constraint.scaleMix += (scale - constraint.scaleMix) * alpha;
+ constraint.shearMix += (shear - constraint.shearMix) * alpha;
+ }
+ };
+ return TransformConstraintTimeline;
+ }(CurveTimeline));
+ TransformConstraintTimeline.ENTRIES = 5;
+ TransformConstraintTimeline.PREV_TIME = -5;
+ TransformConstraintTimeline.PREV_ROTATE = -4;
+ TransformConstraintTimeline.PREV_TRANSLATE = -3;
+ TransformConstraintTimeline.PREV_SCALE = -2;
+ TransformConstraintTimeline.PREV_SHEAR = -1;
+ TransformConstraintTimeline.ROTATE = 1;
+ TransformConstraintTimeline.TRANSLATE = 2;
+ TransformConstraintTimeline.SCALE = 3;
+ TransformConstraintTimeline.SHEAR = 4;
+ spine.TransformConstraintTimeline = TransformConstraintTimeline;
+ var PathConstraintPositionTimeline = (function (_super) {
+ __extends(PathConstraintPositionTimeline, _super);
+ function PathConstraintPositionTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES);
+ return _this;
+ }
+ PathConstraintPositionTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.pathConstraintPosition << 24) + this.pathConstraintIndex;
+ };
+ PathConstraintPositionTimeline.prototype.setFrame = function (frameIndex, time, value) {
+ frameIndex *= PathConstraintPositionTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value;
+ };
+ PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ var frames = this.frames;
+ var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ constraint.position = constraint.data.position;
+ return;
+ case MixPose.current:
+ constraint.position += (constraint.data.position - constraint.position) * alpha;
+ }
+ return;
+ }
+ var position = 0;
+ if (time >= frames[frames.length - PathConstraintPositionTimeline.ENTRIES])
+ position = frames[frames.length + PathConstraintPositionTimeline.PREV_VALUE];
+ else {
+ var frame = Animation.binarySearch(frames, time, PathConstraintPositionTimeline.ENTRIES);
+ position = frames[frame + PathConstraintPositionTimeline.PREV_VALUE];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / PathConstraintPositionTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintPositionTimeline.PREV_TIME] - frameTime));
+ position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent;
+ }
+ if (pose == MixPose.setup)
+ constraint.position = constraint.data.position + (position - constraint.data.position) * alpha;
+ else
+ constraint.position += (position - constraint.position) * alpha;
+ };
+ return PathConstraintPositionTimeline;
+ }(CurveTimeline));
+ PathConstraintPositionTimeline.ENTRIES = 2;
+ PathConstraintPositionTimeline.PREV_TIME = -2;
+ PathConstraintPositionTimeline.PREV_VALUE = -1;
+ PathConstraintPositionTimeline.VALUE = 1;
+ spine.PathConstraintPositionTimeline = PathConstraintPositionTimeline;
+ var PathConstraintSpacingTimeline = (function (_super) {
+ __extends(PathConstraintSpacingTimeline, _super);
+ function PathConstraintSpacingTimeline(frameCount) {
+ return _super.call(this, frameCount) || this;
+ }
+ PathConstraintSpacingTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.pathConstraintSpacing << 24) + this.pathConstraintIndex;
+ };
+ PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ var frames = this.frames;
+ var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ constraint.spacing = constraint.data.spacing;
+ return;
+ case MixPose.current:
+ constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha;
+ }
+ return;
+ }
+ var spacing = 0;
+ if (time >= frames[frames.length - PathConstraintSpacingTimeline.ENTRIES])
+ spacing = frames[frames.length + PathConstraintSpacingTimeline.PREV_VALUE];
+ else {
+ var frame = Animation.binarySearch(frames, time, PathConstraintSpacingTimeline.ENTRIES);
+ spacing = frames[frame + PathConstraintSpacingTimeline.PREV_VALUE];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / PathConstraintSpacingTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintSpacingTimeline.PREV_TIME] - frameTime));
+ spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent;
+ }
+ if (pose == MixPose.setup)
+ constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha;
+ else
+ constraint.spacing += (spacing - constraint.spacing) * alpha;
+ };
+ return PathConstraintSpacingTimeline;
+ }(PathConstraintPositionTimeline));
+ spine.PathConstraintSpacingTimeline = PathConstraintSpacingTimeline;
+ var PathConstraintMixTimeline = (function (_super) {
+ __extends(PathConstraintMixTimeline, _super);
+ function PathConstraintMixTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES);
+ return _this;
+ }
+ PathConstraintMixTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.pathConstraintMix << 24) + this.pathConstraintIndex;
+ };
+ PathConstraintMixTimeline.prototype.setFrame = function (frameIndex, time, rotateMix, translateMix) {
+ frameIndex *= PathConstraintMixTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + PathConstraintMixTimeline.ROTATE] = rotateMix;
+ this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix;
+ };
+ PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ var frames = this.frames;
+ var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ constraint.rotateMix = constraint.data.rotateMix;
+ constraint.translateMix = constraint.data.translateMix;
+ return;
+ case MixPose.current:
+ constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha;
+ constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha;
+ }
+ return;
+ }
+ var rotate = 0, translate = 0;
+ if (time >= frames[frames.length - PathConstraintMixTimeline.ENTRIES]) {
+ rotate = frames[frames.length + PathConstraintMixTimeline.PREV_ROTATE];
+ translate = frames[frames.length + PathConstraintMixTimeline.PREV_TRANSLATE];
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, PathConstraintMixTimeline.ENTRIES);
+ rotate = frames[frame + PathConstraintMixTimeline.PREV_ROTATE];
+ translate = frames[frame + PathConstraintMixTimeline.PREV_TRANSLATE];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / PathConstraintMixTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintMixTimeline.PREV_TIME] - frameTime));
+ rotate += (frames[frame + PathConstraintMixTimeline.ROTATE] - rotate) * percent;
+ translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent;
+ }
+ if (pose == MixPose.setup) {
+ constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha;
+ constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha;
+ }
+ else {
+ constraint.rotateMix += (rotate - constraint.rotateMix) * alpha;
+ constraint.translateMix += (translate - constraint.translateMix) * alpha;
+ }
+ };
+ return PathConstraintMixTimeline;
+ }(CurveTimeline));
+ PathConstraintMixTimeline.ENTRIES = 3;
+ PathConstraintMixTimeline.PREV_TIME = -3;
+ PathConstraintMixTimeline.PREV_ROTATE = -2;
+ PathConstraintMixTimeline.PREV_TRANSLATE = -1;
+ PathConstraintMixTimeline.ROTATE = 1;
+ PathConstraintMixTimeline.TRANSLATE = 2;
+ spine.PathConstraintMixTimeline = PathConstraintMixTimeline;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var AnimationState = (function () {
+ function AnimationState(data) {
+ this.tracks = new Array();
+ this.events = new Array();
+ this.listeners = new Array();
+ this.queue = new EventQueue(this);
+ this.propertyIDs = new spine.IntSet();
+ this.mixingTo = new Array();
+ this.animationsChanged = false;
+ this.timeScale = 1;
+ this.trackEntryPool = new spine.Pool(function () { return new TrackEntry(); });
+ this.data = data;
+ }
+ AnimationState.prototype.update = function (delta) {
+ delta *= this.timeScale;
+ var tracks = this.tracks;
+ for (var i = 0, n = tracks.length; i < n; i++) {
+ var current = tracks[i];
+ if (current == null)
+ continue;
+ current.animationLast = current.nextAnimationLast;
+ current.trackLast = current.nextTrackLast;
+ var currentDelta = delta * current.timeScale;
+ if (current.delay > 0) {
+ current.delay -= currentDelta;
+ if (current.delay > 0)
+ continue;
+ currentDelta = -current.delay;
+ current.delay = 0;
+ }
+ var next = current.next;
+ if (next != null) {
+ var nextTime = current.trackLast - next.delay;
+ if (nextTime >= 0) {
+ next.delay = 0;
+ next.trackTime = nextTime + delta * next.timeScale;
+ current.trackTime += currentDelta;
+ this.setCurrent(i, next, true);
+ while (next.mixingFrom != null) {
+ next.mixTime += currentDelta;
+ next = next.mixingFrom;
+ }
+ continue;
+ }
+ }
+ else if (current.trackLast >= current.trackEnd && current.mixingFrom == null) {
+ tracks[i] = null;
+ this.queue.end(current);
+ this.disposeNext(current);
+ continue;
+ }
+ if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
+ var from = current.mixingFrom;
+ current.mixingFrom = null;
+ while (from != null) {
+ this.queue.end(from);
+ from = from.mixingFrom;
+ }
+ }
+ current.trackTime += currentDelta;
+ }
+ this.queue.drain();
+ };
+ AnimationState.prototype.updateMixingFrom = function (to, delta) {
+ var from = to.mixingFrom;
+ if (from == null)
+ return true;
+ var finished = this.updateMixingFrom(from, delta);
+ if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
+ if (from.totalAlpha == 0 || to.mixDuration == 0) {
+ to.mixingFrom = from.mixingFrom;
+ to.interruptAlpha = from.interruptAlpha;
+ this.queue.end(from);
+ }
+ return finished;
+ }
+ from.animationLast = from.nextAnimationLast;
+ from.trackLast = from.nextTrackLast;
+ from.trackTime += delta * from.timeScale;
+ to.mixTime += delta * to.timeScale;
+ return false;
+ };
+ AnimationState.prototype.apply = function (skeleton) {
+ if (skeleton == null)
+ throw new Error("skeleton cannot be null.");
+ if (this.animationsChanged)
+ this._animationsChanged();
+ var events = this.events;
+ var tracks = this.tracks;
+ var applied = false;
+ for (var i = 0, n = tracks.length; i < n; i++) {
+ var current = tracks[i];
+ if (current == null || current.delay > 0)
+ continue;
+ applied = true;
+ var currentPose = i == 0 ? spine.MixPose.current : spine.MixPose.currentLayered;
+ var mix = current.alpha;
+ if (current.mixingFrom != null)
+ mix *= this.applyMixingFrom(current, skeleton, currentPose);
+ else if (current.trackTime >= current.trackEnd && current.next == null)
+ mix = 0;
+ var animationLast = current.animationLast, animationTime = current.getAnimationTime();
+ var timelineCount = current.animation.timelines.length;
+ var timelines = current.animation.timelines;
+ if (mix == 1) {
+ for (var ii = 0; ii < timelineCount; ii++)
+ timelines[ii].apply(skeleton, animationLast, animationTime, events, 1, spine.MixPose.setup, spine.MixDirection["in"]);
+ }
+ else {
+ var timelineData = current.timelineData;
+ var firstFrame = current.timelinesRotation.length == 0;
+ if (firstFrame)
+ spine.Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null);
+ var timelinesRotation = current.timelinesRotation;
+ for (var ii = 0; ii < timelineCount; ii++) {
+ var timeline = timelines[ii];
+ var pose = timelineData[ii] >= AnimationState.FIRST ? spine.MixPose.setup : currentPose;
+ if (timeline instanceof spine.RotateTimeline) {
+ this.applyRotateTimeline(timeline, skeleton, animationTime, mix, pose, timelinesRotation, ii << 1, firstFrame);
+ }
+ else
+ timeline.apply(skeleton, animationLast, animationTime, events, mix, pose, spine.MixDirection["in"]);
+ }
+ }
+ this.queueEvents(current, animationTime);
+ events.length = 0;
+ current.nextAnimationLast = animationTime;
+ current.nextTrackLast = current.trackTime;
+ }
+ this.queue.drain();
+ return applied;
+ };
+ AnimationState.prototype.applyMixingFrom = function (to, skeleton, currentPose) {
+ var from = to.mixingFrom;
+ if (from.mixingFrom != null)
+ this.applyMixingFrom(from, skeleton, currentPose);
+ var mix = 0;
+ if (to.mixDuration == 0)
+ mix = 1;
+ else {
+ mix = to.mixTime / to.mixDuration;
+ if (mix > 1)
+ mix = 1;
+ }
+ var events = mix < from.eventThreshold ? this.events : null;
+ var attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold;
+ var animationLast = from.animationLast, animationTime = from.getAnimationTime();
+ var timelineCount = from.animation.timelines.length;
+ var timelines = from.animation.timelines;
+ var timelineData = from.timelineData;
+ var timelineDipMix = from.timelineDipMix;
+ var firstFrame = from.timelinesRotation.length == 0;
+ if (firstFrame)
+ spine.Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null);
+ var timelinesRotation = from.timelinesRotation;
+ var pose;
+ var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha = 0;
+ from.totalAlpha = 0;
+ for (var i = 0; i < timelineCount; i++) {
+ var timeline = timelines[i];
+ switch (timelineData[i]) {
+ case AnimationState.SUBSEQUENT:
+ if (!attachments && timeline instanceof spine.AttachmentTimeline)
+ continue;
+ if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
+ continue;
+ pose = currentPose;
+ alpha = alphaMix;
+ break;
+ case AnimationState.FIRST:
+ pose = spine.MixPose.setup;
+ alpha = alphaMix;
+ break;
+ case AnimationState.DIP:
+ pose = spine.MixPose.setup;
+ alpha = alphaDip;
+ break;
+ default:
+ pose = spine.MixPose.setup;
+ alpha = alphaDip;
+ var dipMix = timelineDipMix[i];
+ alpha *= Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
+ break;
+ }
+ from.totalAlpha += alpha;
+ if (timeline instanceof spine.RotateTimeline)
+ this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, pose, timelinesRotation, i << 1, firstFrame);
+ else {
+ timeline.apply(skeleton, animationLast, animationTime, events, alpha, pose, spine.MixDirection.out);
+ }
+ }
+ if (to.mixDuration > 0)
+ this.queueEvents(from, animationTime);
+ this.events.length = 0;
+ from.nextAnimationLast = animationTime;
+ from.nextTrackLast = from.trackTime;
+ return mix;
+ };
+ AnimationState.prototype.applyRotateTimeline = function (timeline, skeleton, time, alpha, pose, timelinesRotation, i, firstFrame) {
+ if (firstFrame)
+ timelinesRotation[i] = 0;
+ if (alpha == 1) {
+ timeline.apply(skeleton, 0, time, null, 1, pose, spine.MixDirection["in"]);
+ return;
+ }
+ var rotateTimeline = timeline;
+ var frames = rotateTimeline.frames;
+ var bone = skeleton.bones[rotateTimeline.boneIndex];
+ if (time < frames[0]) {
+ if (pose == spine.MixPose.setup)
+ bone.rotation = bone.data.rotation;
+ return;
+ }
+ var r2 = 0;
+ if (time >= frames[frames.length - spine.RotateTimeline.ENTRIES])
+ r2 = bone.data.rotation + frames[frames.length + spine.RotateTimeline.PREV_ROTATION];
+ else {
+ var frame = spine.Animation.binarySearch(frames, time, spine.RotateTimeline.ENTRIES);
+ var prevRotation = frames[frame + spine.RotateTimeline.PREV_ROTATION];
+ var frameTime = frames[frame];
+ var percent = rotateTimeline.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + spine.RotateTimeline.PREV_TIME] - frameTime));
+ r2 = frames[frame + spine.RotateTimeline.ROTATION] - prevRotation;
+ r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360;
+ r2 = prevRotation + r2 * percent + bone.data.rotation;
+ r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360;
+ }
+ var r1 = pose == spine.MixPose.setup ? bone.data.rotation : bone.rotation;
+ var total = 0, diff = r2 - r1;
+ if (diff == 0) {
+ total = timelinesRotation[i];
+ }
+ else {
+ diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360;
+ var lastTotal = 0, lastDiff = 0;
+ if (firstFrame) {
+ lastTotal = 0;
+ lastDiff = diff;
+ }
+ else {
+ lastTotal = timelinesRotation[i];
+ lastDiff = timelinesRotation[i + 1];
+ }
+ var current = diff > 0, dir = lastTotal >= 0;
+ if (spine.MathUtils.signum(lastDiff) != spine.MathUtils.signum(diff) && Math.abs(lastDiff) <= 90) {
+ if (Math.abs(lastTotal) > 180)
+ lastTotal += 360 * spine.MathUtils.signum(lastTotal);
+ dir = current;
+ }
+ total = diff + lastTotal - lastTotal % 360;
+ if (dir != current)
+ total += 360 * spine.MathUtils.signum(lastTotal);
+ timelinesRotation[i] = total;
+ }
+ timelinesRotation[i + 1] = diff;
+ r1 += total * alpha;
+ bone.rotation = r1 - (16384 - ((16384.499999999996 - r1 / 360) | 0)) * 360;
+ };
+ AnimationState.prototype.queueEvents = function (entry, animationTime) {
+ var animationStart = entry.animationStart, animationEnd = entry.animationEnd;
+ var duration = animationEnd - animationStart;
+ var trackLastWrapped = entry.trackLast % duration;
+ var events = this.events;
+ var i = 0, n = events.length;
+ for (; i < n; i++) {
+ var event_1 = events[i];
+ if (event_1.time < trackLastWrapped)
+ break;
+ if (event_1.time > animationEnd)
+ continue;
+ this.queue.event(entry, event_1);
+ }
+ if (entry.loop ? (trackLastWrapped > entry.trackTime % duration)
+ : (animationTime >= animationEnd && entry.animationLast < animationEnd)) {
+ this.queue.complete(entry);
+ }
+ for (; i < n; i++) {
+ var event_2 = events[i];
+ if (event_2.time < animationStart)
+ continue;
+ this.queue.event(entry, events[i]);
+ }
+ };
+ AnimationState.prototype.clearTracks = function () {
+ var oldDrainDisabled = this.queue.drainDisabled;
+ this.queue.drainDisabled = true;
+ for (var i = 0, n = this.tracks.length; i < n; i++)
+ this.clearTrack(i);
+ this.tracks.length = 0;
+ this.queue.drainDisabled = oldDrainDisabled;
+ this.queue.drain();
+ };
+ AnimationState.prototype.clearTrack = function (trackIndex) {
+ if (trackIndex >= this.tracks.length)
+ return;
+ var current = this.tracks[trackIndex];
+ if (current == null)
+ return;
+ this.queue.end(current);
+ this.disposeNext(current);
+ var entry = current;
+ while (true) {
+ var from = entry.mixingFrom;
+ if (from == null)
+ break;
+ this.queue.end(from);
+ entry.mixingFrom = null;
+ entry = from;
+ }
+ this.tracks[current.trackIndex] = null;
+ this.queue.drain();
+ };
+ AnimationState.prototype.setCurrent = function (index, current, interrupt) {
+ var from = this.expandToIndex(index);
+ this.tracks[index] = current;
+ if (from != null) {
+ if (interrupt)
+ this.queue.interrupt(from);
+ current.mixingFrom = from;
+ current.mixTime = 0;
+ if (from.mixingFrom != null && from.mixDuration > 0)
+ current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
+ from.timelinesRotation.length = 0;
+ }
+ this.queue.start(current);
+ };
+ AnimationState.prototype.setAnimation = function (trackIndex, animationName, loop) {
+ var animation = this.data.skeletonData.findAnimation(animationName);
+ if (animation == null)
+ throw new Error("Animation not found: " + animationName);
+ return this.setAnimationWith(trackIndex, animation, loop);
+ };
+ AnimationState.prototype.setAnimationWith = function (trackIndex, animation, loop) {
+ if (animation == null)
+ throw new Error("animation cannot be null.");
+ var interrupt = true;
+ var current = this.expandToIndex(trackIndex);
+ if (current != null) {
+ if (current.nextTrackLast == -1) {
+ this.tracks[trackIndex] = current.mixingFrom;
+ this.queue.interrupt(current);
+ this.queue.end(current);
+ this.disposeNext(current);
+ current = current.mixingFrom;
+ interrupt = false;
+ }
+ else
+ this.disposeNext(current);
+ }
+ var entry = this.trackEntry(trackIndex, animation, loop, current);
+ this.setCurrent(trackIndex, entry, interrupt);
+ this.queue.drain();
+ return entry;
+ };
+ AnimationState.prototype.addAnimation = function (trackIndex, animationName, loop, delay) {
+ var animation = this.data.skeletonData.findAnimation(animationName);
+ if (animation == null)
+ throw new Error("Animation not found: " + animationName);
+ return this.addAnimationWith(trackIndex, animation, loop, delay);
+ };
+ AnimationState.prototype.addAnimationWith = function (trackIndex, animation, loop, delay) {
+ if (animation == null)
+ throw new Error("animation cannot be null.");
+ var last = this.expandToIndex(trackIndex);
+ if (last != null) {
+ while (last.next != null)
+ last = last.next;
+ }
+ var entry = this.trackEntry(trackIndex, animation, loop, last);
+ if (last == null) {
+ this.setCurrent(trackIndex, entry, true);
+ this.queue.drain();
+ }
+ else {
+ last.next = entry;
+ if (delay <= 0) {
+ var duration = last.animationEnd - last.animationStart;
+ if (duration != 0)
+ delay += duration * (1 + ((last.trackTime / duration) | 0)) - this.data.getMix(last.animation, animation);
+ else
+ delay = 0;
+ }
+ }
+ entry.delay = delay;
+ return entry;
+ };
+ AnimationState.prototype.setEmptyAnimation = function (trackIndex, mixDuration) {
+ var entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation, false);
+ entry.mixDuration = mixDuration;
+ entry.trackEnd = mixDuration;
+ return entry;
+ };
+ AnimationState.prototype.addEmptyAnimation = function (trackIndex, mixDuration, delay) {
+ if (delay <= 0)
+ delay -= mixDuration;
+ var entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation, false, delay);
+ entry.mixDuration = mixDuration;
+ entry.trackEnd = mixDuration;
+ return entry;
+ };
+ AnimationState.prototype.setEmptyAnimations = function (mixDuration) {
+ var oldDrainDisabled = this.queue.drainDisabled;
+ this.queue.drainDisabled = true;
+ for (var i = 0, n = this.tracks.length; i < n; i++) {
+ var current = this.tracks[i];
+ if (current != null)
+ this.setEmptyAnimation(current.trackIndex, mixDuration);
+ }
+ this.queue.drainDisabled = oldDrainDisabled;
+ this.queue.drain();
+ };
+ AnimationState.prototype.expandToIndex = function (index) {
+ if (index < this.tracks.length)
+ return this.tracks[index];
+ spine.Utils.ensureArrayCapacity(this.tracks, index - this.tracks.length + 1, null);
+ this.tracks.length = index + 1;
+ return null;
+ };
+ AnimationState.prototype.trackEntry = function (trackIndex, animation, loop, last) {
+ var entry = this.trackEntryPool.obtain();
+ entry.trackIndex = trackIndex;
+ entry.animation = animation;
+ entry.loop = loop;
+ entry.eventThreshold = 0;
+ entry.attachmentThreshold = 0;
+ entry.drawOrderThreshold = 0;
+ entry.animationStart = 0;
+ entry.animationEnd = animation.duration;
+ entry.animationLast = -1;
+ entry.nextAnimationLast = -1;
+ entry.delay = 0;
+ entry.trackTime = 0;
+ entry.trackLast = -1;
+ entry.nextTrackLast = -1;
+ entry.trackEnd = Number.MAX_VALUE;
+ entry.timeScale = 1;
+ entry.alpha = 1;
+ entry.interruptAlpha = 1;
+ entry.mixTime = 0;
+ entry.mixDuration = last == null ? 0 : this.data.getMix(last.animation, animation);
+ return entry;
+ };
+ AnimationState.prototype.disposeNext = function (entry) {
+ var next = entry.next;
+ while (next != null) {
+ this.queue.dispose(next);
+ next = next.next;
+ }
+ entry.next = null;
+ };
+ AnimationState.prototype._animationsChanged = function () {
+ this.animationsChanged = false;
+ var propertyIDs = this.propertyIDs;
+ propertyIDs.clear();
+ var mixingTo = this.mixingTo;
+ for (var i = 0, n = this.tracks.length; i < n; i++) {
+ var entry = this.tracks[i];
+ if (entry != null)
+ entry.setTimelineData(null, mixingTo, propertyIDs);
+ }
+ };
+ AnimationState.prototype.getCurrent = function (trackIndex) {
+ if (trackIndex >= this.tracks.length)
+ return null;
+ return this.tracks[trackIndex];
+ };
+ AnimationState.prototype.addListener = function (listener) {
+ if (listener == null)
+ throw new Error("listener cannot be null.");
+ this.listeners.push(listener);
+ };
+ AnimationState.prototype.removeListener = function (listener) {
+ var index = this.listeners.indexOf(listener);
+ if (index >= 0)
+ this.listeners.splice(index, 1);
+ };
+ AnimationState.prototype.clearListeners = function () {
+ this.listeners.length = 0;
+ };
+ AnimationState.prototype.clearListenerNotifications = function () {
+ this.queue.clear();
+ };
+ return AnimationState;
+ }());
+ AnimationState.emptyAnimation = new spine.Animation("", [], 0);
+ AnimationState.SUBSEQUENT = 0;
+ AnimationState.FIRST = 1;
+ AnimationState.DIP = 2;
+ AnimationState.DIP_MIX = 3;
+ spine.AnimationState = AnimationState;
+ var TrackEntry = (function () {
+ function TrackEntry() {
+ this.timelineData = new Array();
+ this.timelineDipMix = new Array();
+ this.timelinesRotation = new Array();
+ }
+ TrackEntry.prototype.reset = function () {
+ this.next = null;
+ this.mixingFrom = null;
+ this.animation = null;
+ this.listener = null;
+ this.timelineData.length = 0;
+ this.timelineDipMix.length = 0;
+ this.timelinesRotation.length = 0;
+ };
+ TrackEntry.prototype.setTimelineData = function (to, mixingToArray, propertyIDs) {
+ if (to != null)
+ mixingToArray.push(to);
+ var lastEntry = this.mixingFrom != null ? this.mixingFrom.setTimelineData(this, mixingToArray, propertyIDs) : this;
+ if (to != null)
+ mixingToArray.pop();
+ var mixingTo = mixingToArray;
+ var mixingToLast = mixingToArray.length - 1;
+ var timelines = this.animation.timelines;
+ var timelinesCount = this.animation.timelines.length;
+ var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
+ this.timelineDipMix.length = 0;
+ var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
+ outer: for (var i = 0; i < timelinesCount; i++) {
+ var id = timelines[i].getPropertyId();
+ if (!propertyIDs.add(id))
+ timelineData[i] = AnimationState.SUBSEQUENT;
+ else if (to == null || !to.hasTimeline(id))
+ timelineData[i] = AnimationState.FIRST;
+ else {
+ for (var ii = mixingToLast; ii >= 0; ii--) {
+ var entry = mixingTo[ii];
+ if (!entry.hasTimeline(id)) {
+ if (entry.mixDuration > 0) {
+ timelineData[i] = AnimationState.DIP_MIX;
+ timelineDipMix[i] = entry;
+ continue outer;
+ }
+ }
+ }
+ timelineData[i] = AnimationState.DIP;
+ }
+ }
+ return lastEntry;
+ };
+ TrackEntry.prototype.hasTimeline = function (id) {
+ var timelines = this.animation.timelines;
+ for (var i = 0, n = timelines.length; i < n; i++)
+ if (timelines[i].getPropertyId() == id)
+ return true;
+ return false;
+ };
+ TrackEntry.prototype.getAnimationTime = function () {
+ if (this.loop) {
+ var duration = this.animationEnd - this.animationStart;
+ if (duration == 0)
+ return this.animationStart;
+ return (this.trackTime % duration) + this.animationStart;
+ }
+ return Math.min(this.trackTime + this.animationStart, this.animationEnd);
+ };
+ TrackEntry.prototype.setAnimationLast = function (animationLast) {
+ this.animationLast = animationLast;
+ this.nextAnimationLast = animationLast;
+ };
+ TrackEntry.prototype.isComplete = function () {
+ return this.trackTime >= this.animationEnd - this.animationStart;
+ };
+ TrackEntry.prototype.resetRotationDirections = function () {
+ this.timelinesRotation.length = 0;
+ };
+ return TrackEntry;
+ }());
+ spine.TrackEntry = TrackEntry;
+ var EventQueue = (function () {
+ function EventQueue(animState) {
+ this.objects = [];
+ this.drainDisabled = false;
+ this.animState = animState;
+ }
+ EventQueue.prototype.start = function (entry) {
+ this.objects.push(EventType.start);
+ this.objects.push(entry);
+ this.animState.animationsChanged = true;
+ };
+ EventQueue.prototype.interrupt = function (entry) {
+ this.objects.push(EventType.interrupt);
+ this.objects.push(entry);
+ };
+ EventQueue.prototype.end = function (entry) {
+ this.objects.push(EventType.end);
+ this.objects.push(entry);
+ this.animState.animationsChanged = true;
+ };
+ EventQueue.prototype.dispose = function (entry) {
+ this.objects.push(EventType.dispose);
+ this.objects.push(entry);
+ };
+ EventQueue.prototype.complete = function (entry) {
+ this.objects.push(EventType.complete);
+ this.objects.push(entry);
+ };
+ EventQueue.prototype.event = function (entry, event) {
+ this.objects.push(EventType.event);
+ this.objects.push(entry);
+ this.objects.push(event);
+ };
+ EventQueue.prototype.drain = function () {
+ if (this.drainDisabled)
+ return;
+ this.drainDisabled = true;
+ var objects = this.objects;
+ var listeners = this.animState.listeners;
+ for (var i = 0; i < objects.length; i += 2) {
+ var type = objects[i];
+ var entry = objects[i + 1];
+ switch (type) {
+ case EventType.start:
+ if (entry.listener != null && entry.listener.start)
+ entry.listener.start(entry);
+ for (var ii = 0; ii < listeners.length; ii++)
+ if (listeners[ii].start)
+ listeners[ii].start(entry);
+ break;
+ case EventType.interrupt:
+ if (entry.listener != null && entry.listener.interrupt)
+ entry.listener.interrupt(entry);
+ for (var ii = 0; ii < listeners.length; ii++)
+ if (listeners[ii].interrupt)
+ listeners[ii].interrupt(entry);
+ break;
+ case EventType.end:
+ if (entry.listener != null && entry.listener.end)
+ entry.listener.end(entry);
+ for (var ii = 0; ii < listeners.length; ii++)
+ if (listeners[ii].end)
+ listeners[ii].end(entry);
+ case EventType.dispose:
+ if (entry.listener != null && entry.listener.dispose)
+ entry.listener.dispose(entry);
+ for (var ii = 0; ii < listeners.length; ii++)
+ if (listeners[ii].dispose)
+ listeners[ii].dispose(entry);
+ this.animState.trackEntryPool.free(entry);
+ break;
+ case EventType.complete:
+ if (entry.listener != null && entry.listener.complete)
+ entry.listener.complete(entry);
+ for (var ii = 0; ii < listeners.length; ii++)
+ if (listeners[ii].complete)
+ listeners[ii].complete(entry);
+ break;
+ case EventType.event:
+ var event_3 = objects[i++ + 2];
+ if (entry.listener != null && entry.listener.event)
+ entry.listener.event(entry, event_3);
+ for (var ii = 0; ii < listeners.length; ii++)
+ if (listeners[ii].event)
+ listeners[ii].event(entry, event_3);
+ break;
+ }
+ }
+ this.clear();
+ this.drainDisabled = false;
+ };
+ EventQueue.prototype.clear = function () {
+ this.objects.length = 0;
+ };
+ return EventQueue;
+ }());
+ spine.EventQueue = EventQueue;
+ var EventType;
+ (function (EventType) {
+ EventType[EventType["start"] = 0] = "start";
+ EventType[EventType["interrupt"] = 1] = "interrupt";
+ EventType[EventType["end"] = 2] = "end";
+ EventType[EventType["dispose"] = 3] = "dispose";
+ EventType[EventType["complete"] = 4] = "complete";
+ EventType[EventType["event"] = 5] = "event";
+ })(EventType = spine.EventType || (spine.EventType = {}));
+ var AnimationStateAdapter2 = (function () {
+ function AnimationStateAdapter2() {
+ }
+ AnimationStateAdapter2.prototype.start = function (entry) {
+ };
+ AnimationStateAdapter2.prototype.interrupt = function (entry) {
+ };
+ AnimationStateAdapter2.prototype.end = function (entry) {
+ };
+ AnimationStateAdapter2.prototype.dispose = function (entry) {
+ };
+ AnimationStateAdapter2.prototype.complete = function (entry) {
+ };
+ AnimationStateAdapter2.prototype.event = function (entry, event) {
+ };
+ return AnimationStateAdapter2;
+ }());
+ spine.AnimationStateAdapter2 = AnimationStateAdapter2;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var AnimationStateData = (function () {
+ function AnimationStateData(skeletonData) {
+ this.animationToMixTime = {};
+ this.defaultMix = 0;
+ if (skeletonData == null)
+ throw new Error("skeletonData cannot be null.");
+ this.skeletonData = skeletonData;
+ }
+ AnimationStateData.prototype.setMix = function (fromName, toName, duration) {
+ var from = this.skeletonData.findAnimation(fromName);
+ if (from == null)
+ throw new Error("Animation not found: " + fromName);
+ var to = this.skeletonData.findAnimation(toName);
+ if (to == null)
+ throw new Error("Animation not found: " + toName);
+ this.setMixWith(from, to, duration);
+ };
+ AnimationStateData.prototype.setMixWith = function (from, to, duration) {
+ if (from == null)
+ throw new Error("from cannot be null.");
+ if (to == null)
+ throw new Error("to cannot be null.");
+ var key = from.name + to.name;
+ this.animationToMixTime[key] = duration;
+ };
+ AnimationStateData.prototype.getMix = function (from, to) {
+ var key = from.name + to.name;
+ var value = this.animationToMixTime[key];
+ return value === undefined ? this.defaultMix : value;
+ };
+ return AnimationStateData;
+ }());
+ spine.AnimationStateData = AnimationStateData;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var AssetManager = (function () {
+ function AssetManager(textureLoader, pathPrefix) {
+ if (pathPrefix === void 0) { pathPrefix = ""; }
+ this.assets = {};
+ this.errors = {};
+ this.toLoad = 0;
+ this.loaded = 0;
+ this.textureLoader = textureLoader;
+ this.pathPrefix = pathPrefix;
+ }
+ AssetManager.prototype.loadText = function (path, success, error) {
+ var _this = this;
+ if (success === void 0) { success = null; }
+ if (error === void 0) { error = null; }
+ path = this.pathPrefix + path;
+ this.toLoad++;
+ var request = new XMLHttpRequest();
+ request.onreadystatechange = function () {
+ if (request.readyState == XMLHttpRequest.DONE) {
+ if (request.status >= 200 && request.status < 300) {
+ _this.assets[path] = request.responseText;
+ if (success)
+ success(path, request.responseText);
+ }
+ else {
+ _this.errors[path] = "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText;
+ if (error)
+ error(path, "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText);
+ }
+ _this.toLoad--;
+ _this.loaded++;
+ }
+ };
+ request.open("GET", path, true);
+ request.send();
+ };
+ AssetManager.prototype.loadTexture = function (path, success, error) {
+ var _this = this;
+ if (success === void 0) { success = null; }
+ if (error === void 0) { error = null; }
+ path = this.pathPrefix + path;
+ this.toLoad++;
+ var img = new Image();
+ img.crossOrigin = "anonymous";
+ img.onload = function (ev) {
+ var texture = _this.textureLoader(img);
+ _this.assets[path] = texture;
+ _this.toLoad--;
+ _this.loaded++;
+ if (success)
+ success(path, img);
+ };
+ img.onerror = function (ev) {
+ _this.errors[path] = "Couldn't load image " + path;
+ _this.toLoad--;
+ _this.loaded++;
+ if (error)
+ error(path, "Couldn't load image " + path);
+ };
+ img.src = path;
+ };
+ AssetManager.prototype.loadTextureData = function (path, data, success, error) {
+ var _this = this;
+ if (success === void 0) { success = null; }
+ if (error === void 0) { error = null; }
+ path = this.pathPrefix + path;
+ this.toLoad++;
+ var img = new Image();
+ img.onload = function (ev) {
+ var texture = _this.textureLoader(img);
+ _this.assets[path] = texture;
+ _this.toLoad--;
+ _this.loaded++;
+ if (success)
+ success(path, img);
+ };
+ img.onerror = function (ev) {
+ _this.errors[path] = "Couldn't load image " + path;
+ _this.toLoad--;
+ _this.loaded++;
+ if (error)
+ error(path, "Couldn't load image " + path);
+ };
+ img.src = data;
+ };
+ AssetManager.prototype.get = function (path) {
+ path = this.pathPrefix + path;
+ return this.assets[path];
+ };
+ AssetManager.prototype.remove = function (path) {
+ path = this.pathPrefix + path;
+ var asset = this.assets[path];
+ if (asset.dispose)
+ asset.dispose();
+ this.assets[path] = null;
+ };
+ AssetManager.prototype.removeAll = function () {
+ for (var key in this.assets) {
+ var asset = this.assets[key];
+ if (asset.dispose)
+ asset.dispose();
+ }
+ this.assets = {};
+ };
+ AssetManager.prototype.isLoadingComplete = function () {
+ return this.toLoad == 0;
+ };
+ AssetManager.prototype.getToLoad = function () {
+ return this.toLoad;
+ };
+ AssetManager.prototype.getLoaded = function () {
+ return this.loaded;
+ };
+ AssetManager.prototype.dispose = function () {
+ this.removeAll();
+ };
+ AssetManager.prototype.hasErrors = function () {
+ return Object.keys(this.errors).length > 0;
+ };
+ AssetManager.prototype.getErrors = function () {
+ return this.errors;
+ };
+ return AssetManager;
+ }());
+ spine.AssetManager = AssetManager;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var AtlasAttachmentLoader = (function () {
+ function AtlasAttachmentLoader(atlas) {
+ this.atlas = atlas;
+ }
+ AtlasAttachmentLoader.prototype.newRegionAttachment = function (skin, name, path) {
+ var region = this.atlas.findRegion(path);
+ if (region == null)
+ throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")");
+ region.renderObject = region;
+ var attachment = new spine.RegionAttachment(name);
+ attachment.setRegion(region);
+ return attachment;
+ };
+ AtlasAttachmentLoader.prototype.newMeshAttachment = function (skin, name, path) {
+ var region = this.atlas.findRegion(path);
+ if (region == null)
+ throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")");
+ region.renderObject = region;
+ var attachment = new spine.MeshAttachment(name);
+ attachment.region = region;
+ return attachment;
+ };
+ AtlasAttachmentLoader.prototype.newBoundingBoxAttachment = function (skin, name) {
+ return new spine.BoundingBoxAttachment(name);
+ };
+ AtlasAttachmentLoader.prototype.newPathAttachment = function (skin, name) {
+ return new spine.PathAttachment(name);
+ };
+ AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) {
+ return new spine.PointAttachment(name);
+ };
+ AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) {
+ return new spine.ClippingAttachment(name);
+ };
+ return AtlasAttachmentLoader;
+ }());
+ spine.AtlasAttachmentLoader = AtlasAttachmentLoader;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var BlendMode;
+ (function (BlendMode) {
+ BlendMode[BlendMode["Normal"] = 0] = "Normal";
+ BlendMode[BlendMode["Additive"] = 1] = "Additive";
+ BlendMode[BlendMode["Multiply"] = 2] = "Multiply";
+ BlendMode[BlendMode["Screen"] = 3] = "Screen";
+ })(BlendMode = spine.BlendMode || (spine.BlendMode = {}));
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var Bone = (function () {
+ function Bone(data, skeleton, parent) {
+ this.children = new Array();
+ this.x = 0;
+ this.y = 0;
+ this.rotation = 0;
+ this.scaleX = 0;
+ this.scaleY = 0;
+ this.shearX = 0;
+ this.shearY = 0;
+ this.ax = 0;
+ this.ay = 0;
+ this.arotation = 0;
+ this.ascaleX = 0;
+ this.ascaleY = 0;
+ this.ashearX = 0;
+ this.ashearY = 0;
+ this.appliedValid = false;
+ this.a = 0;
+ this.b = 0;
+ this.worldX = 0;
+ this.c = 0;
+ this.d = 0;
+ this.worldY = 0;
+ this.sorted = false;
+ if (data == null)
+ throw new Error("data cannot be null.");
+ if (skeleton == null)
+ throw new Error("skeleton cannot be null.");
+ this.data = data;
+ this.skeleton = skeleton;
+ this.parent = parent;
+ this.setToSetupPose();
+ }
+ Bone.prototype.update = function () {
+ this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);
+ };
+ Bone.prototype.updateWorldTransform = function () {
+ this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);
+ };
+ Bone.prototype.updateWorldTransformWith = function (x, y, rotation, scaleX, scaleY, shearX, shearY) {
+ this.ax = x;
+ this.ay = y;
+ this.arotation = rotation;
+ this.ascaleX = scaleX;
+ this.ascaleY = scaleY;
+ this.ashearX = shearX;
+ this.ashearY = shearY;
+ this.appliedValid = true;
+ var parent = this.parent;
+ if (parent == null) {
+ var rotationY = rotation + 90 + shearY;
+ var la = spine.MathUtils.cosDeg(rotation + shearX) * scaleX;
+ var lb = spine.MathUtils.cosDeg(rotationY) * scaleY;
+ var lc = spine.MathUtils.sinDeg(rotation + shearX) * scaleX;
+ var ld = spine.MathUtils.sinDeg(rotationY) * scaleY;
+ var skeleton = this.skeleton;
+ if (skeleton.flipX) {
+ x = -x;
+ la = -la;
+ lb = -lb;
+ }
+ if (skeleton.flipY) {
+ y = -y;
+ lc = -lc;
+ ld = -ld;
+ }
+ this.a = la;
+ this.b = lb;
+ this.c = lc;
+ this.d = ld;
+ this.worldX = x + skeleton.x;
+ this.worldY = y + skeleton.y;
+ return;
+ }
+ var pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;
+ this.worldX = pa * x + pb * y + parent.worldX;
+ this.worldY = pc * x + pd * y + parent.worldY;
+ switch (this.data.transformMode) {
+ case spine.TransformMode.Normal: {
+ var rotationY = rotation + 90 + shearY;
+ var la = spine.MathUtils.cosDeg(rotation + shearX) * scaleX;
+ var lb = spine.MathUtils.cosDeg(rotationY) * scaleY;
+ var lc = spine.MathUtils.sinDeg(rotation + shearX) * scaleX;
+ var ld = spine.MathUtils.sinDeg(rotationY) * scaleY;
+ this.a = pa * la + pb * lc;
+ this.b = pa * lb + pb * ld;
+ this.c = pc * la + pd * lc;
+ this.d = pc * lb + pd * ld;
+ return;
+ }
+ case spine.TransformMode.OnlyTranslation: {
+ var rotationY = rotation + 90 + shearY;
+ this.a = spine.MathUtils.cosDeg(rotation + shearX) * scaleX;
+ this.b = spine.MathUtils.cosDeg(rotationY) * scaleY;
+ this.c = spine.MathUtils.sinDeg(rotation + shearX) * scaleX;
+ this.d = spine.MathUtils.sinDeg(rotationY) * scaleY;
+ break;
+ }
+ case spine.TransformMode.NoRotationOrReflection: {
+ var s = pa * pa + pc * pc;
+ var prx = 0;
+ if (s > 0.0001) {
+ s = Math.abs(pa * pd - pb * pc) / s;
+ pb = pc * s;
+ pd = pa * s;
+ prx = Math.atan2(pc, pa) * spine.MathUtils.radDeg;
+ }
+ else {
+ pa = 0;
+ pc = 0;
+ prx = 90 - Math.atan2(pd, pb) * spine.MathUtils.radDeg;
+ }
+ var rx = rotation + shearX - prx;
+ var ry = rotation + shearY - prx + 90;
+ var la = spine.MathUtils.cosDeg(rx) * scaleX;
+ var lb = spine.MathUtils.cosDeg(ry) * scaleY;
+ var lc = spine.MathUtils.sinDeg(rx) * scaleX;
+ var ld = spine.MathUtils.sinDeg(ry) * scaleY;
+ this.a = pa * la - pb * lc;
+ this.b = pa * lb - pb * ld;
+ this.c = pc * la + pd * lc;
+ this.d = pc * lb + pd * ld;
+ break;
+ }
+ case spine.TransformMode.NoScale:
+ case spine.TransformMode.NoScaleOrReflection: {
+ var cos = spine.MathUtils.cosDeg(rotation);
+ var sin = spine.MathUtils.sinDeg(rotation);
+ var za = pa * cos + pb * sin;
+ var zc = pc * cos + pd * sin;
+ var s = Math.sqrt(za * za + zc * zc);
+ if (s > 0.00001)
+ s = 1 / s;
+ za *= s;
+ zc *= s;
+ s = Math.sqrt(za * za + zc * zc);
+ var r = Math.PI / 2 + Math.atan2(zc, za);
+ var zb = Math.cos(r) * s;
+ var zd = Math.sin(r) * s;
+ var la = spine.MathUtils.cosDeg(shearX) * scaleX;
+ var lb = spine.MathUtils.cosDeg(90 + shearY) * scaleY;
+ var lc = spine.MathUtils.sinDeg(shearX) * scaleX;
+ var ld = spine.MathUtils.sinDeg(90 + shearY) * scaleY;
+ if (this.data.transformMode != spine.TransformMode.NoScaleOrReflection ? pa * pd - pb * pc < 0 : this.skeleton.flipX != this.skeleton.flipY) {
+ zb = -zb;
+ zd = -zd;
+ }
+ this.a = za * la + zb * lc;
+ this.b = za * lb + zb * ld;
+ this.c = zc * la + zd * lc;
+ this.d = zc * lb + zd * ld;
+ return;
+ }
+ }
+ if (this.skeleton.flipX) {
+ this.a = -this.a;
+ this.b = -this.b;
+ }
+ if (this.skeleton.flipY) {
+ this.c = -this.c;
+ this.d = -this.d;
+ }
+ };
+ Bone.prototype.setToSetupPose = function () {
+ var data = this.data;
+ this.x = data.x;
+ this.y = data.y;
+ this.rotation = data.rotation;
+ this.scaleX = data.scaleX;
+ this.scaleY = data.scaleY;
+ this.shearX = data.shearX;
+ this.shearY = data.shearY;
+ };
+ Bone.prototype.getWorldRotationX = function () {
+ return Math.atan2(this.c, this.a) * spine.MathUtils.radDeg;
+ };
+ Bone.prototype.getWorldRotationY = function () {
+ return Math.atan2(this.d, this.b) * spine.MathUtils.radDeg;
+ };
+ Bone.prototype.getWorldScaleX = function () {
+ return Math.sqrt(this.a * this.a + this.c * this.c);
+ };
+ Bone.prototype.getWorldScaleY = function () {
+ return Math.sqrt(this.b * this.b + this.d * this.d);
+ };
+ Bone.prototype.updateAppliedTransform = function () {
+ this.appliedValid = true;
+ var parent = this.parent;
+ if (parent == null) {
+ this.ax = this.worldX;
+ this.ay = this.worldY;
+ this.arotation = Math.atan2(this.c, this.a) * spine.MathUtils.radDeg;
+ this.ascaleX = Math.sqrt(this.a * this.a + this.c * this.c);
+ this.ascaleY = Math.sqrt(this.b * this.b + this.d * this.d);
+ this.ashearX = 0;
+ this.ashearY = Math.atan2(this.a * this.b + this.c * this.d, this.a * this.d - this.b * this.c) * spine.MathUtils.radDeg;
+ return;
+ }
+ var pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;
+ var pid = 1 / (pa * pd - pb * pc);
+ var dx = this.worldX - parent.worldX, dy = this.worldY - parent.worldY;
+ this.ax = (dx * pd * pid - dy * pb * pid);
+ this.ay = (dy * pa * pid - dx * pc * pid);
+ var ia = pid * pd;
+ var id = pid * pa;
+ var ib = pid * pb;
+ var ic = pid * pc;
+ var ra = ia * this.a - ib * this.c;
+ var rb = ia * this.b - ib * this.d;
+ var rc = id * this.c - ic * this.a;
+ var rd = id * this.d - ic * this.b;
+ this.ashearX = 0;
+ this.ascaleX = Math.sqrt(ra * ra + rc * rc);
+ if (this.ascaleX > 0.0001) {
+ var det = ra * rd - rb * rc;
+ this.ascaleY = det / this.ascaleX;
+ this.ashearY = Math.atan2(ra * rb + rc * rd, det) * spine.MathUtils.radDeg;
+ this.arotation = Math.atan2(rc, ra) * spine.MathUtils.radDeg;
+ }
+ else {
+ this.ascaleX = 0;
+ this.ascaleY = Math.sqrt(rb * rb + rd * rd);
+ this.ashearY = 0;
+ this.arotation = 90 - Math.atan2(rd, rb) * spine.MathUtils.radDeg;
+ }
+ };
+ Bone.prototype.worldToLocal = function (world) {
+ var a = this.a, b = this.b, c = this.c, d = this.d;
+ var invDet = 1 / (a * d - b * c);
+ var x = world.x - this.worldX, y = world.y - this.worldY;
+ world.x = (x * d * invDet - y * b * invDet);
+ world.y = (y * a * invDet - x * c * invDet);
+ return world;
+ };
+ Bone.prototype.localToWorld = function (local) {
+ var x = local.x, y = local.y;
+ local.x = x * this.a + y * this.b + this.worldX;
+ local.y = x * this.c + y * this.d + this.worldY;
+ return local;
+ };
+ Bone.prototype.worldToLocalRotation = function (worldRotation) {
+ var sin = spine.MathUtils.sinDeg(worldRotation), cos = spine.MathUtils.cosDeg(worldRotation);
+ return Math.atan2(this.a * sin - this.c * cos, this.d * cos - this.b * sin) * spine.MathUtils.radDeg;
+ };
+ Bone.prototype.localToWorldRotation = function (localRotation) {
+ var sin = spine.MathUtils.sinDeg(localRotation), cos = spine.MathUtils.cosDeg(localRotation);
+ return Math.atan2(cos * this.c + sin * this.d, cos * this.a + sin * this.b) * spine.MathUtils.radDeg;
+ };
+ Bone.prototype.rotateWorld = function (degrees) {
+ var a = this.a, b = this.b, c = this.c, d = this.d;
+ var cos = spine.MathUtils.cosDeg(degrees), sin = spine.MathUtils.sinDeg(degrees);
+ this.a = cos * a - sin * c;
+ this.b = cos * b - sin * d;
+ this.c = sin * a + cos * c;
+ this.d = sin * b + cos * d;
+ this.appliedValid = false;
+ };
+ return Bone;
+ }());
+ spine.Bone = Bone;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var BoneData = (function () {
+ function BoneData(index, name, parent) {
+ this.x = 0;
+ this.y = 0;
+ this.rotation = 0;
+ this.scaleX = 1;
+ this.scaleY = 1;
+ this.shearX = 0;
+ this.shearY = 0;
+ this.transformMode = TransformMode.Normal;
+ if (index < 0)
+ throw new Error("index must be >= 0.");
+ if (name == null)
+ throw new Error("name cannot be null.");
+ this.index = index;
+ this.name = name;
+ this.parent = parent;
+ }
+ return BoneData;
+ }());
+ spine.BoneData = BoneData;
+ var TransformMode;
+ (function (TransformMode) {
+ TransformMode[TransformMode["Normal"] = 0] = "Normal";
+ TransformMode[TransformMode["OnlyTranslation"] = 1] = "OnlyTranslation";
+ TransformMode[TransformMode["NoRotationOrReflection"] = 2] = "NoRotationOrReflection";
+ TransformMode[TransformMode["NoScale"] = 3] = "NoScale";
+ TransformMode[TransformMode["NoScaleOrReflection"] = 4] = "NoScaleOrReflection";
+ })(TransformMode = spine.TransformMode || (spine.TransformMode = {}));
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var Event = (function () {
+ function Event(time, data) {
+ if (data == null)
+ throw new Error("data cannot be null.");
+ this.time = time;
+ this.data = data;
+ }
+ return Event;
+ }());
+ spine.Event = Event;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var EventData = (function () {
+ function EventData(name) {
+ this.name = name;
+ }
+ return EventData;
+ }());
+ spine.EventData = EventData;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var IkConstraint = (function () {
+ function IkConstraint(data, skeleton) {
+ this.mix = 1;
+ this.bendDirection = 0;
+ if (data == null)
+ throw new Error("data cannot be null.");
+ if (skeleton == null)
+ throw new Error("skeleton cannot be null.");
+ this.data = data;
+ this.mix = data.mix;
+ this.bendDirection = data.bendDirection;
+ this.bones = new Array();
+ for (var i = 0; i < data.bones.length; i++)
+ this.bones.push(skeleton.findBone(data.bones[i].name));
+ this.target = skeleton.findBone(data.target.name);
+ }
+ IkConstraint.prototype.getOrder = function () {
+ return this.data.order;
+ };
+ IkConstraint.prototype.apply = function () {
+ this.update();
+ };
+ IkConstraint.prototype.update = function () {
+ var target = this.target;
+ var bones = this.bones;
+ switch (bones.length) {
+ case 1:
+ this.apply1(bones[0], target.worldX, target.worldY, this.mix);
+ break;
+ case 2:
+ this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.mix);
+ break;
+ }
+ };
+ IkConstraint.prototype.apply1 = function (bone, targetX, targetY, alpha) {
+ if (!bone.appliedValid)
+ bone.updateAppliedTransform();
+ var p = bone.parent;
+ var id = 1 / (p.a * p.d - p.b * p.c);
+ var x = targetX - p.worldX, y = targetY - p.worldY;
+ var tx = (x * p.d - y * p.b) * id - bone.ax, ty = (y * p.a - x * p.c) * id - bone.ay;
+ var rotationIK = Math.atan2(ty, tx) * spine.MathUtils.radDeg - bone.ashearX - bone.arotation;
+ if (bone.ascaleX < 0)
+ rotationIK += 180;
+ if (rotationIK > 180)
+ rotationIK -= 360;
+ else if (rotationIK < -180)
+ rotationIK += 360;
+ bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, bone.ascaleX, bone.ascaleY, bone.ashearX, bone.ashearY);
+ };
+ IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, alpha) {
+ if (alpha == 0) {
+ child.updateWorldTransform();
+ return;
+ }
+ if (!parent.appliedValid)
+ parent.updateAppliedTransform();
+ if (!child.appliedValid)
+ child.updateAppliedTransform();
+ var px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, csx = child.ascaleX;
+ var os1 = 0, os2 = 0, s2 = 0;
+ if (psx < 0) {
+ psx = -psx;
+ os1 = 180;
+ s2 = -1;
+ }
+ else {
+ os1 = 0;
+ s2 = 1;
+ }
+ if (psy < 0) {
+ psy = -psy;
+ s2 = -s2;
+ }
+ if (csx < 0) {
+ csx = -csx;
+ os2 = 180;
+ }
+ else
+ os2 = 0;
+ var cx = child.ax, cy = 0, cwx = 0, cwy = 0, a = parent.a, b = parent.b, c = parent.c, d = parent.d;
+ var u = Math.abs(psx - psy) <= 0.0001;
+ if (!u) {
+ cy = 0;
+ cwx = a * cx + parent.worldX;
+ cwy = c * cx + parent.worldY;
+ }
+ else {
+ cy = child.ay;
+ cwx = a * cx + b * cy + parent.worldX;
+ cwy = c * cx + d * cy + parent.worldY;
+ }
+ var pp = parent.parent;
+ a = pp.a;
+ b = pp.b;
+ c = pp.c;
+ d = pp.d;
+ var id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY;
+ var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py;
+ x = cwx - pp.worldX;
+ y = cwy - pp.worldY;
+ var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;
+ var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0;
+ outer: if (u) {
+ l2 *= psx;
+ var cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2);
+ if (cos < -1)
+ cos = -1;
+ else if (cos > 1)
+ cos = 1;
+ a2 = Math.acos(cos) * bendDir;
+ a = l1 + l2 * cos;
+ b = l2 * Math.sin(a2);
+ a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b);
+ }
+ else {
+ a = psx * l2;
+ b = psy * l2;
+ var aa = a * a, bb = b * b, dd = tx * tx + ty * ty, ta = Math.atan2(ty, tx);
+ c = bb * l1 * l1 + aa * dd - aa * bb;
+ var c1 = -2 * bb * l1, c2 = bb - aa;
+ d = c1 * c1 - 4 * c2 * c;
+ if (d >= 0) {
+ var q = Math.sqrt(d);
+ if (c1 < 0)
+ q = -q;
+ q = -(c1 + q) / 2;
+ var r0 = q / c2, r1 = c / q;
+ var r = Math.abs(r0) < Math.abs(r1) ? r0 : r1;
+ if (r * r <= dd) {
+ y = Math.sqrt(dd - r * r) * bendDir;
+ a1 = ta - Math.atan2(y, r);
+ a2 = Math.atan2(y / psy, (r - l1) / psx);
+ break outer;
+ }
+ }
+ var minAngle = spine.MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
+ var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
+ c = -a * l1 / (aa - bb);
+ if (c >= -1 && c <= 1) {
+ c = Math.acos(c);
+ x = a * Math.cos(c) + l1;
+ y = b * Math.sin(c);
+ d = x * x + y * y;
+ if (d < minDist) {
+ minAngle = c;
+ minDist = d;
+ minX = x;
+ minY = y;
+ }
+ if (d > maxDist) {
+ maxAngle = c;
+ maxDist = d;
+ maxX = x;
+ maxY = y;
+ }
+ }
+ if (dd <= (minDist + maxDist) / 2) {
+ a1 = ta - Math.atan2(minY * bendDir, minX);
+ a2 = minAngle * bendDir;
+ }
+ else {
+ a1 = ta - Math.atan2(maxY * bendDir, maxX);
+ a2 = maxAngle * bendDir;
+ }
+ }
+ var os = Math.atan2(cy, cx) * s2;
+ var rotation = parent.arotation;
+ a1 = (a1 - os) * spine.MathUtils.radDeg + os1 - rotation;
+ if (a1 > 180)
+ a1 -= 360;
+ else if (a1 < -180)
+ a1 += 360;
+ parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, parent.ascaleX, parent.ascaleY, 0, 0);
+ rotation = child.arotation;
+ a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation;
+ if (a2 > 180)
+ a2 -= 360;
+ else if (a2 < -180)
+ a2 += 360;
+ child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY);
+ };
+ return IkConstraint;
+ }());
+ spine.IkConstraint = IkConstraint;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var IkConstraintData = (function () {
+ function IkConstraintData(name) {
+ this.order = 0;
+ this.bones = new Array();
+ this.bendDirection = 1;
+ this.mix = 1;
+ this.name = name;
+ }
+ return IkConstraintData;
+ }());
+ spine.IkConstraintData = IkConstraintData;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var PathConstraint = (function () {
+ function PathConstraint(data, skeleton) {
+ this.position = 0;
+ this.spacing = 0;
+ this.rotateMix = 0;
+ this.translateMix = 0;
+ this.spaces = new Array();
+ this.positions = new Array();
+ this.world = new Array();
+ this.curves = new Array();
+ this.lengths = new Array();
+ this.segments = new Array();
+ if (data == null)
+ throw new Error("data cannot be null.");
+ if (skeleton == null)
+ throw new Error("skeleton cannot be null.");
+ this.data = data;
+ this.bones = new Array();
+ for (var i = 0, n = data.bones.length; i < n; i++)
+ this.bones.push(skeleton.findBone(data.bones[i].name));
+ this.target = skeleton.findSlot(data.target.name);
+ this.position = data.position;
+ this.spacing = data.spacing;
+ this.rotateMix = data.rotateMix;
+ this.translateMix = data.translateMix;
+ }
+ PathConstraint.prototype.apply = function () {
+ this.update();
+ };
+ PathConstraint.prototype.update = function () {
+ var attachment = this.target.getAttachment();
+ if (!(attachment instanceof spine.PathAttachment))
+ return;
+ var rotateMix = this.rotateMix, translateMix = this.translateMix;
+ var translate = translateMix > 0, rotate = rotateMix > 0;
+ if (!translate && !rotate)
+ return;
+ var data = this.data;
+ var spacingMode = data.spacingMode;
+ var lengthSpacing = spacingMode == spine.SpacingMode.Length;
+ var rotateMode = data.rotateMode;
+ var tangents = rotateMode == spine.RotateMode.Tangent, scale = rotateMode == spine.RotateMode.ChainScale;
+ var boneCount = this.bones.length, spacesCount = tangents ? boneCount : boneCount + 1;
+ var bones = this.bones;
+ var spaces = spine.Utils.setArraySize(this.spaces, spacesCount), lengths = null;
+ var spacing = this.spacing;
+ if (scale || lengthSpacing) {
+ if (scale)
+ lengths = spine.Utils.setArraySize(this.lengths, boneCount);
+ for (var i = 0, n = spacesCount - 1; i < n;) {
+ var bone = bones[i];
+ var setupLength = bone.data.length;
+ if (setupLength == 0)
+ setupLength = 0.0000001;
+ var x = setupLength * bone.a, y = setupLength * bone.c;
+ var length_1 = Math.sqrt(x * x + y * y);
+ if (scale)
+ lengths[i] = length_1;
+ spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length_1 / setupLength;
+ }
+ }
+ else {
+ for (var i = 1; i < spacesCount; i++)
+ spaces[i] = spacing;
+ }
+ var positions = this.computeWorldPositions(attachment, spacesCount, tangents, data.positionMode == spine.PositionMode.Percent, spacingMode == spine.SpacingMode.Percent);
+ var boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation;
+ var tip = false;
+ if (offsetRotation == 0)
+ tip = rotateMode == spine.RotateMode.Chain;
+ else {
+ tip = false;
+ var p = this.target.bone;
+ offsetRotation *= p.a * p.d - p.b * p.c > 0 ? spine.MathUtils.degRad : -spine.MathUtils.degRad;
+ }
+ for (var i = 0, p = 3; i < boneCount; i++, p += 3) {
+ var bone = bones[i];
+ bone.worldX += (boneX - bone.worldX) * translateMix;
+ bone.worldY += (boneY - bone.worldY) * translateMix;
+ var x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY;
+ if (scale) {
+ var length_2 = lengths[i];
+ if (length_2 != 0) {
+ var s = (Math.sqrt(dx * dx + dy * dy) / length_2 - 1) * rotateMix + 1;
+ bone.a *= s;
+ bone.c *= s;
+ }
+ }
+ boneX = x;
+ boneY = y;
+ if (rotate) {
+ var a = bone.a, b = bone.b, c = bone.c, d = bone.d, r = 0, cos = 0, sin = 0;
+ if (tangents)
+ r = positions[p - 1];
+ else if (spaces[i + 1] == 0)
+ r = positions[p + 2];
+ else
+ r = Math.atan2(dy, dx);
+ r -= Math.atan2(c, a);
+ if (tip) {
+ cos = Math.cos(r);
+ sin = Math.sin(r);
+ var length_3 = bone.data.length;
+ boneX += (length_3 * (cos * a - sin * c) - dx) * rotateMix;
+ boneY += (length_3 * (sin * a + cos * c) - dy) * rotateMix;
+ }
+ else {
+ r += offsetRotation;
+ }
+ if (r > spine.MathUtils.PI)
+ r -= spine.MathUtils.PI2;
+ else if (r < -spine.MathUtils.PI)
+ r += spine.MathUtils.PI2;
+ r *= rotateMix;
+ cos = Math.cos(r);
+ sin = Math.sin(r);
+ bone.a = cos * a - sin * c;
+ bone.b = cos * b - sin * d;
+ bone.c = sin * a + cos * c;
+ bone.d = sin * b + cos * d;
+ }
+ bone.appliedValid = false;
+ }
+ };
+ PathConstraint.prototype.computeWorldPositions = function (path, spacesCount, tangents, percentPosition, percentSpacing) {
+ var target = this.target;
+ var position = this.position;
+ var spaces = this.spaces, out = spine.Utils.setArraySize(this.positions, spacesCount * 3 + 2), world = null;
+ var closed = path.closed;
+ var verticesLength = path.worldVerticesLength, curveCount = verticesLength / 6, prevCurve = PathConstraint.NONE;
+ if (!path.constantSpeed) {
+ var lengths = path.lengths;
+ curveCount -= closed ? 1 : 2;
+ var pathLength_1 = lengths[curveCount];
+ if (percentPosition)
+ position *= pathLength_1;
+ if (percentSpacing) {
+ for (var i = 0; i < spacesCount; i++)
+ spaces[i] *= pathLength_1;
+ }
+ world = spine.Utils.setArraySize(this.world, 8);
+ for (var i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) {
+ var space = spaces[i];
+ position += space;
+ var p = position;
+ if (closed) {
+ p %= pathLength_1;
+ if (p < 0)
+ p += pathLength_1;
+ curve = 0;
+ }
+ else if (p < 0) {
+ if (prevCurve != PathConstraint.BEFORE) {
+ prevCurve = PathConstraint.BEFORE;
+ path.computeWorldVertices(target, 2, 4, world, 0, 2);
+ }
+ this.addBeforePosition(p, world, 0, out, o);
+ continue;
+ }
+ else if (p > pathLength_1) {
+ if (prevCurve != PathConstraint.AFTER) {
+ prevCurve = PathConstraint.AFTER;
+ path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2);
+ }
+ this.addAfterPosition(p - pathLength_1, world, 0, out, o);
+ continue;
+ }
+ for (;; curve++) {
+ var length_4 = lengths[curve];
+ if (p > length_4)
+ continue;
+ if (curve == 0)
+ p /= length_4;
+ else {
+ var prev = lengths[curve - 1];
+ p = (p - prev) / (length_4 - prev);
+ }
+ break;
+ }
+ if (curve != prevCurve) {
+ prevCurve = curve;
+ if (closed && curve == curveCount) {
+ path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2);
+ path.computeWorldVertices(target, 0, 4, world, 4, 2);
+ }
+ else
+ path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2);
+ }
+ this.addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, tangents || (i > 0 && space == 0));
+ }
+ return out;
+ }
+ if (closed) {
+ verticesLength += 2;
+ world = spine.Utils.setArraySize(this.world, verticesLength);
+ path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2);
+ path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2);
+ world[verticesLength - 2] = world[0];
+ world[verticesLength - 1] = world[1];
+ }
+ else {
+ curveCount--;
+ verticesLength -= 4;
+ world = spine.Utils.setArraySize(this.world, verticesLength);
+ path.computeWorldVertices(target, 2, verticesLength, world, 0, 2);
+ }
+ var curves = spine.Utils.setArraySize(this.curves, curveCount);
+ var pathLength = 0;
+ var x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0;
+ var tmpx = 0, tmpy = 0, dddfx = 0, dddfy = 0, ddfx = 0, ddfy = 0, dfx = 0, dfy = 0;
+ for (var i = 0, w = 2; i < curveCount; i++, w += 6) {
+ cx1 = world[w];
+ cy1 = world[w + 1];
+ cx2 = world[w + 2];
+ cy2 = world[w + 3];
+ x2 = world[w + 4];
+ y2 = world[w + 5];
+ tmpx = (x1 - cx1 * 2 + cx2) * 0.1875;
+ tmpy = (y1 - cy1 * 2 + cy2) * 0.1875;
+ dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375;
+ dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375;
+ ddfx = tmpx * 2 + dddfx;
+ ddfy = tmpy * 2 + dddfy;
+ dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667;
+ dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667;
+ pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
+ dfx += ddfx;
+ dfy += ddfy;
+ ddfx += dddfx;
+ ddfy += dddfy;
+ pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
+ dfx += ddfx;
+ dfy += ddfy;
+ pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
+ dfx += ddfx + dddfx;
+ dfy += ddfy + dddfy;
+ pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
+ curves[i] = pathLength;
+ x1 = x2;
+ y1 = y2;
+ }
+ if (percentPosition)
+ position *= pathLength;
+ if (percentSpacing) {
+ for (var i = 0; i < spacesCount; i++)
+ spaces[i] *= pathLength;
+ }
+ var segments = this.segments;
+ var curveLength = 0;
+ for (var i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) {
+ var space = spaces[i];
+ position += space;
+ var p = position;
+ if (closed) {
+ p %= pathLength;
+ if (p < 0)
+ p += pathLength;
+ curve = 0;
+ }
+ else if (p < 0) {
+ this.addBeforePosition(p, world, 0, out, o);
+ continue;
+ }
+ else if (p > pathLength) {
+ this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o);
+ continue;
+ }
+ for (;; curve++) {
+ var length_5 = curves[curve];
+ if (p > length_5)
+ continue;
+ if (curve == 0)
+ p /= length_5;
+ else {
+ var prev = curves[curve - 1];
+ p = (p - prev) / (length_5 - prev);
+ }
+ break;
+ }
+ if (curve != prevCurve) {
+ prevCurve = curve;
+ var ii = curve * 6;
+ x1 = world[ii];
+ y1 = world[ii + 1];
+ cx1 = world[ii + 2];
+ cy1 = world[ii + 3];
+ cx2 = world[ii + 4];
+ cy2 = world[ii + 5];
+ x2 = world[ii + 6];
+ y2 = world[ii + 7];
+ tmpx = (x1 - cx1 * 2 + cx2) * 0.03;
+ tmpy = (y1 - cy1 * 2 + cy2) * 0.03;
+ dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006;
+ dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006;
+ ddfx = tmpx * 2 + dddfx;
+ ddfy = tmpy * 2 + dddfy;
+ dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667;
+ dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667;
+ curveLength = Math.sqrt(dfx * dfx + dfy * dfy);
+ segments[0] = curveLength;
+ for (ii = 1; ii < 8; ii++) {
+ dfx += ddfx;
+ dfy += ddfy;
+ ddfx += dddfx;
+ ddfy += dddfy;
+ curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
+ segments[ii] = curveLength;
+ }
+ dfx += ddfx;
+ dfy += ddfy;
+ curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
+ segments[8] = curveLength;
+ dfx += ddfx + dddfx;
+ dfy += ddfy + dddfy;
+ curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
+ segments[9] = curveLength;
+ segment = 0;
+ }
+ p *= curveLength;
+ for (;; segment++) {
+ var length_6 = segments[segment];
+ if (p > length_6)
+ continue;
+ if (segment == 0)
+ p /= length_6;
+ else {
+ var prev = segments[segment - 1];
+ p = segment + (p - prev) / (length_6 - prev);
+ }
+ break;
+ }
+ this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0));
+ }
+ return out;
+ };
+ PathConstraint.prototype.addBeforePosition = function (p, temp, i, out, o) {
+ var x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx);
+ out[o] = x1 + p * Math.cos(r);
+ out[o + 1] = y1 + p * Math.sin(r);
+ out[o + 2] = r;
+ };
+ PathConstraint.prototype.addAfterPosition = function (p, temp, i, out, o) {
+ var x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx);
+ out[o] = x1 + p * Math.cos(r);
+ out[o + 1] = y1 + p * Math.sin(r);
+ out[o + 2] = r;
+ };
+ PathConstraint.prototype.addCurvePosition = function (p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) {
+ if (p == 0 || isNaN(p))
+ p = 0.0001;
+ var tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u;
+ var ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p;
+ var x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt;
+ out[o] = x;
+ out[o + 1] = y;
+ if (tangents)
+ out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
+ };
+ PathConstraint.prototype.getOrder = function () {
+ return this.data.order;
+ };
+ return PathConstraint;
+ }());
+ PathConstraint.NONE = -1;
+ PathConstraint.BEFORE = -2;
+ PathConstraint.AFTER = -3;
+ spine.PathConstraint = PathConstraint;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var PathConstraintData = (function () {
+ function PathConstraintData(name) {
+ this.order = 0;
+ this.bones = new Array();
+ this.name = name;
+ }
+ return PathConstraintData;
+ }());
+ spine.PathConstraintData = PathConstraintData;
+ var PositionMode;
+ (function (PositionMode) {
+ PositionMode[PositionMode["Fixed"] = 0] = "Fixed";
+ PositionMode[PositionMode["Percent"] = 1] = "Percent";
+ })(PositionMode = spine.PositionMode || (spine.PositionMode = {}));
+ var SpacingMode;
+ (function (SpacingMode) {
+ SpacingMode[SpacingMode["Length"] = 0] = "Length";
+ SpacingMode[SpacingMode["Fixed"] = 1] = "Fixed";
+ SpacingMode[SpacingMode["Percent"] = 2] = "Percent";
+ })(SpacingMode = spine.SpacingMode || (spine.SpacingMode = {}));
+ var RotateMode;
+ (function (RotateMode) {
+ RotateMode[RotateMode["Tangent"] = 0] = "Tangent";
+ RotateMode[RotateMode["Chain"] = 1] = "Chain";
+ RotateMode[RotateMode["ChainScale"] = 2] = "ChainScale";
+ })(RotateMode = spine.RotateMode || (spine.RotateMode = {}));
+})(spine || (spine = {}));
+(function () {
+ if (!Math.fround) {
+ Math.fround = (function (array) {
+ return function (x) {
+ return array[0] = x, array[0];
+ };
+ })(new Float32Array(1));
+ }
+})();
+var spine;
+(function (spine) {
+ var Assets = (function () {
+ function Assets(clientId) {
+ this.toLoad = new Array();
+ this.assets = {};
+ this.clientId = clientId;
+ }
+ Assets.prototype.loaded = function () {
+ var i = 0;
+ for (var v in this.assets)
+ i++;
+ return i;
+ };
+ return Assets;
+ }());
+ var SharedAssetManager = (function () {
+ function SharedAssetManager(pathPrefix) {
+ if (pathPrefix === void 0) { pathPrefix = ""; }
+ this.clientAssets = {};
+ this.queuedAssets = {};
+ this.rawAssets = {};
+ this.errors = {};
+ this.pathPrefix = pathPrefix;
+ }
+ SharedAssetManager.prototype.queueAsset = function (clientId, textureLoader, path) {
+ var clientAssets = this.clientAssets[clientId];
+ if (clientAssets === null || clientAssets === undefined) {
+ clientAssets = new Assets(clientId);
+ this.clientAssets[clientId] = clientAssets;
+ }
+ if (textureLoader !== null)
+ clientAssets.textureLoader = textureLoader;
+ clientAssets.toLoad.push(path);
+ if (this.queuedAssets[path] === path) {
+ return false;
+ }
+ else {
+ this.queuedAssets[path] = path;
+ return true;
+ }
+ };
+ SharedAssetManager.prototype.loadText = function (clientId, path) {
+ var _this = this;
+ path = this.pathPrefix + path;
+ if (!this.queueAsset(clientId, null, path))
+ return;
+ var request = new XMLHttpRequest();
+ request.onreadystatechange = function () {
+ if (request.readyState == XMLHttpRequest.DONE) {
+ if (request.status >= 200 && request.status < 300) {
+ _this.rawAssets[path] = request.responseText;
+ }
+ else {
+ _this.errors[path] = "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText;
+ }
+ }
+ };
+ request.open("GET", path, true);
+ request.send();
+ };
+ SharedAssetManager.prototype.loadJson = function (clientId, path) {
+ var _this = this;
+ path = this.pathPrefix + path;
+ if (!this.queueAsset(clientId, null, path))
+ return;
+ var request = new XMLHttpRequest();
+ request.onreadystatechange = function () {
+ if (request.readyState == XMLHttpRequest.DONE) {
+ if (request.status >= 200 && request.status < 300) {
+ _this.rawAssets[path] = JSON.parse(request.responseText);
+ }
+ else {
+ _this.errors[path] = "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText;
+ }
+ }
+ };
+ request.open("GET", path, true);
+ request.send();
+ };
+ SharedAssetManager.prototype.loadTexture = function (clientId, textureLoader, path) {
+ var _this = this;
+ path = this.pathPrefix + path;
+ if (!this.queueAsset(clientId, textureLoader, path))
+ return;
+ var img = new Image();
+ img.src = path;
+ img.crossOrigin = "anonymous";
+ img.onload = function (ev) {
+ _this.rawAssets[path] = img;
+ };
+ img.onerror = function (ev) {
+ _this.errors[path] = "Couldn't load image " + path;
+ };
+ };
+ SharedAssetManager.prototype.get = function (clientId, path) {
+ path = this.pathPrefix + path;
+ var clientAssets = this.clientAssets[clientId];
+ if (clientAssets === null || clientAssets === undefined)
+ return true;
+ return clientAssets.assets[path];
+ };
+ SharedAssetManager.prototype.updateClientAssets = function (clientAssets) {
+ for (var i = 0; i < clientAssets.toLoad.length; i++) {
+ var path = clientAssets.toLoad[i];
+ var asset = clientAssets.assets[path];
+ if (asset === null || asset === undefined) {
+ var rawAsset = this.rawAssets[path];
+ if (rawAsset === null || rawAsset === undefined)
+ continue;
+ if (rawAsset instanceof HTMLImageElement) {
+ clientAssets.assets[path] = clientAssets.textureLoader(rawAsset);
+ }
+ else {
+ clientAssets.assets[path] = rawAsset;
+ }
+ }
+ }
+ };
+ SharedAssetManager.prototype.isLoadingComplete = function (clientId) {
+ var clientAssets = this.clientAssets[clientId];
+ if (clientAssets === null || clientAssets === undefined)
+ return true;
+ this.updateClientAssets(clientAssets);
+ return clientAssets.toLoad.length == clientAssets.loaded();
+ };
+ SharedAssetManager.prototype.dispose = function () {
+ };
+ SharedAssetManager.prototype.hasErrors = function () {
+ return Object.keys(this.errors).length > 0;
+ };
+ SharedAssetManager.prototype.getErrors = function () {
+ return this.errors;
+ };
+ return SharedAssetManager;
+ }());
+ spine.SharedAssetManager = SharedAssetManager;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var Skeleton = (function () {
+ function Skeleton(data) {
+ this._updateCache = new Array();
+ this.updateCacheReset = new Array();
+ this.time = 0;
+ this.flipX = false;
+ this.flipY = false;
+ this.x = 0;
+ this.y = 0;
+ if (data == null)
+ throw new Error("data cannot be null.");
+ this.data = data;
+ this.bones = new Array();
+ for (var i = 0; i < data.bones.length; i++) {
+ var boneData = data.bones[i];
+ var bone = void 0;
+ if (boneData.parent == null)
+ bone = new spine.Bone(boneData, this, null);
+ else {
+ var parent_1 = this.bones[boneData.parent.index];
+ bone = new spine.Bone(boneData, this, parent_1);
+ parent_1.children.push(bone);
+ }
+ this.bones.push(bone);
+ }
+ this.slots = new Array();
+ this.drawOrder = new Array();
+ for (var i = 0; i < data.slots.length; i++) {
+ var slotData = data.slots[i];
+ var bone = this.bones[slotData.boneData.index];
+ var slot = new spine.Slot(slotData, bone);
+ this.slots.push(slot);
+ this.drawOrder.push(slot);
+ }
+ this.ikConstraints = new Array();
+ for (var i = 0; i < data.ikConstraints.length; i++) {
+ var ikConstraintData = data.ikConstraints[i];
+ this.ikConstraints.push(new spine.IkConstraint(ikConstraintData, this));
+ }
+ this.transformConstraints = new Array();
+ for (var i = 0; i < data.transformConstraints.length; i++) {
+ var transformConstraintData = data.transformConstraints[i];
+ this.transformConstraints.push(new spine.TransformConstraint(transformConstraintData, this));
+ }
+ this.pathConstraints = new Array();
+ for (var i = 0; i < data.pathConstraints.length; i++) {
+ var pathConstraintData = data.pathConstraints[i];
+ this.pathConstraints.push(new spine.PathConstraint(pathConstraintData, this));
+ }
+ this.color = new spine.Color(1, 1, 1, 1);
+ this.updateCache();
+ }
+ Skeleton.prototype.updateCache = function () {
+ var updateCache = this._updateCache;
+ updateCache.length = 0;
+ this.updateCacheReset.length = 0;
+ var bones = this.bones;
+ for (var i = 0, n = bones.length; i < n; i++)
+ bones[i].sorted = false;
+ var ikConstraints = this.ikConstraints;
+ var transformConstraints = this.transformConstraints;
+ var pathConstraints = this.pathConstraints;
+ var ikCount = ikConstraints.length, transformCount = transformConstraints.length, pathCount = pathConstraints.length;
+ var constraintCount = ikCount + transformCount + pathCount;
+ outer: for (var i = 0; i < constraintCount; i++) {
+ for (var ii = 0; ii < ikCount; ii++) {
+ var constraint = ikConstraints[ii];
+ if (constraint.data.order == i) {
+ this.sortIkConstraint(constraint);
+ continue outer;
+ }
+ }
+ for (var ii = 0; ii < transformCount; ii++) {
+ var constraint = transformConstraints[ii];
+ if (constraint.data.order == i) {
+ this.sortTransformConstraint(constraint);
+ continue outer;
+ }
+ }
+ for (var ii = 0; ii < pathCount; ii++) {
+ var constraint = pathConstraints[ii];
+ if (constraint.data.order == i) {
+ this.sortPathConstraint(constraint);
+ continue outer;
+ }
+ }
+ }
+ for (var i = 0, n = bones.length; i < n; i++)
+ this.sortBone(bones[i]);
+ };
+ Skeleton.prototype.sortIkConstraint = function (constraint) {
+ var target = constraint.target;
+ this.sortBone(target);
+ var constrained = constraint.bones;
+ var parent = constrained[0];
+ this.sortBone(parent);
+ if (constrained.length > 1) {
+ var child = constrained[constrained.length - 1];
+ if (!(this._updateCache.indexOf(child) > -1))
+ this.updateCacheReset.push(child);
+ }
+ this._updateCache.push(constraint);
+ this.sortReset(parent.children);
+ constrained[constrained.length - 1].sorted = true;
+ };
+ Skeleton.prototype.sortPathConstraint = function (constraint) {
+ var slot = constraint.target;
+ var slotIndex = slot.data.index;
+ var slotBone = slot.bone;
+ if (this.skin != null)
+ this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone);
+ if (this.data.defaultSkin != null && this.data.defaultSkin != this.skin)
+ this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone);
+ for (var i = 0, n = this.data.skins.length; i < n; i++)
+ this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone);
+ var attachment = slot.getAttachment();
+ if (attachment instanceof spine.PathAttachment)
+ this.sortPathConstraintAttachmentWith(attachment, slotBone);
+ var constrained = constraint.bones;
+ var boneCount = constrained.length;
+ for (var i = 0; i < boneCount; i++)
+ this.sortBone(constrained[i]);
+ this._updateCache.push(constraint);
+ for (var i = 0; i < boneCount; i++)
+ this.sortReset(constrained[i].children);
+ for (var i = 0; i < boneCount; i++)
+ constrained[i].sorted = true;
+ };
+ Skeleton.prototype.sortTransformConstraint = function (constraint) {
+ this.sortBone(constraint.target);
+ var constrained = constraint.bones;
+ var boneCount = constrained.length;
+ if (constraint.data.local) {
+ for (var i = 0; i < boneCount; i++) {
+ var child = constrained[i];
+ this.sortBone(child.parent);
+ if (!(this._updateCache.indexOf(child) > -1))
+ this.updateCacheReset.push(child);
+ }
+ }
+ else {
+ for (var i = 0; i < boneCount; i++) {
+ this.sortBone(constrained[i]);
+ }
+ }
+ this._updateCache.push(constraint);
+ for (var ii = 0; ii < boneCount; ii++)
+ this.sortReset(constrained[ii].children);
+ for (var ii = 0; ii < boneCount; ii++)
+ constrained[ii].sorted = true;
+ };
+ Skeleton.prototype.sortPathConstraintAttachment = function (skin, slotIndex, slotBone) {
+ var attachments = skin.attachments[slotIndex];
+ if (!attachments)
+ return;
+ for (var key in attachments) {
+ this.sortPathConstraintAttachmentWith(attachments[key], slotBone);
+ }
+ };
+ Skeleton.prototype.sortPathConstraintAttachmentWith = function (attachment, slotBone) {
+ if (!(attachment instanceof spine.PathAttachment))
+ return;
+ var pathBones = attachment.bones;
+ if (pathBones == null)
+ this.sortBone(slotBone);
+ else {
+ var bones = this.bones;
+ var i = 0;
+ while (i < pathBones.length) {
+ var boneCount = pathBones[i++];
+ for (var n = i + boneCount; i < n; i++) {
+ var boneIndex = pathBones[i];
+ this.sortBone(bones[boneIndex]);
+ }
+ }
+ }
+ };
+ Skeleton.prototype.sortBone = function (bone) {
+ if (bone.sorted)
+ return;
+ var parent = bone.parent;
+ if (parent != null)
+ this.sortBone(parent);
+ bone.sorted = true;
+ this._updateCache.push(bone);
+ };
+ Skeleton.prototype.sortReset = function (bones) {
+ for (var i = 0, n = bones.length; i < n; i++) {
+ var bone = bones[i];
+ if (bone.sorted)
+ this.sortReset(bone.children);
+ bone.sorted = false;
+ }
+ };
+ Skeleton.prototype.updateWorldTransform = function () {
+ var updateCacheReset = this.updateCacheReset;
+ for (var i = 0, n = updateCacheReset.length; i < n; i++) {
+ var bone = updateCacheReset[i];
+ bone.ax = bone.x;
+ bone.ay = bone.y;
+ bone.arotation = bone.rotation;
+ bone.ascaleX = bone.scaleX;
+ bone.ascaleY = bone.scaleY;
+ bone.ashearX = bone.shearX;
+ bone.ashearY = bone.shearY;
+ bone.appliedValid = true;
+ }
+ var updateCache = this._updateCache;
+ for (var i = 0, n = updateCache.length; i < n; i++)
+ updateCache[i].update();
+ };
+ Skeleton.prototype.setToSetupPose = function () {
+ this.setBonesToSetupPose();
+ this.setSlotsToSetupPose();
+ };
+ Skeleton.prototype.setBonesToSetupPose = function () {
+ var bones = this.bones;
+ for (var i = 0, n = bones.length; i < n; i++)
+ bones[i].setToSetupPose();
+ var ikConstraints = this.ikConstraints;
+ for (var i = 0, n = ikConstraints.length; i < n; i++) {
+ var constraint = ikConstraints[i];
+ constraint.bendDirection = constraint.data.bendDirection;
+ constraint.mix = constraint.data.mix;
+ }
+ var transformConstraints = this.transformConstraints;
+ for (var i = 0, n = transformConstraints.length; i < n; i++) {
+ var constraint = transformConstraints[i];
+ var data = constraint.data;
+ constraint.rotateMix = data.rotateMix;
+ constraint.translateMix = data.translateMix;
+ constraint.scaleMix = data.scaleMix;
+ constraint.shearMix = data.shearMix;
+ }
+ var pathConstraints = this.pathConstraints;
+ for (var i = 0, n = pathConstraints.length; i < n; i++) {
+ var constraint = pathConstraints[i];
+ var data = constraint.data;
+ constraint.position = data.position;
+ constraint.spacing = data.spacing;
+ constraint.rotateMix = data.rotateMix;
+ constraint.translateMix = data.translateMix;
+ }
+ };
+ Skeleton.prototype.setSlotsToSetupPose = function () {
+ var slots = this.slots;
+ spine.Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length);
+ for (var i = 0, n = slots.length; i < n; i++)
+ slots[i].setToSetupPose();
+ };
+ Skeleton.prototype.getRootBone = function () {
+ if (this.bones.length == 0)
+ return null;
+ return this.bones[0];
+ };
+ Skeleton.prototype.findBone = function (boneName) {
+ if (boneName == null)
+ throw new Error("boneName cannot be null.");
+ var bones = this.bones;
+ for (var i = 0, n = bones.length; i < n; i++) {
+ var bone = bones[i];
+ if (bone.data.name == boneName)
+ return bone;
+ }
+ return null;
+ };
+ Skeleton.prototype.findBoneIndex = function (boneName) {
+ if (boneName == null)
+ throw new Error("boneName cannot be null.");
+ var bones = this.bones;
+ for (var i = 0, n = bones.length; i < n; i++)
+ if (bones[i].data.name == boneName)
+ return i;
+ return -1;
+ };
+ Skeleton.prototype.findSlot = function (slotName) {
+ if (slotName == null)
+ throw new Error("slotName cannot be null.");
+ var slots = this.slots;
+ for (var i = 0, n = slots.length; i < n; i++) {
+ var slot = slots[i];
+ if (slot.data.name == slotName)
+ return slot;
+ }
+ return null;
+ };
+ Skeleton.prototype.findSlotIndex = function (slotName) {
+ if (slotName == null)
+ throw new Error("slotName cannot be null.");
+ var slots = this.slots;
+ for (var i = 0, n = slots.length; i < n; i++)
+ if (slots[i].data.name == slotName)
+ return i;
+ return -1;
+ };
+ Skeleton.prototype.setSkinByName = function (skinName) {
+ var skin = this.data.findSkin(skinName);
+ if (skin == null)
+ throw new Error("Skin not found: " + skinName);
+ this.setSkin(skin);
+ };
+ Skeleton.prototype.setSkin = function (newSkin) {
+ if (newSkin != null) {
+ if (this.skin != null)
+ newSkin.attachAll(this, this.skin);
+ else {
+ var slots = this.slots;
+ for (var i = 0, n = slots.length; i < n; i++) {
+ var slot = slots[i];
+ var name_1 = slot.data.attachmentName;
+ if (name_1 != null) {
+ var attachment = newSkin.getAttachment(i, name_1);
+ if (attachment != null)
+ slot.setAttachment(attachment);
+ }
+ }
+ }
+ }
+ this.skin = newSkin;
+ };
+ Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) {
+ return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName);
+ };
+ Skeleton.prototype.getAttachment = function (slotIndex, attachmentName) {
+ if (attachmentName == null)
+ throw new Error("attachmentName cannot be null.");
+ if (this.skin != null) {
+ var attachment = this.skin.getAttachment(slotIndex, attachmentName);
+ if (attachment != null)
+ return attachment;
+ }
+ if (this.data.defaultSkin != null)
+ return this.data.defaultSkin.getAttachment(slotIndex, attachmentName);
+ return null;
+ };
+ Skeleton.prototype.setAttachment = function (slotName, attachmentName) {
+ if (slotName == null)
+ throw new Error("slotName cannot be null.");
+ var slots = this.slots;
+ for (var i = 0, n = slots.length; i < n; i++) {
+ var slot = slots[i];
+ if (slot.data.name == slotName) {
+ var attachment = null;
+ if (attachmentName != null) {
+ attachment = this.getAttachment(i, attachmentName);
+ if (attachment == null)
+ throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName);
+ }
+ slot.setAttachment(attachment);
+ return;
+ }
+ }
+ throw new Error("Slot not found: " + slotName);
+ };
+ Skeleton.prototype.findIkConstraint = function (constraintName) {
+ if (constraintName == null)
+ throw new Error("constraintName cannot be null.");
+ var ikConstraints = this.ikConstraints;
+ for (var i = 0, n = ikConstraints.length; i < n; i++) {
+ var ikConstraint = ikConstraints[i];
+ if (ikConstraint.data.name == constraintName)
+ return ikConstraint;
+ }
+ return null;
+ };
+ Skeleton.prototype.findTransformConstraint = function (constraintName) {
+ if (constraintName == null)
+ throw new Error("constraintName cannot be null.");
+ var transformConstraints = this.transformConstraints;
+ for (var i = 0, n = transformConstraints.length; i < n; i++) {
+ var constraint = transformConstraints[i];
+ if (constraint.data.name == constraintName)
+ return constraint;
+ }
+ return null;
+ };
+ Skeleton.prototype.findPathConstraint = function (constraintName) {
+ if (constraintName == null)
+ throw new Error("constraintName cannot be null.");
+ var pathConstraints = this.pathConstraints;
+ for (var i = 0, n = pathConstraints.length; i < n; i++) {
+ var constraint = pathConstraints[i];
+ if (constraint.data.name == constraintName)
+ return constraint;
+ }
+ return null;
+ };
+ Skeleton.prototype.getBounds = function (offset, size, temp) {
+ if (offset == null)
+ throw new Error("offset cannot be null.");
+ if (size == null)
+ throw new Error("size cannot be null.");
+ var drawOrder = this.drawOrder;
+ var minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY;
+ for (var i = 0, n = drawOrder.length; i < n; i++) {
+ var slot = drawOrder[i];
+ var verticesLength = 0;
+ var vertices = null;
+ var attachment = slot.getAttachment();
+ if (attachment instanceof spine.RegionAttachment) {
+ verticesLength = 8;
+ vertices = spine.Utils.setArraySize(temp, verticesLength, 0);
+ attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
+ }
+ else if (attachment instanceof spine.MeshAttachment) {
+ var mesh = attachment;
+ verticesLength = mesh.worldVerticesLength;
+ vertices = spine.Utils.setArraySize(temp, verticesLength, 0);
+ mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2);
+ }
+ if (vertices != null) {
+ for (var ii = 0, nn = vertices.length; ii < nn; ii += 2) {
+ var x = vertices[ii], y = vertices[ii + 1];
+ minX = Math.min(minX, x);
+ minY = Math.min(minY, y);
+ maxX = Math.max(maxX, x);
+ maxY = Math.max(maxY, y);
+ }
+ }
+ }
+ offset.set(minX, minY);
+ size.set(maxX - minX, maxY - minY);
+ };
+ Skeleton.prototype.update = function (delta) {
+ this.time += delta;
+ };
+ return Skeleton;
+ }());
+ spine.Skeleton = Skeleton;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var SkeletonBounds = (function () {
+ function SkeletonBounds() {
+ this.minX = 0;
+ this.minY = 0;
+ this.maxX = 0;
+ this.maxY = 0;
+ this.boundingBoxes = new Array();
+ this.polygons = new Array();
+ this.polygonPool = new spine.Pool(function () {
+ return spine.Utils.newFloatArray(16);
+ });
+ }
+ SkeletonBounds.prototype.update = function (skeleton, updateAabb) {
+ if (skeleton == null)
+ throw new Error("skeleton cannot be null.");
+ var boundingBoxes = this.boundingBoxes;
+ var polygons = this.polygons;
+ var polygonPool = this.polygonPool;
+ var slots = skeleton.slots;
+ var slotCount = slots.length;
+ boundingBoxes.length = 0;
+ polygonPool.freeAll(polygons);
+ polygons.length = 0;
+ for (var i = 0; i < slotCount; i++) {
+ var slot = slots[i];
+ var attachment = slot.getAttachment();
+ if (attachment instanceof spine.BoundingBoxAttachment) {
+ var boundingBox = attachment;
+ boundingBoxes.push(boundingBox);
+ var polygon = polygonPool.obtain();
+ if (polygon.length != boundingBox.worldVerticesLength) {
+ polygon = spine.Utils.newFloatArray(boundingBox.worldVerticesLength);
+ }
+ polygons.push(polygon);
+ boundingBox.computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon, 0, 2);
+ }
+ }
+ if (updateAabb) {
+ this.aabbCompute();
+ }
+ else {
+ this.minX = Number.POSITIVE_INFINITY;
+ this.minY = Number.POSITIVE_INFINITY;
+ this.maxX = Number.NEGATIVE_INFINITY;
+ this.maxY = Number.NEGATIVE_INFINITY;
+ }
+ };
+ SkeletonBounds.prototype.aabbCompute = function () {
+ var minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY;
+ var polygons = this.polygons;
+ for (var i = 0, n = polygons.length; i < n; i++) {
+ var polygon = polygons[i];
+ var vertices = polygon;
+ for (var ii = 0, nn = polygon.length; ii < nn; ii += 2) {
+ var x = vertices[ii];
+ var y = vertices[ii + 1];
+ minX = Math.min(minX, x);
+ minY = Math.min(minY, y);
+ maxX = Math.max(maxX, x);
+ maxY = Math.max(maxY, y);
+ }
+ }
+ this.minX = minX;
+ this.minY = minY;
+ this.maxX = maxX;
+ this.maxY = maxY;
+ };
+ SkeletonBounds.prototype.aabbContainsPoint = function (x, y) {
+ return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY;
+ };
+ SkeletonBounds.prototype.aabbIntersectsSegment = function (x1, y1, x2, y2) {
+ var minX = this.minX;
+ var minY = this.minY;
+ var maxX = this.maxX;
+ var maxY = this.maxY;
+ if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY))
+ return false;
+ var m = (y2 - y1) / (x2 - x1);
+ var y = m * (minX - x1) + y1;
+ if (y > minY && y < maxY)
+ return true;
+ y = m * (maxX - x1) + y1;
+ if (y > minY && y < maxY)
+ return true;
+ var x = (minY - y1) / m + x1;
+ if (x > minX && x < maxX)
+ return true;
+ x = (maxY - y1) / m + x1;
+ if (x > minX && x < maxX)
+ return true;
+ return false;
+ };
+ SkeletonBounds.prototype.aabbIntersectsSkeleton = function (bounds) {
+ return this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY;
+ };
+ SkeletonBounds.prototype.containsPoint = function (x, y) {
+ var polygons = this.polygons;
+ for (var i = 0, n = polygons.length; i < n; i++)
+ if (this.containsPointPolygon(polygons[i], x, y))
+ return this.boundingBoxes[i];
+ return null;
+ };
+ SkeletonBounds.prototype.containsPointPolygon = function (polygon, x, y) {
+ var vertices = polygon;
+ var nn = polygon.length;
+ var prevIndex = nn - 2;
+ var inside = false;
+ for (var ii = 0; ii < nn; ii += 2) {
+ var vertexY = vertices[ii + 1];
+ var prevY = vertices[prevIndex + 1];
+ if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) {
+ var vertexX = vertices[ii];
+ if (vertexX + (y - vertexY) / (prevY - vertexY) * (vertices[prevIndex] - vertexX) < x)
+ inside = !inside;
+ }
+ prevIndex = ii;
+ }
+ return inside;
+ };
+ SkeletonBounds.prototype.intersectsSegment = function (x1, y1, x2, y2) {
+ var polygons = this.polygons;
+ for (var i = 0, n = polygons.length; i < n; i++)
+ if (this.intersectsSegmentPolygon(polygons[i], x1, y1, x2, y2))
+ return this.boundingBoxes[i];
+ return null;
+ };
+ SkeletonBounds.prototype.intersectsSegmentPolygon = function (polygon, x1, y1, x2, y2) {
+ var vertices = polygon;
+ var nn = polygon.length;
+ var width12 = x1 - x2, height12 = y1 - y2;
+ var det1 = x1 * y2 - y1 * x2;
+ var x3 = vertices[nn - 2], y3 = vertices[nn - 1];
+ for (var ii = 0; ii < nn; ii += 2) {
+ var x4 = vertices[ii], y4 = vertices[ii + 1];
+ var det2 = x3 * y4 - y3 * x4;
+ var width34 = x3 - x4, height34 = y3 - y4;
+ var det3 = width12 * height34 - height12 * width34;
+ var x = (det1 * width34 - width12 * det2) / det3;
+ if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) {
+ var y = (det1 * height34 - height12 * det2) / det3;
+ if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1)))
+ return true;
+ }
+ x3 = x4;
+ y3 = y4;
+ }
+ return false;
+ };
+ SkeletonBounds.prototype.getPolygon = function (boundingBox) {
+ if (boundingBox == null)
+ throw new Error("boundingBox cannot be null.");
+ var index = this.boundingBoxes.indexOf(boundingBox);
+ return index == -1 ? null : this.polygons[index];
+ };
+ SkeletonBounds.prototype.getWidth = function () {
+ return this.maxX - this.minX;
+ };
+ SkeletonBounds.prototype.getHeight = function () {
+ return this.maxY - this.minY;
+ };
+ return SkeletonBounds;
+ }());
+ spine.SkeletonBounds = SkeletonBounds;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var SkeletonClipping = (function () {
+ function SkeletonClipping() {
+ this.triangulator = new spine.Triangulator();
+ this.clippingPolygon = new Array();
+ this.clipOutput = new Array();
+ this.clippedVertices = new Array();
+ this.clippedTriangles = new Array();
+ this.scratch = new Array();
+ }
+ SkeletonClipping.prototype.clipStart = function (slot, clip) {
+ if (this.clipAttachment != null)
+ return 0;
+ this.clipAttachment = clip;
+ var n = clip.worldVerticesLength;
+ var vertices = spine.Utils.setArraySize(this.clippingPolygon, n);
+ clip.computeWorldVertices(slot, 0, n, vertices, 0, 2);
+ var clippingPolygon = this.clippingPolygon;
+ SkeletonClipping.makeClockwise(clippingPolygon);
+ var clippingPolygons = this.clippingPolygons = this.triangulator.decompose(clippingPolygon, this.triangulator.triangulate(clippingPolygon));
+ for (var i = 0, n_1 = clippingPolygons.length; i < n_1; i++) {
+ var polygon = clippingPolygons[i];
+ SkeletonClipping.makeClockwise(polygon);
+ polygon.push(polygon[0]);
+ polygon.push(polygon[1]);
+ }
+ return clippingPolygons.length;
+ };
+ SkeletonClipping.prototype.clipEndWithSlot = function (slot) {
+ if (this.clipAttachment != null && this.clipAttachment.endSlot == slot.data)
+ this.clipEnd();
+ };
+ SkeletonClipping.prototype.clipEnd = function () {
+ if (this.clipAttachment == null)
+ return;
+ this.clipAttachment = null;
+ this.clippingPolygons = null;
+ this.clippedVertices.length = 0;
+ this.clippedTriangles.length = 0;
+ this.clippingPolygon.length = 0;
+ };
+ SkeletonClipping.prototype.isClipping = function () {
+ return this.clipAttachment != null;
+ };
+ SkeletonClipping.prototype.clipTriangles = function (vertices, verticesLength, triangles, trianglesLength, uvs, light, dark, twoColor) {
+ var clipOutput = this.clipOutput, clippedVertices = this.clippedVertices;
+ var clippedTriangles = this.clippedTriangles;
+ var polygons = this.clippingPolygons;
+ var polygonsCount = this.clippingPolygons.length;
+ var vertexSize = twoColor ? 12 : 8;
+ var index = 0;
+ clippedVertices.length = 0;
+ clippedTriangles.length = 0;
+ outer: for (var i = 0; i < trianglesLength; i += 3) {
+ var vertexOffset = triangles[i] << 1;
+ var x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1];
+ var u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1];
+ vertexOffset = triangles[i + 1] << 1;
+ var x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1];
+ var u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1];
+ vertexOffset = triangles[i + 2] << 1;
+ var x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1];
+ var u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1];
+ for (var p = 0; p < polygonsCount; p++) {
+ var s = clippedVertices.length;
+ if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) {
+ var clipOutputLength = clipOutput.length;
+ if (clipOutputLength == 0)
+ continue;
+ var d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1;
+ var d = 1 / (d0 * d2 + d1 * (y1 - y3));
+ var clipOutputCount = clipOutputLength >> 1;
+ var clipOutputItems = this.clipOutput;
+ var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize);
+ for (var ii = 0; ii < clipOutputLength; ii += 2) {
+ var x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
+ clippedVerticesItems[s] = x;
+ clippedVerticesItems[s + 1] = y;
+ clippedVerticesItems[s + 2] = light.r;
+ clippedVerticesItems[s + 3] = light.g;
+ clippedVerticesItems[s + 4] = light.b;
+ clippedVerticesItems[s + 5] = light.a;
+ var c0 = x - x3, c1 = y - y3;
+ var a = (d0 * c0 + d1 * c1) * d;
+ var b = (d4 * c0 + d2 * c1) * d;
+ var c = 1 - a - b;
+ clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c;
+ clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c;
+ if (twoColor) {
+ clippedVerticesItems[s + 8] = dark.r;
+ clippedVerticesItems[s + 9] = dark.g;
+ clippedVerticesItems[s + 10] = dark.b;
+ clippedVerticesItems[s + 11] = dark.a;
+ }
+ s += vertexSize;
+ }
+ s = clippedTriangles.length;
+ var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2));
+ clipOutputCount--;
+ for (var ii = 1; ii < clipOutputCount; ii++) {
+ clippedTrianglesItems[s] = index;
+ clippedTrianglesItems[s + 1] = (index + ii);
+ clippedTrianglesItems[s + 2] = (index + ii + 1);
+ s += 3;
+ }
+ index += clipOutputCount + 1;
+ }
+ else {
+ var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + 3 * vertexSize);
+ clippedVerticesItems[s] = x1;
+ clippedVerticesItems[s + 1] = y1;
+ clippedVerticesItems[s + 2] = light.r;
+ clippedVerticesItems[s + 3] = light.g;
+ clippedVerticesItems[s + 4] = light.b;
+ clippedVerticesItems[s + 5] = light.a;
+ if (!twoColor) {
+ clippedVerticesItems[s + 6] = u1;
+ clippedVerticesItems[s + 7] = v1;
+ clippedVerticesItems[s + 8] = x2;
+ clippedVerticesItems[s + 9] = y2;
+ clippedVerticesItems[s + 10] = light.r;
+ clippedVerticesItems[s + 11] = light.g;
+ clippedVerticesItems[s + 12] = light.b;
+ clippedVerticesItems[s + 13] = light.a;
+ clippedVerticesItems[s + 14] = u2;
+ clippedVerticesItems[s + 15] = v2;
+ clippedVerticesItems[s + 16] = x3;
+ clippedVerticesItems[s + 17] = y3;
+ clippedVerticesItems[s + 18] = light.r;
+ clippedVerticesItems[s + 19] = light.g;
+ clippedVerticesItems[s + 20] = light.b;
+ clippedVerticesItems[s + 21] = light.a;
+ clippedVerticesItems[s + 22] = u3;
+ clippedVerticesItems[s + 23] = v3;
+ }
+ else {
+ clippedVerticesItems[s + 6] = u1;
+ clippedVerticesItems[s + 7] = v1;
+ clippedVerticesItems[s + 8] = dark.r;
+ clippedVerticesItems[s + 9] = dark.g;
+ clippedVerticesItems[s + 10] = dark.b;
+ clippedVerticesItems[s + 11] = dark.a;
+ clippedVerticesItems[s + 12] = x2;
+ clippedVerticesItems[s + 13] = y2;
+ clippedVerticesItems[s + 14] = light.r;
+ clippedVerticesItems[s + 15] = light.g;
+ clippedVerticesItems[s + 16] = light.b;
+ clippedVerticesItems[s + 17] = light.a;
+ clippedVerticesItems[s + 18] = u2;
+ clippedVerticesItems[s + 19] = v2;
+ clippedVerticesItems[s + 20] = dark.r;
+ clippedVerticesItems[s + 21] = dark.g;
+ clippedVerticesItems[s + 22] = dark.b;
+ clippedVerticesItems[s + 23] = dark.a;
+ clippedVerticesItems[s + 24] = x3;
+ clippedVerticesItems[s + 25] = y3;
+ clippedVerticesItems[s + 26] = light.r;
+ clippedVerticesItems[s + 27] = light.g;
+ clippedVerticesItems[s + 28] = light.b;
+ clippedVerticesItems[s + 29] = light.a;
+ clippedVerticesItems[s + 30] = u3;
+ clippedVerticesItems[s + 31] = v3;
+ clippedVerticesItems[s + 32] = dark.r;
+ clippedVerticesItems[s + 33] = dark.g;
+ clippedVerticesItems[s + 34] = dark.b;
+ clippedVerticesItems[s + 35] = dark.a;
+ }
+ s = clippedTriangles.length;
+ var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3);
+ clippedTrianglesItems[s] = index;
+ clippedTrianglesItems[s + 1] = (index + 1);
+ clippedTrianglesItems[s + 2] = (index + 2);
+ index += 3;
+ continue outer;
+ }
+ }
+ }
+ };
+ SkeletonClipping.prototype.clip = function (x1, y1, x2, y2, x3, y3, clippingArea, output) {
+ var originalOutput = output;
+ var clipped = false;
+ var input = null;
+ if (clippingArea.length % 4 >= 2) {
+ input = output;
+ output = this.scratch;
+ }
+ else
+ input = this.scratch;
+ input.length = 0;
+ input.push(x1);
+ input.push(y1);
+ input.push(x2);
+ input.push(y2);
+ input.push(x3);
+ input.push(y3);
+ input.push(x1);
+ input.push(y1);
+ output.length = 0;
+ var clippingVertices = clippingArea;
+ var clippingVerticesLast = clippingArea.length - 4;
+ for (var i = 0;; i += 2) {
+ var edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1];
+ var edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3];
+ var deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2;
+ var inputVertices = input;
+ var inputVerticesLength = input.length - 2, outputStart = output.length;
+ for (var ii = 0; ii < inputVerticesLength; ii += 2) {
+ var inputX = inputVertices[ii], inputY = inputVertices[ii + 1];
+ var inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3];
+ var side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0;
+ if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) {
+ if (side2) {
+ output.push(inputX2);
+ output.push(inputY2);
+ continue;
+ }
+ var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
+ var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
+ output.push(edgeX + (edgeX2 - edgeX) * ua);
+ output.push(edgeY + (edgeY2 - edgeY) * ua);
+ }
+ else if (side2) {
+ var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
+ var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
+ output.push(edgeX + (edgeX2 - edgeX) * ua);
+ output.push(edgeY + (edgeY2 - edgeY) * ua);
+ output.push(inputX2);
+ output.push(inputY2);
+ }
+ clipped = true;
+ }
+ if (outputStart == output.length) {
+ originalOutput.length = 0;
+ return true;
+ }
+ output.push(output[0]);
+ output.push(output[1]);
+ if (i == clippingVerticesLast)
+ break;
+ var temp = output;
+ output = input;
+ output.length = 0;
+ input = temp;
+ }
+ if (originalOutput != output) {
+ originalOutput.length = 0;
+ for (var i = 0, n = output.length - 2; i < n; i++)
+ originalOutput[i] = output[i];
+ }
+ else
+ originalOutput.length = originalOutput.length - 2;
+ return clipped;
+ };
+ SkeletonClipping.makeClockwise = function (polygon) {
+ var vertices = polygon;
+ var verticeslength = polygon.length;
+ var area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x = 0, p1y = 0, p2x = 0, p2y = 0;
+ for (var i = 0, n = verticeslength - 3; i < n; i += 2) {
+ p1x = vertices[i];
+ p1y = vertices[i + 1];
+ p2x = vertices[i + 2];
+ p2y = vertices[i + 3];
+ area += p1x * p2y - p2x * p1y;
+ }
+ if (area < 0)
+ return;
+ for (var i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) {
+ var x = vertices[i], y = vertices[i + 1];
+ var other = lastX - i;
+ vertices[i] = vertices[other];
+ vertices[i + 1] = vertices[other + 1];
+ vertices[other] = x;
+ vertices[other + 1] = y;
+ }
+ };
+ return SkeletonClipping;
+ }());
+ spine.SkeletonClipping = SkeletonClipping;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var SkeletonData = (function () {
+ function SkeletonData() {
+ this.bones = new Array();
+ this.slots = new Array();
+ this.skins = new Array();
+ this.events = new Array();
+ this.animations = new Array();
+ this.ikConstraints = new Array();
+ this.transformConstraints = new Array();
+ this.pathConstraints = new Array();
+ this.fps = 0;
+ }
+ SkeletonData.prototype.findBone = function (boneName) {
+ if (boneName == null)
+ throw new Error("boneName cannot be null.");
+ var bones = this.bones;
+ for (var i = 0, n = bones.length; i < n; i++) {
+ var bone = bones[i];
+ if (bone.name == boneName)
+ return bone;
+ }
+ return null;
+ };
+ SkeletonData.prototype.findBoneIndex = function (boneName) {
+ if (boneName == null)
+ throw new Error("boneName cannot be null.");
+ var bones = this.bones;
+ for (var i = 0, n = bones.length; i < n; i++)
+ if (bones[i].name == boneName)
+ return i;
+ return -1;
+ };
+ SkeletonData.prototype.findSlot = function (slotName) {
+ if (slotName == null)
+ throw new Error("slotName cannot be null.");
+ var slots = this.slots;
+ for (var i = 0, n = slots.length; i < n; i++) {
+ var slot = slots[i];
+ if (slot.name == slotName)
+ return slot;
+ }
+ return null;
+ };
+ SkeletonData.prototype.findSlotIndex = function (slotName) {
+ if (slotName == null)
+ throw new Error("slotName cannot be null.");
+ var slots = this.slots;
+ for (var i = 0, n = slots.length; i < n; i++)
+ if (slots[i].name == slotName)
+ return i;
+ return -1;
+ };
+ SkeletonData.prototype.findSkin = function (skinName) {
+ if (skinName == null)
+ throw new Error("skinName cannot be null.");
+ var skins = this.skins;
+ for (var i = 0, n = skins.length; i < n; i++) {
+ var skin = skins[i];
+ if (skin.name == skinName)
+ return skin;
+ }
+ return null;
+ };
+ SkeletonData.prototype.findEvent = function (eventDataName) {
+ if (eventDataName == null)
+ throw new Error("eventDataName cannot be null.");
+ var events = this.events;
+ for (var i = 0, n = events.length; i < n; i++) {
+ var event_4 = events[i];
+ if (event_4.name == eventDataName)
+ return event_4;
+ }
+ return null;
+ };
+ SkeletonData.prototype.findAnimation = function (animationName) {
+ if (animationName == null)
+ throw new Error("animationName cannot be null.");
+ var animations = this.animations;
+ for (var i = 0, n = animations.length; i < n; i++) {
+ var animation = animations[i];
+ if (animation.name == animationName)
+ return animation;
+ }
+ return null;
+ };
+ SkeletonData.prototype.findIkConstraint = function (constraintName) {
+ if (constraintName == null)
+ throw new Error("constraintName cannot be null.");
+ var ikConstraints = this.ikConstraints;
+ for (var i = 0, n = ikConstraints.length; i < n; i++) {
+ var constraint = ikConstraints[i];
+ if (constraint.name == constraintName)
+ return constraint;
+ }
+ return null;
+ };
+ SkeletonData.prototype.findTransformConstraint = function (constraintName) {
+ if (constraintName == null)
+ throw new Error("constraintName cannot be null.");
+ var transformConstraints = this.transformConstraints;
+ for (var i = 0, n = transformConstraints.length; i < n; i++) {
+ var constraint = transformConstraints[i];
+ if (constraint.name == constraintName)
+ return constraint;
+ }
+ return null;
+ };
+ SkeletonData.prototype.findPathConstraint = function (constraintName) {
+ if (constraintName == null)
+ throw new Error("constraintName cannot be null.");
+ var pathConstraints = this.pathConstraints;
+ for (var i = 0, n = pathConstraints.length; i < n; i++) {
+ var constraint = pathConstraints[i];
+ if (constraint.name == constraintName)
+ return constraint;
+ }
+ return null;
+ };
+ SkeletonData.prototype.findPathConstraintIndex = function (pathConstraintName) {
+ if (pathConstraintName == null)
+ throw new Error("pathConstraintName cannot be null.");
+ var pathConstraints = this.pathConstraints;
+ for (var i = 0, n = pathConstraints.length; i < n; i++)
+ if (pathConstraints[i].name == pathConstraintName)
+ return i;
+ return -1;
+ };
+ return SkeletonData;
+ }());
+ spine.SkeletonData = SkeletonData;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var SkeletonJson = (function () {
+ function SkeletonJson(attachmentLoader) {
+ this.scale = 1;
+ this.linkedMeshes = new Array();
+ this.attachmentLoader = attachmentLoader;
+ }
+ SkeletonJson.prototype.readSkeletonData = function (json) {
+ var scale = this.scale;
+ var skeletonData = new spine.SkeletonData();
+ var root = typeof (json) === "string" ? JSON.parse(json) : json;
+ var skeletonMap = root.skeleton;
+ if (skeletonMap != null) {
+ skeletonData.hash = skeletonMap.hash;
+ skeletonData.version = skeletonMap.spine;
+ skeletonData.width = skeletonMap.width;
+ skeletonData.height = skeletonMap.height;
+ skeletonData.fps = skeletonMap.fps;
+ skeletonData.imagesPath = skeletonMap.images;
+ }
+ if (root.bones) {
+ for (var i = 0; i < root.bones.length; i++) {
+ var boneMap = root.bones[i];
+ var parent_2 = null;
+ var parentName = this.getValue(boneMap, "parent", null);
+ if (parentName != null) {
+ parent_2 = skeletonData.findBone(parentName);
+ if (parent_2 == null)
+ throw new Error("Parent bone not found: " + parentName);
+ }
+ var data = new spine.BoneData(skeletonData.bones.length, boneMap.name, parent_2);
+ data.length = this.getValue(boneMap, "length", 0) * scale;
+ data.x = this.getValue(boneMap, "x", 0) * scale;
+ data.y = this.getValue(boneMap, "y", 0) * scale;
+ data.rotation = this.getValue(boneMap, "rotation", 0);
+ data.scaleX = this.getValue(boneMap, "scaleX", 1);
+ data.scaleY = this.getValue(boneMap, "scaleY", 1);
+ data.shearX = this.getValue(boneMap, "shearX", 0);
+ data.shearY = this.getValue(boneMap, "shearY", 0);
+ data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal"));
+ skeletonData.bones.push(data);
+ }
+ }
+ if (root.slots) {
+ for (var i = 0; i < root.slots.length; i++) {
+ var slotMap = root.slots[i];
+ var slotName = slotMap.name;
+ var boneName = slotMap.bone;
+ var boneData = skeletonData.findBone(boneName);
+ if (boneData == null)
+ throw new Error("Slot bone not found: " + boneName);
+ var data = new spine.SlotData(skeletonData.slots.length, slotName, boneData);
+ var color = this.getValue(slotMap, "color", null);
+ if (color != null)
+ data.color.setFromString(color);
+ var dark = this.getValue(slotMap, "dark", null);
+ if (dark != null) {
+ data.darkColor = new spine.Color(1, 1, 1, 1);
+ data.darkColor.setFromString(dark);
+ }
+ data.attachmentName = this.getValue(slotMap, "attachment", null);
+ data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal"));
+ skeletonData.slots.push(data);
+ }
+ }
+ if (root.ik) {
+ for (var i = 0; i < root.ik.length; i++) {
+ var constraintMap = root.ik[i];
+ var data = new spine.IkConstraintData(constraintMap.name);
+ data.order = this.getValue(constraintMap, "order", 0);
+ for (var j = 0; j < constraintMap.bones.length; j++) {
+ var boneName = constraintMap.bones[j];
+ var bone = skeletonData.findBone(boneName);
+ if (bone == null)
+ throw new Error("IK bone not found: " + boneName);
+ data.bones.push(bone);
+ }
+ var targetName = constraintMap.target;
+ data.target = skeletonData.findBone(targetName);
+ if (data.target == null)
+ throw new Error("IK target bone not found: " + targetName);
+ data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1;
+ data.mix = this.getValue(constraintMap, "mix", 1);
+ skeletonData.ikConstraints.push(data);
+ }
+ }
+ if (root.transform) {
+ for (var i = 0; i < root.transform.length; i++) {
+ var constraintMap = root.transform[i];
+ var data = new spine.TransformConstraintData(constraintMap.name);
+ data.order = this.getValue(constraintMap, "order", 0);
+ for (var j = 0; j < constraintMap.bones.length; j++) {
+ var boneName = constraintMap.bones[j];
+ var bone = skeletonData.findBone(boneName);
+ if (bone == null)
+ throw new Error("Transform constraint bone not found: " + boneName);
+ data.bones.push(bone);
+ }
+ var targetName = constraintMap.target;
+ data.target = skeletonData.findBone(targetName);
+ if (data.target == null)
+ throw new Error("Transform constraint target bone not found: " + targetName);
+ data.local = this.getValue(constraintMap, "local", false);
+ data.relative = this.getValue(constraintMap, "relative", false);
+ data.offsetRotation = this.getValue(constraintMap, "rotation", 0);
+ data.offsetX = this.getValue(constraintMap, "x", 0) * scale;
+ data.offsetY = this.getValue(constraintMap, "y", 0) * scale;
+ data.offsetScaleX = this.getValue(constraintMap, "scaleX", 0);
+ data.offsetScaleY = this.getValue(constraintMap, "scaleY", 0);
+ data.offsetShearY = this.getValue(constraintMap, "shearY", 0);
+ data.rotateMix = this.getValue(constraintMap, "rotateMix", 1);
+ data.translateMix = this.getValue(constraintMap, "translateMix", 1);
+ data.scaleMix = this.getValue(constraintMap, "scaleMix", 1);
+ data.shearMix = this.getValue(constraintMap, "shearMix", 1);
+ skeletonData.transformConstraints.push(data);
+ }
+ }
+ if (root.path) {
+ for (var i = 0; i < root.path.length; i++) {
+ var constraintMap = root.path[i];
+ var data = new spine.PathConstraintData(constraintMap.name);
+ data.order = this.getValue(constraintMap, "order", 0);
+ for (var j = 0; j < constraintMap.bones.length; j++) {
+ var boneName = constraintMap.bones[j];
+ var bone = skeletonData.findBone(boneName);
+ if (bone == null)
+ throw new Error("Transform constraint bone not found: " + boneName);
+ data.bones.push(bone);
+ }
+ var targetName = constraintMap.target;
+ data.target = skeletonData.findSlot(targetName);
+ if (data.target == null)
+ throw new Error("Path target slot not found: " + targetName);
+ data.positionMode = SkeletonJson.positionModeFromString(this.getValue(constraintMap, "positionMode", "percent"));
+ data.spacingMode = SkeletonJson.spacingModeFromString(this.getValue(constraintMap, "spacingMode", "length"));
+ data.rotateMode = SkeletonJson.rotateModeFromString(this.getValue(constraintMap, "rotateMode", "tangent"));
+ data.offsetRotation = this.getValue(constraintMap, "rotation", 0);
+ data.position = this.getValue(constraintMap, "position", 0);
+ if (data.positionMode == spine.PositionMode.Fixed)
+ data.position *= scale;
+ data.spacing = this.getValue(constraintMap, "spacing", 0);
+ if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed)
+ data.spacing *= scale;
+ data.rotateMix = this.getValue(constraintMap, "rotateMix", 1);
+ data.translateMix = this.getValue(constraintMap, "translateMix", 1);
+ skeletonData.pathConstraints.push(data);
+ }
+ }
+ if (root.skins) {
+ for (var skinName in root.skins) {
+ var skinMap = root.skins[skinName];
+ var skin = new spine.Skin(skinName);
+ for (var slotName in skinMap) {
+ var slotIndex = skeletonData.findSlotIndex(slotName);
+ if (slotIndex == -1)
+ throw new Error("Slot not found: " + slotName);
+ var slotMap = skinMap[slotName];
+ for (var entryName in slotMap) {
+ var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData);
+ if (attachment != null)
+ skin.addAttachment(slotIndex, entryName, attachment);
+ }
+ }
+ skeletonData.skins.push(skin);
+ if (skin.name == "default")
+ skeletonData.defaultSkin = skin;
+ }
+ }
+ for (var i = 0, n = this.linkedMeshes.length; i < n; i++) {
+ var linkedMesh = this.linkedMeshes[i];
+ var skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin);
+ if (skin == null)
+ throw new Error("Skin not found: " + linkedMesh.skin);
+ var parent_3 = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);
+ if (parent_3 == null)
+ throw new Error("Parent mesh not found: " + linkedMesh.parent);
+ linkedMesh.mesh.setParentMesh(parent_3);
+ linkedMesh.mesh.updateUVs();
+ }
+ this.linkedMeshes.length = 0;
+ if (root.events) {
+ for (var eventName in root.events) {
+ var eventMap = root.events[eventName];
+ var data = new spine.EventData(eventName);
+ data.intValue = this.getValue(eventMap, "int", 0);
+ data.floatValue = this.getValue(eventMap, "float", 0);
+ data.stringValue = this.getValue(eventMap, "string", "");
+ skeletonData.events.push(data);
+ }
+ }
+ if (root.animations) {
+ for (var animationName in root.animations) {
+ var animationMap = root.animations[animationName];
+ this.readAnimation(animationMap, animationName, skeletonData);
+ }
+ }
+ return skeletonData;
+ };
+ SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name, skeletonData) {
+ var scale = this.scale;
+ name = this.getValue(map, "name", name);
+ var type = this.getValue(map, "type", "region");
+ switch (type) {
+ case "region": {
+ var path = this.getValue(map, "path", name);
+ var region = this.attachmentLoader.newRegionAttachment(skin, name, path);
+ if (region == null)
+ return null;
+ region.path = path;
+ region.x = this.getValue(map, "x", 0) * scale;
+ region.y = this.getValue(map, "y", 0) * scale;
+ region.scaleX = this.getValue(map, "scaleX", 1);
+ region.scaleY = this.getValue(map, "scaleY", 1);
+ region.rotation = this.getValue(map, "rotation", 0);
+ region.width = map.width * scale;
+ region.height = map.height * scale;
+ var color = this.getValue(map, "color", null);
+ if (color != null)
+ region.color.setFromString(color);
+ region.updateOffset();
+ return region;
+ }
+ case "boundingbox": {
+ var box = this.attachmentLoader.newBoundingBoxAttachment(skin, name);
+ if (box == null)
+ return null;
+ this.readVertices(map, box, map.vertexCount << 1);
+ var color = this.getValue(map, "color", null);
+ if (color != null)
+ box.color.setFromString(color);
+ return box;
+ }
+ case "mesh":
+ case "linkedmesh": {
+ var path = this.getValue(map, "path", name);
+ var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path);
+ if (mesh == null)
+ return null;
+ mesh.path = path;
+ var color = this.getValue(map, "color", null);
+ if (color != null)
+ mesh.color.setFromString(color);
+ var parent_4 = this.getValue(map, "parent", null);
+ if (parent_4 != null) {
+ mesh.inheritDeform = this.getValue(map, "deform", true);
+ this.linkedMeshes.push(new LinkedMesh(mesh, this.getValue(map, "skin", null), slotIndex, parent_4));
+ return mesh;
+ }
+ var uvs = map.uvs;
+ this.readVertices(map, mesh, uvs.length);
+ mesh.triangles = map.triangles;
+ mesh.regionUVs = uvs;
+ mesh.updateUVs();
+ mesh.hullLength = this.getValue(map, "hull", 0) * 2;
+ return mesh;
+ }
+ case "path": {
+ var path = this.attachmentLoader.newPathAttachment(skin, name);
+ if (path == null)
+ return null;
+ path.closed = this.getValue(map, "closed", false);
+ path.constantSpeed = this.getValue(map, "constantSpeed", true);
+ var vertexCount = map.vertexCount;
+ this.readVertices(map, path, vertexCount << 1);
+ var lengths = spine.Utils.newArray(vertexCount / 3, 0);
+ for (var i = 0; i < map.lengths.length; i++)
+ lengths[i] = map.lengths[i] * scale;
+ path.lengths = lengths;
+ var color = this.getValue(map, "color", null);
+ if (color != null)
+ path.color.setFromString(color);
+ return path;
+ }
+ case "point": {
+ var point = this.attachmentLoader.newPointAttachment(skin, name);
+ if (point == null)
+ return null;
+ point.x = this.getValue(map, "x", 0) * scale;
+ point.y = this.getValue(map, "y", 0) * scale;
+ point.rotation = this.getValue(map, "rotation", 0);
+ var color = this.getValue(map, "color", null);
+ if (color != null)
+ point.color.setFromString(color);
+ return point;
+ }
+ case "clipping": {
+ var clip = this.attachmentLoader.newClippingAttachment(skin, name);
+ if (clip == null)
+ return null;
+ var end = this.getValue(map, "end", null);
+ if (end != null) {
+ var slot = skeletonData.findSlot(end);
+ if (slot == null)
+ throw new Error("Clipping end slot not found: " + end);
+ clip.endSlot = slot;
+ }
+ var vertexCount = map.vertexCount;
+ this.readVertices(map, clip, vertexCount << 1);
+ var color = this.getValue(map, "color", null);
+ if (color != null)
+ clip.color.setFromString(color);
+ return clip;
+ }
+ }
+ return null;
+ };
+ SkeletonJson.prototype.readVertices = function (map, attachment, verticesLength) {
+ var scale = this.scale;
+ attachment.worldVerticesLength = verticesLength;
+ var vertices = map.vertices;
+ if (verticesLength == vertices.length) {
+ var scaledVertices = spine.Utils.toFloatArray(vertices);
+ if (scale != 1) {
+ for (var i = 0, n = vertices.length; i < n; i++)
+ scaledVertices[i] *= scale;
+ }
+ attachment.vertices = scaledVertices;
+ return;
+ }
+ var weights = new Array();
+ var bones = new Array();
+ for (var i = 0, n = vertices.length; i < n;) {
+ var boneCount = vertices[i++];
+ bones.push(boneCount);
+ for (var nn = i + boneCount * 4; i < nn; i += 4) {
+ bones.push(vertices[i]);
+ weights.push(vertices[i + 1] * scale);
+ weights.push(vertices[i + 2] * scale);
+ weights.push(vertices[i + 3]);
+ }
+ }
+ attachment.bones = bones;
+ attachment.vertices = spine.Utils.toFloatArray(weights);
+ };
+ SkeletonJson.prototype.readAnimation = function (map, name, skeletonData) {
+ var scale = this.scale;
+ var timelines = new Array();
+ var duration = 0;
+ if (map.slots) {
+ for (var slotName in map.slots) {
+ var slotMap = map.slots[slotName];
+ var slotIndex = skeletonData.findSlotIndex(slotName);
+ if (slotIndex == -1)
+ throw new Error("Slot not found: " + slotName);
+ for (var timelineName in slotMap) {
+ var timelineMap = slotMap[timelineName];
+ if (timelineName == "attachment") {
+ var timeline = new spine.AttachmentTimeline(timelineMap.length);
+ timeline.slotIndex = slotIndex;
+ var frameIndex = 0;
+ for (var i = 0; i < timelineMap.length; i++) {
+ var valueMap = timelineMap[i];
+ timeline.setFrame(frameIndex++, valueMap.time, valueMap.name);
+ }
+ timelines.push(timeline);
+ duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
+ }
+ else if (timelineName == "color") {
+ var timeline = new spine.ColorTimeline(timelineMap.length);
+ timeline.slotIndex = slotIndex;
+ var frameIndex = 0;
+ for (var i = 0; i < timelineMap.length; i++) {
+ var valueMap = timelineMap[i];
+ var color = new spine.Color();
+ color.setFromString(valueMap.color);
+ timeline.setFrame(frameIndex, valueMap.time, color.r, color.g, color.b, color.a);
+ this.readCurve(valueMap, timeline, frameIndex);
+ frameIndex++;
+ }
+ timelines.push(timeline);
+ duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.ColorTimeline.ENTRIES]);
+ }
+ else if (timelineName == "twoColor") {
+ var timeline = new spine.TwoColorTimeline(timelineMap.length);
+ timeline.slotIndex = slotIndex;
+ var frameIndex = 0;
+ for (var i = 0; i < timelineMap.length; i++) {
+ var valueMap = timelineMap[i];
+ var light = new spine.Color();
+ var dark = new spine.Color();
+ light.setFromString(valueMap.light);
+ dark.setFromString(valueMap.dark);
+ timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
+ this.readCurve(valueMap, timeline, frameIndex);
+ frameIndex++;
+ }
+ timelines.push(timeline);
+ duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TwoColorTimeline.ENTRIES]);
+ }
+ else
+ throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
+ }
+ }
+ }
+ if (map.bones) {
+ for (var boneName in map.bones) {
+ var boneMap = map.bones[boneName];
+ var boneIndex = skeletonData.findBoneIndex(boneName);
+ if (boneIndex == -1)
+ throw new Error("Bone not found: " + boneName);
+ for (var timelineName in boneMap) {
+ var timelineMap = boneMap[timelineName];
+ if (timelineName === "rotate") {
+ var timeline = new spine.RotateTimeline(timelineMap.length);
+ timeline.boneIndex = boneIndex;
+ var frameIndex = 0;
+ for (var i = 0; i < timelineMap.length; i++) {
+ var valueMap = timelineMap[i];
+ timeline.setFrame(frameIndex, valueMap.time, valueMap.angle);
+ this.readCurve(valueMap, timeline, frameIndex);
+ frameIndex++;
+ }
+ timelines.push(timeline);
+ duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.RotateTimeline.ENTRIES]);
+ }
+ else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") {
+ var timeline = null;
+ var timelineScale = 1;
+ if (timelineName === "scale")
+ timeline = new spine.ScaleTimeline(timelineMap.length);
+ else if (timelineName === "shear")
+ timeline = new spine.ShearTimeline(timelineMap.length);
+ else {
+ timeline = new spine.TranslateTimeline(timelineMap.length);
+ timelineScale = scale;
+ }
+ timeline.boneIndex = boneIndex;
+ var frameIndex = 0;
+ for (var i = 0; i < timelineMap.length; i++) {
+ var valueMap = timelineMap[i];
+ var x = this.getValue(valueMap, "x", 0), y = this.getValue(valueMap, "y", 0);
+ timeline.setFrame(frameIndex, valueMap.time, x * timelineScale, y * timelineScale);
+ this.readCurve(valueMap, timeline, frameIndex);
+ frameIndex++;
+ }
+ timelines.push(timeline);
+ duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TranslateTimeline.ENTRIES]);
+ }
+ else
+ throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
+ }
+ }
+ }
+ if (map.ik) {
+ for (var constraintName in map.ik) {
+ var constraintMap = map.ik[constraintName];
+ var constraint = skeletonData.findIkConstraint(constraintName);
+ var timeline = new spine.IkConstraintTimeline(constraintMap.length);
+ timeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(constraint);
+ var frameIndex = 0;
+ for (var i = 0; i < constraintMap.length; i++) {
+ var valueMap = constraintMap[i];
+ timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1);
+ this.readCurve(valueMap, timeline, frameIndex);
+ frameIndex++;
+ }
+ timelines.push(timeline);
+ duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.IkConstraintTimeline.ENTRIES]);
+ }
+ }
+ if (map.transform) {
+ for (var constraintName in map.transform) {
+ var constraintMap = map.transform[constraintName];
+ var constraint = skeletonData.findTransformConstraint(constraintName);
+ var timeline = new spine.TransformConstraintTimeline(constraintMap.length);
+ timeline.transformConstraintIndex = skeletonData.transformConstraints.indexOf(constraint);
+ var frameIndex = 0;
+ for (var i = 0; i < constraintMap.length; i++) {
+ var valueMap = constraintMap[i];
+ timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
+ this.readCurve(valueMap, timeline, frameIndex);
+ frameIndex++;
+ }
+ timelines.push(timeline);
+ duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TransformConstraintTimeline.ENTRIES]);
+ }
+ }
+ if (map.paths) {
+ for (var constraintName in map.paths) {
+ var constraintMap = map.paths[constraintName];
+ var index = skeletonData.findPathConstraintIndex(constraintName);
+ if (index == -1)
+ throw new Error("Path constraint not found: " + constraintName);
+ var data = skeletonData.pathConstraints[index];
+ for (var timelineName in constraintMap) {
+ var timelineMap = constraintMap[timelineName];
+ if (timelineName === "position" || timelineName === "spacing") {
+ var timeline = null;
+ var timelineScale = 1;
+ if (timelineName === "spacing") {
+ timeline = new spine.PathConstraintSpacingTimeline(timelineMap.length);
+ if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed)
+ timelineScale = scale;
+ }
+ else {
+ timeline = new spine.PathConstraintPositionTimeline(timelineMap.length);
+ if (data.positionMode == spine.PositionMode.Fixed)
+ timelineScale = scale;
+ }
+ timeline.pathConstraintIndex = index;
+ var frameIndex = 0;
+ for (var i = 0; i < timelineMap.length; i++) {
+ var valueMap = timelineMap[i];
+ timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, timelineName, 0) * timelineScale);
+ this.readCurve(valueMap, timeline, frameIndex);
+ frameIndex++;
+ }
+ timelines.push(timeline);
+ duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.PathConstraintPositionTimeline.ENTRIES]);
+ }
+ else if (timelineName === "mix") {
+ var timeline = new spine.PathConstraintMixTimeline(timelineMap.length);
+ timeline.pathConstraintIndex = index;
+ var frameIndex = 0;
+ for (var i = 0; i < timelineMap.length; i++) {
+ var valueMap = timelineMap[i];
+ timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1));
+ this.readCurve(valueMap, timeline, frameIndex);
+ frameIndex++;
+ }
+ timelines.push(timeline);
+ duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.PathConstraintMixTimeline.ENTRIES]);
+ }
+ }
+ }
+ }
+ if (map.deform) {
+ for (var deformName in map.deform) {
+ var deformMap = map.deform[deformName];
+ var skin = skeletonData.findSkin(deformName);
+ if (skin == null)
+ throw new Error("Skin not found: " + deformName);
+ for (var slotName in deformMap) {
+ var slotMap = deformMap[slotName];
+ var slotIndex = skeletonData.findSlotIndex(slotName);
+ if (slotIndex == -1)
+ throw new Error("Slot not found: " + slotMap.name);
+ for (var timelineName in slotMap) {
+ var timelineMap = slotMap[timelineName];
+ var attachment = skin.getAttachment(slotIndex, timelineName);
+ if (attachment == null)
+ throw new Error("Deform attachment not found: " + timelineMap.name);
+ var weighted = attachment.bones != null;
+ var vertices = attachment.vertices;
+ var deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;
+ var timeline = new spine.DeformTimeline(timelineMap.length);
+ timeline.slotIndex = slotIndex;
+ timeline.attachment = attachment;
+ var frameIndex = 0;
+ for (var j = 0; j < timelineMap.length; j++) {
+ var valueMap = timelineMap[j];
+ var deform = void 0;
+ var verticesValue = this.getValue(valueMap, "vertices", null);
+ if (verticesValue == null)
+ deform = weighted ? spine.Utils.newFloatArray(deformLength) : vertices;
+ else {
+ deform = spine.Utils.newFloatArray(deformLength);
+ var start = this.getValue(valueMap, "offset", 0);
+ spine.Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length);
+ if (scale != 1) {
+ for (var i = start, n = i + verticesValue.length; i < n; i++)
+ deform[i] *= scale;
+ }
+ if (!weighted) {
+ for (var i = 0; i < deformLength; i++)
+ deform[i] += vertices[i];
+ }
+ }
+ timeline.setFrame(frameIndex, valueMap.time, deform);
+ this.readCurve(valueMap, timeline, frameIndex);
+ frameIndex++;
+ }
+ timelines.push(timeline);
+ duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
+ }
+ }
+ }
+ }
+ var drawOrderNode = map.drawOrder;
+ if (drawOrderNode == null)
+ drawOrderNode = map.draworder;
+ if (drawOrderNode != null) {
+ var timeline = new spine.DrawOrderTimeline(drawOrderNode.length);
+ var slotCount = skeletonData.slots.length;
+ var frameIndex = 0;
+ for (var j = 0; j < drawOrderNode.length; j++) {
+ var drawOrderMap = drawOrderNode[j];
+ var drawOrder = null;
+ var offsets = this.getValue(drawOrderMap, "offsets", null);
+ if (offsets != null) {
+ drawOrder = spine.Utils.newArray(slotCount, -1);
+ var unchanged = spine.Utils.newArray(slotCount - offsets.length, 0);
+ var originalIndex = 0, unchangedIndex = 0;
+ for (var i = 0; i < offsets.length; i++) {
+ var offsetMap = offsets[i];
+ var slotIndex = skeletonData.findSlotIndex(offsetMap.slot);
+ if (slotIndex == -1)
+ throw new Error("Slot not found: " + offsetMap.slot);
+ while (originalIndex != slotIndex)
+ unchanged[unchangedIndex++] = originalIndex++;
+ drawOrder[originalIndex + offsetMap.offset] = originalIndex++;
+ }
+ while (originalIndex < slotCount)
+ unchanged[unchangedIndex++] = originalIndex++;
+ for (var i = slotCount - 1; i >= 0; i--)
+ if (drawOrder[i] == -1)
+ drawOrder[i] = unchanged[--unchangedIndex];
+ }
+ timeline.setFrame(frameIndex++, drawOrderMap.time, drawOrder);
+ }
+ timelines.push(timeline);
+ duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
+ }
+ if (map.events) {
+ var timeline = new spine.EventTimeline(map.events.length);
+ var frameIndex = 0;
+ for (var i = 0; i < map.events.length; i++) {
+ var eventMap = map.events[i];
+ var eventData = skeletonData.findEvent(eventMap.name);
+ if (eventData == null)
+ throw new Error("Event not found: " + eventMap.name);
+ var event_5 = new spine.Event(spine.Utils.toSinglePrecision(eventMap.time), eventData);
+ event_5.intValue = this.getValue(eventMap, "int", eventData.intValue);
+ event_5.floatValue = this.getValue(eventMap, "float", eventData.floatValue);
+ event_5.stringValue = this.getValue(eventMap, "string", eventData.stringValue);
+ timeline.setFrame(frameIndex++, event_5);
+ }
+ timelines.push(timeline);
+ duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
+ }
+ if (isNaN(duration)) {
+ throw new Error("Error while parsing animation, duration is NaN");
+ }
+ skeletonData.animations.push(new spine.Animation(name, timelines, duration));
+ };
+ SkeletonJson.prototype.readCurve = function (map, timeline, frameIndex) {
+ if (!map.curve)
+ return;
+ if (map.curve === "stepped")
+ timeline.setStepped(frameIndex);
+ else if (Object.prototype.toString.call(map.curve) === '[object Array]') {
+ var curve = map.curve;
+ timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
+ }
+ };
+ SkeletonJson.prototype.getValue = function (map, prop, defaultValue) {
+ return map[prop] !== undefined ? map[prop] : defaultValue;
+ };
+ SkeletonJson.blendModeFromString = function (str) {
+ str = str.toLowerCase();
+ if (str == "normal")
+ return spine.BlendMode.Normal;
+ if (str == "additive")
+ return spine.BlendMode.Additive;
+ if (str == "multiply")
+ return spine.BlendMode.Multiply;
+ if (str == "screen")
+ return spine.BlendMode.Screen;
+ throw new Error("Unknown blend mode: " + str);
+ };
+ SkeletonJson.positionModeFromString = function (str) {
+ str = str.toLowerCase();
+ if (str == "fixed")
+ return spine.PositionMode.Fixed;
+ if (str == "percent")
+ return spine.PositionMode.Percent;
+ throw new Error("Unknown position mode: " + str);
+ };
+ SkeletonJson.spacingModeFromString = function (str) {
+ str = str.toLowerCase();
+ if (str == "length")
+ return spine.SpacingMode.Length;
+ if (str == "fixed")
+ return spine.SpacingMode.Fixed;
+ if (str == "percent")
+ return spine.SpacingMode.Percent;
+ throw new Error("Unknown position mode: " + str);
+ };
+ SkeletonJson.rotateModeFromString = function (str) {
+ str = str.toLowerCase();
+ if (str == "tangent")
+ return spine.RotateMode.Tangent;
+ if (str == "chain")
+ return spine.RotateMode.Chain;
+ if (str == "chainscale")
+ return spine.RotateMode.ChainScale;
+ throw new Error("Unknown rotate mode: " + str);
+ };
+ SkeletonJson.transformModeFromString = function (str) {
+ str = str.toLowerCase();
+ if (str == "normal")
+ return spine.TransformMode.Normal;
+ if (str == "onlytranslation")
+ return spine.TransformMode.OnlyTranslation;
+ if (str == "norotationorreflection")
+ return spine.TransformMode.NoRotationOrReflection;
+ if (str == "noscale")
+ return spine.TransformMode.NoScale;
+ if (str == "noscaleorreflection")
+ return spine.TransformMode.NoScaleOrReflection;
+ throw new Error("Unknown transform mode: " + str);
+ };
+ return SkeletonJson;
+ }());
+ spine.SkeletonJson = SkeletonJson;
+ var LinkedMesh = (function () {
+ function LinkedMesh(mesh, skin, slotIndex, parent) {
+ this.mesh = mesh;
+ this.skin = skin;
+ this.slotIndex = slotIndex;
+ this.parent = parent;
+ }
+ return LinkedMesh;
+ }());
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var Skin = (function () {
+ function Skin(name) {
+ this.attachments = new Array();
+ if (name == null)
+ throw new Error("name cannot be null.");
+ this.name = name;
+ }
+ Skin.prototype.addAttachment = function (slotIndex, name, attachment) {
+ if (attachment == null)
+ throw new Error("attachment cannot be null.");
+ var attachments = this.attachments;
+ if (slotIndex >= attachments.length)
+ attachments.length = slotIndex + 1;
+ if (!attachments[slotIndex])
+ attachments[slotIndex] = {};
+ attachments[slotIndex][name] = attachment;
+ };
+ Skin.prototype.getAttachment = function (slotIndex, name) {
+ var dictionary = this.attachments[slotIndex];
+ return dictionary ? dictionary[name] : null;
+ };
+ Skin.prototype.attachAll = function (skeleton, oldSkin) {
+ var slotIndex = 0;
+ for (var i = 0; i < skeleton.slots.length; i++) {
+ var slot = skeleton.slots[i];
+ var slotAttachment = slot.getAttachment();
+ if (slotAttachment && slotIndex < oldSkin.attachments.length) {
+ var dictionary = oldSkin.attachments[slotIndex];
+ for (var key in dictionary) {
+ var skinAttachment = dictionary[key];
+ if (slotAttachment == skinAttachment) {
+ var attachment = this.getAttachment(slotIndex, key);
+ if (attachment != null)
+ slot.setAttachment(attachment);
+ break;
+ }
+ }
+ }
+ slotIndex++;
+ }
+ };
+ return Skin;
+ }());
+ spine.Skin = Skin;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var Slot = (function () {
+ function Slot(data, bone) {
+ this.attachmentVertices = new Array();
+ if (data == null)
+ throw new Error("data cannot be null.");
+ if (bone == null)
+ throw new Error("bone cannot be null.");
+ this.data = data;
+ this.bone = bone;
+ this.color = new spine.Color();
+ this.darkColor = data.darkColor == null ? null : new spine.Color();
+ this.setToSetupPose();
+ }
+ Slot.prototype.getAttachment = function () {
+ return this.attachment;
+ };
+ Slot.prototype.setAttachment = function (attachment) {
+ if (this.attachment == attachment)
+ return;
+ this.attachment = attachment;
+ this.attachmentTime = this.bone.skeleton.time;
+ this.attachmentVertices.length = 0;
+ };
+ Slot.prototype.setAttachmentTime = function (time) {
+ this.attachmentTime = this.bone.skeleton.time - time;
+ };
+ Slot.prototype.getAttachmentTime = function () {
+ return this.bone.skeleton.time - this.attachmentTime;
+ };
+ Slot.prototype.setToSetupPose = function () {
+ this.color.setFromColor(this.data.color);
+ if (this.darkColor != null)
+ this.darkColor.setFromColor(this.data.darkColor);
+ if (this.data.attachmentName == null)
+ this.attachment = null;
+ else {
+ this.attachment = null;
+ this.setAttachment(this.bone.skeleton.getAttachment(this.data.index, this.data.attachmentName));
+ }
+ };
+ return Slot;
+ }());
+ spine.Slot = Slot;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var SlotData = (function () {
+ function SlotData(index, name, boneData) {
+ this.color = new spine.Color(1, 1, 1, 1);
+ if (index < 0)
+ throw new Error("index must be >= 0.");
+ if (name == null)
+ throw new Error("name cannot be null.");
+ if (boneData == null)
+ throw new Error("boneData cannot be null.");
+ this.index = index;
+ this.name = name;
+ this.boneData = boneData;
+ }
+ return SlotData;
+ }());
+ spine.SlotData = SlotData;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var Texture = (function () {
+ function Texture(image) {
+ this._image = image;
+ }
+ Texture.prototype.getImage = function () {
+ return this._image;
+ };
+ Texture.filterFromString = function (text) {
+ switch (text.toLowerCase()) {
+ case "nearest": return TextureFilter.Nearest;
+ case "linear": return TextureFilter.Linear;
+ case "mipmap": return TextureFilter.MipMap;
+ case "mipmapnearestnearest": return TextureFilter.MipMapNearestNearest;
+ case "mipmaplinearnearest": return TextureFilter.MipMapLinearNearest;
+ case "mipmapnearestlinear": return TextureFilter.MipMapNearestLinear;
+ case "mipmaplinearlinear": return TextureFilter.MipMapLinearLinear;
+ default: throw new Error("Unknown texture filter " + text);
+ }
+ };
+ Texture.wrapFromString = function (text) {
+ switch (text.toLowerCase()) {
+ case "mirroredtepeat": return TextureWrap.MirroredRepeat;
+ case "clamptoedge": return TextureWrap.ClampToEdge;
+ case "repeat": return TextureWrap.Repeat;
+ default: throw new Error("Unknown texture wrap " + text);
+ }
+ };
+ return Texture;
+ }());
+ spine.Texture = Texture;
+ var TextureFilter;
+ (function (TextureFilter) {
+ TextureFilter[TextureFilter["Nearest"] = 9728] = "Nearest";
+ TextureFilter[TextureFilter["Linear"] = 9729] = "Linear";
+ TextureFilter[TextureFilter["MipMap"] = 9987] = "MipMap";
+ TextureFilter[TextureFilter["MipMapNearestNearest"] = 9984] = "MipMapNearestNearest";
+ TextureFilter[TextureFilter["MipMapLinearNearest"] = 9985] = "MipMapLinearNearest";
+ TextureFilter[TextureFilter["MipMapNearestLinear"] = 9986] = "MipMapNearestLinear";
+ TextureFilter[TextureFilter["MipMapLinearLinear"] = 9987] = "MipMapLinearLinear";
+ })(TextureFilter = spine.TextureFilter || (spine.TextureFilter = {}));
+ var TextureWrap;
+ (function (TextureWrap) {
+ TextureWrap[TextureWrap["MirroredRepeat"] = 33648] = "MirroredRepeat";
+ TextureWrap[TextureWrap["ClampToEdge"] = 33071] = "ClampToEdge";
+ TextureWrap[TextureWrap["Repeat"] = 10497] = "Repeat";
+ })(TextureWrap = spine.TextureWrap || (spine.TextureWrap = {}));
+ var TextureRegion = (function () {
+ function TextureRegion() {
+ this.u = 0;
+ this.v = 0;
+ this.u2 = 0;
+ this.v2 = 0;
+ this.width = 0;
+ this.height = 0;
+ this.rotate = false;
+ this.offsetX = 0;
+ this.offsetY = 0;
+ this.originalWidth = 0;
+ this.originalHeight = 0;
+ }
+ return TextureRegion;
+ }());
+ spine.TextureRegion = TextureRegion;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var TextureAtlas = (function () {
+ function TextureAtlas(atlasText, textureLoader) {
+ this.pages = new Array();
+ this.regions = new Array();
+ this.load(atlasText, textureLoader);
+ }
+ TextureAtlas.prototype.load = function (atlasText, textureLoader) {
+ if (textureLoader == null)
+ throw new Error("textureLoader cannot be null.");
+ var reader = new TextureAtlasReader(atlasText);
+ var tuple = new Array(4);
+ var page = null;
+ while (true) {
+ var line = reader.readLine();
+ if (line == null)
+ break;
+ line = line.trim();
+ if (line.length == 0)
+ page = null;
+ else if (!page) {
+ page = new TextureAtlasPage();
+ page.name = line;
+ if (reader.readTuple(tuple) == 2) {
+ page.width = parseInt(tuple[0]);
+ page.height = parseInt(tuple[1]);
+ reader.readTuple(tuple);
+ }
+ reader.readTuple(tuple);
+ page.minFilter = spine.Texture.filterFromString(tuple[0]);
+ page.magFilter = spine.Texture.filterFromString(tuple[1]);
+ var direction = reader.readValue();
+ page.uWrap = spine.TextureWrap.ClampToEdge;
+ page.vWrap = spine.TextureWrap.ClampToEdge;
+ if (direction == "x")
+ page.uWrap = spine.TextureWrap.Repeat;
+ else if (direction == "y")
+ page.vWrap = spine.TextureWrap.Repeat;
+ else if (direction == "xy")
+ page.uWrap = page.vWrap = spine.TextureWrap.Repeat;
+ page.texture = textureLoader(line);
+ page.texture.setFilters(page.minFilter, page.magFilter);
+ page.texture.setWraps(page.uWrap, page.vWrap);
+ page.width = page.texture.getImage().width;
+ page.height = page.texture.getImage().height;
+ this.pages.push(page);
+ }
+ else {
+ var region = new TextureAtlasRegion();
+ region.name = line;
+ region.page = page;
+ region.rotate = reader.readValue() == "true";
+ reader.readTuple(tuple);
+ var x = parseInt(tuple[0]);
+ var y = parseInt(tuple[1]);
+ reader.readTuple(tuple);
+ var width = parseInt(tuple[0]);
+ var height = parseInt(tuple[1]);
+ region.u = x / page.width;
+ region.v = y / page.height;
+ if (region.rotate) {
+ region.u2 = (x + height) / page.width;
+ region.v2 = (y + width) / page.height;
+ }
+ else {
+ region.u2 = (x + width) / page.width;
+ region.v2 = (y + height) / page.height;
+ }
+ region.x = x;
+ region.y = y;
+ region.width = Math.abs(width);
+ region.height = Math.abs(height);
+ if (reader.readTuple(tuple) == 4) {
+ if (reader.readTuple(tuple) == 4) {
+ reader.readTuple(tuple);
+ }
+ }
+ region.originalWidth = parseInt(tuple[0]);
+ region.originalHeight = parseInt(tuple[1]);
+ reader.readTuple(tuple);
+ region.offsetX = parseInt(tuple[0]);
+ region.offsetY = parseInt(tuple[1]);
+ region.index = parseInt(reader.readValue());
+ region.texture = page.texture;
+ this.regions.push(region);
+ }
+ }
+ };
+ TextureAtlas.prototype.findRegion = function (name) {
+ for (var i = 0; i < this.regions.length; i++) {
+ if (this.regions[i].name == name) {
+ return this.regions[i];
+ }
+ }
+ return null;
+ };
+ TextureAtlas.prototype.dispose = function () {
+ for (var i = 0; i < this.pages.length; i++) {
+ this.pages[i].texture.dispose();
+ }
+ };
+ return TextureAtlas;
+ }());
+ spine.TextureAtlas = TextureAtlas;
+ var TextureAtlasReader = (function () {
+ function TextureAtlasReader(text) {
+ this.index = 0;
+ this.lines = text.split(/\r\n|\r|\n/);
+ }
+ TextureAtlasReader.prototype.readLine = function () {
+ if (this.index >= this.lines.length)
+ return null;
+ return this.lines[this.index++];
+ };
+ TextureAtlasReader.prototype.readValue = function () {
+ var line = this.readLine();
+ var colon = line.indexOf(":");
+ if (colon == -1)
+ throw new Error("Invalid line: " + line);
+ return line.substring(colon + 1).trim();
+ };
+ TextureAtlasReader.prototype.readTuple = function (tuple) {
+ var line = this.readLine();
+ var colon = line.indexOf(":");
+ if (colon == -1)
+ throw new Error("Invalid line: " + line);
+ var i = 0, lastMatch = colon + 1;
+ for (; i < 3; i++) {
+ var comma = line.indexOf(",", lastMatch);
+ if (comma == -1)
+ break;
+ tuple[i] = line.substr(lastMatch, comma - lastMatch).trim();
+ lastMatch = comma + 1;
+ }
+ tuple[i] = line.substring(lastMatch).trim();
+ return i + 1;
+ };
+ return TextureAtlasReader;
+ }());
+ var TextureAtlasPage = (function () {
+ function TextureAtlasPage() {
+ }
+ return TextureAtlasPage;
+ }());
+ spine.TextureAtlasPage = TextureAtlasPage;
+ var TextureAtlasRegion = (function (_super) {
+ __extends(TextureAtlasRegion, _super);
+ function TextureAtlasRegion() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ return TextureAtlasRegion;
+ }(spine.TextureRegion));
+ spine.TextureAtlasRegion = TextureAtlasRegion;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var TransformConstraint = (function () {
+ function TransformConstraint(data, skeleton) {
+ this.rotateMix = 0;
+ this.translateMix = 0;
+ this.scaleMix = 0;
+ this.shearMix = 0;
+ this.temp = new spine.Vector2();
+ if (data == null)
+ throw new Error("data cannot be null.");
+ if (skeleton == null)
+ throw new Error("skeleton cannot be null.");
+ this.data = data;
+ this.rotateMix = data.rotateMix;
+ this.translateMix = data.translateMix;
+ this.scaleMix = data.scaleMix;
+ this.shearMix = data.shearMix;
+ this.bones = new Array();
+ for (var i = 0; i < data.bones.length; i++)
+ this.bones.push(skeleton.findBone(data.bones[i].name));
+ this.target = skeleton.findBone(data.target.name);
+ }
+ TransformConstraint.prototype.apply = function () {
+ this.update();
+ };
+ TransformConstraint.prototype.update = function () {
+ if (this.data.local) {
+ if (this.data.relative)
+ this.applyRelativeLocal();
+ else
+ this.applyAbsoluteLocal();
+ }
+ else {
+ if (this.data.relative)
+ this.applyRelativeWorld();
+ else
+ this.applyAbsoluteWorld();
+ }
+ };
+ TransformConstraint.prototype.applyAbsoluteWorld = function () {
+ var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix;
+ var target = this.target;
+ var ta = target.a, tb = target.b, tc = target.c, td = target.d;
+ var degRadReflect = ta * td - tb * tc > 0 ? spine.MathUtils.degRad : -spine.MathUtils.degRad;
+ var offsetRotation = this.data.offsetRotation * degRadReflect;
+ var offsetShearY = this.data.offsetShearY * degRadReflect;
+ var bones = this.bones;
+ for (var i = 0, n = bones.length; i < n; i++) {
+ var bone = bones[i];
+ var modified = false;
+ if (rotateMix != 0) {
+ var a = bone.a, b = bone.b, c = bone.c, d = bone.d;
+ var r = Math.atan2(tc, ta) - Math.atan2(c, a) + offsetRotation;
+ if (r > spine.MathUtils.PI)
+ r -= spine.MathUtils.PI2;
+ else if (r < -spine.MathUtils.PI)
+ r += spine.MathUtils.PI2;
+ r *= rotateMix;
+ var cos = Math.cos(r), sin = Math.sin(r);
+ bone.a = cos * a - sin * c;
+ bone.b = cos * b - sin * d;
+ bone.c = sin * a + cos * c;
+ bone.d = sin * b + cos * d;
+ modified = true;
+ }
+ if (translateMix != 0) {
+ var temp = this.temp;
+ target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY));
+ bone.worldX += (temp.x - bone.worldX) * translateMix;
+ bone.worldY += (temp.y - bone.worldY) * translateMix;
+ modified = true;
+ }
+ if (scaleMix > 0) {
+ var s = Math.sqrt(bone.a * bone.a + bone.c * bone.c);
+ var ts = Math.sqrt(ta * ta + tc * tc);
+ if (s > 0.00001)
+ s = (s + (ts - s + this.data.offsetScaleX) * scaleMix) / s;
+ bone.a *= s;
+ bone.c *= s;
+ s = Math.sqrt(bone.b * bone.b + bone.d * bone.d);
+ ts = Math.sqrt(tb * tb + td * td);
+ if (s > 0.00001)
+ s = (s + (ts - s + this.data.offsetScaleY) * scaleMix) / s;
+ bone.b *= s;
+ bone.d *= s;
+ modified = true;
+ }
+ if (shearMix > 0) {
+ var b = bone.b, d = bone.d;
+ var by = Math.atan2(d, b);
+ var r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(bone.c, bone.a));
+ if (r > spine.MathUtils.PI)
+ r -= spine.MathUtils.PI2;
+ else if (r < -spine.MathUtils.PI)
+ r += spine.MathUtils.PI2;
+ r = by + (r + offsetShearY) * shearMix;
+ var s = Math.sqrt(b * b + d * d);
+ bone.b = Math.cos(r) * s;
+ bone.d = Math.sin(r) * s;
+ modified = true;
+ }
+ if (modified)
+ bone.appliedValid = false;
+ }
+ };
+ TransformConstraint.prototype.applyRelativeWorld = function () {
+ var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix;
+ var target = this.target;
+ var ta = target.a, tb = target.b, tc = target.c, td = target.d;
+ var degRadReflect = ta * td - tb * tc > 0 ? spine.MathUtils.degRad : -spine.MathUtils.degRad;
+ var offsetRotation = this.data.offsetRotation * degRadReflect, offsetShearY = this.data.offsetShearY * degRadReflect;
+ var bones = this.bones;
+ for (var i = 0, n = bones.length; i < n; i++) {
+ var bone = bones[i];
+ var modified = false;
+ if (rotateMix != 0) {
+ var a = bone.a, b = bone.b, c = bone.c, d = bone.d;
+ var r = Math.atan2(tc, ta) + offsetRotation;
+ if (r > spine.MathUtils.PI)
+ r -= spine.MathUtils.PI2;
+ else if (r < -spine.MathUtils.PI)
+ r += spine.MathUtils.PI2;
+ r *= rotateMix;
+ var cos = Math.cos(r), sin = Math.sin(r);
+ bone.a = cos * a - sin * c;
+ bone.b = cos * b - sin * d;
+ bone.c = sin * a + cos * c;
+ bone.d = sin * b + cos * d;
+ modified = true;
+ }
+ if (translateMix != 0) {
+ var temp = this.temp;
+ target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY));
+ bone.worldX += temp.x * translateMix;
+ bone.worldY += temp.y * translateMix;
+ modified = true;
+ }
+ if (scaleMix > 0) {
+ var s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * scaleMix + 1;
+ bone.a *= s;
+ bone.c *= s;
+ s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * scaleMix + 1;
+ bone.b *= s;
+ bone.d *= s;
+ modified = true;
+ }
+ if (shearMix > 0) {
+ var r = Math.atan2(td, tb) - Math.atan2(tc, ta);
+ if (r > spine.MathUtils.PI)
+ r -= spine.MathUtils.PI2;
+ else if (r < -spine.MathUtils.PI)
+ r += spine.MathUtils.PI2;
+ var b = bone.b, d = bone.d;
+ r = Math.atan2(d, b) + (r - spine.MathUtils.PI / 2 + offsetShearY) * shearMix;
+ var s = Math.sqrt(b * b + d * d);
+ bone.b = Math.cos(r) * s;
+ bone.d = Math.sin(r) * s;
+ modified = true;
+ }
+ if (modified)
+ bone.appliedValid = false;
+ }
+ };
+ TransformConstraint.prototype.applyAbsoluteLocal = function () {
+ var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix;
+ var target = this.target;
+ if (!target.appliedValid)
+ target.updateAppliedTransform();
+ var bones = this.bones;
+ for (var i = 0, n = bones.length; i < n; i++) {
+ var bone = bones[i];
+ if (!bone.appliedValid)
+ bone.updateAppliedTransform();
+ var rotation = bone.arotation;
+ if (rotateMix != 0) {
+ var r = target.arotation - rotation + this.data.offsetRotation;
+ r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
+ rotation += r * rotateMix;
+ }
+ var x = bone.ax, y = bone.ay;
+ if (translateMix != 0) {
+ x += (target.ax - x + this.data.offsetX) * translateMix;
+ y += (target.ay - y + this.data.offsetY) * translateMix;
+ }
+ var scaleX = bone.ascaleX, scaleY = bone.ascaleY;
+ if (scaleMix > 0) {
+ if (scaleX > 0.00001)
+ scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * scaleMix) / scaleX;
+ if (scaleY > 0.00001)
+ scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * scaleMix) / scaleY;
+ }
+ var shearY = bone.ashearY;
+ if (shearMix > 0) {
+ var r = target.ashearY - shearY + this.data.offsetShearY;
+ r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
+ bone.shearY += r * shearMix;
+ }
+ bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
+ }
+ };
+ TransformConstraint.prototype.applyRelativeLocal = function () {
+ var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix;
+ var target = this.target;
+ if (!target.appliedValid)
+ target.updateAppliedTransform();
+ var bones = this.bones;
+ for (var i = 0, n = bones.length; i < n; i++) {
+ var bone = bones[i];
+ if (!bone.appliedValid)
+ bone.updateAppliedTransform();
+ var rotation = bone.arotation;
+ if (rotateMix != 0)
+ rotation += (target.arotation + this.data.offsetRotation) * rotateMix;
+ var x = bone.ax, y = bone.ay;
+ if (translateMix != 0) {
+ x += (target.ax + this.data.offsetX) * translateMix;
+ y += (target.ay + this.data.offsetY) * translateMix;
+ }
+ var scaleX = bone.ascaleX, scaleY = bone.ascaleY;
+ if (scaleMix > 0) {
+ if (scaleX > 0.00001)
+ scaleX *= ((target.ascaleX - 1 + this.data.offsetScaleX) * scaleMix) + 1;
+ if (scaleY > 0.00001)
+ scaleY *= ((target.ascaleY - 1 + this.data.offsetScaleY) * scaleMix) + 1;
+ }
+ var shearY = bone.ashearY;
+ if (shearMix > 0)
+ shearY += (target.ashearY + this.data.offsetShearY) * shearMix;
+ bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
+ }
+ };
+ TransformConstraint.prototype.getOrder = function () {
+ return this.data.order;
+ };
+ return TransformConstraint;
+ }());
+ spine.TransformConstraint = TransformConstraint;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var TransformConstraintData = (function () {
+ function TransformConstraintData(name) {
+ this.order = 0;
+ this.bones = new Array();
+ this.rotateMix = 0;
+ this.translateMix = 0;
+ this.scaleMix = 0;
+ this.shearMix = 0;
+ this.offsetRotation = 0;
+ this.offsetX = 0;
+ this.offsetY = 0;
+ this.offsetScaleX = 0;
+ this.offsetScaleY = 0;
+ this.offsetShearY = 0;
+ this.relative = false;
+ this.local = false;
+ if (name == null)
+ throw new Error("name cannot be null.");
+ this.name = name;
+ }
+ return TransformConstraintData;
+ }());
+ spine.TransformConstraintData = TransformConstraintData;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var Triangulator = (function () {
+ function Triangulator() {
+ this.convexPolygons = new Array();
+ this.convexPolygonsIndices = new Array();
+ this.indicesArray = new Array();
+ this.isConcaveArray = new Array();
+ this.triangles = new Array();
+ this.polygonPool = new spine.Pool(function () {
+ return new Array();
+ });
+ this.polygonIndicesPool = new spine.Pool(function () {
+ return new Array();
+ });
+ }
+ Triangulator.prototype.triangulate = function (verticesArray) {
+ var vertices = verticesArray;
+ var vertexCount = verticesArray.length >> 1;
+ var indices = this.indicesArray;
+ indices.length = 0;
+ for (var i = 0; i < vertexCount; i++)
+ indices[i] = i;
+ var isConcave = this.isConcaveArray;
+ isConcave.length = 0;
+ for (var i = 0, n = vertexCount; i < n; ++i)
+ isConcave[i] = Triangulator.isConcave(i, vertexCount, vertices, indices);
+ var triangles = this.triangles;
+ triangles.length = 0;
+ while (vertexCount > 3) {
+ var previous = vertexCount - 1, i = 0, next = 1;
+ while (true) {
+ outer: if (!isConcave[i]) {
+ var p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1;
+ var p1x = vertices[p1], p1y = vertices[p1 + 1];
+ var p2x = vertices[p2], p2y = vertices[p2 + 1];
+ var p3x = vertices[p3], p3y = vertices[p3 + 1];
+ for (var ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) {
+ if (!isConcave[ii])
+ continue;
+ var v = indices[ii] << 1;
+ var vx = vertices[v], vy = vertices[v + 1];
+ if (Triangulator.positiveArea(p3x, p3y, p1x, p1y, vx, vy)) {
+ if (Triangulator.positiveArea(p1x, p1y, p2x, p2y, vx, vy)) {
+ if (Triangulator.positiveArea(p2x, p2y, p3x, p3y, vx, vy))
+ break outer;
+ }
+ }
+ }
+ break;
+ }
+ if (next == 0) {
+ do {
+ if (!isConcave[i])
+ break;
+ i--;
+ } while (i > 0);
+ break;
+ }
+ previous = i;
+ i = next;
+ next = (next + 1) % vertexCount;
+ }
+ triangles.push(indices[(vertexCount + i - 1) % vertexCount]);
+ triangles.push(indices[i]);
+ triangles.push(indices[(i + 1) % vertexCount]);
+ indices.splice(i, 1);
+ isConcave.splice(i, 1);
+ vertexCount--;
+ var previousIndex = (vertexCount + i - 1) % vertexCount;
+ var nextIndex = i == vertexCount ? 0 : i;
+ isConcave[previousIndex] = Triangulator.isConcave(previousIndex, vertexCount, vertices, indices);
+ isConcave[nextIndex] = Triangulator.isConcave(nextIndex, vertexCount, vertices, indices);
+ }
+ if (vertexCount == 3) {
+ triangles.push(indices[2]);
+ triangles.push(indices[0]);
+ triangles.push(indices[1]);
+ }
+ return triangles;
+ };
+ Triangulator.prototype.decompose = function (verticesArray, triangles) {
+ var vertices = verticesArray;
+ var convexPolygons = this.convexPolygons;
+ this.polygonPool.freeAll(convexPolygons);
+ convexPolygons.length = 0;
+ var convexPolygonsIndices = this.convexPolygonsIndices;
+ this.polygonIndicesPool.freeAll(convexPolygonsIndices);
+ convexPolygonsIndices.length = 0;
+ var polygonIndices = this.polygonIndicesPool.obtain();
+ polygonIndices.length = 0;
+ var polygon = this.polygonPool.obtain();
+ polygon.length = 0;
+ var fanBaseIndex = -1, lastWinding = 0;
+ for (var i = 0, n = triangles.length; i < n; i += 3) {
+ var t1 = triangles[i] << 1, t2 = triangles[i + 1] << 1, t3 = triangles[i + 2] << 1;
+ var x1 = vertices[t1], y1 = vertices[t1 + 1];
+ var x2 = vertices[t2], y2 = vertices[t2 + 1];
+ var x3 = vertices[t3], y3 = vertices[t3 + 1];
+ var merged = false;
+ if (fanBaseIndex == t1) {
+ var o = polygon.length - 4;
+ var winding1 = Triangulator.winding(polygon[o], polygon[o + 1], polygon[o + 2], polygon[o + 3], x3, y3);
+ var winding2 = Triangulator.winding(x3, y3, polygon[0], polygon[1], polygon[2], polygon[3]);
+ if (winding1 == lastWinding && winding2 == lastWinding) {
+ polygon.push(x3);
+ polygon.push(y3);
+ polygonIndices.push(t3);
+ merged = true;
+ }
+ }
+ if (!merged) {
+ if (polygon.length > 0) {
+ convexPolygons.push(polygon);
+ convexPolygonsIndices.push(polygonIndices);
+ }
+ else {
+ this.polygonPool.free(polygon);
+ this.polygonIndicesPool.free(polygonIndices);
+ }
+ polygon = this.polygonPool.obtain();
+ polygon.length = 0;
+ polygon.push(x1);
+ polygon.push(y1);
+ polygon.push(x2);
+ polygon.push(y2);
+ polygon.push(x3);
+ polygon.push(y3);
+ polygonIndices = this.polygonIndicesPool.obtain();
+ polygonIndices.length = 0;
+ polygonIndices.push(t1);
+ polygonIndices.push(t2);
+ polygonIndices.push(t3);
+ lastWinding = Triangulator.winding(x1, y1, x2, y2, x3, y3);
+ fanBaseIndex = t1;
+ }
+ }
+ if (polygon.length > 0) {
+ convexPolygons.push(polygon);
+ convexPolygonsIndices.push(polygonIndices);
+ }
+ for (var i = 0, n = convexPolygons.length; i < n; i++) {
+ polygonIndices = convexPolygonsIndices[i];
+ if (polygonIndices.length == 0)
+ continue;
+ var firstIndex = polygonIndices[0];
+ var lastIndex = polygonIndices[polygonIndices.length - 1];
+ polygon = convexPolygons[i];
+ var o = polygon.length - 4;
+ var prevPrevX = polygon[o], prevPrevY = polygon[o + 1];
+ var prevX = polygon[o + 2], prevY = polygon[o + 3];
+ var firstX = polygon[0], firstY = polygon[1];
+ var secondX = polygon[2], secondY = polygon[3];
+ var winding = Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY);
+ for (var ii = 0; ii < n; ii++) {
+ if (ii == i)
+ continue;
+ var otherIndices = convexPolygonsIndices[ii];
+ if (otherIndices.length != 3)
+ continue;
+ var otherFirstIndex = otherIndices[0];
+ var otherSecondIndex = otherIndices[1];
+ var otherLastIndex = otherIndices[2];
+ var otherPoly = convexPolygons[ii];
+ var x3 = otherPoly[otherPoly.length - 2], y3 = otherPoly[otherPoly.length - 1];
+ if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex)
+ continue;
+ var winding1 = Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3);
+ var winding2 = Triangulator.winding(x3, y3, firstX, firstY, secondX, secondY);
+ if (winding1 == winding && winding2 == winding) {
+ otherPoly.length = 0;
+ otherIndices.length = 0;
+ polygon.push(x3);
+ polygon.push(y3);
+ polygonIndices.push(otherLastIndex);
+ prevPrevX = prevX;
+ prevPrevY = prevY;
+ prevX = x3;
+ prevY = y3;
+ ii = 0;
+ }
+ }
+ }
+ for (var i = convexPolygons.length - 1; i >= 0; i--) {
+ polygon = convexPolygons[i];
+ if (polygon.length == 0) {
+ convexPolygons.splice(i, 1);
+ this.polygonPool.free(polygon);
+ polygonIndices = convexPolygonsIndices[i];
+ convexPolygonsIndices.splice(i, 1);
+ this.polygonIndicesPool.free(polygonIndices);
+ }
+ }
+ return convexPolygons;
+ };
+ Triangulator.isConcave = function (index, vertexCount, vertices, indices) {
+ var previous = indices[(vertexCount + index - 1) % vertexCount] << 1;
+ var current = indices[index] << 1;
+ var next = indices[(index + 1) % vertexCount] << 1;
+ return !this.positiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1], vertices[next], vertices[next + 1]);
+ };
+ Triangulator.positiveArea = function (p1x, p1y, p2x, p2y, p3x, p3y) {
+ return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0;
+ };
+ Triangulator.winding = function (p1x, p1y, p2x, p2y, p3x, p3y) {
+ var px = p2x - p1x, py = p2y - p1y;
+ return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1;
+ };
+ return Triangulator;
+ }());
+ spine.Triangulator = Triangulator;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var IntSet = (function () {
+ function IntSet() {
+ this.array = new Array();
+ }
+ IntSet.prototype.add = function (value) {
+ var contains = this.contains(value);
+ this.array[value | 0] = value | 0;
+ return !contains;
+ };
+ IntSet.prototype.contains = function (value) {
+ return this.array[value | 0] != undefined;
+ };
+ IntSet.prototype.remove = function (value) {
+ this.array[value | 0] = undefined;
+ };
+ IntSet.prototype.clear = function () {
+ this.array.length = 0;
+ };
+ return IntSet;
+ }());
+ spine.IntSet = IntSet;
+ var Color = (function () {
+ function Color(r, g, b, a) {
+ if (r === void 0) { r = 0; }
+ if (g === void 0) { g = 0; }
+ if (b === void 0) { b = 0; }
+ if (a === void 0) { a = 0; }
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ this.a = a;
+ }
+ Color.prototype.set = function (r, g, b, a) {
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ this.a = a;
+ this.clamp();
+ return this;
+ };
+ Color.prototype.setFromColor = function (c) {
+ this.r = c.r;
+ this.g = c.g;
+ this.b = c.b;
+ this.a = c.a;
+ return this;
+ };
+ Color.prototype.setFromString = function (hex) {
+ hex = hex.charAt(0) == '#' ? hex.substr(1) : hex;
+ this.r = parseInt(hex.substr(0, 2), 16) / 255.0;
+ this.g = parseInt(hex.substr(2, 2), 16) / 255.0;
+ this.b = parseInt(hex.substr(4, 2), 16) / 255.0;
+ this.a = (hex.length != 8 ? 255 : parseInt(hex.substr(6, 2), 16)) / 255.0;
+ return this;
+ };
+ Color.prototype.add = function (r, g, b, a) {
+ this.r += r;
+ this.g += g;
+ this.b += b;
+ this.a += a;
+ this.clamp();
+ return this;
+ };
+ Color.prototype.clamp = function () {
+ if (this.r < 0)
+ this.r = 0;
+ else if (this.r > 1)
+ this.r = 1;
+ if (this.g < 0)
+ this.g = 0;
+ else if (this.g > 1)
+ this.g = 1;
+ if (this.b < 0)
+ this.b = 0;
+ else if (this.b > 1)
+ this.b = 1;
+ if (this.a < 0)
+ this.a = 0;
+ else if (this.a > 1)
+ this.a = 1;
+ return this;
+ };
+ return Color;
+ }());
+ Color.WHITE = new Color(1, 1, 1, 1);
+ Color.RED = new Color(1, 0, 0, 1);
+ Color.GREEN = new Color(0, 1, 0, 1);
+ Color.BLUE = new Color(0, 0, 1, 1);
+ Color.MAGENTA = new Color(1, 0, 1, 1);
+ spine.Color = Color;
+ var MathUtils = (function () {
+ function MathUtils() {
+ }
+ MathUtils.clamp = function (value, min, max) {
+ if (value < min)
+ return min;
+ if (value > max)
+ return max;
+ return value;
+ };
+ MathUtils.cosDeg = function (degrees) {
+ return Math.cos(degrees * MathUtils.degRad);
+ };
+ MathUtils.sinDeg = function (degrees) {
+ return Math.sin(degrees * MathUtils.degRad);
+ };
+ MathUtils.signum = function (value) {
+ return value > 0 ? 1 : value < 0 ? -1 : 0;
+ };
+ MathUtils.toInt = function (x) {
+ return x > 0 ? Math.floor(x) : Math.ceil(x);
+ };
+ MathUtils.cbrt = function (x) {
+ var y = Math.pow(Math.abs(x), 1 / 3);
+ return x < 0 ? -y : y;
+ };
+ MathUtils.randomTriangular = function (min, max) {
+ return MathUtils.randomTriangularWith(min, max, (min + max) * 0.5);
+ };
+ MathUtils.randomTriangularWith = function (min, max, mode) {
+ var u = Math.random();
+ var d = max - min;
+ if (u <= (mode - min) / d)
+ return min + Math.sqrt(u * d * (mode - min));
+ return max - Math.sqrt((1 - u) * d * (max - mode));
+ };
+ return MathUtils;
+ }());
+ MathUtils.PI = 3.1415927;
+ MathUtils.PI2 = MathUtils.PI * 2;
+ MathUtils.radiansToDegrees = 180 / MathUtils.PI;
+ MathUtils.radDeg = MathUtils.radiansToDegrees;
+ MathUtils.degreesToRadians = MathUtils.PI / 180;
+ MathUtils.degRad = MathUtils.degreesToRadians;
+ spine.MathUtils = MathUtils;
+ var Interpolation = (function () {
+ function Interpolation() {
+ }
+ Interpolation.prototype.apply = function (start, end, a) {
+ return start + (end - start) * this.applyInternal(a);
+ };
+ return Interpolation;
+ }());
+ spine.Interpolation = Interpolation;
+ var Pow = (function (_super) {
+ __extends(Pow, _super);
+ function Pow(power) {
+ var _this = _super.call(this) || this;
+ _this.power = 2;
+ _this.power = power;
+ return _this;
+ }
+ Pow.prototype.applyInternal = function (a) {
+ if (a <= 0.5)
+ return Math.pow(a * 2, this.power) / 2;
+ return Math.pow((a - 1) * 2, this.power) / (this.power % 2 == 0 ? -2 : 2) + 1;
+ };
+ return Pow;
+ }(Interpolation));
+ spine.Pow = Pow;
+ var PowOut = (function (_super) {
+ __extends(PowOut, _super);
+ function PowOut(power) {
+ return _super.call(this, power) || this;
+ }
+ PowOut.prototype.applyInternal = function (a) {
+ return Math.pow(a - 1, this.power) * (this.power % 2 == 0 ? -1 : 1) + 1;
+ };
+ return PowOut;
+ }(Pow));
+ spine.PowOut = PowOut;
+ var Utils = (function () {
+ function Utils() {
+ }
+ Utils.arrayCopy = function (source, sourceStart, dest, destStart, numElements) {
+ for (var i = sourceStart, j = destStart; i < sourceStart + numElements; i++, j++) {
+ dest[j] = source[i];
+ }
+ };
+ Utils.setArraySize = function (array, size, value) {
+ if (value === void 0) { value = 0; }
+ var oldSize = array.length;
+ if (oldSize == size)
+ return array;
+ array.length = size;
+ if (oldSize < size) {
+ for (var i = oldSize; i < size; i++)
+ array[i] = value;
+ }
+ return array;
+ };
+ Utils.ensureArrayCapacity = function (array, size, value) {
+ if (value === void 0) { value = 0; }
+ if (array.length >= size)
+ return array;
+ return Utils.setArraySize(array, size, value);
+ };
+ Utils.newArray = function (size, defaultValue) {
+ var array = new Array(size);
+ for (var i = 0; i < size; i++)
+ array[i] = defaultValue;
+ return array;
+ };
+ Utils.newFloatArray = function (size) {
+ if (Utils.SUPPORTS_TYPED_ARRAYS) {
+ return new Float32Array(size);
+ }
+ else {
+ var array = new Array(size);
+ for (var i = 0; i < array.length; i++)
+ array[i] = 0;
+ return array;
+ }
+ };
+ Utils.newShortArray = function (size) {
+ if (Utils.SUPPORTS_TYPED_ARRAYS) {
+ return new Int16Array(size);
+ }
+ else {
+ var array = new Array(size);
+ for (var i = 0; i < array.length; i++)
+ array[i] = 0;
+ return array;
+ }
+ };
+ Utils.toFloatArray = function (array) {
+ return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array;
+ };
+ Utils.toSinglePrecision = function (value) {
+ return Utils.SUPPORTS_TYPED_ARRAYS ? Math.fround(value) : value;
+ };
+ return Utils;
+ }());
+ Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined";
+ spine.Utils = Utils;
+ var DebugUtils = (function () {
+ function DebugUtils() {
+ }
+ DebugUtils.logBones = function (skeleton) {
+ for (var i = 0; i < skeleton.bones.length; i++) {
+ var bone = skeleton.bones[i];
+ console.log(bone.data.name + ", " + bone.a + ", " + bone.b + ", " + bone.c + ", " + bone.d + ", " + bone.worldX + ", " + bone.worldY);
+ }
+ };
+ return DebugUtils;
+ }());
+ spine.DebugUtils = DebugUtils;
+ var Pool = (function () {
+ function Pool(instantiator) {
+ this.items = new Array();
+ this.instantiator = instantiator;
+ }
+ Pool.prototype.obtain = function () {
+ return this.items.length > 0 ? this.items.pop() : this.instantiator();
+ };
+ Pool.prototype.free = function (item) {
+ if (item.reset)
+ item.reset();
+ this.items.push(item);
+ };
+ Pool.prototype.freeAll = function (items) {
+ for (var i = 0; i < items.length; i++) {
+ if (items[i].reset)
+ items[i].reset();
+ this.items[i] = items[i];
+ }
+ };
+ Pool.prototype.clear = function () {
+ this.items.length = 0;
+ };
+ return Pool;
+ }());
+ spine.Pool = Pool;
+ var Vector2 = (function () {
+ function Vector2(x, y) {
+ if (x === void 0) { x = 0; }
+ if (y === void 0) { y = 0; }
+ this.x = x;
+ this.y = y;
+ }
+ Vector2.prototype.set = function (x, y) {
+ this.x = x;
+ this.y = y;
+ return this;
+ };
+ Vector2.prototype.length = function () {
+ var x = this.x;
+ var y = this.y;
+ return Math.sqrt(x * x + y * y);
+ };
+ Vector2.prototype.normalize = function () {
+ var len = this.length();
+ if (len != 0) {
+ this.x /= len;
+ this.y /= len;
+ }
+ return this;
+ };
+ return Vector2;
+ }());
+ spine.Vector2 = Vector2;
+ var TimeKeeper = (function () {
+ function TimeKeeper() {
+ this.maxDelta = 0.064;
+ this.framesPerSecond = 0;
+ this.delta = 0;
+ this.totalTime = 0;
+ this.lastTime = Date.now() / 1000;
+ this.frameCount = 0;
+ this.frameTime = 0;
+ }
+ TimeKeeper.prototype.update = function () {
+ var now = Date.now() / 1000;
+ this.delta = now - this.lastTime;
+ this.frameTime += this.delta;
+ this.totalTime += this.delta;
+ if (this.delta > this.maxDelta)
+ this.delta = this.maxDelta;
+ this.lastTime = now;
+ this.frameCount++;
+ if (this.frameTime > 1) {
+ this.framesPerSecond = this.frameCount / this.frameTime;
+ this.frameTime = 0;
+ this.frameCount = 0;
+ }
+ };
+ return TimeKeeper;
+ }());
+ spine.TimeKeeper = TimeKeeper;
+ var WindowedMean = (function () {
+ function WindowedMean(windowSize) {
+ if (windowSize === void 0) { windowSize = 32; }
+ this.addedValues = 0;
+ this.lastValue = 0;
+ this.mean = 0;
+ this.dirty = true;
+ this.values = new Array(windowSize);
+ }
+ WindowedMean.prototype.hasEnoughData = function () {
+ return this.addedValues >= this.values.length;
+ };
+ WindowedMean.prototype.addValue = function (value) {
+ if (this.addedValues < this.values.length)
+ this.addedValues++;
+ this.values[this.lastValue++] = value;
+ if (this.lastValue > this.values.length - 1)
+ this.lastValue = 0;
+ this.dirty = true;
+ };
+ WindowedMean.prototype.getMean = function () {
+ if (this.hasEnoughData()) {
+ if (this.dirty) {
+ var mean = 0;
+ for (var i = 0; i < this.values.length; i++) {
+ mean += this.values[i];
+ }
+ this.mean = mean / this.values.length;
+ this.dirty = false;
+ }
+ return this.mean;
+ }
+ else {
+ return 0;
+ }
+ };
+ return WindowedMean;
+ }());
+ spine.WindowedMean = WindowedMean;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var Attachment = (function () {
+ function Attachment(name) {
+ if (name == null)
+ throw new Error("name cannot be null.");
+ this.name = name;
+ }
+ return Attachment;
+ }());
+ spine.Attachment = Attachment;
+ var VertexAttachment = (function (_super) {
+ __extends(VertexAttachment, _super);
+ function VertexAttachment(name) {
+ var _this = _super.call(this, name) || this;
+ _this.id = (VertexAttachment.nextID++ & 65535) << 11;
+ _this.worldVerticesLength = 0;
+ return _this;
+ }
+ VertexAttachment.prototype.computeWorldVertices = function (slot, start, count, worldVertices, offset, stride) {
+ count = offset + (count >> 1) * stride;
+ var skeleton = slot.bone.skeleton;
+ var deformArray = slot.attachmentVertices;
+ var vertices = this.vertices;
+ var bones = this.bones;
+ if (bones == null) {
+ if (deformArray.length > 0)
+ vertices = deformArray;
+ var bone = slot.bone;
+ var x = bone.worldX;
+ var y = bone.worldY;
+ var a = bone.a, b = bone.b, c = bone.c, d = bone.d;
+ for (var v_1 = start, w = offset; w < count; v_1 += 2, w += stride) {
+ var vx = vertices[v_1], vy = vertices[v_1 + 1];
+ worldVertices[w] = vx * a + vy * b + x;
+ worldVertices[w + 1] = vx * c + vy * d + y;
+ }
+ return;
+ }
+ var v = 0, skip = 0;
+ for (var i = 0; i < start; i += 2) {
+ var n = bones[v];
+ v += n + 1;
+ skip += n;
+ }
+ var skeletonBones = skeleton.bones;
+ if (deformArray.length == 0) {
+ for (var w = offset, b = skip * 3; w < count; w += stride) {
+ var wx = 0, wy = 0;
+ var n = bones[v++];
+ n += v;
+ for (; v < n; v++, b += 3) {
+ var bone = skeletonBones[bones[v]];
+ var vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2];
+ wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
+ wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
+ }
+ worldVertices[w] = wx;
+ worldVertices[w + 1] = wy;
+ }
+ }
+ else {
+ var deform = deformArray;
+ for (var w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) {
+ var wx = 0, wy = 0;
+ var n = bones[v++];
+ n += v;
+ for (; v < n; v++, b += 3, f += 2) {
+ var bone = skeletonBones[bones[v]];
+ var vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2];
+ wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
+ wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
+ }
+ worldVertices[w] = wx;
+ worldVertices[w + 1] = wy;
+ }
+ }
+ };
+ VertexAttachment.prototype.applyDeform = function (sourceAttachment) {
+ return this == sourceAttachment;
+ };
+ return VertexAttachment;
+ }(Attachment));
+ VertexAttachment.nextID = 0;
+ spine.VertexAttachment = VertexAttachment;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var AttachmentType;
+ (function (AttachmentType) {
+ AttachmentType[AttachmentType["Region"] = 0] = "Region";
+ AttachmentType[AttachmentType["BoundingBox"] = 1] = "BoundingBox";
+ AttachmentType[AttachmentType["Mesh"] = 2] = "Mesh";
+ AttachmentType[AttachmentType["LinkedMesh"] = 3] = "LinkedMesh";
+ AttachmentType[AttachmentType["Path"] = 4] = "Path";
+ AttachmentType[AttachmentType["Point"] = 5] = "Point";
+ })(AttachmentType = spine.AttachmentType || (spine.AttachmentType = {}));
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var BoundingBoxAttachment = (function (_super) {
+ __extends(BoundingBoxAttachment, _super);
+ function BoundingBoxAttachment(name) {
+ var _this = _super.call(this, name) || this;
+ _this.color = new spine.Color(1, 1, 1, 1);
+ return _this;
+ }
+ return BoundingBoxAttachment;
+ }(spine.VertexAttachment));
+ spine.BoundingBoxAttachment = BoundingBoxAttachment;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var ClippingAttachment = (function (_super) {
+ __extends(ClippingAttachment, _super);
+ function ClippingAttachment(name) {
+ var _this = _super.call(this, name) || this;
+ _this.color = new spine.Color(0.2275, 0.2275, 0.8078, 1);
+ return _this;
+ }
+ return ClippingAttachment;
+ }(spine.VertexAttachment));
+ spine.ClippingAttachment = ClippingAttachment;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var MeshAttachment = (function (_super) {
+ __extends(MeshAttachment, _super);
+ function MeshAttachment(name) {
+ var _this = _super.call(this, name) || this;
+ _this.color = new spine.Color(1, 1, 1, 1);
+ _this.inheritDeform = false;
+ _this.tempColor = new spine.Color(0, 0, 0, 0);
+ return _this;
+ }
+ MeshAttachment.prototype.updateUVs = function () {
+ var u = 0, v = 0, width = 0, height = 0;
+ if (this.region == null) {
+ u = v = 0;
+ width = height = 1;
+ }
+ else {
+ u = this.region.u;
+ v = this.region.v;
+ width = this.region.u2 - u;
+ height = this.region.v2 - v;
+ }
+ var regionUVs = this.regionUVs;
+ if (this.uvs == null || this.uvs.length != regionUVs.length)
+ this.uvs = spine.Utils.newFloatArray(regionUVs.length);
+ var uvs = this.uvs;
+ if (this.region.rotate) {
+ for (var i = 0, n = uvs.length; i < n; i += 2) {
+ uvs[i] = u + regionUVs[i + 1] * width;
+ uvs[i + 1] = v + height - regionUVs[i] * height;
+ }
+ }
+ else {
+ for (var i = 0, n = uvs.length; i < n; i += 2) {
+ uvs[i] = u + regionUVs[i] * width;
+ uvs[i + 1] = v + regionUVs[i + 1] * height;
+ }
+ }
+ };
+ MeshAttachment.prototype.applyDeform = function (sourceAttachment) {
+ return this == sourceAttachment || (this.inheritDeform && this.parentMesh == sourceAttachment);
+ };
+ MeshAttachment.prototype.getParentMesh = function () {
+ return this.parentMesh;
+ };
+ MeshAttachment.prototype.setParentMesh = function (parentMesh) {
+ this.parentMesh = parentMesh;
+ if (parentMesh != null) {
+ this.bones = parentMesh.bones;
+ this.vertices = parentMesh.vertices;
+ this.worldVerticesLength = parentMesh.worldVerticesLength;
+ this.regionUVs = parentMesh.regionUVs;
+ this.triangles = parentMesh.triangles;
+ this.hullLength = parentMesh.hullLength;
+ this.worldVerticesLength = parentMesh.worldVerticesLength;
+ }
+ };
+ return MeshAttachment;
+ }(spine.VertexAttachment));
+ spine.MeshAttachment = MeshAttachment;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var PathAttachment = (function (_super) {
+ __extends(PathAttachment, _super);
+ function PathAttachment(name) {
+ var _this = _super.call(this, name) || this;
+ _this.closed = false;
+ _this.constantSpeed = false;
+ _this.color = new spine.Color(1, 1, 1, 1);
+ return _this;
+ }
+ return PathAttachment;
+ }(spine.VertexAttachment));
+ spine.PathAttachment = PathAttachment;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var PointAttachment = (function (_super) {
+ __extends(PointAttachment, _super);
+ function PointAttachment(name) {
+ var _this = _super.call(this, name) || this;
+ _this.color = new spine.Color(0.38, 0.94, 0, 1);
+ return _this;
+ }
+ PointAttachment.prototype.computeWorldPosition = function (bone, point) {
+ point.x = this.x * bone.a + this.y * bone.b + bone.worldX;
+ point.y = this.x * bone.c + this.y * bone.d + bone.worldY;
+ return point;
+ };
+ PointAttachment.prototype.computeWorldRotation = function (bone) {
+ var cos = spine.MathUtils.cosDeg(this.rotation), sin = spine.MathUtils.sinDeg(this.rotation);
+ var x = cos * bone.a + sin * bone.b;
+ var y = cos * bone.c + sin * bone.d;
+ return Math.atan2(y, x) * spine.MathUtils.radDeg;
+ };
+ return PointAttachment;
+ }(spine.VertexAttachment));
+ spine.PointAttachment = PointAttachment;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var RegionAttachment = (function (_super) {
+ __extends(RegionAttachment, _super);
+ function RegionAttachment(name) {
+ var _this = _super.call(this, name) || this;
+ _this.x = 0;
+ _this.y = 0;
+ _this.scaleX = 1;
+ _this.scaleY = 1;
+ _this.rotation = 0;
+ _this.width = 0;
+ _this.height = 0;
+ _this.color = new spine.Color(1, 1, 1, 1);
+ _this.offset = spine.Utils.newFloatArray(8);
+ _this.uvs = spine.Utils.newFloatArray(8);
+ _this.tempColor = new spine.Color(1, 1, 1, 1);
+ return _this;
+ }
+ RegionAttachment.prototype.updateOffset = function () {
+ var regionScaleX = this.width / this.region.originalWidth * this.scaleX;
+ var regionScaleY = this.height / this.region.originalHeight * this.scaleY;
+ var localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX;
+ var localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY;
+ var localX2 = localX + this.region.width * regionScaleX;
+ var localY2 = localY + this.region.height * regionScaleY;
+ var radians = this.rotation * Math.PI / 180;
+ var cos = Math.cos(radians);
+ var sin = Math.sin(radians);
+ var localXCos = localX * cos + this.x;
+ var localXSin = localX * sin;
+ var localYCos = localY * cos + this.y;
+ var localYSin = localY * sin;
+ var localX2Cos = localX2 * cos + this.x;
+ var localX2Sin = localX2 * sin;
+ var localY2Cos = localY2 * cos + this.y;
+ var localY2Sin = localY2 * sin;
+ var offset = this.offset;
+ offset[RegionAttachment.OX1] = localXCos - localYSin;
+ offset[RegionAttachment.OY1] = localYCos + localXSin;
+ offset[RegionAttachment.OX2] = localXCos - localY2Sin;
+ offset[RegionAttachment.OY2] = localY2Cos + localXSin;
+ offset[RegionAttachment.OX3] = localX2Cos - localY2Sin;
+ offset[RegionAttachment.OY3] = localY2Cos + localX2Sin;
+ offset[RegionAttachment.OX4] = localX2Cos - localYSin;
+ offset[RegionAttachment.OY4] = localYCos + localX2Sin;
+ };
+ RegionAttachment.prototype.setRegion = function (region) {
+ this.region = region;
+ var uvs = this.uvs;
+ if (region.rotate) {
+ uvs[2] = region.u;
+ uvs[3] = region.v2;
+ uvs[4] = region.u;
+ uvs[5] = region.v;
+ uvs[6] = region.u2;
+ uvs[7] = region.v;
+ uvs[0] = region.u2;
+ uvs[1] = region.v2;
+ }
+ else {
+ uvs[0] = region.u;
+ uvs[1] = region.v2;
+ uvs[2] = region.u;
+ uvs[3] = region.v;
+ uvs[4] = region.u2;
+ uvs[5] = region.v;
+ uvs[6] = region.u2;
+ uvs[7] = region.v2;
+ }
+ };
+ RegionAttachment.prototype.computeWorldVertices = function (bone, worldVertices, offset, stride) {
+ var vertexOffset = this.offset;
+ var x = bone.worldX, y = bone.worldY;
+ var a = bone.a, b = bone.b, c = bone.c, d = bone.d;
+ var offsetX = 0, offsetY = 0;
+ offsetX = vertexOffset[RegionAttachment.OX1];
+ offsetY = vertexOffset[RegionAttachment.OY1];
+ worldVertices[offset] = offsetX * a + offsetY * b + x;
+ worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
+ offset += stride;
+ offsetX = vertexOffset[RegionAttachment.OX2];
+ offsetY = vertexOffset[RegionAttachment.OY2];
+ worldVertices[offset] = offsetX * a + offsetY * b + x;
+ worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
+ offset += stride;
+ offsetX = vertexOffset[RegionAttachment.OX3];
+ offsetY = vertexOffset[RegionAttachment.OY3];
+ worldVertices[offset] = offsetX * a + offsetY * b + x;
+ worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
+ offset += stride;
+ offsetX = vertexOffset[RegionAttachment.OX4];
+ offsetY = vertexOffset[RegionAttachment.OY4];
+ worldVertices[offset] = offsetX * a + offsetY * b + x;
+ worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
+ };
+ return RegionAttachment;
+ }(spine.Attachment));
+ RegionAttachment.OX1 = 0;
+ RegionAttachment.OY1 = 1;
+ RegionAttachment.OX2 = 2;
+ RegionAttachment.OY2 = 3;
+ RegionAttachment.OX3 = 4;
+ RegionAttachment.OY3 = 5;
+ RegionAttachment.OX4 = 6;
+ RegionAttachment.OY4 = 7;
+ RegionAttachment.X1 = 0;
+ RegionAttachment.Y1 = 1;
+ RegionAttachment.C1R = 2;
+ RegionAttachment.C1G = 3;
+ RegionAttachment.C1B = 4;
+ RegionAttachment.C1A = 5;
+ RegionAttachment.U1 = 6;
+ RegionAttachment.V1 = 7;
+ RegionAttachment.X2 = 8;
+ RegionAttachment.Y2 = 9;
+ RegionAttachment.C2R = 10;
+ RegionAttachment.C2G = 11;
+ RegionAttachment.C2B = 12;
+ RegionAttachment.C2A = 13;
+ RegionAttachment.U2 = 14;
+ RegionAttachment.V2 = 15;
+ RegionAttachment.X3 = 16;
+ RegionAttachment.Y3 = 17;
+ RegionAttachment.C3R = 18;
+ RegionAttachment.C3G = 19;
+ RegionAttachment.C3B = 20;
+ RegionAttachment.C3A = 21;
+ RegionAttachment.U3 = 22;
+ RegionAttachment.V3 = 23;
+ RegionAttachment.X4 = 24;
+ RegionAttachment.Y4 = 25;
+ RegionAttachment.C4R = 26;
+ RegionAttachment.C4G = 27;
+ RegionAttachment.C4B = 28;
+ RegionAttachment.C4A = 29;
+ RegionAttachment.U4 = 30;
+ RegionAttachment.V4 = 31;
+ spine.RegionAttachment = RegionAttachment;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var JitterEffect = (function () {
+ function JitterEffect(jitterX, jitterY) {
+ this.jitterX = 0;
+ this.jitterY = 0;
+ this.jitterX = jitterX;
+ this.jitterY = jitterY;
+ }
+ JitterEffect.prototype.begin = function (skeleton) {
+ };
+ JitterEffect.prototype.transform = function (position, uv, light, dark) {
+ position.x += spine.MathUtils.randomTriangular(-this.jitterX, this.jitterY);
+ position.y += spine.MathUtils.randomTriangular(-this.jitterX, this.jitterY);
+ };
+ JitterEffect.prototype.end = function () {
+ };
+ return JitterEffect;
+ }());
+ spine.JitterEffect = JitterEffect;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var SwirlEffect = (function () {
+ function SwirlEffect(radius) {
+ this.centerX = 0;
+ this.centerY = 0;
+ this.radius = 0;
+ this.angle = 0;
+ this.worldX = 0;
+ this.worldY = 0;
+ this.radius = radius;
+ }
+ SwirlEffect.prototype.begin = function (skeleton) {
+ this.worldX = skeleton.x + this.centerX;
+ this.worldY = skeleton.y + this.centerY;
+ };
+ SwirlEffect.prototype.transform = function (position, uv, light, dark) {
+ var radAngle = this.angle * spine.MathUtils.degreesToRadians;
+ var x = position.x - this.worldX;
+ var y = position.y - this.worldY;
+ var dist = Math.sqrt(x * x + y * y);
+ if (dist < this.radius) {
+ var theta = SwirlEffect.interpolation.apply(0, radAngle, (this.radius - dist) / this.radius);
+ var cos = Math.cos(theta);
+ var sin = Math.sin(theta);
+ position.x = cos * x - sin * y + this.worldX;
+ position.y = sin * x + cos * y + this.worldY;
+ }
+ };
+ SwirlEffect.prototype.end = function () {
+ };
+ return SwirlEffect;
+ }());
+ SwirlEffect.interpolation = new spine.PowOut(2);
+ spine.SwirlEffect = SwirlEffect;
+})(spine || (spine = {}));
+
+var sp = sp || {};
+sp.spine = spine;
diff --git a/frameworks/cocos2d-html5/external/box2d/box2d.js b/frameworks/cocos2d-html5/external/box2d/box2d.js
new file mode 100644
index 0000000..2f9447d
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/box2d/box2d.js
@@ -0,0 +1,10882 @@
+/*
+ * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *
+ * Sean Lin 2012-5-8,
+ *
+ * The library is box2dweb, http://code.google.com/p/box2dweb/
+ *
+ * It is a port of Box2DFlash 2.1a to JavaScript.
+ * You can read the documentation for Box2dFlash, since nearly everything is
+ * organized the same way. http://www.box2dflash.org/docs/2.1a/reference/
+ *
+ */
+
+var Box2D = {};
+
+(function (a2j, undefined) {
+
+ if(!(Object.defineProperty instanceof Function)
+ && Object.prototype.__defineGetter__ instanceof Function
+ && Object.prototype.__defineSetter__ instanceof Function)
+ {
+ Object.defineProperty = function(obj, p, cfg) {
+ if(cfg.get instanceof Function)
+ obj.__defineGetter__(p, cfg.get);
+ if(cfg.set instanceof Function)
+ obj.__defineSetter__(p, cfg.set);
+ }
+ }
+
+ function emptyFn() {};
+ a2j.inherit = function(cls, base) {
+ var tmpCtr = cls;
+ emptyFn.prototype = base.prototype;
+ cls.prototype = new emptyFn;
+ cls.prototype.constructor = tmpCtr;
+ };
+
+ a2j.generateCallback = function generateCallback(context, cb) {
+ return function () {
+ cb.apply(context, arguments);
+ };
+ };
+
+ a2j.NVector = function NVector(length) {
+ if (length === undefined) length = 0;
+ var tmp = new Array(length || 0);
+ for (var i = 0; i < length; ++i)
+ tmp[i] = 0;
+ return tmp;
+ };
+
+ a2j.is = function is(o1, o2) {
+ if (o1 === null) return false;
+ if ((o2 instanceof Function) && (o1 instanceof o2)) return true;
+ if ((o1.constructor.__implements != undefined) && (o1.constructor.__implements[o2])) return true;
+ return false;
+ };
+
+ a2j.parseUInt = function(v) {
+ return Math.abs(parseInt(v));
+ }
+
+})(Box2D);
+
+//#TODO remove assignments from global namespace
+var Vector = Array;
+var Vector_a2j_Number = Box2D.NVector;
+//package structure
+if (typeof(Box2D) === "undefined") Box2D = {};
+if (typeof(Box2D.Collision) === "undefined") Box2D.Collision = {};
+if (typeof(Box2D.Collision.Shapes) === "undefined") Box2D.Collision.Shapes = {};
+if (typeof(Box2D.Common) === "undefined") Box2D.Common = {};
+if (typeof(Box2D.Common.Math) === "undefined") Box2D.Common.Math = {};
+if (typeof(Box2D.Dynamics) === "undefined") Box2D.Dynamics = {};
+if (typeof(Box2D.Dynamics.Contacts) === "undefined") Box2D.Dynamics.Contacts = {};
+if (typeof(Box2D.Dynamics.Controllers) === "undefined") Box2D.Dynamics.Controllers = {};
+if (typeof(Box2D.Dynamics.Joints) === "undefined") Box2D.Dynamics.Joints = {};
+//pre-definitions
+(function () {
+ Box2D.Collision.IBroadPhase = 'Box2D.Collision.IBroadPhase';
+
+ function b2AABB() {
+ b2AABB.b2AABB.apply(this, arguments);
+ };
+ Box2D.Collision.b2AABB = b2AABB;
+
+ function b2Bound() {
+ b2Bound.b2Bound.apply(this, arguments);
+ };
+ Box2D.Collision.b2Bound = b2Bound;
+
+ function b2BoundValues() {
+ b2BoundValues.b2BoundValues.apply(this, arguments);
+ if (this.constructor === b2BoundValues) this.b2BoundValues.apply(this, arguments);
+ };
+ Box2D.Collision.b2BoundValues = b2BoundValues;
+
+ function b2Collision() {
+ b2Collision.b2Collision.apply(this, arguments);
+ };
+ Box2D.Collision.b2Collision = b2Collision;
+
+ function b2ContactID() {
+ b2ContactID.b2ContactID.apply(this, arguments);
+ if (this.constructor === b2ContactID) this.b2ContactID.apply(this, arguments);
+ };
+ Box2D.Collision.b2ContactID = b2ContactID;
+
+ function b2ContactPoint() {
+ b2ContactPoint.b2ContactPoint.apply(this, arguments);
+ };
+ Box2D.Collision.b2ContactPoint = b2ContactPoint;
+
+ function b2Distance() {
+ b2Distance.b2Distance.apply(this, arguments);
+ };
+ Box2D.Collision.b2Distance = b2Distance;
+
+ function b2DistanceInput() {
+ b2DistanceInput.b2DistanceInput.apply(this, arguments);
+ };
+ Box2D.Collision.b2DistanceInput = b2DistanceInput;
+
+ function b2DistanceOutput() {
+ b2DistanceOutput.b2DistanceOutput.apply(this, arguments);
+ };
+ Box2D.Collision.b2DistanceOutput = b2DistanceOutput;
+
+ function b2DistanceProxy() {
+ b2DistanceProxy.b2DistanceProxy.apply(this, arguments);
+ };
+ Box2D.Collision.b2DistanceProxy = b2DistanceProxy;
+
+ function b2DynamicTree() {
+ b2DynamicTree.b2DynamicTree.apply(this, arguments);
+ if (this.constructor === b2DynamicTree) this.b2DynamicTree.apply(this, arguments);
+ };
+ Box2D.Collision.b2DynamicTree = b2DynamicTree;
+
+ function b2DynamicTreeBroadPhase() {
+ b2DynamicTreeBroadPhase.b2DynamicTreeBroadPhase.apply(this, arguments);
+ };
+ Box2D.Collision.b2DynamicTreeBroadPhase = b2DynamicTreeBroadPhase;
+
+ function b2DynamicTreeNode() {
+ b2DynamicTreeNode.b2DynamicTreeNode.apply(this, arguments);
+ };
+ Box2D.Collision.b2DynamicTreeNode = b2DynamicTreeNode;
+
+ function b2DynamicTreePair() {
+ b2DynamicTreePair.b2DynamicTreePair.apply(this, arguments);
+ };
+ Box2D.Collision.b2DynamicTreePair = b2DynamicTreePair;
+
+ function b2Manifold() {
+ b2Manifold.b2Manifold.apply(this, arguments);
+ if (this.constructor === b2Manifold) this.b2Manifold.apply(this, arguments);
+ };
+ Box2D.Collision.b2Manifold = b2Manifold;
+
+ function b2ManifoldPoint() {
+ b2ManifoldPoint.b2ManifoldPoint.apply(this, arguments);
+ if (this.constructor === b2ManifoldPoint) this.b2ManifoldPoint.apply(this, arguments);
+ };
+ Box2D.Collision.b2ManifoldPoint = b2ManifoldPoint;
+
+ function b2Point() {
+ b2Point.b2Point.apply(this, arguments);
+ };
+ Box2D.Collision.b2Point = b2Point;
+
+ function b2RayCastInput() {
+ b2RayCastInput.b2RayCastInput.apply(this, arguments);
+ if (this.constructor === b2RayCastInput) this.b2RayCastInput.apply(this, arguments);
+ };
+ Box2D.Collision.b2RayCastInput = b2RayCastInput;
+
+ function b2RayCastOutput() {
+ b2RayCastOutput.b2RayCastOutput.apply(this, arguments);
+ };
+ Box2D.Collision.b2RayCastOutput = b2RayCastOutput;
+
+ function b2Segment() {
+ b2Segment.b2Segment.apply(this, arguments);
+ };
+ Box2D.Collision.b2Segment = b2Segment;
+
+ function b2SeparationFunction() {
+ b2SeparationFunction.b2SeparationFunction.apply(this, arguments);
+ };
+ Box2D.Collision.b2SeparationFunction = b2SeparationFunction;
+
+ function b2Simplex() {
+ b2Simplex.b2Simplex.apply(this, arguments);
+ if (this.constructor === b2Simplex) this.b2Simplex.apply(this, arguments);
+ };
+ Box2D.Collision.b2Simplex = b2Simplex;
+
+ function b2SimplexCache() {
+ b2SimplexCache.b2SimplexCache.apply(this, arguments);
+ };
+ Box2D.Collision.b2SimplexCache = b2SimplexCache;
+
+ function b2SimplexVertex() {
+ b2SimplexVertex.b2SimplexVertex.apply(this, arguments);
+ };
+ Box2D.Collision.b2SimplexVertex = b2SimplexVertex;
+
+ function b2TimeOfImpact() {
+ b2TimeOfImpact.b2TimeOfImpact.apply(this, arguments);
+ };
+ Box2D.Collision.b2TimeOfImpact = b2TimeOfImpact;
+
+ function b2TOIInput() {
+ b2TOIInput.b2TOIInput.apply(this, arguments);
+ };
+ Box2D.Collision.b2TOIInput = b2TOIInput;
+
+ function b2WorldManifold() {
+ b2WorldManifold.b2WorldManifold.apply(this, arguments);
+ if (this.constructor === b2WorldManifold) this.b2WorldManifold.apply(this, arguments);
+ };
+ Box2D.Collision.b2WorldManifold = b2WorldManifold;
+
+ function ClipVertex() {
+ ClipVertex.ClipVertex.apply(this, arguments);
+ };
+ Box2D.Collision.ClipVertex = ClipVertex;
+
+ function Features() {
+ Features.Features.apply(this, arguments);
+ };
+ Box2D.Collision.Features = Features;
+
+ function b2CircleShape() {
+ b2CircleShape.b2CircleShape.apply(this, arguments);
+ if (this.constructor === b2CircleShape) this.b2CircleShape.apply(this, arguments);
+ };
+ Box2D.Collision.Shapes.b2CircleShape = b2CircleShape;
+
+ function b2EdgeChainDef() {
+ b2EdgeChainDef.b2EdgeChainDef.apply(this, arguments);
+ if (this.constructor === b2EdgeChainDef) this.b2EdgeChainDef.apply(this, arguments);
+ };
+ Box2D.Collision.Shapes.b2EdgeChainDef = b2EdgeChainDef;
+
+ function b2EdgeShape() {
+ b2EdgeShape.b2EdgeShape.apply(this, arguments);
+ if (this.constructor === b2EdgeShape) this.b2EdgeShape.apply(this, arguments);
+ };
+ Box2D.Collision.Shapes.b2EdgeShape = b2EdgeShape;
+
+ function b2MassData() {
+ b2MassData.b2MassData.apply(this, arguments);
+ };
+ Box2D.Collision.Shapes.b2MassData = b2MassData;
+
+ function b2PolygonShape() {
+ b2PolygonShape.b2PolygonShape.apply(this, arguments);
+ if (this.constructor === b2PolygonShape) this.b2PolygonShape.apply(this, arguments);
+ };
+ Box2D.Collision.Shapes.b2PolygonShape = b2PolygonShape;
+
+ function b2Shape() {
+ b2Shape.b2Shape.apply(this, arguments);
+ if (this.constructor === b2Shape) this.b2Shape.apply(this, arguments);
+ };
+ Box2D.Collision.Shapes.b2Shape = b2Shape;
+ Box2D.Common.b2internal = 'Box2D.Common.b2internal';
+
+ function b2Color() {
+ b2Color.b2Color.apply(this, arguments);
+ if (this.constructor === b2Color) this.b2Color.apply(this, arguments);
+ };
+ Box2D.Common.b2Color = b2Color;
+
+ function b2Settings() {
+ b2Settings.b2Settings.apply(this, arguments);
+ };
+ Box2D.Common.b2Settings = b2Settings;
+
+ function b2Mat22() {
+ b2Mat22.b2Mat22.apply(this, arguments);
+ if (this.constructor === b2Mat22) this.b2Mat22.apply(this, arguments);
+ };
+ Box2D.Common.Math.b2Mat22 = b2Mat22;
+
+ function b2Mat33() {
+ b2Mat33.b2Mat33.apply(this, arguments);
+ if (this.constructor === b2Mat33) this.b2Mat33.apply(this, arguments);
+ };
+ Box2D.Common.Math.b2Mat33 = b2Mat33;
+
+ function b2Math() {
+ b2Math.b2Math.apply(this, arguments);
+ };
+ Box2D.Common.Math.b2Math = b2Math;
+
+ function b2Sweep() {
+ b2Sweep.b2Sweep.apply(this, arguments);
+ };
+ Box2D.Common.Math.b2Sweep = b2Sweep;
+
+ function b2Transform() {
+ b2Transform.b2Transform.apply(this, arguments);
+ if (this.constructor === b2Transform) this.b2Transform.apply(this, arguments);
+ };
+ Box2D.Common.Math.b2Transform = b2Transform;
+
+ function b2Vec2() {
+ b2Vec2.b2Vec2.apply(this, arguments);
+ if (this.constructor === b2Vec2) this.b2Vec2.apply(this, arguments);
+ };
+ Box2D.Common.Math.b2Vec2 = b2Vec2;
+
+ function b2Vec3() {
+ b2Vec3.b2Vec3.apply(this, arguments);
+ if (this.constructor === b2Vec3) this.b2Vec3.apply(this, arguments);
+ };
+ Box2D.Common.Math.b2Vec3 = b2Vec3;
+
+ function b2Body() {
+ b2Body.b2Body.apply(this, arguments);
+ if (this.constructor === b2Body) this.b2Body.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2Body = b2Body;
+
+ function b2BodyDef() {
+ b2BodyDef.b2BodyDef.apply(this, arguments);
+ if (this.constructor === b2BodyDef) this.b2BodyDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2BodyDef = b2BodyDef;
+
+ function b2ContactFilter() {
+ b2ContactFilter.b2ContactFilter.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2ContactFilter = b2ContactFilter;
+
+ function b2ContactImpulse() {
+ b2ContactImpulse.b2ContactImpulse.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2ContactImpulse = b2ContactImpulse;
+
+ function b2ContactListener() {
+ b2ContactListener.b2ContactListener.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2ContactListener = b2ContactListener;
+
+ function b2ContactManager() {
+ b2ContactManager.b2ContactManager.apply(this, arguments);
+ if (this.constructor === b2ContactManager) this.b2ContactManager.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2ContactManager = b2ContactManager;
+
+ function b2DebugDraw() {
+ b2DebugDraw.b2DebugDraw.apply(this, arguments);
+ if (this.constructor === b2DebugDraw) this.b2DebugDraw.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2DebugDraw = b2DebugDraw;
+
+ function b2DestructionListener() {
+ b2DestructionListener.b2DestructionListener.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2DestructionListener = b2DestructionListener;
+
+ function b2FilterData() {
+ b2FilterData.b2FilterData.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2FilterData = b2FilterData;
+
+ function b2Fixture() {
+ b2Fixture.b2Fixture.apply(this, arguments);
+ if (this.constructor === b2Fixture) this.b2Fixture.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2Fixture = b2Fixture;
+
+ function b2FixtureDef() {
+ b2FixtureDef.b2FixtureDef.apply(this, arguments);
+ if (this.constructor === b2FixtureDef) this.b2FixtureDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2FixtureDef = b2FixtureDef;
+
+ function b2Island() {
+ b2Island.b2Island.apply(this, arguments);
+ if (this.constructor === b2Island) this.b2Island.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2Island = b2Island;
+
+ function b2TimeStep() {
+ b2TimeStep.b2TimeStep.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2TimeStep = b2TimeStep;
+
+ function b2World() {
+ b2World.b2World.apply(this, arguments);
+ if (this.constructor === b2World) this.b2World.apply(this, arguments);
+ };
+ Box2D.Dynamics.b2World = b2World;
+
+ function b2CircleContact() {
+ b2CircleContact.b2CircleContact.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2CircleContact = b2CircleContact;
+
+ function b2Contact() {
+ b2Contact.b2Contact.apply(this, arguments);
+ if (this.constructor === b2Contact) this.b2Contact.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2Contact = b2Contact;
+
+ function b2ContactConstraint() {
+ b2ContactConstraint.b2ContactConstraint.apply(this, arguments);
+ if (this.constructor === b2ContactConstraint) this.b2ContactConstraint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2ContactConstraint = b2ContactConstraint;
+
+ function b2ContactConstraintPoint() {
+ b2ContactConstraintPoint.b2ContactConstraintPoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2ContactConstraintPoint = b2ContactConstraintPoint;
+
+ function b2ContactEdge() {
+ b2ContactEdge.b2ContactEdge.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2ContactEdge = b2ContactEdge;
+
+ function b2ContactFactory() {
+ b2ContactFactory.b2ContactFactory.apply(this, arguments);
+ if (this.constructor === b2ContactFactory) this.b2ContactFactory.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2ContactFactory = b2ContactFactory;
+
+ function b2ContactRegister() {
+ b2ContactRegister.b2ContactRegister.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2ContactRegister = b2ContactRegister;
+
+ function b2ContactResult() {
+ b2ContactResult.b2ContactResult.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2ContactResult = b2ContactResult;
+
+ function b2ContactSolver() {
+ b2ContactSolver.b2ContactSolver.apply(this, arguments);
+ if (this.constructor === b2ContactSolver) this.b2ContactSolver.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2ContactSolver = b2ContactSolver;
+
+ function b2EdgeAndCircleContact() {
+ b2EdgeAndCircleContact.b2EdgeAndCircleContact.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2EdgeAndCircleContact = b2EdgeAndCircleContact;
+
+ function b2NullContact() {
+ b2NullContact.b2NullContact.apply(this, arguments);
+ if (this.constructor === b2NullContact) this.b2NullContact.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2NullContact = b2NullContact;
+
+ function b2PolyAndCircleContact() {
+ b2PolyAndCircleContact.b2PolyAndCircleContact.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2PolyAndCircleContact = b2PolyAndCircleContact;
+
+ function b2PolyAndEdgeContact() {
+ b2PolyAndEdgeContact.b2PolyAndEdgeContact.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2PolyAndEdgeContact = b2PolyAndEdgeContact;
+
+ function b2PolygonContact() {
+ b2PolygonContact.b2PolygonContact.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2PolygonContact = b2PolygonContact;
+
+ function b2PositionSolverManifold() {
+ b2PositionSolverManifold.b2PositionSolverManifold.apply(this, arguments);
+ if (this.constructor === b2PositionSolverManifold) this.b2PositionSolverManifold.apply(this, arguments);
+ };
+ Box2D.Dynamics.Contacts.b2PositionSolverManifold = b2PositionSolverManifold;
+
+ function b2BuoyancyController() {
+ b2BuoyancyController.b2BuoyancyController.apply(this, arguments);
+ };
+ Box2D.Dynamics.Controllers.b2BuoyancyController = b2BuoyancyController;
+
+ function b2ConstantAccelController() {
+ b2ConstantAccelController.b2ConstantAccelController.apply(this, arguments);
+ };
+ Box2D.Dynamics.Controllers.b2ConstantAccelController = b2ConstantAccelController;
+
+ function b2ConstantForceController() {
+ b2ConstantForceController.b2ConstantForceController.apply(this, arguments);
+ };
+ Box2D.Dynamics.Controllers.b2ConstantForceController = b2ConstantForceController;
+
+ function b2Controller() {
+ b2Controller.b2Controller.apply(this, arguments);
+ };
+ Box2D.Dynamics.Controllers.b2Controller = b2Controller;
+
+ function b2ControllerEdge() {
+ b2ControllerEdge.b2ControllerEdge.apply(this, arguments);
+ };
+ Box2D.Dynamics.Controllers.b2ControllerEdge = b2ControllerEdge;
+
+ function b2GravityController() {
+ b2GravityController.b2GravityController.apply(this, arguments);
+ };
+ Box2D.Dynamics.Controllers.b2GravityController = b2GravityController;
+
+ function b2TensorDampingController() {
+ b2TensorDampingController.b2TensorDampingController.apply(this, arguments);
+ };
+ Box2D.Dynamics.Controllers.b2TensorDampingController = b2TensorDampingController;
+
+ function b2DistanceJoint() {
+ b2DistanceJoint.b2DistanceJoint.apply(this, arguments);
+ if (this.constructor === b2DistanceJoint) this.b2DistanceJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2DistanceJoint = b2DistanceJoint;
+
+ function b2DistanceJointDef() {
+ b2DistanceJointDef.b2DistanceJointDef.apply(this, arguments);
+ if (this.constructor === b2DistanceJointDef) this.b2DistanceJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2DistanceJointDef = b2DistanceJointDef;
+
+ function b2FrictionJoint() {
+ b2FrictionJoint.b2FrictionJoint.apply(this, arguments);
+ if (this.constructor === b2FrictionJoint) this.b2FrictionJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2FrictionJoint = b2FrictionJoint;
+
+ function b2FrictionJointDef() {
+ b2FrictionJointDef.b2FrictionJointDef.apply(this, arguments);
+ if (this.constructor === b2FrictionJointDef) this.b2FrictionJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2FrictionJointDef = b2FrictionJointDef;
+
+ function b2GearJoint() {
+ b2GearJoint.b2GearJoint.apply(this, arguments);
+ if (this.constructor === b2GearJoint) this.b2GearJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2GearJoint = b2GearJoint;
+
+ function b2GearJointDef() {
+ b2GearJointDef.b2GearJointDef.apply(this, arguments);
+ if (this.constructor === b2GearJointDef) this.b2GearJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2GearJointDef = b2GearJointDef;
+
+ function b2Jacobian() {
+ b2Jacobian.b2Jacobian.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2Jacobian = b2Jacobian;
+
+ function b2Joint() {
+ b2Joint.b2Joint.apply(this, arguments);
+ if (this.constructor === b2Joint) this.b2Joint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2Joint = b2Joint;
+
+ function b2JointDef() {
+ b2JointDef.b2JointDef.apply(this, arguments);
+ if (this.constructor === b2JointDef) this.b2JointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2JointDef = b2JointDef;
+
+ function b2JointEdge() {
+ b2JointEdge.b2JointEdge.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2JointEdge = b2JointEdge;
+
+ function b2LineJoint() {
+ b2LineJoint.b2LineJoint.apply(this, arguments);
+ if (this.constructor === b2LineJoint) this.b2LineJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2LineJoint = b2LineJoint;
+
+ function b2LineJointDef() {
+ b2LineJointDef.b2LineJointDef.apply(this, arguments);
+ if (this.constructor === b2LineJointDef) this.b2LineJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2LineJointDef = b2LineJointDef;
+
+ function b2MouseJoint() {
+ b2MouseJoint.b2MouseJoint.apply(this, arguments);
+ if (this.constructor === b2MouseJoint) this.b2MouseJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2MouseJoint = b2MouseJoint;
+
+ function b2MouseJointDef() {
+ b2MouseJointDef.b2MouseJointDef.apply(this, arguments);
+ if (this.constructor === b2MouseJointDef) this.b2MouseJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2MouseJointDef = b2MouseJointDef;
+
+ function b2PrismaticJoint() {
+ b2PrismaticJoint.b2PrismaticJoint.apply(this, arguments);
+ if (this.constructor === b2PrismaticJoint) this.b2PrismaticJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2PrismaticJoint = b2PrismaticJoint;
+
+ function b2PrismaticJointDef() {
+ b2PrismaticJointDef.b2PrismaticJointDef.apply(this, arguments);
+ if (this.constructor === b2PrismaticJointDef) this.b2PrismaticJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2PrismaticJointDef = b2PrismaticJointDef;
+
+ function b2PulleyJoint() {
+ b2PulleyJoint.b2PulleyJoint.apply(this, arguments);
+ if (this.constructor === b2PulleyJoint) this.b2PulleyJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2PulleyJoint = b2PulleyJoint;
+
+ function b2PulleyJointDef() {
+ b2PulleyJointDef.b2PulleyJointDef.apply(this, arguments);
+ if (this.constructor === b2PulleyJointDef) this.b2PulleyJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2PulleyJointDef = b2PulleyJointDef;
+
+ function b2RevoluteJoint() {
+ b2RevoluteJoint.b2RevoluteJoint.apply(this, arguments);
+ if (this.constructor === b2RevoluteJoint) this.b2RevoluteJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2RevoluteJoint = b2RevoluteJoint;
+
+ function b2RevoluteJointDef() {
+ b2RevoluteJointDef.b2RevoluteJointDef.apply(this, arguments);
+ if (this.constructor === b2RevoluteJointDef) this.b2RevoluteJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2RevoluteJointDef = b2RevoluteJointDef;
+
+ function b2WeldJoint() {
+ b2WeldJoint.b2WeldJoint.apply(this, arguments);
+ if (this.constructor === b2WeldJoint) this.b2WeldJoint.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2WeldJoint = b2WeldJoint;
+
+ function b2WeldJointDef() {
+ b2WeldJointDef.b2WeldJointDef.apply(this, arguments);
+ if (this.constructor === b2WeldJointDef) this.b2WeldJointDef.apply(this, arguments);
+ };
+ Box2D.Dynamics.Joints.b2WeldJointDef = b2WeldJointDef;
+})(); //definitions
+Box2D.postDefs = [];
+(function () {
+ var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
+ b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef,
+ b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape,
+ b2MassData = Box2D.Collision.Shapes.b2MassData,
+ b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
+ b2Shape = Box2D.Collision.Shapes.b2Shape,
+ b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3,
+ b2AABB = Box2D.Collision.b2AABB,
+ b2Bound = Box2D.Collision.b2Bound,
+ b2BoundValues = Box2D.Collision.b2BoundValues,
+ b2Collision = Box2D.Collision.b2Collision,
+ b2ContactID = Box2D.Collision.b2ContactID,
+ b2ContactPoint = Box2D.Collision.b2ContactPoint,
+ b2Distance = Box2D.Collision.b2Distance,
+ b2DistanceInput = Box2D.Collision.b2DistanceInput,
+ b2DistanceOutput = Box2D.Collision.b2DistanceOutput,
+ b2DistanceProxy = Box2D.Collision.b2DistanceProxy,
+ b2DynamicTree = Box2D.Collision.b2DynamicTree,
+ b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase,
+ b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode,
+ b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair,
+ b2Manifold = Box2D.Collision.b2Manifold,
+ b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint,
+ b2Point = Box2D.Collision.b2Point,
+ b2RayCastInput = Box2D.Collision.b2RayCastInput,
+ b2RayCastOutput = Box2D.Collision.b2RayCastOutput,
+ b2Segment = Box2D.Collision.b2Segment,
+ b2SeparationFunction = Box2D.Collision.b2SeparationFunction,
+ b2Simplex = Box2D.Collision.b2Simplex,
+ b2SimplexCache = Box2D.Collision.b2SimplexCache,
+ b2SimplexVertex = Box2D.Collision.b2SimplexVertex,
+ b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact,
+ b2TOIInput = Box2D.Collision.b2TOIInput,
+ b2WorldManifold = Box2D.Collision.b2WorldManifold,
+ ClipVertex = Box2D.Collision.ClipVertex,
+ Features = Box2D.Collision.Features,
+ IBroadPhase = Box2D.Collision.IBroadPhase;
+
+ b2AABB.b2AABB = function () {
+ this.lowerBound = new b2Vec2();
+ this.upperBound = new b2Vec2();
+ };
+ b2AABB.prototype.IsValid = function () {
+ var dX = this.upperBound.x - this.lowerBound.x;
+ var dY = this.upperBound.y - this.lowerBound.y;
+ var valid = dX >= 0.0 && dY >= 0.0;
+ valid = valid && this.lowerBound.IsValid() && this.upperBound.IsValid();
+ return valid;
+ }
+ b2AABB.prototype.GetCenter = function () {
+ return new b2Vec2((this.lowerBound.x + this.upperBound.x) / 2, (this.lowerBound.y + this.upperBound.y) / 2);
+ }
+ b2AABB.prototype.GetExtents = function () {
+ return new b2Vec2((this.upperBound.x - this.lowerBound.x) / 2, (this.upperBound.y - this.lowerBound.y) / 2);
+ }
+ b2AABB.prototype.Contains = function (aabb) {
+ var result = true;
+ result = result && this.lowerBound.x <= aabb.lowerBound.x;
+ result = result && this.lowerBound.y <= aabb.lowerBound.y;
+ result = result && aabb.upperBound.x <= this.upperBound.x;
+ result = result && aabb.upperBound.y <= this.upperBound.y;
+ return result;
+ }
+ b2AABB.prototype.RayCast = function (output, input) {
+ var tmin = (-Number.MAX_VALUE);
+ var tmax = Number.MAX_VALUE;
+ var pX = input.p1.x;
+ var pY = input.p1.y;
+ var dX = input.p2.x - input.p1.x;
+ var dY = input.p2.y - input.p1.y;
+ var absDX = Math.abs(dX);
+ var absDY = Math.abs(dY);
+ var normal = output.normal;
+ var inv_d = 0;
+ var t1 = 0;
+ var t2 = 0;
+ var t3 = 0;
+ var s = 0; {
+ if (absDX < Number.MIN_VALUE) {
+ if (pX < this.lowerBound.x || this.upperBound.x < pX) return false;
+ }
+ else {
+ inv_d = 1.0 / dX;
+ t1 = (this.lowerBound.x - pX) * inv_d;
+ t2 = (this.upperBound.x - pX) * inv_d;
+ s = (-1.0);
+ if (t1 > t2) {
+ t3 = t1;
+ t1 = t2;
+ t2 = t3;
+ s = 1.0;
+ }
+ if (t1 > tmin) {
+ normal.x = s;
+ normal.y = 0;
+ tmin = t1;
+ }
+ tmax = Math.min(tmax, t2);
+ if (tmin > tmax) return false;
+ }
+ } {
+ if (absDY < Number.MIN_VALUE) {
+ if (pY < this.lowerBound.y || this.upperBound.y < pY) return false;
+ }
+ else {
+ inv_d = 1.0 / dY;
+ t1 = (this.lowerBound.y - pY) * inv_d;
+ t2 = (this.upperBound.y - pY) * inv_d;
+ s = (-1.0);
+ if (t1 > t2) {
+ t3 = t1;
+ t1 = t2;
+ t2 = t3;
+ s = 1.0;
+ }
+ if (t1 > tmin) {
+ normal.y = s;
+ normal.x = 0;
+ tmin = t1;
+ }
+ tmax = Math.min(tmax, t2);
+ if (tmin > tmax) return false;
+ }
+ }
+ output.fraction = tmin;
+ return true;
+ }
+ b2AABB.prototype.TestOverlap = function (other) {
+ var d1X = other.lowerBound.x - this.upperBound.x;
+ var d1Y = other.lowerBound.y - this.upperBound.y;
+ var d2X = this.lowerBound.x - other.upperBound.x;
+ var d2Y = this.lowerBound.y - other.upperBound.y;
+ if (d1X > 0.0 || d1Y > 0.0) return false;
+ if (d2X > 0.0 || d2Y > 0.0) return false;
+ return true;
+ }
+ b2AABB.Combine = function (aabb1, aabb2) {
+ var aabb = new b2AABB();
+ aabb.Combine(aabb1, aabb2);
+ return aabb;
+ }
+ b2AABB.prototype.Combine = function (aabb1, aabb2) {
+ this.lowerBound.x = Math.min(aabb1.lowerBound.x, aabb2.lowerBound.x);
+ this.lowerBound.y = Math.min(aabb1.lowerBound.y, aabb2.lowerBound.y);
+ this.upperBound.x = Math.max(aabb1.upperBound.x, aabb2.upperBound.x);
+ this.upperBound.y = Math.max(aabb1.upperBound.y, aabb2.upperBound.y);
+ }
+ b2Bound.b2Bound = function () {};
+ b2Bound.prototype.IsLower = function () {
+ return (this.value & 1) == 0;
+ }
+ b2Bound.prototype.IsUpper = function () {
+ return (this.value & 1) == 1;
+ }
+ b2Bound.prototype.Swap = function (b) {
+ var tempValue = this.value;
+ var tempProxy = this.proxy;
+ var tempStabbingCount = this.stabbingCount;
+ this.value = b.value;
+ this.proxy = b.proxy;
+ this.stabbingCount = b.stabbingCount;
+ b.value = tempValue;
+ b.proxy = tempProxy;
+ b.stabbingCount = tempStabbingCount;
+ }
+ b2BoundValues.b2BoundValues = function () {};
+ b2BoundValues.prototype.b2BoundValues = function () {
+ this.lowerValues = new Vector_a2j_Number();
+ this.lowerValues[0] = 0.0;
+ this.lowerValues[1] = 0.0;
+ this.upperValues = new Vector_a2j_Number();
+ this.upperValues[0] = 0.0;
+ this.upperValues[1] = 0.0;
+ }
+ b2Collision.b2Collision = function () {};
+ b2Collision.ClipSegmentToLine = function (vOut, vIn, normal, offset) {
+ if (offset === undefined) offset = 0;
+ var cv;
+ var numOut = 0;
+ cv = vIn[0];
+ var vIn0 = cv.v;
+ cv = vIn[1];
+ var vIn1 = cv.v;
+ var distance0 = normal.x * vIn0.x + normal.y * vIn0.y - offset;
+ var distance1 = normal.x * vIn1.x + normal.y * vIn1.y - offset;
+ if (distance0 <= 0.0) vOut[numOut++].Set(vIn[0]);
+ if (distance1 <= 0.0) vOut[numOut++].Set(vIn[1]);
+ if (distance0 * distance1 < 0.0) {
+ var interp = distance0 / (distance0 - distance1);
+ cv = vOut[numOut];
+ var tVec = cv.v;
+ tVec.x = vIn0.x + interp * (vIn1.x - vIn0.x);
+ tVec.y = vIn0.y + interp * (vIn1.y - vIn0.y);
+ cv = vOut[numOut];
+ var cv2;
+ if (distance0 > 0.0) {
+ cv2 = vIn[0];
+ cv.id = cv2.id;
+ }
+ else {
+ cv2 = vIn[1];
+ cv.id = cv2.id;
+ }++numOut;
+ }
+ return numOut;
+ }
+ b2Collision.EdgeSeparation = function (poly1, xf1, edge1, poly2, xf2) {
+ if (edge1 === undefined) edge1 = 0;
+ var count1 = parseInt(poly1.m_vertexCount);
+ var vertices1 = poly1.m_vertices;
+ var normals1 = poly1.m_normals;
+ var count2 = parseInt(poly2.m_vertexCount);
+ var vertices2 = poly2.m_vertices;
+ var tMat;
+ var tVec;
+ tMat = xf1.R;
+ tVec = normals1[edge1];
+ var normal1WorldX = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var normal1WorldY = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tMat = xf2.R;
+ var normal1X = (tMat.col1.x * normal1WorldX + tMat.col1.y * normal1WorldY);
+ var normal1Y = (tMat.col2.x * normal1WorldX + tMat.col2.y * normal1WorldY);
+ var index = 0;
+ var minDot = Number.MAX_VALUE;
+ for (var i = 0; i < count2; ++i) {
+ tVec = vertices2[i];
+ var dot = tVec.x * normal1X + tVec.y * normal1Y;
+ if (dot < minDot) {
+ minDot = dot;
+ index = i;
+ }
+ }
+ tVec = vertices1[edge1];
+ tMat = xf1.R;
+ var v1X = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var v1Y = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tVec = vertices2[index];
+ tMat = xf2.R;
+ var v2X = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var v2Y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ v2X -= v1X;
+ v2Y -= v1Y;
+ var separation = v2X * normal1WorldX + v2Y * normal1WorldY;
+ return separation;
+ }
+ b2Collision.FindMaxSeparation = function (edgeIndex, poly1, xf1, poly2, xf2) {
+ var count1 = parseInt(poly1.m_vertexCount);
+ var normals1 = poly1.m_normals;
+ var tVec;
+ var tMat;
+ tMat = xf2.R;
+ tVec = poly2.m_centroid;
+ var dX = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var dY = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tMat = xf1.R;
+ tVec = poly1.m_centroid;
+ dX -= xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ dY -= xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ var dLocal1X = (dX * xf1.R.col1.x + dY * xf1.R.col1.y);
+ var dLocal1Y = (dX * xf1.R.col2.x + dY * xf1.R.col2.y);
+ var edge = 0;
+ var maxDot = (-Number.MAX_VALUE);
+ for (var i = 0; i < count1; ++i) {
+ tVec = normals1[i];
+ var dot = (tVec.x * dLocal1X + tVec.y * dLocal1Y);
+ if (dot > maxDot) {
+ maxDot = dot;
+ edge = i;
+ }
+ }
+ var s = b2Collision.EdgeSeparation(poly1, xf1, edge, poly2, xf2);
+ var prevEdge = parseInt(edge - 1 >= 0 ? edge - 1 : count1 - 1);
+ var sPrev = b2Collision.EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2);
+ var nextEdge = parseInt(edge + 1 < count1 ? edge + 1 : 0);
+ var sNext = b2Collision.EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2);
+ var bestEdge = 0;
+ var bestSeparation = 0;
+ var increment = 0;
+ if (sPrev > s && sPrev > sNext) {
+ increment = (-1);
+ bestEdge = prevEdge;
+ bestSeparation = sPrev;
+ }
+ else if (sNext > s) {
+ increment = 1;
+ bestEdge = nextEdge;
+ bestSeparation = sNext;
+ }
+ else {
+ edgeIndex[0] = edge;
+ return s;
+ }
+ while (true) {
+ if (increment == (-1)) edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1;
+ else edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0;s = b2Collision.EdgeSeparation(poly1, xf1, edge, poly2, xf2);
+ if (s > bestSeparation) {
+ bestEdge = edge;
+ bestSeparation = s;
+ }
+ else {
+ break;
+ }
+ }
+ edgeIndex[0] = bestEdge;
+ return bestSeparation;
+ }
+ b2Collision.FindIncidentEdge = function (c, poly1, xf1, edge1, poly2, xf2) {
+ if (edge1 === undefined) edge1 = 0;
+ var count1 = parseInt(poly1.m_vertexCount);
+ var normals1 = poly1.m_normals;
+ var count2 = parseInt(poly2.m_vertexCount);
+ var vertices2 = poly2.m_vertices;
+ var normals2 = poly2.m_normals;
+ var tMat;
+ var tVec;
+ tMat = xf1.R;
+ tVec = normals1[edge1];
+ var normal1X = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var normal1Y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tMat = xf2.R;
+ var tX = (tMat.col1.x * normal1X + tMat.col1.y * normal1Y);
+ normal1Y = (tMat.col2.x * normal1X + tMat.col2.y * normal1Y);
+ normal1X = tX;
+ var index = 0;
+ var minDot = Number.MAX_VALUE;
+ for (var i = 0; i < count2; ++i) {
+ tVec = normals2[i];
+ var dot = (normal1X * tVec.x + normal1Y * tVec.y);
+ if (dot < minDot) {
+ minDot = dot;
+ index = i;
+ }
+ }
+ var tClip;
+ var i1 = parseInt(index);
+ var i2 = parseInt(i1 + 1 < count2 ? i1 + 1 : 0);
+ tClip = c[0];
+ tVec = vertices2[i1];
+ tMat = xf2.R;
+ tClip.v.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ tClip.v.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tClip.id.features.referenceEdge = edge1;
+ tClip.id.features.incidentEdge = i1;
+ tClip.id.features.incidentVertex = 0;
+ tClip = c[1];
+ tVec = vertices2[i2];
+ tMat = xf2.R;
+ tClip.v.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ tClip.v.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tClip.id.features.referenceEdge = edge1;
+ tClip.id.features.incidentEdge = i2;
+ tClip.id.features.incidentVertex = 1;
+ }
+ b2Collision.MakeClipPointVector = function () {
+ var r = new Vector(2);
+ r[0] = new ClipVertex();
+ r[1] = new ClipVertex();
+ return r;
+ }
+ b2Collision.CollidePolygons = function (manifold, polyA, xfA, polyB, xfB) {
+ var cv;
+ manifold.m_pointCount = 0;
+ var totalRadius = polyA.m_radius + polyB.m_radius;
+ var edgeA = 0;
+ b2Collision.s_edgeAO[0] = edgeA;
+ var separationA = b2Collision.FindMaxSeparation(b2Collision.s_edgeAO, polyA, xfA, polyB, xfB);
+ edgeA = b2Collision.s_edgeAO[0];
+ if (separationA > totalRadius) return;
+ var edgeB = 0;
+ b2Collision.s_edgeBO[0] = edgeB;
+ var separationB = b2Collision.FindMaxSeparation(b2Collision.s_edgeBO, polyB, xfB, polyA, xfA);
+ edgeB = b2Collision.s_edgeBO[0];
+ if (separationB > totalRadius) return;
+ var poly1;
+ var poly2;
+ var xf1;
+ var xf2;
+ var edge1 = 0;
+ var flip = 0;
+ var k_relativeTol = 0.98;
+ var k_absoluteTol = 0.001;
+ var tMat;
+ if (separationB > k_relativeTol * separationA + k_absoluteTol) {
+ poly1 = polyB;
+ poly2 = polyA;
+ xf1 = xfB;
+ xf2 = xfA;
+ edge1 = edgeB;
+ manifold.m_type = b2Manifold.e_faceB;
+ flip = 1;
+ }
+ else {
+ poly1 = polyA;
+ poly2 = polyB;
+ xf1 = xfA;
+ xf2 = xfB;
+ edge1 = edgeA;
+ manifold.m_type = b2Manifold.e_faceA;
+ flip = 0;
+ }
+ var incidentEdge = b2Collision.s_incidentEdge;
+ b2Collision.FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2);
+ var count1 = parseInt(poly1.m_vertexCount);
+ var vertices1 = poly1.m_vertices;
+ var local_v11 = vertices1[edge1];
+ var local_v12;
+ if (edge1 + 1 < count1) {
+ local_v12 = vertices1[parseInt(edge1 + 1)];
+ }
+ else {
+ local_v12 = vertices1[0];
+ }
+ var localTangent = b2Collision.s_localTangent;
+ localTangent.Set(local_v12.x - local_v11.x, local_v12.y - local_v11.y);
+ localTangent.Normalize();
+ var localNormal = b2Collision.s_localNormal;
+ localNormal.x = localTangent.y;
+ localNormal.y = (-localTangent.x);
+ var planePoint = b2Collision.s_planePoint;
+ planePoint.Set(0.5 * (local_v11.x + local_v12.x), 0.5 * (local_v11.y + local_v12.y));
+ var tangent = b2Collision.s_tangent;
+ tMat = xf1.R;
+ tangent.x = (tMat.col1.x * localTangent.x + tMat.col2.x * localTangent.y);
+ tangent.y = (tMat.col1.y * localTangent.x + tMat.col2.y * localTangent.y);
+ var tangent2 = b2Collision.s_tangent2;
+ tangent2.x = (-tangent.x);
+ tangent2.y = (-tangent.y);
+ var normal = b2Collision.s_normal;
+ normal.x = tangent.y;
+ normal.y = (-tangent.x);
+ var v11 = b2Collision.s_v11;
+ var v12 = b2Collision.s_v12;
+ v11.x = xf1.position.x + (tMat.col1.x * local_v11.x + tMat.col2.x * local_v11.y);
+ v11.y = xf1.position.y + (tMat.col1.y * local_v11.x + tMat.col2.y * local_v11.y);
+ v12.x = xf1.position.x + (tMat.col1.x * local_v12.x + tMat.col2.x * local_v12.y);
+ v12.y = xf1.position.y + (tMat.col1.y * local_v12.x + tMat.col2.y * local_v12.y);
+ var frontOffset = normal.x * v11.x + normal.y * v11.y;
+ var sideOffset1 = (-tangent.x * v11.x) - tangent.y * v11.y + totalRadius;
+ var sideOffset2 = tangent.x * v12.x + tangent.y * v12.y + totalRadius;
+ var clipPoints1 = b2Collision.s_clipPoints1;
+ var clipPoints2 = b2Collision.s_clipPoints2;
+ var np = 0;
+ np = b2Collision.ClipSegmentToLine(clipPoints1, incidentEdge, tangent2, sideOffset1);
+ if (np < 2) return;
+ np = b2Collision.ClipSegmentToLine(clipPoints2, clipPoints1, tangent, sideOffset2);
+ if (np < 2) return;
+ manifold.m_localPlaneNormal.SetV(localNormal);
+ manifold.m_localPoint.SetV(planePoint);
+ var pointCount = 0;
+ for (var i = 0; i < b2Settings.b2_maxManifoldPoints; ++i) {
+ cv = clipPoints2[i];
+ var separation = normal.x * cv.v.x + normal.y * cv.v.y - frontOffset;
+ if (separation <= totalRadius) {
+ var cp = manifold.m_points[pointCount];
+ tMat = xf2.R;
+ var tX = cv.v.x - xf2.position.x;
+ var tY = cv.v.y - xf2.position.y;
+ cp.m_localPoint.x = (tX * tMat.col1.x + tY * tMat.col1.y);
+ cp.m_localPoint.y = (tX * tMat.col2.x + tY * tMat.col2.y);
+ cp.m_id.Set(cv.id);
+ cp.m_id.features.flip = flip;
+ ++pointCount;
+ }
+ }
+ manifold.m_pointCount = pointCount;
+ }
+ b2Collision.CollideCircles = function (manifold, circle1, xf1, circle2, xf2) {
+ manifold.m_pointCount = 0;
+ var tMat;
+ var tVec;
+ tMat = xf1.R;
+ tVec = circle1.m_p;
+ var p1X = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var p1Y = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tMat = xf2.R;
+ tVec = circle2.m_p;
+ var p2X = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var p2Y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ var dX = p2X - p1X;
+ var dY = p2Y - p1Y;
+ var distSqr = dX * dX + dY * dY;
+ var radius = circle1.m_radius + circle2.m_radius;
+ if (distSqr > radius * radius) {
+ return;
+ }
+ manifold.m_type = b2Manifold.e_circles;
+ manifold.m_localPoint.SetV(circle1.m_p);
+ manifold.m_localPlaneNormal.SetZero();
+ manifold.m_pointCount = 1;
+ manifold.m_points[0].m_localPoint.SetV(circle2.m_p);
+ manifold.m_points[0].m_id.key = 0;
+ }
+ b2Collision.CollidePolygonAndCircle = function (manifold, polygon, xf1, circle, xf2) {
+ manifold.m_pointCount = 0;
+ var tPoint;
+ var dX = 0;
+ var dY = 0;
+ var positionX = 0;
+ var positionY = 0;
+ var tVec;
+ var tMat;
+ tMat = xf2.R;
+ tVec = circle.m_p;
+ var cX = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var cY = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ dX = cX - xf1.position.x;
+ dY = cY - xf1.position.y;
+ tMat = xf1.R;
+ var cLocalX = (dX * tMat.col1.x + dY * tMat.col1.y);
+ var cLocalY = (dX * tMat.col2.x + dY * tMat.col2.y);
+ var dist = 0;
+ var normalIndex = 0;
+ var separation = (-Number.MAX_VALUE);
+ var radius = polygon.m_radius + circle.m_radius;
+ var vertexCount = parseInt(polygon.m_vertexCount);
+ var vertices = polygon.m_vertices;
+ var normals = polygon.m_normals;
+ for (var i = 0; i < vertexCount; ++i) {
+ tVec = vertices[i];
+ dX = cLocalX - tVec.x;
+ dY = cLocalY - tVec.y;
+ tVec = normals[i];
+ var s = tVec.x * dX + tVec.y * dY;
+ if (s > radius) {
+ return;
+ }
+ if (s > separation) {
+ separation = s;
+ normalIndex = i;
+ }
+ }
+ var vertIndex1 = parseInt(normalIndex);
+ var vertIndex2 = parseInt(vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0);
+ var v1 = vertices[vertIndex1];
+ var v2 = vertices[vertIndex2];
+ if (separation < Number.MIN_VALUE) {
+ manifold.m_pointCount = 1;
+ manifold.m_type = b2Manifold.e_faceA;
+ manifold.m_localPlaneNormal.SetV(normals[normalIndex]);
+ manifold.m_localPoint.x = 0.5 * (v1.x + v2.x);
+ manifold.m_localPoint.y = 0.5 * (v1.y + v2.y);
+ manifold.m_points[0].m_localPoint.SetV(circle.m_p);
+ manifold.m_points[0].m_id.key = 0;
+ return;
+ }
+ var u1 = (cLocalX - v1.x) * (v2.x - v1.x) + (cLocalY - v1.y) * (v2.y - v1.y);
+ var u2 = (cLocalX - v2.x) * (v1.x - v2.x) + (cLocalY - v2.y) * (v1.y - v2.y);
+ if (u1 <= 0.0) {
+ if ((cLocalX - v1.x) * (cLocalX - v1.x) + (cLocalY - v1.y) * (cLocalY - v1.y) > radius * radius) return;
+ manifold.m_pointCount = 1;
+ manifold.m_type = b2Manifold.e_faceA;
+ manifold.m_localPlaneNormal.x = cLocalX - v1.x;
+ manifold.m_localPlaneNormal.y = cLocalY - v1.y;
+ manifold.m_localPlaneNormal.Normalize();
+ manifold.m_localPoint.SetV(v1);
+ manifold.m_points[0].m_localPoint.SetV(circle.m_p);
+ manifold.m_points[0].m_id.key = 0;
+ }
+ else if (u2 <= 0) {
+ if ((cLocalX - v2.x) * (cLocalX - v2.x) + (cLocalY - v2.y) * (cLocalY - v2.y) > radius * radius) return;
+ manifold.m_pointCount = 1;
+ manifold.m_type = b2Manifold.e_faceA;
+ manifold.m_localPlaneNormal.x = cLocalX - v2.x;
+ manifold.m_localPlaneNormal.y = cLocalY - v2.y;
+ manifold.m_localPlaneNormal.Normalize();
+ manifold.m_localPoint.SetV(v2);
+ manifold.m_points[0].m_localPoint.SetV(circle.m_p);
+ manifold.m_points[0].m_id.key = 0;
+ }
+ else {
+ var faceCenterX = 0.5 * (v1.x + v2.x);
+ var faceCenterY = 0.5 * (v1.y + v2.y);
+ separation = (cLocalX - faceCenterX) * normals[vertIndex1].x + (cLocalY - faceCenterY) * normals[vertIndex1].y;
+ if (separation > radius) return;
+ manifold.m_pointCount = 1;
+ manifold.m_type = b2Manifold.e_faceA;
+ manifold.m_localPlaneNormal.x = normals[vertIndex1].x;
+ manifold.m_localPlaneNormal.y = normals[vertIndex1].y;
+ manifold.m_localPlaneNormal.Normalize();
+ manifold.m_localPoint.Set(faceCenterX, faceCenterY);
+ manifold.m_points[0].m_localPoint.SetV(circle.m_p);
+ manifold.m_points[0].m_id.key = 0;
+ }
+ }
+ b2Collision.TestOverlap = function (a, b) {
+ var t1 = b.lowerBound;
+ var t2 = a.upperBound;
+ var d1X = t1.x - t2.x;
+ var d1Y = t1.y - t2.y;
+ t1 = a.lowerBound;
+ t2 = b.upperBound;
+ var d2X = t1.x - t2.x;
+ var d2Y = t1.y - t2.y;
+ if (d1X > 0.0 || d1Y > 0.0) return false;
+ if (d2X > 0.0 || d2Y > 0.0) return false;
+ return true;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Collision.b2Collision.s_incidentEdge = b2Collision.MakeClipPointVector();
+ Box2D.Collision.b2Collision.s_clipPoints1 = b2Collision.MakeClipPointVector();
+ Box2D.Collision.b2Collision.s_clipPoints2 = b2Collision.MakeClipPointVector();
+ Box2D.Collision.b2Collision.s_edgeAO = new Vector_a2j_Number(1);
+ Box2D.Collision.b2Collision.s_edgeBO = new Vector_a2j_Number(1);
+ Box2D.Collision.b2Collision.s_localTangent = new b2Vec2();
+ Box2D.Collision.b2Collision.s_localNormal = new b2Vec2();
+ Box2D.Collision.b2Collision.s_planePoint = new b2Vec2();
+ Box2D.Collision.b2Collision.s_normal = new b2Vec2();
+ Box2D.Collision.b2Collision.s_tangent = new b2Vec2();
+ Box2D.Collision.b2Collision.s_tangent2 = new b2Vec2();
+ Box2D.Collision.b2Collision.s_v11 = new b2Vec2();
+ Box2D.Collision.b2Collision.s_v12 = new b2Vec2();
+ Box2D.Collision.b2Collision.b2CollidePolyTempVec = new b2Vec2();
+ Box2D.Collision.b2Collision.b2_nullFeature = 0x000000ff;
+ });
+ b2ContactID.b2ContactID = function () {
+ this.features = new Features();
+ };
+ b2ContactID.prototype.b2ContactID = function () {
+ this.features._m_id = this;
+ }
+ b2ContactID.prototype.Set = function (id) {
+ this.key = id._key;
+ }
+ b2ContactID.prototype.Copy = function () {
+ var id = new b2ContactID();
+ id.key = this.key;
+ return id;
+ }
+ Object.defineProperty(b2ContactID.prototype, 'key', {
+ enumerable: false,
+ configurable: true,
+ get: function () {
+ return this._key;
+ }
+ });
+ Object.defineProperty(b2ContactID.prototype, 'key', {
+ enumerable: false,
+ configurable: true,
+ set: function (value) {
+ if (value === undefined) value = 0;
+ this._key = value;
+ this.features._referenceEdge = this._key & 0x000000ff;
+ this.features._incidentEdge = ((this._key & 0x0000ff00) >> 8) & 0x000000ff;
+ this.features._incidentVertex = ((this._key & 0x00ff0000) >> 16) & 0x000000ff;
+ this.features._flip = ((this._key & 0xff000000) >> 24) & 0x000000ff;
+ }
+ });
+ b2ContactPoint.b2ContactPoint = function () {
+ this.position = new b2Vec2();
+ this.velocity = new b2Vec2();
+ this.normal = new b2Vec2();
+ this.id = new b2ContactID();
+ };
+ b2Distance.b2Distance = function () {};
+ b2Distance.Distance = function (output, cache, input) {
+ ++b2Distance.b2_gjkCalls;
+ var proxyA = input.proxyA;
+ var proxyB = input.proxyB;
+ var transformA = input.transformA;
+ var transformB = input.transformB;
+ var simplex = b2Distance.s_simplex;
+ simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB);
+ var vertices = simplex.m_vertices;
+ var k_maxIters = 20;
+ var saveA = b2Distance.s_saveA;
+ var saveB = b2Distance.s_saveB;
+ var saveCount = 0;
+ var closestPoint = simplex.GetClosestPoint();
+ var distanceSqr1 = closestPoint.LengthSquared();
+ var distanceSqr2 = distanceSqr1;
+ var i = 0;
+ var p;
+ var iter = 0;
+ while (iter < k_maxIters) {
+ saveCount = simplex.m_count;
+ for (i = 0;
+ i < saveCount; i++) {
+ saveA[i] = vertices[i].indexA;
+ saveB[i] = vertices[i].indexB;
+ }
+ switch (simplex.m_count) {
+ case 1:
+ break;
+ case 2:
+ simplex.Solve2();
+ break;
+ case 3:
+ simplex.Solve3();
+ break;
+ default:
+ b2Settings.b2Assert(false);
+ }
+ if (simplex.m_count == 3) {
+ break;
+ }
+ p = simplex.GetClosestPoint();
+ distanceSqr2 = p.LengthSquared();
+ if (distanceSqr2 > distanceSqr1) {}
+ distanceSqr1 = distanceSqr2;
+ var d = simplex.GetSearchDirection();
+ if (d.LengthSquared() < Number.MIN_VALUE * Number.MIN_VALUE) {
+ break;
+ }
+ var vertex = vertices[simplex.m_count];
+ vertex.indexA = proxyA.GetSupport(b2Math.MulTMV(transformA.R, d.GetNegative()));
+ vertex.wA = b2Math.MulX(transformA, proxyA.GetVertex(vertex.indexA));
+ vertex.indexB = proxyB.GetSupport(b2Math.MulTMV(transformB.R, d));
+ vertex.wB = b2Math.MulX(transformB, proxyB.GetVertex(vertex.indexB));
+ vertex.w = b2Math.SubtractVV(vertex.wB, vertex.wA);
+ ++iter;
+ ++b2Distance.b2_gjkIters;
+ var duplicate = false;
+ for (i = 0;
+ i < saveCount; i++) {
+ if (vertex.indexA == saveA[i] && vertex.indexB == saveB[i]) {
+ duplicate = true;
+ break;
+ }
+ }
+ if (duplicate) {
+ break;
+ }++simplex.m_count;
+ }
+ b2Distance.b2_gjkMaxIters = b2Math.Max(b2Distance.b2_gjkMaxIters, iter);
+ simplex.GetWitnessPoints(output.pointA, output.pointB);
+ output.distance = b2Math.SubtractVV(output.pointA, output.pointB).Length();
+ output.iterations = iter;
+ simplex.WriteCache(cache);
+ if (input.useRadii) {
+ var rA = proxyA.m_radius;
+ var rB = proxyB.m_radius;
+ if (output.distance > rA + rB && output.distance > Number.MIN_VALUE) {
+ output.distance -= rA + rB;
+ var normal = b2Math.SubtractVV(output.pointB, output.pointA);
+ normal.Normalize();
+ output.pointA.x += rA * normal.x;
+ output.pointA.y += rA * normal.y;
+ output.pointB.x -= rB * normal.x;
+ output.pointB.y -= rB * normal.y;
+ }
+ else {
+ p = new b2Vec2();
+ p.x = .5 * (output.pointA.x + output.pointB.x);
+ p.y = .5 * (output.pointA.y + output.pointB.y);
+ output.pointA.x = output.pointB.x = p.x;
+ output.pointA.y = output.pointB.y = p.y;
+ output.distance = 0.0;
+ }
+ }
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Collision.b2Distance.s_simplex = new b2Simplex();
+ Box2D.Collision.b2Distance.s_saveA = new Vector_a2j_Number(3);
+ Box2D.Collision.b2Distance.s_saveB = new Vector_a2j_Number(3);
+ });
+ b2DistanceInput.b2DistanceInput = function () {};
+ b2DistanceOutput.b2DistanceOutput = function () {
+ this.pointA = new b2Vec2();
+ this.pointB = new b2Vec2();
+ };
+ b2DistanceProxy.b2DistanceProxy = function () {};
+ b2DistanceProxy.prototype.Set = function (shape) {
+ switch (shape.GetType()) {
+ case b2Shape.e_circleShape:
+ {
+ var circle = (shape instanceof b2CircleShape ? shape : null);
+ this.m_vertices = new Vector(1, true);
+ this.m_vertices[0] = circle.m_p;
+ this.m_count = 1;
+ this.m_radius = circle.m_radius;
+ }
+ break;
+ case b2Shape.e_polygonShape:
+ {
+ var polygon = (shape instanceof b2PolygonShape ? shape : null);
+ this.m_vertices = polygon.m_vertices;
+ this.m_count = polygon.m_vertexCount;
+ this.m_radius = polygon.m_radius;
+ }
+ break;
+ default:
+ b2Settings.b2Assert(false);
+ }
+ }
+ b2DistanceProxy.prototype.GetSupport = function (d) {
+ var bestIndex = 0;
+ var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y;
+ for (var i = 1; i < this.m_count; ++i) {
+ var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y;
+ if (value > bestValue) {
+ bestIndex = i;
+ bestValue = value;
+ }
+ }
+ return bestIndex;
+ }
+ b2DistanceProxy.prototype.GetSupportVertex = function (d) {
+ var bestIndex = 0;
+ var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y;
+ for (var i = 1; i < this.m_count; ++i) {
+ var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y;
+ if (value > bestValue) {
+ bestIndex = i;
+ bestValue = value;
+ }
+ }
+ return this.m_vertices[bestIndex];
+ }
+ b2DistanceProxy.prototype.GetVertexCount = function () {
+ return this.m_count;
+ }
+ b2DistanceProxy.prototype.GetVertex = function (index) {
+ if (index === undefined) index = 0;
+ b2Settings.b2Assert(0 <= index && index < this.m_count);
+ return this.m_vertices[index];
+ }
+ b2DynamicTree.b2DynamicTree = function () {};
+ b2DynamicTree.prototype.b2DynamicTree = function () {
+ this.m_root = null;
+ this.m_freeList = null;
+ this.m_path = 0;
+ this.m_insertionCount = 0;
+ }
+ b2DynamicTree.prototype.CreateProxy = function (aabb, userData) {
+ var node = this.AllocateNode();
+ var extendX = b2Settings.b2_aabbExtension;
+ var extendY = b2Settings.b2_aabbExtension;
+ node.aabb.lowerBound.x = aabb.lowerBound.x - extendX;
+ node.aabb.lowerBound.y = aabb.lowerBound.y - extendY;
+ node.aabb.upperBound.x = aabb.upperBound.x + extendX;
+ node.aabb.upperBound.y = aabb.upperBound.y + extendY;
+ node.userData = userData;
+ this.InsertLeaf(node);
+ return node;
+ }
+ b2DynamicTree.prototype.DestroyProxy = function (proxy) {
+ this.RemoveLeaf(proxy);
+ this.FreeNode(proxy);
+ }
+ b2DynamicTree.prototype.MoveProxy = function (proxy, aabb, displacement) {
+ b2Settings.b2Assert(proxy.IsLeaf());
+ if (proxy.aabb.Contains(aabb)) {
+ return false;
+ }
+ this.RemoveLeaf(proxy);
+ var extendX = b2Settings.b2_aabbExtension + b2Settings.b2_aabbMultiplier * (displacement.x > 0 ? displacement.x : (-displacement.x));
+ var extendY = b2Settings.b2_aabbExtension + b2Settings.b2_aabbMultiplier * (displacement.y > 0 ? displacement.y : (-displacement.y));
+ proxy.aabb.lowerBound.x = aabb.lowerBound.x - extendX;
+ proxy.aabb.lowerBound.y = aabb.lowerBound.y - extendY;
+ proxy.aabb.upperBound.x = aabb.upperBound.x + extendX;
+ proxy.aabb.upperBound.y = aabb.upperBound.y + extendY;
+ this.InsertLeaf(proxy);
+ return true;
+ }
+ b2DynamicTree.prototype.Rebalance = function (iterations) {
+ if (iterations === undefined) iterations = 0;
+ if (this.m_root == null) return;
+ for (var i = 0; i < iterations; i++) {
+ var node = this.m_root;
+ var bit = 0;
+ while (node.IsLeaf() == false) {
+ node = (this.m_path >> bit) & 1 ? node.child2 : node.child1;
+ bit = (bit + 1) & 31;
+ }++this.m_path;
+ this.RemoveLeaf(node);
+ this.InsertLeaf(node);
+ }
+ }
+ b2DynamicTree.prototype.GetFatAABB = function (proxy) {
+ return proxy.aabb;
+ }
+ b2DynamicTree.prototype.GetUserData = function (proxy) {
+ return proxy.userData;
+ }
+ b2DynamicTree.prototype.Query = function (callback, aabb) {
+ if (this.m_root == null) return;
+ var stack = new Vector();
+ var count = 0;
+ stack[count++] = this.m_root;
+ while (count > 0) {
+ var node = stack[--count];
+ if (node.aabb.TestOverlap(aabb)) {
+ if (node.IsLeaf()) {
+ var proceed = callback(node);
+ if (!proceed) return;
+ }
+ else {
+ stack[count++] = node.child1;
+ stack[count++] = node.child2;
+ }
+ }
+ }
+ }
+ b2DynamicTree.prototype.RayCast = function (callback, input) {
+ if (this.m_root == null) return;
+ var p1 = input.p1;
+ var p2 = input.p2;
+ var r = b2Math.SubtractVV(p1, p2);
+ r.Normalize();
+ var v = b2Math.CrossFV(1.0, r);
+ var abs_v = b2Math.AbsV(v);
+ var maxFraction = input.maxFraction;
+ var segmentAABB = new b2AABB();
+ var tX = 0;
+ var tY = 0; {
+ tX = p1.x + maxFraction * (p2.x - p1.x);
+ tY = p1.y + maxFraction * (p2.y - p1.y);
+ segmentAABB.lowerBound.x = Math.min(p1.x, tX);
+ segmentAABB.lowerBound.y = Math.min(p1.y, tY);
+ segmentAABB.upperBound.x = Math.max(p1.x, tX);
+ segmentAABB.upperBound.y = Math.max(p1.y, tY);
+ }
+ var stack = new Vector();
+ var count = 0;
+ stack[count++] = this.m_root;
+ while (count > 0) {
+ var node = stack[--count];
+ if (node.aabb.TestOverlap(segmentAABB) == false) {
+ continue;
+ }
+ var c = node.aabb.GetCenter();
+ var h = node.aabb.GetExtents();
+ var separation = Math.abs(v.x * (p1.x - c.x) + v.y * (p1.y - c.y)) - abs_v.x * h.x - abs_v.y * h.y;
+ if (separation > 0.0) continue;
+ if (node.IsLeaf()) {
+ var subInput = new b2RayCastInput();
+ subInput.p1 = input.p1;
+ subInput.p2 = input.p2;
+ subInput.maxFraction = input.maxFraction;
+ maxFraction = callback(subInput, node);
+ if (maxFraction == 0.0) return;
+ if (maxFraction > 0.0) {
+ tX = p1.x + maxFraction * (p2.x - p1.x);
+ tY = p1.y + maxFraction * (p2.y - p1.y);
+ segmentAABB.lowerBound.x = Math.min(p1.x, tX);
+ segmentAABB.lowerBound.y = Math.min(p1.y, tY);
+ segmentAABB.upperBound.x = Math.max(p1.x, tX);
+ segmentAABB.upperBound.y = Math.max(p1.y, tY);
+ }
+ }
+ else {
+ stack[count++] = node.child1;
+ stack[count++] = node.child2;
+ }
+ }
+ }
+ b2DynamicTree.prototype.AllocateNode = function () {
+ if (this.m_freeList) {
+ var node = this.m_freeList;
+ this.m_freeList = node.parent;
+ node.parent = null;
+ node.child1 = null;
+ node.child2 = null;
+ return node;
+ }
+ return new b2DynamicTreeNode();
+ }
+ b2DynamicTree.prototype.FreeNode = function (node) {
+ node.parent = this.m_freeList;
+ this.m_freeList = node;
+ }
+ b2DynamicTree.prototype.InsertLeaf = function (leaf) {
+ ++this.m_insertionCount;
+ if (this.m_root == null) {
+ this.m_root = leaf;
+ this.m_root.parent = null;
+ return;
+ }
+ var center = leaf.aabb.GetCenter();
+ var sibling = this.m_root;
+ if (sibling.IsLeaf() == false) {
+ do {
+ var child1 = sibling.child1;
+ var child2 = sibling.child2;
+ var norm1 = Math.abs((child1.aabb.lowerBound.x + child1.aabb.upperBound.x) / 2 - center.x) + Math.abs((child1.aabb.lowerBound.y + child1.aabb.upperBound.y) / 2 - center.y);
+ var norm2 = Math.abs((child2.aabb.lowerBound.x + child2.aabb.upperBound.x) / 2 - center.x) + Math.abs((child2.aabb.lowerBound.y + child2.aabb.upperBound.y) / 2 - center.y);
+ if (norm1 < norm2) {
+ sibling = child1;
+ }
+ else {
+ sibling = child2;
+ }
+ }
+ while (sibling.IsLeaf() == false)
+ }
+ var node1 = sibling.parent;
+ var node2 = this.AllocateNode();
+ node2.parent = node1;
+ node2.userData = null;
+ node2.aabb.Combine(leaf.aabb, sibling.aabb);
+ if (node1) {
+ if (sibling.parent.child1 == sibling) {
+ node1.child1 = node2;
+ }
+ else {
+ node1.child2 = node2;
+ }
+ node2.child1 = sibling;
+ node2.child2 = leaf;
+ sibling.parent = node2;
+ leaf.parent = node2;
+ do {
+ if (node1.aabb.Contains(node2.aabb)) break;
+ node1.aabb.Combine(node1.child1.aabb, node1.child2.aabb);
+ node2 = node1;
+ node1 = node1.parent;
+ }
+ while (node1)
+ }
+ else {
+ node2.child1 = sibling;
+ node2.child2 = leaf;
+ sibling.parent = node2;
+ leaf.parent = node2;
+ this.m_root = node2;
+ }
+ }
+ b2DynamicTree.prototype.RemoveLeaf = function (leaf) {
+ if (leaf == this.m_root) {
+ this.m_root = null;
+ return;
+ }
+ var node2 = leaf.parent;
+ var node1 = node2.parent;
+ var sibling;
+ if (node2.child1 == leaf) {
+ sibling = node2.child2;
+ }
+ else {
+ sibling = node2.child1;
+ }
+ if (node1) {
+ if (node1.child1 == node2) {
+ node1.child1 = sibling;
+ }
+ else {
+ node1.child2 = sibling;
+ }
+ sibling.parent = node1;
+ this.FreeNode(node2);
+ while (node1) {
+ var oldAABB = node1.aabb;
+ node1.aabb = b2AABB.Combine(node1.child1.aabb, node1.child2.aabb);
+ if (oldAABB.Contains(node1.aabb)) break;
+ node1 = node1.parent;
+ }
+ }
+ else {
+ this.m_root = sibling;
+ sibling.parent = null;
+ this.FreeNode(node2);
+ }
+ }
+ b2DynamicTreeBroadPhase.b2DynamicTreeBroadPhase = function () {
+ this.m_tree = new b2DynamicTree();
+ this.m_moveBuffer = new Vector();
+ this.m_pairBuffer = new Vector();
+ this.m_pairCount = 0;
+ };
+ b2DynamicTreeBroadPhase.prototype.CreateProxy = function (aabb, userData) {
+ var proxy = this.m_tree.CreateProxy(aabb, userData);
+ ++this.m_proxyCount;
+ this.BufferMove(proxy);
+ return proxy;
+ }
+ b2DynamicTreeBroadPhase.prototype.DestroyProxy = function (proxy) {
+ this.UnBufferMove(proxy);
+ --this.m_proxyCount;
+ this.m_tree.DestroyProxy(proxy);
+ }
+ b2DynamicTreeBroadPhase.prototype.MoveProxy = function (proxy, aabb, displacement) {
+ var buffer = this.m_tree.MoveProxy(proxy, aabb, displacement);
+ if (buffer) {
+ this.BufferMove(proxy);
+ }
+ }
+ b2DynamicTreeBroadPhase.prototype.TestOverlap = function (proxyA, proxyB) {
+ var aabbA = this.m_tree.GetFatAABB(proxyA);
+ var aabbB = this.m_tree.GetFatAABB(proxyB);
+ return aabbA.TestOverlap(aabbB);
+ }
+ b2DynamicTreeBroadPhase.prototype.GetUserData = function (proxy) {
+ return this.m_tree.GetUserData(proxy);
+ }
+ b2DynamicTreeBroadPhase.prototype.GetFatAABB = function (proxy) {
+ return this.m_tree.GetFatAABB(proxy);
+ }
+ b2DynamicTreeBroadPhase.prototype.GetProxyCount = function () {
+ return this.m_proxyCount;
+ }
+ b2DynamicTreeBroadPhase.prototype.UpdatePairs = function (callback) {
+ var __this = this;
+ __this.m_pairCount = 0;
+ var i = 0,
+ queryProxy;
+ for (i = 0;
+ i < __this.m_moveBuffer.length; ++i) {
+ queryProxy = __this.m_moveBuffer[i];
+
+ function QueryCallback(proxy) {
+ if (proxy == queryProxy) return true;
+ if (__this.m_pairCount == __this.m_pairBuffer.length) {
+ __this.m_pairBuffer[__this.m_pairCount] = new b2DynamicTreePair();
+ }
+ var pair = __this.m_pairBuffer[__this.m_pairCount];
+ pair.proxyA = proxy < queryProxy ? proxy : queryProxy;
+ pair.proxyB = proxy >= queryProxy ? proxy : queryProxy;++__this.m_pairCount;
+ return true;
+ };
+ var fatAABB = __this.m_tree.GetFatAABB(queryProxy);
+ __this.m_tree.Query(QueryCallback, fatAABB);
+ }
+ __this.m_moveBuffer.length = 0;
+ for (var i = 0; i < __this.m_pairCount;) {
+ var primaryPair = __this.m_pairBuffer[i];
+ var userDataA = __this.m_tree.GetUserData(primaryPair.proxyA);
+ var userDataB = __this.m_tree.GetUserData(primaryPair.proxyB);
+ callback(userDataA, userDataB);
+ ++i;
+ while (i < __this.m_pairCount) {
+ var pair = __this.m_pairBuffer[i];
+ if (pair.proxyA != primaryPair.proxyA || pair.proxyB != primaryPair.proxyB) {
+ break;
+ }++i;
+ }
+ }
+ }
+ b2DynamicTreeBroadPhase.prototype.Query = function (callback, aabb) {
+ this.m_tree.Query(callback, aabb);
+ }
+ b2DynamicTreeBroadPhase.prototype.RayCast = function (callback, input) {
+ this.m_tree.RayCast(callback, input);
+ }
+ b2DynamicTreeBroadPhase.prototype.Validate = function () {}
+ b2DynamicTreeBroadPhase.prototype.Rebalance = function (iterations) {
+ if (iterations === undefined) iterations = 0;
+ this.m_tree.Rebalance(iterations);
+ }
+ b2DynamicTreeBroadPhase.prototype.BufferMove = function (proxy) {
+ this.m_moveBuffer[this.m_moveBuffer.length] = proxy;
+ }
+ b2DynamicTreeBroadPhase.prototype.UnBufferMove = function (proxy) {
+ var i = parseInt(this.m_moveBuffer.indexOf(proxy));
+ this.m_moveBuffer.splice(i, 1);
+ }
+ b2DynamicTreeBroadPhase.prototype.ComparePairs = function (pair1, pair2) {
+ return 0;
+ }
+ b2DynamicTreeBroadPhase.__implements = {};
+ b2DynamicTreeBroadPhase.__implements[IBroadPhase] = true;
+ b2DynamicTreeNode.b2DynamicTreeNode = function () {
+ this.aabb = new b2AABB();
+ };
+ b2DynamicTreeNode.prototype.IsLeaf = function () {
+ return this.child1 == null;
+ }
+ b2DynamicTreePair.b2DynamicTreePair = function () {};
+ b2Manifold.b2Manifold = function () {
+ this.m_pointCount = 0;
+ };
+ b2Manifold.prototype.b2Manifold = function () {
+ this.m_points = new Vector(b2Settings.b2_maxManifoldPoints);
+ for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) {
+ this.m_points[i] = new b2ManifoldPoint();
+ }
+ this.m_localPlaneNormal = new b2Vec2();
+ this.m_localPoint = new b2Vec2();
+ }
+ b2Manifold.prototype.Reset = function () {
+ for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) {
+ ((this.m_points[i] instanceof b2ManifoldPoint ? this.m_points[i] : null)).Reset();
+ }
+ this.m_localPlaneNormal.SetZero();
+ this.m_localPoint.SetZero();
+ this.m_type = 0;
+ this.m_pointCount = 0;
+ }
+ b2Manifold.prototype.Set = function (m) {
+ this.m_pointCount = m.m_pointCount;
+ for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) {
+ ((this.m_points[i] instanceof b2ManifoldPoint ? this.m_points[i] : null)).Set(m.m_points[i]);
+ }
+ this.m_localPlaneNormal.SetV(m.m_localPlaneNormal);
+ this.m_localPoint.SetV(m.m_localPoint);
+ this.m_type = m.m_type;
+ }
+ b2Manifold.prototype.Copy = function () {
+ var copy = new b2Manifold();
+ copy.Set(this);
+ return copy;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Collision.b2Manifold.e_circles = 0x0001;
+ Box2D.Collision.b2Manifold.e_faceA = 0x0002;
+ Box2D.Collision.b2Manifold.e_faceB = 0x0004;
+ });
+ b2ManifoldPoint.b2ManifoldPoint = function () {
+ this.m_localPoint = new b2Vec2();
+ this.m_id = new b2ContactID();
+ };
+ b2ManifoldPoint.prototype.b2ManifoldPoint = function () {
+ this.Reset();
+ }
+ b2ManifoldPoint.prototype.Reset = function () {
+ this.m_localPoint.SetZero();
+ this.m_normalImpulse = 0.0;
+ this.m_tangentImpulse = 0.0;
+ this.m_id.key = 0;
+ }
+ b2ManifoldPoint.prototype.Set = function (m) {
+ this.m_localPoint.SetV(m.m_localPoint);
+ this.m_normalImpulse = m.m_normalImpulse;
+ this.m_tangentImpulse = m.m_tangentImpulse;
+ this.m_id.Set(m.m_id);
+ }
+ b2Point.b2Point = function () {
+ this.p = new b2Vec2();
+ };
+ b2Point.prototype.Support = function (xf, vX, vY) {
+ if (vX === undefined) vX = 0;
+ if (vY === undefined) vY = 0;
+ return this.p;
+ }
+ b2Point.prototype.GetFirstVertex = function (xf) {
+ return this.p;
+ }
+ b2RayCastInput.b2RayCastInput = function () {
+ this.p1 = new b2Vec2();
+ this.p2 = new b2Vec2();
+ };
+ b2RayCastInput.prototype.b2RayCastInput = function (p1, p2, maxFraction) {
+ if (p1 === undefined) p1 = null;
+ if (p2 === undefined) p2 = null;
+ if (maxFraction === undefined) maxFraction = 1;
+ if (p1) this.p1.SetV(p1);
+ if (p2) this.p2.SetV(p2);
+ this.maxFraction = maxFraction;
+ }
+ b2RayCastOutput.b2RayCastOutput = function () {
+ this.normal = new b2Vec2();
+ };
+ b2Segment.b2Segment = function () {
+ this.p1 = new b2Vec2();
+ this.p2 = new b2Vec2();
+ };
+ b2Segment.prototype.TestSegment = function (lambda, normal, segment, maxLambda) {
+ if (maxLambda === undefined) maxLambda = 0;
+ var s = segment.p1;
+ var rX = segment.p2.x - s.x;
+ var rY = segment.p2.y - s.y;
+ var dX = this.p2.x - this.p1.x;
+ var dY = this.p2.y - this.p1.y;
+ var nX = dY;
+ var nY = (-dX);
+ var k_slop = 100.0 * Number.MIN_VALUE;
+ var denom = (-(rX * nX + rY * nY));
+ if (denom > k_slop) {
+ var bX = s.x - this.p1.x;
+ var bY = s.y - this.p1.y;
+ var a = (bX * nX + bY * nY);
+ if (0.0 <= a && a <= maxLambda * denom) {
+ var mu2 = (-rX * bY) + rY * bX;
+ if ((-k_slop * denom) <= mu2 && mu2 <= denom * (1.0 + k_slop)) {
+ a /= denom;
+ var nLen = Math.sqrt(nX * nX + nY * nY);
+ nX /= nLen;
+ nY /= nLen;
+ lambda[0] = a;
+ normal.Set(nX, nY);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ b2Segment.prototype.Extend = function (aabb) {
+ this.ExtendForward(aabb);
+ this.ExtendBackward(aabb);
+ }
+ b2Segment.prototype.ExtendForward = function (aabb) {
+ var dX = this.p2.x - this.p1.x;
+ var dY = this.p2.y - this.p1.y;
+ var lambda = Math.min(dX > 0 ? (aabb.upperBound.x - this.p1.x) / dX : dX < 0 ? (aabb.lowerBound.x - this.p1.x) / dX : Number.POSITIVE_INFINITY,
+ dY > 0 ? (aabb.upperBound.y - this.p1.y) / dY : dY < 0 ? (aabb.lowerBound.y - this.p1.y) / dY : Number.POSITIVE_INFINITY);
+ this.p2.x = this.p1.x + dX * lambda;
+ this.p2.y = this.p1.y + dY * lambda;
+ }
+ b2Segment.prototype.ExtendBackward = function (aabb) {
+ var dX = (-this.p2.x) + this.p1.x;
+ var dY = (-this.p2.y) + this.p1.y;
+ var lambda = Math.min(dX > 0 ? (aabb.upperBound.x - this.p2.x) / dX : dX < 0 ? (aabb.lowerBound.x - this.p2.x) / dX : Number.POSITIVE_INFINITY,
+ dY > 0 ? (aabb.upperBound.y - this.p2.y) / dY : dY < 0 ? (aabb.lowerBound.y - this.p2.y) / dY : Number.POSITIVE_INFINITY);
+ this.p1.x = this.p2.x + dX * lambda;
+ this.p1.y = this.p2.y + dY * lambda;
+ }
+ b2SeparationFunction.b2SeparationFunction = function () {
+ this.m_localPoint = new b2Vec2();
+ this.m_axis = new b2Vec2();
+ };
+ b2SeparationFunction.prototype.Initialize = function (cache, proxyA, transformA, proxyB, transformB) {
+ this.m_proxyA = proxyA;
+ this.m_proxyB = proxyB;
+ var count = parseInt(cache.count);
+ b2Settings.b2Assert(0 < count && count < 3);
+ var localPointA;
+ var localPointA1;
+ var localPointA2;
+ var localPointB;
+ var localPointB1;
+ var localPointB2;
+ var pointAX = 0;
+ var pointAY = 0;
+ var pointBX = 0;
+ var pointBY = 0;
+ var normalX = 0;
+ var normalY = 0;
+ var tMat;
+ var tVec;
+ var s = 0;
+ var sgn = 0;
+ if (count == 1) {
+ this.m_type = b2SeparationFunction.e_points;
+ localPointA = this.m_proxyA.GetVertex(cache.indexA[0]);
+ localPointB = this.m_proxyB.GetVertex(cache.indexB[0]);
+ tVec = localPointA;
+ tMat = transformA.R;
+ pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tVec = localPointB;
+ tMat = transformB.R;
+ pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ this.m_axis.x = pointBX - pointAX;
+ this.m_axis.y = pointBY - pointAY;
+ this.m_axis.Normalize();
+ }
+ else if (cache.indexB[0] == cache.indexB[1]) {
+ this.m_type = b2SeparationFunction.e_faceA;
+ localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]);
+ localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]);
+ localPointB = this.m_proxyB.GetVertex(cache.indexB[0]);
+ this.m_localPoint.x = 0.5 * (localPointA1.x + localPointA2.x);
+ this.m_localPoint.y = 0.5 * (localPointA1.y + localPointA2.y);
+ this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointA2, localPointA1), 1.0);
+ this.m_axis.Normalize();
+ tVec = this.m_axis;
+ tMat = transformA.R;
+ normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tVec = this.m_localPoint;
+ tMat = transformA.R;
+ pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tVec = localPointB;
+ tMat = transformB.R;
+ pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ s = (pointBX - pointAX) * normalX + (pointBY - pointAY) * normalY;
+ if (s < 0.0) {
+ this.m_axis.NegativeSelf();
+ }
+ }
+ else if (cache.indexA[0] == cache.indexA[0]) {
+ this.m_type = b2SeparationFunction.e_faceB;
+ localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]);
+ localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]);
+ localPointA = this.m_proxyA.GetVertex(cache.indexA[0]);
+ this.m_localPoint.x = 0.5 * (localPointB1.x + localPointB2.x);
+ this.m_localPoint.y = 0.5 * (localPointB1.y + localPointB2.y);
+ this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointB2, localPointB1), 1.0);
+ this.m_axis.Normalize();
+ tVec = this.m_axis;
+ tMat = transformB.R;
+ normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tVec = this.m_localPoint;
+ tMat = transformB.R;
+ pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tVec = localPointA;
+ tMat = transformA.R;
+ pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ s = (pointAX - pointBX) * normalX + (pointAY - pointBY) * normalY;
+ if (s < 0.0) {
+ this.m_axis.NegativeSelf();
+ }
+ }
+ else {
+ localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]);
+ localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]);
+ localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]);
+ localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]);
+ var pA = b2Math.MulX(transformA, localPointA);
+ var dA = b2Math.MulMV(transformA.R, b2Math.SubtractVV(localPointA2, localPointA1));
+ var pB = b2Math.MulX(transformB, localPointB);
+ var dB = b2Math.MulMV(transformB.R, b2Math.SubtractVV(localPointB2, localPointB1));
+ var a = dA.x * dA.x + dA.y * dA.y;
+ var e = dB.x * dB.x + dB.y * dB.y;
+ var r = b2Math.SubtractVV(dB, dA);
+ var c = dA.x * r.x + dA.y * r.y;
+ var f = dB.x * r.x + dB.y * r.y;
+ var b = dA.x * dB.x + dA.y * dB.y;
+ var denom = a * e - b * b;
+ s = 0.0;
+ if (denom != 0.0) {
+ s = b2Math.Clamp((b * f - c * e) / denom, 0.0, 1.0);
+ }
+ var t = (b * s + f) / e;
+ if (t < 0.0) {
+ t = 0.0;
+ s = b2Math.Clamp((b - c) / a, 0.0, 1.0);
+ }
+ localPointA = new b2Vec2();
+ localPointA.x = localPointA1.x + s * (localPointA2.x - localPointA1.x);
+ localPointA.y = localPointA1.y + s * (localPointA2.y - localPointA1.y);
+ localPointB = new b2Vec2();
+ localPointB.x = localPointB1.x + s * (localPointB2.x - localPointB1.x);
+ localPointB.y = localPointB1.y + s * (localPointB2.y - localPointB1.y);
+ if (s == 0.0 || s == 1.0) {
+ this.m_type = b2SeparationFunction.e_faceB;
+ this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointB2, localPointB1), 1.0);
+ this.m_axis.Normalize();
+ this.m_localPoint = localPointB;
+ tVec = this.m_axis;
+ tMat = transformB.R;
+ normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tVec = this.m_localPoint;
+ tMat = transformB.R;
+ pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tVec = localPointA;
+ tMat = transformA.R;
+ pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ sgn = (pointAX - pointBX) * normalX + (pointAY - pointBY) * normalY;
+ if (s < 0.0) {
+ this.m_axis.NegativeSelf();
+ }
+ }
+ else {
+ this.m_type = b2SeparationFunction.e_faceA;
+ this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointA2, localPointA1), 1.0);
+ this.m_localPoint = localPointA;
+ tVec = this.m_axis;
+ tMat = transformA.R;
+ normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tVec = this.m_localPoint;
+ tMat = transformA.R;
+ pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tVec = localPointB;
+ tMat = transformB.R;
+ pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ sgn = (pointBX - pointAX) * normalX + (pointBY - pointAY) * normalY;
+ if (s < 0.0) {
+ this.m_axis.NegativeSelf();
+ }
+ }
+ }
+ }
+ b2SeparationFunction.prototype.Evaluate = function (transformA, transformB) {
+ var axisA;
+ var axisB;
+ var localPointA;
+ var localPointB;
+ var pointA;
+ var pointB;
+ var separation = 0;
+ var normal;
+ switch (this.m_type) {
+ case b2SeparationFunction.e_points:
+ {
+ axisA = b2Math.MulTMV(transformA.R, this.m_axis);
+ axisB = b2Math.MulTMV(transformB.R, this.m_axis.GetNegative());
+ localPointA = this.m_proxyA.GetSupportVertex(axisA);
+ localPointB = this.m_proxyB.GetSupportVertex(axisB);
+ pointA = b2Math.MulX(transformA, localPointA);
+ pointB = b2Math.MulX(transformB, localPointB);
+ separation = (pointB.x - pointA.x) * this.m_axis.x + (pointB.y - pointA.y) * this.m_axis.y;
+ return separation;
+ }
+ case b2SeparationFunction.e_faceA:
+ {
+ normal = b2Math.MulMV(transformA.R, this.m_axis);
+ pointA = b2Math.MulX(transformA, this.m_localPoint);
+ axisB = b2Math.MulTMV(transformB.R, normal.GetNegative());
+ localPointB = this.m_proxyB.GetSupportVertex(axisB);
+ pointB = b2Math.MulX(transformB, localPointB);
+ separation = (pointB.x - pointA.x) * normal.x + (pointB.y - pointA.y) * normal.y;
+ return separation;
+ }
+ case b2SeparationFunction.e_faceB:
+ {
+ normal = b2Math.MulMV(transformB.R, this.m_axis);
+ pointB = b2Math.MulX(transformB, this.m_localPoint);
+ axisA = b2Math.MulTMV(transformA.R, normal.GetNegative());
+ localPointA = this.m_proxyA.GetSupportVertex(axisA);
+ pointA = b2Math.MulX(transformA, localPointA);
+ separation = (pointA.x - pointB.x) * normal.x + (pointA.y - pointB.y) * normal.y;
+ return separation;
+ }
+ default:
+ b2Settings.b2Assert(false);
+ return 0.0;
+ }
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Collision.b2SeparationFunction.e_points = 0x01;
+ Box2D.Collision.b2SeparationFunction.e_faceA = 0x02;
+ Box2D.Collision.b2SeparationFunction.e_faceB = 0x04;
+ });
+ b2Simplex.b2Simplex = function () {
+ this.m_v1 = new b2SimplexVertex();
+ this.m_v2 = new b2SimplexVertex();
+ this.m_v3 = new b2SimplexVertex();
+ this.m_vertices = new Vector(3);
+ };
+ b2Simplex.prototype.b2Simplex = function () {
+ this.m_vertices[0] = this.m_v1;
+ this.m_vertices[1] = this.m_v2;
+ this.m_vertices[2] = this.m_v3;
+ }
+ b2Simplex.prototype.ReadCache = function (cache, proxyA, transformA, proxyB, transformB) {
+ b2Settings.b2Assert(0 <= cache.count && cache.count <= 3);
+ var wALocal;
+ var wBLocal;
+ this.m_count = cache.count;
+ var vertices = this.m_vertices;
+ for (var i = 0; i < this.m_count; i++) {
+ var v = vertices[i];
+ v.indexA = cache.indexA[i];
+ v.indexB = cache.indexB[i];
+ wALocal = proxyA.GetVertex(v.indexA);
+ wBLocal = proxyB.GetVertex(v.indexB);
+ v.wA = b2Math.MulX(transformA, wALocal);
+ v.wB = b2Math.MulX(transformB, wBLocal);
+ v.w = b2Math.SubtractVV(v.wB, v.wA);
+ v.a = 0;
+ }
+ if (this.m_count > 1) {
+ var metric1 = cache.metric;
+ var metric2 = this.GetMetric();
+ if (metric2 < .5 * metric1 || 2.0 * metric1 < metric2 || metric2 < Number.MIN_VALUE) {
+ this.m_count = 0;
+ }
+ }
+ if (this.m_count == 0) {
+ v = vertices[0];
+ v.indexA = 0;
+ v.indexB = 0;
+ wALocal = proxyA.GetVertex(0);
+ wBLocal = proxyB.GetVertex(0);
+ v.wA = b2Math.MulX(transformA, wALocal);
+ v.wB = b2Math.MulX(transformB, wBLocal);
+ v.w = b2Math.SubtractVV(v.wB, v.wA);
+ this.m_count = 1;
+ }
+ }
+ b2Simplex.prototype.WriteCache = function (cache) {
+ cache.metric = this.GetMetric();
+ cache.count = Box2D.parseUInt(this.m_count);
+ var vertices = this.m_vertices;
+ for (var i = 0; i < this.m_count; i++) {
+ cache.indexA[i] = Box2D.parseUInt(vertices[i].indexA);
+ cache.indexB[i] = Box2D.parseUInt(vertices[i].indexB);
+ }
+ }
+ b2Simplex.prototype.GetSearchDirection = function () {
+ switch (this.m_count) {
+ case 1:
+ return this.m_v1.w.GetNegative();
+ case 2:
+ {
+ var e12 = b2Math.SubtractVV(this.m_v2.w, this.m_v1.w);
+ var sgn = b2Math.CrossVV(e12, this.m_v1.w.GetNegative());
+ if (sgn > 0.0) {
+ return b2Math.CrossFV(1.0, e12);
+ }
+ else {
+ return b2Math.CrossVF(e12, 1.0);
+ }
+ }
+ default:
+ b2Settings.b2Assert(false);
+ return new b2Vec2();
+ }
+ }
+ b2Simplex.prototype.GetClosestPoint = function () {
+ switch (this.m_count) {
+ case 0:
+ b2Settings.b2Assert(false);
+ return new b2Vec2();
+ case 1:
+ return this.m_v1.w;
+ case 2:
+ return new b2Vec2(this.m_v1.a * this.m_v1.w.x + this.m_v2.a * this.m_v2.w.x, this.m_v1.a * this.m_v1.w.y + this.m_v2.a * this.m_v2.w.y);
+ default:
+ b2Settings.b2Assert(false);
+ return new b2Vec2();
+ }
+ }
+ b2Simplex.prototype.GetWitnessPoints = function (pA, pB) {
+ switch (this.m_count) {
+ case 0:
+ b2Settings.b2Assert(false);
+ break;
+ case 1:
+ pA.SetV(this.m_v1.wA);
+ pB.SetV(this.m_v1.wB);
+ break;
+ case 2:
+ pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x;
+ pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y;
+ pB.x = this.m_v1.a * this.m_v1.wB.x + this.m_v2.a * this.m_v2.wB.x;
+ pB.y = this.m_v1.a * this.m_v1.wB.y + this.m_v2.a * this.m_v2.wB.y;
+ break;
+ case 3:
+ pB.x = pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x + this.m_v3.a * this.m_v3.wA.x;
+ pB.y = pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y + this.m_v3.a * this.m_v3.wA.y;
+ break;
+ default:
+ b2Settings.b2Assert(false);
+ break;
+ }
+ }
+ b2Simplex.prototype.GetMetric = function () {
+ switch (this.m_count) {
+ case 0:
+ b2Settings.b2Assert(false);
+ return 0.0;
+ case 1:
+ return 0.0;
+ case 2:
+ return b2Math.SubtractVV(this.m_v1.w, this.m_v2.w).Length();
+ case 3:
+ return b2Math.CrossVV(b2Math.SubtractVV(this.m_v2.w, this.m_v1.w), b2Math.SubtractVV(this.m_v3.w, this.m_v1.w));
+ default:
+ b2Settings.b2Assert(false);
+ return 0.0;
+ }
+ }
+ b2Simplex.prototype.Solve2 = function () {
+ var w1 = this.m_v1.w;
+ var w2 = this.m_v2.w;
+ var e12 = b2Math.SubtractVV(w2, w1);
+ var d12_2 = (-(w1.x * e12.x + w1.y * e12.y));
+ if (d12_2 <= 0.0) {
+ this.m_v1.a = 1.0;
+ this.m_count = 1;
+ return;
+ }
+ var d12_1 = (w2.x * e12.x + w2.y * e12.y);
+ if (d12_1 <= 0.0) {
+ this.m_v2.a = 1.0;
+ this.m_count = 1;
+ this.m_v1.Set(this.m_v2);
+ return;
+ }
+ var inv_d12 = 1.0 / (d12_1 + d12_2);
+ this.m_v1.a = d12_1 * inv_d12;
+ this.m_v2.a = d12_2 * inv_d12;
+ this.m_count = 2;
+ }
+ b2Simplex.prototype.Solve3 = function () {
+ var w1 = this.m_v1.w;
+ var w2 = this.m_v2.w;
+ var w3 = this.m_v3.w;
+ var e12 = b2Math.SubtractVV(w2, w1);
+ var w1e12 = b2Math.Dot(w1, e12);
+ var w2e12 = b2Math.Dot(w2, e12);
+ var d12_1 = w2e12;
+ var d12_2 = (-w1e12);
+ var e13 = b2Math.SubtractVV(w3, w1);
+ var w1e13 = b2Math.Dot(w1, e13);
+ var w3e13 = b2Math.Dot(w3, e13);
+ var d13_1 = w3e13;
+ var d13_2 = (-w1e13);
+ var e23 = b2Math.SubtractVV(w3, w2);
+ var w2e23 = b2Math.Dot(w2, e23);
+ var w3e23 = b2Math.Dot(w3, e23);
+ var d23_1 = w3e23;
+ var d23_2 = (-w2e23);
+ var n123 = b2Math.CrossVV(e12, e13);
+ var d123_1 = n123 * b2Math.CrossVV(w2, w3);
+ var d123_2 = n123 * b2Math.CrossVV(w3, w1);
+ var d123_3 = n123 * b2Math.CrossVV(w1, w2);
+ if (d12_2 <= 0.0 && d13_2 <= 0.0) {
+ this.m_v1.a = 1.0;
+ this.m_count = 1;
+ return;
+ }
+ if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0) {
+ var inv_d12 = 1.0 / (d12_1 + d12_2);
+ this.m_v1.a = d12_1 * inv_d12;
+ this.m_v2.a = d12_2 * inv_d12;
+ this.m_count = 2;
+ return;
+ }
+ if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0) {
+ var inv_d13 = 1.0 / (d13_1 + d13_2);
+ this.m_v1.a = d13_1 * inv_d13;
+ this.m_v3.a = d13_2 * inv_d13;
+ this.m_count = 2;
+ this.m_v2.Set(this.m_v3);
+ return;
+ }
+ if (d12_1 <= 0.0 && d23_2 <= 0.0) {
+ this.m_v2.a = 1.0;
+ this.m_count = 1;
+ this.m_v1.Set(this.m_v2);
+ return;
+ }
+ if (d13_1 <= 0.0 && d23_1 <= 0.0) {
+ this.m_v3.a = 1.0;
+ this.m_count = 1;
+ this.m_v1.Set(this.m_v3);
+ return;
+ }
+ if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0) {
+ var inv_d23 = 1.0 / (d23_1 + d23_2);
+ this.m_v2.a = d23_1 * inv_d23;
+ this.m_v3.a = d23_2 * inv_d23;
+ this.m_count = 2;
+ this.m_v1.Set(this.m_v3);
+ return;
+ }
+ var inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3);
+ this.m_v1.a = d123_1 * inv_d123;
+ this.m_v2.a = d123_2 * inv_d123;
+ this.m_v3.a = d123_3 * inv_d123;
+ this.m_count = 3;
+ }
+ b2SimplexCache.b2SimplexCache = function () {
+ this.indexA = new Vector_a2j_Number(3);
+ this.indexB = new Vector_a2j_Number(3);
+ };
+ b2SimplexVertex.b2SimplexVertex = function () {};
+ b2SimplexVertex.prototype.Set = function (other) {
+ this.wA.SetV(other.wA);
+ this.wB.SetV(other.wB);
+ this.w.SetV(other.w);
+ this.a = other.a;
+ this.indexA = other.indexA;
+ this.indexB = other.indexB;
+ }
+ b2TimeOfImpact.b2TimeOfImpact = function () {};
+ b2TimeOfImpact.TimeOfImpact = function (input) {
+ ++b2TimeOfImpact.b2_toiCalls;
+ var proxyA = input.proxyA;
+ var proxyB = input.proxyB;
+ var sweepA = input.sweepA;
+ var sweepB = input.sweepB;
+ b2Settings.b2Assert(sweepA.t0 == sweepB.t0);
+ b2Settings.b2Assert(1.0 - sweepA.t0 > Number.MIN_VALUE);
+ var radius = proxyA.m_radius + proxyB.m_radius;
+ var tolerance = input.tolerance;
+ var alpha = 0.0;
+ var k_maxIterations = 1000;
+ var iter = 0;
+ var target = 0.0;
+ b2TimeOfImpact.s_cache.count = 0;
+ b2TimeOfImpact.s_distanceInput.useRadii = false;
+ for (;;) {
+ sweepA.GetTransform(b2TimeOfImpact.s_xfA, alpha);
+ sweepB.GetTransform(b2TimeOfImpact.s_xfB, alpha);
+ b2TimeOfImpact.s_distanceInput.proxyA = proxyA;
+ b2TimeOfImpact.s_distanceInput.proxyB = proxyB;
+ b2TimeOfImpact.s_distanceInput.transformA = b2TimeOfImpact.s_xfA;
+ b2TimeOfImpact.s_distanceInput.transformB = b2TimeOfImpact.s_xfB;
+ b2Distance.Distance(b2TimeOfImpact.s_distanceOutput, b2TimeOfImpact.s_cache, b2TimeOfImpact.s_distanceInput);
+ if (b2TimeOfImpact.s_distanceOutput.distance <= 0.0) {
+ alpha = 1.0;
+ break;
+ }
+ b2TimeOfImpact.s_fcn.Initialize(b2TimeOfImpact.s_cache, proxyA, b2TimeOfImpact.s_xfA, proxyB, b2TimeOfImpact.s_xfB);
+ var separation = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB);
+ if (separation <= 0.0) {
+ alpha = 1.0;
+ break;
+ }
+ if (iter == 0) {
+ if (separation > radius) {
+ target = b2Math.Max(radius - tolerance, 0.75 * radius);
+ }
+ else {
+ target = b2Math.Max(separation - tolerance, 0.02 * radius);
+ }
+ }
+ if (separation - target < 0.5 * tolerance) {
+ if (iter == 0) {
+ alpha = 1.0;
+ break;
+ }
+ break;
+ }
+ var newAlpha = alpha; {
+ var x1 = alpha;
+ var x2 = 1.0;
+ var f1 = separation;
+ sweepA.GetTransform(b2TimeOfImpact.s_xfA, x2);
+ sweepB.GetTransform(b2TimeOfImpact.s_xfB, x2);
+ var f2 = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB);
+ if (f2 >= target) {
+ alpha = 1.0;
+ break;
+ }
+ var rootIterCount = 0;
+ for (;;) {
+ var x = 0;
+ if (rootIterCount & 1) {
+ x = x1 + (target - f1) * (x2 - x1) / (f2 - f1);
+ }
+ else {
+ x = 0.5 * (x1 + x2);
+ }
+ sweepA.GetTransform(b2TimeOfImpact.s_xfA, x);
+ sweepB.GetTransform(b2TimeOfImpact.s_xfB, x);
+ var f = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB);
+ if (b2Math.Abs(f - target) < 0.025 * tolerance) {
+ newAlpha = x;
+ break;
+ }
+ if (f > target) {
+ x1 = x;
+ f1 = f;
+ }
+ else {
+ x2 = x;
+ f2 = f;
+ }++rootIterCount;
+ ++b2TimeOfImpact.b2_toiRootIters;
+ if (rootIterCount == 50) {
+ break;
+ }
+ }
+ b2TimeOfImpact.b2_toiMaxRootIters = b2Math.Max(b2TimeOfImpact.b2_toiMaxRootIters, rootIterCount);
+ }
+ if (newAlpha < (1.0 + 100.0 * Number.MIN_VALUE) * alpha) {
+ break;
+ }
+ alpha = newAlpha;
+ iter++;
+ ++b2TimeOfImpact.b2_toiIters;
+ if (iter == k_maxIterations) {
+ break;
+ }
+ }
+ b2TimeOfImpact.b2_toiMaxIters = b2Math.Max(b2TimeOfImpact.b2_toiMaxIters, iter);
+ return alpha;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Collision.b2TimeOfImpact.b2_toiCalls = 0;
+ Box2D.Collision.b2TimeOfImpact.b2_toiIters = 0;
+ Box2D.Collision.b2TimeOfImpact.b2_toiMaxIters = 0;
+ Box2D.Collision.b2TimeOfImpact.b2_toiRootIters = 0;
+ Box2D.Collision.b2TimeOfImpact.b2_toiMaxRootIters = 0;
+ Box2D.Collision.b2TimeOfImpact.s_cache = new b2SimplexCache();
+ Box2D.Collision.b2TimeOfImpact.s_distanceInput = new b2DistanceInput();
+ Box2D.Collision.b2TimeOfImpact.s_xfA = new b2Transform();
+ Box2D.Collision.b2TimeOfImpact.s_xfB = new b2Transform();
+ Box2D.Collision.b2TimeOfImpact.s_fcn = new b2SeparationFunction();
+ Box2D.Collision.b2TimeOfImpact.s_distanceOutput = new b2DistanceOutput();
+ });
+ b2TOIInput.b2TOIInput = function () {
+ this.proxyA = new b2DistanceProxy();
+ this.proxyB = new b2DistanceProxy();
+ this.sweepA = new b2Sweep();
+ this.sweepB = new b2Sweep();
+ };
+ b2WorldManifold.b2WorldManifold = function () {
+ this.m_normal = new b2Vec2();
+ };
+ b2WorldManifold.prototype.b2WorldManifold = function () {
+ this.m_points = new Vector(b2Settings.b2_maxManifoldPoints);
+ for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) {
+ this.m_points[i] = new b2Vec2();
+ }
+ }
+ b2WorldManifold.prototype.Initialize = function (manifold, xfA, radiusA, xfB, radiusB) {
+ if (radiusA === undefined) radiusA = 0;
+ if (radiusB === undefined) radiusB = 0;
+ if (manifold.m_pointCount == 0) {
+ return;
+ }
+ var i = 0;
+ var tVec;
+ var tMat;
+ var normalX = 0;
+ var normalY = 0;
+ var planePointX = 0;
+ var planePointY = 0;
+ var clipPointX = 0;
+ var clipPointY = 0;
+ switch (manifold.m_type) {
+ case b2Manifold.e_circles:
+ {
+ tMat = xfA.R;
+ tVec = manifold.m_localPoint;
+ var pointAX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ var pointAY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tMat = xfB.R;
+ tVec = manifold.m_points[0].m_localPoint;
+ var pointBX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ var pointBY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ var dX = pointBX - pointAX;
+ var dY = pointBY - pointAY;
+ var d2 = dX * dX + dY * dY;
+ if (d2 > Number.MIN_VALUE * Number.MIN_VALUE) {
+ var d = Math.sqrt(d2);
+ this.m_normal.x = dX / d;
+ this.m_normal.y = dY / d;
+ }
+ else {
+ this.m_normal.x = 1;
+ this.m_normal.y = 0;
+ }
+ var cAX = pointAX + radiusA * this.m_normal.x;
+ var cAY = pointAY + radiusA * this.m_normal.y;
+ var cBX = pointBX - radiusB * this.m_normal.x;
+ var cBY = pointBY - radiusB * this.m_normal.y;
+ this.m_points[0].x = 0.5 * (cAX + cBX);
+ this.m_points[0].y = 0.5 * (cAY + cBY);
+ }
+ break;
+ case b2Manifold.e_faceA:
+ {
+ tMat = xfA.R;
+ tVec = manifold.m_localPlaneNormal;
+ normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tMat = xfA.R;
+ tVec = manifold.m_localPoint;
+ planePointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ planePointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ this.m_normal.x = normalX;
+ this.m_normal.y = normalY;
+ for (i = 0;
+ i < manifold.m_pointCount; i++) {
+ tMat = xfB.R;
+ tVec = manifold.m_points[i].m_localPoint;
+ clipPointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ clipPointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ this.m_points[i].x = clipPointX + 0.5 * (radiusA - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusB) * normalX;
+ this.m_points[i].y = clipPointY + 0.5 * (radiusA - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusB) * normalY;
+ }
+ }
+ break;
+ case b2Manifold.e_faceB:
+ {
+ tMat = xfB.R;
+ tVec = manifold.m_localPlaneNormal;
+ normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tMat = xfB.R;
+ tVec = manifold.m_localPoint;
+ planePointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ planePointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ this.m_normal.x = (-normalX);
+ this.m_normal.y = (-normalY);
+ for (i = 0;
+ i < manifold.m_pointCount; i++) {
+ tMat = xfA.R;
+ tVec = manifold.m_points[i].m_localPoint;
+ clipPointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ clipPointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ this.m_points[i].x = clipPointX + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA) * normalX;
+ this.m_points[i].y = clipPointY + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA) * normalY;
+ }
+ }
+ break;
+ }
+ }
+ ClipVertex.ClipVertex = function () {
+ this.v = new b2Vec2();
+ this.id = new b2ContactID();
+ };
+ ClipVertex.prototype.Set = function (other) {
+ this.v.SetV(other.v);
+ this.id.Set(other.id);
+ }
+ Features.Features = function () {};
+ Object.defineProperty(Features.prototype, 'referenceEdge', {
+ enumerable: false,
+ configurable: true,
+ get: function () {
+ return this._referenceEdge;
+ }
+ });
+ Object.defineProperty(Features.prototype, 'referenceEdge', {
+ enumerable: false,
+ configurable: true,
+ set: function (value) {
+ if (value === undefined) value = 0;
+ this._referenceEdge = value;
+ this._m_id._key = (this._m_id._key & 0xffffff00) | (this._referenceEdge & 0x000000ff);
+ }
+ });
+ Object.defineProperty(Features.prototype, 'incidentEdge', {
+ enumerable: false,
+ configurable: true,
+ get: function () {
+ return this._incidentEdge;
+ }
+ });
+ Object.defineProperty(Features.prototype, 'incidentEdge', {
+ enumerable: false,
+ configurable: true,
+ set: function (value) {
+ if (value === undefined) value = 0;
+ this._incidentEdge = value;
+ this._m_id._key = (this._m_id._key & 0xffff00ff) | ((this._incidentEdge << 8) & 0x0000ff00);
+ }
+ });
+ Object.defineProperty(Features.prototype, 'incidentVertex', {
+ enumerable: false,
+ configurable: true,
+ get: function () {
+ return this._incidentVertex;
+ }
+ });
+ Object.defineProperty(Features.prototype, 'incidentVertex', {
+ enumerable: false,
+ configurable: true,
+ set: function (value) {
+ if (value === undefined) value = 0;
+ this._incidentVertex = value;
+ this._m_id._key = (this._m_id._key & 0xff00ffff) | ((this._incidentVertex << 16) & 0x00ff0000);
+ }
+ });
+ Object.defineProperty(Features.prototype, 'flip', {
+ enumerable: false,
+ configurable: true,
+ get: function () {
+ return this._flip;
+ }
+ });
+ Object.defineProperty(Features.prototype, 'flip', {
+ enumerable: false,
+ configurable: true,
+ set: function (value) {
+ if (value === undefined) value = 0;
+ this._flip = value;
+ this._m_id._key = (this._m_id._key & 0x00ffffff) | ((this._flip << 24) & 0xff000000);
+ }
+ });
+})();
+(function () {
+ var b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
+ b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef,
+ b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape,
+ b2MassData = Box2D.Collision.Shapes.b2MassData,
+ b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
+ b2Shape = Box2D.Collision.Shapes.b2Shape,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3,
+ b2Body = Box2D.Dynamics.b2Body,
+ b2BodyDef = Box2D.Dynamics.b2BodyDef,
+ b2ContactFilter = Box2D.Dynamics.b2ContactFilter,
+ b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse,
+ b2ContactListener = Box2D.Dynamics.b2ContactListener,
+ b2ContactManager = Box2D.Dynamics.b2ContactManager,
+ b2DebugDraw = Box2D.Dynamics.b2DebugDraw,
+ b2DestructionListener = Box2D.Dynamics.b2DestructionListener,
+ b2FilterData = Box2D.Dynamics.b2FilterData,
+ b2Fixture = Box2D.Dynamics.b2Fixture,
+ b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
+ b2Island = Box2D.Dynamics.b2Island,
+ b2TimeStep = Box2D.Dynamics.b2TimeStep,
+ b2World = Box2D.Dynamics.b2World,
+ b2AABB = Box2D.Collision.b2AABB,
+ b2Bound = Box2D.Collision.b2Bound,
+ b2BoundValues = Box2D.Collision.b2BoundValues,
+ b2Collision = Box2D.Collision.b2Collision,
+ b2ContactID = Box2D.Collision.b2ContactID,
+ b2ContactPoint = Box2D.Collision.b2ContactPoint,
+ b2Distance = Box2D.Collision.b2Distance,
+ b2DistanceInput = Box2D.Collision.b2DistanceInput,
+ b2DistanceOutput = Box2D.Collision.b2DistanceOutput,
+ b2DistanceProxy = Box2D.Collision.b2DistanceProxy,
+ b2DynamicTree = Box2D.Collision.b2DynamicTree,
+ b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase,
+ b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode,
+ b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair,
+ b2Manifold = Box2D.Collision.b2Manifold,
+ b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint,
+ b2Point = Box2D.Collision.b2Point,
+ b2RayCastInput = Box2D.Collision.b2RayCastInput,
+ b2RayCastOutput = Box2D.Collision.b2RayCastOutput,
+ b2Segment = Box2D.Collision.b2Segment,
+ b2SeparationFunction = Box2D.Collision.b2SeparationFunction,
+ b2Simplex = Box2D.Collision.b2Simplex,
+ b2SimplexCache = Box2D.Collision.b2SimplexCache,
+ b2SimplexVertex = Box2D.Collision.b2SimplexVertex,
+ b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact,
+ b2TOIInput = Box2D.Collision.b2TOIInput,
+ b2WorldManifold = Box2D.Collision.b2WorldManifold,
+ ClipVertex = Box2D.Collision.ClipVertex,
+ Features = Box2D.Collision.Features,
+ IBroadPhase = Box2D.Collision.IBroadPhase;
+
+ Box2D.inherit(b2CircleShape, Box2D.Collision.Shapes.b2Shape);
+ b2CircleShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype;
+ b2CircleShape.b2CircleShape = function () {
+ Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments);
+ this.m_p = new b2Vec2();
+ };
+ b2CircleShape.prototype.Copy = function () {
+ var s = new b2CircleShape();
+ s.Set(this);
+ return s;
+ }
+ b2CircleShape.prototype.Set = function (other) {
+ this.__super.Set.call(this, other);
+ if (Box2D.is(other, b2CircleShape)) {
+ var other2 = (other instanceof b2CircleShape ? other : null);
+ this.m_p.SetV(other2.m_p);
+ }
+ }
+ b2CircleShape.prototype.TestPoint = function (transform, p) {
+ var tMat = transform.R;
+ var dX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y);
+ var dY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y);
+ dX = p.x - dX;
+ dY = p.y - dY;
+ return (dX * dX + dY * dY) <= this.m_radius * this.m_radius;
+ }
+ b2CircleShape.prototype.RayCast = function (output, input, transform) {
+ var tMat = transform.R;
+ var positionX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y);
+ var positionY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y);
+ var sX = input.p1.x - positionX;
+ var sY = input.p1.y - positionY;
+ var b = (sX * sX + sY * sY) - this.m_radius * this.m_radius;
+ var rX = input.p2.x - input.p1.x;
+ var rY = input.p2.y - input.p1.y;
+ var c = (sX * rX + sY * rY);
+ var rr = (rX * rX + rY * rY);
+ var sigma = c * c - rr * b;
+ if (sigma < 0.0 || rr < Number.MIN_VALUE) {
+ return false;
+ }
+ var a = (-(c + Math.sqrt(sigma)));
+ if (0.0 <= a && a <= input.maxFraction * rr) {
+ a /= rr;
+ output.fraction = a;
+ output.normal.x = sX + a * rX;
+ output.normal.y = sY + a * rY;
+ output.normal.Normalize();
+ return true;
+ }
+ return false;
+ }
+ b2CircleShape.prototype.ComputeAABB = function (aabb, transform) {
+ var tMat = transform.R;
+ var pX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y);
+ var pY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y);
+ aabb.lowerBound.Set(pX - this.m_radius, pY - this.m_radius);
+ aabb.upperBound.Set(pX + this.m_radius, pY + this.m_radius);
+ }
+ b2CircleShape.prototype.ComputeMass = function (massData, density) {
+ if (density === undefined) density = 0;
+ massData.mass = density * b2Settings.b2_pi * this.m_radius * this.m_radius;
+ massData.center.SetV(this.m_p);
+ massData.I = massData.mass * (0.5 * this.m_radius * this.m_radius + (this.m_p.x * this.m_p.x + this.m_p.y * this.m_p.y));
+ }
+ b2CircleShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) {
+ if (offset === undefined) offset = 0;
+ var p = b2Math.MulX(xf, this.m_p);
+ var l = (-(b2Math.Dot(normal, p) - offset));
+ if (l < (-this.m_radius) + Number.MIN_VALUE) {
+ return 0;
+ }
+ if (l > this.m_radius) {
+ c.SetV(p);
+ return Math.PI * this.m_radius * this.m_radius;
+ }
+ var r2 = this.m_radius * this.m_radius;
+ var l2 = l * l;
+ var area = r2 * (Math.asin(l / this.m_radius) + Math.PI / 2) + l * Math.sqrt(r2 - l2);
+ var com = (-2 / 3 * Math.pow(r2 - l2, 1.5) / area);
+ c.x = p.x + normal.x * com;
+ c.y = p.y + normal.y * com;
+ return area;
+ }
+ b2CircleShape.prototype.GetLocalPosition = function () {
+ return this.m_p;
+ }
+ b2CircleShape.prototype.SetLocalPosition = function (position) {
+ this.m_p.SetV(position);
+ }
+ b2CircleShape.prototype.GetRadius = function () {
+ return this.m_radius;
+ }
+ b2CircleShape.prototype.SetRadius = function (radius) {
+ if (radius === undefined) radius = 0;
+ this.m_radius = radius;
+ }
+ b2CircleShape.prototype.b2CircleShape = function (radius) {
+ if (radius === undefined) radius = 0;
+ this.__super.b2Shape.call(this);
+ this.m_type = b2Shape.e_circleShape;
+ this.m_radius = radius;
+ }
+ b2EdgeChainDef.b2EdgeChainDef = function () {};
+ b2EdgeChainDef.prototype.b2EdgeChainDef = function () {
+ this.vertexCount = 0;
+ this.isALoop = true;
+ this.vertices = [];
+ }
+ Box2D.inherit(b2EdgeShape, Box2D.Collision.Shapes.b2Shape);
+ b2EdgeShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype;
+ b2EdgeShape.b2EdgeShape = function () {
+ Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments);
+ this.s_supportVec = new b2Vec2();
+ this.m_v1 = new b2Vec2();
+ this.m_v2 = new b2Vec2();
+ this.m_coreV1 = new b2Vec2();
+ this.m_coreV2 = new b2Vec2();
+ this.m_normal = new b2Vec2();
+ this.m_direction = new b2Vec2();
+ this.m_cornerDir1 = new b2Vec2();
+ this.m_cornerDir2 = new b2Vec2();
+ };
+ b2EdgeShape.prototype.TestPoint = function (transform, p) {
+ return false;
+ }
+ b2EdgeShape.prototype.RayCast = function (output, input, transform) {
+ var tMat;
+ var rX = input.p2.x - input.p1.x;
+ var rY = input.p2.y - input.p1.y;
+ tMat = transform.R;
+ var v1X = transform.position.x + (tMat.col1.x * this.m_v1.x + tMat.col2.x * this.m_v1.y);
+ var v1Y = transform.position.y + (tMat.col1.y * this.m_v1.x + tMat.col2.y * this.m_v1.y);
+ var nX = transform.position.y + (tMat.col1.y * this.m_v2.x + tMat.col2.y * this.m_v2.y) - v1Y;
+ var nY = (-(transform.position.x + (tMat.col1.x * this.m_v2.x + tMat.col2.x * this.m_v2.y) - v1X));
+ var k_slop = 100.0 * Number.MIN_VALUE;
+ var denom = (-(rX * nX + rY * nY));
+ if (denom > k_slop) {
+ var bX = input.p1.x - v1X;
+ var bY = input.p1.y - v1Y;
+ var a = (bX * nX + bY * nY);
+ if (0.0 <= a && a <= input.maxFraction * denom) {
+ var mu2 = (-rX * bY) + rY * bX;
+ if ((-k_slop * denom) <= mu2 && mu2 <= denom * (1.0 + k_slop)) {
+ a /= denom;
+ output.fraction = a;
+ var nLen = Math.sqrt(nX * nX + nY * nY);
+ output.normal.x = nX / nLen;
+ output.normal.y = nY / nLen;
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ b2EdgeShape.prototype.ComputeAABB = function (aabb, transform) {
+ var tMat = transform.R;
+ var v1X = transform.position.x + (tMat.col1.x * this.m_v1.x + tMat.col2.x * this.m_v1.y);
+ var v1Y = transform.position.y + (tMat.col1.y * this.m_v1.x + tMat.col2.y * this.m_v1.y);
+ var v2X = transform.position.x + (tMat.col1.x * this.m_v2.x + tMat.col2.x * this.m_v2.y);
+ var v2Y = transform.position.y + (tMat.col1.y * this.m_v2.x + tMat.col2.y * this.m_v2.y);
+ if (v1X < v2X) {
+ aabb.lowerBound.x = v1X;
+ aabb.upperBound.x = v2X;
+ }
+ else {
+ aabb.lowerBound.x = v2X;
+ aabb.upperBound.x = v1X;
+ }
+ if (v1Y < v2Y) {
+ aabb.lowerBound.y = v1Y;
+ aabb.upperBound.y = v2Y;
+ }
+ else {
+ aabb.lowerBound.y = v2Y;
+ aabb.upperBound.y = v1Y;
+ }
+ }
+ b2EdgeShape.prototype.ComputeMass = function (massData, density) {
+ if (density === undefined) density = 0;
+ massData.mass = 0;
+ massData.center.SetV(this.m_v1);
+ massData.I = 0;
+ }
+ b2EdgeShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) {
+ if (offset === undefined) offset = 0;
+ var v0 = new b2Vec2(normal.x * offset, normal.y * offset);
+ var v1 = b2Math.MulX(xf, this.m_v1);
+ var v2 = b2Math.MulX(xf, this.m_v2);
+ var d1 = b2Math.Dot(normal, v1) - offset;
+ var d2 = b2Math.Dot(normal, v2) - offset;
+ if (d1 > 0) {
+ if (d2 > 0) {
+ return 0;
+ }
+ else {
+ v1.x = (-d2 / (d1 - d2) * v1.x) + d1 / (d1 - d2) * v2.x;
+ v1.y = (-d2 / (d1 - d2) * v1.y) + d1 / (d1 - d2) * v2.y;
+ }
+ }
+ else {
+ if (d2 > 0) {
+ v2.x = (-d2 / (d1 - d2) * v1.x) + d1 / (d1 - d2) * v2.x;
+ v2.y = (-d2 / (d1 - d2) * v1.y) + d1 / (d1 - d2) * v2.y;
+ }
+ else {}
+ }
+ c.x = (v0.x + v1.x + v2.x) / 3;
+ c.y = (v0.y + v1.y + v2.y) / 3;
+ return 0.5 * ((v1.x - v0.x) * (v2.y - v0.y) - (v1.y - v0.y) * (v2.x - v0.x));
+ }
+ b2EdgeShape.prototype.GetLength = function () {
+ return this.m_length;
+ }
+ b2EdgeShape.prototype.GetVertex1 = function () {
+ return this.m_v1;
+ }
+ b2EdgeShape.prototype.GetVertex2 = function () {
+ return this.m_v2;
+ }
+ b2EdgeShape.prototype.GetCoreVertex1 = function () {
+ return this.m_coreV1;
+ }
+ b2EdgeShape.prototype.GetCoreVertex2 = function () {
+ return this.m_coreV2;
+ }
+ b2EdgeShape.prototype.GetNormalVector = function () {
+ return this.m_normal;
+ }
+ b2EdgeShape.prototype.GetDirectionVector = function () {
+ return this.m_direction;
+ }
+ b2EdgeShape.prototype.GetCorner1Vector = function () {
+ return this.m_cornerDir1;
+ }
+ b2EdgeShape.prototype.GetCorner2Vector = function () {
+ return this.m_cornerDir2;
+ }
+ b2EdgeShape.prototype.Corner1IsConvex = function () {
+ return this.m_cornerConvex1;
+ }
+ b2EdgeShape.prototype.Corner2IsConvex = function () {
+ return this.m_cornerConvex2;
+ }
+ b2EdgeShape.prototype.GetFirstVertex = function (xf) {
+ var tMat = xf.R;
+ return new b2Vec2(xf.position.x + (tMat.col1.x * this.m_coreV1.x + tMat.col2.x * this.m_coreV1.y), xf.position.y + (tMat.col1.y * this.m_coreV1.x + tMat.col2.y * this.m_coreV1.y));
+ }
+ b2EdgeShape.prototype.GetNextEdge = function () {
+ return this.m_nextEdge;
+ }
+ b2EdgeShape.prototype.GetPrevEdge = function () {
+ return this.m_prevEdge;
+ }
+ b2EdgeShape.prototype.Support = function (xf, dX, dY) {
+ if (dX === undefined) dX = 0;
+ if (dY === undefined) dY = 0;
+ var tMat = xf.R;
+ var v1X = xf.position.x + (tMat.col1.x * this.m_coreV1.x + tMat.col2.x * this.m_coreV1.y);
+ var v1Y = xf.position.y + (tMat.col1.y * this.m_coreV1.x + tMat.col2.y * this.m_coreV1.y);
+ var v2X = xf.position.x + (tMat.col1.x * this.m_coreV2.x + tMat.col2.x * this.m_coreV2.y);
+ var v2Y = xf.position.y + (tMat.col1.y * this.m_coreV2.x + tMat.col2.y * this.m_coreV2.y);
+ if ((v1X * dX + v1Y * dY) > (v2X * dX + v2Y * dY)) {
+ this.s_supportVec.x = v1X;
+ this.s_supportVec.y = v1Y;
+ }
+ else {
+ this.s_supportVec.x = v2X;
+ this.s_supportVec.y = v2Y;
+ }
+ return this.s_supportVec;
+ }
+ b2EdgeShape.prototype.b2EdgeShape = function (v1, v2) {
+ this.__super.b2Shape.call(this);
+ this.m_type = b2Shape.e_edgeShape;
+ this.m_prevEdge = null;
+ this.m_nextEdge = null;
+ this.m_v1 = v1;
+ this.m_v2 = v2;
+ this.m_direction.Set(this.m_v2.x - this.m_v1.x, this.m_v2.y - this.m_v1.y);
+ this.m_length = this.m_direction.Normalize();
+ this.m_normal.Set(this.m_direction.y, (-this.m_direction.x));
+ this.m_coreV1.Set((-b2Settings.b2_toiSlop * (this.m_normal.x - this.m_direction.x)) + this.m_v1.x, (-b2Settings.b2_toiSlop * (this.m_normal.y - this.m_direction.y)) + this.m_v1.y);
+ this.m_coreV2.Set((-b2Settings.b2_toiSlop * (this.m_normal.x + this.m_direction.x)) + this.m_v2.x, (-b2Settings.b2_toiSlop * (this.m_normal.y + this.m_direction.y)) + this.m_v2.y);
+ this.m_cornerDir1 = this.m_normal;
+ this.m_cornerDir2.Set((-this.m_normal.x), (-this.m_normal.y));
+ }
+ b2EdgeShape.prototype.SetPrevEdge = function (edge, core, cornerDir, convex) {
+ this.m_prevEdge = edge;
+ this.m_coreV1 = core;
+ this.m_cornerDir1 = cornerDir;
+ this.m_cornerConvex1 = convex;
+ }
+ b2EdgeShape.prototype.SetNextEdge = function (edge, core, cornerDir, convex) {
+ this.m_nextEdge = edge;
+ this.m_coreV2 = core;
+ this.m_cornerDir2 = cornerDir;
+ this.m_cornerConvex2 = convex;
+ }
+ b2MassData.b2MassData = function () {
+ this.mass = 0.0;
+ this.center = new b2Vec2(0, 0);
+ this.I = 0.0;
+ };
+ Box2D.inherit(b2PolygonShape, Box2D.Collision.Shapes.b2Shape);
+ b2PolygonShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype;
+ b2PolygonShape.b2PolygonShape = function () {
+ Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments);
+ };
+ b2PolygonShape.prototype.Copy = function () {
+ var s = new b2PolygonShape();
+ s.Set(this);
+ return s;
+ }
+ b2PolygonShape.prototype.Set = function (other) {
+ this.__super.Set.call(this, other);
+ if (Box2D.is(other, b2PolygonShape)) {
+ var other2 = (other instanceof b2PolygonShape ? other : null);
+ this.m_centroid.SetV(other2.m_centroid);
+ this.m_vertexCount = other2.m_vertexCount;
+ this.Reserve(this.m_vertexCount);
+ for (var i = 0; i < this.m_vertexCount; i++) {
+ this.m_vertices[i].SetV(other2.m_vertices[i]);
+ this.m_normals[i].SetV(other2.m_normals[i]);
+ }
+ }
+ }
+ b2PolygonShape.prototype.SetAsArray = function (vertices, vertexCount) {
+ if (vertexCount === undefined) vertexCount = 0;
+ var v = new Vector();
+ var i = 0,
+ tVec;
+ for (i = 0;
+ i < vertices.length; ++i) {
+ tVec = vertices[i];
+ v.push(tVec);
+ }
+ this.SetAsVector(v, vertexCount);
+ }
+ b2PolygonShape.AsArray = function (vertices, vertexCount) {
+ if (vertexCount === undefined) vertexCount = 0;
+ var polygonShape = new b2PolygonShape();
+ polygonShape.SetAsArray(vertices, vertexCount);
+ return polygonShape;
+ }
+ b2PolygonShape.prototype.SetAsVector = function (vertices, vertexCount) {
+ if (vertexCount === undefined) vertexCount = 0;
+ if (vertexCount == 0) vertexCount = vertices.length;
+ b2Settings.b2Assert(2 <= vertexCount);
+ this.m_vertexCount = vertexCount;
+ this.Reserve(vertexCount);
+ var i = 0;
+ for (i = 0;
+ i < this.m_vertexCount; i++) {
+ this.m_vertices[i].SetV(vertices[i]);
+ }
+ for (i = 0;
+ i < this.m_vertexCount; ++i) {
+ var i1 = parseInt(i);
+ var i2 = parseInt(i + 1 < this.m_vertexCount ? i + 1 : 0);
+ var edge = b2Math.SubtractVV(this.m_vertices[i2], this.m_vertices[i1]);
+ b2Settings.b2Assert(edge.LengthSquared() > Number.MIN_VALUE);
+ this.m_normals[i].SetV(b2Math.CrossVF(edge, 1.0));
+ this.m_normals[i].Normalize();
+ }
+ this.m_centroid = b2PolygonShape.ComputeCentroid(this.m_vertices, this.m_vertexCount);
+ }
+ b2PolygonShape.AsVector = function (vertices, vertexCount) {
+ if (vertexCount === undefined) vertexCount = 0;
+ var polygonShape = new b2PolygonShape();
+ polygonShape.SetAsVector(vertices, vertexCount);
+ return polygonShape;
+ }
+ b2PolygonShape.prototype.SetAsBox = function (hx, hy) {
+ if (hx === undefined) hx = 0;
+ if (hy === undefined) hy = 0;
+ this.m_vertexCount = 4;
+ this.Reserve(4);
+ this.m_vertices[0].Set((-hx), (-hy));
+ this.m_vertices[1].Set(hx, (-hy));
+ this.m_vertices[2].Set(hx, hy);
+ this.m_vertices[3].Set((-hx), hy);
+ this.m_normals[0].Set(0.0, (-1.0));
+ this.m_normals[1].Set(1.0, 0.0);
+ this.m_normals[2].Set(0.0, 1.0);
+ this.m_normals[3].Set((-1.0), 0.0);
+ this.m_centroid.SetZero();
+ }
+ b2PolygonShape.AsBox = function (hx, hy) {
+ if (hx === undefined) hx = 0;
+ if (hy === undefined) hy = 0;
+ var polygonShape = new b2PolygonShape();
+ polygonShape.SetAsBox(hx, hy);
+ return polygonShape;
+ }
+ b2PolygonShape.prototype.SetAsOrientedBox = function (hx, hy, center, angle) {
+ if (hx === undefined) hx = 0;
+ if (hy === undefined) hy = 0;
+ if (center === undefined) center = null;
+ if (angle === undefined) angle = 0.0;
+ this.m_vertexCount = 4;
+ this.Reserve(4);
+ this.m_vertices[0].Set((-hx), (-hy));
+ this.m_vertices[1].Set(hx, (-hy));
+ this.m_vertices[2].Set(hx, hy);
+ this.m_vertices[3].Set((-hx), hy);
+ this.m_normals[0].Set(0.0, (-1.0));
+ this.m_normals[1].Set(1.0, 0.0);
+ this.m_normals[2].Set(0.0, 1.0);
+ this.m_normals[3].Set((-1.0), 0.0);
+ this.m_centroid = center;
+ var xf = new b2Transform();
+ xf.position = center;
+ xf.R.Set(angle);
+ for (var i = 0; i < this.m_vertexCount; ++i) {
+ this.m_vertices[i] = b2Math.MulX(xf, this.m_vertices[i]);
+ this.m_normals[i] = b2Math.MulMV(xf.R, this.m_normals[i]);
+ }
+ }
+ b2PolygonShape.AsOrientedBox = function (hx, hy, center, angle) {
+ if (hx === undefined) hx = 0;
+ if (hy === undefined) hy = 0;
+ if (center === undefined) center = null;
+ if (angle === undefined) angle = 0.0;
+ var polygonShape = new b2PolygonShape();
+ polygonShape.SetAsOrientedBox(hx, hy, center, angle);
+ return polygonShape;
+ }
+ b2PolygonShape.prototype.SetAsEdge = function (v1, v2) {
+ this.m_vertexCount = 2;
+ this.Reserve(2);
+ this.m_vertices[0].SetV(v1);
+ this.m_vertices[1].SetV(v2);
+ this.m_centroid.x = 0.5 * (v1.x + v2.x);
+ this.m_centroid.y = 0.5 * (v1.y + v2.y);
+ this.m_normals[0] = b2Math.CrossVF(b2Math.SubtractVV(v2, v1), 1.0);
+ this.m_normals[0].Normalize();
+ this.m_normals[1].x = (-this.m_normals[0].x);
+ this.m_normals[1].y = (-this.m_normals[0].y);
+ }
+ b2PolygonShape.AsEdge = function (v1, v2) {
+ var polygonShape = new b2PolygonShape();
+ polygonShape.SetAsEdge(v1, v2);
+ return polygonShape;
+ }
+ b2PolygonShape.prototype.TestPoint = function (xf, p) {
+ var tVec;
+ var tMat = xf.R;
+ var tX = p.x - xf.position.x;
+ var tY = p.y - xf.position.y;
+ var pLocalX = (tX * tMat.col1.x + tY * tMat.col1.y);
+ var pLocalY = (tX * tMat.col2.x + tY * tMat.col2.y);
+ for (var i = 0; i < this.m_vertexCount; ++i) {
+ tVec = this.m_vertices[i];
+ tX = pLocalX - tVec.x;
+ tY = pLocalY - tVec.y;
+ tVec = this.m_normals[i];
+ var dot = (tVec.x * tX + tVec.y * tY);
+ if (dot > 0.0) {
+ return false;
+ }
+ }
+ return true;
+ }
+ b2PolygonShape.prototype.RayCast = function (output, input, transform) {
+ var lower = 0.0;
+ var upper = input.maxFraction;
+ var tX = 0;
+ var tY = 0;
+ var tMat;
+ var tVec;
+ tX = input.p1.x - transform.position.x;
+ tY = input.p1.y - transform.position.y;
+ tMat = transform.R;
+ var p1X = (tX * tMat.col1.x + tY * tMat.col1.y);
+ var p1Y = (tX * tMat.col2.x + tY * tMat.col2.y);
+ tX = input.p2.x - transform.position.x;
+ tY = input.p2.y - transform.position.y;
+ tMat = transform.R;
+ var p2X = (tX * tMat.col1.x + tY * tMat.col1.y);
+ var p2Y = (tX * tMat.col2.x + tY * tMat.col2.y);
+ var dX = p2X - p1X;
+ var dY = p2Y - p1Y;
+ var index = parseInt((-1));
+ for (var i = 0; i < this.m_vertexCount; ++i) {
+ tVec = this.m_vertices[i];
+ tX = tVec.x - p1X;
+ tY = tVec.y - p1Y;
+ tVec = this.m_normals[i];
+ var numerator = (tVec.x * tX + tVec.y * tY);
+ var denominator = (tVec.x * dX + tVec.y * dY);
+ if (denominator == 0.0) {
+ if (numerator < 0.0) {
+ return false;
+ }
+ }
+ else {
+ if (denominator < 0.0 && numerator < lower * denominator) {
+ lower = numerator / denominator;
+ index = i;
+ }
+ else if (denominator > 0.0 && numerator < upper * denominator) {
+ upper = numerator / denominator;
+ }
+ }
+ if (upper < lower - Number.MIN_VALUE) {
+ return false;
+ }
+ }
+ if (index >= 0) {
+ output.fraction = lower;
+ tMat = transform.R;
+ tVec = this.m_normals[index];
+ output.normal.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ output.normal.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ return true;
+ }
+ return false;
+ }
+ b2PolygonShape.prototype.ComputeAABB = function (aabb, xf) {
+ var tMat = xf.R;
+ var tVec = this.m_vertices[0];
+ var lowerX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var lowerY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ var upperX = lowerX;
+ var upperY = lowerY;
+ for (var i = 1; i < this.m_vertexCount; ++i) {
+ tVec = this.m_vertices[i];
+ var vX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var vY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ lowerX = lowerX < vX ? lowerX : vX;
+ lowerY = lowerY < vY ? lowerY : vY;
+ upperX = upperX > vX ? upperX : vX;
+ upperY = upperY > vY ? upperY : vY;
+ }
+ aabb.lowerBound.x = lowerX - this.m_radius;
+ aabb.lowerBound.y = lowerY - this.m_radius;
+ aabb.upperBound.x = upperX + this.m_radius;
+ aabb.upperBound.y = upperY + this.m_radius;
+ }
+ b2PolygonShape.prototype.ComputeMass = function (massData, density) {
+ if (density === undefined) density = 0;
+ if (this.m_vertexCount == 2) {
+ massData.center.x = 0.5 * (this.m_vertices[0].x + this.m_vertices[1].x);
+ massData.center.y = 0.5 * (this.m_vertices[0].y + this.m_vertices[1].y);
+ massData.mass = 0.0;
+ massData.I = 0.0;
+ return;
+ }
+ var centerX = 0.0;
+ var centerY = 0.0;
+ var area = 0.0;
+ var I = 0.0;
+ var p1X = 0.0;
+ var p1Y = 0.0;
+ var k_inv3 = 1.0 / 3.0;
+ for (var i = 0; i < this.m_vertexCount; ++i) {
+ var p2 = this.m_vertices[i];
+ var p3 = i + 1 < this.m_vertexCount ? this.m_vertices[parseInt(i + 1)] : this.m_vertices[0];
+ var e1X = p2.x - p1X;
+ var e1Y = p2.y - p1Y;
+ var e2X = p3.x - p1X;
+ var e2Y = p3.y - p1Y;
+ var D = e1X * e2Y - e1Y * e2X;
+ var triangleArea = 0.5 * D;area += triangleArea;
+ centerX += triangleArea * k_inv3 * (p1X + p2.x + p3.x);
+ centerY += triangleArea * k_inv3 * (p1Y + p2.y + p3.y);
+ var px = p1X;
+ var py = p1Y;
+ var ex1 = e1X;
+ var ey1 = e1Y;
+ var ex2 = e2X;
+ var ey2 = e2Y;
+ var intx2 = k_inv3 * (0.25 * (ex1 * ex1 + ex2 * ex1 + ex2 * ex2) + (px * ex1 + px * ex2)) + 0.5 * px * px;
+ var inty2 = k_inv3 * (0.25 * (ey1 * ey1 + ey2 * ey1 + ey2 * ey2) + (py * ey1 + py * ey2)) + 0.5 * py * py;I += D * (intx2 + inty2);
+ }
+ massData.mass = density * area;
+ centerX *= 1.0 / area;
+ centerY *= 1.0 / area;
+ massData.center.Set(centerX, centerY);
+ massData.I = density * I;
+ }
+ b2PolygonShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) {
+ if (offset === undefined) offset = 0;
+ var normalL = b2Math.MulTMV(xf.R, normal);
+ var offsetL = offset - b2Math.Dot(normal, xf.position);
+ var depths = new Vector_a2j_Number();
+ var diveCount = 0;
+ var intoIndex = parseInt((-1));
+ var outoIndex = parseInt((-1));
+ var lastSubmerged = false;
+ var i = 0;
+ for (i = 0;
+ i < this.m_vertexCount; ++i) {
+ depths[i] = b2Math.Dot(normalL, this.m_vertices[i]) - offsetL;
+ var isSubmerged = depths[i] < (-Number.MIN_VALUE);
+ if (i > 0) {
+ if (isSubmerged) {
+ if (!lastSubmerged) {
+ intoIndex = i - 1;
+ diveCount++;
+ }
+ }
+ else {
+ if (lastSubmerged) {
+ outoIndex = i - 1;
+ diveCount++;
+ }
+ }
+ }
+ lastSubmerged = isSubmerged;
+ }
+ switch (diveCount) {
+ case 0:
+ if (lastSubmerged) {
+ var md = new b2MassData();
+ this.ComputeMass(md, 1);
+ c.SetV(b2Math.MulX(xf, md.center));
+ return md.mass;
+ }
+ else {
+ return 0;
+ }
+ break;
+ case 1:
+ if (intoIndex == (-1)) {
+ intoIndex = this.m_vertexCount - 1;
+ }
+ else {
+ outoIndex = this.m_vertexCount - 1;
+ }
+ break;
+ }
+ var intoIndex2 = parseInt((intoIndex + 1) % this.m_vertexCount);
+ var outoIndex2 = parseInt((outoIndex + 1) % this.m_vertexCount);
+ var intoLamdda = (0 - depths[intoIndex]) / (depths[intoIndex2] - depths[intoIndex]);
+ var outoLamdda = (0 - depths[outoIndex]) / (depths[outoIndex2] - depths[outoIndex]);
+ var intoVec = new b2Vec2(this.m_vertices[intoIndex].x * (1 - intoLamdda) + this.m_vertices[intoIndex2].x * intoLamdda, this.m_vertices[intoIndex].y * (1 - intoLamdda) + this.m_vertices[intoIndex2].y * intoLamdda);
+ var outoVec = new b2Vec2(this.m_vertices[outoIndex].x * (1 - outoLamdda) + this.m_vertices[outoIndex2].x * outoLamdda, this.m_vertices[outoIndex].y * (1 - outoLamdda) + this.m_vertices[outoIndex2].y * outoLamdda);
+ var area = 0;
+ var center = new b2Vec2();
+ var p2 = this.m_vertices[intoIndex2];
+ var p3;
+ i = intoIndex2;
+ while (i != outoIndex2) {
+ i = (i + 1) % this.m_vertexCount;
+ if (i == outoIndex2) p3 = outoVec;
+ else p3 = this.m_vertices[i];
+ var triangleArea = 0.5 * ((p2.x - intoVec.x) * (p3.y - intoVec.y) - (p2.y - intoVec.y) * (p3.x - intoVec.x));
+ area += triangleArea;
+ center.x += triangleArea * (intoVec.x + p2.x + p3.x) / 3;
+ center.y += triangleArea * (intoVec.y + p2.y + p3.y) / 3;
+ p2 = p3;
+ }
+ center.Multiply(1 / area);
+ c.SetV(b2Math.MulX(xf, center));
+ return area;
+ }
+ b2PolygonShape.prototype.GetVertexCount = function () {
+ return this.m_vertexCount;
+ }
+ b2PolygonShape.prototype.GetVertices = function () {
+ return this.m_vertices;
+ }
+ b2PolygonShape.prototype.GetNormals = function () {
+ return this.m_normals;
+ }
+ b2PolygonShape.prototype.GetSupport = function (d) {
+ var bestIndex = 0;
+ var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y;
+ for (var i = 1; i < this.m_vertexCount; ++i) {
+ var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y;
+ if (value > bestValue) {
+ bestIndex = i;
+ bestValue = value;
+ }
+ }
+ return bestIndex;
+ }
+ b2PolygonShape.prototype.GetSupportVertex = function (d) {
+ var bestIndex = 0;
+ var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y;
+ for (var i = 1; i < this.m_vertexCount; ++i) {
+ var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y;
+ if (value > bestValue) {
+ bestIndex = i;
+ bestValue = value;
+ }
+ }
+ return this.m_vertices[bestIndex];
+ }
+ b2PolygonShape.prototype.Validate = function () {
+ return false;
+ }
+ b2PolygonShape.prototype.b2PolygonShape = function () {
+ this.__super.b2Shape.call(this);
+ this.m_type = b2Shape.e_polygonShape;
+ this.m_centroid = new b2Vec2();
+ this.m_vertices = new Vector();
+ this.m_normals = new Vector();
+ }
+ b2PolygonShape.prototype.Reserve = function (count) {
+ if (count === undefined) count = 0;
+ for (var i = parseInt(this.m_vertices.length); i < count; i++) {
+ this.m_vertices[i] = new b2Vec2();
+ this.m_normals[i] = new b2Vec2();
+ }
+ }
+ b2PolygonShape.ComputeCentroid = function (vs, count) {
+ if (count === undefined) count = 0;
+ var c = new b2Vec2();
+ var area = 0.0;
+ var p1X = 0.0;
+ var p1Y = 0.0;
+ var inv3 = 1.0 / 3.0;
+ for (var i = 0; i < count; ++i) {
+ var p2 = vs[i];
+ var p3 = i + 1 < count ? vs[parseInt(i + 1)] : vs[0];
+ var e1X = p2.x - p1X;
+ var e1Y = p2.y - p1Y;
+ var e2X = p3.x - p1X;
+ var e2Y = p3.y - p1Y;
+ var D = (e1X * e2Y - e1Y * e2X);
+ var triangleArea = 0.5 * D;area += triangleArea;
+ c.x += triangleArea * inv3 * (p1X + p2.x + p3.x);
+ c.y += triangleArea * inv3 * (p1Y + p2.y + p3.y);
+ }
+ c.x *= 1.0 / area;
+ c.y *= 1.0 / area;
+ return c;
+ }
+ b2PolygonShape.ComputeOBB = function (obb, vs, count) {
+ if (count === undefined) count = 0;
+ var i = 0;
+ var p = new Vector(count + 1);
+ for (i = 0;
+ i < count; ++i) {
+ p[i] = vs[i];
+ }
+ p[count] = p[0];
+ var minArea = Number.MAX_VALUE;
+ for (i = 1;
+ i <= count; ++i) {
+ var root = p[parseInt(i - 1)];
+ var uxX = p[i].x - root.x;
+ var uxY = p[i].y - root.y;
+ var length = Math.sqrt(uxX * uxX + uxY * uxY);
+ uxX /= length;
+ uxY /= length;
+ var uyX = (-uxY);
+ var uyY = uxX;
+ var lowerX = Number.MAX_VALUE;
+ var lowerY = Number.MAX_VALUE;
+ var upperX = (-Number.MAX_VALUE);
+ var upperY = (-Number.MAX_VALUE);
+ for (var j = 0; j < count; ++j) {
+ var dX = p[j].x - root.x;
+ var dY = p[j].y - root.y;
+ var rX = (uxX * dX + uxY * dY);
+ var rY = (uyX * dX + uyY * dY);
+ if (rX < lowerX) lowerX = rX;
+ if (rY < lowerY) lowerY = rY;
+ if (rX > upperX) upperX = rX;
+ if (rY > upperY) upperY = rY;
+ }
+ var area = (upperX - lowerX) * (upperY - lowerY);
+ if (area < 0.95 * minArea) {
+ minArea = area;
+ obb.R.col1.x = uxX;
+ obb.R.col1.y = uxY;
+ obb.R.col2.x = uyX;
+ obb.R.col2.y = uyY;
+ var centerX = 0.5 * (lowerX + upperX);
+ var centerY = 0.5 * (lowerY + upperY);
+ var tMat = obb.R;
+ obb.center.x = root.x + (tMat.col1.x * centerX + tMat.col2.x * centerY);
+ obb.center.y = root.y + (tMat.col1.y * centerX + tMat.col2.y * centerY);
+ obb.extents.x = 0.5 * (upperX - lowerX);
+ obb.extents.y = 0.5 * (upperY - lowerY);
+ }
+ }
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Collision.Shapes.b2PolygonShape.s_mat = new b2Mat22();
+ });
+ b2Shape.b2Shape = function () {};
+ b2Shape.prototype.Copy = function () {
+ return null;
+ }
+ b2Shape.prototype.Set = function (other) {
+ this.m_radius = other.m_radius;
+ }
+ b2Shape.prototype.GetType = function () {
+ return this.m_type;
+ }
+ b2Shape.prototype.TestPoint = function (xf, p) {
+ return false;
+ }
+ b2Shape.prototype.RayCast = function (output, input, transform) {
+ return false;
+ }
+ b2Shape.prototype.ComputeAABB = function (aabb, xf) {}
+ b2Shape.prototype.ComputeMass = function (massData, density) {
+ if (density === undefined) density = 0;
+ }
+ b2Shape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) {
+ if (offset === undefined) offset = 0;
+ return 0;
+ }
+ b2Shape.TestOverlap = function (shape1, transform1, shape2, transform2) {
+ var input = new b2DistanceInput();
+ input.proxyA = new b2DistanceProxy();
+ input.proxyA.Set(shape1);
+ input.proxyB = new b2DistanceProxy();
+ input.proxyB.Set(shape2);
+ input.transformA = transform1;
+ input.transformB = transform2;
+ input.useRadii = true;
+ var simplexCache = new b2SimplexCache();
+ simplexCache.count = 0;
+ var output = new b2DistanceOutput();
+ b2Distance.Distance(output, simplexCache, input);
+ return output.distance < 10.0 * Number.MIN_VALUE;
+ }
+ b2Shape.prototype.b2Shape = function () {
+ this.m_type = b2Shape.e_unknownShape;
+ this.m_radius = b2Settings.b2_linearSlop;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Collision.Shapes.b2Shape.e_unknownShape = parseInt((-1));
+ Box2D.Collision.Shapes.b2Shape.e_circleShape = 0;
+ Box2D.Collision.Shapes.b2Shape.e_polygonShape = 1;
+ Box2D.Collision.Shapes.b2Shape.e_edgeShape = 2;
+ Box2D.Collision.Shapes.b2Shape.e_shapeTypeCount = 3;
+ Box2D.Collision.Shapes.b2Shape.e_hitCollide = 1;
+ Box2D.Collision.Shapes.b2Shape.e_missCollide = 0;
+ Box2D.Collision.Shapes.b2Shape.e_startsInsideCollide = parseInt((-1));
+ });
+})();
+(function () {
+ var b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3;
+
+ b2Color.b2Color = function () {
+ this._r = 0;
+ this._g = 0;
+ this._b = 0;
+ };
+ b2Color.prototype.b2Color = function (rr, gg, bb) {
+ if (rr === undefined) rr = 0;
+ if (gg === undefined) gg = 0;
+ if (bb === undefined) bb = 0;
+ this._r = Box2D.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0));
+ this._g = Box2D.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0));
+ this._b = Box2D.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0));
+ }
+ b2Color.prototype.Set = function (rr, gg, bb) {
+ if (rr === undefined) rr = 0;
+ if (gg === undefined) gg = 0;
+ if (bb === undefined) bb = 0;
+ this._r = Box2D.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0));
+ this._g = Box2D.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0));
+ this._b = Box2D.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0));
+ }
+ Object.defineProperty(b2Color.prototype, 'r', {
+ enumerable: false,
+ configurable: true,
+ set: function (rr) {
+ if (rr === undefined) rr = 0;
+ this._r = Box2D.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0));
+ }
+ });
+ Object.defineProperty(b2Color.prototype, 'g', {
+ enumerable: false,
+ configurable: true,
+ set: function (gg) {
+ if (gg === undefined) gg = 0;
+ this._g = Box2D.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0));
+ }
+ });
+ Object.defineProperty(b2Color.prototype, 'b', {
+ enumerable: false,
+ configurable: true,
+ set: function (bb) {
+ if (bb === undefined) bb = 0;
+ this._b = Box2D.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0));
+ }
+ });
+ Object.defineProperty(b2Color.prototype, 'color', {
+ enumerable: false,
+ configurable: true,
+ get: function () {
+ return (this._r << 16) | (this._g << 8) | (this._b);
+ }
+ });
+ b2Settings.b2Settings = function () {};
+ b2Settings.b2MixFriction = function (friction1, friction2) {
+ if (friction1 === undefined) friction1 = 0;
+ if (friction2 === undefined) friction2 = 0;
+ return Math.sqrt(friction1 * friction2);
+ }
+ b2Settings.b2MixRestitution = function (restitution1, restitution2) {
+ if (restitution1 === undefined) restitution1 = 0;
+ if (restitution2 === undefined) restitution2 = 0;
+ return restitution1 > restitution2 ? restitution1 : restitution2;
+ }
+ b2Settings.b2Assert = function (a) {
+ if (!a) {
+ throw "Assertion Failed";
+ }
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Common.b2Settings.VERSION = "2.1alpha";
+ Box2D.Common.b2Settings.USHRT_MAX = 0x0000ffff;
+ Box2D.Common.b2Settings.b2_pi = Math.PI;
+ Box2D.Common.b2Settings.b2_maxManifoldPoints = 2;
+ Box2D.Common.b2Settings.b2_aabbExtension = 0.1;
+ Box2D.Common.b2Settings.b2_aabbMultiplier = 2.0;
+ Box2D.Common.b2Settings.b2_polygonRadius = 2.0 * b2Settings.b2_linearSlop;
+ Box2D.Common.b2Settings.b2_linearSlop = 0.005;
+ Box2D.Common.b2Settings.b2_angularSlop = 2.0 / 180.0 * b2Settings.b2_pi;
+ Box2D.Common.b2Settings.b2_toiSlop = 8.0 * b2Settings.b2_linearSlop;
+ Box2D.Common.b2Settings.b2_maxTOIContactsPerIsland = 32;
+ Box2D.Common.b2Settings.b2_maxTOIJointsPerIsland = 32;
+ Box2D.Common.b2Settings.b2_velocityThreshold = 1.0;
+ Box2D.Common.b2Settings.b2_maxLinearCorrection = 0.2;
+ Box2D.Common.b2Settings.b2_maxAngularCorrection = 8.0 / 180.0 * b2Settings.b2_pi;
+ Box2D.Common.b2Settings.b2_maxTranslation = 2.0;
+ Box2D.Common.b2Settings.b2_maxTranslationSquared = b2Settings.b2_maxTranslation * b2Settings.b2_maxTranslation;
+ Box2D.Common.b2Settings.b2_maxRotation = 0.5 * b2Settings.b2_pi;
+ Box2D.Common.b2Settings.b2_maxRotationSquared = b2Settings.b2_maxRotation * b2Settings.b2_maxRotation;
+ Box2D.Common.b2Settings.b2_contactBaumgarte = 0.2;
+ Box2D.Common.b2Settings.b2_timeToSleep = 0.5;
+ Box2D.Common.b2Settings.b2_linearSleepTolerance = 0.01;
+ Box2D.Common.b2Settings.b2_angularSleepTolerance = 2.0 / 180.0 * b2Settings.b2_pi;
+ });
+})();
+(function () {
+ var b2AABB = Box2D.Collision.b2AABB,
+ b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3;
+
+ b2Mat22.b2Mat22 = function () {
+ this.col1 = new b2Vec2();
+ this.col2 = new b2Vec2();
+ };
+ b2Mat22.prototype.b2Mat22 = function () {
+ this.SetIdentity();
+ }
+ b2Mat22.FromAngle = function (angle) {
+ if (angle === undefined) angle = 0;
+ var mat = new b2Mat22();
+ mat.Set(angle);
+ return mat;
+ }
+ b2Mat22.FromVV = function (c1, c2) {
+ var mat = new b2Mat22();
+ mat.SetVV(c1, c2);
+ return mat;
+ }
+ b2Mat22.prototype.Set = function (angle) {
+ if (angle === undefined) angle = 0;
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+ this.col1.x = c;
+ this.col2.x = (-s);
+ this.col1.y = s;
+ this.col2.y = c;
+ }
+ b2Mat22.prototype.SetVV = function (c1, c2) {
+ this.col1.SetV(c1);
+ this.col2.SetV(c2);
+ }
+ b2Mat22.prototype.Copy = function () {
+ var mat = new b2Mat22();
+ mat.SetM(this);
+ return mat;
+ }
+ b2Mat22.prototype.SetM = function (m) {
+ this.col1.SetV(m.col1);
+ this.col2.SetV(m.col2);
+ }
+ b2Mat22.prototype.AddM = function (m) {
+ this.col1.x += m.col1.x;
+ this.col1.y += m.col1.y;
+ this.col2.x += m.col2.x;
+ this.col2.y += m.col2.y;
+ }
+ b2Mat22.prototype.SetIdentity = function () {
+ this.col1.x = 1.0;
+ this.col2.x = 0.0;
+ this.col1.y = 0.0;
+ this.col2.y = 1.0;
+ }
+ b2Mat22.prototype.SetZero = function () {
+ this.col1.x = 0.0;
+ this.col2.x = 0.0;
+ this.col1.y = 0.0;
+ this.col2.y = 0.0;
+ }
+ b2Mat22.prototype.GetAngle = function () {
+ return Math.atan2(this.col1.y, this.col1.x);
+ }
+ b2Mat22.prototype.GetInverse = function (out) {
+ var a = this.col1.x;
+ var b = this.col2.x;
+ var c = this.col1.y;
+ var d = this.col2.y;
+ var det = a * d - b * c;
+ if (det != 0.0) {
+ det = 1.0 / det;
+ }
+ out.col1.x = det * d;
+ out.col2.x = (-det * b);
+ out.col1.y = (-det * c);
+ out.col2.y = det * a;
+ return out;
+ }
+ b2Mat22.prototype.Solve = function (out, bX, bY) {
+ if (bX === undefined) bX = 0;
+ if (bY === undefined) bY = 0;
+ var a11 = this.col1.x;
+ var a12 = this.col2.x;
+ var a21 = this.col1.y;
+ var a22 = this.col2.y;
+ var det = a11 * a22 - a12 * a21;
+ if (det != 0.0) {
+ det = 1.0 / det;
+ }
+ out.x = det * (a22 * bX - a12 * bY);
+ out.y = det * (a11 * bY - a21 * bX);
+ return out;
+ }
+ b2Mat22.prototype.Abs = function () {
+ this.col1.Abs();
+ this.col2.Abs();
+ }
+ b2Mat33.b2Mat33 = function () {
+ this.col1 = new b2Vec3();
+ this.col2 = new b2Vec3();
+ this.col3 = new b2Vec3();
+ };
+ b2Mat33.prototype.b2Mat33 = function (c1, c2, c3) {
+ if (c1 === undefined) c1 = null;
+ if (c2 === undefined) c2 = null;
+ if (c3 === undefined) c3 = null;
+ if (!c1 && !c2 && !c3) {
+ this.col1.SetZero();
+ this.col2.SetZero();
+ this.col3.SetZero();
+ }
+ else {
+ this.col1.SetV(c1);
+ this.col2.SetV(c2);
+ this.col3.SetV(c3);
+ }
+ }
+ b2Mat33.prototype.SetVVV = function (c1, c2, c3) {
+ this.col1.SetV(c1);
+ this.col2.SetV(c2);
+ this.col3.SetV(c3);
+ }
+ b2Mat33.prototype.Copy = function () {
+ return new b2Mat33(this.col1, this.col2, this.col3);
+ }
+ b2Mat33.prototype.SetM = function (m) {
+ this.col1.SetV(m.col1);
+ this.col2.SetV(m.col2);
+ this.col3.SetV(m.col3);
+ }
+ b2Mat33.prototype.AddM = function (m) {
+ this.col1.x += m.col1.x;
+ this.col1.y += m.col1.y;
+ this.col1.z += m.col1.z;
+ this.col2.x += m.col2.x;
+ this.col2.y += m.col2.y;
+ this.col2.z += m.col2.z;
+ this.col3.x += m.col3.x;
+ this.col3.y += m.col3.y;
+ this.col3.z += m.col3.z;
+ }
+ b2Mat33.prototype.SetIdentity = function () {
+ this.col1.x = 1.0;
+ this.col2.x = 0.0;
+ this.col3.x = 0.0;
+ this.col1.y = 0.0;
+ this.col2.y = 1.0;
+ this.col3.y = 0.0;
+ this.col1.z = 0.0;
+ this.col2.z = 0.0;
+ this.col3.z = 1.0;
+ }
+ b2Mat33.prototype.SetZero = function () {
+ this.col1.x = 0.0;
+ this.col2.x = 0.0;
+ this.col3.x = 0.0;
+ this.col1.y = 0.0;
+ this.col2.y = 0.0;
+ this.col3.y = 0.0;
+ this.col1.z = 0.0;
+ this.col2.z = 0.0;
+ this.col3.z = 0.0;
+ }
+ b2Mat33.prototype.Solve22 = function (out, bX, bY) {
+ if (bX === undefined) bX = 0;
+ if (bY === undefined) bY = 0;
+ var a11 = this.col1.x;
+ var a12 = this.col2.x;
+ var a21 = this.col1.y;
+ var a22 = this.col2.y;
+ var det = a11 * a22 - a12 * a21;
+ if (det != 0.0) {
+ det = 1.0 / det;
+ }
+ out.x = det * (a22 * bX - a12 * bY);
+ out.y = det * (a11 * bY - a21 * bX);
+ return out;
+ }
+ b2Mat33.prototype.Solve33 = function (out, bX, bY, bZ) {
+ if (bX === undefined) bX = 0;
+ if (bY === undefined) bY = 0;
+ if (bZ === undefined) bZ = 0;
+ var a11 = this.col1.x;
+ var a21 = this.col1.y;
+ var a31 = this.col1.z;
+ var a12 = this.col2.x;
+ var a22 = this.col2.y;
+ var a32 = this.col2.z;
+ var a13 = this.col3.x;
+ var a23 = this.col3.y;
+ var a33 = this.col3.z;
+ var det = a11 * (a22 * a33 - a32 * a23) + a21 * (a32 * a13 - a12 * a33) + a31 * (a12 * a23 - a22 * a13);
+ if (det != 0.0) {
+ det = 1.0 / det;
+ }
+ out.x = det * (bX * (a22 * a33 - a32 * a23) + bY * (a32 * a13 - a12 * a33) + bZ * (a12 * a23 - a22 * a13));
+ out.y = det * (a11 * (bY * a33 - bZ * a23) + a21 * (bZ * a13 - bX * a33) + a31 * (bX * a23 - bY * a13));
+ out.z = det * (a11 * (a22 * bZ - a32 * bY) + a21 * (a32 * bX - a12 * bZ) + a31 * (a12 * bY - a22 * bX));
+ return out;
+ }
+ b2Math.b2Math = function () {};
+ b2Math.IsValid = function (x) {
+ if (x === undefined) x = 0;
+ return isFinite(x);
+ }
+ b2Math.Dot = function (a, b) {
+ return a.x * b.x + a.y * b.y;
+ }
+ b2Math.CrossVV = function (a, b) {
+ return a.x * b.y - a.y * b.x;
+ }
+ b2Math.CrossVF = function (a, s) {
+ if (s === undefined) s = 0;
+ var v = new b2Vec2(s * a.y, (-s * a.x));
+ return v;
+ }
+ b2Math.CrossFV = function (s, a) {
+ if (s === undefined) s = 0;
+ var v = new b2Vec2((-s * a.y), s * a.x);
+ return v;
+ }
+ b2Math.MulMV = function (A, v) {
+ var u = new b2Vec2(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y);
+ return u;
+ }
+ b2Math.MulTMV = function (A, v) {
+ var u = new b2Vec2(b2Math.Dot(v, A.col1), b2Math.Dot(v, A.col2));
+ return u;
+ }
+ b2Math.MulX = function (T, v) {
+ var a = b2Math.MulMV(T.R, v);
+ a.x += T.position.x;
+ a.y += T.position.y;
+ return a;
+ }
+ b2Math.MulXT = function (T, v) {
+ var a = b2Math.SubtractVV(v, T.position);
+ var tX = (a.x * T.R.col1.x + a.y * T.R.col1.y);
+ a.y = (a.x * T.R.col2.x + a.y * T.R.col2.y);
+ a.x = tX;
+ return a;
+ }
+ b2Math.AddVV = function (a, b) {
+ var v = new b2Vec2(a.x + b.x, a.y + b.y);
+ return v;
+ }
+ b2Math.SubtractVV = function (a, b) {
+ var v = new b2Vec2(a.x - b.x, a.y - b.y);
+ return v;
+ }
+ b2Math.Distance = function (a, b) {
+ var cX = a.x - b.x;
+ var cY = a.y - b.y;
+ return Math.sqrt(cX * cX + cY * cY);
+ }
+ b2Math.DistanceSquared = function (a, b) {
+ var cX = a.x - b.x;
+ var cY = a.y - b.y;
+ return (cX * cX + cY * cY);
+ }
+ b2Math.MulFV = function (s, a) {
+ if (s === undefined) s = 0;
+ var v = new b2Vec2(s * a.x, s * a.y);
+ return v;
+ }
+ b2Math.AddMM = function (A, B) {
+ var C = b2Mat22.FromVV(b2Math.AddVV(A.col1, B.col1), b2Math.AddVV(A.col2, B.col2));
+ return C;
+ }
+ b2Math.MulMM = function (A, B) {
+ var C = b2Mat22.FromVV(b2Math.MulMV(A, B.col1), b2Math.MulMV(A, B.col2));
+ return C;
+ }
+ b2Math.MulTMM = function (A, B) {
+ var c1 = new b2Vec2(b2Math.Dot(A.col1, B.col1), b2Math.Dot(A.col2, B.col1));
+ var c2 = new b2Vec2(b2Math.Dot(A.col1, B.col2), b2Math.Dot(A.col2, B.col2));
+ var C = b2Mat22.FromVV(c1, c2);
+ return C;
+ }
+ b2Math.Abs = function (a) {
+ if (a === undefined) a = 0;
+ return a > 0.0 ? a : (-a);
+ }
+ b2Math.AbsV = function (a) {
+ var b = new b2Vec2(b2Math.Abs(a.x), b2Math.Abs(a.y));
+ return b;
+ }
+ b2Math.AbsM = function (A) {
+ var B = b2Mat22.FromVV(b2Math.AbsV(A.col1), b2Math.AbsV(A.col2));
+ return B;
+ }
+ b2Math.Min = function (a, b) {
+ if (a === undefined) a = 0;
+ if (b === undefined) b = 0;
+ return a < b ? a : b;
+ }
+ b2Math.MinV = function (a, b) {
+ var c = new b2Vec2(b2Math.Min(a.x, b.x), b2Math.Min(a.y, b.y));
+ return c;
+ }
+ b2Math.Max = function (a, b) {
+ if (a === undefined) a = 0;
+ if (b === undefined) b = 0;
+ return a > b ? a : b;
+ }
+ b2Math.MaxV = function (a, b) {
+ var c = new b2Vec2(b2Math.Max(a.x, b.x), b2Math.Max(a.y, b.y));
+ return c;
+ }
+ b2Math.Clamp = function (a, low, high) {
+ if (a === undefined) a = 0;
+ if (low === undefined) low = 0;
+ if (high === undefined) high = 0;
+ return a < low ? low : a > high ? high : a;
+ }
+ b2Math.ClampV = function (a, low, high) {
+ return b2Math.MaxV(low, b2Math.MinV(a, high));
+ }
+ b2Math.Swap = function (a, b) {
+ var tmp = a[0];
+ a[0] = b[0];
+ b[0] = tmp;
+ }
+ b2Math.Random = function () {
+ return Math.random() * 2 - 1;
+ }
+ b2Math.RandomRange = function (lo, hi) {
+ if (lo === undefined) lo = 0;
+ if (hi === undefined) hi = 0;
+ var r = Math.random();
+ r = (hi - lo) * r + lo;
+ return r;
+ }
+ b2Math.NextPowerOfTwo = function (x) {
+ if (x === undefined) x = 0;
+ x |= (x >> 1) & 0x7FFFFFFF;
+ x |= (x >> 2) & 0x3FFFFFFF;
+ x |= (x >> 4) & 0x0FFFFFFF;
+ x |= (x >> 8) & 0x00FFFFFF;
+ x |= (x >> 16) & 0x0000FFFF;
+ return x + 1;
+ }
+ b2Math.IsPowerOfTwo = function (x) {
+ if (x === undefined) x = 0;
+ var result = x > 0 && (x & (x - 1)) == 0;
+ return result;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Common.Math.b2Math.b2Vec2_zero = new b2Vec2(0.0, 0.0);
+ Box2D.Common.Math.b2Math.b2Mat22_identity = b2Mat22.FromVV(new b2Vec2(1.0, 0.0), new b2Vec2(0.0, 1.0));
+ Box2D.Common.Math.b2Math.b2Transform_identity = new b2Transform(b2Math.b2Vec2_zero, b2Math.b2Mat22_identity);
+ });
+ b2Sweep.b2Sweep = function () {
+ this.localCenter = new b2Vec2();
+ this.c0 = new b2Vec2;
+ this.c = new b2Vec2();
+ };
+ b2Sweep.prototype.Set = function (other) {
+ this.localCenter.SetV(other.localCenter);
+ this.c0.SetV(other.c0);
+ this.c.SetV(other.c);
+ this.a0 = other.a0;
+ this.a = other.a;
+ this.t0 = other.t0;
+ }
+ b2Sweep.prototype.Copy = function () {
+ var copy = new b2Sweep();
+ copy.localCenter.SetV(this.localCenter);
+ copy.c0.SetV(this.c0);
+ copy.c.SetV(this.c);
+ copy.a0 = this.a0;
+ copy.a = this.a;
+ copy.t0 = this.t0;
+ return copy;
+ }
+ b2Sweep.prototype.GetTransform = function (xf, alpha) {
+ if (alpha === undefined) alpha = 0;
+ xf.position.x = (1.0 - alpha) * this.c0.x + alpha * this.c.x;
+ xf.position.y = (1.0 - alpha) * this.c0.y + alpha * this.c.y;
+ var angle = (1.0 - alpha) * this.a0 + alpha * this.a;
+ xf.R.Set(angle);
+ var tMat = xf.R;
+ xf.position.x -= (tMat.col1.x * this.localCenter.x + tMat.col2.x * this.localCenter.y);
+ xf.position.y -= (tMat.col1.y * this.localCenter.x + tMat.col2.y * this.localCenter.y);
+ }
+ b2Sweep.prototype.Advance = function (t) {
+ if (t === undefined) t = 0;
+ if (this.t0 < t && 1.0 - this.t0 > Number.MIN_VALUE) {
+ var alpha = (t - this.t0) / (1.0 - this.t0);
+ this.c0.x = (1.0 - alpha) * this.c0.x + alpha * this.c.x;
+ this.c0.y = (1.0 - alpha) * this.c0.y + alpha * this.c.y;
+ this.a0 = (1.0 - alpha) * this.a0 + alpha * this.a;
+ this.t0 = t;
+ }
+ }
+ b2Transform.b2Transform = function () {
+ this.position = new b2Vec2;
+ this.R = new b2Mat22();
+ };
+ b2Transform.prototype.b2Transform = function (pos, r) {
+ if (pos === undefined) pos = null;
+ if (r === undefined) r = null;
+ if (pos) {
+ this.position.SetV(pos);
+ this.R.SetM(r);
+ }
+ }
+ b2Transform.prototype.Initialize = function (pos, r) {
+ this.position.SetV(pos);
+ this.R.SetM(r);
+ }
+ b2Transform.prototype.SetIdentity = function () {
+ this.position.SetZero();
+ this.R.SetIdentity();
+ }
+ b2Transform.prototype.Set = function (x) {
+ this.position.SetV(x.position);
+ this.R.SetM(x.R);
+ }
+ b2Transform.prototype.GetAngle = function () {
+ return Math.atan2(this.R.col1.y, this.R.col1.x);
+ }
+ b2Vec2.b2Vec2 = function () {};
+ b2Vec2.prototype.b2Vec2 = function (x_, y_) {
+ if (x_ === undefined) x_ = 0;
+ if (y_ === undefined) y_ = 0;
+ this.x = x_;
+ this.y = y_;
+ }
+ b2Vec2.prototype.SetZero = function () {
+ this.x = 0.0;
+ this.y = 0.0;
+ }
+ b2Vec2.prototype.Set = function (x_, y_) {
+ if (x_ === undefined) x_ = 0;
+ if (y_ === undefined) y_ = 0;
+ this.x = x_;
+ this.y = y_;
+ }
+ b2Vec2.prototype.SetV = function (v) {
+ this.x = v.x;
+ this.y = v.y;
+ }
+ b2Vec2.prototype.GetNegative = function () {
+ return new b2Vec2((-this.x), (-this.y));
+ }
+ b2Vec2.prototype.NegativeSelf = function () {
+ this.x = (-this.x);
+ this.y = (-this.y);
+ }
+ b2Vec2.Make = function (x_, y_) {
+ if (x_ === undefined) x_ = 0;
+ if (y_ === undefined) y_ = 0;
+ return new b2Vec2(x_, y_);
+ }
+ b2Vec2.prototype.Copy = function () {
+ return new b2Vec2(this.x, this.y);
+ }
+ b2Vec2.prototype.Add = function (v) {
+ this.x += v.x;
+ this.y += v.y;
+ }
+ b2Vec2.prototype.Subtract = function (v) {
+ this.x -= v.x;
+ this.y -= v.y;
+ }
+ b2Vec2.prototype.Multiply = function (a) {
+ if (a === undefined) a = 0;
+ this.x *= a;
+ this.y *= a;
+ }
+ b2Vec2.prototype.MulM = function (A) {
+ var tX = this.x;
+ this.x = A.col1.x * tX + A.col2.x * this.y;
+ this.y = A.col1.y * tX + A.col2.y * this.y;
+ }
+ b2Vec2.prototype.MulTM = function (A) {
+ var tX = b2Math.Dot(this, A.col1);
+ this.y = b2Math.Dot(this, A.col2);
+ this.x = tX;
+ }
+ b2Vec2.prototype.CrossVF = function (s) {
+ if (s === undefined) s = 0;
+ var tX = this.x;
+ this.x = s * this.y;
+ this.y = (-s * tX);
+ }
+ b2Vec2.prototype.CrossFV = function (s) {
+ if (s === undefined) s = 0;
+ var tX = this.x;
+ this.x = (-s * this.y);
+ this.y = s * tX;
+ }
+ b2Vec2.prototype.MinV = function (b) {
+ this.x = this.x < b.x ? this.x : b.x;
+ this.y = this.y < b.y ? this.y : b.y;
+ }
+ b2Vec2.prototype.MaxV = function (b) {
+ this.x = this.x > b.x ? this.x : b.x;
+ this.y = this.y > b.y ? this.y : b.y;
+ }
+ b2Vec2.prototype.Abs = function () {
+ if (this.x < 0) this.x = (-this.x);
+ if (this.y < 0) this.y = (-this.y);
+ }
+ b2Vec2.prototype.Length = function () {
+ return Math.sqrt(this.x * this.x + this.y * this.y);
+ }
+ b2Vec2.prototype.LengthSquared = function () {
+ return (this.x * this.x + this.y * this.y);
+ }
+ b2Vec2.prototype.Normalize = function () {
+ var length = Math.sqrt(this.x * this.x + this.y * this.y);
+ if (length < Number.MIN_VALUE) {
+ return 0.0;
+ }
+ var invLength = 1.0 / length;
+ this.x *= invLength;
+ this.y *= invLength;
+ return length;
+ }
+ b2Vec2.prototype.IsValid = function () {
+ return b2Math.IsValid(this.x) && b2Math.IsValid(this.y);
+ }
+ b2Vec3.b2Vec3 = function () {};
+ b2Vec3.prototype.b2Vec3 = function (x, y, z) {
+ if (x === undefined) x = 0;
+ if (y === undefined) y = 0;
+ if (z === undefined) z = 0;
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+ b2Vec3.prototype.SetZero = function () {
+ this.x = this.y = this.z = 0.0;
+ }
+ b2Vec3.prototype.Set = function (x, y, z) {
+ if (x === undefined) x = 0;
+ if (y === undefined) y = 0;
+ if (z === undefined) z = 0;
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+ b2Vec3.prototype.SetV = function (v) {
+ this.x = v.x;
+ this.y = v.y;
+ this.z = v.z;
+ }
+ b2Vec3.prototype.GetNegative = function () {
+ return new b2Vec3((-this.x), (-this.y), (-this.z));
+ }
+ b2Vec3.prototype.NegativeSelf = function () {
+ this.x = (-this.x);
+ this.y = (-this.y);
+ this.z = (-this.z);
+ }
+ b2Vec3.prototype.Copy = function () {
+ return new b2Vec3(this.x, this.y, this.z);
+ }
+ b2Vec3.prototype.Add = function (v) {
+ this.x += v.x;
+ this.y += v.y;
+ this.z += v.z;
+ }
+ b2Vec3.prototype.Subtract = function (v) {
+ this.x -= v.x;
+ this.y -= v.y;
+ this.z -= v.z;
+ }
+ b2Vec3.prototype.Multiply = function (a) {
+ if (a === undefined) a = 0;
+ this.x *= a;
+ this.y *= a;
+ this.z *= a;
+ }
+})();
+(function () {
+ var b2ControllerEdge = Box2D.Dynamics.Controllers.b2ControllerEdge,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3,
+ b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2AABB = Box2D.Collision.b2AABB,
+ b2Bound = Box2D.Collision.b2Bound,
+ b2BoundValues = Box2D.Collision.b2BoundValues,
+ b2Collision = Box2D.Collision.b2Collision,
+ b2ContactID = Box2D.Collision.b2ContactID,
+ b2ContactPoint = Box2D.Collision.b2ContactPoint,
+ b2Distance = Box2D.Collision.b2Distance,
+ b2DistanceInput = Box2D.Collision.b2DistanceInput,
+ b2DistanceOutput = Box2D.Collision.b2DistanceOutput,
+ b2DistanceProxy = Box2D.Collision.b2DistanceProxy,
+ b2DynamicTree = Box2D.Collision.b2DynamicTree,
+ b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase,
+ b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode,
+ b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair,
+ b2Manifold = Box2D.Collision.b2Manifold,
+ b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint,
+ b2Point = Box2D.Collision.b2Point,
+ b2RayCastInput = Box2D.Collision.b2RayCastInput,
+ b2RayCastOutput = Box2D.Collision.b2RayCastOutput,
+ b2Segment = Box2D.Collision.b2Segment,
+ b2SeparationFunction = Box2D.Collision.b2SeparationFunction,
+ b2Simplex = Box2D.Collision.b2Simplex,
+ b2SimplexCache = Box2D.Collision.b2SimplexCache,
+ b2SimplexVertex = Box2D.Collision.b2SimplexVertex,
+ b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact,
+ b2TOIInput = Box2D.Collision.b2TOIInput,
+ b2WorldManifold = Box2D.Collision.b2WorldManifold,
+ ClipVertex = Box2D.Collision.ClipVertex,
+ Features = Box2D.Collision.Features,
+ IBroadPhase = Box2D.Collision.IBroadPhase,
+ b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
+ b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef,
+ b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape,
+ b2MassData = Box2D.Collision.Shapes.b2MassData,
+ b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
+ b2Shape = Box2D.Collision.Shapes.b2Shape,
+ b2Body = Box2D.Dynamics.b2Body,
+ b2BodyDef = Box2D.Dynamics.b2BodyDef,
+ b2ContactFilter = Box2D.Dynamics.b2ContactFilter,
+ b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse,
+ b2ContactListener = Box2D.Dynamics.b2ContactListener,
+ b2ContactManager = Box2D.Dynamics.b2ContactManager,
+ b2DebugDraw = Box2D.Dynamics.b2DebugDraw,
+ b2DestructionListener = Box2D.Dynamics.b2DestructionListener,
+ b2FilterData = Box2D.Dynamics.b2FilterData,
+ b2Fixture = Box2D.Dynamics.b2Fixture,
+ b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
+ b2Island = Box2D.Dynamics.b2Island,
+ b2TimeStep = Box2D.Dynamics.b2TimeStep,
+ b2World = Box2D.Dynamics.b2World,
+ b2CircleContact = Box2D.Dynamics.Contacts.b2CircleContact,
+ b2Contact = Box2D.Dynamics.Contacts.b2Contact,
+ b2ContactConstraint = Box2D.Dynamics.Contacts.b2ContactConstraint,
+ b2ContactConstraintPoint = Box2D.Dynamics.Contacts.b2ContactConstraintPoint,
+ b2ContactEdge = Box2D.Dynamics.Contacts.b2ContactEdge,
+ b2ContactFactory = Box2D.Dynamics.Contacts.b2ContactFactory,
+ b2ContactRegister = Box2D.Dynamics.Contacts.b2ContactRegister,
+ b2ContactResult = Box2D.Dynamics.Contacts.b2ContactResult,
+ b2ContactSolver = Box2D.Dynamics.Contacts.b2ContactSolver,
+ b2EdgeAndCircleContact = Box2D.Dynamics.Contacts.b2EdgeAndCircleContact,
+ b2NullContact = Box2D.Dynamics.Contacts.b2NullContact,
+ b2PolyAndCircleContact = Box2D.Dynamics.Contacts.b2PolyAndCircleContact,
+ b2PolyAndEdgeContact = Box2D.Dynamics.Contacts.b2PolyAndEdgeContact,
+ b2PolygonContact = Box2D.Dynamics.Contacts.b2PolygonContact,
+ b2PositionSolverManifold = Box2D.Dynamics.Contacts.b2PositionSolverManifold,
+ b2Controller = Box2D.Dynamics.Controllers.b2Controller,
+ b2DistanceJoint = Box2D.Dynamics.Joints.b2DistanceJoint,
+ b2DistanceJointDef = Box2D.Dynamics.Joints.b2DistanceJointDef,
+ b2FrictionJoint = Box2D.Dynamics.Joints.b2FrictionJoint,
+ b2FrictionJointDef = Box2D.Dynamics.Joints.b2FrictionJointDef,
+ b2GearJoint = Box2D.Dynamics.Joints.b2GearJoint,
+ b2GearJointDef = Box2D.Dynamics.Joints.b2GearJointDef,
+ b2Jacobian = Box2D.Dynamics.Joints.b2Jacobian,
+ b2Joint = Box2D.Dynamics.Joints.b2Joint,
+ b2JointDef = Box2D.Dynamics.Joints.b2JointDef,
+ b2JointEdge = Box2D.Dynamics.Joints.b2JointEdge,
+ b2LineJoint = Box2D.Dynamics.Joints.b2LineJoint,
+ b2LineJointDef = Box2D.Dynamics.Joints.b2LineJointDef,
+ b2MouseJoint = Box2D.Dynamics.Joints.b2MouseJoint,
+ b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef,
+ b2PrismaticJoint = Box2D.Dynamics.Joints.b2PrismaticJoint,
+ b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef,
+ b2PulleyJoint = Box2D.Dynamics.Joints.b2PulleyJoint,
+ b2PulleyJointDef = Box2D.Dynamics.Joints.b2PulleyJointDef,
+ b2RevoluteJoint = Box2D.Dynamics.Joints.b2RevoluteJoint,
+ b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef,
+ b2WeldJoint = Box2D.Dynamics.Joints.b2WeldJoint,
+ b2WeldJointDef = Box2D.Dynamics.Joints.b2WeldJointDef;
+
+ b2Body.b2Body = function () {
+ this.m_xf = new b2Transform();
+ this.m_sweep = new b2Sweep();
+ this.m_linearVelocity = new b2Vec2();
+ this.m_force = new b2Vec2();
+ };
+ b2Body.prototype.connectEdges = function (s1, s2, angle1) {
+ if (angle1 === undefined) angle1 = 0;
+ var angle2 = Math.atan2(s2.GetDirectionVector().y, s2.GetDirectionVector().x);
+ var coreOffset = Math.tan((angle2 - angle1) * 0.5);
+ var core = b2Math.MulFV(coreOffset, s2.GetDirectionVector());
+ core = b2Math.SubtractVV(core, s2.GetNormalVector());
+ core = b2Math.MulFV(b2Settings.b2_toiSlop, core);
+ core = b2Math.AddVV(core, s2.GetVertex1());
+ var cornerDir = b2Math.AddVV(s1.GetDirectionVector(), s2.GetDirectionVector());
+ cornerDir.Normalize();
+ var convex = b2Math.Dot(s1.GetDirectionVector(), s2.GetNormalVector()) > 0.0;
+ s1.SetNextEdge(s2, core, cornerDir, convex);
+ s2.SetPrevEdge(s1, core, cornerDir, convex);
+ return angle2;
+ }
+ b2Body.prototype.CreateFixture = function (def) {
+ if (this.m_world.IsLocked() == true) {
+ return null;
+ }
+ var fixture = new b2Fixture();
+ fixture.Create(this, this.m_xf, def);
+ if (this.m_flags & b2Body.e_activeFlag) {
+ var broadPhase = this.m_world.m_contactManager.m_broadPhase;
+ fixture.CreateProxy(broadPhase, this.m_xf);
+ }
+ fixture.m_next = this.m_fixtureList;
+ this.m_fixtureList = fixture;
+ ++this.m_fixtureCount;
+ fixture.m_body = this;
+ if (fixture.m_density > 0.0) {
+ this.ResetMassData();
+ }
+ this.m_world.m_flags |= b2World.e_newFixture;
+ return fixture;
+ }
+ b2Body.prototype.CreateFixture2 = function (shape, density) {
+ if (density === undefined) density = 0.0;
+ var def = new b2FixtureDef();
+ def.shape = shape;
+ def.density = density;
+ return this.CreateFixture(def);
+ }
+ b2Body.prototype.DestroyFixture = function (fixture) {
+ if (this.m_world.IsLocked() == true) {
+ return;
+ }
+ var node = this.m_fixtureList;
+ var ppF = null;
+ var found = false;
+ while (node != null) {
+ if (node == fixture) {
+ if (ppF) ppF.m_next = fixture.m_next;
+ else this.m_fixtureList = fixture.m_next;
+ found = true;
+ break;
+ }
+ ppF = node;
+ node = node.m_next;
+ }
+ var edge = this.m_contactList;
+ while (edge) {
+ var c = edge.contact;
+ edge = edge.next;
+ var fixtureA = c.GetFixtureA();
+ var fixtureB = c.GetFixtureB();
+ if (fixture == fixtureA || fixture == fixtureB) {
+ this.m_world.m_contactManager.Destroy(c);
+ }
+ }
+ if (this.m_flags & b2Body.e_activeFlag) {
+ var broadPhase = this.m_world.m_contactManager.m_broadPhase;
+ fixture.DestroyProxy(broadPhase);
+ }
+ else {}
+ fixture.Destroy();
+ fixture.m_body = null;
+ fixture.m_next = null;
+ --this.m_fixtureCount;
+ this.ResetMassData();
+ }
+ b2Body.prototype.SetPositionAndAngle = function (position, angle) {
+ if (angle === undefined) angle = 0;
+ var f;
+ if (this.m_world.IsLocked() == true) {
+ return;
+ }
+ this.m_xf.R.Set(angle);
+ this.m_xf.position.SetV(position);
+ var tMat = this.m_xf.R;
+ var tVec = this.m_sweep.localCenter;
+ this.m_sweep.c.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ this.m_sweep.c.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ this.m_sweep.c.x += this.m_xf.position.x;
+ this.m_sweep.c.y += this.m_xf.position.y;
+ this.m_sweep.c0.SetV(this.m_sweep.c);
+ this.m_sweep.a0 = this.m_sweep.a = angle;
+ var broadPhase = this.m_world.m_contactManager.m_broadPhase;
+ for (f = this.m_fixtureList;
+ f; f = f.m_next) {
+ f.Synchronize(broadPhase, this.m_xf, this.m_xf);
+ }
+ this.m_world.m_contactManager.FindNewContacts();
+ }
+ b2Body.prototype.SetTransform = function (xf) {
+ this.SetPositionAndAngle(xf.position, xf.GetAngle());
+ }
+ b2Body.prototype.GetTransform = function () {
+ return this.m_xf;
+ }
+ b2Body.prototype.GetPosition = function () {
+ return this.m_xf.position;
+ }
+ b2Body.prototype.SetPosition = function (position) {
+ this.SetPositionAndAngle(position, this.GetAngle());
+ }
+ b2Body.prototype.GetAngle = function () {
+ return this.m_sweep.a;
+ }
+ b2Body.prototype.SetAngle = function (angle) {
+ if (angle === undefined) angle = 0;
+ this.SetPositionAndAngle(this.GetPosition(), angle);
+ }
+ b2Body.prototype.GetWorldCenter = function () {
+ return this.m_sweep.c;
+ }
+ b2Body.prototype.GetLocalCenter = function () {
+ return this.m_sweep.localCenter;
+ }
+ b2Body.prototype.SetLinearVelocity = function (v) {
+ if (this.m_type == b2Body.b2_staticBody) {
+ return;
+ }
+ this.m_linearVelocity.SetV(v);
+ }
+ b2Body.prototype.GetLinearVelocity = function () {
+ return this.m_linearVelocity;
+ }
+ b2Body.prototype.SetAngularVelocity = function (omega) {
+ if (omega === undefined) omega = 0;
+ if (this.m_type == b2Body.b2_staticBody) {
+ return;
+ }
+ this.m_angularVelocity = omega;
+ }
+ b2Body.prototype.GetAngularVelocity = function () {
+ return this.m_angularVelocity;
+ }
+ b2Body.prototype.GetDefinition = function () {
+ var bd = new b2BodyDef();
+ bd.type = this.GetType();
+ bd.allowSleep = (this.m_flags & b2Body.e_allowSleepFlag) == b2Body.e_allowSleepFlag;
+ bd.angle = this.GetAngle();
+ bd.angularDamping = this.m_angularDamping;
+ bd.angularVelocity = this.m_angularVelocity;
+ bd.fixedRotation = (this.m_flags & b2Body.e_fixedRotationFlag) == b2Body.e_fixedRotationFlag;
+ bd.bullet = (this.m_flags & b2Body.e_bulletFlag) == b2Body.e_bulletFlag;
+ bd.awake = (this.m_flags & b2Body.e_awakeFlag) == b2Body.e_awakeFlag;
+ bd.linearDamping = this.m_linearDamping;
+ bd.linearVelocity.SetV(this.GetLinearVelocity());
+ bd.position = this.GetPosition();
+ bd.userData = this.GetUserData();
+ return bd;
+ }
+ b2Body.prototype.ApplyForce = function (force, point) {
+ if (this.m_type != b2Body.b2_dynamicBody) {
+ return;
+ }
+ if (this.IsAwake() == false) {
+ this.SetAwake(true);
+ }
+ this.m_force.x += force.x;
+ this.m_force.y += force.y;
+ this.m_torque += ((point.x - this.m_sweep.c.x) * force.y - (point.y - this.m_sweep.c.y) * force.x);
+ }
+ b2Body.prototype.ApplyTorque = function (torque) {
+ if (torque === undefined) torque = 0;
+ if (this.m_type != b2Body.b2_dynamicBody) {
+ return;
+ }
+ if (this.IsAwake() == false) {
+ this.SetAwake(true);
+ }
+ this.m_torque += torque;
+ }
+ b2Body.prototype.ApplyImpulse = function (impulse, point) {
+ if (this.m_type != b2Body.b2_dynamicBody) {
+ return;
+ }
+ if (this.IsAwake() == false) {
+ this.SetAwake(true);
+ }
+ this.m_linearVelocity.x += this.m_invMass * impulse.x;
+ this.m_linearVelocity.y += this.m_invMass * impulse.y;
+ this.m_angularVelocity += this.m_invI * ((point.x - this.m_sweep.c.x) * impulse.y - (point.y - this.m_sweep.c.y) * impulse.x);
+ }
+ b2Body.prototype.Split = function (callback) {
+ var linearVelocity = this.GetLinearVelocity().Copy();
+ var angularVelocity = this.GetAngularVelocity();
+ var center = this.GetWorldCenter();
+ var body1 = this;
+ var body2 = this.m_world.CreateBody(this.GetDefinition());
+ var prev;
+ for (var f = body1.m_fixtureList; f;) {
+ if (callback(f)) {
+ var next = f.m_next;
+ if (prev) {
+ prev.m_next = next;
+ }
+ else {
+ body1.m_fixtureList = next;
+ }
+ body1.m_fixtureCount--;
+ f.m_next = body2.m_fixtureList;
+ body2.m_fixtureList = f;
+ body2.m_fixtureCount++;
+ f.m_body = body2;
+ f = next;
+ }
+ else {
+ prev = f;
+ f = f.m_next;
+ }
+ }
+ body1.ResetMassData();
+ body2.ResetMassData();
+ var center1 = body1.GetWorldCenter();
+ var center2 = body2.GetWorldCenter();
+ var velocity1 = b2Math.AddVV(linearVelocity, b2Math.CrossFV(angularVelocity, b2Math.SubtractVV(center1, center)));
+ var velocity2 = b2Math.AddVV(linearVelocity, b2Math.CrossFV(angularVelocity, b2Math.SubtractVV(center2, center)));
+ body1.SetLinearVelocity(velocity1);
+ body2.SetLinearVelocity(velocity2);
+ body1.SetAngularVelocity(angularVelocity);
+ body2.SetAngularVelocity(angularVelocity);
+ body1.SynchronizeFixtures();
+ body2.SynchronizeFixtures();
+ return body2;
+ }
+ b2Body.prototype.Merge = function (other) {
+ var f;
+ for (f = other.m_fixtureList;
+ f;) {
+ var next = f.m_next;
+ other.m_fixtureCount--;
+ f.m_next = this.m_fixtureList;
+ this.m_fixtureList = f;
+ this.m_fixtureCount++;
+ f.m_body = body2;
+ f = next;
+ }
+ body1.m_fixtureCount = 0;
+ var body1 = this;
+ var body2 = other;
+ var center1 = body1.GetWorldCenter();
+ var center2 = body2.GetWorldCenter();
+ var velocity1 = body1.GetLinearVelocity().Copy();
+ var velocity2 = body2.GetLinearVelocity().Copy();
+ var angular1 = body1.GetAngularVelocity();
+ var angular = body2.GetAngularVelocity();
+ body1.ResetMassData();
+ this.SynchronizeFixtures();
+ }
+ b2Body.prototype.GetMass = function () {
+ return this.m_mass;
+ }
+ b2Body.prototype.GetInertia = function () {
+ return this.m_I;
+ }
+ b2Body.prototype.GetMassData = function (data) {
+ data.mass = this.m_mass;
+ data.I = this.m_I;
+ data.center.SetV(this.m_sweep.localCenter);
+ }
+ b2Body.prototype.SetMassData = function (massData) {
+ b2Settings.b2Assert(this.m_world.IsLocked() == false);
+ if (this.m_world.IsLocked() == true) {
+ return;
+ }
+ if (this.m_type != b2Body.b2_dynamicBody) {
+ return;
+ }
+ this.m_invMass = 0.0;
+ this.m_I = 0.0;
+ this.m_invI = 0.0;
+ this.m_mass = massData.mass;
+ if (this.m_mass <= 0.0) {
+ this.m_mass = 1.0;
+ }
+ this.m_invMass = 1.0 / this.m_mass;
+ if (massData.I > 0.0 && (this.m_flags & b2Body.e_fixedRotationFlag) == 0) {
+ this.m_I = massData.I - this.m_mass * (massData.center.x * massData.center.x + massData.center.y * massData.center.y);
+ this.m_invI = 1.0 / this.m_I;
+ }
+ var oldCenter = this.m_sweep.c.Copy();
+ this.m_sweep.localCenter.SetV(massData.center);
+ this.m_sweep.c0.SetV(b2Math.MulX(this.m_xf, this.m_sweep.localCenter));
+ this.m_sweep.c.SetV(this.m_sweep.c0);
+ this.m_linearVelocity.x += this.m_angularVelocity * (-(this.m_sweep.c.y - oldCenter.y));
+ this.m_linearVelocity.y += this.m_angularVelocity * (+(this.m_sweep.c.x - oldCenter.x));
+ }
+ b2Body.prototype.ResetMassData = function () {
+ this.m_mass = 0.0;
+ this.m_invMass = 0.0;
+ this.m_I = 0.0;
+ this.m_invI = 0.0;
+ this.m_sweep.localCenter.SetZero();
+ if (this.m_type == b2Body.b2_staticBody || this.m_type == b2Body.b2_kinematicBody) {
+ return;
+ }
+ var center = b2Vec2.Make(0, 0);
+ for (var f = this.m_fixtureList; f; f = f.m_next) {
+ if (f.m_density == 0.0) {
+ continue;
+ }
+ var massData = f.GetMassData();
+ this.m_mass += massData.mass;
+ center.x += massData.center.x * massData.mass;
+ center.y += massData.center.y * massData.mass;
+ this.m_I += massData.I;
+ }
+ if (this.m_mass > 0.0) {
+ this.m_invMass = 1.0 / this.m_mass;
+ center.x *= this.m_invMass;
+ center.y *= this.m_invMass;
+ }
+ else {
+ this.m_mass = 1.0;
+ this.m_invMass = 1.0;
+ }
+ if (this.m_I > 0.0 && (this.m_flags & b2Body.e_fixedRotationFlag) == 0) {
+ this.m_I -= this.m_mass * (center.x * center.x + center.y * center.y);
+ this.m_I *= this.m_inertiaScale;
+ b2Settings.b2Assert(this.m_I > 0);
+ this.m_invI = 1.0 / this.m_I;
+ }
+ else {
+ this.m_I = 0.0;
+ this.m_invI = 0.0;
+ }
+ var oldCenter = this.m_sweep.c.Copy();
+ this.m_sweep.localCenter.SetV(center);
+ this.m_sweep.c0.SetV(b2Math.MulX(this.m_xf, this.m_sweep.localCenter));
+ this.m_sweep.c.SetV(this.m_sweep.c0);
+ this.m_linearVelocity.x += this.m_angularVelocity * (-(this.m_sweep.c.y - oldCenter.y));
+ this.m_linearVelocity.y += this.m_angularVelocity * (+(this.m_sweep.c.x - oldCenter.x));
+ }
+ b2Body.prototype.GetWorldPoint = function (localPoint) {
+ var A = this.m_xf.R;
+ var u = new b2Vec2(A.col1.x * localPoint.x + A.col2.x * localPoint.y, A.col1.y * localPoint.x + A.col2.y * localPoint.y);
+ u.x += this.m_xf.position.x;
+ u.y += this.m_xf.position.y;
+ return u;
+ }
+ b2Body.prototype.GetWorldVector = function (localVector) {
+ return b2Math.MulMV(this.m_xf.R, localVector);
+ }
+ b2Body.prototype.GetLocalPoint = function (worldPoint) {
+ return b2Math.MulXT(this.m_xf, worldPoint);
+ }
+ b2Body.prototype.GetLocalVector = function (worldVector) {
+ return b2Math.MulTMV(this.m_xf.R, worldVector);
+ }
+ b2Body.prototype.GetLinearVelocityFromWorldPoint = function (worldPoint) {
+ return new b2Vec2(this.m_linearVelocity.x - this.m_angularVelocity * (worldPoint.y - this.m_sweep.c.y), this.m_linearVelocity.y + this.m_angularVelocity * (worldPoint.x - this.m_sweep.c.x));
+ }
+ b2Body.prototype.GetLinearVelocityFromLocalPoint = function (localPoint) {
+ var A = this.m_xf.R;
+ var worldPoint = new b2Vec2(A.col1.x * localPoint.x + A.col2.x * localPoint.y, A.col1.y * localPoint.x + A.col2.y * localPoint.y);
+ worldPoint.x += this.m_xf.position.x;
+ worldPoint.y += this.m_xf.position.y;
+ return new b2Vec2(this.m_linearVelocity.x - this.m_angularVelocity * (worldPoint.y - this.m_sweep.c.y), this.m_linearVelocity.y + this.m_angularVelocity * (worldPoint.x - this.m_sweep.c.x));
+ }
+ b2Body.prototype.GetLinearDamping = function () {
+ return this.m_linearDamping;
+ }
+ b2Body.prototype.SetLinearDamping = function (linearDamping) {
+ if (linearDamping === undefined) linearDamping = 0;
+ this.m_linearDamping = linearDamping;
+ }
+ b2Body.prototype.GetAngularDamping = function () {
+ return this.m_angularDamping;
+ }
+ b2Body.prototype.SetAngularDamping = function (angularDamping) {
+ if (angularDamping === undefined) angularDamping = 0;
+ this.m_angularDamping = angularDamping;
+ }
+ b2Body.prototype.SetType = function (type) {
+ if (type === undefined) type = 0;
+ if (this.m_type == type) {
+ return;
+ }
+ this.m_type = type;
+ this.ResetMassData();
+ if (this.m_type == b2Body.b2_staticBody) {
+ this.m_linearVelocity.SetZero();
+ this.m_angularVelocity = 0.0;
+ }
+ this.SetAwake(true);
+ this.m_force.SetZero();
+ this.m_torque = 0.0;
+ for (var ce = this.m_contactList; ce; ce = ce.next) {
+ ce.contact.FlagForFiltering();
+ }
+ }
+ b2Body.prototype.GetType = function () {
+ return this.m_type;
+ }
+ b2Body.prototype.SetBullet = function (flag) {
+ if (flag) {
+ this.m_flags |= b2Body.e_bulletFlag;
+ }
+ else {
+ this.m_flags &= ~b2Body.e_bulletFlag;
+ }
+ }
+ b2Body.prototype.IsBullet = function () {
+ return (this.m_flags & b2Body.e_bulletFlag) == b2Body.e_bulletFlag;
+ }
+ b2Body.prototype.SetSleepingAllowed = function (flag) {
+ if (flag) {
+ this.m_flags |= b2Body.e_allowSleepFlag;
+ }
+ else {
+ this.m_flags &= ~b2Body.e_allowSleepFlag;
+ this.SetAwake(true);
+ }
+ }
+ b2Body.prototype.SetAwake = function (flag) {
+ if (flag) {
+ this.m_flags |= b2Body.e_awakeFlag;
+ this.m_sleepTime = 0.0;
+ }
+ else {
+ this.m_flags &= ~b2Body.e_awakeFlag;
+ this.m_sleepTime = 0.0;
+ this.m_linearVelocity.SetZero();
+ this.m_angularVelocity = 0.0;
+ this.m_force.SetZero();
+ this.m_torque = 0.0;
+ }
+ }
+ b2Body.prototype.IsAwake = function () {
+ return (this.m_flags & b2Body.e_awakeFlag) == b2Body.e_awakeFlag;
+ }
+ b2Body.prototype.SetFixedRotation = function (fixed) {
+ if (fixed) {
+ this.m_flags |= b2Body.e_fixedRotationFlag;
+ }
+ else {
+ this.m_flags &= ~b2Body.e_fixedRotationFlag;
+ }
+ this.ResetMassData();
+ }
+ b2Body.prototype.IsFixedRotation = function () {
+ return (this.m_flags & b2Body.e_fixedRotationFlag) == b2Body.e_fixedRotationFlag;
+ }
+ b2Body.prototype.SetActive = function (flag) {
+ if (flag == this.IsActive()) {
+ return;
+ }
+ var broadPhase;
+ var f;
+ if (flag) {
+ this.m_flags |= b2Body.e_activeFlag;
+ broadPhase = this.m_world.m_contactManager.m_broadPhase;
+ for (f = this.m_fixtureList;
+ f; f = f.m_next) {
+ f.CreateProxy(broadPhase, this.m_xf);
+ }
+ }
+ else {
+ this.m_flags &= ~b2Body.e_activeFlag;
+ broadPhase = this.m_world.m_contactManager.m_broadPhase;
+ for (f = this.m_fixtureList;
+ f; f = f.m_next) {
+ f.DestroyProxy(broadPhase);
+ }
+ var ce = this.m_contactList;
+ while (ce) {
+ var ce0 = ce;
+ ce = ce.next;
+ this.m_world.m_contactManager.Destroy(ce0.contact);
+ }
+ this.m_contactList = null;
+ }
+ }
+ b2Body.prototype.IsActive = function () {
+ return (this.m_flags & b2Body.e_activeFlag) == b2Body.e_activeFlag;
+ }
+ b2Body.prototype.IsSleepingAllowed = function () {
+ return (this.m_flags & b2Body.e_allowSleepFlag) == b2Body.e_allowSleepFlag;
+ }
+ b2Body.prototype.GetFixtureList = function () {
+ return this.m_fixtureList;
+ }
+ b2Body.prototype.GetJointList = function () {
+ return this.m_jointList;
+ }
+ b2Body.prototype.GetControllerList = function () {
+ return this.m_controllerList;
+ }
+ b2Body.prototype.GetContactList = function () {
+ return this.m_contactList;
+ }
+ b2Body.prototype.GetNext = function () {
+ return this.m_next;
+ }
+ b2Body.prototype.GetUserData = function () {
+ return this.m_userData;
+ }
+ b2Body.prototype.SetUserData = function (data) {
+ this.m_userData = data;
+ }
+ b2Body.prototype.GetWorld = function () {
+ return this.m_world;
+ }
+ b2Body.prototype.b2Body = function (bd, world) {
+ this.m_flags = 0;
+ if (bd.bullet) {
+ this.m_flags |= b2Body.e_bulletFlag;
+ }
+ if (bd.fixedRotation) {
+ this.m_flags |= b2Body.e_fixedRotationFlag;
+ }
+ if (bd.allowSleep) {
+ this.m_flags |= b2Body.e_allowSleepFlag;
+ }
+ if (bd.awake) {
+ this.m_flags |= b2Body.e_awakeFlag;
+ }
+ if (bd.active) {
+ this.m_flags |= b2Body.e_activeFlag;
+ }
+ this.m_world = world;
+ this.m_xf.position.SetV(bd.position);
+ this.m_xf.R.Set(bd.angle);
+ this.m_sweep.localCenter.SetZero();
+ this.m_sweep.t0 = 1.0;
+ this.m_sweep.a0 = this.m_sweep.a = bd.angle;
+ var tMat = this.m_xf.R;
+ var tVec = this.m_sweep.localCenter;
+ this.m_sweep.c.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ this.m_sweep.c.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ this.m_sweep.c.x += this.m_xf.position.x;
+ this.m_sweep.c.y += this.m_xf.position.y;
+ this.m_sweep.c0.SetV(this.m_sweep.c);
+ this.m_jointList = null;
+ this.m_controllerList = null;
+ this.m_contactList = null;
+ this.m_controllerCount = 0;
+ this.m_prev = null;
+ this.m_next = null;
+ this.m_linearVelocity.SetV(bd.linearVelocity);
+ this.m_angularVelocity = bd.angularVelocity;
+ this.m_linearDamping = bd.linearDamping;
+ this.m_angularDamping = bd.angularDamping;
+ this.m_force.Set(0.0, 0.0);
+ this.m_torque = 0.0;
+ this.m_sleepTime = 0.0;
+ this.m_type = bd.type;
+ if (this.m_type == b2Body.b2_dynamicBody) {
+ this.m_mass = 1.0;
+ this.m_invMass = 1.0;
+ }
+ else {
+ this.m_mass = 0.0;
+ this.m_invMass = 0.0;
+ }
+ this.m_I = 0.0;
+ this.m_invI = 0.0;
+ this.m_inertiaScale = bd.inertiaScale;
+ this.m_userData = bd.userData;
+ this.m_fixtureList = null;
+ this.m_fixtureCount = 0;
+ }
+ b2Body.prototype.SynchronizeFixtures = function () {
+ var xf1 = b2Body.s_xf1;
+ xf1.R.Set(this.m_sweep.a0);
+ var tMat = xf1.R;
+ var tVec = this.m_sweep.localCenter;
+ xf1.position.x = this.m_sweep.c0.x - (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ xf1.position.y = this.m_sweep.c0.y - (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ var f;
+ var broadPhase = this.m_world.m_contactManager.m_broadPhase;
+ for (f = this.m_fixtureList;
+ f; f = f.m_next) {
+ f.Synchronize(broadPhase, xf1, this.m_xf);
+ }
+ }
+ b2Body.prototype.SynchronizeTransform = function () {
+ this.m_xf.R.Set(this.m_sweep.a);
+ var tMat = this.m_xf.R;
+ var tVec = this.m_sweep.localCenter;
+ this.m_xf.position.x = this.m_sweep.c.x - (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ this.m_xf.position.y = this.m_sweep.c.y - (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ }
+ b2Body.prototype.ShouldCollide = function (other) {
+ if (this.m_type != b2Body.b2_dynamicBody && other.m_type != b2Body.b2_dynamicBody) {
+ return false;
+ }
+ for (var jn = this.m_jointList; jn; jn = jn.next) {
+ if (jn.other == other) if (jn.joint.m_collideConnected == false) {
+ return false;
+ }
+ }
+ return true;
+ }
+ b2Body.prototype.Advance = function (t) {
+ if (t === undefined) t = 0;
+ this.m_sweep.Advance(t);
+ this.m_sweep.c.SetV(this.m_sweep.c0);
+ this.m_sweep.a = this.m_sweep.a0;
+ this.SynchronizeTransform();
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.b2Body.s_xf1 = new b2Transform();
+ Box2D.Dynamics.b2Body.e_islandFlag = 0x0001;
+ Box2D.Dynamics.b2Body.e_awakeFlag = 0x0002;
+ Box2D.Dynamics.b2Body.e_allowSleepFlag = 0x0004;
+ Box2D.Dynamics.b2Body.e_bulletFlag = 0x0008;
+ Box2D.Dynamics.b2Body.e_fixedRotationFlag = 0x0010;
+ Box2D.Dynamics.b2Body.e_activeFlag = 0x0020;
+ Box2D.Dynamics.b2Body.b2_staticBody = 0;
+ Box2D.Dynamics.b2Body.b2_kinematicBody = 1;
+ Box2D.Dynamics.b2Body.b2_dynamicBody = 2;
+ });
+ b2BodyDef.b2BodyDef = function () {
+ this.position = new b2Vec2();
+ this.linearVelocity = new b2Vec2();
+ };
+ b2BodyDef.prototype.b2BodyDef = function () {
+ this.userData = null;
+ this.position.Set(0.0, 0.0);
+ this.angle = 0.0;
+ this.linearVelocity.Set(0, 0);
+ this.angularVelocity = 0.0;
+ this.linearDamping = 0.0;
+ this.angularDamping = 0.0;
+ this.allowSleep = true;
+ this.awake = true;
+ this.fixedRotation = false;
+ this.bullet = false;
+ this.type = b2Body.b2_staticBody;
+ this.active = true;
+ this.inertiaScale = 1.0;
+ }
+ b2ContactFilter.b2ContactFilter = function () {};
+ b2ContactFilter.prototype.ShouldCollide = function (fixtureA, fixtureB) {
+ var filter1 = fixtureA.GetFilterData();
+ var filter2 = fixtureB.GetFilterData();
+ if (filter1.groupIndex == filter2.groupIndex && filter1.groupIndex != 0) {
+ return filter1.groupIndex > 0;
+ }
+ var collide = (filter1.maskBits & filter2.categoryBits) != 0 && (filter1.categoryBits & filter2.maskBits) != 0;
+ return collide;
+ }
+ b2ContactFilter.prototype.RayCollide = function (userData, fixture) {
+ if (!userData) return true;
+ return this.ShouldCollide((userData instanceof b2Fixture ? userData : null), fixture);
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.b2ContactFilter.b2_defaultFilter = new b2ContactFilter();
+ });
+ b2ContactImpulse.b2ContactImpulse = function () {
+ this.normalImpulses = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints);
+ this.tangentImpulses = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints);
+ };
+ b2ContactListener.b2ContactListener = function () {};
+ b2ContactListener.prototype.BeginContact = function (contact) {}
+ b2ContactListener.prototype.EndContact = function (contact) {}
+ b2ContactListener.prototype.PreSolve = function (contact, oldManifold) {}
+ b2ContactListener.prototype.PostSolve = function (contact, impulse) {}
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.b2ContactListener.b2_defaultListener = new b2ContactListener();
+ });
+ b2ContactManager.b2ContactManager = function () {};
+ b2ContactManager.prototype.b2ContactManager = function () {
+ this.m_world = null;
+ this.m_contactCount = 0;
+ this.m_contactFilter = b2ContactFilter.b2_defaultFilter;
+ this.m_contactListener = b2ContactListener.b2_defaultListener;
+ this.m_contactFactory = new b2ContactFactory(this.m_allocator);
+ this.m_broadPhase = new b2DynamicTreeBroadPhase();
+ }
+ b2ContactManager.prototype.AddPair = function (proxyUserDataA, proxyUserDataB) {
+ var fixtureA = (proxyUserDataA instanceof b2Fixture ? proxyUserDataA : null);
+ var fixtureB = (proxyUserDataB instanceof b2Fixture ? proxyUserDataB : null);
+ var bodyA = fixtureA.GetBody();
+ var bodyB = fixtureB.GetBody();
+ if (bodyA == bodyB) return;
+ var edge = bodyB.GetContactList();
+ while (edge) {
+ if (edge.other == bodyA) {
+ var fA = edge.contact.GetFixtureA();
+ var fB = edge.contact.GetFixtureB();
+ if (fA == fixtureA && fB == fixtureB) return;
+ if (fA == fixtureB && fB == fixtureA) return;
+ }
+ edge = edge.next;
+ }
+ if (bodyB.ShouldCollide(bodyA) == false) {
+ return;
+ }
+ if (this.m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) {
+ return;
+ }
+ var c = this.m_contactFactory.Create(fixtureA, fixtureB);
+ fixtureA = c.GetFixtureA();
+ fixtureB = c.GetFixtureB();
+ bodyA = fixtureA.m_body;
+ bodyB = fixtureB.m_body;
+ c.m_prev = null;
+ c.m_next = this.m_world.m_contactList;
+ if (this.m_world.m_contactList != null) {
+ this.m_world.m_contactList.m_prev = c;
+ }
+ this.m_world.m_contactList = c;
+ c.m_nodeA.contact = c;
+ c.m_nodeA.other = bodyB;
+ c.m_nodeA.prev = null;
+ c.m_nodeA.next = bodyA.m_contactList;
+ if (bodyA.m_contactList != null) {
+ bodyA.m_contactList.prev = c.m_nodeA;
+ }
+ bodyA.m_contactList = c.m_nodeA;
+ c.m_nodeB.contact = c;
+ c.m_nodeB.other = bodyA;
+ c.m_nodeB.prev = null;
+ c.m_nodeB.next = bodyB.m_contactList;
+ if (bodyB.m_contactList != null) {
+ bodyB.m_contactList.prev = c.m_nodeB;
+ }
+ bodyB.m_contactList = c.m_nodeB;
+ ++this.m_world.m_contactCount;
+ return;
+ }
+ b2ContactManager.prototype.FindNewContacts = function () {
+ this.m_broadPhase.UpdatePairs(Box2D.generateCallback(this, this.AddPair));
+ }
+ b2ContactManager.prototype.Destroy = function (c) {
+ var fixtureA = c.GetFixtureA();
+ var fixtureB = c.GetFixtureB();
+ var bodyA = fixtureA.GetBody();
+ var bodyB = fixtureB.GetBody();
+ if (c.IsTouching()) {
+ this.m_contactListener.EndContact(c);
+ }
+ if (c.m_prev) {
+ c.m_prev.m_next = c.m_next;
+ }
+ if (c.m_next) {
+ c.m_next.m_prev = c.m_prev;
+ }
+ if (c == this.m_world.m_contactList) {
+ this.m_world.m_contactList = c.m_next;
+ }
+ if (c.m_nodeA.prev) {
+ c.m_nodeA.prev.next = c.m_nodeA.next;
+ }
+ if (c.m_nodeA.next) {
+ c.m_nodeA.next.prev = c.m_nodeA.prev;
+ }
+ if (c.m_nodeA == bodyA.m_contactList) {
+ bodyA.m_contactList = c.m_nodeA.next;
+ }
+ if (c.m_nodeB.prev) {
+ c.m_nodeB.prev.next = c.m_nodeB.next;
+ }
+ if (c.m_nodeB.next) {
+ c.m_nodeB.next.prev = c.m_nodeB.prev;
+ }
+ if (c.m_nodeB == bodyB.m_contactList) {
+ bodyB.m_contactList = c.m_nodeB.next;
+ }
+ this.m_contactFactory.Destroy(c);
+ --this.m_contactCount;
+ }
+ b2ContactManager.prototype.Collide = function () {
+ var c = this.m_world.m_contactList;
+ while (c) {
+ var fixtureA = c.GetFixtureA();
+ var fixtureB = c.GetFixtureB();
+ var bodyA = fixtureA.GetBody();
+ var bodyB = fixtureB.GetBody();
+ if (bodyA.IsAwake() == false && bodyB.IsAwake() == false) {
+ c = c.GetNext();
+ continue;
+ }
+ if (c.m_flags & b2Contact.e_filterFlag) {
+ if (bodyB.ShouldCollide(bodyA) == false) {
+ var cNuke = c;
+ c = cNuke.GetNext();
+ this.Destroy(cNuke);
+ continue;
+ }
+ if (this.m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) {
+ cNuke = c;
+ c = cNuke.GetNext();
+ this.Destroy(cNuke);
+ continue;
+ }
+ c.m_flags &= ~b2Contact.e_filterFlag;
+ }
+ var proxyA = fixtureA.m_proxy;
+ var proxyB = fixtureB.m_proxy;
+ var overlap = this.m_broadPhase.TestOverlap(proxyA, proxyB);
+ if (overlap == false) {
+ cNuke = c;
+ c = cNuke.GetNext();
+ this.Destroy(cNuke);
+ continue;
+ }
+ c.Update(this.m_contactListener);
+ c = c.GetNext();
+ }
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.b2ContactManager.s_evalCP = new b2ContactPoint();
+ });
+ b2DebugDraw.b2DebugDraw = function () {};
+ b2DebugDraw.prototype.b2DebugDraw = function () {}
+ b2DebugDraw.prototype.SetFlags = function (flags) {
+ if (flags === undefined) flags = 0;
+ }
+ b2DebugDraw.prototype.GetFlags = function () {}
+ b2DebugDraw.prototype.AppendFlags = function (flags) {
+ if (flags === undefined) flags = 0;
+ }
+ b2DebugDraw.prototype.ClearFlags = function (flags) {
+ if (flags === undefined) flags = 0;
+ }
+ b2DebugDraw.prototype.SetSprite = function (sprite) {}
+ b2DebugDraw.prototype.GetSprite = function () {}
+ b2DebugDraw.prototype.SetDrawScale = function (drawScale) {
+ if (drawScale === undefined) drawScale = 0;
+ }
+ b2DebugDraw.prototype.GetDrawScale = function () {}
+ b2DebugDraw.prototype.SetLineThickness = function (lineThickness) {
+ if (lineThickness === undefined) lineThickness = 0;
+ }
+ b2DebugDraw.prototype.GetLineThickness = function () {}
+ b2DebugDraw.prototype.SetAlpha = function (alpha) {
+ if (alpha === undefined) alpha = 0;
+ }
+ b2DebugDraw.prototype.GetAlpha = function () {}
+ b2DebugDraw.prototype.SetFillAlpha = function (alpha) {
+ if (alpha === undefined) alpha = 0;
+ }
+ b2DebugDraw.prototype.GetFillAlpha = function () {}
+ b2DebugDraw.prototype.SetXFormScale = function (xformScale) {
+ if (xformScale === undefined) xformScale = 0;
+ }
+ b2DebugDraw.prototype.GetXFormScale = function () {}
+ b2DebugDraw.prototype.DrawPolygon = function (vertices, vertexCount, color) {
+ if (vertexCount === undefined) vertexCount = 0;
+ }
+ b2DebugDraw.prototype.DrawSolidPolygon = function (vertices, vertexCount, color) {
+ if (vertexCount === undefined) vertexCount = 0;
+ }
+ b2DebugDraw.prototype.DrawCircle = function (center, radius, color) {
+ if (radius === undefined) radius = 0;
+ }
+ b2DebugDraw.prototype.DrawSolidCircle = function (center, radius, axis, color) {
+ if (radius === undefined) radius = 0;
+ }
+ b2DebugDraw.prototype.DrawSegment = function (p1, p2, color) {}
+ b2DebugDraw.prototype.DrawTransform = function (xf) {}
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.b2DebugDraw.e_shapeBit = 0x0001;
+ Box2D.Dynamics.b2DebugDraw.e_jointBit = 0x0002;
+ Box2D.Dynamics.b2DebugDraw.e_aabbBit = 0x0004;
+ Box2D.Dynamics.b2DebugDraw.e_pairBit = 0x0008;
+ Box2D.Dynamics.b2DebugDraw.e_centerOfMassBit = 0x0010;
+ Box2D.Dynamics.b2DebugDraw.e_controllerBit = 0x0020;
+ });
+ b2DestructionListener.b2DestructionListener = function () {};
+ b2DestructionListener.prototype.SayGoodbyeJoint = function (joint) {}
+ b2DestructionListener.prototype.SayGoodbyeFixture = function (fixture) {}
+ b2FilterData.b2FilterData = function () {
+ this.categoryBits = 0x0001;
+ this.maskBits = 0xFFFF;
+ this.groupIndex = 0;
+ };
+ b2FilterData.prototype.Copy = function () {
+ var copy = new b2FilterData();
+ copy.categoryBits = this.categoryBits;
+ copy.maskBits = this.maskBits;
+ copy.groupIndex = this.groupIndex;
+ return copy;
+ }
+ b2Fixture.b2Fixture = function () {
+ this.m_filter = new b2FilterData();
+ };
+ b2Fixture.prototype.GetType = function () {
+ return this.m_shape.GetType();
+ }
+ b2Fixture.prototype.GetShape = function () {
+ return this.m_shape;
+ }
+ b2Fixture.prototype.SetSensor = function (sensor) {
+ if (this.m_isSensor == sensor) return;
+ this.m_isSensor = sensor;
+ if (this.m_body == null) return;
+ var edge = this.m_body.GetContactList();
+ while (edge) {
+ var contact = edge.contact;
+ var fixtureA = contact.GetFixtureA();
+ var fixtureB = contact.GetFixtureB();
+ if (fixtureA == this || fixtureB == this) contact.SetSensor(fixtureA.IsSensor() || fixtureB.IsSensor());
+ edge = edge.next;
+ }
+ }
+ b2Fixture.prototype.IsSensor = function () {
+ return this.m_isSensor;
+ }
+ b2Fixture.prototype.SetFilterData = function (filter) {
+ this.m_filter = filter.Copy();
+ if (this.m_body) return;
+ var edge = this.m_body.GetContactList();
+ while (edge) {
+ var contact = edge.contact;
+ var fixtureA = contact.GetFixtureA();
+ var fixtureB = contact.GetFixtureB();
+ if (fixtureA == this || fixtureB == this) contact.FlagForFiltering();
+ edge = edge.next;
+ }
+ }
+ b2Fixture.prototype.GetFilterData = function () {
+ return this.m_filter.Copy();
+ }
+ b2Fixture.prototype.GetBody = function () {
+ return this.m_body;
+ }
+ b2Fixture.prototype.GetNext = function () {
+ return this.m_next;
+ }
+ b2Fixture.prototype.GetUserData = function () {
+ return this.m_userData;
+ }
+ b2Fixture.prototype.SetUserData = function (data) {
+ this.m_userData = data;
+ }
+ b2Fixture.prototype.TestPoint = function (p) {
+ return this.m_shape.TestPoint(this.m_body.GetTransform(), p);
+ }
+ b2Fixture.prototype.RayCast = function (output, input) {
+ return this.m_shape.RayCast(output, input, this.m_body.GetTransform());
+ }
+ b2Fixture.prototype.GetMassData = function (massData) {
+ if (massData === undefined) massData = null;
+ if (massData == null) {
+ massData = new b2MassData();
+ }
+ this.m_shape.ComputeMass(massData, this.m_density);
+ return massData;
+ }
+ b2Fixture.prototype.SetDensity = function (density) {
+ if (density === undefined) density = 0;
+ this.m_density = density;
+ }
+ b2Fixture.prototype.GetDensity = function () {
+ return this.m_density;
+ }
+ b2Fixture.prototype.GetFriction = function () {
+ return this.m_friction;
+ }
+ b2Fixture.prototype.SetFriction = function (friction) {
+ if (friction === undefined) friction = 0;
+ this.m_friction = friction;
+ }
+ b2Fixture.prototype.GetRestitution = function () {
+ return this.m_restitution;
+ }
+ b2Fixture.prototype.SetRestitution = function (restitution) {
+ if (restitution === undefined) restitution = 0;
+ this.m_restitution = restitution;
+ }
+ b2Fixture.prototype.GetAABB = function () {
+ return this.m_aabb;
+ }
+ b2Fixture.prototype.b2Fixture = function () {
+ this.m_aabb = new b2AABB();
+ this.m_userData = null;
+ this.m_body = null;
+ this.m_next = null;
+ this.m_shape = null;
+ this.m_density = 0.0;
+ this.m_friction = 0.0;
+ this.m_restitution = 0.0;
+ }
+ b2Fixture.prototype.Create = function (body, xf, def) {
+ this.m_userData = def.userData;
+ this.m_friction = def.friction;
+ this.m_restitution = def.restitution;
+ this.m_body = body;
+ this.m_next = null;
+ this.m_filter = def.filter.Copy();
+ this.m_isSensor = def.isSensor;
+ this.m_shape = def.shape.Copy();
+ this.m_density = def.density;
+ }
+ b2Fixture.prototype.Destroy = function () {
+ this.m_shape = null;
+ }
+ b2Fixture.prototype.CreateProxy = function (broadPhase, xf) {
+ this.m_shape.ComputeAABB(this.m_aabb, xf);
+ this.m_proxy = broadPhase.CreateProxy(this.m_aabb, this);
+ }
+ b2Fixture.prototype.DestroyProxy = function (broadPhase) {
+ if (this.m_proxy == null) {
+ return;
+ }
+ broadPhase.DestroyProxy(this.m_proxy);
+ this.m_proxy = null;
+ }
+ b2Fixture.prototype.Synchronize = function (broadPhase, transform1, transform2) {
+ if (!this.m_proxy) return;
+ var aabb1 = new b2AABB();
+ var aabb2 = new b2AABB();
+ this.m_shape.ComputeAABB(aabb1, transform1);
+ this.m_shape.ComputeAABB(aabb2, transform2);
+ this.m_aabb.Combine(aabb1, aabb2);
+ var displacement = b2Math.SubtractVV(transform2.position, transform1.position);
+ broadPhase.MoveProxy(this.m_proxy, this.m_aabb, displacement);
+ }
+ b2FixtureDef.b2FixtureDef = function () {
+ this.filter = new b2FilterData();
+ };
+ b2FixtureDef.prototype.b2FixtureDef = function () {
+ this.shape = null;
+ this.userData = null;
+ this.friction = 0.2;
+ this.restitution = 0.0;
+ this.density = 0.0;
+ this.filter.categoryBits = 0x0001;
+ this.filter.maskBits = 0xFFFF;
+ this.filter.groupIndex = 0;
+ this.isSensor = false;
+ }
+ b2Island.b2Island = function () {};
+ b2Island.prototype.b2Island = function () {
+ this.m_bodies = new Vector();
+ this.m_contacts = new Vector();
+ this.m_joints = new Vector();
+ }
+ b2Island.prototype.Initialize = function (bodyCapacity, contactCapacity, jointCapacity, allocator, listener, contactSolver) {
+ if (bodyCapacity === undefined) bodyCapacity = 0;
+ if (contactCapacity === undefined) contactCapacity = 0;
+ if (jointCapacity === undefined) jointCapacity = 0;
+ var i = 0;
+ this.m_bodyCapacity = bodyCapacity;
+ this.m_contactCapacity = contactCapacity;
+ this.m_jointCapacity = jointCapacity;
+ this.m_bodyCount = 0;
+ this.m_contactCount = 0;
+ this.m_jointCount = 0;
+ this.m_allocator = allocator;
+ this.m_listener = listener;
+ this.m_contactSolver = contactSolver;
+ for (i = this.m_bodies.length;
+ i < bodyCapacity; i++)
+ this.m_bodies[i] = null;
+ for (i = this.m_contacts.length;
+ i < contactCapacity; i++)
+ this.m_contacts[i] = null;
+ for (i = this.m_joints.length;
+ i < jointCapacity; i++)
+ this.m_joints[i] = null;
+ }
+ b2Island.prototype.Clear = function () {
+ this.m_bodyCount = 0;
+ this.m_contactCount = 0;
+ this.m_jointCount = 0;
+ }
+ b2Island.prototype.Solve = function (step, gravity, allowSleep) {
+ var i = 0;
+ var j = 0;
+ var b;
+ var joint;
+ for (i = 0;
+ i < this.m_bodyCount; ++i) {
+ b = this.m_bodies[i];
+ if (b.GetType() != b2Body.b2_dynamicBody) continue;
+ b.m_linearVelocity.x += step.dt * (gravity.x + b.m_invMass * b.m_force.x);
+ b.m_linearVelocity.y += step.dt * (gravity.y + b.m_invMass * b.m_force.y);
+ b.m_angularVelocity += step.dt * b.m_invI * b.m_torque;
+ b.m_linearVelocity.Multiply(b2Math.Clamp(1.0 - step.dt * b.m_linearDamping, 0.0, 1.0));
+ b.m_angularVelocity *= b2Math.Clamp(1.0 - step.dt * b.m_angularDamping, 0.0, 1.0);
+ }
+ this.m_contactSolver.Initialize(step, this.m_contacts, this.m_contactCount, this.m_allocator);
+ var contactSolver = this.m_contactSolver;
+ contactSolver.InitVelocityConstraints(step);
+ for (i = 0;
+ i < this.m_jointCount; ++i) {
+ joint = this.m_joints[i];
+ joint.InitVelocityConstraints(step);
+ }
+ for (i = 0;
+ i < step.velocityIterations; ++i) {
+ for (j = 0;
+ j < this.m_jointCount; ++j) {
+ joint = this.m_joints[j];
+ joint.SolveVelocityConstraints(step);
+ }
+ contactSolver.SolveVelocityConstraints();
+ }
+ for (i = 0;
+ i < this.m_jointCount; ++i) {
+ joint = this.m_joints[i];
+ joint.FinalizeVelocityConstraints();
+ }
+ contactSolver.FinalizeVelocityConstraints();
+ for (i = 0;
+ i < this.m_bodyCount; ++i) {
+ b = this.m_bodies[i];
+ if (b.GetType() == b2Body.b2_staticBody) continue;
+ var translationX = step.dt * b.m_linearVelocity.x;
+ var translationY = step.dt * b.m_linearVelocity.y;
+ if ((translationX * translationX + translationY * translationY) > b2Settings.b2_maxTranslationSquared) {
+ b.m_linearVelocity.Normalize();
+ b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * step.inv_dt;
+ b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * step.inv_dt;
+ }
+ var rotation = step.dt * b.m_angularVelocity;
+ if (rotation * rotation > b2Settings.b2_maxRotationSquared) {
+ if (b.m_angularVelocity < 0.0) {
+ b.m_angularVelocity = (-b2Settings.b2_maxRotation * step.inv_dt);
+ }
+ else {
+ b.m_angularVelocity = b2Settings.b2_maxRotation * step.inv_dt;
+ }
+ }
+ b.m_sweep.c0.SetV(b.m_sweep.c);
+ b.m_sweep.a0 = b.m_sweep.a;
+ b.m_sweep.c.x += step.dt * b.m_linearVelocity.x;
+ b.m_sweep.c.y += step.dt * b.m_linearVelocity.y;
+ b.m_sweep.a += step.dt * b.m_angularVelocity;
+ b.SynchronizeTransform();
+ }
+ for (i = 0;
+ i < step.positionIterations; ++i) {
+ var contactsOkay = contactSolver.SolvePositionConstraints(b2Settings.b2_contactBaumgarte);
+ var jointsOkay = true;
+ for (j = 0;
+ j < this.m_jointCount; ++j) {
+ joint = this.m_joints[j];
+ var jointOkay = joint.SolvePositionConstraints(b2Settings.b2_contactBaumgarte);
+ jointsOkay = jointsOkay && jointOkay;
+ }
+ if (contactsOkay && jointsOkay) {
+ break;
+ }
+ }
+ this.Report(contactSolver.m_constraints);
+ if (allowSleep) {
+ var minSleepTime = Number.MAX_VALUE;
+ var linTolSqr = b2Settings.b2_linearSleepTolerance * b2Settings.b2_linearSleepTolerance;
+ var angTolSqr = b2Settings.b2_angularSleepTolerance * b2Settings.b2_angularSleepTolerance;
+ for (i = 0;
+ i < this.m_bodyCount; ++i) {
+ b = this.m_bodies[i];
+ if (b.GetType() == b2Body.b2_staticBody) {
+ continue;
+ }
+ if ((b.m_flags & b2Body.e_allowSleepFlag) == 0) {
+ b.m_sleepTime = 0.0;
+ minSleepTime = 0.0;
+ }
+ if ((b.m_flags & b2Body.e_allowSleepFlag) == 0 || b.m_angularVelocity * b.m_angularVelocity > angTolSqr || b2Math.Dot(b.m_linearVelocity, b.m_linearVelocity) > linTolSqr) {
+ b.m_sleepTime = 0.0;
+ minSleepTime = 0.0;
+ }
+ else {
+ b.m_sleepTime += step.dt;
+ minSleepTime = b2Math.Min(minSleepTime, b.m_sleepTime);
+ }
+ }
+ if (minSleepTime >= b2Settings.b2_timeToSleep) {
+ for (i = 0;
+ i < this.m_bodyCount; ++i) {
+ b = this.m_bodies[i];
+ b.SetAwake(false);
+ }
+ }
+ }
+ }
+ b2Island.prototype.SolveTOI = function (subStep) {
+ var i = 0;
+ var j = 0;
+ this.m_contactSolver.Initialize(subStep, this.m_contacts, this.m_contactCount, this.m_allocator);
+ var contactSolver = this.m_contactSolver;
+ for (i = 0;
+ i < this.m_jointCount; ++i) {
+ this.m_joints[i].InitVelocityConstraints(subStep);
+ }
+ for (i = 0;
+ i < subStep.velocityIterations; ++i) {
+ contactSolver.SolveVelocityConstraints();
+ for (j = 0;
+ j < this.m_jointCount; ++j) {
+ this.m_joints[j].SolveVelocityConstraints(subStep);
+ }
+ }
+ for (i = 0;
+ i < this.m_bodyCount; ++i) {
+ var b = this.m_bodies[i];
+ if (b.GetType() == b2Body.b2_staticBody) continue;
+ var translationX = subStep.dt * b.m_linearVelocity.x;
+ var translationY = subStep.dt * b.m_linearVelocity.y;
+ if ((translationX * translationX + translationY * translationY) > b2Settings.b2_maxTranslationSquared) {
+ b.m_linearVelocity.Normalize();
+ b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * subStep.inv_dt;
+ b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * subStep.inv_dt;
+ }
+ var rotation = subStep.dt * b.m_angularVelocity;
+ if (rotation * rotation > b2Settings.b2_maxRotationSquared) {
+ if (b.m_angularVelocity < 0.0) {
+ b.m_angularVelocity = (-b2Settings.b2_maxRotation * subStep.inv_dt);
+ }
+ else {
+ b.m_angularVelocity = b2Settings.b2_maxRotation * subStep.inv_dt;
+ }
+ }
+ b.m_sweep.c0.SetV(b.m_sweep.c);
+ b.m_sweep.a0 = b.m_sweep.a;
+ b.m_sweep.c.x += subStep.dt * b.m_linearVelocity.x;
+ b.m_sweep.c.y += subStep.dt * b.m_linearVelocity.y;
+ b.m_sweep.a += subStep.dt * b.m_angularVelocity;
+ b.SynchronizeTransform();
+ }
+ var k_toiBaumgarte = 0.75;
+ for (i = 0;
+ i < subStep.positionIterations; ++i) {
+ var contactsOkay = contactSolver.SolvePositionConstraints(k_toiBaumgarte);
+ var jointsOkay = true;
+ for (j = 0;
+ j < this.m_jointCount; ++j) {
+ var jointOkay = this.m_joints[j].SolvePositionConstraints(b2Settings.b2_contactBaumgarte);
+ jointsOkay = jointsOkay && jointOkay;
+ }
+ if (contactsOkay && jointsOkay) {
+ break;
+ }
+ }
+ this.Report(contactSolver.m_constraints);
+ }
+ b2Island.prototype.Report = function (constraints) {
+ if (this.m_listener == null) {
+ return;
+ }
+ for (var i = 0; i < this.m_contactCount; ++i) {
+ var c = this.m_contacts[i];
+ var cc = constraints[i];
+ for (var j = 0; j < cc.pointCount; ++j) {
+ b2Island.s_impulse.normalImpulses[j] = cc.points[j].normalImpulse;
+ b2Island.s_impulse.tangentImpulses[j] = cc.points[j].tangentImpulse;
+ }
+ this.m_listener.PostSolve(c, b2Island.s_impulse);
+ }
+ }
+ b2Island.prototype.AddBody = function (body) {
+ body.m_islandIndex = this.m_bodyCount;
+ this.m_bodies[this.m_bodyCount++] = body;
+ }
+ b2Island.prototype.AddContact = function (contact) {
+ this.m_contacts[this.m_contactCount++] = contact;
+ }
+ b2Island.prototype.AddJoint = function (joint) {
+ this.m_joints[this.m_jointCount++] = joint;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.b2Island.s_impulse = new b2ContactImpulse();
+ });
+ b2TimeStep.b2TimeStep = function () {};
+ b2TimeStep.prototype.Set = function (step) {
+ this.dt = step.dt;
+ this.inv_dt = step.inv_dt;
+ this.positionIterations = step.positionIterations;
+ this.velocityIterations = step.velocityIterations;
+ this.warmStarting = step.warmStarting;
+ }
+ b2World.b2World = function () {
+ this.s_stack = new Vector();
+ this.m_contactManager = new b2ContactManager();
+ this.m_contactSolver = new b2ContactSolver();
+ this.m_island = new b2Island();
+ };
+ b2World.prototype.b2World = function (gravity, doSleep) {
+ this.m_destructionListener = null;
+ this.m_debugDraw = null;
+ this.m_bodyList = null;
+ this.m_contactList = null;
+ this.m_jointList = null;
+ this.m_controllerList = null;
+ this.m_bodyCount = 0;
+ this.m_contactCount = 0;
+ this.m_jointCount = 0;
+ this.m_controllerCount = 0;
+ b2World.m_warmStarting = true;
+ b2World.m_continuousPhysics = true;
+ this.m_allowSleep = doSleep;
+ gravity.y = gravity.y;
+ this.m_gravity = gravity;
+ this.m_inv_dt0 = 0.0;
+ this.m_contactManager.m_world = this;
+ var bd = new b2BodyDef();
+ this.m_groundBody = this.CreateBody(bd);
+ }
+ b2World.prototype.SetDestructionListener = function (listener) {
+ this.m_destructionListener = listener;
+ }
+ b2World.prototype.SetContactFilter = function (filter) {
+ this.m_contactManager.m_contactFilter = filter;
+ }
+ b2World.prototype.SetContactListener = function (listener) {
+ this.m_contactManager.m_contactListener = listener;
+ }
+ b2World.prototype.SetDebugDraw = function (debugDraw) {
+ this.m_debugDraw = debugDraw;
+ }
+ b2World.prototype.SetBroadPhase = function (broadPhase) {
+ var oldBroadPhase = this.m_contactManager.m_broadPhase;
+ this.m_contactManager.m_broadPhase = broadPhase;
+ for (var b = this.m_bodyList; b; b = b.m_next) {
+ for (var f = b.m_fixtureList; f; f = f.m_next) {
+ f.m_proxy = broadPhase.CreateProxy(oldBroadPhase.GetFatAABB(f.m_proxy), f);
+ }
+ }
+ }
+ b2World.prototype.Validate = function () {
+ this.m_contactManager.m_broadPhase.Validate();
+ }
+ b2World.prototype.GetProxyCount = function () {
+ return this.m_contactManager.m_broadPhase.GetProxyCount();
+ }
+ b2World.prototype.CreateBody = function (def) {
+ if (this.IsLocked() == true) {
+ return null;
+ }
+ var b = new b2Body(def, this);
+ b.m_prev = null;
+ b.m_next = this.m_bodyList;
+ if (this.m_bodyList) {
+ this.m_bodyList.m_prev = b;
+ }
+ this.m_bodyList = b;
+ ++this.m_bodyCount;
+ return b;
+ }
+ b2World.prototype.DestroyBody = function (b) {
+ if (this.IsLocked() == true) {
+ return;
+ }
+ var jn = b.m_jointList;
+ while (jn) {
+ var jn0 = jn;
+ jn = jn.next;
+ if (this.m_destructionListener) {
+ this.m_destructionListener.SayGoodbyeJoint(jn0.joint);
+ }
+ this.DestroyJoint(jn0.joint);
+ }
+ var coe = b.m_controllerList;
+ while (coe) {
+ var coe0 = coe;
+ coe = coe.nextController;
+ coe0.controller.RemoveBody(b);
+ }
+ var ce = b.m_contactList;
+ while (ce) {
+ var ce0 = ce;
+ ce = ce.next;
+ this.m_contactManager.Destroy(ce0.contact);
+ }
+ b.m_contactList = null;
+ var f = b.m_fixtureList;
+ while (f) {
+ var f0 = f;
+ f = f.m_next;
+ if (this.m_destructionListener) {
+ this.m_destructionListener.SayGoodbyeFixture(f0);
+ }
+ f0.DestroyProxy(this.m_contactManager.m_broadPhase);
+ f0.Destroy();
+ }
+ b.m_fixtureList = null;
+ b.m_fixtureCount = 0;
+ if (b.m_prev) {
+ b.m_prev.m_next = b.m_next;
+ }
+ if (b.m_next) {
+ b.m_next.m_prev = b.m_prev;
+ }
+ if (b == this.m_bodyList) {
+ this.m_bodyList = b.m_next;
+ }--this.m_bodyCount;
+ }
+ b2World.prototype.CreateJoint = function (def) {
+ var j = b2Joint.Create(def, null);
+ j.m_prev = null;
+ j.m_next = this.m_jointList;
+ if (this.m_jointList) {
+ this.m_jointList.m_prev = j;
+ }
+ this.m_jointList = j;
+ ++this.m_jointCount;
+ j.m_edgeA.joint = j;
+ j.m_edgeA.other = j.m_bodyB;
+ j.m_edgeA.prev = null;
+ j.m_edgeA.next = j.m_bodyA.m_jointList;
+ if (j.m_bodyA.m_jointList) j.m_bodyA.m_jointList.prev = j.m_edgeA;
+ j.m_bodyA.m_jointList = j.m_edgeA;
+ j.m_edgeB.joint = j;
+ j.m_edgeB.other = j.m_bodyA;
+ j.m_edgeB.prev = null;
+ j.m_edgeB.next = j.m_bodyB.m_jointList;
+ if (j.m_bodyB.m_jointList) j.m_bodyB.m_jointList.prev = j.m_edgeB;
+ j.m_bodyB.m_jointList = j.m_edgeB;
+ var bodyA = def.bodyA;
+ var bodyB = def.bodyB;
+ if (def.collideConnected == false) {
+ var edge = bodyB.GetContactList();
+ while (edge) {
+ if (edge.other == bodyA) {
+ edge.contact.FlagForFiltering();
+ }
+ edge = edge.next;
+ }
+ }
+ return j;
+ }
+ b2World.prototype.DestroyJoint = function (j) {
+ var collideConnected = j.m_collideConnected;
+ if (j.m_prev) {
+ j.m_prev.m_next = j.m_next;
+ }
+ if (j.m_next) {
+ j.m_next.m_prev = j.m_prev;
+ }
+ if (j == this.m_jointList) {
+ this.m_jointList = j.m_next;
+ }
+ var bodyA = j.m_bodyA;
+ var bodyB = j.m_bodyB;
+ bodyA.SetAwake(true);
+ bodyB.SetAwake(true);
+ if (j.m_edgeA.prev) {
+ j.m_edgeA.prev.next = j.m_edgeA.next;
+ }
+ if (j.m_edgeA.next) {
+ j.m_edgeA.next.prev = j.m_edgeA.prev;
+ }
+ if (j.m_edgeA == bodyA.m_jointList) {
+ bodyA.m_jointList = j.m_edgeA.next;
+ }
+ j.m_edgeA.prev = null;
+ j.m_edgeA.next = null;
+ if (j.m_edgeB.prev) {
+ j.m_edgeB.prev.next = j.m_edgeB.next;
+ }
+ if (j.m_edgeB.next) {
+ j.m_edgeB.next.prev = j.m_edgeB.prev;
+ }
+ if (j.m_edgeB == bodyB.m_jointList) {
+ bodyB.m_jointList = j.m_edgeB.next;
+ }
+ j.m_edgeB.prev = null;
+ j.m_edgeB.next = null;
+ b2Joint.Destroy(j, null);
+ --this.m_jointCount;
+ if (collideConnected == false) {
+ var edge = bodyB.GetContactList();
+ while (edge) {
+ if (edge.other == bodyA) {
+ edge.contact.FlagForFiltering();
+ }
+ edge = edge.next;
+ }
+ }
+ }
+ b2World.prototype.AddController = function (c) {
+ c.m_next = this.m_controllerList;
+ c.m_prev = null;
+ this.m_controllerList = c;
+ c.m_world = this;
+ this.m_controllerCount++;
+ return c;
+ }
+ b2World.prototype.RemoveController = function (c) {
+ if (c.m_prev) c.m_prev.m_next = c.m_next;
+ if (c.m_next) c.m_next.m_prev = c.m_prev;
+ if (this.m_controllerList == c) this.m_controllerList = c.m_next;
+ this.m_controllerCount--;
+ }
+ b2World.prototype.CreateController = function (controller) {
+ if (controller.m_world != this) throw new Error("Controller can only be a member of one world");
+ controller.m_next = this.m_controllerList;
+ controller.m_prev = null;
+ if (this.m_controllerList) this.m_controllerList.m_prev = controller;
+ this.m_controllerList = controller;
+ ++this.m_controllerCount;
+ controller.m_world = this;
+ return controller;
+ }
+ b2World.prototype.DestroyController = function (controller) {
+ controller.Clear();
+ if (controller.m_next) controller.m_next.m_prev = controller.m_prev;
+ if (controller.m_prev) controller.m_prev.m_next = controller.m_next;
+ if (controller == this.m_controllerList) this.m_controllerList = controller.m_next;
+ --this.m_controllerCount;
+ }
+ b2World.prototype.SetWarmStarting = function (flag) {
+ b2World.m_warmStarting = flag;
+ }
+ b2World.prototype.SetContinuousPhysics = function (flag) {
+ b2World.m_continuousPhysics = flag;
+ }
+ b2World.prototype.GetBodyCount = function () {
+ return this.m_bodyCount;
+ }
+ b2World.prototype.GetJointCount = function () {
+ return this.m_jointCount;
+ }
+ b2World.prototype.GetContactCount = function () {
+ return this.m_contactCount;
+ }
+ b2World.prototype.SetGravity = function (gravity) {
+ this.m_gravity = gravity;
+ }
+ b2World.prototype.GetGravity = function () {
+ return this.m_gravity;
+ }
+ b2World.prototype.GetGroundBody = function () {
+ return this.m_groundBody;
+ }
+ b2World.prototype.Step = function (dt, velocityIterations, positionIterations) {
+ if (dt === undefined) dt = 0;
+ if (velocityIterations === undefined) velocityIterations = 0;
+ if (positionIterations === undefined) positionIterations = 0;
+ if (this.m_flags & b2World.e_newFixture) {
+ this.m_contactManager.FindNewContacts();
+ this.m_flags &= ~b2World.e_newFixture;
+ }
+ this.m_flags |= b2World.e_locked;
+ var step = b2World.s_timestep2;
+ step.dt = dt;
+ step.velocityIterations = velocityIterations;
+ step.positionIterations = positionIterations;
+ if (dt > 0.0) {
+ step.inv_dt = 1.0 / dt;
+ }
+ else {
+ step.inv_dt = 0.0;
+ }
+ step.dtRatio = this.m_inv_dt0 * dt;
+ step.warmStarting = b2World.m_warmStarting;
+ this.m_contactManager.Collide();
+ if (step.dt > 0.0) {
+ this.Solve(step);
+ }
+ if (b2World.m_continuousPhysics && step.dt > 0.0) {
+ this.SolveTOI(step);
+ }
+ if (step.dt > 0.0) {
+ this.m_inv_dt0 = step.inv_dt;
+ }
+ this.m_flags &= ~b2World.e_locked;
+ }
+ b2World.prototype.ClearForces = function () {
+ for (var body = this.m_bodyList; body; body = body.m_next) {
+ body.m_force.SetZero();
+ body.m_torque = 0.0;
+ }
+ }
+ b2World.prototype.DrawDebugData = function () {
+ if (this.m_debugDraw == null) {
+ return;
+ }
+ this.m_debugDraw.m_sprite.graphics.clear();
+ var flags = this.m_debugDraw.GetFlags();
+ var i = 0;
+ var b;
+ var f;
+ var s;
+ var j;
+ var bp;
+ var invQ = new b2Vec2;
+ var x1 = new b2Vec2;
+ var x2 = new b2Vec2;
+ var xf;
+ var b1 = new b2AABB();
+ var b2 = new b2AABB();
+ var vs = [new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Vec2()];
+ var color = new b2Color(0, 0, 0);
+ if (flags & b2DebugDraw.e_shapeBit) {
+ for (b = this.m_bodyList;
+ b; b = b.m_next) {
+ xf = b.m_xf;
+ for (f = b.GetFixtureList();
+ f; f = f.m_next) {
+ s = f.GetShape();
+ if (b.IsActive() == false) {
+ color.Set(0.5, 0.5, 0.3);
+ this.DrawShape(s, xf, color);
+ }
+ else if (b.GetType() == b2Body.b2_staticBody) {
+ color.Set(0.5, 0.9, 0.5);
+ this.DrawShape(s, xf, color);
+ }
+ else if (b.GetType() == b2Body.b2_kinematicBody) {
+ color.Set(0.5, 0.5, 0.9);
+ this.DrawShape(s, xf, color);
+ }
+ else if (b.IsAwake() == false) {
+ color.Set(0.6, 0.6, 0.6);
+ this.DrawShape(s, xf, color);
+ }
+ else {
+ color.Set(0.9, 0.7, 0.7);
+ this.DrawShape(s, xf, color);
+ }
+ }
+ }
+ }
+ if (flags & b2DebugDraw.e_jointBit) {
+ for (j = this.m_jointList;
+ j; j = j.m_next) {
+ this.DrawJoint(j);
+ }
+ }
+ if (flags & b2DebugDraw.e_controllerBit) {
+ for (var c = this.m_controllerList; c; c = c.m_next) {
+ c.Draw(this.m_debugDraw);
+ }
+ }
+ if (flags & b2DebugDraw.e_pairBit) {
+ color.Set(0.3, 0.9, 0.9);
+ for (var contact = this.m_contactManager.m_contactList; contact; contact = contact.GetNext()) {
+ var fixtureA = contact.GetFixtureA();
+ var fixtureB = contact.GetFixtureB();
+ var cA = fixtureA.GetAABB().GetCenter();
+ var cB = fixtureB.GetAABB().GetCenter();
+ this.m_debugDraw.DrawSegment(cA, cB, color);
+ }
+ }
+ if (flags & b2DebugDraw.e_aabbBit) {
+ bp = this.m_contactManager.m_broadPhase;
+ vs = [new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Vec2()];
+ for (b = this.m_bodyList;
+ b; b = b.GetNext()) {
+ if (b.IsActive() == false) {
+ continue;
+ }
+ for (f = b.GetFixtureList();
+ f; f = f.GetNext()) {
+ var aabb = bp.GetFatAABB(f.m_proxy);
+ vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y);
+ vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y);
+ vs[2].Set(aabb.upperBound.x, aabb.upperBound.y);
+ vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y);
+ this.m_debugDraw.DrawPolygon(vs, 4, color);
+ }
+ }
+ }
+ if (flags & b2DebugDraw.e_centerOfMassBit) {
+ for (b = this.m_bodyList;
+ b; b = b.m_next) {
+ xf = b2World.s_xf;
+ xf.R = b.m_xf.R;
+ xf.position = b.GetWorldCenter();
+ this.m_debugDraw.DrawTransform(xf);
+ }
+ }
+ }
+ b2World.prototype.QueryAABB = function (callback, aabb) {
+ var __this = this;
+ var broadPhase = __this.m_contactManager.m_broadPhase;
+
+ function WorldQueryWrapper(proxy) {
+ return callback(broadPhase.GetUserData(proxy));
+ };
+ broadPhase.Query(WorldQueryWrapper, aabb);
+ }
+ b2World.prototype.QueryShape = function (callback, shape, transform) {
+ var __this = this;
+ if (transform === undefined) transform = null;
+ if (transform == null) {
+ transform = new b2Transform();
+ transform.SetIdentity();
+ }
+ var broadPhase = __this.m_contactManager.m_broadPhase;
+
+ function WorldQueryWrapper(proxy) {
+ var fixture = (broadPhase.GetUserData(proxy) instanceof b2Fixture ? broadPhase.GetUserData(proxy) : null);
+ if (b2Shape.TestOverlap(shape, transform, fixture.GetShape(), fixture.GetBody().GetTransform())) return callback(fixture);
+ return true;
+ };
+ var aabb = new b2AABB();
+ shape.ComputeAABB(aabb, transform);
+ broadPhase.Query(WorldQueryWrapper, aabb);
+ }
+ b2World.prototype.QueryPoint = function (callback, p) {
+ var __this = this;
+ var broadPhase = __this.m_contactManager.m_broadPhase;
+
+ function WorldQueryWrapper(proxy) {
+ var fixture = (broadPhase.GetUserData(proxy) instanceof b2Fixture ? broadPhase.GetUserData(proxy) : null);
+ if (fixture.TestPoint(p)) return callback(fixture);
+ return true;
+ };
+ var aabb = new b2AABB();
+ aabb.lowerBound.Set(p.x - b2Settings.b2_linearSlop, p.y - b2Settings.b2_linearSlop);
+ aabb.upperBound.Set(p.x + b2Settings.b2_linearSlop, p.y + b2Settings.b2_linearSlop);
+ broadPhase.Query(WorldQueryWrapper, aabb);
+ }
+ b2World.prototype.RayCast = function (callback, point1, point2) {
+ var __this = this;
+ var broadPhase = __this.m_contactManager.m_broadPhase;
+ var output = new b2RayCastOutput;
+
+ function RayCastWrapper(input, proxy) {
+ var userData = broadPhase.GetUserData(proxy);
+ var fixture = (userData instanceof b2Fixture ? userData : null);
+ var hit = fixture.RayCast(output, input);
+ if (hit) {
+ var fraction = output.fraction;
+ var point = new b2Vec2((1.0 - fraction) * point1.x + fraction * point2.x, (1.0 - fraction) * point1.y + fraction * point2.y);
+ return callback(fixture, point, output.normal, fraction);
+ }
+ return input.maxFraction;
+ };
+ var input = new b2RayCastInput(point1, point2);
+ broadPhase.RayCast(RayCastWrapper, input);
+ }
+ b2World.prototype.RayCastOne = function (point1, point2) {
+ var __this = this;
+ var result;
+
+ function RayCastOneWrapper(fixture, point, normal, fraction) {
+ if (fraction === undefined) fraction = 0;
+ result = fixture;
+ return fraction;
+ };
+ __this.RayCast(RayCastOneWrapper, point1, point2);
+ return result;
+ }
+ b2World.prototype.RayCastAll = function (point1, point2) {
+ var __this = this;
+ var result = new Vector();
+
+ function RayCastAllWrapper(fixture, point, normal, fraction) {
+ if (fraction === undefined) fraction = 0;
+ result[result.length] = fixture;
+ return 1;
+ };
+ __this.RayCast(RayCastAllWrapper, point1, point2);
+ return result;
+ }
+ b2World.prototype.GetBodyList = function () {
+ return this.m_bodyList;
+ }
+ b2World.prototype.GetJointList = function () {
+ return this.m_jointList;
+ }
+ b2World.prototype.GetContactList = function () {
+ return this.m_contactList;
+ }
+ b2World.prototype.IsLocked = function () {
+ return (this.m_flags & b2World.e_locked) > 0;
+ }
+ b2World.prototype.Solve = function (step) {
+ var b;
+ for (var controller = this.m_controllerList; controller; controller = controller.m_next) {
+ controller.Step(step);
+ }
+ var island = this.m_island;
+ island.Initialize(this.m_bodyCount, this.m_contactCount, this.m_jointCount, null, this.m_contactManager.m_contactListener, this.m_contactSolver);
+ for (b = this.m_bodyList;
+ b; b = b.m_next) {
+ b.m_flags &= ~b2Body.e_islandFlag;
+ }
+ for (var c = this.m_contactList; c; c = c.m_next) {
+ c.m_flags &= ~b2Contact.e_islandFlag;
+ }
+ for (var j = this.m_jointList; j; j = j.m_next) {
+ j.m_islandFlag = false;
+ }
+ var stackSize = parseInt(this.m_bodyCount);
+ var stack = this.s_stack;
+ for (var seed = this.m_bodyList; seed; seed = seed.m_next) {
+ if (seed.m_flags & b2Body.e_islandFlag) {
+ continue;
+ }
+ if (seed.IsAwake() == false || seed.IsActive() == false) {
+ continue;
+ }
+ if (seed.GetType() == b2Body.b2_staticBody) {
+ continue;
+ }
+ island.Clear();
+ var stackCount = 0;
+ stack[stackCount++] = seed;
+ seed.m_flags |= b2Body.e_islandFlag;
+ while (stackCount > 0) {
+ b = stack[--stackCount];
+ island.AddBody(b);
+ if (b.IsAwake() == false) {
+ b.SetAwake(true);
+ }
+ if (b.GetType() == b2Body.b2_staticBody) {
+ continue;
+ }
+ var other;
+ for (var ce = b.m_contactList; ce; ce = ce.next) {
+ if (ce.contact.m_flags & b2Contact.e_islandFlag) {
+ continue;
+ }
+ if (ce.contact.IsSensor() == true || ce.contact.IsEnabled() == false || ce.contact.IsTouching() == false) {
+ continue;
+ }
+ island.AddContact(ce.contact);
+ ce.contact.m_flags |= b2Contact.e_islandFlag;
+ other = ce.other;
+ if (other.m_flags & b2Body.e_islandFlag) {
+ continue;
+ }
+ stack[stackCount++] = other;
+ other.m_flags |= b2Body.e_islandFlag;
+ }
+ for (var jn = b.m_jointList; jn; jn = jn.next) {
+ if (jn.joint.m_islandFlag == true) {
+ continue;
+ }
+ other = jn.other;
+ if (other.IsActive() == false) {
+ continue;
+ }
+ island.AddJoint(jn.joint);
+ jn.joint.m_islandFlag = true;
+ if (other.m_flags & b2Body.e_islandFlag) {
+ continue;
+ }
+ stack[stackCount++] = other;
+ other.m_flags |= b2Body.e_islandFlag;
+ }
+ }
+ island.Solve(step, this.m_gravity, this.m_allowSleep);
+ for (var i = 0; i < island.m_bodyCount; ++i) {
+ b = island.m_bodies[i];
+ if (b.GetType() == b2Body.b2_staticBody) {
+ b.m_flags &= ~b2Body.e_islandFlag;
+ }
+ }
+ }
+ for (i = 0;
+ i < stack.length; ++i) {
+ if (!stack[i]) break;
+ stack[i] = null;
+ }
+ for (b = this.m_bodyList;
+ b; b = b.m_next) {
+ if (b.IsAwake() == false || b.IsActive() == false) {
+ continue;
+ }
+ if (b.GetType() == b2Body.b2_staticBody) {
+ continue;
+ }
+ b.SynchronizeFixtures();
+ }
+ this.m_contactManager.FindNewContacts();
+ }
+ b2World.prototype.SolveTOI = function (step) {
+ var b;
+ var fA;
+ var fB;
+ var bA;
+ var bB;
+ var cEdge;
+ var j;
+ var island = this.m_island;
+ island.Initialize(this.m_bodyCount, b2Settings.b2_maxTOIContactsPerIsland, b2Settings.b2_maxTOIJointsPerIsland, null, this.m_contactManager.m_contactListener, this.m_contactSolver);
+ var queue = b2World.s_queue;
+ for (b = this.m_bodyList;
+ b; b = b.m_next) {
+ b.m_flags &= ~b2Body.e_islandFlag;
+ b.m_sweep.t0 = 0.0;
+ }
+ var c;
+ for (c = this.m_contactList;
+ c; c = c.m_next) {
+ c.m_flags &= ~ (b2Contact.e_toiFlag | b2Contact.e_islandFlag);
+ }
+ for (j = this.m_jointList;
+ j; j = j.m_next) {
+ j.m_islandFlag = false;
+ }
+ for (;;) {
+ var minContact = null;
+ var minTOI = 1.0;
+ for (c = this.m_contactList;
+ c; c = c.m_next) {
+ if (c.IsSensor() == true || c.IsEnabled() == false || c.IsContinuous() == false) {
+ continue;
+ }
+ var toi = 1.0;
+ if (c.m_flags & b2Contact.e_toiFlag) {
+ toi = c.m_toi;
+ }
+ else {
+ fA = c.m_fixtureA;
+ fB = c.m_fixtureB;
+ bA = fA.m_body;
+ bB = fB.m_body;
+ if ((bA.GetType() != b2Body.b2_dynamicBody || bA.IsAwake() == false) && (bB.GetType() != b2Body.b2_dynamicBody || bB.IsAwake() == false)) {
+ continue;
+ }
+ var t0 = bA.m_sweep.t0;
+ if (bA.m_sweep.t0 < bB.m_sweep.t0) {
+ t0 = bB.m_sweep.t0;
+ bA.m_sweep.Advance(t0);
+ }
+ else if (bB.m_sweep.t0 < bA.m_sweep.t0) {
+ t0 = bA.m_sweep.t0;
+ bB.m_sweep.Advance(t0);
+ }
+ toi = c.ComputeTOI(bA.m_sweep, bB.m_sweep);
+ b2Settings.b2Assert(0.0 <= toi && toi <= 1.0);
+ if (toi > 0.0 && toi < 1.0) {
+ toi = (1.0 - toi) * t0 + toi;
+ if (toi > 1) toi = 1;
+ }
+ c.m_toi = toi;
+ c.m_flags |= b2Contact.e_toiFlag;
+ }
+ if (Number.MIN_VALUE < toi && toi < minTOI) {
+ minContact = c;
+ minTOI = toi;
+ }
+ }
+ if (minContact == null || 1.0 - 100.0 * Number.MIN_VALUE < minTOI) {
+ break;
+ }
+ fA = minContact.m_fixtureA;
+ fB = minContact.m_fixtureB;
+ bA = fA.m_body;
+ bB = fB.m_body;
+ b2World.s_backupA.Set(bA.m_sweep);
+ b2World.s_backupB.Set(bB.m_sweep);
+ bA.Advance(minTOI);
+ bB.Advance(minTOI);
+ minContact.Update(this.m_contactManager.m_contactListener);
+ minContact.m_flags &= ~b2Contact.e_toiFlag;
+ if (minContact.IsSensor() == true || minContact.IsEnabled() == false) {
+ bA.m_sweep.Set(b2World.s_backupA);
+ bB.m_sweep.Set(b2World.s_backupB);
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ continue;
+ }
+ if (minContact.IsTouching() == false) {
+ continue;
+ }
+ var seed = bA;
+ if (seed.GetType() != b2Body.b2_dynamicBody) {
+ seed = bB;
+ }
+ island.Clear();
+ var queueStart = 0;
+ var queueSize = 0;
+ queue[queueStart + queueSize++] = seed;
+ seed.m_flags |= b2Body.e_islandFlag;
+ while (queueSize > 0) {
+ b = queue[queueStart++];
+ --queueSize;
+ island.AddBody(b);
+ if (b.IsAwake() == false) {
+ b.SetAwake(true);
+ }
+ if (b.GetType() != b2Body.b2_dynamicBody) {
+ continue;
+ }
+ for (cEdge = b.m_contactList;
+ cEdge; cEdge = cEdge.next) {
+ if (island.m_contactCount == island.m_contactCapacity) {
+ break;
+ }
+ if (cEdge.contact.m_flags & b2Contact.e_islandFlag) {
+ continue;
+ }
+ if (cEdge.contact.IsSensor() == true || cEdge.contact.IsEnabled() == false || cEdge.contact.IsTouching() == false) {
+ continue;
+ }
+ island.AddContact(cEdge.contact);
+ cEdge.contact.m_flags |= b2Contact.e_islandFlag;
+ var other = cEdge.other;
+ if (other.m_flags & b2Body.e_islandFlag) {
+ continue;
+ }
+ if (other.GetType() != b2Body.b2_staticBody) {
+ other.Advance(minTOI);
+ other.SetAwake(true);
+ }
+ queue[queueStart + queueSize] = other;
+ ++queueSize;
+ other.m_flags |= b2Body.e_islandFlag;
+ }
+ for (var jEdge = b.m_jointList; jEdge; jEdge = jEdge.next) {
+ if (island.m_jointCount == island.m_jointCapacity) continue;
+ if (jEdge.joint.m_islandFlag == true) continue;
+ other = jEdge.other;
+ if (other.IsActive() == false) {
+ continue;
+ }
+ island.AddJoint(jEdge.joint);
+ jEdge.joint.m_islandFlag = true;
+ if (other.m_flags & b2Body.e_islandFlag) continue;
+ if (other.GetType() != b2Body.b2_staticBody) {
+ other.Advance(minTOI);
+ other.SetAwake(true);
+ }
+ queue[queueStart + queueSize] = other;
+ ++queueSize;
+ other.m_flags |= b2Body.e_islandFlag;
+ }
+ }
+ var subStep = b2World.s_timestep;
+ subStep.warmStarting = false;
+ subStep.dt = (1.0 - minTOI) * step.dt;
+ subStep.inv_dt = 1.0 / subStep.dt;
+ subStep.dtRatio = 0.0;
+ subStep.velocityIterations = step.velocityIterations;
+ subStep.positionIterations = step.positionIterations;
+ island.SolveTOI(subStep);
+ var i = 0;
+ for (i = 0;
+ i < island.m_bodyCount; ++i) {
+ b = island.m_bodies[i];
+ b.m_flags &= ~b2Body.e_islandFlag;
+ if (b.IsAwake() == false) {
+ continue;
+ }
+ if (b.GetType() != b2Body.b2_dynamicBody) {
+ continue;
+ }
+ b.SynchronizeFixtures();
+ for (cEdge = b.m_contactList;
+ cEdge; cEdge = cEdge.next) {
+ cEdge.contact.m_flags &= ~b2Contact.e_toiFlag;
+ }
+ }
+ for (i = 0;
+ i < island.m_contactCount; ++i) {
+ c = island.m_contacts[i];
+ c.m_flags &= ~ (b2Contact.e_toiFlag | b2Contact.e_islandFlag);
+ }
+ for (i = 0;
+ i < island.m_jointCount; ++i) {
+ j = island.m_joints[i];
+ j.m_islandFlag = false;
+ }
+ this.m_contactManager.FindNewContacts();
+ }
+ }
+ b2World.prototype.DrawJoint = function (joint) {
+ var b1 = joint.GetBodyA();
+ var b2 = joint.GetBodyB();
+ var xf1 = b1.m_xf;
+ var xf2 = b2.m_xf;
+ var x1 = xf1.position;
+ var x2 = xf2.position;
+ var p1 = joint.GetAnchorA();
+ var p2 = joint.GetAnchorB();
+ var color = b2World.s_jointColor;
+ switch (joint.m_type) {
+ case b2Joint.e_distanceJoint:
+ this.m_debugDraw.DrawSegment(p1, p2, color);
+ break;
+ case b2Joint.e_pulleyJoint:
+ {
+ var pulley = ((joint instanceof b2PulleyJoint ? joint : null));
+ var s1 = pulley.GetGroundAnchorA();
+ var s2 = pulley.GetGroundAnchorB();
+ this.m_debugDraw.DrawSegment(s1, p1, color);
+ this.m_debugDraw.DrawSegment(s2, p2, color);
+ this.m_debugDraw.DrawSegment(s1, s2, color);
+ }
+ break;
+ case b2Joint.e_mouseJoint:
+ this.m_debugDraw.DrawSegment(p1, p2, color);
+ break;
+ default:
+ if (b1 != this.m_groundBody) this.m_debugDraw.DrawSegment(x1, p1, color);
+ this.m_debugDraw.DrawSegment(p1, p2, color);
+ if (b2 != this.m_groundBody) this.m_debugDraw.DrawSegment(x2, p2, color);
+ }
+ }
+ b2World.prototype.DrawShape = function (shape, xf, color) {
+ switch (shape.m_type) {
+ case b2Shape.e_circleShape:
+ {
+ var circle = ((shape instanceof b2CircleShape ? shape : null));
+ var center = b2Math.MulX(xf, circle.m_p);
+ var radius = circle.m_radius;
+ var axis = xf.R.col1;
+ this.m_debugDraw.DrawSolidCircle(center, radius, axis, color);
+ }
+ break;
+ case b2Shape.e_polygonShape:
+ {
+ var i = 0;
+ var poly = ((shape instanceof b2PolygonShape ? shape : null));
+ var vertexCount = parseInt(poly.GetVertexCount());
+ var localVertices = poly.GetVertices();
+ var vertices = new Vector(vertexCount);
+ for (i = 0;
+ i < vertexCount; ++i) {
+ vertices[i] = b2Math.MulX(xf, localVertices[i]);
+ }
+ this.m_debugDraw.DrawSolidPolygon(vertices, vertexCount, color);
+ }
+ break;
+ case b2Shape.e_edgeShape:
+ {
+ var edge = (shape instanceof b2EdgeShape ? shape : null);
+ this.m_debugDraw.DrawSegment(b2Math.MulX(xf, edge.GetVertex1()), b2Math.MulX(xf, edge.GetVertex2()), color);
+ }
+ break;
+ }
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.b2World.s_timestep2 = new b2TimeStep();
+ Box2D.Dynamics.b2World.s_xf = new b2Transform();
+ Box2D.Dynamics.b2World.s_backupA = new b2Sweep();
+ Box2D.Dynamics.b2World.s_backupB = new b2Sweep();
+ Box2D.Dynamics.b2World.s_timestep = new b2TimeStep();
+ Box2D.Dynamics.b2World.s_queue = new Vector();
+ Box2D.Dynamics.b2World.s_jointColor = new b2Color(0.5, 0.8, 0.8);
+ Box2D.Dynamics.b2World.e_newFixture = 0x0001;
+ Box2D.Dynamics.b2World.e_locked = 0x0002;
+ });
+})();
+(function () {
+ var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
+ b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef,
+ b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape,
+ b2MassData = Box2D.Collision.Shapes.b2MassData,
+ b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
+ b2Shape = Box2D.Collision.Shapes.b2Shape,
+ b2CircleContact = Box2D.Dynamics.Contacts.b2CircleContact,
+ b2Contact = Box2D.Dynamics.Contacts.b2Contact,
+ b2ContactConstraint = Box2D.Dynamics.Contacts.b2ContactConstraint,
+ b2ContactConstraintPoint = Box2D.Dynamics.Contacts.b2ContactConstraintPoint,
+ b2ContactEdge = Box2D.Dynamics.Contacts.b2ContactEdge,
+ b2ContactFactory = Box2D.Dynamics.Contacts.b2ContactFactory,
+ b2ContactRegister = Box2D.Dynamics.Contacts.b2ContactRegister,
+ b2ContactResult = Box2D.Dynamics.Contacts.b2ContactResult,
+ b2ContactSolver = Box2D.Dynamics.Contacts.b2ContactSolver,
+ b2EdgeAndCircleContact = Box2D.Dynamics.Contacts.b2EdgeAndCircleContact,
+ b2NullContact = Box2D.Dynamics.Contacts.b2NullContact,
+ b2PolyAndCircleContact = Box2D.Dynamics.Contacts.b2PolyAndCircleContact,
+ b2PolyAndEdgeContact = Box2D.Dynamics.Contacts.b2PolyAndEdgeContact,
+ b2PolygonContact = Box2D.Dynamics.Contacts.b2PolygonContact,
+ b2PositionSolverManifold = Box2D.Dynamics.Contacts.b2PositionSolverManifold,
+ b2Body = Box2D.Dynamics.b2Body,
+ b2BodyDef = Box2D.Dynamics.b2BodyDef,
+ b2ContactFilter = Box2D.Dynamics.b2ContactFilter,
+ b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse,
+ b2ContactListener = Box2D.Dynamics.b2ContactListener,
+ b2ContactManager = Box2D.Dynamics.b2ContactManager,
+ b2DebugDraw = Box2D.Dynamics.b2DebugDraw,
+ b2DestructionListener = Box2D.Dynamics.b2DestructionListener,
+ b2FilterData = Box2D.Dynamics.b2FilterData,
+ b2Fixture = Box2D.Dynamics.b2Fixture,
+ b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
+ b2Island = Box2D.Dynamics.b2Island,
+ b2TimeStep = Box2D.Dynamics.b2TimeStep,
+ b2World = Box2D.Dynamics.b2World,
+ b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3,
+ b2AABB = Box2D.Collision.b2AABB,
+ b2Bound = Box2D.Collision.b2Bound,
+ b2BoundValues = Box2D.Collision.b2BoundValues,
+ b2Collision = Box2D.Collision.b2Collision,
+ b2ContactID = Box2D.Collision.b2ContactID,
+ b2ContactPoint = Box2D.Collision.b2ContactPoint,
+ b2Distance = Box2D.Collision.b2Distance,
+ b2DistanceInput = Box2D.Collision.b2DistanceInput,
+ b2DistanceOutput = Box2D.Collision.b2DistanceOutput,
+ b2DistanceProxy = Box2D.Collision.b2DistanceProxy,
+ b2DynamicTree = Box2D.Collision.b2DynamicTree,
+ b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase,
+ b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode,
+ b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair,
+ b2Manifold = Box2D.Collision.b2Manifold,
+ b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint,
+ b2Point = Box2D.Collision.b2Point,
+ b2RayCastInput = Box2D.Collision.b2RayCastInput,
+ b2RayCastOutput = Box2D.Collision.b2RayCastOutput,
+ b2Segment = Box2D.Collision.b2Segment,
+ b2SeparationFunction = Box2D.Collision.b2SeparationFunction,
+ b2Simplex = Box2D.Collision.b2Simplex,
+ b2SimplexCache = Box2D.Collision.b2SimplexCache,
+ b2SimplexVertex = Box2D.Collision.b2SimplexVertex,
+ b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact,
+ b2TOIInput = Box2D.Collision.b2TOIInput,
+ b2WorldManifold = Box2D.Collision.b2WorldManifold,
+ ClipVertex = Box2D.Collision.ClipVertex,
+ Features = Box2D.Collision.Features,
+ IBroadPhase = Box2D.Collision.IBroadPhase;
+
+ Box2D.inherit(b2CircleContact, Box2D.Dynamics.Contacts.b2Contact);
+ b2CircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype;
+ b2CircleContact.b2CircleContact = function () {
+ Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments);
+ };
+ b2CircleContact.Create = function (allocator) {
+ return new b2CircleContact();
+ }
+ b2CircleContact.Destroy = function (contact, allocator) {}
+ b2CircleContact.prototype.Reset = function (fixtureA, fixtureB) {
+ this.__super.Reset.call(this, fixtureA, fixtureB);
+ }
+ b2CircleContact.prototype.Evaluate = function () {
+ var bA = this.m_fixtureA.GetBody();
+ var bB = this.m_fixtureB.GetBody();
+ b2Collision.CollideCircles(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2CircleShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf);
+ }
+ b2Contact.b2Contact = function () {
+ this.m_nodeA = new b2ContactEdge();
+ this.m_nodeB = new b2ContactEdge();
+ this.m_manifold = new b2Manifold();
+ this.m_oldManifold = new b2Manifold();
+ };
+ b2Contact.prototype.GetManifold = function () {
+ return this.m_manifold;
+ }
+ b2Contact.prototype.GetWorldManifold = function (worldManifold) {
+ var bodyA = this.m_fixtureA.GetBody();
+ var bodyB = this.m_fixtureB.GetBody();
+ var shapeA = this.m_fixtureA.GetShape();
+ var shapeB = this.m_fixtureB.GetShape();
+ worldManifold.Initialize(this.m_manifold, bodyA.GetTransform(), shapeA.m_radius, bodyB.GetTransform(), shapeB.m_radius);
+ }
+ b2Contact.prototype.IsTouching = function () {
+ return (this.m_flags & b2Contact.e_touchingFlag) == b2Contact.e_touchingFlag;
+ }
+ b2Contact.prototype.IsContinuous = function () {
+ return (this.m_flags & b2Contact.e_continuousFlag) == b2Contact.e_continuousFlag;
+ }
+ b2Contact.prototype.SetSensor = function (sensor) {
+ if (sensor) {
+ this.m_flags |= b2Contact.e_sensorFlag;
+ }
+ else {
+ this.m_flags &= ~b2Contact.e_sensorFlag;
+ }
+ }
+ b2Contact.prototype.IsSensor = function () {
+ return (this.m_flags & b2Contact.e_sensorFlag) == b2Contact.e_sensorFlag;
+ }
+ b2Contact.prototype.SetEnabled = function (flag) {
+ if (flag) {
+ this.m_flags |= b2Contact.e_enabledFlag;
+ }
+ else {
+ this.m_flags &= ~b2Contact.e_enabledFlag;
+ }
+ }
+ b2Contact.prototype.IsEnabled = function () {
+ return (this.m_flags & b2Contact.e_enabledFlag) == b2Contact.e_enabledFlag;
+ }
+ b2Contact.prototype.GetNext = function () {
+ return this.m_next;
+ }
+ b2Contact.prototype.GetFixtureA = function () {
+ return this.m_fixtureA;
+ }
+ b2Contact.prototype.GetFixtureB = function () {
+ return this.m_fixtureB;
+ }
+ b2Contact.prototype.FlagForFiltering = function () {
+ this.m_flags |= b2Contact.e_filterFlag;
+ }
+ b2Contact.prototype.b2Contact = function () {}
+ b2Contact.prototype.Reset = function (fixtureA, fixtureB) {
+ if (fixtureA === undefined) fixtureA = null;
+ if (fixtureB === undefined) fixtureB = null;
+ this.m_flags = b2Contact.e_enabledFlag;
+ if (!fixtureA || !fixtureB) {
+ this.m_fixtureA = null;
+ this.m_fixtureB = null;
+ return;
+ }
+ if (fixtureA.IsSensor() || fixtureB.IsSensor()) {
+ this.m_flags |= b2Contact.e_sensorFlag;
+ }
+ var bodyA = fixtureA.GetBody();
+ var bodyB = fixtureB.GetBody();
+ if (bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) {
+ this.m_flags |= b2Contact.e_continuousFlag;
+ }
+ this.m_fixtureA = fixtureA;
+ this.m_fixtureB = fixtureB;
+ this.m_manifold.m_pointCount = 0;
+ this.m_prev = null;
+ this.m_next = null;
+ this.m_nodeA.contact = null;
+ this.m_nodeA.prev = null;
+ this.m_nodeA.next = null;
+ this.m_nodeA.other = null;
+ this.m_nodeB.contact = null;
+ this.m_nodeB.prev = null;
+ this.m_nodeB.next = null;
+ this.m_nodeB.other = null;
+ }
+ b2Contact.prototype.Update = function (listener) {
+ var tManifold = this.m_oldManifold;
+ this.m_oldManifold = this.m_manifold;
+ this.m_manifold = tManifold;
+ this.m_flags |= b2Contact.e_enabledFlag;
+ var touching = false;
+ var wasTouching = (this.m_flags & b2Contact.e_touchingFlag) == b2Contact.e_touchingFlag;
+ var bodyA = this.m_fixtureA.m_body;
+ var bodyB = this.m_fixtureB.m_body;
+ var aabbOverlap = this.m_fixtureA.m_aabb.TestOverlap(this.m_fixtureB.m_aabb);
+ if (this.m_flags & b2Contact.e_sensorFlag) {
+ if (aabbOverlap) {
+ var shapeA = this.m_fixtureA.GetShape();
+ var shapeB = this.m_fixtureB.GetShape();
+ var xfA = bodyA.GetTransform();
+ var xfB = bodyB.GetTransform();
+ touching = b2Shape.TestOverlap(shapeA, xfA, shapeB, xfB);
+ }
+ this.m_manifold.m_pointCount = 0;
+ }
+ else {
+ if (bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) {
+ this.m_flags |= b2Contact.e_continuousFlag;
+ }
+ else {
+ this.m_flags &= ~b2Contact.e_continuousFlag;
+ }
+ if (aabbOverlap) {
+ this.Evaluate();
+ touching = this.m_manifold.m_pointCount > 0;
+ for (var i = 0; i < this.m_manifold.m_pointCount; ++i) {
+ var mp2 = this.m_manifold.m_points[i];
+ mp2.m_normalImpulse = 0.0;
+ mp2.m_tangentImpulse = 0.0;
+ var id2 = mp2.m_id;
+ for (var j = 0; j < this.m_oldManifold.m_pointCount; ++j) {
+ var mp1 = this.m_oldManifold.m_points[j];
+ if (mp1.m_id.key == id2.key) {
+ mp2.m_normalImpulse = mp1.m_normalImpulse;
+ mp2.m_tangentImpulse = mp1.m_tangentImpulse;
+ break;
+ }
+ }
+ }
+ }
+ else {
+ this.m_manifold.m_pointCount = 0;
+ }
+ if (touching != wasTouching) {
+ bodyA.SetAwake(true);
+ bodyB.SetAwake(true);
+ }
+ }
+ if (touching) {
+ this.m_flags |= b2Contact.e_touchingFlag;
+ }
+ else {
+ this.m_flags &= ~b2Contact.e_touchingFlag;
+ }
+ if (wasTouching == false && touching == true) {
+ listener.BeginContact(this);
+ }
+ if (wasTouching == true && touching == false) {
+ listener.EndContact(this);
+ }
+ if ((this.m_flags & b2Contact.e_sensorFlag) == 0) {
+ listener.PreSolve(this, this.m_oldManifold);
+ }
+ }
+ b2Contact.prototype.Evaluate = function () {}
+ b2Contact.prototype.ComputeTOI = function (sweepA, sweepB) {
+ b2Contact.s_input.proxyA.Set(this.m_fixtureA.GetShape());
+ b2Contact.s_input.proxyB.Set(this.m_fixtureB.GetShape());
+ b2Contact.s_input.sweepA = sweepA;
+ b2Contact.s_input.sweepB = sweepB;
+ b2Contact.s_input.tolerance = b2Settings.b2_linearSlop;
+ return b2TimeOfImpact.TimeOfImpact(b2Contact.s_input);
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.Contacts.b2Contact.e_sensorFlag = 0x0001;
+ Box2D.Dynamics.Contacts.b2Contact.e_continuousFlag = 0x0002;
+ Box2D.Dynamics.Contacts.b2Contact.e_islandFlag = 0x0004;
+ Box2D.Dynamics.Contacts.b2Contact.e_toiFlag = 0x0008;
+ Box2D.Dynamics.Contacts.b2Contact.e_touchingFlag = 0x0010;
+ Box2D.Dynamics.Contacts.b2Contact.e_enabledFlag = 0x0020;
+ Box2D.Dynamics.Contacts.b2Contact.e_filterFlag = 0x0040;
+ Box2D.Dynamics.Contacts.b2Contact.s_input = new b2TOIInput();
+ });
+ b2ContactConstraint.b2ContactConstraint = function () {
+ this.localPlaneNormal = new b2Vec2();
+ this.localPoint = new b2Vec2();
+ this.normal = new b2Vec2();
+ this.normalMass = new b2Mat22();
+ this.K = new b2Mat22();
+ };
+ b2ContactConstraint.prototype.b2ContactConstraint = function () {
+ this.points = new Vector(b2Settings.b2_maxManifoldPoints);
+ for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) {
+ this.points[i] = new b2ContactConstraintPoint();
+ }
+ }
+ b2ContactConstraintPoint.b2ContactConstraintPoint = function () {
+ this.localPoint = new b2Vec2();
+ this.rA = new b2Vec2();
+ this.rB = new b2Vec2();
+ };
+ b2ContactEdge.b2ContactEdge = function () {};
+ b2ContactFactory.b2ContactFactory = function () {};
+ b2ContactFactory.prototype.b2ContactFactory = function (allocator) {
+ this.m_allocator = allocator;
+ this.InitializeRegisters();
+ }
+ b2ContactFactory.prototype.AddType = function (createFcn, destroyFcn, type1, type2) {
+ if (type1 === undefined) type1 = 0;
+ if (type2 === undefined) type2 = 0;
+ this.m_registers[type1][type2].createFcn = createFcn;
+ this.m_registers[type1][type2].destroyFcn = destroyFcn;
+ this.m_registers[type1][type2].primary = true;
+ if (type1 != type2) {
+ this.m_registers[type2][type1].createFcn = createFcn;
+ this.m_registers[type2][type1].destroyFcn = destroyFcn;
+ this.m_registers[type2][type1].primary = false;
+ }
+ }
+ b2ContactFactory.prototype.InitializeRegisters = function () {
+ this.m_registers = new Vector(b2Shape.e_shapeTypeCount);
+ for (var i = 0; i < b2Shape.e_shapeTypeCount; i++) {
+ this.m_registers[i] = new Vector(b2Shape.e_shapeTypeCount);
+ for (var j = 0; j < b2Shape.e_shapeTypeCount; j++) {
+ this.m_registers[i][j] = new b2ContactRegister();
+ }
+ }
+ this.AddType(b2CircleContact.Create, b2CircleContact.Destroy, b2Shape.e_circleShape, b2Shape.e_circleShape);
+ this.AddType(b2PolyAndCircleContact.Create, b2PolyAndCircleContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_circleShape);
+ this.AddType(b2PolygonContact.Create, b2PolygonContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_polygonShape);
+ this.AddType(b2EdgeAndCircleContact.Create, b2EdgeAndCircleContact.Destroy, b2Shape.e_edgeShape, b2Shape.e_circleShape);
+ this.AddType(b2PolyAndEdgeContact.Create, b2PolyAndEdgeContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_edgeShape);
+ }
+ b2ContactFactory.prototype.Create = function (fixtureA, fixtureB) {
+ var type1 = parseInt(fixtureA.GetType());
+ var type2 = parseInt(fixtureB.GetType());
+ var reg = this.m_registers[type1][type2];
+ var c;
+ if (reg.pool) {
+ c = reg.pool;
+ reg.pool = c.m_next;
+ reg.poolCount--;
+ c.Reset(fixtureA, fixtureB);
+ return c;
+ }
+ var createFcn = reg.createFcn;
+ if (createFcn != null) {
+ if (reg.primary) {
+ c = createFcn(this.m_allocator);
+ c.Reset(fixtureA, fixtureB);
+ return c;
+ }
+ else {
+ c = createFcn(this.m_allocator);
+ c.Reset(fixtureB, fixtureA);
+ return c;
+ }
+ }
+ else {
+ return null;
+ }
+ }
+ b2ContactFactory.prototype.Destroy = function (contact) {
+ if (contact.m_manifold.m_pointCount > 0) {
+ contact.m_fixtureA.m_body.SetAwake(true);
+ contact.m_fixtureB.m_body.SetAwake(true);
+ }
+ var type1 = parseInt(contact.m_fixtureA.GetType());
+ var type2 = parseInt(contact.m_fixtureB.GetType());
+ var reg = this.m_registers[type1][type2];
+ if (true) {
+ reg.poolCount++;
+ contact.m_next = reg.pool;
+ reg.pool = contact;
+ }
+ var destroyFcn = reg.destroyFcn;
+ destroyFcn(contact, this.m_allocator);
+ }
+ b2ContactRegister.b2ContactRegister = function () {};
+ b2ContactResult.b2ContactResult = function () {
+ this.position = new b2Vec2();
+ this.normal = new b2Vec2();
+ this.id = new b2ContactID();
+ };
+ b2ContactSolver.b2ContactSolver = function () {
+ this.m_step = new b2TimeStep();
+ this.m_constraints = new Vector();
+ };
+ b2ContactSolver.prototype.b2ContactSolver = function () {}
+ b2ContactSolver.prototype.Initialize = function (step, contacts, contactCount, allocator) {
+ if (contactCount === undefined) contactCount = 0;
+ var contact;
+ this.m_step.Set(step);
+ this.m_allocator = allocator;
+ var i = 0;
+ var tVec;
+ var tMat;
+ this.m_constraintCount = contactCount;
+ while (this.m_constraints.length < this.m_constraintCount) {
+ this.m_constraints[this.m_constraints.length] = new b2ContactConstraint();
+ }
+ for (i = 0;
+ i < contactCount; ++i) {
+ contact = contacts[i];
+ var fixtureA = contact.m_fixtureA;
+ var fixtureB = contact.m_fixtureB;
+ var shapeA = fixtureA.m_shape;
+ var shapeB = fixtureB.m_shape;
+ var radiusA = shapeA.m_radius;
+ var radiusB = shapeB.m_radius;
+ var bodyA = fixtureA.m_body;
+ var bodyB = fixtureB.m_body;
+ var manifold = contact.GetManifold();
+ var friction = b2Settings.b2MixFriction(fixtureA.GetFriction(), fixtureB.GetFriction());
+ var restitution = b2Settings.b2MixRestitution(fixtureA.GetRestitution(), fixtureB.GetRestitution());
+ var vAX = bodyA.m_linearVelocity.x;
+ var vAY = bodyA.m_linearVelocity.y;
+ var vBX = bodyB.m_linearVelocity.x;
+ var vBY = bodyB.m_linearVelocity.y;
+ var wA = bodyA.m_angularVelocity;
+ var wB = bodyB.m_angularVelocity;
+ b2Settings.b2Assert(manifold.m_pointCount > 0);
+ b2ContactSolver.s_worldManifold.Initialize(manifold, bodyA.m_xf, radiusA, bodyB.m_xf, radiusB);
+ var normalX = b2ContactSolver.s_worldManifold.m_normal.x;
+ var normalY = b2ContactSolver.s_worldManifold.m_normal.y;
+ var cc = this.m_constraints[i];
+ cc.bodyA = bodyA;
+ cc.bodyB = bodyB;
+ cc.manifold = manifold;
+ cc.normal.x = normalX;
+ cc.normal.y = normalY;
+ cc.pointCount = manifold.m_pointCount;
+ cc.friction = friction;
+ cc.restitution = restitution;
+ cc.localPlaneNormal.x = manifold.m_localPlaneNormal.x;
+ cc.localPlaneNormal.y = manifold.m_localPlaneNormal.y;
+ cc.localPoint.x = manifold.m_localPoint.x;
+ cc.localPoint.y = manifold.m_localPoint.y;
+ cc.radius = radiusA + radiusB;
+ cc.type = manifold.m_type;
+ for (var k = 0; k < cc.pointCount; ++k) {
+ var cp = manifold.m_points[k];
+ var ccp = cc.points[k];
+ ccp.normalImpulse = cp.m_normalImpulse;
+ ccp.tangentImpulse = cp.m_tangentImpulse;
+ ccp.localPoint.SetV(cp.m_localPoint);
+ var rAX = ccp.rA.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyA.m_sweep.c.x;
+ var rAY = ccp.rA.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyA.m_sweep.c.y;
+ var rBX = ccp.rB.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyB.m_sweep.c.x;
+ var rBY = ccp.rB.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyB.m_sweep.c.y;
+ var rnA = rAX * normalY - rAY * normalX;
+ var rnB = rBX * normalY - rBY * normalX;
+ rnA *= rnA;
+ rnB *= rnB;
+ var kNormal = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rnA + bodyB.m_invI * rnB;
+ ccp.normalMass = 1.0 / kNormal;
+ var kEqualized = bodyA.m_mass * bodyA.m_invMass + bodyB.m_mass * bodyB.m_invMass;
+ kEqualized += bodyA.m_mass * bodyA.m_invI * rnA + bodyB.m_mass * bodyB.m_invI * rnB;
+ ccp.equalizedMass = 1.0 / kEqualized;
+ var tangentX = normalY;
+ var tangentY = (-normalX);
+ var rtA = rAX * tangentY - rAY * tangentX;
+ var rtB = rBX * tangentY - rBY * tangentX;
+ rtA *= rtA;
+ rtB *= rtB;
+ var kTangent = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rtA + bodyB.m_invI * rtB;
+ ccp.tangentMass = 1.0 / kTangent;
+ ccp.velocityBias = 0.0;
+ var tX = vBX + ((-wB * rBY)) - vAX - ((-wA * rAY));
+ var tY = vBY + (wB * rBX) - vAY - (wA * rAX);
+ var vRel = cc.normal.x * tX + cc.normal.y * tY;
+ if (vRel < (-b2Settings.b2_velocityThreshold)) {
+ ccp.velocityBias += (-cc.restitution * vRel);
+ }
+ }
+ if (cc.pointCount == 2) {
+ var ccp1 = cc.points[0];
+ var ccp2 = cc.points[1];
+ var invMassA = bodyA.m_invMass;
+ var invIA = bodyA.m_invI;
+ var invMassB = bodyB.m_invMass;
+ var invIB = bodyB.m_invI;
+ var rn1A = ccp1.rA.x * normalY - ccp1.rA.y * normalX;
+ var rn1B = ccp1.rB.x * normalY - ccp1.rB.y * normalX;
+ var rn2A = ccp2.rA.x * normalY - ccp2.rA.y * normalX;
+ var rn2B = ccp2.rB.x * normalY - ccp2.rB.y * normalX;
+ var k11 = invMassA + invMassB + invIA * rn1A * rn1A + invIB * rn1B * rn1B;
+ var k22 = invMassA + invMassB + invIA * rn2A * rn2A + invIB * rn2B * rn2B;
+ var k12 = invMassA + invMassB + invIA * rn1A * rn2A + invIB * rn1B * rn2B;
+ var k_maxConditionNumber = 100.0;
+ if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) {
+ cc.K.col1.Set(k11, k12);
+ cc.K.col2.Set(k12, k22);
+ cc.K.GetInverse(cc.normalMass);
+ }
+ else {
+ cc.pointCount = 1;
+ }
+ }
+ }
+ }
+ b2ContactSolver.prototype.InitVelocityConstraints = function (step) {
+ var tVec;
+ var tVec2;
+ var tMat;
+ for (var i = 0; i < this.m_constraintCount; ++i) {
+ var c = this.m_constraints[i];
+ var bodyA = c.bodyA;
+ var bodyB = c.bodyB;
+ var invMassA = bodyA.m_invMass;
+ var invIA = bodyA.m_invI;
+ var invMassB = bodyB.m_invMass;
+ var invIB = bodyB.m_invI;
+ var normalX = c.normal.x;
+ var normalY = c.normal.y;
+ var tangentX = normalY;
+ var tangentY = (-normalX);
+ var tX = 0;
+ var j = 0;
+ var tCount = 0;
+ if (step.warmStarting) {
+ tCount = c.pointCount;
+ for (j = 0;
+ j < tCount; ++j) {
+ var ccp = c.points[j];
+ ccp.normalImpulse *= step.dtRatio;
+ ccp.tangentImpulse *= step.dtRatio;
+ var PX = ccp.normalImpulse * normalX + ccp.tangentImpulse * tangentX;
+ var PY = ccp.normalImpulse * normalY + ccp.tangentImpulse * tangentY;
+ bodyA.m_angularVelocity -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX);
+ bodyA.m_linearVelocity.x -= invMassA * PX;
+ bodyA.m_linearVelocity.y -= invMassA * PY;
+ bodyB.m_angularVelocity += invIB * (ccp.rB.x * PY - ccp.rB.y * PX);
+ bodyB.m_linearVelocity.x += invMassB * PX;
+ bodyB.m_linearVelocity.y += invMassB * PY;
+ }
+ }
+ else {
+ tCount = c.pointCount;
+ for (j = 0;
+ j < tCount; ++j) {
+ var ccp2 = c.points[j];
+ ccp2.normalImpulse = 0.0;
+ ccp2.tangentImpulse = 0.0;
+ }
+ }
+ }
+ }
+ b2ContactSolver.prototype.SolveVelocityConstraints = function () {
+ var j = 0;
+ var ccp;
+ var rAX = 0;
+ var rAY = 0;
+ var rBX = 0;
+ var rBY = 0;
+ var dvX = 0;
+ var dvY = 0;
+ var vn = 0;
+ var vt = 0;
+ var lambda = 0;
+ var maxFriction = 0;
+ var newImpulse = 0;
+ var PX = 0;
+ var PY = 0;
+ var dX = 0;
+ var dY = 0;
+ var P1X = 0;
+ var P1Y = 0;
+ var P2X = 0;
+ var P2Y = 0;
+ var tMat;
+ var tVec;
+ for (var i = 0; i < this.m_constraintCount; ++i) {
+ var c = this.m_constraints[i];
+ var bodyA = c.bodyA;
+ var bodyB = c.bodyB;
+ var wA = bodyA.m_angularVelocity;
+ var wB = bodyB.m_angularVelocity;
+ var vA = bodyA.m_linearVelocity;
+ var vB = bodyB.m_linearVelocity;
+ var invMassA = bodyA.m_invMass;
+ var invIA = bodyA.m_invI;
+ var invMassB = bodyB.m_invMass;
+ var invIB = bodyB.m_invI;
+ var normalX = c.normal.x;
+ var normalY = c.normal.y;
+ var tangentX = normalY;
+ var tangentY = (-normalX);
+ var friction = c.friction;
+ var tX = 0;
+ for (j = 0;
+ j < c.pointCount; j++) {
+ ccp = c.points[j];
+ dvX = vB.x - wB * ccp.rB.y - vA.x + wA * ccp.rA.y;
+ dvY = vB.y + wB * ccp.rB.x - vA.y - wA * ccp.rA.x;
+ vt = dvX * tangentX + dvY * tangentY;
+ lambda = ccp.tangentMass * (-vt);
+ maxFriction = friction * ccp.normalImpulse;
+ newImpulse = b2Math.Clamp(ccp.tangentImpulse + lambda, (-maxFriction), maxFriction);
+ lambda = newImpulse - ccp.tangentImpulse;
+ PX = lambda * tangentX;
+ PY = lambda * tangentY;
+ vA.x -= invMassA * PX;
+ vA.y -= invMassA * PY;
+ wA -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX);
+ vB.x += invMassB * PX;
+ vB.y += invMassB * PY;
+ wB += invIB * (ccp.rB.x * PY - ccp.rB.y * PX);
+ ccp.tangentImpulse = newImpulse;
+ }
+ var tCount = parseInt(c.pointCount);
+ if (c.pointCount == 1) {
+ ccp = c.points[0];
+ dvX = vB.x + ((-wB * ccp.rB.y)) - vA.x - ((-wA * ccp.rA.y));
+ dvY = vB.y + (wB * ccp.rB.x) - vA.y - (wA * ccp.rA.x);
+ vn = dvX * normalX + dvY * normalY;
+ lambda = (-ccp.normalMass * (vn - ccp.velocityBias));
+ newImpulse = ccp.normalImpulse + lambda;
+ newImpulse = newImpulse > 0 ? newImpulse : 0.0;
+ lambda = newImpulse - ccp.normalImpulse;
+ PX = lambda * normalX;
+ PY = lambda * normalY;
+ vA.x -= invMassA * PX;
+ vA.y -= invMassA * PY;
+ wA -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX);
+ vB.x += invMassB * PX;
+ vB.y += invMassB * PY;
+ wB += invIB * (ccp.rB.x * PY - ccp.rB.y * PX);
+ ccp.normalImpulse = newImpulse;
+ }
+ else {
+ var cp1 = c.points[0];
+ var cp2 = c.points[1];
+ var aX = cp1.normalImpulse;
+ var aY = cp2.normalImpulse;
+ var dv1X = vB.x - wB * cp1.rB.y - vA.x + wA * cp1.rA.y;
+ var dv1Y = vB.y + wB * cp1.rB.x - vA.y - wA * cp1.rA.x;
+ var dv2X = vB.x - wB * cp2.rB.y - vA.x + wA * cp2.rA.y;
+ var dv2Y = vB.y + wB * cp2.rB.x - vA.y - wA * cp2.rA.x;
+ var vn1 = dv1X * normalX + dv1Y * normalY;
+ var vn2 = dv2X * normalX + dv2Y * normalY;
+ var bX = vn1 - cp1.velocityBias;
+ var bY = vn2 - cp2.velocityBias;
+ tMat = c.K;
+ bX -= tMat.col1.x * aX + tMat.col2.x * aY;
+ bY -= tMat.col1.y * aX + tMat.col2.y * aY;
+ var k_errorTol = 0.001;
+ for (;;) {
+ tMat = c.normalMass;
+ var xX = (-(tMat.col1.x * bX + tMat.col2.x * bY));
+ var xY = (-(tMat.col1.y * bX + tMat.col2.y * bY));
+ if (xX >= 0.0 && xY >= 0.0) {
+ dX = xX - aX;
+ dY = xY - aY;
+ P1X = dX * normalX;
+ P1Y = dX * normalY;
+ P2X = dY * normalX;
+ P2Y = dY * normalY;
+ vA.x -= invMassA * (P1X + P2X);
+ vA.y -= invMassA * (P1Y + P2Y);
+ wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X);
+ vB.x += invMassB * (P1X + P2X);
+ vB.y += invMassB * (P1Y + P2Y);
+ wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X);
+ cp1.normalImpulse = xX;
+ cp2.normalImpulse = xY;
+ break;
+ }
+ xX = (-cp1.normalMass * bX);
+ xY = 0.0;
+ vn1 = 0.0;
+ vn2 = c.K.col1.y * xX + bY;
+ if (xX >= 0.0 && vn2 >= 0.0) {
+ dX = xX - aX;
+ dY = xY - aY;
+ P1X = dX * normalX;
+ P1Y = dX * normalY;
+ P2X = dY * normalX;
+ P2Y = dY * normalY;
+ vA.x -= invMassA * (P1X + P2X);
+ vA.y -= invMassA * (P1Y + P2Y);
+ wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X);
+ vB.x += invMassB * (P1X + P2X);
+ vB.y += invMassB * (P1Y + P2Y);
+ wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X);
+ cp1.normalImpulse = xX;
+ cp2.normalImpulse = xY;
+ break;
+ }
+ xX = 0.0;
+ xY = (-cp2.normalMass * bY);
+ vn1 = c.K.col2.x * xY + bX;
+ vn2 = 0.0;
+ if (xY >= 0.0 && vn1 >= 0.0) {
+ dX = xX - aX;
+ dY = xY - aY;
+ P1X = dX * normalX;
+ P1Y = dX * normalY;
+ P2X = dY * normalX;
+ P2Y = dY * normalY;
+ vA.x -= invMassA * (P1X + P2X);
+ vA.y -= invMassA * (P1Y + P2Y);
+ wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X);
+ vB.x += invMassB * (P1X + P2X);
+ vB.y += invMassB * (P1Y + P2Y);
+ wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X);
+ cp1.normalImpulse = xX;
+ cp2.normalImpulse = xY;
+ break;
+ }
+ xX = 0.0;
+ xY = 0.0;
+ vn1 = bX;
+ vn2 = bY;
+ if (vn1 >= 0.0 && vn2 >= 0.0) {
+ dX = xX - aX;
+ dY = xY - aY;
+ P1X = dX * normalX;
+ P1Y = dX * normalY;
+ P2X = dY * normalX;
+ P2Y = dY * normalY;
+ vA.x -= invMassA * (P1X + P2X);
+ vA.y -= invMassA * (P1Y + P2Y);
+ wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X);
+ vB.x += invMassB * (P1X + P2X);
+ vB.y += invMassB * (P1Y + P2Y);
+ wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X);
+ cp1.normalImpulse = xX;
+ cp2.normalImpulse = xY;
+ break;
+ }
+ break;
+ }
+ }
+ bodyA.m_angularVelocity = wA;
+ bodyB.m_angularVelocity = wB;
+ }
+ }
+ b2ContactSolver.prototype.FinalizeVelocityConstraints = function () {
+ for (var i = 0; i < this.m_constraintCount; ++i) {
+ var c = this.m_constraints[i];
+ var m = c.manifold;
+ for (var j = 0; j < c.pointCount; ++j) {
+ var point1 = m.m_points[j];
+ var point2 = c.points[j];
+ point1.m_normalImpulse = point2.normalImpulse;
+ point1.m_tangentImpulse = point2.tangentImpulse;
+ }
+ }
+ }
+ b2ContactSolver.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var minSeparation = 0.0;
+ for (var i = 0; i < this.m_constraintCount; i++) {
+ var c = this.m_constraints[i];
+ var bodyA = c.bodyA;
+ var bodyB = c.bodyB;
+ var invMassA = bodyA.m_mass * bodyA.m_invMass;
+ var invIA = bodyA.m_mass * bodyA.m_invI;
+ var invMassB = bodyB.m_mass * bodyB.m_invMass;
+ var invIB = bodyB.m_mass * bodyB.m_invI;
+ b2ContactSolver.s_psm.Initialize(c);
+ var normal = b2ContactSolver.s_psm.m_normal;
+ for (var j = 0; j < c.pointCount; j++) {
+ var ccp = c.points[j];
+ var point = b2ContactSolver.s_psm.m_points[j];
+ var separation = b2ContactSolver.s_psm.m_separations[j];
+ var rAX = point.x - bodyA.m_sweep.c.x;
+ var rAY = point.y - bodyA.m_sweep.c.y;
+ var rBX = point.x - bodyB.m_sweep.c.x;
+ var rBY = point.y - bodyB.m_sweep.c.y;
+ minSeparation = minSeparation < separation ? minSeparation : separation;
+ var C = b2Math.Clamp(baumgarte * (separation + b2Settings.b2_linearSlop), (-b2Settings.b2_maxLinearCorrection), 0.0);
+ var impulse = (-ccp.equalizedMass * C);
+ var PX = impulse * normal.x;
+ var PY = impulse * normal.y;bodyA.m_sweep.c.x -= invMassA * PX;
+ bodyA.m_sweep.c.y -= invMassA * PY;
+ bodyA.m_sweep.a -= invIA * (rAX * PY - rAY * PX);
+ bodyA.SynchronizeTransform();
+ bodyB.m_sweep.c.x += invMassB * PX;
+ bodyB.m_sweep.c.y += invMassB * PY;
+ bodyB.m_sweep.a += invIB * (rBX * PY - rBY * PX);
+ bodyB.SynchronizeTransform();
+ }
+ }
+ return minSeparation > (-1.5 * b2Settings.b2_linearSlop);
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.Contacts.b2ContactSolver.s_worldManifold = new b2WorldManifold();
+ Box2D.Dynamics.Contacts.b2ContactSolver.s_psm = new b2PositionSolverManifold();
+ });
+ Box2D.inherit(b2EdgeAndCircleContact, Box2D.Dynamics.Contacts.b2Contact);
+ b2EdgeAndCircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype;
+ b2EdgeAndCircleContact.b2EdgeAndCircleContact = function () {
+ Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments);
+ };
+ b2EdgeAndCircleContact.Create = function (allocator) {
+ return new b2EdgeAndCircleContact();
+ }
+ b2EdgeAndCircleContact.Destroy = function (contact, allocator) {}
+ b2EdgeAndCircleContact.prototype.Reset = function (fixtureA, fixtureB) {
+ this.__super.Reset.call(this, fixtureA, fixtureB);
+ }
+ b2EdgeAndCircleContact.prototype.Evaluate = function () {
+ var bA = this.m_fixtureA.GetBody();
+ var bB = this.m_fixtureB.GetBody();
+ this.b2CollideEdgeAndCircle(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2EdgeShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf);
+ }
+ b2EdgeAndCircleContact.prototype.b2CollideEdgeAndCircle = function (manifold, edge, xf1, circle, xf2) {}
+ Box2D.inherit(b2NullContact, Box2D.Dynamics.Contacts.b2Contact);
+ b2NullContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype;
+ b2NullContact.b2NullContact = function () {
+ Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments);
+ };
+ b2NullContact.prototype.b2NullContact = function () {
+ this.__super.b2Contact.call(this);
+ }
+ b2NullContact.prototype.Evaluate = function () {}
+ Box2D.inherit(b2PolyAndCircleContact, Box2D.Dynamics.Contacts.b2Contact);
+ b2PolyAndCircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype;
+ b2PolyAndCircleContact.b2PolyAndCircleContact = function () {
+ Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments);
+ };
+ b2PolyAndCircleContact.Create = function (allocator) {
+ return new b2PolyAndCircleContact();
+ }
+ b2PolyAndCircleContact.Destroy = function (contact, allocator) {}
+ b2PolyAndCircleContact.prototype.Reset = function (fixtureA, fixtureB) {
+ this.__super.Reset.call(this, fixtureA, fixtureB);
+ b2Settings.b2Assert(fixtureA.GetType() == b2Shape.e_polygonShape);
+ b2Settings.b2Assert(fixtureB.GetType() == b2Shape.e_circleShape);
+ }
+ b2PolyAndCircleContact.prototype.Evaluate = function () {
+ var bA = this.m_fixtureA.m_body;
+ var bB = this.m_fixtureB.m_body;
+ b2Collision.CollidePolygonAndCircle(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf);
+ }
+ Box2D.inherit(b2PolyAndEdgeContact, Box2D.Dynamics.Contacts.b2Contact);
+ b2PolyAndEdgeContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype;
+ b2PolyAndEdgeContact.b2PolyAndEdgeContact = function () {
+ Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments);
+ };
+ b2PolyAndEdgeContact.Create = function (allocator) {
+ return new b2PolyAndEdgeContact();
+ }
+ b2PolyAndEdgeContact.Destroy = function (contact, allocator) {}
+ b2PolyAndEdgeContact.prototype.Reset = function (fixtureA, fixtureB) {
+ this.__super.Reset.call(this, fixtureA, fixtureB);
+ b2Settings.b2Assert(fixtureA.GetType() == b2Shape.e_polygonShape);
+ b2Settings.b2Assert(fixtureB.GetType() == b2Shape.e_edgeShape);
+ }
+ b2PolyAndEdgeContact.prototype.Evaluate = function () {
+ var bA = this.m_fixtureA.GetBody();
+ var bB = this.m_fixtureB.GetBody();
+ this.b2CollidePolyAndEdge(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2EdgeShape ? this.m_fixtureB.GetShape() : null), bB.m_xf);
+ }
+ b2PolyAndEdgeContact.prototype.b2CollidePolyAndEdge = function (manifold, polygon, xf1, edge, xf2) {}
+ Box2D.inherit(b2PolygonContact, Box2D.Dynamics.Contacts.b2Contact);
+ b2PolygonContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype;
+ b2PolygonContact.b2PolygonContact = function () {
+ Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments);
+ };
+ b2PolygonContact.Create = function (allocator) {
+ return new b2PolygonContact();
+ }
+ b2PolygonContact.Destroy = function (contact, allocator) {}
+ b2PolygonContact.prototype.Reset = function (fixtureA, fixtureB) {
+ this.__super.Reset.call(this, fixtureA, fixtureB);
+ }
+ b2PolygonContact.prototype.Evaluate = function () {
+ var bA = this.m_fixtureA.GetBody();
+ var bB = this.m_fixtureB.GetBody();
+ b2Collision.CollidePolygons(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2PolygonShape ? this.m_fixtureB.GetShape() : null), bB.m_xf);
+ }
+ b2PositionSolverManifold.b2PositionSolverManifold = function () {};
+ b2PositionSolverManifold.prototype.b2PositionSolverManifold = function () {
+ this.m_normal = new b2Vec2();
+ this.m_separations = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints);
+ this.m_points = new Vector(b2Settings.b2_maxManifoldPoints);
+ for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) {
+ this.m_points[i] = new b2Vec2();
+ }
+ }
+ b2PositionSolverManifold.prototype.Initialize = function (cc) {
+ b2Settings.b2Assert(cc.pointCount > 0);
+ var i = 0;
+ var clipPointX = 0;
+ var clipPointY = 0;
+ var tMat;
+ var tVec;
+ var planePointX = 0;
+ var planePointY = 0;
+ switch (cc.type) {
+ case b2Manifold.e_circles:
+ {
+ tMat = cc.bodyA.m_xf.R;
+ tVec = cc.localPoint;
+ var pointAX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var pointAY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tMat = cc.bodyB.m_xf.R;
+ tVec = cc.points[0].localPoint;
+ var pointBX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ var pointBY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ var dX = pointBX - pointAX;
+ var dY = pointBY - pointAY;
+ var d2 = dX * dX + dY * dY;
+ if (d2 > Number.MIN_VALUE * Number.MIN_VALUE) {
+ var d = Math.sqrt(d2);
+ this.m_normal.x = dX / d;
+ this.m_normal.y = dY / d;
+ }
+ else {
+ this.m_normal.x = 1.0;
+ this.m_normal.y = 0.0;
+ }
+ this.m_points[0].x = 0.5 * (pointAX + pointBX);
+ this.m_points[0].y = 0.5 * (pointAY + pointBY);
+ this.m_separations[0] = dX * this.m_normal.x + dY * this.m_normal.y - cc.radius;
+ }
+ break;
+ case b2Manifold.e_faceA:
+ {
+ tMat = cc.bodyA.m_xf.R;
+ tVec = cc.localPlaneNormal;
+ this.m_normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ this.m_normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tMat = cc.bodyA.m_xf.R;
+ tVec = cc.localPoint;
+ planePointX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ planePointY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tMat = cc.bodyB.m_xf.R;
+ for (i = 0;
+ i < cc.pointCount; ++i) {
+ tVec = cc.points[i].localPoint;
+ clipPointX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ clipPointY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ this.m_separations[i] = (clipPointX - planePointX) * this.m_normal.x + (clipPointY - planePointY) * this.m_normal.y - cc.radius;
+ this.m_points[i].x = clipPointX;
+ this.m_points[i].y = clipPointY;
+ }
+ }
+ break;
+ case b2Manifold.e_faceB:
+ {
+ tMat = cc.bodyB.m_xf.R;
+ tVec = cc.localPlaneNormal;
+ this.m_normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ this.m_normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tMat = cc.bodyB.m_xf.R;
+ tVec = cc.localPoint;
+ planePointX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ planePointY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ tMat = cc.bodyA.m_xf.R;
+ for (i = 0;
+ i < cc.pointCount; ++i) {
+ tVec = cc.points[i].localPoint;
+ clipPointX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
+ clipPointY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
+ this.m_separations[i] = (clipPointX - planePointX) * this.m_normal.x + (clipPointY - planePointY) * this.m_normal.y - cc.radius;
+ this.m_points[i].Set(clipPointX, clipPointY);
+ }
+ this.m_normal.x *= (-1);
+ this.m_normal.y *= (-1);
+ }
+ break;
+ }
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointA = new b2Vec2();
+ Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointB = new b2Vec2();
+ });
+})();
+(function () {
+ var b2Body = Box2D.Dynamics.b2Body,
+ b2BodyDef = Box2D.Dynamics.b2BodyDef,
+ b2ContactFilter = Box2D.Dynamics.b2ContactFilter,
+ b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse,
+ b2ContactListener = Box2D.Dynamics.b2ContactListener,
+ b2ContactManager = Box2D.Dynamics.b2ContactManager,
+ b2DebugDraw = Box2D.Dynamics.b2DebugDraw,
+ b2DestructionListener = Box2D.Dynamics.b2DestructionListener,
+ b2FilterData = Box2D.Dynamics.b2FilterData,
+ b2Fixture = Box2D.Dynamics.b2Fixture,
+ b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
+ b2Island = Box2D.Dynamics.b2Island,
+ b2TimeStep = Box2D.Dynamics.b2TimeStep,
+ b2World = Box2D.Dynamics.b2World,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3,
+ b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
+ b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef,
+ b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape,
+ b2MassData = Box2D.Collision.Shapes.b2MassData,
+ b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
+ b2Shape = Box2D.Collision.Shapes.b2Shape,
+ b2BuoyancyController = Box2D.Dynamics.Controllers.b2BuoyancyController,
+ b2ConstantAccelController = Box2D.Dynamics.Controllers.b2ConstantAccelController,
+ b2ConstantForceController = Box2D.Dynamics.Controllers.b2ConstantForceController,
+ b2Controller = Box2D.Dynamics.Controllers.b2Controller,
+ b2ControllerEdge = Box2D.Dynamics.Controllers.b2ControllerEdge,
+ b2GravityController = Box2D.Dynamics.Controllers.b2GravityController,
+ b2TensorDampingController = Box2D.Dynamics.Controllers.b2TensorDampingController;
+
+ Box2D.inherit(b2BuoyancyController, Box2D.Dynamics.Controllers.b2Controller);
+ b2BuoyancyController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype;
+ b2BuoyancyController.b2BuoyancyController = function () {
+ Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments);
+ this.normal = new b2Vec2(0, (-1));
+ this.offset = 0;
+ this.density = 0;
+ this.velocity = new b2Vec2(0, 0);
+ this.linearDrag = 2;
+ this.angularDrag = 1;
+ this.useDensity = false;
+ this.useWorldGravity = true;
+ this.gravity = null;
+ };
+ b2BuoyancyController.prototype.Step = function (step) {
+ if (!this.m_bodyList) return;
+ if (this.useWorldGravity) {
+ this.gravity = this.GetWorld().GetGravity().Copy();
+ }
+ for (var i = this.m_bodyList; i; i = i.nextBody) {
+ var body = i.body;
+ if (body.IsAwake() == false) {
+ continue;
+ }
+ var areac = new b2Vec2();
+ var massc = new b2Vec2();
+ var area = 0.0;
+ var mass = 0.0;
+ for (var fixture = body.GetFixtureList(); fixture; fixture = fixture.GetNext()) {
+ var sc = new b2Vec2();
+ var sarea = fixture.GetShape().ComputeSubmergedArea(this.normal, this.offset, body.GetTransform(), sc);
+ area += sarea;
+ areac.x += sarea * sc.x;
+ areac.y += sarea * sc.y;
+ var shapeDensity = 0;
+ if (this.useDensity) {
+ shapeDensity = 1;
+ }
+ else {
+ shapeDensity = 1;
+ }
+ mass += sarea * shapeDensity;
+ massc.x += sarea * sc.x * shapeDensity;
+ massc.y += sarea * sc.y * shapeDensity;
+ }
+ areac.x /= area;
+ areac.y /= area;
+ massc.x /= mass;
+ massc.y /= mass;
+ if (area < Number.MIN_VALUE) continue;
+ var buoyancyForce = this.gravity.GetNegative();
+ buoyancyForce.Multiply(this.density * area);
+ body.ApplyForce(buoyancyForce, massc);
+ var dragForce = body.GetLinearVelocityFromWorldPoint(areac);
+ dragForce.Subtract(this.velocity);
+ dragForce.Multiply((-this.linearDrag * area));
+ body.ApplyForce(dragForce, areac);
+ body.ApplyTorque((-body.GetInertia() / body.GetMass() * area * body.GetAngularVelocity() * this.angularDrag));
+ }
+ }
+ b2BuoyancyController.prototype.Draw = function (debugDraw) {
+ var r = 1000;
+ var p1 = new b2Vec2();
+ var p2 = new b2Vec2();
+ p1.x = this.normal.x * this.offset + this.normal.y * r;
+ p1.y = this.normal.y * this.offset - this.normal.x * r;
+ p2.x = this.normal.x * this.offset - this.normal.y * r;
+ p2.y = this.normal.y * this.offset + this.normal.x * r;
+ var color = new b2Color(0, 0, 1);
+ debugDraw.DrawSegment(p1, p2, color);
+ }
+ Box2D.inherit(b2ConstantAccelController, Box2D.Dynamics.Controllers.b2Controller);
+ b2ConstantAccelController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype;
+ b2ConstantAccelController.b2ConstantAccelController = function () {
+ Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments);
+ this.A = new b2Vec2(0, 0);
+ };
+ b2ConstantAccelController.prototype.Step = function (step) {
+ var smallA = new b2Vec2(this.A.x * step.dt, this.A.y * step.dt);
+ for (var i = this.m_bodyList; i; i = i.nextBody) {
+ var body = i.body;
+ if (!body.IsAwake()) continue;
+ body.SetLinearVelocity(new b2Vec2(body.GetLinearVelocity().x + smallA.x, body.GetLinearVelocity().y + smallA.y));
+ }
+ }
+ Box2D.inherit(b2ConstantForceController, Box2D.Dynamics.Controllers.b2Controller);
+ b2ConstantForceController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype;
+ b2ConstantForceController.b2ConstantForceController = function () {
+ Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments);
+ this.F = new b2Vec2(0, 0);
+ };
+ b2ConstantForceController.prototype.Step = function (step) {
+ for (var i = this.m_bodyList; i; i = i.nextBody) {
+ var body = i.body;
+ if (!body.IsAwake()) continue;
+ body.ApplyForce(this.F, body.GetWorldCenter());
+ }
+ }
+ b2Controller.b2Controller = function () {};
+ b2Controller.prototype.Step = function (step) {}
+ b2Controller.prototype.Draw = function (debugDraw) {}
+ b2Controller.prototype.AddBody = function (body) {
+ var edge = new b2ControllerEdge();
+ edge.controller = this;
+ edge.body = body;
+ edge.nextBody = this.m_bodyList;
+ edge.prevBody = null;
+ this.m_bodyList = edge;
+ if (edge.nextBody) edge.nextBody.prevBody = edge;
+ this.m_bodyCount++;
+ edge.nextController = body.m_controllerList;
+ edge.prevController = null;
+ body.m_controllerList = edge;
+ if (edge.nextController) edge.nextController.prevController = edge;
+ body.m_controllerCount++;
+ }
+ b2Controller.prototype.RemoveBody = function (body) {
+ var edge = body.m_controllerList;
+ while (edge && edge.controller != this)
+ edge = edge.nextController;
+ if (edge.prevBody) edge.prevBody.nextBody = edge.nextBody;
+ if (edge.nextBody) edge.nextBody.prevBody = edge.prevBody;
+ if (edge.nextController) edge.nextController.prevController = edge.prevController;
+ if (edge.prevController) edge.prevController.nextController = edge.nextController;
+ if (this.m_bodyList == edge) this.m_bodyList = edge.nextBody;
+ if (body.m_controllerList == edge) body.m_controllerList = edge.nextController;
+ body.m_controllerCount--;
+ this.m_bodyCount--;
+ }
+ b2Controller.prototype.Clear = function () {
+ while (this.m_bodyList)
+ this.RemoveBody(this.m_bodyList.body);
+ }
+ b2Controller.prototype.GetNext = function () {
+ return this.m_next;
+ }
+ b2Controller.prototype.GetWorld = function () {
+ return this.m_world;
+ }
+ b2Controller.prototype.GetBodyList = function () {
+ return this.m_bodyList;
+ }
+ b2ControllerEdge.b2ControllerEdge = function () {};
+ Box2D.inherit(b2GravityController, Box2D.Dynamics.Controllers.b2Controller);
+ b2GravityController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype;
+ b2GravityController.b2GravityController = function () {
+ Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments);
+ this.G = 1;
+ this.invSqr = true;
+ };
+ b2GravityController.prototype.Step = function (step) {
+ var i = null;
+ var body1 = null;
+ var p1 = null;
+ var mass1 = 0;
+ var j = null;
+ var body2 = null;
+ var p2 = null;
+ var dx = 0;
+ var dy = 0;
+ var r2 = 0;
+ var f = null;
+ if (this.invSqr) {
+ for (i = this.m_bodyList;
+ i; i = i.nextBody) {
+ body1 = i.body;
+ p1 = body1.GetWorldCenter();
+ mass1 = body1.GetMass();
+ for (j = this.m_bodyList;
+ j != i; j = j.nextBody) {
+ body2 = j.body;
+ p2 = body2.GetWorldCenter();
+ dx = p2.x - p1.x;
+ dy = p2.y - p1.y;
+ r2 = dx * dx + dy * dy;
+ if (r2 < Number.MIN_VALUE) continue;
+ f = new b2Vec2(dx, dy);
+ f.Multiply(this.G / r2 / Math.sqrt(r2) * mass1 * body2.GetMass());
+ if (body1.IsAwake()) body1.ApplyForce(f, p1);
+ f.Multiply((-1));
+ if (body2.IsAwake()) body2.ApplyForce(f, p2);
+ }
+ }
+ }
+ else {
+ for (i = this.m_bodyList;
+ i; i = i.nextBody) {
+ body1 = i.body;
+ p1 = body1.GetWorldCenter();
+ mass1 = body1.GetMass();
+ for (j = this.m_bodyList;
+ j != i; j = j.nextBody) {
+ body2 = j.body;
+ p2 = body2.GetWorldCenter();
+ dx = p2.x - p1.x;
+ dy = p2.y - p1.y;
+ r2 = dx * dx + dy * dy;
+ if (r2 < Number.MIN_VALUE) continue;
+ f = new b2Vec2(dx, dy);
+ f.Multiply(this.G / r2 * mass1 * body2.GetMass());
+ if (body1.IsAwake()) body1.ApplyForce(f, p1);
+ f.Multiply((-1));
+ if (body2.IsAwake()) body2.ApplyForce(f, p2);
+ }
+ }
+ }
+ }
+ Box2D.inherit(b2TensorDampingController, Box2D.Dynamics.Controllers.b2Controller);
+ b2TensorDampingController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype;
+ b2TensorDampingController.b2TensorDampingController = function () {
+ Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments);
+ this.T = new b2Mat22();
+ this.maxTimestep = 0;
+ };
+ b2TensorDampingController.prototype.SetAxisAligned = function (xDamping, yDamping) {
+ if (xDamping === undefined) xDamping = 0;
+ if (yDamping === undefined) yDamping = 0;
+ this.T.col1.x = (-xDamping);
+ this.T.col1.y = 0;
+ this.T.col2.x = 0;
+ this.T.col2.y = (-yDamping);
+ if (xDamping > 0 || yDamping > 0) {
+ this.maxTimestep = 1 / Math.max(xDamping, yDamping);
+ }
+ else {
+ this.maxTimestep = 0;
+ }
+ }
+ b2TensorDampingController.prototype.Step = function (step) {
+ var timestep = step.dt;
+ if (timestep <= Number.MIN_VALUE) return;
+ if (timestep > this.maxTimestep && this.maxTimestep > 0) timestep = this.maxTimestep;
+ for (var i = this.m_bodyList; i; i = i.nextBody) {
+ var body = i.body;
+ if (!body.IsAwake()) {
+ continue;
+ }
+ var damping = body.GetWorldVector(b2Math.MulMV(this.T, body.GetLocalVector(body.GetLinearVelocity())));
+ body.SetLinearVelocity(new b2Vec2(body.GetLinearVelocity().x + damping.x * timestep, body.GetLinearVelocity().y + damping.y * timestep));
+ }
+ }
+})();
+(function () {
+ var b2Color = Box2D.Common.b2Color,
+ b2internal = Box2D.Common.b2internal,
+ b2Settings = Box2D.Common.b2Settings,
+ b2Mat22 = Box2D.Common.Math.b2Mat22,
+ b2Mat33 = Box2D.Common.Math.b2Mat33,
+ b2Math = Box2D.Common.Math.b2Math,
+ b2Sweep = Box2D.Common.Math.b2Sweep,
+ b2Transform = Box2D.Common.Math.b2Transform,
+ b2Vec2 = Box2D.Common.Math.b2Vec2,
+ b2Vec3 = Box2D.Common.Math.b2Vec3,
+ b2DistanceJoint = Box2D.Dynamics.Joints.b2DistanceJoint,
+ b2DistanceJointDef = Box2D.Dynamics.Joints.b2DistanceJointDef,
+ b2FrictionJoint = Box2D.Dynamics.Joints.b2FrictionJoint,
+ b2FrictionJointDef = Box2D.Dynamics.Joints.b2FrictionJointDef,
+ b2GearJoint = Box2D.Dynamics.Joints.b2GearJoint,
+ b2GearJointDef = Box2D.Dynamics.Joints.b2GearJointDef,
+ b2Jacobian = Box2D.Dynamics.Joints.b2Jacobian,
+ b2Joint = Box2D.Dynamics.Joints.b2Joint,
+ b2JointDef = Box2D.Dynamics.Joints.b2JointDef,
+ b2JointEdge = Box2D.Dynamics.Joints.b2JointEdge,
+ b2LineJoint = Box2D.Dynamics.Joints.b2LineJoint,
+ b2LineJointDef = Box2D.Dynamics.Joints.b2LineJointDef,
+ b2MouseJoint = Box2D.Dynamics.Joints.b2MouseJoint,
+ b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef,
+ b2PrismaticJoint = Box2D.Dynamics.Joints.b2PrismaticJoint,
+ b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef,
+ b2PulleyJoint = Box2D.Dynamics.Joints.b2PulleyJoint,
+ b2PulleyJointDef = Box2D.Dynamics.Joints.b2PulleyJointDef,
+ b2RevoluteJoint = Box2D.Dynamics.Joints.b2RevoluteJoint,
+ b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef,
+ b2WeldJoint = Box2D.Dynamics.Joints.b2WeldJoint,
+ b2WeldJointDef = Box2D.Dynamics.Joints.b2WeldJointDef,
+ b2Body = Box2D.Dynamics.b2Body,
+ b2BodyDef = Box2D.Dynamics.b2BodyDef,
+ b2ContactFilter = Box2D.Dynamics.b2ContactFilter,
+ b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse,
+ b2ContactListener = Box2D.Dynamics.b2ContactListener,
+ b2ContactManager = Box2D.Dynamics.b2ContactManager,
+ b2DebugDraw = Box2D.Dynamics.b2DebugDraw,
+ b2DestructionListener = Box2D.Dynamics.b2DestructionListener,
+ b2FilterData = Box2D.Dynamics.b2FilterData,
+ b2Fixture = Box2D.Dynamics.b2Fixture,
+ b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
+ b2Island = Box2D.Dynamics.b2Island,
+ b2TimeStep = Box2D.Dynamics.b2TimeStep,
+ b2World = Box2D.Dynamics.b2World;
+
+ Box2D.inherit(b2DistanceJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2DistanceJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2DistanceJoint.b2DistanceJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.m_localAnchor1 = new b2Vec2();
+ this.m_localAnchor2 = new b2Vec2();
+ this.m_u = new b2Vec2();
+ };
+ b2DistanceJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchor1);
+ }
+ b2DistanceJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchor2);
+ }
+ b2DistanceJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * this.m_impulse * this.m_u.x, inv_dt * this.m_impulse * this.m_u.y);
+ }
+ b2DistanceJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return 0.0;
+ }
+ b2DistanceJoint.prototype.GetLength = function () {
+ return this.m_length;
+ }
+ b2DistanceJoint.prototype.SetLength = function (length) {
+ if (length === undefined) length = 0;
+ this.m_length = length;
+ }
+ b2DistanceJoint.prototype.GetFrequency = function () {
+ return this.m_frequencyHz;
+ }
+ b2DistanceJoint.prototype.SetFrequency = function (hz) {
+ if (hz === undefined) hz = 0;
+ this.m_frequencyHz = hz;
+ }
+ b2DistanceJoint.prototype.GetDampingRatio = function () {
+ return this.m_dampingRatio;
+ }
+ b2DistanceJoint.prototype.SetDampingRatio = function (ratio) {
+ if (ratio === undefined) ratio = 0;
+ this.m_dampingRatio = ratio;
+ }
+ b2DistanceJoint.prototype.b2DistanceJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ var tMat;
+ var tX = 0;
+ var tY = 0;
+ this.m_localAnchor1.SetV(def.localAnchorA);
+ this.m_localAnchor2.SetV(def.localAnchorB);
+ this.m_length = def.length;
+ this.m_frequencyHz = def.frequencyHz;
+ this.m_dampingRatio = def.dampingRatio;
+ this.m_impulse = 0.0;
+ this.m_gamma = 0.0;
+ this.m_bias = 0.0;
+ }
+ b2DistanceJoint.prototype.InitVelocityConstraints = function (step) {
+ var tMat;
+ var tX = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ this.m_u.x = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X;
+ this.m_u.y = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y;
+ var length = Math.sqrt(this.m_u.x * this.m_u.x + this.m_u.y * this.m_u.y);
+ if (length > b2Settings.b2_linearSlop) {
+ this.m_u.Multiply(1.0 / length);
+ }
+ else {
+ this.m_u.SetZero();
+ }
+ var cr1u = (r1X * this.m_u.y - r1Y * this.m_u.x);
+ var cr2u = (r2X * this.m_u.y - r2Y * this.m_u.x);
+ var invMass = bA.m_invMass + bA.m_invI * cr1u * cr1u + bB.m_invMass + bB.m_invI * cr2u * cr2u;
+ this.m_mass = invMass != 0.0 ? 1.0 / invMass : 0.0;
+ if (this.m_frequencyHz > 0.0) {
+ var C = length - this.m_length;
+ var omega = 2.0 * Math.PI * this.m_frequencyHz;
+ var d = 2.0 * this.m_mass * this.m_dampingRatio * omega;
+ var k = this.m_mass * omega * omega;
+ this.m_gamma = step.dt * (d + step.dt * k);
+ this.m_gamma = this.m_gamma != 0.0 ? 1 / this.m_gamma : 0.0;
+ this.m_bias = C * step.dt * k * this.m_gamma;
+ this.m_mass = invMass + this.m_gamma;
+ this.m_mass = this.m_mass != 0.0 ? 1.0 / this.m_mass : 0.0;
+ }
+ if (step.warmStarting) {
+ this.m_impulse *= step.dtRatio;
+ var PX = this.m_impulse * this.m_u.x;
+ var PY = this.m_impulse * this.m_u.y;
+ bA.m_linearVelocity.x -= bA.m_invMass * PX;
+ bA.m_linearVelocity.y -= bA.m_invMass * PY;
+ bA.m_angularVelocity -= bA.m_invI * (r1X * PY - r1Y * PX);
+ bB.m_linearVelocity.x += bB.m_invMass * PX;
+ bB.m_linearVelocity.y += bB.m_invMass * PY;
+ bB.m_angularVelocity += bB.m_invI * (r2X * PY - r2Y * PX);
+ }
+ else {
+ this.m_impulse = 0.0;
+ }
+ }
+ b2DistanceJoint.prototype.SolveVelocityConstraints = function (step) {
+ var tMat;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y));
+ var v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X);
+ var v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y));
+ var v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X);
+ var Cdot = (this.m_u.x * (v2X - v1X) + this.m_u.y * (v2Y - v1Y));
+ var impulse = (-this.m_mass * (Cdot + this.m_bias + this.m_gamma * this.m_impulse));
+ this.m_impulse += impulse;
+ var PX = impulse * this.m_u.x;
+ var PY = impulse * this.m_u.y;
+ bA.m_linearVelocity.x -= bA.m_invMass * PX;
+ bA.m_linearVelocity.y -= bA.m_invMass * PY;
+ bA.m_angularVelocity -= bA.m_invI * (r1X * PY - r1Y * PX);
+ bB.m_linearVelocity.x += bB.m_invMass * PX;
+ bB.m_linearVelocity.y += bB.m_invMass * PY;
+ bB.m_angularVelocity += bB.m_invI * (r2X * PY - r2Y * PX);
+ }
+ b2DistanceJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var tMat;
+ if (this.m_frequencyHz > 0.0) {
+ return true;
+ }
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X;
+ var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y;
+ var length = Math.sqrt(dX * dX + dY * dY);
+ dX /= length;
+ dY /= length;
+ var C = length - this.m_length;
+ C = b2Math.Clamp(C, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection);
+ var impulse = (-this.m_mass * C);
+ this.m_u.Set(dX, dY);
+ var PX = impulse * this.m_u.x;
+ var PY = impulse * this.m_u.y;
+ bA.m_sweep.c.x -= bA.m_invMass * PX;
+ bA.m_sweep.c.y -= bA.m_invMass * PY;
+ bA.m_sweep.a -= bA.m_invI * (r1X * PY - r1Y * PX);
+ bB.m_sweep.c.x += bB.m_invMass * PX;
+ bB.m_sweep.c.y += bB.m_invMass * PY;
+ bB.m_sweep.a += bB.m_invI * (r2X * PY - r2Y * PX);
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ return b2Math.Abs(C) < b2Settings.b2_linearSlop;
+ }
+ Box2D.inherit(b2DistanceJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2DistanceJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2DistanceJointDef.b2DistanceJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.localAnchorA = new b2Vec2();
+ this.localAnchorB = new b2Vec2();
+ };
+ b2DistanceJointDef.prototype.b2DistanceJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_distanceJoint;
+ this.length = 1.0;
+ this.frequencyHz = 0.0;
+ this.dampingRatio = 0.0;
+ }
+ b2DistanceJointDef.prototype.Initialize = function (bA, bB, anchorA, anchorB) {
+ this.bodyA = bA;
+ this.bodyB = bB;
+ this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchorA));
+ this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchorB));
+ var dX = anchorB.x - anchorA.x;
+ var dY = anchorB.y - anchorA.y;
+ this.length = Math.sqrt(dX * dX + dY * dY);
+ this.frequencyHz = 0.0;
+ this.dampingRatio = 0.0;
+ }
+ Box2D.inherit(b2FrictionJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2FrictionJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2FrictionJoint.b2FrictionJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.m_localAnchorA = new b2Vec2();
+ this.m_localAnchorB = new b2Vec2();
+ this.m_linearMass = new b2Mat22();
+ this.m_linearImpulse = new b2Vec2();
+ };
+ b2FrictionJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchorA);
+ }
+ b2FrictionJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchorB);
+ }
+ b2FrictionJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * this.m_linearImpulse.x, inv_dt * this.m_linearImpulse.y);
+ }
+ b2FrictionJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return inv_dt * this.m_angularImpulse;
+ }
+ b2FrictionJoint.prototype.SetMaxForce = function (force) {
+ if (force === undefined) force = 0;
+ this.m_maxForce = force;
+ }
+ b2FrictionJoint.prototype.GetMaxForce = function () {
+ return this.m_maxForce;
+ }
+ b2FrictionJoint.prototype.SetMaxTorque = function (torque) {
+ if (torque === undefined) torque = 0;
+ this.m_maxTorque = torque;
+ }
+ b2FrictionJoint.prototype.GetMaxTorque = function () {
+ return this.m_maxTorque;
+ }
+ b2FrictionJoint.prototype.b2FrictionJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ this.m_localAnchorA.SetV(def.localAnchorA);
+ this.m_localAnchorB.SetV(def.localAnchorB);
+ this.m_linearMass.SetZero();
+ this.m_angularMass = 0.0;
+ this.m_linearImpulse.SetZero();
+ this.m_angularImpulse = 0.0;
+ this.m_maxForce = def.maxForce;
+ this.m_maxTorque = def.maxTorque;
+ }
+ b2FrictionJoint.prototype.InitVelocityConstraints = function (step) {
+ var tMat;
+ var tX = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ tMat = bA.m_xf.R;
+ var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x;
+ var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rAX + tMat.col2.x * rAY);
+ rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY);
+ rAX = tX;
+ tMat = bB.m_xf.R;
+ var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x;
+ var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rBX + tMat.col2.x * rBY);
+ rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY);
+ rBX = tX;
+ var mA = bA.m_invMass;
+ var mB = bB.m_invMass;
+ var iA = bA.m_invI;
+ var iB = bB.m_invI;
+ var K = new b2Mat22();
+ K.col1.x = mA + mB;
+ K.col2.x = 0.0;
+ K.col1.y = 0.0;
+ K.col2.y = mA + mB;
+ K.col1.x += iA * rAY * rAY;
+ K.col2.x += (-iA * rAX * rAY);
+ K.col1.y += (-iA * rAX * rAY);
+ K.col2.y += iA * rAX * rAX;
+ K.col1.x += iB * rBY * rBY;
+ K.col2.x += (-iB * rBX * rBY);
+ K.col1.y += (-iB * rBX * rBY);
+ K.col2.y += iB * rBX * rBX;
+ K.GetInverse(this.m_linearMass);
+ this.m_angularMass = iA + iB;
+ if (this.m_angularMass > 0.0) {
+ this.m_angularMass = 1.0 / this.m_angularMass;
+ }
+ if (step.warmStarting) {
+ this.m_linearImpulse.x *= step.dtRatio;
+ this.m_linearImpulse.y *= step.dtRatio;
+ this.m_angularImpulse *= step.dtRatio;
+ var P = this.m_linearImpulse;
+ bA.m_linearVelocity.x -= mA * P.x;
+ bA.m_linearVelocity.y -= mA * P.y;
+ bA.m_angularVelocity -= iA * (rAX * P.y - rAY * P.x + this.m_angularImpulse);
+ bB.m_linearVelocity.x += mB * P.x;
+ bB.m_linearVelocity.y += mB * P.y;
+ bB.m_angularVelocity += iB * (rBX * P.y - rBY * P.x + this.m_angularImpulse);
+ }
+ else {
+ this.m_linearImpulse.SetZero();
+ this.m_angularImpulse = 0.0;
+ }
+ }
+ b2FrictionJoint.prototype.SolveVelocityConstraints = function (step) {
+ var tMat;
+ var tX = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var vA = bA.m_linearVelocity;
+ var wA = bA.m_angularVelocity;
+ var vB = bB.m_linearVelocity;
+ var wB = bB.m_angularVelocity;
+ var mA = bA.m_invMass;
+ var mB = bB.m_invMass;
+ var iA = bA.m_invI;
+ var iB = bB.m_invI;
+ tMat = bA.m_xf.R;
+ var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x;
+ var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rAX + tMat.col2.x * rAY);
+ rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY);
+ rAX = tX;
+ tMat = bB.m_xf.R;
+ var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x;
+ var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rBX + tMat.col2.x * rBY);
+ rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY);
+ rBX = tX;
+ var maxImpulse = 0; {
+ var Cdot = wB - wA;
+ var impulse = (-this.m_angularMass * Cdot);
+ var oldImpulse = this.m_angularImpulse;
+ maxImpulse = step.dt * this.m_maxTorque;
+ this.m_angularImpulse = b2Math.Clamp(this.m_angularImpulse + impulse, (-maxImpulse), maxImpulse);
+ impulse = this.m_angularImpulse - oldImpulse;
+ wA -= iA * impulse;
+ wB += iB * impulse;
+ } {
+ var CdotX = vB.x - wB * rBY - vA.x + wA * rAY;
+ var CdotY = vB.y + wB * rBX - vA.y - wA * rAX;
+ var impulseV = b2Math.MulMV(this.m_linearMass, new b2Vec2((-CdotX), (-CdotY)));
+ var oldImpulseV = this.m_linearImpulse.Copy();
+ this.m_linearImpulse.Add(impulseV);
+ maxImpulse = step.dt * this.m_maxForce;
+ if (this.m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) {
+ this.m_linearImpulse.Normalize();
+ this.m_linearImpulse.Multiply(maxImpulse);
+ }
+ impulseV = b2Math.SubtractVV(this.m_linearImpulse, oldImpulseV);
+ vA.x -= mA * impulseV.x;
+ vA.y -= mA * impulseV.y;
+ wA -= iA * (rAX * impulseV.y - rAY * impulseV.x);
+ vB.x += mB * impulseV.x;
+ vB.y += mB * impulseV.y;
+ wB += iB * (rBX * impulseV.y - rBY * impulseV.x);
+ }
+ bA.m_angularVelocity = wA;
+ bB.m_angularVelocity = wB;
+ }
+ b2FrictionJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ return true;
+ }
+ Box2D.inherit(b2FrictionJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2FrictionJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2FrictionJointDef.b2FrictionJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.localAnchorA = new b2Vec2();
+ this.localAnchorB = new b2Vec2();
+ };
+ b2FrictionJointDef.prototype.b2FrictionJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_frictionJoint;
+ this.maxForce = 0.0;
+ this.maxTorque = 0.0;
+ }
+ b2FrictionJointDef.prototype.Initialize = function (bA, bB, anchor) {
+ this.bodyA = bA;
+ this.bodyB = bB;
+ this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchor));
+ this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchor));
+ }
+ Box2D.inherit(b2GearJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2GearJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2GearJoint.b2GearJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.m_groundAnchor1 = new b2Vec2();
+ this.m_groundAnchor2 = new b2Vec2();
+ this.m_localAnchor1 = new b2Vec2();
+ this.m_localAnchor2 = new b2Vec2();
+ this.m_J = new b2Jacobian();
+ };
+ b2GearJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchor1);
+ }
+ b2GearJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchor2);
+ }
+ b2GearJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * this.m_impulse * this.m_J.linearB.x, inv_dt * this.m_impulse * this.m_J.linearB.y);
+ }
+ b2GearJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ var tMat = this.m_bodyB.m_xf.R;
+ var rX = this.m_localAnchor1.x - this.m_bodyB.m_sweep.localCenter.x;
+ var rY = this.m_localAnchor1.y - this.m_bodyB.m_sweep.localCenter.y;
+ var tX = tMat.col1.x * rX + tMat.col2.x * rY;
+ rY = tMat.col1.y * rX + tMat.col2.y * rY;
+ rX = tX;
+ var PX = this.m_impulse * this.m_J.linearB.x;
+ var PY = this.m_impulse * this.m_J.linearB.y;
+ return inv_dt * (this.m_impulse * this.m_J.angularB - rX * PY + rY * PX);
+ }
+ b2GearJoint.prototype.GetRatio = function () {
+ return this.m_ratio;
+ }
+ b2GearJoint.prototype.SetRatio = function (ratio) {
+ if (ratio === undefined) ratio = 0;
+ this.m_ratio = ratio;
+ }
+ b2GearJoint.prototype.b2GearJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ var type1 = parseInt(def.joint1.m_type);
+ var type2 = parseInt(def.joint2.m_type);
+ this.m_revolute1 = null;
+ this.m_prismatic1 = null;
+ this.m_revolute2 = null;
+ this.m_prismatic2 = null;
+ var coordinate1 = 0;
+ var coordinate2 = 0;
+ this.m_ground1 = def.joint1.GetBodyA();
+ this.m_bodyA = def.joint1.GetBodyB();
+ if (type1 == b2Joint.e_revoluteJoint) {
+ this.m_revolute1 = (def.joint1 instanceof b2RevoluteJoint ? def.joint1 : null);
+ this.m_groundAnchor1.SetV(this.m_revolute1.m_localAnchor1);
+ this.m_localAnchor1.SetV(this.m_revolute1.m_localAnchor2);
+ coordinate1 = this.m_revolute1.GetJointAngle();
+ }
+ else {
+ this.m_prismatic1 = (def.joint1 instanceof b2PrismaticJoint ? def.joint1 : null);
+ this.m_groundAnchor1.SetV(this.m_prismatic1.m_localAnchor1);
+ this.m_localAnchor1.SetV(this.m_prismatic1.m_localAnchor2);
+ coordinate1 = this.m_prismatic1.GetJointTranslation();
+ }
+ this.m_ground2 = def.joint2.GetBodyA();
+ this.m_bodyB = def.joint2.GetBodyB();
+ if (type2 == b2Joint.e_revoluteJoint) {
+ this.m_revolute2 = (def.joint2 instanceof b2RevoluteJoint ? def.joint2 : null);
+ this.m_groundAnchor2.SetV(this.m_revolute2.m_localAnchor1);
+ this.m_localAnchor2.SetV(this.m_revolute2.m_localAnchor2);
+ coordinate2 = this.m_revolute2.GetJointAngle();
+ }
+ else {
+ this.m_prismatic2 = (def.joint2 instanceof b2PrismaticJoint ? def.joint2 : null);
+ this.m_groundAnchor2.SetV(this.m_prismatic2.m_localAnchor1);
+ this.m_localAnchor2.SetV(this.m_prismatic2.m_localAnchor2);
+ coordinate2 = this.m_prismatic2.GetJointTranslation();
+ }
+ this.m_ratio = def.ratio;
+ this.m_constant = coordinate1 + this.m_ratio * coordinate2;
+ this.m_impulse = 0.0;
+ }
+ b2GearJoint.prototype.InitVelocityConstraints = function (step) {
+ var g1 = this.m_ground1;
+ var g2 = this.m_ground2;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var ugX = 0;
+ var ugY = 0;
+ var rX = 0;
+ var rY = 0;
+ var tMat;
+ var tVec;
+ var crug = 0;
+ var tX = 0;
+ var K = 0.0;
+ this.m_J.SetZero();
+ if (this.m_revolute1) {
+ this.m_J.angularA = (-1.0);
+ K += bA.m_invI;
+ }
+ else {
+ tMat = g1.m_xf.R;
+ tVec = this.m_prismatic1.m_localXAxis1;
+ ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tMat = bA.m_xf.R;
+ rX = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ rY = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = tMat.col1.x * rX + tMat.col2.x * rY;
+ rY = tMat.col1.y * rX + tMat.col2.y * rY;
+ rX = tX;
+ crug = rX * ugY - rY * ugX;
+ this.m_J.linearA.Set((-ugX), (-ugY));
+ this.m_J.angularA = (-crug);
+ K += bA.m_invMass + bA.m_invI * crug * crug;
+ }
+ if (this.m_revolute2) {
+ this.m_J.angularB = (-this.m_ratio);
+ K += this.m_ratio * this.m_ratio * bB.m_invI;
+ }
+ else {
+ tMat = g2.m_xf.R;
+ tVec = this.m_prismatic2.m_localXAxis1;
+ ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
+ ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
+ tMat = bB.m_xf.R;
+ rX = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ rY = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = tMat.col1.x * rX + tMat.col2.x * rY;
+ rY = tMat.col1.y * rX + tMat.col2.y * rY;
+ rX = tX;
+ crug = rX * ugY - rY * ugX;
+ this.m_J.linearB.Set((-this.m_ratio * ugX), (-this.m_ratio * ugY));
+ this.m_J.angularB = (-this.m_ratio * crug);
+ K += this.m_ratio * this.m_ratio * (bB.m_invMass + bB.m_invI * crug * crug);
+ }
+ this.m_mass = K > 0.0 ? 1.0 / K : 0.0;
+ if (step.warmStarting) {
+ bA.m_linearVelocity.x += bA.m_invMass * this.m_impulse * this.m_J.linearA.x;
+ bA.m_linearVelocity.y += bA.m_invMass * this.m_impulse * this.m_J.linearA.y;
+ bA.m_angularVelocity += bA.m_invI * this.m_impulse * this.m_J.angularA;
+ bB.m_linearVelocity.x += bB.m_invMass * this.m_impulse * this.m_J.linearB.x;
+ bB.m_linearVelocity.y += bB.m_invMass * this.m_impulse * this.m_J.linearB.y;
+ bB.m_angularVelocity += bB.m_invI * this.m_impulse * this.m_J.angularB;
+ }
+ else {
+ this.m_impulse = 0.0;
+ }
+ }
+ b2GearJoint.prototype.SolveVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var Cdot = this.m_J.Compute(bA.m_linearVelocity, bA.m_angularVelocity, bB.m_linearVelocity, bB.m_angularVelocity);
+ var impulse = (-this.m_mass * Cdot);
+ this.m_impulse += impulse;
+ bA.m_linearVelocity.x += bA.m_invMass * impulse * this.m_J.linearA.x;
+ bA.m_linearVelocity.y += bA.m_invMass * impulse * this.m_J.linearA.y;
+ bA.m_angularVelocity += bA.m_invI * impulse * this.m_J.angularA;
+ bB.m_linearVelocity.x += bB.m_invMass * impulse * this.m_J.linearB.x;
+ bB.m_linearVelocity.y += bB.m_invMass * impulse * this.m_J.linearB.y;
+ bB.m_angularVelocity += bB.m_invI * impulse * this.m_J.angularB;
+ }
+ b2GearJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var linearError = 0.0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var coordinate1 = 0;
+ var coordinate2 = 0;
+ if (this.m_revolute1) {
+ coordinate1 = this.m_revolute1.GetJointAngle();
+ }
+ else {
+ coordinate1 = this.m_prismatic1.GetJointTranslation();
+ }
+ if (this.m_revolute2) {
+ coordinate2 = this.m_revolute2.GetJointAngle();
+ }
+ else {
+ coordinate2 = this.m_prismatic2.GetJointTranslation();
+ }
+ var C = this.m_constant - (coordinate1 + this.m_ratio * coordinate2);
+ var impulse = (-this.m_mass * C);
+ bA.m_sweep.c.x += bA.m_invMass * impulse * this.m_J.linearA.x;
+ bA.m_sweep.c.y += bA.m_invMass * impulse * this.m_J.linearA.y;
+ bA.m_sweep.a += bA.m_invI * impulse * this.m_J.angularA;
+ bB.m_sweep.c.x += bB.m_invMass * impulse * this.m_J.linearB.x;
+ bB.m_sweep.c.y += bB.m_invMass * impulse * this.m_J.linearB.y;
+ bB.m_sweep.a += bB.m_invI * impulse * this.m_J.angularB;
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ return linearError < b2Settings.b2_linearSlop;
+ }
+ Box2D.inherit(b2GearJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2GearJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2GearJointDef.b2GearJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ };
+ b2GearJointDef.prototype.b2GearJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_gearJoint;
+ this.joint1 = null;
+ this.joint2 = null;
+ this.ratio = 1.0;
+ }
+ b2Jacobian.b2Jacobian = function () {
+ this.linearA = new b2Vec2();
+ this.linearB = new b2Vec2();
+ };
+ b2Jacobian.prototype.SetZero = function () {
+ this.linearA.SetZero();
+ this.angularA = 0.0;
+ this.linearB.SetZero();
+ this.angularB = 0.0;
+ }
+ b2Jacobian.prototype.Set = function (x1, a1, x2, a2) {
+ if (a1 === undefined) a1 = 0;
+ if (a2 === undefined) a2 = 0;
+ this.linearA.SetV(x1);
+ this.angularA = a1;
+ this.linearB.SetV(x2);
+ this.angularB = a2;
+ }
+ b2Jacobian.prototype.Compute = function (x1, a1, x2, a2) {
+ if (a1 === undefined) a1 = 0;
+ if (a2 === undefined) a2 = 0;
+ return (this.linearA.x * x1.x + this.linearA.y * x1.y) + this.angularA * a1 + (this.linearB.x * x2.x + this.linearB.y * x2.y) + this.angularB * a2;
+ }
+ b2Joint.b2Joint = function () {
+ this.m_edgeA = new b2JointEdge();
+ this.m_edgeB = new b2JointEdge();
+ this.m_localCenterA = new b2Vec2();
+ this.m_localCenterB = new b2Vec2();
+ };
+ b2Joint.prototype.GetType = function () {
+ return this.m_type;
+ }
+ b2Joint.prototype.GetAnchorA = function () {
+ return null;
+ }
+ b2Joint.prototype.GetAnchorB = function () {
+ return null;
+ }
+ b2Joint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return null;
+ }
+ b2Joint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return 0.0;
+ }
+ b2Joint.prototype.GetBodyA = function () {
+ return this.m_bodyA;
+ }
+ b2Joint.prototype.GetBodyB = function () {
+ return this.m_bodyB;
+ }
+ b2Joint.prototype.GetNext = function () {
+ return this.m_next;
+ }
+ b2Joint.prototype.GetUserData = function () {
+ return this.m_userData;
+ }
+ b2Joint.prototype.SetUserData = function (data) {
+ this.m_userData = data;
+ }
+ b2Joint.prototype.IsActive = function () {
+ return this.m_bodyA.IsActive() && this.m_bodyB.IsActive();
+ }
+ b2Joint.Create = function (def, allocator) {
+ var joint = null;
+ switch (def.type) {
+ case b2Joint.e_distanceJoint:
+ {
+ joint = new b2DistanceJoint((def instanceof b2DistanceJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_mouseJoint:
+ {
+ joint = new b2MouseJoint((def instanceof b2MouseJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_prismaticJoint:
+ {
+ joint = new b2PrismaticJoint((def instanceof b2PrismaticJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_revoluteJoint:
+ {
+ joint = new b2RevoluteJoint((def instanceof b2RevoluteJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_pulleyJoint:
+ {
+ joint = new b2PulleyJoint((def instanceof b2PulleyJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_gearJoint:
+ {
+ joint = new b2GearJoint((def instanceof b2GearJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_lineJoint:
+ {
+ joint = new b2LineJoint((def instanceof b2LineJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_weldJoint:
+ {
+ joint = new b2WeldJoint((def instanceof b2WeldJointDef ? def : null));
+ }
+ break;
+ case b2Joint.e_frictionJoint:
+ {
+ joint = new b2FrictionJoint((def instanceof b2FrictionJointDef ? def : null));
+ }
+ break;
+ default:
+ break;
+ }
+ return joint;
+ }
+ b2Joint.Destroy = function (joint, allocator) {}
+ b2Joint.prototype.b2Joint = function (def) {
+ b2Settings.b2Assert(def.bodyA != def.bodyB);
+ this.m_type = def.type;
+ this.m_prev = null;
+ this.m_next = null;
+ this.m_bodyA = def.bodyA;
+ this.m_bodyB = def.bodyB;
+ this.m_collideConnected = def.collideConnected;
+ this.m_islandFlag = false;
+ this.m_userData = def.userData;
+ }
+ b2Joint.prototype.InitVelocityConstraints = function (step) {}
+ b2Joint.prototype.SolveVelocityConstraints = function (step) {}
+ b2Joint.prototype.FinalizeVelocityConstraints = function () {}
+ b2Joint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ return false;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.Joints.b2Joint.e_unknownJoint = 0;
+ Box2D.Dynamics.Joints.b2Joint.e_revoluteJoint = 1;
+ Box2D.Dynamics.Joints.b2Joint.e_prismaticJoint = 2;
+ Box2D.Dynamics.Joints.b2Joint.e_distanceJoint = 3;
+ Box2D.Dynamics.Joints.b2Joint.e_pulleyJoint = 4;
+ Box2D.Dynamics.Joints.b2Joint.e_mouseJoint = 5;
+ Box2D.Dynamics.Joints.b2Joint.e_gearJoint = 6;
+ Box2D.Dynamics.Joints.b2Joint.e_lineJoint = 7;
+ Box2D.Dynamics.Joints.b2Joint.e_weldJoint = 8;
+ Box2D.Dynamics.Joints.b2Joint.e_frictionJoint = 9;
+ Box2D.Dynamics.Joints.b2Joint.e_inactiveLimit = 0;
+ Box2D.Dynamics.Joints.b2Joint.e_atLowerLimit = 1;
+ Box2D.Dynamics.Joints.b2Joint.e_atUpperLimit = 2;
+ Box2D.Dynamics.Joints.b2Joint.e_equalLimits = 3;
+ });
+ b2JointDef.b2JointDef = function () {};
+ b2JointDef.prototype.b2JointDef = function () {
+ this.type = b2Joint.e_unknownJoint;
+ this.userData = null;
+ this.bodyA = null;
+ this.bodyB = null;
+ this.collideConnected = false;
+ }
+ b2JointEdge.b2JointEdge = function () {};
+ Box2D.inherit(b2LineJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2LineJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2LineJoint.b2LineJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.m_localAnchor1 = new b2Vec2();
+ this.m_localAnchor2 = new b2Vec2();
+ this.m_localXAxis1 = new b2Vec2();
+ this.m_localYAxis1 = new b2Vec2();
+ this.m_axis = new b2Vec2();
+ this.m_perp = new b2Vec2();
+ this.m_K = new b2Mat22();
+ this.m_impulse = new b2Vec2();
+ };
+ b2LineJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchor1);
+ }
+ b2LineJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchor2);
+ }
+ b2LineJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.x), inv_dt * (this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.y));
+ }
+ b2LineJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return inv_dt * this.m_impulse.y;
+ }
+ b2LineJoint.prototype.GetJointTranslation = function () {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ var p1 = bA.GetWorldPoint(this.m_localAnchor1);
+ var p2 = bB.GetWorldPoint(this.m_localAnchor2);
+ var dX = p2.x - p1.x;
+ var dY = p2.y - p1.y;
+ var axis = bA.GetWorldVector(this.m_localXAxis1);
+ var translation = axis.x * dX + axis.y * dY;
+ return translation;
+ }
+ b2LineJoint.prototype.GetJointSpeed = function () {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var p1X = bA.m_sweep.c.x + r1X;
+ var p1Y = bA.m_sweep.c.y + r1Y;
+ var p2X = bB.m_sweep.c.x + r2X;
+ var p2Y = bB.m_sweep.c.y + r2Y;
+ var dX = p2X - p1X;
+ var dY = p2Y - p1Y;
+ var axis = bA.GetWorldVector(this.m_localXAxis1);
+ var v1 = bA.m_linearVelocity;
+ var v2 = bB.m_linearVelocity;
+ var w1 = bA.m_angularVelocity;
+ var w2 = bB.m_angularVelocity;
+ var speed = (dX * ((-w1 * axis.y)) + dY * (w1 * axis.x)) + (axis.x * (((v2.x + ((-w2 * r2Y))) - v1.x) - ((-w1 * r1Y))) + axis.y * (((v2.y + (w2 * r2X)) - v1.y) - (w1 * r1X)));
+ return speed;
+ }
+ b2LineJoint.prototype.IsLimitEnabled = function () {
+ return this.m_enableLimit;
+ }
+ b2LineJoint.prototype.EnableLimit = function (flag) {
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_enableLimit = flag;
+ }
+ b2LineJoint.prototype.GetLowerLimit = function () {
+ return this.m_lowerTranslation;
+ }
+ b2LineJoint.prototype.GetUpperLimit = function () {
+ return this.m_upperTranslation;
+ }
+ b2LineJoint.prototype.SetLimits = function (lower, upper) {
+ if (lower === undefined) lower = 0;
+ if (upper === undefined) upper = 0;
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_lowerTranslation = lower;
+ this.m_upperTranslation = upper;
+ }
+ b2LineJoint.prototype.IsMotorEnabled = function () {
+ return this.m_enableMotor;
+ }
+ b2LineJoint.prototype.EnableMotor = function (flag) {
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_enableMotor = flag;
+ }
+ b2LineJoint.prototype.SetMotorSpeed = function (speed) {
+ if (speed === undefined) speed = 0;
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_motorSpeed = speed;
+ }
+ b2LineJoint.prototype.GetMotorSpeed = function () {
+ return this.m_motorSpeed;
+ }
+ b2LineJoint.prototype.SetMaxMotorForce = function (force) {
+ if (force === undefined) force = 0;
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_maxMotorForce = force;
+ }
+ b2LineJoint.prototype.GetMaxMotorForce = function () {
+ return this.m_maxMotorForce;
+ }
+ b2LineJoint.prototype.GetMotorForce = function () {
+ return this.m_motorImpulse;
+ }
+ b2LineJoint.prototype.b2LineJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ var tMat;
+ var tX = 0;
+ var tY = 0;
+ this.m_localAnchor1.SetV(def.localAnchorA);
+ this.m_localAnchor2.SetV(def.localAnchorB);
+ this.m_localXAxis1.SetV(def.localAxisA);
+ this.m_localYAxis1.x = (-this.m_localXAxis1.y);
+ this.m_localYAxis1.y = this.m_localXAxis1.x;
+ this.m_impulse.SetZero();
+ this.m_motorMass = 0.0;
+ this.m_motorImpulse = 0.0;
+ this.m_lowerTranslation = def.lowerTranslation;
+ this.m_upperTranslation = def.upperTranslation;
+ this.m_maxMotorForce = def.maxMotorForce;
+ this.m_motorSpeed = def.motorSpeed;
+ this.m_enableLimit = def.enableLimit;
+ this.m_enableMotor = def.enableMotor;
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ this.m_axis.SetZero();
+ this.m_perp.SetZero();
+ }
+ b2LineJoint.prototype.InitVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ var tX = 0;
+ this.m_localCenterA.SetV(bA.GetLocalCenter());
+ this.m_localCenterB.SetV(bB.GetLocalCenter());
+ var xf1 = bA.GetTransform();
+ var xf2 = bB.GetTransform();
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - this.m_localCenterA.x;
+ var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - this.m_localCenterB.x;
+ var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X;
+ var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y;
+ this.m_invMassA = bA.m_invMass;
+ this.m_invMassB = bB.m_invMass;
+ this.m_invIA = bA.m_invI;
+ this.m_invIB = bB.m_invI; {
+ this.m_axis.SetV(b2Math.MulMV(xf1.R, this.m_localXAxis1));
+ this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x;
+ this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x;
+ this.m_motorMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_a1 * this.m_a1 + this.m_invIB * this.m_a2 * this.m_a2;
+ this.m_motorMass = this.m_motorMass > Number.MIN_VALUE ? 1.0 / this.m_motorMass : 0.0;
+ } {
+ this.m_perp.SetV(b2Math.MulMV(xf1.R, this.m_localYAxis1));
+ this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x;
+ this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x;
+ var m1 = this.m_invMassA;
+ var m2 = this.m_invMassB;
+ var i1 = this.m_invIA;
+ var i2 = this.m_invIB;
+ this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2;
+ this.m_K.col1.y = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2;
+ this.m_K.col2.x = this.m_K.col1.y;
+ this.m_K.col2.y = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2;
+ }
+ if (this.m_enableLimit) {
+ var jointTransition = this.m_axis.x * dX + this.m_axis.y * dY;
+ if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) {
+ this.m_limitState = b2Joint.e_equalLimits;
+ }
+ else if (jointTransition <= this.m_lowerTranslation) {
+ if (this.m_limitState != b2Joint.e_atLowerLimit) {
+ this.m_limitState = b2Joint.e_atLowerLimit;
+ this.m_impulse.y = 0.0;
+ }
+ }
+ else if (jointTransition >= this.m_upperTranslation) {
+ if (this.m_limitState != b2Joint.e_atUpperLimit) {
+ this.m_limitState = b2Joint.e_atUpperLimit;
+ this.m_impulse.y = 0.0;
+ }
+ }
+ else {
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ this.m_impulse.y = 0.0;
+ }
+ }
+ else {
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ }
+ if (this.m_enableMotor == false) {
+ this.m_motorImpulse = 0.0;
+ }
+ if (step.warmStarting) {
+ this.m_impulse.x *= step.dtRatio;
+ this.m_impulse.y *= step.dtRatio;
+ this.m_motorImpulse *= step.dtRatio;
+ var PX = this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.x;
+ var PY = this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.y;
+ var L1 = this.m_impulse.x * this.m_s1 + (this.m_motorImpulse + this.m_impulse.y) * this.m_a1;
+ var L2 = this.m_impulse.x * this.m_s2 + (this.m_motorImpulse + this.m_impulse.y) * this.m_a2;
+ bA.m_linearVelocity.x -= this.m_invMassA * PX;
+ bA.m_linearVelocity.y -= this.m_invMassA * PY;
+ bA.m_angularVelocity -= this.m_invIA * L1;
+ bB.m_linearVelocity.x += this.m_invMassB * PX;
+ bB.m_linearVelocity.y += this.m_invMassB * PY;
+ bB.m_angularVelocity += this.m_invIB * L2;
+ }
+ else {
+ this.m_impulse.SetZero();
+ this.m_motorImpulse = 0.0;
+ }
+ }
+ b2LineJoint.prototype.SolveVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var v1 = bA.m_linearVelocity;
+ var w1 = bA.m_angularVelocity;
+ var v2 = bB.m_linearVelocity;
+ var w2 = bB.m_angularVelocity;
+ var PX = 0;
+ var PY = 0;
+ var L1 = 0;
+ var L2 = 0;
+ if (this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) {
+ var Cdot = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1;
+ var impulse = this.m_motorMass * (this.m_motorSpeed - Cdot);
+ var oldImpulse = this.m_motorImpulse;
+ var maxImpulse = step.dt * this.m_maxMotorForce;
+ this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse);
+ impulse = this.m_motorImpulse - oldImpulse;
+ PX = impulse * this.m_axis.x;
+ PY = impulse * this.m_axis.y;
+ L1 = impulse * this.m_a1;
+ L2 = impulse * this.m_a2;
+ v1.x -= this.m_invMassA * PX;
+ v1.y -= this.m_invMassA * PY;
+ w1 -= this.m_invIA * L1;
+ v2.x += this.m_invMassB * PX;
+ v2.y += this.m_invMassB * PY;
+ w2 += this.m_invIB * L2;
+ }
+ var Cdot1 = this.m_perp.x * (v2.x - v1.x) + this.m_perp.y * (v2.y - v1.y) + this.m_s2 * w2 - this.m_s1 * w1;
+ if (this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) {
+ var Cdot2 = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1;
+ var f1 = this.m_impulse.Copy();
+ var df = this.m_K.Solve(new b2Vec2(), (-Cdot1), (-Cdot2));
+ this.m_impulse.Add(df);
+ if (this.m_limitState == b2Joint.e_atLowerLimit) {
+ this.m_impulse.y = b2Math.Max(this.m_impulse.y, 0.0);
+ }
+ else if (this.m_limitState == b2Joint.e_atUpperLimit) {
+ this.m_impulse.y = b2Math.Min(this.m_impulse.y, 0.0);
+ }
+ var b = (-Cdot1) - (this.m_impulse.y - f1.y) * this.m_K.col2.x;
+ var f2r = 0;
+ if (this.m_K.col1.x != 0.0) {
+ f2r = b / this.m_K.col1.x + f1.x;
+ }
+ else {
+ f2r = f1.x;
+ }
+ this.m_impulse.x = f2r;
+ df.x = this.m_impulse.x - f1.x;
+ df.y = this.m_impulse.y - f1.y;
+ PX = df.x * this.m_perp.x + df.y * this.m_axis.x;
+ PY = df.x * this.m_perp.y + df.y * this.m_axis.y;
+ L1 = df.x * this.m_s1 + df.y * this.m_a1;
+ L2 = df.x * this.m_s2 + df.y * this.m_a2;
+ v1.x -= this.m_invMassA * PX;
+ v1.y -= this.m_invMassA * PY;
+ w1 -= this.m_invIA * L1;
+ v2.x += this.m_invMassB * PX;
+ v2.y += this.m_invMassB * PY;
+ w2 += this.m_invIB * L2;
+ }
+ else {
+ var df2 = 0;
+ if (this.m_K.col1.x != 0.0) {
+ df2 = ((-Cdot1)) / this.m_K.col1.x;
+ }
+ else {
+ df2 = 0.0;
+ }
+ this.m_impulse.x += df2;
+ PX = df2 * this.m_perp.x;
+ PY = df2 * this.m_perp.y;
+ L1 = df2 * this.m_s1;
+ L2 = df2 * this.m_s2;
+ v1.x -= this.m_invMassA * PX;
+ v1.y -= this.m_invMassA * PY;
+ w1 -= this.m_invIA * L1;
+ v2.x += this.m_invMassB * PX;
+ v2.y += this.m_invMassB * PY;
+ w2 += this.m_invIB * L2;
+ }
+ bA.m_linearVelocity.SetV(v1);
+ bA.m_angularVelocity = w1;
+ bB.m_linearVelocity.SetV(v2);
+ bB.m_angularVelocity = w2;
+ }
+ b2LineJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var limitC = 0;
+ var oldLimitImpulse = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var c1 = bA.m_sweep.c;
+ var a1 = bA.m_sweep.a;
+ var c2 = bB.m_sweep.c;
+ var a2 = bB.m_sweep.a;
+ var tMat;
+ var tX = 0;
+ var m1 = 0;
+ var m2 = 0;
+ var i1 = 0;
+ var i2 = 0;
+ var linearError = 0.0;
+ var angularError = 0.0;
+ var active = false;
+ var C2 = 0.0;
+ var R1 = b2Mat22.FromAngle(a1);
+ var R2 = b2Mat22.FromAngle(a2);
+ tMat = R1;
+ var r1X = this.m_localAnchor1.x - this.m_localCenterA.x;
+ var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = R2;
+ var r2X = this.m_localAnchor2.x - this.m_localCenterB.x;
+ var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var dX = c2.x + r2X - c1.x - r1X;
+ var dY = c2.y + r2Y - c1.y - r1Y;
+ if (this.m_enableLimit) {
+ this.m_axis = b2Math.MulMV(R1, this.m_localXAxis1);
+ this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x;
+ this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x;
+ var translation = this.m_axis.x * dX + this.m_axis.y * dY;
+ if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) {
+ C2 = b2Math.Clamp(translation, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection);
+ linearError = b2Math.Abs(translation);
+ active = true;
+ }
+ else if (translation <= this.m_lowerTranslation) {
+ C2 = b2Math.Clamp(translation - this.m_lowerTranslation + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0);
+ linearError = this.m_lowerTranslation - translation;
+ active = true;
+ }
+ else if (translation >= this.m_upperTranslation) {
+ C2 = b2Math.Clamp(translation - this.m_upperTranslation + b2Settings.b2_linearSlop, 0.0, b2Settings.b2_maxLinearCorrection);
+ linearError = translation - this.m_upperTranslation;
+ active = true;
+ }
+ }
+ this.m_perp = b2Math.MulMV(R1, this.m_localYAxis1);
+ this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x;
+ this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x;
+ var impulse = new b2Vec2();
+ var C1 = this.m_perp.x * dX + this.m_perp.y * dY;
+ linearError = b2Math.Max(linearError, b2Math.Abs(C1));
+ angularError = 0.0;
+ if (active) {
+ m1 = this.m_invMassA;
+ m2 = this.m_invMassB;
+ i1 = this.m_invIA;
+ i2 = this.m_invIB;
+ this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2;
+ this.m_K.col1.y = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2;
+ this.m_K.col2.x = this.m_K.col1.y;
+ this.m_K.col2.y = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2;
+ this.m_K.Solve(impulse, (-C1), (-C2));
+ }
+ else {
+ m1 = this.m_invMassA;
+ m2 = this.m_invMassB;
+ i1 = this.m_invIA;
+ i2 = this.m_invIB;
+ var k11 = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2;
+ var impulse1 = 0;
+ if (k11 != 0.0) {
+ impulse1 = ((-C1)) / k11;
+ }
+ else {
+ impulse1 = 0.0;
+ }
+ impulse.x = impulse1;
+ impulse.y = 0.0;
+ }
+ var PX = impulse.x * this.m_perp.x + impulse.y * this.m_axis.x;
+ var PY = impulse.x * this.m_perp.y + impulse.y * this.m_axis.y;
+ var L1 = impulse.x * this.m_s1 + impulse.y * this.m_a1;
+ var L2 = impulse.x * this.m_s2 + impulse.y * this.m_a2;
+ c1.x -= this.m_invMassA * PX;
+ c1.y -= this.m_invMassA * PY;
+ a1 -= this.m_invIA * L1;
+ c2.x += this.m_invMassB * PX;
+ c2.y += this.m_invMassB * PY;
+ a2 += this.m_invIB * L2;
+ bA.m_sweep.a = a1;
+ bB.m_sweep.a = a2;
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ return linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop;
+ }
+ Box2D.inherit(b2LineJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2LineJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2LineJointDef.b2LineJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.localAnchorA = new b2Vec2();
+ this.localAnchorB = new b2Vec2();
+ this.localAxisA = new b2Vec2();
+ };
+ b2LineJointDef.prototype.b2LineJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_lineJoint;
+ this.localAxisA.Set(1.0, 0.0);
+ this.enableLimit = false;
+ this.lowerTranslation = 0.0;
+ this.upperTranslation = 0.0;
+ this.enableMotor = false;
+ this.maxMotorForce = 0.0;
+ this.motorSpeed = 0.0;
+ }
+ b2LineJointDef.prototype.Initialize = function (bA, bB, anchor, axis) {
+ this.bodyA = bA;
+ this.bodyB = bB;
+ this.localAnchorA = this.bodyA.GetLocalPoint(anchor);
+ this.localAnchorB = this.bodyB.GetLocalPoint(anchor);
+ this.localAxisA = this.bodyA.GetLocalVector(axis);
+ }
+ Box2D.inherit(b2MouseJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2MouseJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2MouseJoint.b2MouseJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.K = new b2Mat22();
+ this.K1 = new b2Mat22();
+ this.K2 = new b2Mat22();
+ this.m_localAnchor = new b2Vec2();
+ this.m_target = new b2Vec2();
+ this.m_impulse = new b2Vec2();
+ this.m_mass = new b2Mat22();
+ this.m_C = new b2Vec2();
+ };
+ b2MouseJoint.prototype.GetAnchorA = function () {
+ return this.m_target;
+ }
+ b2MouseJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchor);
+ }
+ b2MouseJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y);
+ }
+ b2MouseJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return 0.0;
+ }
+ b2MouseJoint.prototype.GetTarget = function () {
+ return this.m_target;
+ }
+ b2MouseJoint.prototype.SetTarget = function (target) {
+ if (this.m_bodyB.IsAwake() == false) {
+ this.m_bodyB.SetAwake(true);
+ }
+ this.m_target = target;
+ }
+ b2MouseJoint.prototype.GetMaxForce = function () {
+ return this.m_maxForce;
+ }
+ b2MouseJoint.prototype.SetMaxForce = function (maxForce) {
+ if (maxForce === undefined) maxForce = 0;
+ this.m_maxForce = maxForce;
+ }
+ b2MouseJoint.prototype.GetFrequency = function () {
+ return this.m_frequencyHz;
+ }
+ b2MouseJoint.prototype.SetFrequency = function (hz) {
+ if (hz === undefined) hz = 0;
+ this.m_frequencyHz = hz;
+ }
+ b2MouseJoint.prototype.GetDampingRatio = function () {
+ return this.m_dampingRatio;
+ }
+ b2MouseJoint.prototype.SetDampingRatio = function (ratio) {
+ if (ratio === undefined) ratio = 0;
+ this.m_dampingRatio = ratio;
+ }
+ b2MouseJoint.prototype.b2MouseJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ this.m_target.SetV(def.target);
+ var tX = this.m_target.x - this.m_bodyB.m_xf.position.x;
+ var tY = this.m_target.y - this.m_bodyB.m_xf.position.y;
+ var tMat = this.m_bodyB.m_xf.R;
+ this.m_localAnchor.x = (tX * tMat.col1.x + tY * tMat.col1.y);
+ this.m_localAnchor.y = (tX * tMat.col2.x + tY * tMat.col2.y);
+ this.m_maxForce = def.maxForce;
+ this.m_impulse.SetZero();
+ this.m_frequencyHz = def.frequencyHz;
+ this.m_dampingRatio = def.dampingRatio;
+ this.m_beta = 0.0;
+ this.m_gamma = 0.0;
+ }
+ b2MouseJoint.prototype.InitVelocityConstraints = function (step) {
+ var b = this.m_bodyB;
+ var mass = b.GetMass();
+ var omega = 2.0 * Math.PI * this.m_frequencyHz;
+ var d = 2.0 * mass * this.m_dampingRatio * omega;
+ var k = mass * omega * omega;
+ this.m_gamma = step.dt * (d + step.dt * k);
+ this.m_gamma = this.m_gamma != 0 ? 1 / this.m_gamma : 0.0;
+ this.m_beta = step.dt * k * this.m_gamma;
+ var tMat;tMat = b.m_xf.R;
+ var rX = this.m_localAnchor.x - b.m_sweep.localCenter.x;
+ var rY = this.m_localAnchor.y - b.m_sweep.localCenter.y;
+ var tX = (tMat.col1.x * rX + tMat.col2.x * rY);rY = (tMat.col1.y * rX + tMat.col2.y * rY);
+ rX = tX;
+ var invMass = b.m_invMass;
+ var invI = b.m_invI;this.K1.col1.x = invMass;
+ this.K1.col2.x = 0.0;
+ this.K1.col1.y = 0.0;
+ this.K1.col2.y = invMass;
+ this.K2.col1.x = invI * rY * rY;
+ this.K2.col2.x = (-invI * rX * rY);
+ this.K2.col1.y = (-invI * rX * rY);
+ this.K2.col2.y = invI * rX * rX;
+ this.K.SetM(this.K1);
+ this.K.AddM(this.K2);
+ this.K.col1.x += this.m_gamma;
+ this.K.col2.y += this.m_gamma;
+ this.K.GetInverse(this.m_mass);
+ this.m_C.x = b.m_sweep.c.x + rX - this.m_target.x;
+ this.m_C.y = b.m_sweep.c.y + rY - this.m_target.y;
+ b.m_angularVelocity *= 0.98;
+ this.m_impulse.x *= step.dtRatio;
+ this.m_impulse.y *= step.dtRatio;
+ b.m_linearVelocity.x += invMass * this.m_impulse.x;
+ b.m_linearVelocity.y += invMass * this.m_impulse.y;
+ b.m_angularVelocity += invI * (rX * this.m_impulse.y - rY * this.m_impulse.x);
+ }
+ b2MouseJoint.prototype.SolveVelocityConstraints = function (step) {
+ var b = this.m_bodyB;
+ var tMat;
+ var tX = 0;
+ var tY = 0;
+ tMat = b.m_xf.R;
+ var rX = this.m_localAnchor.x - b.m_sweep.localCenter.x;
+ var rY = this.m_localAnchor.y - b.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rX + tMat.col2.x * rY);
+ rY = (tMat.col1.y * rX + tMat.col2.y * rY);
+ rX = tX;
+ var CdotX = b.m_linearVelocity.x + ((-b.m_angularVelocity * rY));
+ var CdotY = b.m_linearVelocity.y + (b.m_angularVelocity * rX);
+ tMat = this.m_mass;
+ tX = CdotX + this.m_beta * this.m_C.x + this.m_gamma * this.m_impulse.x;
+ tY = CdotY + this.m_beta * this.m_C.y + this.m_gamma * this.m_impulse.y;
+ var impulseX = (-(tMat.col1.x * tX + tMat.col2.x * tY));
+ var impulseY = (-(tMat.col1.y * tX + tMat.col2.y * tY));
+ var oldImpulseX = this.m_impulse.x;
+ var oldImpulseY = this.m_impulse.y;
+ this.m_impulse.x += impulseX;
+ this.m_impulse.y += impulseY;
+ var maxImpulse = step.dt * this.m_maxForce;
+ if (this.m_impulse.LengthSquared() > maxImpulse * maxImpulse) {
+ this.m_impulse.Multiply(maxImpulse / this.m_impulse.Length());
+ }
+ impulseX = this.m_impulse.x - oldImpulseX;
+ impulseY = this.m_impulse.y - oldImpulseY;
+ b.m_linearVelocity.x += b.m_invMass * impulseX;
+ b.m_linearVelocity.y += b.m_invMass * impulseY;
+ b.m_angularVelocity += b.m_invI * (rX * impulseY - rY * impulseX);
+ }
+ b2MouseJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ return true;
+ }
+ Box2D.inherit(b2MouseJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2MouseJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2MouseJointDef.b2MouseJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.target = new b2Vec2();
+ };
+ b2MouseJointDef.prototype.b2MouseJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_mouseJoint;
+ this.maxForce = 0.0;
+ this.frequencyHz = 5.0;
+ this.dampingRatio = 0.7;
+ }
+ Box2D.inherit(b2PrismaticJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2PrismaticJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2PrismaticJoint.b2PrismaticJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.m_localAnchor1 = new b2Vec2();
+ this.m_localAnchor2 = new b2Vec2();
+ this.m_localXAxis1 = new b2Vec2();
+ this.m_localYAxis1 = new b2Vec2();
+ this.m_axis = new b2Vec2();
+ this.m_perp = new b2Vec2();
+ this.m_K = new b2Mat33();
+ this.m_impulse = new b2Vec3();
+ };
+ b2PrismaticJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchor1);
+ }
+ b2PrismaticJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchor2);
+ }
+ b2PrismaticJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.x), inv_dt * (this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.y));
+ }
+ b2PrismaticJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return inv_dt * this.m_impulse.y;
+ }
+ b2PrismaticJoint.prototype.GetJointTranslation = function () {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ var p1 = bA.GetWorldPoint(this.m_localAnchor1);
+ var p2 = bB.GetWorldPoint(this.m_localAnchor2);
+ var dX = p2.x - p1.x;
+ var dY = p2.y - p1.y;
+ var axis = bA.GetWorldVector(this.m_localXAxis1);
+ var translation = axis.x * dX + axis.y * dY;
+ return translation;
+ }
+ b2PrismaticJoint.prototype.GetJointSpeed = function () {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var p1X = bA.m_sweep.c.x + r1X;
+ var p1Y = bA.m_sweep.c.y + r1Y;
+ var p2X = bB.m_sweep.c.x + r2X;
+ var p2Y = bB.m_sweep.c.y + r2Y;
+ var dX = p2X - p1X;
+ var dY = p2Y - p1Y;
+ var axis = bA.GetWorldVector(this.m_localXAxis1);
+ var v1 = bA.m_linearVelocity;
+ var v2 = bB.m_linearVelocity;
+ var w1 = bA.m_angularVelocity;
+ var w2 = bB.m_angularVelocity;
+ var speed = (dX * ((-w1 * axis.y)) + dY * (w1 * axis.x)) + (axis.x * (((v2.x + ((-w2 * r2Y))) - v1.x) - ((-w1 * r1Y))) + axis.y * (((v2.y + (w2 * r2X)) - v1.y) - (w1 * r1X)));
+ return speed;
+ }
+ b2PrismaticJoint.prototype.IsLimitEnabled = function () {
+ return this.m_enableLimit;
+ }
+ b2PrismaticJoint.prototype.EnableLimit = function (flag) {
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_enableLimit = flag;
+ }
+ b2PrismaticJoint.prototype.GetLowerLimit = function () {
+ return this.m_lowerTranslation;
+ }
+ b2PrismaticJoint.prototype.GetUpperLimit = function () {
+ return this.m_upperTranslation;
+ }
+ b2PrismaticJoint.prototype.SetLimits = function (lower, upper) {
+ if (lower === undefined) lower = 0;
+ if (upper === undefined) upper = 0;
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_lowerTranslation = lower;
+ this.m_upperTranslation = upper;
+ }
+ b2PrismaticJoint.prototype.IsMotorEnabled = function () {
+ return this.m_enableMotor;
+ }
+ b2PrismaticJoint.prototype.EnableMotor = function (flag) {
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_enableMotor = flag;
+ }
+ b2PrismaticJoint.prototype.SetMotorSpeed = function (speed) {
+ if (speed === undefined) speed = 0;
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_motorSpeed = speed;
+ }
+ b2PrismaticJoint.prototype.GetMotorSpeed = function () {
+ return this.m_motorSpeed;
+ }
+ b2PrismaticJoint.prototype.SetMaxMotorForce = function (force) {
+ if (force === undefined) force = 0;
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_maxMotorForce = force;
+ }
+ b2PrismaticJoint.prototype.GetMotorForce = function () {
+ return this.m_motorImpulse;
+ }
+ b2PrismaticJoint.prototype.b2PrismaticJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ var tMat;
+ var tX = 0;
+ var tY = 0;
+ this.m_localAnchor1.SetV(def.localAnchorA);
+ this.m_localAnchor2.SetV(def.localAnchorB);
+ this.m_localXAxis1.SetV(def.localAxisA);
+ this.m_localYAxis1.x = (-this.m_localXAxis1.y);
+ this.m_localYAxis1.y = this.m_localXAxis1.x;
+ this.m_refAngle = def.referenceAngle;
+ this.m_impulse.SetZero();
+ this.m_motorMass = 0.0;
+ this.m_motorImpulse = 0.0;
+ this.m_lowerTranslation = def.lowerTranslation;
+ this.m_upperTranslation = def.upperTranslation;
+ this.m_maxMotorForce = def.maxMotorForce;
+ this.m_motorSpeed = def.motorSpeed;
+ this.m_enableLimit = def.enableLimit;
+ this.m_enableMotor = def.enableMotor;
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ this.m_axis.SetZero();
+ this.m_perp.SetZero();
+ }
+ b2PrismaticJoint.prototype.InitVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ var tX = 0;
+ this.m_localCenterA.SetV(bA.GetLocalCenter());
+ this.m_localCenterB.SetV(bB.GetLocalCenter());
+ var xf1 = bA.GetTransform();
+ var xf2 = bB.GetTransform();
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - this.m_localCenterA.x;
+ var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - this.m_localCenterB.x;
+ var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X;
+ var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y;
+ this.m_invMassA = bA.m_invMass;
+ this.m_invMassB = bB.m_invMass;
+ this.m_invIA = bA.m_invI;
+ this.m_invIB = bB.m_invI; {
+ this.m_axis.SetV(b2Math.MulMV(xf1.R, this.m_localXAxis1));
+ this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x;
+ this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x;
+ this.m_motorMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_a1 * this.m_a1 + this.m_invIB * this.m_a2 * this.m_a2;
+ if (this.m_motorMass > Number.MIN_VALUE) this.m_motorMass = 1.0 / this.m_motorMass;
+ } {
+ this.m_perp.SetV(b2Math.MulMV(xf1.R, this.m_localYAxis1));
+ this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x;
+ this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x;
+ var m1 = this.m_invMassA;
+ var m2 = this.m_invMassB;
+ var i1 = this.m_invIA;
+ var i2 = this.m_invIB;
+ this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2;
+ this.m_K.col1.y = i1 * this.m_s1 + i2 * this.m_s2;
+ this.m_K.col1.z = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2;
+ this.m_K.col2.x = this.m_K.col1.y;
+ this.m_K.col2.y = i1 + i2;
+ this.m_K.col2.z = i1 * this.m_a1 + i2 * this.m_a2;
+ this.m_K.col3.x = this.m_K.col1.z;
+ this.m_K.col3.y = this.m_K.col2.z;
+ this.m_K.col3.z = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2;
+ }
+ if (this.m_enableLimit) {
+ var jointTransition = this.m_axis.x * dX + this.m_axis.y * dY;
+ if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) {
+ this.m_limitState = b2Joint.e_equalLimits;
+ }
+ else if (jointTransition <= this.m_lowerTranslation) {
+ if (this.m_limitState != b2Joint.e_atLowerLimit) {
+ this.m_limitState = b2Joint.e_atLowerLimit;
+ this.m_impulse.z = 0.0;
+ }
+ }
+ else if (jointTransition >= this.m_upperTranslation) {
+ if (this.m_limitState != b2Joint.e_atUpperLimit) {
+ this.m_limitState = b2Joint.e_atUpperLimit;
+ this.m_impulse.z = 0.0;
+ }
+ }
+ else {
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ this.m_impulse.z = 0.0;
+ }
+ }
+ else {
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ }
+ if (this.m_enableMotor == false) {
+ this.m_motorImpulse = 0.0;
+ }
+ if (step.warmStarting) {
+ this.m_impulse.x *= step.dtRatio;
+ this.m_impulse.y *= step.dtRatio;
+ this.m_motorImpulse *= step.dtRatio;
+ var PX = this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.x;
+ var PY = this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.y;
+ var L1 = this.m_impulse.x * this.m_s1 + this.m_impulse.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_a1;
+ var L2 = this.m_impulse.x * this.m_s2 + this.m_impulse.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_a2;
+ bA.m_linearVelocity.x -= this.m_invMassA * PX;
+ bA.m_linearVelocity.y -= this.m_invMassA * PY;
+ bA.m_angularVelocity -= this.m_invIA * L1;
+ bB.m_linearVelocity.x += this.m_invMassB * PX;
+ bB.m_linearVelocity.y += this.m_invMassB * PY;
+ bB.m_angularVelocity += this.m_invIB * L2;
+ }
+ else {
+ this.m_impulse.SetZero();
+ this.m_motorImpulse = 0.0;
+ }
+ }
+ b2PrismaticJoint.prototype.SolveVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var v1 = bA.m_linearVelocity;
+ var w1 = bA.m_angularVelocity;
+ var v2 = bB.m_linearVelocity;
+ var w2 = bB.m_angularVelocity;
+ var PX = 0;
+ var PY = 0;
+ var L1 = 0;
+ var L2 = 0;
+ if (this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) {
+ var Cdot = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1;
+ var impulse = this.m_motorMass * (this.m_motorSpeed - Cdot);
+ var oldImpulse = this.m_motorImpulse;
+ var maxImpulse = step.dt * this.m_maxMotorForce;
+ this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse);
+ impulse = this.m_motorImpulse - oldImpulse;
+ PX = impulse * this.m_axis.x;
+ PY = impulse * this.m_axis.y;
+ L1 = impulse * this.m_a1;
+ L2 = impulse * this.m_a2;
+ v1.x -= this.m_invMassA * PX;
+ v1.y -= this.m_invMassA * PY;
+ w1 -= this.m_invIA * L1;
+ v2.x += this.m_invMassB * PX;
+ v2.y += this.m_invMassB * PY;
+ w2 += this.m_invIB * L2;
+ }
+ var Cdot1X = this.m_perp.x * (v2.x - v1.x) + this.m_perp.y * (v2.y - v1.y) + this.m_s2 * w2 - this.m_s1 * w1;
+ var Cdot1Y = w2 - w1;
+ if (this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) {
+ var Cdot2 = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1;
+ var f1 = this.m_impulse.Copy();
+ var df = this.m_K.Solve33(new b2Vec3(), (-Cdot1X), (-Cdot1Y), (-Cdot2));
+ this.m_impulse.Add(df);
+ if (this.m_limitState == b2Joint.e_atLowerLimit) {
+ this.m_impulse.z = b2Math.Max(this.m_impulse.z, 0.0);
+ }
+ else if (this.m_limitState == b2Joint.e_atUpperLimit) {
+ this.m_impulse.z = b2Math.Min(this.m_impulse.z, 0.0);
+ }
+ var bX = (-Cdot1X) - (this.m_impulse.z - f1.z) * this.m_K.col3.x;
+ var bY = (-Cdot1Y) - (this.m_impulse.z - f1.z) * this.m_K.col3.y;
+ var f2r = this.m_K.Solve22(new b2Vec2(), bX, bY);
+ f2r.x += f1.x;
+ f2r.y += f1.y;
+ this.m_impulse.x = f2r.x;
+ this.m_impulse.y = f2r.y;
+ df.x = this.m_impulse.x - f1.x;
+ df.y = this.m_impulse.y - f1.y;
+ df.z = this.m_impulse.z - f1.z;
+ PX = df.x * this.m_perp.x + df.z * this.m_axis.x;
+ PY = df.x * this.m_perp.y + df.z * this.m_axis.y;
+ L1 = df.x * this.m_s1 + df.y + df.z * this.m_a1;
+ L2 = df.x * this.m_s2 + df.y + df.z * this.m_a2;
+ v1.x -= this.m_invMassA * PX;
+ v1.y -= this.m_invMassA * PY;
+ w1 -= this.m_invIA * L1;
+ v2.x += this.m_invMassB * PX;
+ v2.y += this.m_invMassB * PY;
+ w2 += this.m_invIB * L2;
+ }
+ else {
+ var df2 = this.m_K.Solve22(new b2Vec2(), (-Cdot1X), (-Cdot1Y));
+ this.m_impulse.x += df2.x;
+ this.m_impulse.y += df2.y;
+ PX = df2.x * this.m_perp.x;
+ PY = df2.x * this.m_perp.y;
+ L1 = df2.x * this.m_s1 + df2.y;
+ L2 = df2.x * this.m_s2 + df2.y;
+ v1.x -= this.m_invMassA * PX;
+ v1.y -= this.m_invMassA * PY;
+ w1 -= this.m_invIA * L1;
+ v2.x += this.m_invMassB * PX;
+ v2.y += this.m_invMassB * PY;
+ w2 += this.m_invIB * L2;
+ }
+ bA.m_linearVelocity.SetV(v1);
+ bA.m_angularVelocity = w1;
+ bB.m_linearVelocity.SetV(v2);
+ bB.m_angularVelocity = w2;
+ }
+ b2PrismaticJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var limitC = 0;
+ var oldLimitImpulse = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var c1 = bA.m_sweep.c;
+ var a1 = bA.m_sweep.a;
+ var c2 = bB.m_sweep.c;
+ var a2 = bB.m_sweep.a;
+ var tMat;
+ var tX = 0;
+ var m1 = 0;
+ var m2 = 0;
+ var i1 = 0;
+ var i2 = 0;
+ var linearError = 0.0;
+ var angularError = 0.0;
+ var active = false;
+ var C2 = 0.0;
+ var R1 = b2Mat22.FromAngle(a1);
+ var R2 = b2Mat22.FromAngle(a2);
+ tMat = R1;
+ var r1X = this.m_localAnchor1.x - this.m_localCenterA.x;
+ var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = R2;
+ var r2X = this.m_localAnchor2.x - this.m_localCenterB.x;
+ var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var dX = c2.x + r2X - c1.x - r1X;
+ var dY = c2.y + r2Y - c1.y - r1Y;
+ if (this.m_enableLimit) {
+ this.m_axis = b2Math.MulMV(R1, this.m_localXAxis1);
+ this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x;
+ this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x;
+ var translation = this.m_axis.x * dX + this.m_axis.y * dY;
+ if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) {
+ C2 = b2Math.Clamp(translation, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection);
+ linearError = b2Math.Abs(translation);
+ active = true;
+ }
+ else if (translation <= this.m_lowerTranslation) {
+ C2 = b2Math.Clamp(translation - this.m_lowerTranslation + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0);
+ linearError = this.m_lowerTranslation - translation;
+ active = true;
+ }
+ else if (translation >= this.m_upperTranslation) {
+ C2 = b2Math.Clamp(translation - this.m_upperTranslation + b2Settings.b2_linearSlop, 0.0, b2Settings.b2_maxLinearCorrection);
+ linearError = translation - this.m_upperTranslation;
+ active = true;
+ }
+ }
+ this.m_perp = b2Math.MulMV(R1, this.m_localYAxis1);
+ this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x;
+ this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x;
+ var impulse = new b2Vec3();
+ var C1X = this.m_perp.x * dX + this.m_perp.y * dY;
+ var C1Y = a2 - a1 - this.m_refAngle;
+ linearError = b2Math.Max(linearError, b2Math.Abs(C1X));
+ angularError = b2Math.Abs(C1Y);
+ if (active) {
+ m1 = this.m_invMassA;
+ m2 = this.m_invMassB;
+ i1 = this.m_invIA;
+ i2 = this.m_invIB;
+ this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2;
+ this.m_K.col1.y = i1 * this.m_s1 + i2 * this.m_s2;
+ this.m_K.col1.z = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2;
+ this.m_K.col2.x = this.m_K.col1.y;
+ this.m_K.col2.y = i1 + i2;
+ this.m_K.col2.z = i1 * this.m_a1 + i2 * this.m_a2;
+ this.m_K.col3.x = this.m_K.col1.z;
+ this.m_K.col3.y = this.m_K.col2.z;
+ this.m_K.col3.z = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2;
+ this.m_K.Solve33(impulse, (-C1X), (-C1Y), (-C2));
+ }
+ else {
+ m1 = this.m_invMassA;
+ m2 = this.m_invMassB;
+ i1 = this.m_invIA;
+ i2 = this.m_invIB;
+ var k11 = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2;
+ var k12 = i1 * this.m_s1 + i2 * this.m_s2;
+ var k22 = i1 + i2;
+ this.m_K.col1.Set(k11, k12, 0.0);
+ this.m_K.col2.Set(k12, k22, 0.0);
+ var impulse1 = this.m_K.Solve22(new b2Vec2(), (-C1X), (-C1Y));
+ impulse.x = impulse1.x;
+ impulse.y = impulse1.y;
+ impulse.z = 0.0;
+ }
+ var PX = impulse.x * this.m_perp.x + impulse.z * this.m_axis.x;
+ var PY = impulse.x * this.m_perp.y + impulse.z * this.m_axis.y;
+ var L1 = impulse.x * this.m_s1 + impulse.y + impulse.z * this.m_a1;
+ var L2 = impulse.x * this.m_s2 + impulse.y + impulse.z * this.m_a2;
+ c1.x -= this.m_invMassA * PX;
+ c1.y -= this.m_invMassA * PY;
+ a1 -= this.m_invIA * L1;
+ c2.x += this.m_invMassB * PX;
+ c2.y += this.m_invMassB * PY;
+ a2 += this.m_invIB * L2;
+ bA.m_sweep.a = a1;
+ bB.m_sweep.a = a2;
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ return linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop;
+ }
+ Box2D.inherit(b2PrismaticJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2PrismaticJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2PrismaticJointDef.b2PrismaticJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.localAnchorA = new b2Vec2();
+ this.localAnchorB = new b2Vec2();
+ this.localAxisA = new b2Vec2();
+ };
+ b2PrismaticJointDef.prototype.b2PrismaticJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_prismaticJoint;
+ this.localAxisA.Set(1.0, 0.0);
+ this.referenceAngle = 0.0;
+ this.enableLimit = false;
+ this.lowerTranslation = 0.0;
+ this.upperTranslation = 0.0;
+ this.enableMotor = false;
+ this.maxMotorForce = 0.0;
+ this.motorSpeed = 0.0;
+ }
+ b2PrismaticJointDef.prototype.Initialize = function (bA, bB, anchor, axis) {
+ this.bodyA = bA;
+ this.bodyB = bB;
+ this.localAnchorA = this.bodyA.GetLocalPoint(anchor);
+ this.localAnchorB = this.bodyB.GetLocalPoint(anchor);
+ this.localAxisA = this.bodyA.GetLocalVector(axis);
+ this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle();
+ }
+ Box2D.inherit(b2PulleyJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2PulleyJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2PulleyJoint.b2PulleyJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.m_groundAnchor1 = new b2Vec2();
+ this.m_groundAnchor2 = new b2Vec2();
+ this.m_localAnchor1 = new b2Vec2();
+ this.m_localAnchor2 = new b2Vec2();
+ this.m_u1 = new b2Vec2();
+ this.m_u2 = new b2Vec2();
+ };
+ b2PulleyJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchor1);
+ }
+ b2PulleyJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchor2);
+ }
+ b2PulleyJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * this.m_impulse * this.m_u2.x, inv_dt * this.m_impulse * this.m_u2.y);
+ }
+ b2PulleyJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return 0.0;
+ }
+ b2PulleyJoint.prototype.GetGroundAnchorA = function () {
+ var a = this.m_ground.m_xf.position.Copy();
+ a.Add(this.m_groundAnchor1);
+ return a;
+ }
+ b2PulleyJoint.prototype.GetGroundAnchorB = function () {
+ var a = this.m_ground.m_xf.position.Copy();
+ a.Add(this.m_groundAnchor2);
+ return a;
+ }
+ b2PulleyJoint.prototype.GetLength1 = function () {
+ var p = this.m_bodyA.GetWorldPoint(this.m_localAnchor1);
+ var sX = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x;
+ var sY = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y;
+ var dX = p.x - sX;
+ var dY = p.y - sY;
+ return Math.sqrt(dX * dX + dY * dY);
+ }
+ b2PulleyJoint.prototype.GetLength2 = function () {
+ var p = this.m_bodyB.GetWorldPoint(this.m_localAnchor2);
+ var sX = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x;
+ var sY = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y;
+ var dX = p.x - sX;
+ var dY = p.y - sY;
+ return Math.sqrt(dX * dX + dY * dY);
+ }
+ b2PulleyJoint.prototype.GetRatio = function () {
+ return this.m_ratio;
+ }
+ b2PulleyJoint.prototype.b2PulleyJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ var tMat;
+ var tX = 0;
+ var tY = 0;
+ this.m_ground = this.m_bodyA.m_world.m_groundBody;
+ this.m_groundAnchor1.x = def.groundAnchorA.x - this.m_ground.m_xf.position.x;
+ this.m_groundAnchor1.y = def.groundAnchorA.y - this.m_ground.m_xf.position.y;
+ this.m_groundAnchor2.x = def.groundAnchorB.x - this.m_ground.m_xf.position.x;
+ this.m_groundAnchor2.y = def.groundAnchorB.y - this.m_ground.m_xf.position.y;
+ this.m_localAnchor1.SetV(def.localAnchorA);
+ this.m_localAnchor2.SetV(def.localAnchorB);
+ this.m_ratio = def.ratio;
+ this.m_constant = def.lengthA + this.m_ratio * def.lengthB;
+ this.m_maxLength1 = b2Math.Min(def.maxLengthA, this.m_constant - this.m_ratio * b2PulleyJoint.b2_minPulleyLength);
+ this.m_maxLength2 = b2Math.Min(def.maxLengthB, (this.m_constant - b2PulleyJoint.b2_minPulleyLength) / this.m_ratio);
+ this.m_impulse = 0.0;
+ this.m_limitImpulse1 = 0.0;
+ this.m_limitImpulse2 = 0.0;
+ }
+ b2PulleyJoint.prototype.InitVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var p1X = bA.m_sweep.c.x + r1X;
+ var p1Y = bA.m_sweep.c.y + r1Y;
+ var p2X = bB.m_sweep.c.x + r2X;
+ var p2Y = bB.m_sweep.c.y + r2Y;
+ var s1X = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x;
+ var s1Y = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y;
+ var s2X = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x;
+ var s2Y = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y;
+ this.m_u1.Set(p1X - s1X, p1Y - s1Y);
+ this.m_u2.Set(p2X - s2X, p2Y - s2Y);
+ var length1 = this.m_u1.Length();
+ var length2 = this.m_u2.Length();
+ if (length1 > b2Settings.b2_linearSlop) {
+ this.m_u1.Multiply(1.0 / length1);
+ }
+ else {
+ this.m_u1.SetZero();
+ }
+ if (length2 > b2Settings.b2_linearSlop) {
+ this.m_u2.Multiply(1.0 / length2);
+ }
+ else {
+ this.m_u2.SetZero();
+ }
+ var C = this.m_constant - length1 - this.m_ratio * length2;
+ if (C > 0.0) {
+ this.m_state = b2Joint.e_inactiveLimit;
+ this.m_impulse = 0.0;
+ }
+ else {
+ this.m_state = b2Joint.e_atUpperLimit;
+ }
+ if (length1 < this.m_maxLength1) {
+ this.m_limitState1 = b2Joint.e_inactiveLimit;
+ this.m_limitImpulse1 = 0.0;
+ }
+ else {
+ this.m_limitState1 = b2Joint.e_atUpperLimit;
+ }
+ if (length2 < this.m_maxLength2) {
+ this.m_limitState2 = b2Joint.e_inactiveLimit;
+ this.m_limitImpulse2 = 0.0;
+ }
+ else {
+ this.m_limitState2 = b2Joint.e_atUpperLimit;
+ }
+ var cr1u1 = r1X * this.m_u1.y - r1Y * this.m_u1.x;
+ var cr2u2 = r2X * this.m_u2.y - r2Y * this.m_u2.x;
+ this.m_limitMass1 = bA.m_invMass + bA.m_invI * cr1u1 * cr1u1;
+ this.m_limitMass2 = bB.m_invMass + bB.m_invI * cr2u2 * cr2u2;
+ this.m_pulleyMass = this.m_limitMass1 + this.m_ratio * this.m_ratio * this.m_limitMass2;
+ this.m_limitMass1 = 1.0 / this.m_limitMass1;
+ this.m_limitMass2 = 1.0 / this.m_limitMass2;
+ this.m_pulleyMass = 1.0 / this.m_pulleyMass;
+ if (step.warmStarting) {
+ this.m_impulse *= step.dtRatio;
+ this.m_limitImpulse1 *= step.dtRatio;
+ this.m_limitImpulse2 *= step.dtRatio;
+ var P1X = ((-this.m_impulse) - this.m_limitImpulse1) * this.m_u1.x;
+ var P1Y = ((-this.m_impulse) - this.m_limitImpulse1) * this.m_u1.y;
+ var P2X = ((-this.m_ratio * this.m_impulse) - this.m_limitImpulse2) * this.m_u2.x;
+ var P2Y = ((-this.m_ratio * this.m_impulse) - this.m_limitImpulse2) * this.m_u2.y;
+ bA.m_linearVelocity.x += bA.m_invMass * P1X;
+ bA.m_linearVelocity.y += bA.m_invMass * P1Y;
+ bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X);
+ bB.m_linearVelocity.x += bB.m_invMass * P2X;
+ bB.m_linearVelocity.y += bB.m_invMass * P2Y;
+ bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X);
+ }
+ else {
+ this.m_impulse = 0.0;
+ this.m_limitImpulse1 = 0.0;
+ this.m_limitImpulse2 = 0.0;
+ }
+ }
+ b2PulleyJoint.prototype.SolveVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var v1X = 0;
+ var v1Y = 0;
+ var v2X = 0;
+ var v2Y = 0;
+ var P1X = 0;
+ var P1Y = 0;
+ var P2X = 0;
+ var P2Y = 0;
+ var Cdot = 0;
+ var impulse = 0;
+ var oldImpulse = 0;
+ if (this.m_state == b2Joint.e_atUpperLimit) {
+ v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y));
+ v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X);
+ v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y));
+ v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X);
+ Cdot = (-(this.m_u1.x * v1X + this.m_u1.y * v1Y)) - this.m_ratio * (this.m_u2.x * v2X + this.m_u2.y * v2Y);
+ impulse = this.m_pulleyMass * ((-Cdot));
+ oldImpulse = this.m_impulse;
+ this.m_impulse = b2Math.Max(0.0, this.m_impulse + impulse);
+ impulse = this.m_impulse - oldImpulse;
+ P1X = (-impulse * this.m_u1.x);
+ P1Y = (-impulse * this.m_u1.y);
+ P2X = (-this.m_ratio * impulse * this.m_u2.x);
+ P2Y = (-this.m_ratio * impulse * this.m_u2.y);
+ bA.m_linearVelocity.x += bA.m_invMass * P1X;
+ bA.m_linearVelocity.y += bA.m_invMass * P1Y;
+ bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X);
+ bB.m_linearVelocity.x += bB.m_invMass * P2X;
+ bB.m_linearVelocity.y += bB.m_invMass * P2Y;
+ bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X);
+ }
+ if (this.m_limitState1 == b2Joint.e_atUpperLimit) {
+ v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y));
+ v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X);
+ Cdot = (-(this.m_u1.x * v1X + this.m_u1.y * v1Y));
+ impulse = (-this.m_limitMass1 * Cdot);
+ oldImpulse = this.m_limitImpulse1;
+ this.m_limitImpulse1 = b2Math.Max(0.0, this.m_limitImpulse1 + impulse);
+ impulse = this.m_limitImpulse1 - oldImpulse;
+ P1X = (-impulse * this.m_u1.x);
+ P1Y = (-impulse * this.m_u1.y);
+ bA.m_linearVelocity.x += bA.m_invMass * P1X;
+ bA.m_linearVelocity.y += bA.m_invMass * P1Y;
+ bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X);
+ }
+ if (this.m_limitState2 == b2Joint.e_atUpperLimit) {
+ v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y));
+ v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X);
+ Cdot = (-(this.m_u2.x * v2X + this.m_u2.y * v2Y));
+ impulse = (-this.m_limitMass2 * Cdot);
+ oldImpulse = this.m_limitImpulse2;
+ this.m_limitImpulse2 = b2Math.Max(0.0, this.m_limitImpulse2 + impulse);
+ impulse = this.m_limitImpulse2 - oldImpulse;
+ P2X = (-impulse * this.m_u2.x);
+ P2Y = (-impulse * this.m_u2.y);
+ bB.m_linearVelocity.x += bB.m_invMass * P2X;
+ bB.m_linearVelocity.y += bB.m_invMass * P2Y;
+ bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X);
+ }
+ }
+ b2PulleyJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ var s1X = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x;
+ var s1Y = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y;
+ var s2X = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x;
+ var s2Y = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y;
+ var r1X = 0;
+ var r1Y = 0;
+ var r2X = 0;
+ var r2Y = 0;
+ var p1X = 0;
+ var p1Y = 0;
+ var p2X = 0;
+ var p2Y = 0;
+ var length1 = 0;
+ var length2 = 0;
+ var C = 0;
+ var impulse = 0;
+ var oldImpulse = 0;
+ var oldLimitPositionImpulse = 0;
+ var tX = 0;
+ var linearError = 0.0;
+ if (this.m_state == b2Joint.e_atUpperLimit) {
+ tMat = bA.m_xf.R;
+ r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ p1X = bA.m_sweep.c.x + r1X;
+ p1Y = bA.m_sweep.c.y + r1Y;
+ p2X = bB.m_sweep.c.x + r2X;
+ p2Y = bB.m_sweep.c.y + r2Y;
+ this.m_u1.Set(p1X - s1X, p1Y - s1Y);
+ this.m_u2.Set(p2X - s2X, p2Y - s2Y);
+ length1 = this.m_u1.Length();
+ length2 = this.m_u2.Length();
+ if (length1 > b2Settings.b2_linearSlop) {
+ this.m_u1.Multiply(1.0 / length1);
+ }
+ else {
+ this.m_u1.SetZero();
+ }
+ if (length2 > b2Settings.b2_linearSlop) {
+ this.m_u2.Multiply(1.0 / length2);
+ }
+ else {
+ this.m_u2.SetZero();
+ }
+ C = this.m_constant - length1 - this.m_ratio * length2;
+ linearError = b2Math.Max(linearError, (-C));
+ C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0);
+ impulse = (-this.m_pulleyMass * C);
+ p1X = (-impulse * this.m_u1.x);
+ p1Y = (-impulse * this.m_u1.y);
+ p2X = (-this.m_ratio * impulse * this.m_u2.x);
+ p2Y = (-this.m_ratio * impulse * this.m_u2.y);
+ bA.m_sweep.c.x += bA.m_invMass * p1X;
+ bA.m_sweep.c.y += bA.m_invMass * p1Y;
+ bA.m_sweep.a += bA.m_invI * (r1X * p1Y - r1Y * p1X);
+ bB.m_sweep.c.x += bB.m_invMass * p2X;
+ bB.m_sweep.c.y += bB.m_invMass * p2Y;
+ bB.m_sweep.a += bB.m_invI * (r2X * p2Y - r2Y * p2X);
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ }
+ if (this.m_limitState1 == b2Joint.e_atUpperLimit) {
+ tMat = bA.m_xf.R;
+ r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ p1X = bA.m_sweep.c.x + r1X;
+ p1Y = bA.m_sweep.c.y + r1Y;
+ this.m_u1.Set(p1X - s1X, p1Y - s1Y);
+ length1 = this.m_u1.Length();
+ if (length1 > b2Settings.b2_linearSlop) {
+ this.m_u1.x *= 1.0 / length1;
+ this.m_u1.y *= 1.0 / length1;
+ }
+ else {
+ this.m_u1.SetZero();
+ }
+ C = this.m_maxLength1 - length1;
+ linearError = b2Math.Max(linearError, (-C));
+ C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0);
+ impulse = (-this.m_limitMass1 * C);
+ p1X = (-impulse * this.m_u1.x);
+ p1Y = (-impulse * this.m_u1.y);
+ bA.m_sweep.c.x += bA.m_invMass * p1X;
+ bA.m_sweep.c.y += bA.m_invMass * p1Y;
+ bA.m_sweep.a += bA.m_invI * (r1X * p1Y - r1Y * p1X);
+ bA.SynchronizeTransform();
+ }
+ if (this.m_limitState2 == b2Joint.e_atUpperLimit) {
+ tMat = bB.m_xf.R;
+ r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ p2X = bB.m_sweep.c.x + r2X;
+ p2Y = bB.m_sweep.c.y + r2Y;
+ this.m_u2.Set(p2X - s2X, p2Y - s2Y);
+ length2 = this.m_u2.Length();
+ if (length2 > b2Settings.b2_linearSlop) {
+ this.m_u2.x *= 1.0 / length2;
+ this.m_u2.y *= 1.0 / length2;
+ }
+ else {
+ this.m_u2.SetZero();
+ }
+ C = this.m_maxLength2 - length2;
+ linearError = b2Math.Max(linearError, (-C));
+ C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0);
+ impulse = (-this.m_limitMass2 * C);
+ p2X = (-impulse * this.m_u2.x);
+ p2Y = (-impulse * this.m_u2.y);
+ bB.m_sweep.c.x += bB.m_invMass * p2X;
+ bB.m_sweep.c.y += bB.m_invMass * p2Y;
+ bB.m_sweep.a += bB.m_invI * (r2X * p2Y - r2Y * p2X);
+ bB.SynchronizeTransform();
+ }
+ return linearError < b2Settings.b2_linearSlop;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.Joints.b2PulleyJoint.b2_minPulleyLength = 2.0;
+ });
+ Box2D.inherit(b2PulleyJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2PulleyJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2PulleyJointDef.b2PulleyJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.groundAnchorA = new b2Vec2();
+ this.groundAnchorB = new b2Vec2();
+ this.localAnchorA = new b2Vec2();
+ this.localAnchorB = new b2Vec2();
+ };
+ b2PulleyJointDef.prototype.b2PulleyJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_pulleyJoint;
+ this.groundAnchorA.Set((-1.0), 1.0);
+ this.groundAnchorB.Set(1.0, 1.0);
+ this.localAnchorA.Set((-1.0), 0.0);
+ this.localAnchorB.Set(1.0, 0.0);
+ this.lengthA = 0.0;
+ this.maxLengthA = 0.0;
+ this.lengthB = 0.0;
+ this.maxLengthB = 0.0;
+ this.ratio = 1.0;
+ this.collideConnected = true;
+ }
+ b2PulleyJointDef.prototype.Initialize = function (bA, bB, gaA, gaB, anchorA, anchorB, r) {
+ if (r === undefined) r = 0;
+ this.bodyA = bA;
+ this.bodyB = bB;
+ this.groundAnchorA.SetV(gaA);
+ this.groundAnchorB.SetV(gaB);
+ this.localAnchorA = this.bodyA.GetLocalPoint(anchorA);
+ this.localAnchorB = this.bodyB.GetLocalPoint(anchorB);
+ var d1X = anchorA.x - gaA.x;
+ var d1Y = anchorA.y - gaA.y;
+ this.lengthA = Math.sqrt(d1X * d1X + d1Y * d1Y);
+ var d2X = anchorB.x - gaB.x;
+ var d2Y = anchorB.y - gaB.y;
+ this.lengthB = Math.sqrt(d2X * d2X + d2Y * d2Y);
+ this.ratio = r;
+ var C = this.lengthA + this.ratio * this.lengthB;
+ this.maxLengthA = C - this.ratio * b2PulleyJoint.b2_minPulleyLength;
+ this.maxLengthB = (C - b2PulleyJoint.b2_minPulleyLength) / this.ratio;
+ }
+ Box2D.inherit(b2RevoluteJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2RevoluteJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2RevoluteJoint.b2RevoluteJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.K = new b2Mat22();
+ this.K1 = new b2Mat22();
+ this.K2 = new b2Mat22();
+ this.K3 = new b2Mat22();
+ this.impulse3 = new b2Vec3();
+ this.impulse2 = new b2Vec2();
+ this.reduced = new b2Vec2();
+ this.m_localAnchor1 = new b2Vec2();
+ this.m_localAnchor2 = new b2Vec2();
+ this.m_impulse = new b2Vec3();
+ this.m_mass = new b2Mat33();
+ };
+ b2RevoluteJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchor1);
+ }
+ b2RevoluteJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchor2);
+ }
+ b2RevoluteJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y);
+ }
+ b2RevoluteJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return inv_dt * this.m_impulse.z;
+ }
+ b2RevoluteJoint.prototype.GetJointAngle = function () {
+ return this.m_bodyB.m_sweep.a - this.m_bodyA.m_sweep.a - this.m_referenceAngle;
+ }
+ b2RevoluteJoint.prototype.GetJointSpeed = function () {
+ return this.m_bodyB.m_angularVelocity - this.m_bodyA.m_angularVelocity;
+ }
+ b2RevoluteJoint.prototype.IsLimitEnabled = function () {
+ return this.m_enableLimit;
+ }
+ b2RevoluteJoint.prototype.EnableLimit = function (flag) {
+ this.m_enableLimit = flag;
+ }
+ b2RevoluteJoint.prototype.GetLowerLimit = function () {
+ return this.m_lowerAngle;
+ }
+ b2RevoluteJoint.prototype.GetUpperLimit = function () {
+ return this.m_upperAngle;
+ }
+ b2RevoluteJoint.prototype.SetLimits = function (lower, upper) {
+ if (lower === undefined) lower = 0;
+ if (upper === undefined) upper = 0;
+ this.m_lowerAngle = lower;
+ this.m_upperAngle = upper;
+ }
+ b2RevoluteJoint.prototype.IsMotorEnabled = function () {
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ return this.m_enableMotor;
+ }
+ b2RevoluteJoint.prototype.EnableMotor = function (flag) {
+ this.m_enableMotor = flag;
+ }
+ b2RevoluteJoint.prototype.SetMotorSpeed = function (speed) {
+ if (speed === undefined) speed = 0;
+ this.m_bodyA.SetAwake(true);
+ this.m_bodyB.SetAwake(true);
+ this.m_motorSpeed = speed;
+ }
+ b2RevoluteJoint.prototype.GetMotorSpeed = function () {
+ return this.m_motorSpeed;
+ }
+ b2RevoluteJoint.prototype.SetMaxMotorTorque = function (torque) {
+ if (torque === undefined) torque = 0;
+ this.m_maxMotorTorque = torque;
+ }
+ b2RevoluteJoint.prototype.GetMotorTorque = function () {
+ return this.m_maxMotorTorque;
+ }
+ b2RevoluteJoint.prototype.b2RevoluteJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ this.m_localAnchor1.SetV(def.localAnchorA);
+ this.m_localAnchor2.SetV(def.localAnchorB);
+ this.m_referenceAngle = def.referenceAngle;
+ this.m_impulse.SetZero();
+ this.m_motorImpulse = 0.0;
+ this.m_lowerAngle = def.lowerAngle;
+ this.m_upperAngle = def.upperAngle;
+ this.m_maxMotorTorque = def.maxMotorTorque;
+ this.m_motorSpeed = def.motorSpeed;
+ this.m_enableLimit = def.enableLimit;
+ this.m_enableMotor = def.enableMotor;
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ }
+ b2RevoluteJoint.prototype.InitVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ var tX = 0;
+ if (this.m_enableMotor || this.m_enableLimit) {}
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var m1 = bA.m_invMass;
+ var m2 = bB.m_invMass;
+ var i1 = bA.m_invI;
+ var i2 = bB.m_invI;
+ this.m_mass.col1.x = m1 + m2 + r1Y * r1Y * i1 + r2Y * r2Y * i2;
+ this.m_mass.col2.x = (-r1Y * r1X * i1) - r2Y * r2X * i2;
+ this.m_mass.col3.x = (-r1Y * i1) - r2Y * i2;
+ this.m_mass.col1.y = this.m_mass.col2.x;
+ this.m_mass.col2.y = m1 + m2 + r1X * r1X * i1 + r2X * r2X * i2;
+ this.m_mass.col3.y = r1X * i1 + r2X * i2;
+ this.m_mass.col1.z = this.m_mass.col3.x;
+ this.m_mass.col2.z = this.m_mass.col3.y;
+ this.m_mass.col3.z = i1 + i2;
+ this.m_motorMass = 1.0 / (i1 + i2);
+ if (this.m_enableMotor == false) {
+ this.m_motorImpulse = 0.0;
+ }
+ if (this.m_enableLimit) {
+ var jointAngle = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle;
+ if (b2Math.Abs(this.m_upperAngle - this.m_lowerAngle) < 2.0 * b2Settings.b2_angularSlop) {
+ this.m_limitState = b2Joint.e_equalLimits;
+ }
+ else if (jointAngle <= this.m_lowerAngle) {
+ if (this.m_limitState != b2Joint.e_atLowerLimit) {
+ this.m_impulse.z = 0.0;
+ }
+ this.m_limitState = b2Joint.e_atLowerLimit;
+ }
+ else if (jointAngle >= this.m_upperAngle) {
+ if (this.m_limitState != b2Joint.e_atUpperLimit) {
+ this.m_impulse.z = 0.0;
+ }
+ this.m_limitState = b2Joint.e_atUpperLimit;
+ }
+ else {
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ this.m_impulse.z = 0.0;
+ }
+ }
+ else {
+ this.m_limitState = b2Joint.e_inactiveLimit;
+ }
+ if (step.warmStarting) {
+ this.m_impulse.x *= step.dtRatio;
+ this.m_impulse.y *= step.dtRatio;
+ this.m_motorImpulse *= step.dtRatio;
+ var PX = this.m_impulse.x;
+ var PY = this.m_impulse.y;
+ bA.m_linearVelocity.x -= m1 * PX;
+ bA.m_linearVelocity.y -= m1 * PY;
+ bA.m_angularVelocity -= i1 * ((r1X * PY - r1Y * PX) + this.m_motorImpulse + this.m_impulse.z);
+ bB.m_linearVelocity.x += m2 * PX;
+ bB.m_linearVelocity.y += m2 * PY;
+ bB.m_angularVelocity += i2 * ((r2X * PY - r2Y * PX) + this.m_motorImpulse + this.m_impulse.z);
+ }
+ else {
+ this.m_impulse.SetZero();
+ this.m_motorImpulse = 0.0;
+ }
+ }
+ b2RevoluteJoint.prototype.SolveVelocityConstraints = function (step) {
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var tMat;
+ var tX = 0;
+ var newImpulse = 0;
+ var r1X = 0;
+ var r1Y = 0;
+ var r2X = 0;
+ var r2Y = 0;
+ var v1 = bA.m_linearVelocity;
+ var w1 = bA.m_angularVelocity;
+ var v2 = bB.m_linearVelocity;
+ var w2 = bB.m_angularVelocity;
+ var m1 = bA.m_invMass;
+ var m2 = bB.m_invMass;
+ var i1 = bA.m_invI;
+ var i2 = bB.m_invI;
+ if (this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) {
+ var Cdot = w2 - w1 - this.m_motorSpeed;
+ var impulse = this.m_motorMass * ((-Cdot));
+ var oldImpulse = this.m_motorImpulse;
+ var maxImpulse = step.dt * this.m_maxMotorTorque;
+ this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse);
+ impulse = this.m_motorImpulse - oldImpulse;
+ w1 -= i1 * impulse;
+ w2 += i2 * impulse;
+ }
+ if (this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) {
+ tMat = bA.m_xf.R;
+ r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var Cdot1X = v2.x + ((-w2 * r2Y)) - v1.x - ((-w1 * r1Y));
+ var Cdot1Y = v2.y + (w2 * r2X) - v1.y - (w1 * r1X);
+ var Cdot2 = w2 - w1;
+ this.m_mass.Solve33(this.impulse3, (-Cdot1X), (-Cdot1Y), (-Cdot2));
+ if (this.m_limitState == b2Joint.e_equalLimits) {
+ this.m_impulse.Add(this.impulse3);
+ }
+ else if (this.m_limitState == b2Joint.e_atLowerLimit) {
+ newImpulse = this.m_impulse.z + this.impulse3.z;
+ if (newImpulse < 0.0) {
+ this.m_mass.Solve22(this.reduced, (-Cdot1X), (-Cdot1Y));
+ this.impulse3.x = this.reduced.x;
+ this.impulse3.y = this.reduced.y;
+ this.impulse3.z = (-this.m_impulse.z);
+ this.m_impulse.x += this.reduced.x;
+ this.m_impulse.y += this.reduced.y;
+ this.m_impulse.z = 0.0;
+ }
+ }
+ else if (this.m_limitState == b2Joint.e_atUpperLimit) {
+ newImpulse = this.m_impulse.z + this.impulse3.z;
+ if (newImpulse > 0.0) {
+ this.m_mass.Solve22(this.reduced, (-Cdot1X), (-Cdot1Y));
+ this.impulse3.x = this.reduced.x;
+ this.impulse3.y = this.reduced.y;
+ this.impulse3.z = (-this.m_impulse.z);
+ this.m_impulse.x += this.reduced.x;
+ this.m_impulse.y += this.reduced.y;
+ this.m_impulse.z = 0.0;
+ }
+ }
+ v1.x -= m1 * this.impulse3.x;
+ v1.y -= m1 * this.impulse3.y;
+ w1 -= i1 * (r1X * this.impulse3.y - r1Y * this.impulse3.x + this.impulse3.z);
+ v2.x += m2 * this.impulse3.x;
+ v2.y += m2 * this.impulse3.y;
+ w2 += i2 * (r2X * this.impulse3.y - r2Y * this.impulse3.x + this.impulse3.z);
+ }
+ else {
+ tMat = bA.m_xf.R;
+ r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var CdotX = v2.x + ((-w2 * r2Y)) - v1.x - ((-w1 * r1Y));
+ var CdotY = v2.y + (w2 * r2X) - v1.y - (w1 * r1X);
+ this.m_mass.Solve22(this.impulse2, (-CdotX), (-CdotY));
+ this.m_impulse.x += this.impulse2.x;
+ this.m_impulse.y += this.impulse2.y;
+ v1.x -= m1 * this.impulse2.x;
+ v1.y -= m1 * this.impulse2.y;
+ w1 -= i1 * (r1X * this.impulse2.y - r1Y * this.impulse2.x);
+ v2.x += m2 * this.impulse2.x;
+ v2.y += m2 * this.impulse2.y;
+ w2 += i2 * (r2X * this.impulse2.y - r2Y * this.impulse2.x);
+ }
+ bA.m_linearVelocity.SetV(v1);
+ bA.m_angularVelocity = w1;
+ bB.m_linearVelocity.SetV(v2);
+ bB.m_angularVelocity = w2;
+ }
+ b2RevoluteJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var oldLimitImpulse = 0;
+ var C = 0;
+ var tMat;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var angularError = 0.0;
+ var positionError = 0.0;
+ var tX = 0;
+ var impulseX = 0;
+ var impulseY = 0;
+ if (this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) {
+ var angle = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle;
+ var limitImpulse = 0.0;
+ if (this.m_limitState == b2Joint.e_equalLimits) {
+ C = b2Math.Clamp(angle - this.m_lowerAngle, (-b2Settings.b2_maxAngularCorrection), b2Settings.b2_maxAngularCorrection);
+ limitImpulse = (-this.m_motorMass * C);
+ angularError = b2Math.Abs(C);
+ }
+ else if (this.m_limitState == b2Joint.e_atLowerLimit) {
+ C = angle - this.m_lowerAngle;
+ angularError = (-C);
+ C = b2Math.Clamp(C + b2Settings.b2_angularSlop, (-b2Settings.b2_maxAngularCorrection), 0.0);
+ limitImpulse = (-this.m_motorMass * C);
+ }
+ else if (this.m_limitState == b2Joint.e_atUpperLimit) {
+ C = angle - this.m_upperAngle;
+ angularError = C;
+ C = b2Math.Clamp(C - b2Settings.b2_angularSlop, 0.0, b2Settings.b2_maxAngularCorrection);
+ limitImpulse = (-this.m_motorMass * C);
+ }
+ bA.m_sweep.a -= bA.m_invI * limitImpulse;
+ bB.m_sweep.a += bB.m_invI * limitImpulse;
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ } {
+ tMat = bA.m_xf.R;
+ var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x;
+ var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y);
+ r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y);
+ r1X = tX;
+ tMat = bB.m_xf.R;
+ var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x;
+ var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y);
+ r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y);
+ r2X = tX;
+ var CX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X;
+ var CY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y;
+ var CLengthSquared = CX * CX + CY * CY;
+ var CLength = Math.sqrt(CLengthSquared);
+ positionError = CLength;
+ var invMass1 = bA.m_invMass;
+ var invMass2 = bB.m_invMass;
+ var invI1 = bA.m_invI;
+ var invI2 = bB.m_invI;
+ var k_allowedStretch = 10.0 * b2Settings.b2_linearSlop;
+ if (CLengthSquared > k_allowedStretch * k_allowedStretch) {
+ var uX = CX / CLength;
+ var uY = CY / CLength;
+ var k = invMass1 + invMass2;
+ var m = 1.0 / k;
+ impulseX = m * ((-CX));
+ impulseY = m * ((-CY));
+ var k_beta = 0.5;
+ bA.m_sweep.c.x -= k_beta * invMass1 * impulseX;
+ bA.m_sweep.c.y -= k_beta * invMass1 * impulseY;
+ bB.m_sweep.c.x += k_beta * invMass2 * impulseX;
+ bB.m_sweep.c.y += k_beta * invMass2 * impulseY;
+ CX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X;
+ CY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y;
+ }
+ this.K1.col1.x = invMass1 + invMass2;
+ this.K1.col2.x = 0.0;
+ this.K1.col1.y = 0.0;
+ this.K1.col2.y = invMass1 + invMass2;
+ this.K2.col1.x = invI1 * r1Y * r1Y;
+ this.K2.col2.x = (-invI1 * r1X * r1Y);
+ this.K2.col1.y = (-invI1 * r1X * r1Y);
+ this.K2.col2.y = invI1 * r1X * r1X;
+ this.K3.col1.x = invI2 * r2Y * r2Y;
+ this.K3.col2.x = (-invI2 * r2X * r2Y);
+ this.K3.col1.y = (-invI2 * r2X * r2Y);
+ this.K3.col2.y = invI2 * r2X * r2X;
+ this.K.SetM(this.K1);
+ this.K.AddM(this.K2);
+ this.K.AddM(this.K3);
+ this.K.Solve(b2RevoluteJoint.tImpulse, (-CX), (-CY));
+ impulseX = b2RevoluteJoint.tImpulse.x;
+ impulseY = b2RevoluteJoint.tImpulse.y;
+ bA.m_sweep.c.x -= bA.m_invMass * impulseX;
+ bA.m_sweep.c.y -= bA.m_invMass * impulseY;
+ bA.m_sweep.a -= bA.m_invI * (r1X * impulseY - r1Y * impulseX);
+ bB.m_sweep.c.x += bB.m_invMass * impulseX;
+ bB.m_sweep.c.y += bB.m_invMass * impulseY;
+ bB.m_sweep.a += bB.m_invI * (r2X * impulseY - r2Y * impulseX);
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ }
+ return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop;
+ }
+ Box2D.postDefs.push(function () {
+ Box2D.Dynamics.Joints.b2RevoluteJoint.tImpulse = new b2Vec2();
+ });
+ Box2D.inherit(b2RevoluteJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2RevoluteJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2RevoluteJointDef.b2RevoluteJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.localAnchorA = new b2Vec2();
+ this.localAnchorB = new b2Vec2();
+ };
+ b2RevoluteJointDef.prototype.b2RevoluteJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_revoluteJoint;
+ this.localAnchorA.Set(0.0, 0.0);
+ this.localAnchorB.Set(0.0, 0.0);
+ this.referenceAngle = 0.0;
+ this.lowerAngle = 0.0;
+ this.upperAngle = 0.0;
+ this.maxMotorTorque = 0.0;
+ this.motorSpeed = 0.0;
+ this.enableLimit = false;
+ this.enableMotor = false;
+ }
+ b2RevoluteJointDef.prototype.Initialize = function (bA, bB, anchor) {
+ this.bodyA = bA;
+ this.bodyB = bB;
+ this.localAnchorA = this.bodyA.GetLocalPoint(anchor);
+ this.localAnchorB = this.bodyB.GetLocalPoint(anchor);
+ this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle();
+ }
+ Box2D.inherit(b2WeldJoint, Box2D.Dynamics.Joints.b2Joint);
+ b2WeldJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype;
+ b2WeldJoint.b2WeldJoint = function () {
+ Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments);
+ this.m_localAnchorA = new b2Vec2();
+ this.m_localAnchorB = new b2Vec2();
+ this.m_impulse = new b2Vec3();
+ this.m_mass = new b2Mat33();
+ };
+ b2WeldJoint.prototype.GetAnchorA = function () {
+ return this.m_bodyA.GetWorldPoint(this.m_localAnchorA);
+ }
+ b2WeldJoint.prototype.GetAnchorB = function () {
+ return this.m_bodyB.GetWorldPoint(this.m_localAnchorB);
+ }
+ b2WeldJoint.prototype.GetReactionForce = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y);
+ }
+ b2WeldJoint.prototype.GetReactionTorque = function (inv_dt) {
+ if (inv_dt === undefined) inv_dt = 0;
+ return inv_dt * this.m_impulse.z;
+ }
+ b2WeldJoint.prototype.b2WeldJoint = function (def) {
+ this.__super.b2Joint.call(this, def);
+ this.m_localAnchorA.SetV(def.localAnchorA);
+ this.m_localAnchorB.SetV(def.localAnchorB);
+ this.m_referenceAngle = def.referenceAngle;
+ this.m_impulse.SetZero();
+ this.m_mass = new b2Mat33();
+ }
+ b2WeldJoint.prototype.InitVelocityConstraints = function (step) {
+ var tMat;
+ var tX = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ tMat = bA.m_xf.R;
+ var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x;
+ var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rAX + tMat.col2.x * rAY);
+ rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY);
+ rAX = tX;
+ tMat = bB.m_xf.R;
+ var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x;
+ var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rBX + tMat.col2.x * rBY);
+ rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY);
+ rBX = tX;
+ var mA = bA.m_invMass;
+ var mB = bB.m_invMass;
+ var iA = bA.m_invI;
+ var iB = bB.m_invI;
+ this.m_mass.col1.x = mA + mB + rAY * rAY * iA + rBY * rBY * iB;
+ this.m_mass.col2.x = (-rAY * rAX * iA) - rBY * rBX * iB;
+ this.m_mass.col3.x = (-rAY * iA) - rBY * iB;
+ this.m_mass.col1.y = this.m_mass.col2.x;
+ this.m_mass.col2.y = mA + mB + rAX * rAX * iA + rBX * rBX * iB;
+ this.m_mass.col3.y = rAX * iA + rBX * iB;
+ this.m_mass.col1.z = this.m_mass.col3.x;
+ this.m_mass.col2.z = this.m_mass.col3.y;
+ this.m_mass.col3.z = iA + iB;
+ if (step.warmStarting) {
+ this.m_impulse.x *= step.dtRatio;
+ this.m_impulse.y *= step.dtRatio;
+ this.m_impulse.z *= step.dtRatio;
+ bA.m_linearVelocity.x -= mA * this.m_impulse.x;
+ bA.m_linearVelocity.y -= mA * this.m_impulse.y;
+ bA.m_angularVelocity -= iA * (rAX * this.m_impulse.y - rAY * this.m_impulse.x + this.m_impulse.z);
+ bB.m_linearVelocity.x += mB * this.m_impulse.x;
+ bB.m_linearVelocity.y += mB * this.m_impulse.y;
+ bB.m_angularVelocity += iB * (rBX * this.m_impulse.y - rBY * this.m_impulse.x + this.m_impulse.z);
+ }
+ else {
+ this.m_impulse.SetZero();
+ }
+ }
+ b2WeldJoint.prototype.SolveVelocityConstraints = function (step) {
+ var tMat;
+ var tX = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ var vA = bA.m_linearVelocity;
+ var wA = bA.m_angularVelocity;
+ var vB = bB.m_linearVelocity;
+ var wB = bB.m_angularVelocity;
+ var mA = bA.m_invMass;
+ var mB = bB.m_invMass;
+ var iA = bA.m_invI;
+ var iB = bB.m_invI;
+ tMat = bA.m_xf.R;
+ var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x;
+ var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rAX + tMat.col2.x * rAY);
+ rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY);
+ rAX = tX;
+ tMat = bB.m_xf.R;
+ var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x;
+ var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rBX + tMat.col2.x * rBY);
+ rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY);
+ rBX = tX;
+ var Cdot1X = vB.x - wB * rBY - vA.x + wA * rAY;
+ var Cdot1Y = vB.y + wB * rBX - vA.y - wA * rAX;
+ var Cdot2 = wB - wA;
+ var impulse = new b2Vec3();
+ this.m_mass.Solve33(impulse, (-Cdot1X), (-Cdot1Y), (-Cdot2));
+ this.m_impulse.Add(impulse);
+ vA.x -= mA * impulse.x;
+ vA.y -= mA * impulse.y;
+ wA -= iA * (rAX * impulse.y - rAY * impulse.x + impulse.z);
+ vB.x += mB * impulse.x;
+ vB.y += mB * impulse.y;
+ wB += iB * (rBX * impulse.y - rBY * impulse.x + impulse.z);
+ bA.m_angularVelocity = wA;
+ bB.m_angularVelocity = wB;
+ }
+ b2WeldJoint.prototype.SolvePositionConstraints = function (baumgarte) {
+ if (baumgarte === undefined) baumgarte = 0;
+ var tMat;
+ var tX = 0;
+ var bA = this.m_bodyA;
+ var bB = this.m_bodyB;
+ tMat = bA.m_xf.R;
+ var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x;
+ var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rAX + tMat.col2.x * rAY);
+ rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY);
+ rAX = tX;
+ tMat = bB.m_xf.R;
+ var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x;
+ var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y;
+ tX = (tMat.col1.x * rBX + tMat.col2.x * rBY);
+ rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY);
+ rBX = tX;
+ var mA = bA.m_invMass;
+ var mB = bB.m_invMass;
+ var iA = bA.m_invI;
+ var iB = bB.m_invI;
+ var C1X = bB.m_sweep.c.x + rBX - bA.m_sweep.c.x - rAX;
+ var C1Y = bB.m_sweep.c.y + rBY - bA.m_sweep.c.y - rAY;
+ var C2 = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle;
+ var k_allowedStretch = 10.0 * b2Settings.b2_linearSlop;
+ var positionError = Math.sqrt(C1X * C1X + C1Y * C1Y);
+ var angularError = b2Math.Abs(C2);
+ if (positionError > k_allowedStretch) {
+ iA *= 1.0;
+ iB *= 1.0;
+ }
+ this.m_mass.col1.x = mA + mB + rAY * rAY * iA + rBY * rBY * iB;
+ this.m_mass.col2.x = (-rAY * rAX * iA) - rBY * rBX * iB;
+ this.m_mass.col3.x = (-rAY * iA) - rBY * iB;
+ this.m_mass.col1.y = this.m_mass.col2.x;
+ this.m_mass.col2.y = mA + mB + rAX * rAX * iA + rBX * rBX * iB;
+ this.m_mass.col3.y = rAX * iA + rBX * iB;
+ this.m_mass.col1.z = this.m_mass.col3.x;
+ this.m_mass.col2.z = this.m_mass.col3.y;
+ this.m_mass.col3.z = iA + iB;
+ var impulse = new b2Vec3();
+ this.m_mass.Solve33(impulse, (-C1X), (-C1Y), (-C2));
+ bA.m_sweep.c.x -= mA * impulse.x;
+ bA.m_sweep.c.y -= mA * impulse.y;
+ bA.m_sweep.a -= iA * (rAX * impulse.y - rAY * impulse.x + impulse.z);
+ bB.m_sweep.c.x += mB * impulse.x;
+ bB.m_sweep.c.y += mB * impulse.y;
+ bB.m_sweep.a += iB * (rBX * impulse.y - rBY * impulse.x + impulse.z);
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop;
+ }
+ Box2D.inherit(b2WeldJointDef, Box2D.Dynamics.Joints.b2JointDef);
+ b2WeldJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype;
+ b2WeldJointDef.b2WeldJointDef = function () {
+ Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments);
+ this.localAnchorA = new b2Vec2();
+ this.localAnchorB = new b2Vec2();
+ };
+ b2WeldJointDef.prototype.b2WeldJointDef = function () {
+ this.__super.b2JointDef.call(this);
+ this.type = b2Joint.e_weldJoint;
+ this.referenceAngle = 0.0;
+ }
+ b2WeldJointDef.prototype.Initialize = function (bA, bB, anchor) {
+ this.bodyA = bA;
+ this.bodyB = bB;
+ this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchor));
+ this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchor));
+ this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle();
+ }
+})();
+(function () {
+ var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;
+ b2DebugDraw.b2DebugDraw = function () {
+ this.m_drawScale = 1.0;
+ this.m_lineThickness = 1.0;
+ this.m_alpha = 1.0;
+ this.m_fillAlpha = 1.0;
+ this.m_xformScale = 1.0;
+ var __this = this;
+ //#WORKAROUND
+ this.m_sprite = {
+ graphics: {
+ clear: function () {
+ __this.m_ctx.clearRect(0, 0, __this.m_ctx.canvas.width, __this.m_ctx.canvas.height)
+ }
+ }
+ };
+ };
+ b2DebugDraw.prototype._color = function (color, alpha) {
+ return "rgba(" + ((color & 0xFF0000) >> 16) + "," + ((color & 0xFF00) >> 8) + "," + (color & 0xFF) + "," + alpha + ")";
+ };
+ b2DebugDraw.prototype.b2DebugDraw = function () {
+ this.m_drawFlags = 0;
+ };
+ b2DebugDraw.prototype.SetFlags = function (flags) {
+ if (flags === undefined) flags = 0;
+ this.m_drawFlags = flags;
+ };
+ b2DebugDraw.prototype.GetFlags = function () {
+ return this.m_drawFlags;
+ };
+ b2DebugDraw.prototype.AppendFlags = function (flags) {
+ if (flags === undefined) flags = 0;
+ this.m_drawFlags |= flags;
+ };
+ b2DebugDraw.prototype.ClearFlags = function (flags) {
+ if (flags === undefined) flags = 0;
+ this.m_drawFlags &= ~flags;
+ };
+ b2DebugDraw.prototype.SetSprite = function (sprite) {
+ this.m_ctx = sprite;
+ };
+ b2DebugDraw.prototype.GetSprite = function () {
+ return this.m_ctx;
+ };
+ b2DebugDraw.prototype.SetDrawScale = function (drawScale) {
+ if (drawScale === undefined) drawScale = 0;
+ this.m_drawScale = drawScale;
+ };
+ b2DebugDraw.prototype.GetDrawScale = function () {
+ return this.m_drawScale;
+ };
+ b2DebugDraw.prototype.SetLineThickness = function (lineThickness) {
+ if (lineThickness === undefined) lineThickness = 0;
+ this.m_lineThickness = lineThickness;
+ this.m_ctx.strokeWidth = lineThickness;
+ };
+ b2DebugDraw.prototype.GetLineThickness = function () {
+ return this.m_lineThickness;
+ };
+ b2DebugDraw.prototype.SetAlpha = function (alpha) {
+ if (alpha === undefined) alpha = 0;
+ this.m_alpha = alpha;
+ };
+ b2DebugDraw.prototype.GetAlpha = function () {
+ return this.m_alpha;
+ };
+ b2DebugDraw.prototype.SetFillAlpha = function (alpha) {
+ if (alpha === undefined) alpha = 0;
+ this.m_fillAlpha = alpha;
+ };
+ b2DebugDraw.prototype.GetFillAlpha = function () {
+ return this.m_fillAlpha;
+ };
+ b2DebugDraw.prototype.SetXFormScale = function (xformScale) {
+ if (xformScale === undefined) xformScale = 0;
+ this.m_xformScale = xformScale;
+ };
+ b2DebugDraw.prototype.GetXFormScale = function () {
+ return this.m_xformScale;
+ };
+ b2DebugDraw.prototype.DrawPolygon = function (vertices, vertexCount, color) {
+ if (!vertexCount) return;
+ var s = this.m_ctx;
+ var drawScale = this.m_drawScale;
+ s.beginPath();
+ s.strokeStyle = this._color(color.color, this.m_alpha);
+ s.moveTo(vertices[0].x * drawScale, vertices[0].y * drawScale);
+ for (var i = 1; i < vertexCount; i++) {
+ s.lineTo(vertices[i].x * drawScale, vertices[i].y * drawScale);
+ }
+ s.lineTo(vertices[0].x * drawScale, vertices[0].y * drawScale);
+ s.closePath();
+ s.stroke();
+ };
+ b2DebugDraw.prototype.DrawSolidPolygon = function (vertices, vertexCount, color) {
+ if (!vertexCount) return;
+ var s = this.m_ctx;
+ var drawScale = this.m_drawScale;
+ s.beginPath();
+ s.strokeStyle = this._color(color.color, this.m_alpha);
+ s.fillStyle = this._color(color.color, this.m_fillAlpha);
+ s.moveTo(vertices[0].x * drawScale, vertices[0].y * drawScale);
+ for (var i = 1; i < vertexCount; i++) {
+ s.lineTo(vertices[i].x * drawScale, vertices[i].y * drawScale);
+ }
+ s.lineTo(vertices[0].x * drawScale, vertices[0].y * drawScale);
+ s.closePath();
+ s.fill();
+ s.stroke();
+ };
+ b2DebugDraw.prototype.DrawCircle = function (center, radius, color) {
+ if (!radius) return;
+ var s = this.m_ctx;
+ var drawScale = this.m_drawScale;
+ s.beginPath();
+ s.strokeStyle = this._color(color.color, this.m_alpha);
+ s.arc(center.x * drawScale, center.y * drawScale, radius * drawScale, 0, Math.PI * 2, true);
+ s.closePath();
+ s.stroke();
+ };
+ b2DebugDraw.prototype.DrawSolidCircle = function (center, radius, axis, color) {
+ if (!radius) return;
+ var s = this.m_ctx,
+ drawScale = this.m_drawScale,
+ cx = center.x * drawScale,
+ cy = center.y * drawScale;
+ s.moveTo(0, 0);
+ s.beginPath();
+ s.strokeStyle = this._color(color.color, this.m_alpha);
+ s.fillStyle = this._color(color.color, this.m_fillAlpha);
+ s.arc(cx, cy, radius * drawScale, 0, Math.PI * 2, true);
+ s.moveTo(cx, cy);
+ s.lineTo((center.x + axis.x * radius) * drawScale, (center.y + axis.y * radius) * drawScale);
+ s.closePath();
+ s.fill();
+ s.stroke();
+ };
+ b2DebugDraw.prototype.DrawSegment = function (p1, p2, color) {
+ var s = this.m_ctx,
+ drawScale = this.m_drawScale;
+ s.strokeStyle = this._color(color.color, this.m_alpha);
+ s.beginPath();
+ s.moveTo(p1.x * drawScale, p1.y * drawScale);
+ s.lineTo(p2.x * drawScale, p2.y * drawScale);
+ s.closePath();
+ s.stroke();
+ };
+ b2DebugDraw.prototype.DrawTransform = function (xf) {
+ var s = this.m_ctx,
+ drawScale = this.m_drawScale;
+ s.beginPath();
+ s.strokeStyle = this._color(0xff0000, this.m_alpha);
+ s.moveTo(xf.position.x * drawScale, xf.position.y * drawScale);
+ s.lineTo((xf.position.x + this.m_xformScale * xf.R.col1.x) * drawScale, (xf.position.y + this.m_xformScale * xf.R.col1.y) * drawScale);
+
+ s.strokeStyle = this._color(0xff00, this.m_alpha);
+ s.moveTo(xf.position.x * drawScale, xf.position.y * drawScale);
+ s.lineTo((xf.position.x + this.m_xformScale * xf.R.col2.x) * drawScale, (xf.position.y + this.m_xformScale * xf.R.col2.y) * drawScale);
+ s.closePath();
+ s.stroke();
+ };
+})(); //post-definitions
+var i;
+for (i = 0; i < Box2D.postDefs.length; ++i) Box2D.postDefs[i]();
+delete Box2D.postDefs;
+
+if (typeof require !== 'undefined' && typeof module !== 'undefined') {
+ module.exports = Box2D;
+}
diff --git a/frameworks/cocos2d-html5/external/chipmunk/chipmunk.js b/frameworks/cocos2d-html5/external/chipmunk/chipmunk.js
new file mode 100644
index 0000000..0101792
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/chipmunk/chipmunk.js
@@ -0,0 +1,6236 @@
+(function(){
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+Object.create = Object.create || function(o) {
+ function F() {}
+ F.prototype = o;
+ return new F();
+};
+
+//var VERSION = CP_VERSION_MAJOR + "." + CP_VERSION_MINOR + "." + CP_VERSION_RELEASE;
+
+var cp;
+if(typeof exports === 'undefined'){
+ cp = {};
+
+ if(typeof window === 'object'){
+ window["cp"] = cp;
+ }
+} else {
+ cp = exports;
+}
+
+var assert = function(value, message)
+{
+ if (!value) {
+ throw new Error('Assertion failed: ' + message);
+ }
+};
+
+var assertSoft = function(value, message)
+{
+ if(!value && console && console.warn) {
+ console.warn("ASSERTION FAILED: " + message);
+ if(console.trace) {
+ console.trace();
+ }
+ }
+};
+
+var mymin = function(a, b)
+{
+ return a < b ? a : b;
+};
+var mymax = function(a, b)
+{
+ return a > b ? a : b;
+};
+
+var min, max;
+if (typeof window === 'object' && window.navigator.userAgent.indexOf('Firefox') > -1){
+ // On firefox, Math.min and Math.max are really fast:
+ // http://jsperf.com/math-vs-greater-than/8
+ min = Math.min;
+ max = Math.max;
+} else {
+ // On chrome and safari, Math.min / max are slooow. The ternery operator above is faster
+ // than the builtins because we only have to deal with 2 arguments that are always numbers.
+ min = mymin;
+ max = mymax;
+}
+
+/* The hashpair function takes two numbers and returns a hash code for them.
+ * Required that hashPair(a, b) === hashPair(b, a).
+ * Chipmunk's hashPair function is defined as:
+ * #define CP_HASH_COEF (3344921057ul)
+ * #define CP_HASH_PAIR(A, B) ((cpHashValue)(A)*CP_HASH_COEF ^ (cpHashValue)(B)*CP_HASH_COEF)
+ * But thats not suitable in javascript because multiplying by a large number will make the number
+ * a large float.
+ *
+ * The result of hashPair is used as the key in objects, so it returns a string.
+ */
+var hashPair = function(a, b)
+{
+ //assert(typeof(a) === 'number', "HashPair used on something not a number");
+ return a < b ? a + ' ' + b : b + ' ' + a;
+};
+
+var deleteObjFromList = function(arr, obj)
+{
+ for(var i=0; i> 1;
+ for(var i=1; i maxx || (x == maxx && y > maxy)){
+ maxx = x;
+ maxy = y;
+ end = i;
+ }
+ }
+ return [start, end];
+};
+
+var SWAP = function(arr, idx1, idx2)
+{
+ var tmp = arr[idx1*2];
+ arr[idx1*2] = arr[idx2*2];
+ arr[idx2*2] = tmp;
+
+ tmp = arr[idx1*2+1];
+ arr[idx1*2+1] = arr[idx2*2+1];
+ arr[idx2*2+1] = tmp;
+};
+
+var QHullPartition = function(verts, offs, count, a, b, tol)
+{
+ if(count === 0) return 0;
+
+ var max = 0;
+ var pivot = offs;
+
+ var delta = vsub(b, a);
+ var valueTol = tol * vlength(delta);
+
+ var head = offs;
+ for(var tail = offs+count-1; head <= tail;){
+ var v = new Vect(verts[head * 2], verts[head * 2 + 1]);
+ var value = vcross(delta, vsub(v, a));
+ if(value > valueTol){
+ if(value > max){
+ max = value;
+ pivot = head;
+ }
+
+ head++;
+ } else {
+ SWAP(verts, head, tail);
+ tail--;
+ }
+ }
+
+ // move the new pivot to the front if it's not already there.
+ if(pivot != offs) SWAP(verts, offs, pivot);
+ return head - offs;
+};
+
+var QHullReduce = function(tol, verts, offs, count, a, pivot, b, resultPos)
+{
+ if(count < 0){
+ return 0;
+ } else if(count == 0) {
+ verts[resultPos*2] = pivot.x;
+ verts[resultPos*2+1] = pivot.y;
+ return 1;
+ } else {
+ var left_count = QHullPartition(verts, offs, count, a, pivot, tol);
+ var left = new Vect(verts[offs*2], verts[offs*2+1]);
+ var index = QHullReduce(tol, verts, offs + 1, left_count - 1, a, left, pivot, resultPos);
+
+ var pivotPos = resultPos + index++;
+ verts[pivotPos*2] = pivot.x;
+ verts[pivotPos*2+1] = pivot.y;
+
+ var right_count = QHullPartition(verts, offs + left_count, count - left_count, pivot, b, tol);
+ var right = new Vect(verts[(offs+left_count)*2], verts[(offs+left_count)*2+1]);
+ return index + QHullReduce(tol, verts, offs + left_count + 1, right_count - 1, pivot, right, b, resultPos + index);
+ }
+};
+
+// QuickHull seemed like a neat algorithm, and efficient-ish for large input sets.
+// My implementation performs an in place reduction using the result array as scratch space.
+//
+// Pass an Array into result to put the result of the calculation there. Otherwise, pass null
+// and the verts list will be edited in-place.
+//
+// Expects the verts to be described in the same way as cpPolyShape - which is to say, it should
+// be a list of [x1,y1,x2,y2,x3,y3,...].
+//
+// tolerance is in world coordinates. Eg, 2.
+cp.convexHull = function(verts, result, tolerance)
+{
+ if(result){
+ // Copy the line vertexes into the empty part of the result polyline to use as a scratch buffer.
+ for (var i = 0; i < verts.length; i++){
+ result[i] = verts[i];
+ }
+ } else {
+ // If a result array was not specified, reduce the input instead.
+ result = verts;
+ }
+
+ // Degenerate case, all points are the same.
+ var indexes = loopIndexes(verts);
+ var start = indexes[0], end = indexes[1];
+ if(start == end){
+ //if(first) (*first) = 0;
+ result.length = 2;
+ return result;
+ }
+
+ SWAP(result, 0, start);
+ SWAP(result, 1, end == 0 ? start : end);
+
+ var a = new Vect(result[0], result[1]);
+ var b = new Vect(result[2], result[3]);
+
+ var count = verts.length >> 1;
+ //if(first) (*first) = start;
+ var resultCount = QHullReduce(tolerance, result, 2, count - 2, a, b, a, 1) + 1;
+ result.length = resultCount*2;
+
+ assertSoft(polyValidate(result),
+ "Internal error: cpConvexHull() and cpPolyValidate() did not agree." +
+ "Please report this error with as much info as you can.");
+ return result;
+};
+
+/// Clamp @c f to be between @c min and @c max.
+var clamp = function(f, minv, maxv)
+{
+ return min(max(f, minv), maxv);
+};
+
+/// Clamp @c f to be between 0 and 1.
+var clamp01 = function(f)
+{
+ return max(0, min(f, 1));
+};
+
+/// Linearly interpolate (or extrapolate) between @c f1 and @c f2 by @c t percent.
+var lerp = function(f1, f2, t)
+{
+ return f1*(1 - t) + f2*t;
+};
+
+/// Linearly interpolate from @c f1 to @c f2 by no more than @c d.
+var lerpconst = function(f1, f2, d)
+{
+ return f1 + clamp(f2 - f1, -d, d);
+};
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+// I'm using an array tuple here because (at time of writing) its about 3x faster
+// than an object on firefox, and the same speed on chrome.
+
+//var numVects = 0;
+
+var Vect = cp.Vect = function(x, y)
+{
+ this.x = x;
+ this.y = y;
+ //numVects++;
+
+// var s = new Error().stack;
+// traces[s] = traces[s] ? traces[s]+1 : 1;
+};
+
+cp.v = function (x,y) { return new Vect(x, y) };
+
+var vzero = cp.vzero = new Vect(0,0);
+
+// The functions below *could* be rewritten to be instance methods on Vect. I don't
+// know how that would effect performance. For now, I'm keeping the JS similar to
+// the original C code.
+
+/// Vector dot product.
+var vdot = cp.v.dot = function(v1, v2)
+{
+ return v1.x*v2.x + v1.y*v2.y;
+};
+
+var vdot2 = function(x1, y1, x2, y2)
+{
+ return x1*x2 + y1*y2;
+};
+
+/// Returns the length of v.
+var vlength = cp.v.len = function(v)
+{
+ return Math.sqrt(vdot(v, v));
+};
+
+var vlength2 = cp.v.len2 = function(x, y)
+{
+ return Math.sqrt(x*x + y*y);
+};
+
+/// Check if two vectors are equal. (Be careful when comparing floating point numbers!)
+var veql = cp.v.eql = function(v1, v2)
+{
+ return (v1.x === v2.x && v1.y === v2.y);
+};
+
+/// Add two vectors
+var vadd = cp.v.add = function(v1, v2)
+{
+ return new Vect(v1.x + v2.x, v1.y + v2.y);
+};
+
+Vect.prototype.add = function(v2)
+{
+ this.x += v2.x;
+ this.y += v2.y;
+ return this;
+};
+
+/// Subtract two vectors.
+var vsub = cp.v.sub = function(v1, v2)
+{
+ return new Vect(v1.x - v2.x, v1.y - v2.y);
+};
+
+Vect.prototype.sub = function(v2)
+{
+ this.x -= v2.x;
+ this.y -= v2.y;
+ return this;
+};
+
+/// Negate a vector.
+var vneg = cp.v.neg = function(v)
+{
+ return new Vect(-v.x, -v.y);
+};
+
+Vect.prototype.neg = function()
+{
+ this.x = -this.x;
+ this.y = -this.y;
+ return this;
+};
+
+/// Scalar multiplication.
+var vmult = cp.v.mult = function(v, s)
+{
+ return new Vect(v.x*s, v.y*s);
+};
+
+Vect.prototype.mult = function(s)
+{
+ this.x *= s;
+ this.y *= s;
+ return this;
+};
+
+/// 2D vector cross product analog.
+/// The cross product of 2D vectors results in a 3D vector with only a z component.
+/// This function returns the magnitude of the z value.
+var vcross = cp.v.cross = function(v1, v2)
+{
+ return v1.x*v2.y - v1.y*v2.x;
+};
+
+var vcross2 = function(x1, y1, x2, y2)
+{
+ return x1*y2 - y1*x2;
+};
+
+/// Returns a perpendicular vector. (90 degree rotation)
+var vperp = cp.v.perp = function(v)
+{
+ return new Vect(-v.y, v.x);
+};
+
+/// Returns a perpendicular vector. (-90 degree rotation)
+var vpvrperp = cp.v.pvrperp = function(v)
+{
+ return new Vect(v.y, -v.x);
+};
+
+/// Returns the vector projection of v1 onto v2.
+var vproject = cp.v.project = function(v1, v2)
+{
+ return vmult(v2, vdot(v1, v2)/vlengthsq(v2));
+};
+
+Vect.prototype.project = function(v2)
+{
+ this.mult(vdot(this, v2) / vlengthsq(v2));
+ return this;
+};
+
+/// Uses complex number multiplication to rotate v1 by v2. Scaling will occur if v1 is not a unit vector.
+var vrotate = cp.v.rotate = function(v1, v2)
+{
+ return new Vect(v1.x*v2.x - v1.y*v2.y, v1.x*v2.y + v1.y*v2.x);
+};
+
+Vect.prototype.rotate = function(v2)
+{
+ this.x = this.x * v2.x - this.y * v2.y;
+ this.y = this.x * v2.y + this.y * v2.x;
+ return this;
+};
+
+/// Inverse of vrotate().
+var vunrotate = cp.v.unrotate = function(v1, v2)
+{
+ return new Vect(v1.x*v2.x + v1.y*v2.y, v1.y*v2.x - v1.x*v2.y);
+};
+
+/// Returns the squared length of v. Faster than vlength() when you only need to compare lengths.
+var vlengthsq = cp.v.lengthsq = function(v)
+{
+ return vdot(v, v);
+};
+
+var vlengthsq2 = cp.v.lengthsq2 = function(x, y)
+{
+ return x*x + y*y;
+};
+
+/// Linearly interpolate between v1 and v2.
+var vlerp = cp.v.lerp = function(v1, v2, t)
+{
+ return vadd(vmult(v1, 1 - t), vmult(v2, t));
+};
+
+/// Returns a normalized copy of v.
+var vnormalize = cp.v.normalize = function(v)
+{
+ return vmult(v, 1/vlength(v));
+};
+
+/// Returns a normalized copy of v or vzero if v was already vzero. Protects against divide by zero errors.
+var vnormalize_safe = cp.v.normalize_safe = function(v)
+{
+ return (v.x === 0 && v.y === 0 ? vzero : vnormalize(v));
+};
+
+/// Clamp v to length len.
+var vclamp = cp.v.clamp = function(v, len)
+{
+ return (vdot(v,v) > len*len) ? vmult(vnormalize(v), len) : v;
+};
+
+/// Linearly interpolate between v1 towards v2 by distance d.
+var vlerpconst = cp.v.lerpconst = function(v1, v2, d)
+{
+ return vadd(v1, vclamp(vsub(v2, v1), d));
+};
+
+/// Returns the distance between v1 and v2.
+var vdist = cp.v.dist = function(v1, v2)
+{
+ return vlength(vsub(v1, v2));
+};
+
+/// Returns the squared distance between v1 and v2. Faster than vdist() when you only need to compare distances.
+var vdistsq = cp.v.distsq = function(v1, v2)
+{
+ return vlengthsq(vsub(v1, v2));
+};
+
+/// Returns true if the distance between v1 and v2 is less than dist.
+var vnear = cp.v.near = function(v1, v2, dist)
+{
+ return vdistsq(v1, v2) < dist*dist;
+};
+
+/// Spherical linearly interpolate between v1 and v2.
+var vslerp = cp.v.slerp = function(v1, v2, t)
+{
+ var omega = Math.acos(vdot(v1, v2));
+
+ if(omega) {
+ var denom = 1/Math.sin(omega);
+ return vadd(vmult(v1, Math.sin((1 - t)*omega)*denom), vmult(v2, Math.sin(t*omega)*denom));
+ } else {
+ return v1;
+ }
+};
+
+/// Spherical linearly interpolate between v1 towards v2 by no more than angle a radians
+var vslerpconst = cp.v.slerpconst = function(v1, v2, a)
+{
+ var angle = Math.acos(vdot(v1, v2));
+ return vslerp(v1, v2, min(a, angle)/angle);
+};
+
+/// Returns the unit length vector for the given angle (in radians).
+var vforangle = cp.v.forangle = function(a)
+{
+ return new Vect(Math.cos(a), Math.sin(a));
+};
+
+/// Returns the angular direction v is pointing in (in radians).
+var vtoangle = cp.v.toangle = function(v)
+{
+ return Math.atan2(v.y, v.x);
+};
+
+/// Returns a string representation of v. Intended mostly for debugging purposes and not production use.
+var vstr = cp.v.str = function(v)
+{
+ return "(" + v.x.toFixed(3) + ", " + v.y.toFixed(3) + ")";
+};
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/// Chipmunk's axis-aligned 2D bounding box type along with a few handy routines.
+
+var numBB = 0;
+
+// Bounding boxes are JS objects with {l, b, r, t} = left, bottom, right, top, respectively.
+var BB = cp.BB = function(l, b, r, t)
+{
+ this.l = l;
+ this.b = b;
+ this.r = r;
+ this.t = t;
+
+ numBB++;
+};
+
+cp.bb = function(l, b, r, t) { return new BB(l, b, r, t); };
+
+var bbNewForCircle = function(p, r)
+{
+ return new BB(
+ p.x - r,
+ p.y - r,
+ p.x + r,
+ p.y + r
+ );
+};
+
+/// Returns true if @c a and @c b intersect.
+var bbIntersects = function(a, b)
+{
+ return (a.l <= b.r && b.l <= a.r && a.b <= b.t && b.b <= a.t);
+};
+var bbIntersects2 = function(bb, l, b, r, t)
+{
+ return (bb.l <= r && l <= bb.r && bb.b <= t && b <= bb.t);
+};
+
+/// Returns true if @c other lies completely within @c bb.
+var bbContainsBB = function(bb, other)
+{
+ return (bb.l <= other.l && bb.r >= other.r && bb.b <= other.b && bb.t >= other.t);
+};
+
+/// Returns true if @c bb contains @c v.
+var bbContainsVect = function(bb, v)
+{
+ return (bb.l <= v.x && bb.r >= v.x && bb.b <= v.y && bb.t >= v.y);
+};
+var bbContainsVect2 = function(l, b, r, t, v)
+{
+ return (l <= v.x && r >= v.x && b <= v.y && t >= v.y);
+};
+
+/// Returns a bounding box that holds both bounding boxes.
+var bbMerge = function(a, b){
+ return new BB(
+ min(a.l, b.l),
+ min(a.b, b.b),
+ max(a.r, b.r),
+ max(a.t, b.t)
+ );
+};
+
+/// Returns a bounding box that holds both @c bb and @c v.
+var bbExpand = function(bb, v){
+ return new BB(
+ min(bb.l, v.x),
+ min(bb.b, v.y),
+ max(bb.r, v.x),
+ max(bb.t, v.y)
+ );
+};
+
+/// Returns the area of the bounding box.
+var bbArea = function(bb)
+{
+ return (bb.r - bb.l)*(bb.t - bb.b);
+};
+
+/// Merges @c a and @c b and returns the area of the merged bounding box.
+var bbMergedArea = function(a, b)
+{
+ return (max(a.r, b.r) - min(a.l, b.l))*(max(a.t, b.t) - min(a.b, b.b));
+};
+
+var bbMergedArea2 = function(bb, l, b, r, t)
+{
+ return (max(bb.r, r) - min(bb.l, l))*(max(bb.t, t) - min(bb.b, b));
+};
+
+/// Return true if the bounding box intersects the line segment with ends @c a and @c b.
+var bbIntersectsSegment = function(bb, a, b)
+{
+ return (bbSegmentQuery(bb, a, b) != Infinity);
+};
+
+/// Clamp a vector to a bounding box.
+var bbClampVect = function(bb, v)
+{
+ var x = min(max(bb.l, v.x), bb.r);
+ var y = min(max(bb.b, v.y), bb.t);
+ return new Vect(x, y);
+};
+
+// TODO edge case issue
+/// Wrap a vector to a bounding box.
+var bbWrapVect = function(bb, v)
+{
+ var ix = Math.abs(bb.r - bb.l);
+ var modx = (v.x - bb.l) % ix;
+ var x = (modx > 0) ? modx : modx + ix;
+
+ var iy = Math.abs(bb.t - bb.b);
+ var mody = (v.y - bb.b) % iy;
+ var y = (mody > 0) ? mody : mody + iy;
+
+ return new Vect(x + bb.l, y + bb.b);
+};
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/// Segment query info struct.
+/* These are created using literals where needed.
+typedef struct cpSegmentQueryInfo {
+ /// The shape that was hit, null if no collision occurred.
+ cpShape *shape;
+ /// The normalized distance along the query segment in the range [0, 1].
+ cpFloat t;
+ /// The normal of the surface hit.
+ cpVect n;
+} cpSegmentQueryInfo;
+*/
+
+var shapeIDCounter = 0;
+
+var CP_NO_GROUP = cp.NO_GROUP = 0;
+var CP_ALL_LAYERS = cp.ALL_LAYERS = ~0;
+var CP_ALL_CATEGORIES = cp.ALL_CATEGORIES = ~0; // Chipmunk v7.0 compatibility
+
+cp.resetShapeIdCounter = function()
+{
+ shapeIDCounter = 0;
+};
+
+/// The cpShape struct defines the shape of a rigid body.
+//
+/// Opaque collision shape struct. Do not create directly - instead use
+/// PolyShape, CircleShape and SegmentShape.
+var Shape = cp.Shape = function(body) {
+ /// The rigid body this collision shape is attached to.
+ this.body = body;
+
+ /// The current bounding box of the shape.
+ this.bb_l = this.bb_b = this.bb_r = this.bb_t = 0;
+
+ this.hashid = shapeIDCounter++;
+
+ /// Sensor flag.
+ /// Sensor shapes call collision callbacks but don't produce collisions.
+ this.sensor = false;
+
+ /// Coefficient of restitution. (elasticity)
+ this.e = 0;
+ /// Coefficient of friction.
+ this.u = 0;
+ /// Surface velocity used when solving for friction.
+ this.surface_v = vzero;
+
+ /// Collision type of this shape used when picking collision handlers.
+ this.collision_type = 0;
+ /// Group of this shape. Shapes in the same group don't collide.
+ this.group = 0;
+ // Layer bitmask for this shape. Shapes only collide if the bitwise and of their layers is non-zero.
+ this.layers = CP_ALL_LAYERS;
+
+ this.space = null;
+
+ // Copy the collision code from the prototype into the actual object. This makes collision
+ // function lookups slightly faster.
+ this.collisionCode = this.collisionCode;
+};
+
+Shape.prototype.setElasticity = function(e) { this.e = e; };
+Shape.prototype.setFriction = function(u) { this.body.activate(); this.u = u; };
+Shape.prototype.setLayers = function(layers) { this.body.activate(); this.layers = layers; };
+Shape.prototype.setSensor = function(sensor) { this.body.activate(); this.sensor = sensor; };
+Shape.prototype.setCollisionType = function(collision_type) { this.body.activate(); this.collision_type = collision_type; };
+Shape.prototype.getBody = function() { return this.body; };
+
+Shape.prototype.active = function()
+{
+// return shape->prev || (shape->body && shape->body->shapeList == shape);
+ return this.body && this.body.shapeList.indexOf(this) !== -1;
+};
+
+Shape.prototype.setBody = function(body)
+{
+ assert(!this.active(), "You cannot change the body on an active shape. You must remove the shape from the space before changing the body.");
+ this.body = body;
+};
+
+Shape.prototype.cacheBB = function()
+{
+ return this.update(this.body.p, this.body.rot);
+};
+
+Shape.prototype.update = function(pos, rot)
+{
+ assert(!isNaN(rot.x), 'Rotation is NaN');
+ assert(!isNaN(pos.x), 'Position is NaN');
+ this.cacheData(pos, rot);
+};
+
+Shape.prototype.pointQuery = function(p)
+{
+ var info = this.nearestPointQuery(p);
+ if (info.d < 0) return info;
+};
+
+Shape.prototype.getBB = function()
+{
+ return new BB(this.bb_l, this.bb_b, this.bb_r, this.bb_t);
+};
+
+/* Not implemented - all these getters and setters. Just edit the object directly.
+CP_DefineShapeStructGetter(cpBody*, body, Body);
+void cpShapeSetBody(cpShape *shape, cpBody *body);
+
+CP_DefineShapeStructGetter(cpBB, bb, BB);
+CP_DefineShapeStructProperty(cpBool, sensor, Sensor, cpTrue);
+CP_DefineShapeStructProperty(cpFloat, e, Elasticity, cpFalse);
+CP_DefineShapeStructProperty(cpFloat, u, Friction, cpTrue);
+CP_DefineShapeStructProperty(cpVect, surface_v, SurfaceVelocity, cpTrue);
+CP_DefineShapeStructProperty(cpDataPointer, data, UserData, cpFalse);
+CP_DefineShapeStructProperty(cpCollisionType, collision_type, CollisionType, cpTrue);
+CP_DefineShapeStructProperty(cpGroup, group, Group, cpTrue);
+CP_DefineShapeStructProperty(cpLayers, layers, Layers, cpTrue);
+*/
+
+/// Extended point query info struct. Returned from calling pointQuery on a shape.
+var PointQueryExtendedInfo = function(shape)
+{
+ /// Shape that was hit, NULL if no collision occurred.
+ this.shape = shape;
+ /// Depth of the point inside the shape.
+ this.d = Infinity;
+ /// Direction of minimum norm to the shape's surface.
+ this.n = vzero;
+};
+
+var NearestPointQueryInfo = function(shape, p, d)
+{
+ /// The nearest shape, NULL if no shape was within range.
+ this.shape = shape;
+ /// The closest point on the shape's surface. (in world space coordinates)
+ this.p = p;
+ /// The distance to the point. The distance is negative if the point is inside the shape.
+ this.d = d;
+};
+
+var SegmentQueryInfo = function(shape, t, n)
+{
+ /// The shape that was hit, NULL if no collision occurred.
+ this.shape = shape;
+ /// The normalized distance along the query segment in the range [0, 1].
+ this.t = t;
+ /// The normal of the surface hit.
+ this.n = n;
+};
+
+/// Get the hit point for a segment query.
+SegmentQueryInfo.prototype.hitPoint = function(start, end)
+{
+ return vlerp(start, end, this.t);
+};
+
+/// Get the hit distance for a segment query.
+SegmentQueryInfo.prototype.hitDist = function(start, end)
+{
+ return vdist(start, end) * this.t;
+};
+
+// Circles.
+
+var CircleShape = cp.CircleShape = function(body, radius, offset)
+{
+ this.c = this.tc = offset;
+ this.r = radius;
+
+ this.type = 'circle';
+
+ Shape.call(this, body);
+};
+
+CircleShape.prototype = Object.create(Shape.prototype);
+
+CircleShape.prototype.cacheData = function(p, rot)
+{
+ //var c = this.tc = vadd(p, vrotate(this.c, rot));
+ var c = this.tc = vrotate(this.c, rot).add(p);
+ //this.bb = bbNewForCircle(c, this.r);
+ var r = this.r;
+ this.bb_l = c.x - r;
+ this.bb_b = c.y - r;
+ this.bb_r = c.x + r;
+ this.bb_t = c.y + r;
+};
+
+/// Test if a point lies within a shape.
+/*CircleShape.prototype.pointQuery = function(p)
+{
+ var delta = vsub(p, this.tc);
+ var distsq = vlengthsq(delta);
+ var r = this.r;
+
+ if(distsq < r*r){
+ var info = new PointQueryExtendedInfo(this);
+
+ var dist = Math.sqrt(distsq);
+ info.d = r - dist;
+ info.n = vmult(delta, 1/dist);
+ return info;
+ }
+};*/
+
+CircleShape.prototype.nearestPointQuery = function(p)
+{
+ var deltax = p.x - this.tc.x;
+ var deltay = p.y - this.tc.y;
+ var d = vlength2(deltax, deltay);
+ var r = this.r;
+
+ var nearestp = new Vect(this.tc.x + deltax * r/d, this.tc.y + deltay * r/d);
+ return new NearestPointQueryInfo(this, nearestp, d - r);
+};
+
+var circleSegmentQuery = function(shape, center, r, a, b, info)
+{
+ // offset the line to be relative to the circle
+ a = vsub(a, center);
+ b = vsub(b, center);
+
+ var qa = vdot(a, a) - 2*vdot(a, b) + vdot(b, b);
+ var qb = -2*vdot(a, a) + 2*vdot(a, b);
+ var qc = vdot(a, a) - r*r;
+
+ var det = qb*qb - 4*qa*qc;
+
+ if(det >= 0)
+ {
+ var t = (-qb - Math.sqrt(det))/(2*qa);
+ if(0 <= t && t <= 1){
+ return new SegmentQueryInfo(shape, t, vnormalize(vlerp(a, b, t)));
+ }
+ }
+};
+
+CircleShape.prototype.segmentQuery = function(a, b)
+{
+ return circleSegmentQuery(this, this.tc, this.r, a, b);
+};
+
+// The C API has these, and also getters. Its not idiomatic to
+// write getters and setters in JS.
+/*
+CircleShape.prototype.setRadius = function(radius)
+{
+ this.r = radius;
+}
+
+CircleShape.prototype.setOffset = function(offset)
+{
+ this.c = offset;
+}*/
+
+// Segment shape
+
+var SegmentShape = cp.SegmentShape = function(body, a, b, r)
+{
+ this.a = a;
+ this.b = b;
+ this.n = vperp(vnormalize(vsub(b, a)));
+
+ this.ta = this.tb = this.tn = null;
+
+ this.r = r;
+
+ this.a_tangent = vzero;
+ this.b_tangent = vzero;
+
+ this.type = 'segment';
+ Shape.call(this, body);
+};
+
+SegmentShape.prototype = Object.create(Shape.prototype);
+
+SegmentShape.prototype.cacheData = function(p, rot)
+{
+ this.ta = vadd(p, vrotate(this.a, rot));
+ this.tb = vadd(p, vrotate(this.b, rot));
+ this.tn = vrotate(this.n, rot);
+
+ var l,r,b,t;
+
+ if(this.ta.x < this.tb.x){
+ l = this.ta.x;
+ r = this.tb.x;
+ } else {
+ l = this.tb.x;
+ r = this.ta.x;
+ }
+
+ if(this.ta.y < this.tb.y){
+ b = this.ta.y;
+ t = this.tb.y;
+ } else {
+ b = this.tb.y;
+ t = this.ta.y;
+ }
+
+ var rad = this.r;
+
+ this.bb_l = l - rad;
+ this.bb_b = b - rad;
+ this.bb_r = r + rad;
+ this.bb_t = t + rad;
+};
+
+SegmentShape.prototype.nearestPointQuery = function(p)
+{
+ var closest = closestPointOnSegment(p, this.ta, this.tb);
+
+ var deltax = p.x - closest.x;
+ var deltay = p.y - closest.y;
+ var d = vlength2(deltax, deltay);
+ var r = this.r;
+
+ var nearestp = (d ? vadd(closest, vmult(new Vect(deltax, deltay), r/d)) : closest);
+ return new NearestPointQueryInfo(this, nearestp, d - r);
+};
+
+SegmentShape.prototype.segmentQuery = function(a, b)
+{
+ var n = this.tn;
+ var d = vdot(vsub(this.ta, a), n);
+ var r = this.r;
+
+ var flipped_n = (d > 0 ? vneg(n) : n);
+ var n_offset = vsub(vmult(flipped_n, r), a);
+
+ var seg_a = vadd(this.ta, n_offset);
+ var seg_b = vadd(this.tb, n_offset);
+ var delta = vsub(b, a);
+
+ if(vcross(delta, seg_a)*vcross(delta, seg_b) <= 0){
+ var d_offset = d + (d > 0 ? -r : r);
+ var ad = -d_offset;
+ var bd = vdot(delta, n) - d_offset;
+
+ if(ad*bd < 0){
+ return new SegmentQueryInfo(this, ad/(ad - bd), flipped_n);
+ }
+ } else if(r !== 0){
+ var info1 = circleSegmentQuery(this, this.ta, this.r, a, b);
+ var info2 = circleSegmentQuery(this, this.tb, this.r, a, b);
+
+ if (info1){
+ return info2 && info2.t < info1.t ? info2 : info1;
+ } else {
+ return info2;
+ }
+ }
+};
+
+SegmentShape.prototype.setNeighbors = function(prev, next)
+{
+ this.a_tangent = vsub(prev, this.a);
+ this.b_tangent = vsub(next, this.b);
+};
+
+SegmentShape.prototype.setEndpoints = function(a, b)
+{
+ this.a = a;
+ this.b = b;
+ this.n = vperp(vnormalize(vsub(b, a)));
+};
+
+/*
+cpSegmentShapeSetRadius(cpShape *shape, cpFloat radius)
+{
+ this.r = radius;
+}*/
+
+/*
+CP_DeclareShapeGetter(cpSegmentShape, cpVect, A);
+CP_DeclareShapeGetter(cpSegmentShape, cpVect, B);
+CP_DeclareShapeGetter(cpSegmentShape, cpVect, Normal);
+CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius);
+*/
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/// Check that a set of vertexes is convex and has a clockwise winding.
+var polyValidate = function(verts)
+{
+ var len = verts.length;
+ for(var i=0; i 0){
+ if(vcross2(bx - ax, by - ay, cx - bx, cy - by) > 0){
+ return false;
+ }
+ }
+
+ return true;
+};
+
+/// Initialize a polygon shape.
+/// The vertexes must be convex and have a clockwise winding.
+var PolyShape = cp.PolyShape = function(body, verts, offset)
+{
+ this.setVerts(verts, offset);
+ this.type = 'poly';
+ Shape.call(this, body);
+};
+
+PolyShape.prototype = Object.create(Shape.prototype);
+
+var SplittingPlane = function(n, d)
+{
+ this.n = n;
+ this.d = d;
+};
+
+SplittingPlane.prototype.compare = function(v)
+{
+ return vdot(this.n, v) - this.d;
+};
+
+PolyShape.prototype.setVerts = function(verts, offset)
+{
+ assert(verts.length >= 4, "Polygons require some verts");
+ assert(typeof(verts[0]) === 'number',
+ 'Polygon verticies should be specified in a flattened list (eg [x1,y1,x2,y2,x3,y3,...])');
+
+ // Fail if the user attempts to pass a concave poly, or a bad winding.
+ assert(polyValidate(verts), "Polygon is concave or has a reversed winding. Consider using cpConvexHull()");
+
+ var len = verts.length;
+ var numVerts = len >> 1;
+
+ // This a pretty bad way to do this in javascript. As a first pass, I want to keep
+ // the code similar to the C.
+ this.verts = new Array(len);
+ this.tVerts = new Array(len);
+ this.planes = new Array(numVerts);
+ this.tPlanes = new Array(numVerts);
+
+ for(var i=0; i>1] = new SplittingPlane(n, vdot2(n.x, n.y, ax, ay));
+ this.tPlanes[i>>1] = new SplittingPlane(new Vect(0,0), 0);
+ }
+};
+
+/// Initialize a box shaped polygon shape.
+var BoxShape = cp.BoxShape = function(body, width, height)
+{
+ var hw = width/2;
+ var hh = height/2;
+
+ return BoxShape2(body, new BB(-hw, -hh, hw, hh));
+};
+
+/// Initialize an offset box shaped polygon shape.
+var BoxShape2 = cp.BoxShape2 = function(body, box)
+{
+ var verts = [
+ box.l, box.b,
+ box.l, box.t,
+ box.r, box.t,
+ box.r, box.b
+ ];
+
+ return new PolyShape(body, verts, vzero);
+};
+
+PolyShape.prototype.transformVerts = function(p, rot)
+{
+ var src = this.verts;
+ var dst = this.tVerts;
+
+ var l = Infinity, r = -Infinity;
+ var b = Infinity, t = -Infinity;
+
+ for(var i=0; i (' + vx + ',' + vy + ')');
+
+ dst[i] = vx;
+ dst[i+1] = vy;
+
+ l = min(l, vx);
+ r = max(r, vx);
+ b = min(b, vy);
+ t = max(t, vy);
+ }
+
+ this.bb_l = l;
+ this.bb_b = b;
+ this.bb_r = r;
+ this.bb_t = t;
+};
+
+PolyShape.prototype.transformAxes = function(p, rot)
+{
+ var src = this.planes;
+ var dst = this.tPlanes;
+
+ for(var i=0; i 0) outside = true;
+
+ var v1x = verts[i*2];
+ var v1y = verts[i*2 + 1];
+ var closest = closestPointOnSegment2(p.x, p.y, v0x, v0y, v1x, v1y);
+
+ var dist = vdist(p, closest);
+ if(dist < minDist){
+ minDist = dist;
+ closestPoint = closest;
+ }
+
+ v0x = v1x;
+ v0y = v1y;
+ }
+
+ return new NearestPointQueryInfo(this, closestPoint, (outside ? minDist : -minDist));
+};
+
+PolyShape.prototype.segmentQuery = function(a, b)
+{
+ var axes = this.tPlanes;
+ var verts = this.tVerts;
+ var numVerts = axes.length;
+ var len = numVerts * 2;
+
+ for(var i=0; i an) continue;
+
+ var bn = vdot(b, n);
+ var t = (axes[i].d - an)/(bn - an);
+ if(t < 0 || 1 < t) continue;
+
+ var point = vlerp(a, b, t);
+ var dt = -vcross(n, point);
+ var dtMin = -vcross2(n.x, n.y, verts[i*2], verts[i*2+1]);
+ var dtMax = -vcross2(n.x, n.y, verts[(i*2+2)%len], verts[(i*2+3)%len]);
+
+ if(dtMin <= dt && dt <= dtMax){
+ // josephg: In the original C code, this function keeps
+ // looping through axes after finding a match. I *think*
+ // this code is equivalent...
+ return new SegmentQueryInfo(this, t, n);
+ }
+ }
+};
+
+PolyShape.prototype.valueOnAxis = function(n, d)
+{
+ var verts = this.tVerts;
+ var m = vdot2(n.x, n.y, verts[0], verts[1]);
+
+ for(var i=2; i 0) return false;
+ }
+
+ return true;
+};
+
+PolyShape.prototype.containsVertPartial = function(vx, vy, n)
+{
+ var planes = this.tPlanes;
+
+ for(var i=0; i 0) return false;
+ }
+
+ return true;
+};
+
+// These methods are provided for API compatibility with Chipmunk. I recommend against using
+// them - just access the poly.verts list directly.
+PolyShape.prototype.getNumVerts = function() { return this.verts.length / 2; };
+PolyShape.prototype.getCount = PolyShape.prototype.getNumVerts; // v7.0 compatibility
+PolyShape.prototype.getVert = function(i)
+{
+ return new Vect(this.verts[i * 2], this.verts[i * 2 + 1]);
+};
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/// @defgroup cpBody cpBody
+/// Chipmunk's rigid body type. Rigid bodies hold the physical properties of an object like
+/// it's mass, and position and velocity of it's center of gravity. They don't have an shape on their own.
+/// They are given a shape by creating collision shapes (cpShape) that point to the body.
+/// @{
+
+var Body = cp.Body = function(m, i) {
+ /// Mass of the body.
+ /// Must agree with cpBody.m_inv! Use body.setMass() when changing the mass for this reason.
+ //this.m;
+ /// Mass inverse.
+ //this.m_inv;
+
+ /// Moment of inertia of the body.
+ /// Must agree with cpBody.i_inv! Use body.setMoment() when changing the moment for this reason.
+ //this.i;
+ /// Moment of inertia inverse.
+ //this.i_inv;
+
+ /// Position of the rigid body's center of gravity.
+ this.p = new Vect(0,0);
+ /// Velocity of the rigid body's center of gravity.
+ this.vx = this.vy = 0;
+ /// Force acting on the rigid body's center of gravity.
+ this.f = new Vect(0,0);
+
+ /// Rotation of the body around it's center of gravity in radians.
+ /// Must agree with cpBody.rot! Use cpBodySetAngle() when changing the angle for this reason.
+ //this.a;
+ /// Angular velocity of the body around it's center of gravity in radians/second.
+ this.w = 0;
+ /// Torque applied to the body around it's center of gravity.
+ this.t = 0;
+
+ /// Cached unit length vector representing the angle of the body.
+ /// Used for fast rotations using cpvrotate().
+ //cpVect rot;
+
+ /// Maximum velocity allowed when updating the velocity.
+ this.v_limit = Infinity;
+ /// Maximum rotational rate (in radians/second) allowed when updating the angular velocity.
+ this.w_limit = Infinity;
+
+ // This stuff is all private.
+ this.v_biasx = this.v_biasy = 0;
+ this.w_bias = 0;
+
+ this.space = null;
+
+ this.shapeList = [];
+ this.arbiterList = null; // These are both wacky linked lists.
+ this.constraintList = null;
+
+ // This stuff is used to track information on the collision graph.
+ this.nodeRoot = null;
+ this.nodeNext = null;
+ this.nodeIdleTime = 0;
+
+ // Set this.m and this.m_inv
+ this.setMass(m);
+
+ // Set this.i and this.i_inv
+ this.setMoment(i);
+
+ // Set this.a and this.rot
+ this.rot = new Vect(0,0);
+ this.setAngle(0);
+};
+
+// I wonder if this should use the constructor style like Body...
+var createStaticBody = function()
+{
+ var body = new Body(Infinity, Infinity);
+ body.nodeIdleTime = Infinity;
+
+ return body;
+};
+ cp.StaticBody = createStaticBody;
+
+if (typeof DEBUG !== 'undefined' && DEBUG) {
+ var v_assert_nan = function(v, message){assert(v.x == v.x && v.y == v.y, message); };
+ var v_assert_infinite = function(v, message){assert(Math.abs(v.x) !== Infinity && Math.abs(v.y) !== Infinity, message);};
+ var v_assert_sane = function(v, message){v_assert_nan(v, message); v_assert_infinite(v, message);};
+
+ Body.prototype.sanityCheck = function()
+ {
+ assert(this.m === this.m && this.m_inv === this.m_inv, "Body's mass is invalid.");
+ assert(this.i === this.i && this.i_inv === this.i_inv, "Body's moment is invalid.");
+
+ v_assert_sane(this.p, "Body's position is invalid.");
+ v_assert_sane(this.f, "Body's force is invalid.");
+ assert(this.vx === this.vx && Math.abs(this.vx) !== Infinity, "Body's velocity is invalid.");
+ assert(this.vy === this.vy && Math.abs(this.vy) !== Infinity, "Body's velocity is invalid.");
+
+ assert(this.a === this.a && Math.abs(this.a) !== Infinity, "Body's angle is invalid.");
+ assert(this.w === this.w && Math.abs(this.w) !== Infinity, "Body's angular velocity is invalid.");
+ assert(this.t === this.t && Math.abs(this.t) !== Infinity, "Body's torque is invalid.");
+
+ v_assert_sane(this.rot, "Body's rotation vector is invalid.");
+
+ assert(this.v_limit === this.v_limit, "Body's velocity limit is invalid.");
+ assert(this.w_limit === this.w_limit, "Body's angular velocity limit is invalid.");
+ };
+} else {
+ Body.prototype.sanityCheck = function(){};
+}
+
+Body.prototype.getPos = function() { return this.p; };
+Body.prototype.getVel = function() { return new Vect(this.vx, this.vy); };
+Body.prototype.getAngVel = function() { return this.w; };
+// chipmunk v7.0 compatibility
+Body.prototype.getPosition = Body.prototype.getPos;
+Body.prototype.getVelocity = Body.prototype.getVel;
+Body.prototype.getAngularVelocity = Body.prototype.getAngVel;
+Body.prototype.getCenterOfGravity = function() {
+ // FIXME: what is the best way to calculate the center of gravity?
+ // Needed for Chipmunk v7.0 compatibility
+ return this.p;
+};
+
+/// Returns true if the body is sleeping.
+Body.prototype.isSleeping = function()
+{
+ return this.nodeRoot !== null;
+};
+
+/// Returns true if the body is static.
+Body.prototype.isStatic = function()
+{
+ return this.nodeIdleTime === Infinity;
+};
+
+/// Returns true if the body has not been added to a space.
+Body.prototype.isRogue = function()
+{
+ return this.space === null;
+};
+
+// It would be nicer to use defineProperty for this, but its about 30x slower:
+// http://jsperf.com/defineproperty-vs-setter
+Body.prototype.setMass = function(mass)
+{
+ assert(mass > 0, "Mass must be positive and non-zero.");
+
+ //activate is defined in cpSpaceComponent
+ this.activate();
+ this.m = mass;
+ this.m_inv = 1/mass;
+};
+
+Body.prototype.setMoment = function(moment)
+{
+ assert(moment > 0, "Moment of Inertia must be positive and non-zero.");
+
+ this.activate();
+ this.i = moment;
+ this.i_inv = 1/moment;
+};
+
+Body.prototype.addShape = function(shape)
+{
+ this.shapeList.push(shape);
+};
+
+Body.prototype.removeShape = function(shape)
+{
+ // This implementation has a linear time complexity with the number of shapes.
+ // The original implementation used linked lists instead, which might be faster if
+ // you're constantly editing the shape of a body. I expect most bodies will never
+ // have their shape edited, so I'm just going to use the simplest possible implemention.
+ deleteObjFromList(this.shapeList, shape);
+};
+
+var filterConstraints = function(node, body, filter)
+{
+ if(node === filter){
+ return node.next(body);
+ } else if(node.a === body){
+ node.next_a = filterConstraints(node.next_a, body, filter);
+ } else {
+ node.next_b = filterConstraints(node.next_b, body, filter);
+ }
+
+ return node;
+};
+
+Body.prototype.removeConstraint = function(constraint)
+{
+ // The constraint must be in the constraints list when this is called.
+ this.constraintList = filterConstraints(this.constraintList, this, constraint);
+};
+
+Body.prototype.setPos = function(pos)
+{
+ this.activate();
+ this.sanityCheck();
+ // If I allow the position to be set to vzero, vzero will get changed.
+ if (pos === vzero) {
+ pos = cp.v(0,0);
+ }
+ this.p = pos;
+};
+
+Body.prototype.setVel = function(velocity)
+{
+ this.activate();
+ this.vx = velocity.x;
+ this.vy = velocity.y;
+};
+
+Body.prototype.setAngVel = function(w)
+{
+ this.activate();
+ this.w = w;
+};
+
+Body.prototype.setAngleInternal = function(angle)
+{
+ assert(!isNaN(angle), "Internal Error: Attempting to set body's angle to NaN");
+ this.a = angle;//fmod(a, (cpFloat)M_PI*2.0f);
+
+ //this.rot = vforangle(angle);
+ this.rot.x = Math.cos(angle);
+ this.rot.y = Math.sin(angle);
+};
+
+Body.prototype.setAngle = function(angle)
+{
+ this.activate();
+ this.sanityCheck();
+ this.setAngleInternal(angle);
+};
+
+Body.prototype.velocity_func = function(gravity, damping, dt)
+{
+ //this.v = vclamp(vadd(vmult(this.v, damping), vmult(vadd(gravity, vmult(this.f, this.m_inv)), dt)), this.v_limit);
+ var vx = this.vx * damping + (gravity.x + this.f.x * this.m_inv) * dt;
+ var vy = this.vy * damping + (gravity.y + this.f.y * this.m_inv) * dt;
+
+ //var v = vclamp(new Vect(vx, vy), this.v_limit);
+ //this.vx = v.x; this.vy = v.y;
+ var v_limit = this.v_limit;
+ var lensq = vx * vx + vy * vy;
+ var scale = (lensq > v_limit*v_limit) ? v_limit / Math.sqrt(lensq) : 1;
+ this.vx = vx * scale;
+ this.vy = vy * scale;
+
+ var w_limit = this.w_limit;
+ this.w = clamp(this.w*damping + this.t*this.i_inv*dt, -w_limit, w_limit);
+
+ this.sanityCheck();
+};
+
+Body.prototype.position_func = function(dt)
+{
+ //this.p = vadd(this.p, vmult(vadd(this.v, this.v_bias), dt));
+
+ //this.p = this.p + (this.v + this.v_bias) * dt;
+ this.p.x += (this.vx + this.v_biasx) * dt;
+ this.p.y += (this.vy + this.v_biasy) * dt;
+
+ this.setAngleInternal(this.a + (this.w + this.w_bias)*dt);
+
+ this.v_biasx = this.v_biasy = 0;
+ this.w_bias = 0;
+
+ this.sanityCheck();
+};
+
+Body.prototype.resetForces = function()
+{
+ this.activate();
+ this.f = new Vect(0,0);
+ this.t = 0;
+};
+
+Body.prototype.applyForce = function(force, r)
+{
+ this.activate();
+ this.f = vadd(this.f, force);
+ this.t += vcross(r, force);
+};
+
+Body.prototype.applyImpulse = function(j, r)
+{
+ this.activate();
+ apply_impulse(this, j.x, j.y, r);
+};
+
+Body.prototype.getVelAtPoint = function(r)
+{
+ return vadd(new Vect(this.vx, this.vy), vmult(vperp(r), this.w));
+};
+
+/// Get the velocity on a body (in world units) at a point on the body in world coordinates.
+Body.prototype.getVelAtWorldPoint = function(point)
+{
+ return this.getVelAtPoint(vsub(point, this.p));
+};
+
+/// Get the velocity on a body (in world units) at a point on the body in local coordinates.
+Body.prototype.getVelAtLocalPoint = function(point)
+{
+ return this.getVelAtPoint(vrotate(point, this.rot));
+};
+
+Body.prototype.eachShape = function(func)
+{
+ for(var i = 0, len = this.shapeList.length; i < len; i++) {
+ func(this.shapeList[i]);
+ }
+};
+
+Body.prototype.eachConstraint = function(func)
+{
+ var constraint = this.constraintList;
+ while(constraint) {
+ var next = constraint.next(this);
+ func(constraint);
+ constraint = next;
+ }
+};
+
+Body.prototype.eachArbiter = function(func)
+{
+ var arb = this.arbiterList;
+ while(arb){
+ var next = arb.next(this);
+
+ arb.swappedColl = (this === arb.body_b);
+ func(arb);
+
+ arb = next;
+ }
+};
+
+/// Convert body relative/local coordinates to absolute/world coordinates.
+Body.prototype.local2World = function(v)
+{
+ return vadd(this.p, vrotate(v, this.rot));
+};
+
+/// Convert body absolute/world coordinates to relative/local coordinates.
+Body.prototype.world2Local = function(v)
+{
+ return vunrotate(vsub(v, this.p), this.rot);
+};
+// chipmunk v7.0 compatibility
+Body.prototype.localToWorld = Body.prototype.local2World;
+Body.prototype.worldToLocal = Body.prototype.world2Local;
+
+/// Get the kinetic energy of a body.
+Body.prototype.kineticEnergy = function()
+{
+ // Need to do some fudging to avoid NaNs
+ var vsq = this.vx*this.vx + this.vy*this.vy;
+ var wsq = this.w * this.w;
+ return (vsq ? vsq*this.m : 0) + (wsq ? wsq*this.i : 0);
+};
+
+/* Copyright (c) 2010 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ @defgroup cpSpatialIndex cpSpatialIndex
+
+ Spatial indexes are data structures that are used to accelerate collision detection
+ and spatial queries. Chipmunk provides a number of spatial index algorithms to pick from
+ and they are programmed in a generic way so that you can use them for holding more than
+ just Shapes.
+
+ It works by using pointers to the objects you add and using a callback to ask your code
+ for bounding boxes when it needs them. Several types of queries can be performed an index as well
+ as reindexing and full collision information. All communication to the spatial indexes is performed
+ through callback functions.
+
+ Spatial indexes should be treated as opaque structs.
+ This means you shouldn't be reading any of the fields directly.
+
+ All spatial indexes define the following methods:
+
+ // The number of objects in the spatial index.
+ count = 0;
+
+ // Iterate the objects in the spatial index. @c func will be called once for each object.
+ each(func);
+
+ // Returns true if the spatial index contains the given object.
+ // Most spatial indexes use hashed storage, so you must provide a hash value too.
+ contains(obj, hashid);
+
+ // Add an object to a spatial index.
+ insert(obj, hashid);
+
+ // Remove an object from a spatial index.
+ remove(obj, hashid);
+
+ // Perform a full reindex of a spatial index.
+ reindex();
+
+ // Reindex a single object in the spatial index.
+ reindexObject(obj, hashid);
+
+ // Perform a point query against the spatial index, calling @c func for each potential match.
+ // A pointer to the point will be passed as @c obj1 of @c func.
+ // func(shape);
+ pointQuery(point, func);
+
+ // Perform a segment query against the spatial index, calling @c func for each potential match.
+ // func(shape);
+ segmentQuery(vect a, vect b, t_exit, func);
+
+ // Perform a rectangle query against the spatial index, calling @c func for each potential match.
+ // func(shape);
+ query(bb, func);
+
+ // Simultaneously reindex and find all colliding objects.
+ // @c func will be called once for each potentially overlapping pair of objects found.
+ // If the spatial index was initialized with a static index, it will collide it's objects against that as well.
+ reindexQuery(func);
+*/
+
+var SpatialIndex = cp.SpatialIndex = function(staticIndex)
+{
+ this.staticIndex = staticIndex;
+
+
+ if(staticIndex){
+ if(staticIndex.dynamicIndex){
+ throw new Error("This static index is already associated with a dynamic index.");
+ }
+ staticIndex.dynamicIndex = this;
+ }
+};
+
+// Collide the objects in an index against the objects in a staticIndex using the query callback function.
+SpatialIndex.prototype.collideStatic = function(staticIndex, func)
+{
+ if(staticIndex.count > 0){
+ var query = staticIndex.query;
+
+ this.each(function(obj) {
+ query(obj, new BB(obj.bb_l, obj.bb_b, obj.bb_r, obj.bb_t), func);
+ });
+ }
+};
+
+
+/* Copyright (c) 2009 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+// This file implements a modified AABB tree for collision detection.
+
+var BBTree = cp.BBTree = function(staticIndex)
+{
+ SpatialIndex.call(this, staticIndex);
+
+ this.velocityFunc = null;
+
+ // This is a hash from object ID -> object for the objects stored in the BBTree.
+ this.leaves = {};
+ // A count of the number of leaves in the BBTree.
+ this.count = 0;
+
+ this.root = null;
+
+ // A linked list containing an object pool of tree nodes and pairs.
+ this.pooledNodes = null;
+ this.pooledPairs = null;
+
+ this.stamp = 0;
+};
+
+BBTree.prototype = Object.create(SpatialIndex.prototype);
+
+var numNodes = 0;
+
+var Node = function(tree, a, b)
+{
+ this.obj = null;
+ this.bb_l = min(a.bb_l, b.bb_l);
+ this.bb_b = min(a.bb_b, b.bb_b);
+ this.bb_r = max(a.bb_r, b.bb_r);
+ this.bb_t = max(a.bb_t, b.bb_t);
+ this.parent = null;
+
+ this.setA(a);
+ this.setB(b);
+};
+
+BBTree.prototype.makeNode = function(a, b)
+{
+ var node = this.pooledNodes;
+ if(node){
+ this.pooledNodes = node.parent;
+ node.constructor(this, a, b);
+ return node;
+ } else {
+ numNodes++;
+ return new Node(this, a, b);
+ }
+};
+
+var numLeaves = 0;
+var Leaf = function(tree, obj)
+{
+ this.obj = obj;
+ tree.getBB(obj, this);
+
+ this.parent = null;
+
+ this.stamp = 1;
+ this.pairs = null;
+ numLeaves++;
+};
+
+// **** Misc Functions
+
+BBTree.prototype.getBB = function(obj, dest)
+{
+ var velocityFunc = this.velocityFunc;
+ if(velocityFunc){
+ var coef = 0.1;
+ var x = (obj.bb_r - obj.bb_l)*coef;
+ var y = (obj.bb_t - obj.bb_b)*coef;
+
+ var v = vmult(velocityFunc(obj), 0.1);
+
+ dest.bb_l = obj.bb_l + min(-x, v.x);
+ dest.bb_b = obj.bb_b + min(-y, v.y);
+ dest.bb_r = obj.bb_r + max( x, v.x);
+ dest.bb_t = obj.bb_t + max( y, v.y);
+ } else {
+ dest.bb_l = obj.bb_l;
+ dest.bb_b = obj.bb_b;
+ dest.bb_r = obj.bb_r;
+ dest.bb_t = obj.bb_t;
+ }
+};
+
+BBTree.prototype.getStamp = function()
+{
+ var dynamic = this.dynamicIndex;
+ return (dynamic && dynamic.stamp ? dynamic.stamp : this.stamp);
+};
+
+BBTree.prototype.incrementStamp = function()
+{
+ if(this.dynamicIndex && this.dynamicIndex.stamp){
+ this.dynamicIndex.stamp++;
+ } else {
+ this.stamp++;
+ }
+}
+
+// **** Pair/Thread Functions
+
+var numPairs = 0;
+// Objects created with constructors are faster than object literals. :(
+var Pair = function(leafA, nextA, leafB, nextB)
+{
+ this.prevA = null;
+ this.leafA = leafA;
+ this.nextA = nextA;
+
+ this.prevB = null;
+ this.leafB = leafB;
+ this.nextB = nextB;
+};
+
+BBTree.prototype.makePair = function(leafA, nextA, leafB, nextB)
+{
+ //return new Pair(leafA, nextA, leafB, nextB);
+ var pair = this.pooledPairs;
+ if (pair)
+ {
+ this.pooledPairs = pair.prevA;
+
+ pair.prevA = null;
+ pair.leafA = leafA;
+ pair.nextA = nextA;
+
+ pair.prevB = null;
+ pair.leafB = leafB;
+ pair.nextB = nextB;
+
+ //pair.constructor(leafA, nextA, leafB, nextB);
+ return pair;
+ } else {
+ numPairs++;
+ return new Pair(leafA, nextA, leafB, nextB);
+ }
+};
+
+Pair.prototype.recycle = function(tree)
+{
+ this.prevA = tree.pooledPairs;
+ tree.pooledPairs = this;
+};
+
+var unlinkThread = function(prev, leaf, next)
+{
+ if(next){
+ if(next.leafA === leaf) next.prevA = prev; else next.prevB = prev;
+ }
+
+ if(prev){
+ if(prev.leafA === leaf) prev.nextA = next; else prev.nextB = next;
+ } else {
+ leaf.pairs = next;
+ }
+};
+
+Leaf.prototype.clearPairs = function(tree)
+{
+ var pair = this.pairs,
+ next;
+
+ this.pairs = null;
+
+ while(pair){
+ if(pair.leafA === this){
+ next = pair.nextA;
+ unlinkThread(pair.prevB, pair.leafB, pair.nextB);
+ } else {
+ next = pair.nextB;
+ unlinkThread(pair.prevA, pair.leafA, pair.nextA);
+ }
+ pair.recycle(tree);
+ pair = next;
+ }
+};
+
+var pairInsert = function(a, b, tree)
+{
+ var nextA = a.pairs, nextB = b.pairs;
+ var pair = tree.makePair(a, nextA, b, nextB);
+ a.pairs = b.pairs = pair;
+
+ if(nextA){
+ if(nextA.leafA === a) nextA.prevA = pair; else nextA.prevB = pair;
+ }
+
+ if(nextB){
+ if(nextB.leafA === b) nextB.prevA = pair; else nextB.prevB = pair;
+ }
+};
+
+// **** Node Functions
+
+Node.prototype.recycle = function(tree)
+{
+ this.parent = tree.pooledNodes;
+ tree.pooledNodes = this;
+};
+
+Leaf.prototype.recycle = function(tree)
+{
+ // Its not worth the overhead to recycle leaves.
+};
+
+Node.prototype.setA = function(value)
+{
+ this.A = value;
+ value.parent = this;
+};
+
+Node.prototype.setB = function(value)
+{
+ this.B = value;
+ value.parent = this;
+};
+
+Leaf.prototype.isLeaf = true;
+Node.prototype.isLeaf = false;
+
+Node.prototype.otherChild = function(child)
+{
+ return (this.A == child ? this.B : this.A);
+};
+
+Node.prototype.replaceChild = function(child, value, tree)
+{
+ assertSoft(child == this.A || child == this.B, "Node is not a child of parent.");
+
+ if(this.A == child){
+ this.A.recycle(tree);
+ this.setA(value);
+ } else {
+ this.B.recycle(tree);
+ this.setB(value);
+ }
+
+ for(var node=this; node; node = node.parent){
+ //node.bb = bbMerge(node.A.bb, node.B.bb);
+ var a = node.A;
+ var b = node.B;
+ node.bb_l = min(a.bb_l, b.bb_l);
+ node.bb_b = min(a.bb_b, b.bb_b);
+ node.bb_r = max(a.bb_r, b.bb_r);
+ node.bb_t = max(a.bb_t, b.bb_t);
+ }
+};
+
+Node.prototype.bbArea = Leaf.prototype.bbArea = function()
+{
+ return (this.bb_r - this.bb_l)*(this.bb_t - this.bb_b);
+};
+
+var bbTreeMergedArea = function(a, b)
+{
+ return (max(a.bb_r, b.bb_r) - min(a.bb_l, b.bb_l))*(max(a.bb_t, b.bb_t) - min(a.bb_b, b.bb_b));
+};
+
+// **** Subtree Functions
+
+// Would it be better to make these functions instance methods on Node and Leaf?
+
+var bbProximity = function(a, b)
+{
+ return Math.abs(a.bb_l + a.bb_r - b.bb_l - b.bb_r) + Math.abs(a.bb_b + a.bb_t - b.bb_b - b.bb_t);
+};
+
+var subtreeInsert = function(subtree, leaf, tree)
+{
+// var s = new Error().stack;
+// traces[s] = traces[s] ? traces[s]+1 : 1;
+
+ if(subtree == null){
+ return leaf;
+ } else if(subtree.isLeaf){
+ return tree.makeNode(leaf, subtree);
+ } else {
+ var cost_a = subtree.B.bbArea() + bbTreeMergedArea(subtree.A, leaf);
+ var cost_b = subtree.A.bbArea() + bbTreeMergedArea(subtree.B, leaf);
+
+ if(cost_a === cost_b){
+ cost_a = bbProximity(subtree.A, leaf);
+ cost_b = bbProximity(subtree.B, leaf);
+ }
+
+ if(cost_b < cost_a){
+ subtree.setB(subtreeInsert(subtree.B, leaf, tree));
+ } else {
+ subtree.setA(subtreeInsert(subtree.A, leaf, tree));
+ }
+
+// subtree.bb = bbMerge(subtree.bb, leaf.bb);
+ subtree.bb_l = min(subtree.bb_l, leaf.bb_l);
+ subtree.bb_b = min(subtree.bb_b, leaf.bb_b);
+ subtree.bb_r = max(subtree.bb_r, leaf.bb_r);
+ subtree.bb_t = max(subtree.bb_t, leaf.bb_t);
+
+ return subtree;
+ }
+};
+
+Node.prototype.intersectsBB = Leaf.prototype.intersectsBB = function(bb)
+{
+ return (this.bb_l <= bb.r && bb.l <= this.bb_r && this.bb_b <= bb.t && bb.b <= this.bb_t);
+};
+
+var subtreeQuery = function(subtree, bb, func)
+{
+ //if(bbIntersectsBB(subtree.bb, bb)){
+ if(subtree.intersectsBB(bb)){
+ if(subtree.isLeaf){
+ func(subtree.obj);
+ } else {
+ subtreeQuery(subtree.A, bb, func);
+ subtreeQuery(subtree.B, bb, func);
+ }
+ }
+};
+
+/// Returns the fraction along the segment query the node hits. Returns Infinity if it doesn't hit.
+var nodeSegmentQuery = function(node, a, b)
+{
+ var idx = 1/(b.x - a.x);
+ var tx1 = (node.bb_l == a.x ? -Infinity : (node.bb_l - a.x)*idx);
+ var tx2 = (node.bb_r == a.x ? Infinity : (node.bb_r - a.x)*idx);
+ var txmin = min(tx1, tx2);
+ var txmax = max(tx1, tx2);
+
+ var idy = 1/(b.y - a.y);
+ var ty1 = (node.bb_b == a.y ? -Infinity : (node.bb_b - a.y)*idy);
+ var ty2 = (node.bb_t == a.y ? Infinity : (node.bb_t - a.y)*idy);
+ var tymin = min(ty1, ty2);
+ var tymax = max(ty1, ty2);
+
+ if(tymin <= txmax && txmin <= tymax){
+ var min_ = max(txmin, tymin);
+ var max_ = min(txmax, tymax);
+
+ if(0.0 <= max_ && min_ <= 1.0) return max(min_, 0.0);
+ }
+
+ return Infinity;
+};
+
+var subtreeSegmentQuery = function(subtree, a, b, t_exit, func)
+{
+ if(subtree.isLeaf){
+ return func(subtree.obj);
+ } else {
+ var t_a = nodeSegmentQuery(subtree.A, a, b);
+ var t_b = nodeSegmentQuery(subtree.B, a, b);
+
+ if(t_a < t_b){
+ if(t_a < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.A, a, b, t_exit, func));
+ if(t_b < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.B, a, b, t_exit, func));
+ } else {
+ if(t_b < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.B, a, b, t_exit, func));
+ if(t_a < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.A, a, b, t_exit, func));
+ }
+
+ return t_exit;
+ }
+};
+
+BBTree.prototype.subtreeRecycle = function(node)
+{
+ if(node.isLeaf){
+ this.subtreeRecycle(node.A);
+ this.subtreeRecycle(node.B);
+ node.recycle(this);
+ }
+};
+
+var subtreeRemove = function(subtree, leaf, tree)
+{
+ if(leaf == subtree){
+ return null;
+ } else {
+ var parent = leaf.parent;
+ if(parent == subtree){
+ var other = subtree.otherChild(leaf);
+ other.parent = subtree.parent;
+ subtree.recycle(tree);
+ return other;
+ } else {
+ parent.parent.replaceChild(parent, parent.otherChild(leaf), tree);
+ return subtree;
+ }
+ }
+};
+
+// **** Marking Functions
+
+/*
+typedef struct MarkContext {
+ bbTree *tree;
+ Node *staticRoot;
+ cpSpatialIndexQueryFunc func;
+} MarkContext;
+*/
+
+var bbTreeIntersectsNode = function(a, b)
+{
+ return (a.bb_l <= b.bb_r && b.bb_l <= a.bb_r && a.bb_b <= b.bb_t && b.bb_b <= a.bb_t);
+};
+
+Leaf.prototype.markLeafQuery = function(leaf, left, tree, func)
+{
+ if(bbTreeIntersectsNode(leaf, this)){
+ if(left){
+ pairInsert(leaf, this, tree);
+ } else {
+ if(this.stamp < leaf.stamp) pairInsert(this, leaf, tree);
+ if(func) func(leaf.obj, this.obj);
+ }
+ }
+};
+
+Node.prototype.markLeafQuery = function(leaf, left, tree, func)
+{
+ if(bbTreeIntersectsNode(leaf, this)){
+ this.A.markLeafQuery(leaf, left, tree, func);
+ this.B.markLeafQuery(leaf, left, tree, func);
+ }
+};
+
+Leaf.prototype.markSubtree = function(tree, staticRoot, func)
+{
+ if(this.stamp == tree.getStamp()){
+ if(staticRoot) staticRoot.markLeafQuery(this, false, tree, func);
+
+ for(var node = this; node.parent; node = node.parent){
+ if(node == node.parent.A){
+ node.parent.B.markLeafQuery(this, true, tree, func);
+ } else {
+ node.parent.A.markLeafQuery(this, false, tree, func);
+ }
+ }
+ } else {
+ var pair = this.pairs;
+ while(pair){
+ if(this === pair.leafB){
+ if(func) func(pair.leafA.obj, this.obj);
+ pair = pair.nextB;
+ } else {
+ pair = pair.nextA;
+ }
+ }
+ }
+};
+
+Node.prototype.markSubtree = function(tree, staticRoot, func)
+{
+ this.A.markSubtree(tree, staticRoot, func);
+ this.B.markSubtree(tree, staticRoot, func);
+};
+
+// **** Leaf Functions
+
+Leaf.prototype.containsObj = function(obj)
+{
+ return (this.bb_l <= obj.bb_l && this.bb_r >= obj.bb_r && this.bb_b <= obj.bb_b && this.bb_t >= obj.bb_t);
+};
+
+Leaf.prototype.update = function(tree)
+{
+ var root = tree.root;
+ var obj = this.obj;
+
+ //if(!bbContainsBB(this.bb, bb)){
+ if(!this.containsObj(obj)){
+ tree.getBB(this.obj, this);
+
+ root = subtreeRemove(root, this, tree);
+ tree.root = subtreeInsert(root, this, tree);
+
+ this.clearPairs(tree);
+ this.stamp = tree.getStamp();
+
+ return true;
+ }
+
+ return false;
+};
+
+Leaf.prototype.addPairs = function(tree)
+{
+ var dynamicIndex = tree.dynamicIndex;
+ if(dynamicIndex){
+ var dynamicRoot = dynamicIndex.root;
+ if(dynamicRoot){
+ dynamicRoot.markLeafQuery(this, true, dynamicIndex, null);
+ }
+ } else {
+ var staticRoot = tree.staticIndex.root;
+ this.markSubtree(tree, staticRoot, null);
+ }
+};
+
+// **** Insert/Remove
+
+BBTree.prototype.insert = function(obj, hashid)
+{
+ var leaf = new Leaf(this, obj);
+
+ this.leaves[hashid] = leaf;
+ this.root = subtreeInsert(this.root, leaf, this);
+ this.count++;
+
+ leaf.stamp = this.getStamp();
+ leaf.addPairs(this);
+ this.incrementStamp();
+};
+
+BBTree.prototype.remove = function(obj, hashid)
+{
+ var leaf = this.leaves[hashid];
+
+ delete this.leaves[hashid];
+ this.root = subtreeRemove(this.root, leaf, this);
+ this.count--;
+
+ leaf.clearPairs(this);
+ leaf.recycle(this);
+};
+
+BBTree.prototype.contains = function(obj, hashid)
+{
+ return this.leaves[hashid] != null;
+};
+
+// **** Reindex
+var voidQueryFunc = function(obj1, obj2){};
+
+BBTree.prototype.reindexQuery = function(func)
+{
+ if(!this.root) return;
+
+ // LeafUpdate() may modify this.root. Don't cache it.
+ var hashid,
+ leaves = this.leaves;
+ for (hashid in leaves)
+ {
+ leaves[hashid].update(this);
+ }
+
+ var staticIndex = this.staticIndex;
+ var staticRoot = staticIndex && staticIndex.root;
+
+ this.root.markSubtree(this, staticRoot, func);
+ if(staticIndex && !staticRoot) this.collideStatic(this, staticIndex, func);
+
+ this.incrementStamp();
+};
+
+BBTree.prototype.reindex = function()
+{
+ this.reindexQuery(voidQueryFunc);
+};
+
+BBTree.prototype.reindexObject = function(obj, hashid)
+{
+ var leaf = this.leaves[hashid];
+ if(leaf){
+ if(leaf.update(this)) leaf.addPairs(this);
+ this.incrementStamp();
+ }
+};
+
+// **** Query
+
+// This has since been removed from upstream Chipmunk - which recommends you just use query() below
+// directly.
+BBTree.prototype.pointQuery = function(point, func)
+{
+ this.query(new BB(point.x, point.y, point.x, point.y), func);
+};
+
+BBTree.prototype.segmentQuery = function(a, b, t_exit, func)
+{
+ if(this.root) subtreeSegmentQuery(this.root, a, b, t_exit, func);
+};
+
+BBTree.prototype.query = function(bb, func)
+{
+ if(this.root) subtreeQuery(this.root, bb, func);
+};
+
+// **** Misc
+
+BBTree.prototype.count = function()
+{
+ return this.count;
+};
+
+BBTree.prototype.each = function(func)
+{
+ var hashid;
+ for(hashid in this.leaves)
+ {
+ func(this.leaves[hashid].obj);
+ }
+};
+
+// **** Tree Optimization
+
+var bbTreeMergedArea2 = function(node, l, b, r, t)
+{
+ return (max(node.bb_r, r) - min(node.bb_l, l))*(max(node.bb_t, t) - min(node.bb_b, b));
+};
+
+var partitionNodes = function(tree, nodes, offset, count)
+{
+ if(count == 1){
+ return nodes[offset];
+ } else if(count == 2) {
+ return tree.makeNode(nodes[offset], nodes[offset + 1]);
+ }
+
+ // Find the AABB for these nodes
+ //var bb = nodes[offset].bb;
+ var node = nodes[offset];
+ var bb_l = node.bb_l,
+ bb_b = node.bb_b,
+ bb_r = node.bb_r,
+ bb_t = node.bb_t;
+
+ var end = offset + count;
+ for(var i=offset + 1; i bb_t - bb_b);
+
+ // Sort the bounds and use the median as the splitting point
+ var bounds = new Array(count*2);
+ if(splitWidth){
+ for(var i=offset; inext = next;
+ if(prev.body_a === body) {
+ prev.thread_a_next = next;
+ } else {
+ prev.thread_b_next = next;
+ }
+ } else {
+ body.arbiterList = next;
+ }
+
+ if(next){
+ // cpArbiterThreadForBody(next, body)->prev = prev;
+ if(next.body_a === body){
+ next.thread_a_prev = prev;
+ } else {
+ next.thread_b_prev = prev;
+ }
+ }
+};
+
+Arbiter.prototype.unthread = function()
+{
+ unthreadHelper(this, this.body_a, this.thread_a_prev, this.thread_a_next);
+ unthreadHelper(this, this.body_b, this.thread_b_prev, this.thread_b_next);
+ this.thread_a_prev = this.thread_a_next = null;
+ this.thread_b_prev = this.thread_b_next = null;
+};
+
+//cpFloat
+//cpContactsEstimateCrushingImpulse(cpContact *contacts, int numContacts)
+//{
+// cpFloat fsum = 0;
+// cpVect vsum = vzero;
+//
+// for(int i=0; i= mindist*mindist) return;
+
+ var dist = Math.sqrt(distsq);
+
+ // Allocate and initialize the contact.
+ return new Contact(
+ vadd(p1, vmult(delta, 0.5 + (r1 - 0.5*mindist)/(dist ? dist : Infinity))),
+ (dist ? vmult(delta, 1/dist) : new Vect(1, 0)),
+ dist - mindist,
+ 0
+ );
+};
+
+// Collide circle shapes.
+var circle2circle = function(circ1, circ2)
+{
+ var contact = circle2circleQuery(circ1.tc, circ2.tc, circ1.r, circ2.r);
+ return contact ? [contact] : NONE;
+};
+
+var circle2segment = function(circleShape, segmentShape)
+{
+ var seg_a = segmentShape.ta;
+ var seg_b = segmentShape.tb;
+ var center = circleShape.tc;
+
+ var seg_delta = vsub(seg_b, seg_a);
+ var closest_t = clamp01(vdot(seg_delta, vsub(center, seg_a))/vlengthsq(seg_delta));
+ var closest = vadd(seg_a, vmult(seg_delta, closest_t));
+
+ var contact = circle2circleQuery(center, closest, circleShape.r, segmentShape.r);
+ if(contact){
+ var n = contact.n;
+
+ // Reject endcap collisions if tangents are provided.
+ return (
+ (closest_t === 0 && vdot(n, segmentShape.a_tangent) < 0) ||
+ (closest_t === 1 && vdot(n, segmentShape.b_tangent) < 0)
+ ) ? NONE : [contact];
+ } else {
+ return NONE;
+ }
+}
+
+// Find the minimum separating axis for the given poly and axis list.
+//
+// This function needs to return two values - the index of the min. separating axis and
+// the value itself. Short of inlining MSA, returning values through a global like this
+// is the fastest implementation.
+//
+// See: http://jsperf.com/return-two-values-from-function/2
+var last_MSA_min = 0;
+var findMSA = function(poly, planes)
+{
+ var min_index = 0;
+ var min = poly.valueOnAxis(planes[0].n, planes[0].d);
+ if(min > 0) return -1;
+
+ for(var i=1; i 0) {
+ return -1;
+ } else if(dist > min){
+ min = dist;
+ min_index = i;
+ }
+ }
+
+ last_MSA_min = min;
+ return min_index;
+};
+
+// Add contacts for probably penetrating vertexes.
+// This handles the degenerate case where an overlap was detected, but no vertexes fall inside
+// the opposing polygon. (like a star of david)
+var findVertsFallback = function(poly1, poly2, n, dist)
+{
+ var arr = [];
+
+ var verts1 = poly1.tVerts;
+ for(var i=0; i>1)));
+ }
+ }
+
+ var verts2 = poly2.tVerts;
+ for(var i=0; i>1)));
+ }
+ }
+
+ return (arr.length ? arr : findVertsFallback(poly1, poly2, n, dist));
+};
+
+// Collide poly shapes together.
+var poly2poly = function(poly1, poly2)
+{
+ var mini1 = findMSA(poly2, poly1.tPlanes);
+ if(mini1 == -1) return NONE;
+ var min1 = last_MSA_min;
+
+ var mini2 = findMSA(poly1, poly2.tPlanes);
+ if(mini2 == -1) return NONE;
+ var min2 = last_MSA_min;
+
+ // There is overlap, find the penetrating verts
+ if(min1 > min2)
+ return findVerts(poly1, poly2, poly1.tPlanes[mini1].n, min1);
+ else
+ return findVerts(poly1, poly2, vneg(poly2.tPlanes[mini2].n), min2);
+};
+
+// Like cpPolyValueOnAxis(), but for segments.
+var segValueOnAxis = function(seg, n, d)
+{
+ var a = vdot(n, seg.ta) - seg.r;
+ var b = vdot(n, seg.tb) - seg.r;
+ return min(a, b) - d;
+};
+
+// Identify vertexes that have penetrated the segment.
+var findPointsBehindSeg = function(arr, seg, poly, pDist, coef)
+{
+ var dta = vcross(seg.tn, seg.ta);
+ var dtb = vcross(seg.tn, seg.tb);
+ var n = vmult(seg.tn, coef);
+
+ var verts = poly.tVerts;
+ for(var i=0; i= dt && dt >= dtb){
+ arr.push(new Contact(new Vect(vx, vy), n, pDist, hashPair(poly.hashid, i)));
+ }
+ }
+ }
+};
+
+// This one is complicated and gross. Just don't go there...
+// TODO: Comment me!
+var seg2poly = function(seg, poly)
+{
+ var arr = [];
+
+ var planes = poly.tPlanes;
+ var numVerts = planes.length;
+
+ var segD = vdot(seg.tn, seg.ta);
+ var minNorm = poly.valueOnAxis(seg.tn, segD) - seg.r;
+ var minNeg = poly.valueOnAxis(vneg(seg.tn), -segD) - seg.r;
+ if(minNeg > 0 || minNorm > 0) return NONE;
+
+ var mini = 0;
+ var poly_min = segValueOnAxis(seg, planes[0].n, planes[0].d);
+ if(poly_min > 0) return NONE;
+ for(var i=0; i 0){
+ return NONE;
+ } else if(dist > poly_min){
+ poly_min = dist;
+ mini = i;
+ }
+ }
+
+ var poly_n = vneg(planes[mini].n);
+
+ var va = vadd(seg.ta, vmult(poly_n, seg.r));
+ var vb = vadd(seg.tb, vmult(poly_n, seg.r));
+ if(poly.containsVert(va.x, va.y))
+ arr.push(new Contact(va, poly_n, poly_min, hashPair(seg.hashid, 0)));
+ if(poly.containsVert(vb.x, vb.y))
+ arr.push(new Contact(vb, poly_n, poly_min, hashPair(seg.hashid, 1)));
+
+ // Floating point precision problems here.
+ // This will have to do for now.
+// poly_min -= cp_collision_slop; // TODO is this needed anymore?
+
+ if(minNorm >= poly_min || minNeg >= poly_min) {
+ if(minNorm > minNeg)
+ findPointsBehindSeg(arr, seg, poly, minNorm, 1);
+ else
+ findPointsBehindSeg(arr, seg, poly, minNeg, -1);
+ }
+
+ // If no other collision points are found, try colliding endpoints.
+ if(arr.length === 0){
+ var mini2 = mini * 2;
+ var verts = poly.tVerts;
+
+ var poly_a = new Vect(verts[mini2], verts[mini2+1]);
+
+ var con;
+ if((con = circle2circleQuery(seg.ta, poly_a, seg.r, 0, arr))) return [con];
+ if((con = circle2circleQuery(seg.tb, poly_a, seg.r, 0, arr))) return [con];
+
+ var len = numVerts * 2;
+ var poly_b = new Vect(verts[(mini2+2)%len], verts[(mini2+3)%len]);
+ if((con = circle2circleQuery(seg.ta, poly_b, seg.r, 0, arr))) return [con];
+ if((con = circle2circleQuery(seg.tb, poly_b, seg.r, 0, arr))) return [con];
+ }
+
+// console.log(poly.tVerts, poly.tPlanes);
+// console.log('seg2poly', arr);
+ return arr;
+};
+
+// This one is less gross, but still gross.
+// TODO: Comment me!
+var circle2poly = function(circ, poly)
+{
+ var planes = poly.tPlanes;
+
+ var mini = 0;
+ var min = vdot(planes[0].n, circ.tc) - planes[0].d - circ.r;
+ for(var i=0; i 0){
+ return NONE;
+ } else if(dist > min) {
+ min = dist;
+ mini = i;
+ }
+ }
+
+ var n = planes[mini].n;
+
+ var verts = poly.tVerts;
+ var len = verts.length;
+ var mini2 = mini<<1;
+
+ //var a = poly.tVerts[mini];
+ //var b = poly.tVerts[(mini + 1)%poly.tVerts.length];
+ var ax = verts[mini2];
+ var ay = verts[mini2+1];
+ var bx = verts[(mini2+2)%len];
+ var by = verts[(mini2+3)%len];
+
+ var dta = vcross2(n.x, n.y, ax, ay);
+ var dtb = vcross2(n.x, n.y, bx, by);
+ var dt = vcross(n, circ.tc);
+
+ if(dt < dtb){
+ var con = circle2circleQuery(circ.tc, new Vect(bx, by), circ.r, 0, con);
+ return con ? [con] : NONE;
+ } else if(dt < dta) {
+ return [new Contact(
+ vsub(circ.tc, vmult(n, circ.r + min/2)),
+ vneg(n),
+ min,
+ 0
+ )];
+ } else {
+ var con = circle2circleQuery(circ.tc, new Vect(ax, ay), circ.r, 0, con);
+ return con ? [con] : NONE;
+ }
+};
+
+// The javascripty way to do this would be either nested object or methods on the prototypes.
+//
+// However, the *fastest* way is the method below.
+// See: http://jsperf.com/dispatch
+
+// These are copied from the prototypes into the actual objects in the Shape constructor.
+CircleShape.prototype.collisionCode = 0;
+SegmentShape.prototype.collisionCode = 1;
+PolyShape.prototype.collisionCode = 2;
+
+CircleShape.prototype.collisionTable = [
+ circle2circle,
+ circle2segment,
+ circle2poly
+];
+
+SegmentShape.prototype.collisionTable = [
+ null,
+ function(segA, segB) { return NONE; }, // seg2seg
+ seg2poly
+];
+
+PolyShape.prototype.collisionTable = [
+ null,
+ null,
+ poly2poly
+];
+
+var collideShapes = cp.collideShapes = function(a, b)
+{
+ assert(a.collisionCode <= b.collisionCode, 'Collided shapes must be sorted by type');
+ return a.collisionTable[b.collisionCode](a, b);
+};
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+var defaultCollisionHandler = new CollisionHandler();
+
+/// Basic Unit of Simulation in Chipmunk
+var Space = cp.Space = function() {
+ this.stamp = 0;
+ this.curr_dt = 0;
+
+ this.bodies = [];
+ this.rousedBodies = [];
+ this.sleepingComponents = [];
+
+ this.staticShapes = new BBTree(null);
+ this.activeShapes = new BBTree(this.staticShapes);
+
+ this.arbiters = [];
+ this.contactBuffersHead = null;
+ this.cachedArbiters = {};
+ //this.pooledArbiters = [];
+
+ this.constraints = [];
+
+ this.locked = 0;
+
+ this.collisionHandlers = {};
+ this.defaultHandler = defaultCollisionHandler;
+
+ this.postStepCallbacks = [];
+
+ /// Number of iterations to use in the impulse solver to solve contacts.
+ this.iterations = 10;
+
+ /// Gravity to pass to rigid bodies when integrating velocity.
+ this.gravity = vzero;
+
+ /// Damping rate expressed as the fraction of velocity bodies retain each second.
+ /// A value of 0.9 would mean that each body's velocity will drop 10% per second.
+ /// The default value is 1.0, meaning no damping is applied.
+ /// @note This damping value is different than those of cpDampedSpring and cpDampedRotarySpring.
+ this.damping = 1;
+
+ /// Speed threshold for a body to be considered idle.
+ /// The default value of 0 means to let the space guess a good threshold based on gravity.
+ this.idleSpeedThreshold = 0;
+
+ /// Time a group of bodies must remain idle in order to fall asleep.
+ /// Enabling sleeping also implicitly enables the the contact graph.
+ /// The default value of Infinity disables the sleeping algorithm.
+ this.sleepTimeThreshold = Infinity;
+
+ /// Amount of encouraged penetration between colliding shapes..
+ /// Used to reduce oscillating contacts and keep the collision cache warm.
+ /// Defaults to 0.1. If you have poor simulation quality,
+ /// increase this number as much as possible without allowing visible amounts of overlap.
+ this.collisionSlop = 0.1;
+
+ /// Determines how fast overlapping shapes are pushed apart.
+ /// Expressed as a fraction of the error remaining after each second.
+ /// Defaults to pow(1.0 - 0.1, 60.0) meaning that Chipmunk fixes 10% of overlap each frame at 60Hz.
+ this.collisionBias = Math.pow(1 - 0.1, 60);
+
+ /// Number of frames that contact information should persist.
+ /// Defaults to 3. There is probably never a reason to change this value.
+ this.collisionPersistence = 3;
+
+ /// Rebuild the contact graph during each step. Must be enabled to use the cpBodyEachArbiter() function.
+ /// Disabled by default for a small performance boost. Enabled implicitly when the sleeping feature is enabled.
+ this.enableContactGraph = false;
+
+ /// The designated static body for this space.
+ /// You can modify this body, or replace it with your own static body.
+ /// By default it points to a statically allocated cpBody in the cpSpace struct.
+ this.staticBody = new Body(Infinity, Infinity);
+ this.staticBody.nodeIdleTime = Infinity;
+
+ // Cache the collideShapes callback function for the space.
+ this.collideShapes = this.makeCollideShapes();
+};
+
+Space.prototype.getCurrentTimeStep = function() { return this.curr_dt; };
+
+Space.prototype.setIterations = function(iter) { this.iterations = iter; };
+
+/// returns true from inside a callback and objects cannot be added/removed.
+Space.prototype.isLocked = function()
+{
+ return this.locked;
+};
+
+var assertSpaceUnlocked = function(space)
+{
+ assert(!space.locked, "This addition/removal cannot be done safely during a call to cpSpaceStep() \
+ or during a query. Put these calls into a post-step callback.");
+};
+
+// **** Collision handler function management
+
+/// Set a collision handler to be used whenever the two shapes with the given collision types collide.
+/// You can pass null for any function you don't want to implement.
+Space.prototype.addCollisionHandler = function(a, b, begin, preSolve, postSolve, separate)
+{
+ assertSpaceUnlocked(this);
+
+ // Remove any old function so the new one will get added.
+ this.removeCollisionHandler(a, b);
+
+ var handler = new CollisionHandler();
+ handler.a = a;
+ handler.b = b;
+ if(begin) handler.begin = begin;
+ if(preSolve) handler.preSolve = preSolve;
+ if(postSolve) handler.postSolve = postSolve;
+ if(separate) handler.separate = separate;
+
+ this.collisionHandlers[hashPair(a, b)] = handler;
+};
+
+/// Unset a collision handler.
+Space.prototype.removeCollisionHandler = function(a, b)
+{
+ assertSpaceUnlocked(this);
+
+ delete this.collisionHandlers[hashPair(a, b)];
+};
+
+/// Set a default collision handler for this space.
+/// The default collision handler is invoked for each colliding pair of shapes
+/// that isn't explicitly handled by a specific collision handler.
+/// You can pass null for any function you don't want to implement.
+Space.prototype.setDefaultCollisionHandler = function(begin, preSolve, postSolve, separate)
+{
+ assertSpaceUnlocked(this);
+
+ var handler = new CollisionHandler();
+ if(begin) handler.begin = begin;
+ if(preSolve) handler.preSolve = preSolve;
+ if(postSolve) handler.postSolve = postSolve;
+ if(separate) handler.separate = separate;
+
+ this.defaultHandler = handler;
+};
+
+Space.prototype.lookupHandler = function(a, b)
+{
+ return this.collisionHandlers[hashPair(a, b)] || this.defaultHandler;
+};
+
+// **** Body, Shape, and Joint Management
+
+/// Add a collision shape to the simulation.
+/// If the shape is attached to a static body, it will be added as a static shape.
+Space.prototype.addShape = function(shape)
+{
+ var body = shape.body;
+ if(body.isStatic()) return this.addStaticShape(shape);
+
+ assert(!shape.space, "This shape is already added to a space and cannot be added to another.");
+ assertSpaceUnlocked(this);
+
+ body.activate();
+ body.addShape(shape);
+
+ shape.update(body.p, body.rot);
+ this.activeShapes.insert(shape, shape.hashid);
+ shape.space = this;
+
+ return shape;
+};
+
+/// Explicity add a shape as a static shape to the simulation.
+Space.prototype.addStaticShape = function(shape)
+{
+ assert(!shape.space, "This shape is already added to a space and cannot be added to another.");
+ assertSpaceUnlocked(this);
+
+ var body = shape.body;
+ body.addShape(shape);
+
+ shape.update(body.p, body.rot);
+ this.staticShapes.insert(shape, shape.hashid);
+ shape.space = this;
+
+ return shape;
+};
+
+/// Add a rigid body to the simulation.
+Space.prototype.addBody = function(body)
+{
+ assert(!body.isStatic(), "Static bodies cannot be added to a space as they are not meant to be simulated.");
+ assert(!body.space, "This body is already added to a space and cannot be added to another.");
+ assertSpaceUnlocked(this);
+
+ this.bodies.push(body);
+ body.space = this;
+
+ return body;
+};
+
+/// Add a constraint to the simulation.
+Space.prototype.addConstraint = function(constraint)
+{
+ assert(!constraint.space, "This shape is already added to a space and cannot be added to another.");
+ assertSpaceUnlocked(this);
+
+ var a = constraint.a, b = constraint.b;
+
+ a.activate();
+ b.activate();
+ this.constraints.push(constraint);
+
+ // Push onto the heads of the bodies' constraint lists
+ constraint.next_a = a.constraintList; a.constraintList = constraint;
+ constraint.next_b = b.constraintList; b.constraintList = constraint;
+ constraint.space = this;
+
+ return constraint;
+};
+
+Space.prototype.filterArbiters = function(body, filter)
+{
+ for (var hash in this.cachedArbiters)
+ {
+ var arb = this.cachedArbiters[hash];
+
+ // Match on the filter shape, or if it's null the filter body
+ if(
+ (body === arb.body_a && (filter === arb.a || filter === null)) ||
+ (body === arb.body_b && (filter === arb.b || filter === null))
+ ){
+ // Call separate when removing shapes.
+ if(filter && arb.state !== 'cached') arb.callSeparate(this);
+
+ arb.unthread();
+
+ deleteObjFromList(this.arbiters, arb);
+ //this.pooledArbiters.push(arb);
+
+ delete this.cachedArbiters[hash];
+ }
+ }
+};
+
+/// Remove a collision shape from the simulation.
+Space.prototype.removeShape = function(shape)
+{
+ var body = shape.body;
+ if(body.isStatic()){
+ this.removeStaticShape(shape);
+ } else {
+ assert(this.containsShape(shape),
+ "Cannot remove a shape that was not added to the space. (Removed twice maybe?)");
+ assertSpaceUnlocked(this);
+
+ body.activate();
+ body.removeShape(shape);
+ this.filterArbiters(body, shape);
+ this.activeShapes.remove(shape, shape.hashid);
+ shape.space = null;
+ }
+};
+
+/// Remove a collision shape added using addStaticShape() from the simulation.
+Space.prototype.removeStaticShape = function(shape)
+{
+ assert(this.containsShape(shape),
+ "Cannot remove a static or sleeping shape that was not added to the space. (Removed twice maybe?)");
+ assertSpaceUnlocked(this);
+
+ var body = shape.body;
+ if(body.isStatic()) body.activateStatic(shape);
+ body.removeShape(shape);
+ this.filterArbiters(body, shape);
+ this.staticShapes.remove(shape, shape.hashid);
+ shape.space = null;
+};
+
+/// Remove a rigid body from the simulation.
+Space.prototype.removeBody = function(body)
+{
+ assert(this.containsBody(body),
+ "Cannot remove a body that was not added to the space. (Removed twice maybe?)");
+ assertSpaceUnlocked(this);
+
+ body.activate();
+// this.filterArbiters(body, null);
+ deleteObjFromList(this.bodies, body);
+ body.space = null;
+};
+
+/// Remove a constraint from the simulation.
+Space.prototype.removeConstraint = function(constraint)
+{
+ assert(this.containsConstraint(constraint),
+ "Cannot remove a constraint that was not added to the space. (Removed twice maybe?)");
+ assertSpaceUnlocked(this);
+
+ constraint.a.activate();
+ constraint.b.activate();
+ deleteObjFromList(this.constraints, constraint);
+
+ constraint.a.removeConstraint(constraint);
+ constraint.b.removeConstraint(constraint);
+ constraint.space = null;
+};
+
+/// Test if a collision shape has been added to the space.
+Space.prototype.containsShape = function(shape)
+{
+ return (shape.space === this);
+};
+
+/// Test if a rigid body has been added to the space.
+Space.prototype.containsBody = function(body)
+{
+ return (body.space == this);
+};
+
+/// Test if a constraint has been added to the space.
+Space.prototype.containsConstraint = function(constraint)
+{
+ return (constraint.space == this);
+};
+
+Space.prototype.uncacheArbiter = function(arb)
+{
+ delete this.cachedArbiters[hashPair(arb.a.hashid, arb.b.hashid)];
+ deleteObjFromList(this.arbiters, arb);
+};
+
+
+// **** Iteration
+
+/// Call @c func for each body in the space.
+Space.prototype.eachBody = function(func)
+{
+ this.lock(); {
+ var bodies = this.bodies;
+
+ for(var i=0; i keThreshold ? 0 : body.nodeIdleTime + dt);
+ }
+ }
+
+ // Awaken any sleeping bodies found and then push arbiters to the bodies' lists.
+ var arbiters = this.arbiters;
+ for(var i=0, count=arbiters.length; i= 0, "Internal Error: Space lock underflow.");
+
+ if(this.locked === 0 && runPostStep){
+ var waking = this.rousedBodies;
+ for(var i=0; i this.collisionPersistence){
+ // The tail buffer is available, rotate the ring
+ var tail = head.next;
+ tail.stamp = stamp;
+ tail.contacts.length = 0;
+ this.contactBuffersHead = tail;
+ } else {
+ // Allocate a new buffer and push it into the ring
+ var buffer = new ContactBuffer(stamp, head);
+ this.contactBuffersHead = head.next = buffer;
+ }
+};
+
+cpContact *
+cpContactBufferGetArray(cpSpace *space)
+{
+ if(space.contactBuffersHead.numContacts + CP_MAX_CONTACTS_PER_ARBITER > CP_CONTACTS_BUFFER_SIZE){
+ // contact buffer could overflow on the next collision, push a fresh one.
+ space.pushFreshContactBuffer();
+ }
+
+ cpContactBufferHeader *head = space.contactBuffersHead;
+ return ((cpContactBuffer *)head)->contacts + head.numContacts;
+}
+
+void
+cpSpacePushContacts(cpSpace *space, int count)
+{
+ cpAssertHard(count <= CP_MAX_CONTACTS_PER_ARBITER, "Internal Error: Contact buffer overflow!");
+ space.contactBuffersHead.numContacts += count;
+}
+
+static void
+cpSpacePopContacts(cpSpace *space, int count){
+ space.contactBuffersHead.numContacts -= count;
+}
+*/
+
+// **** Collision Detection Functions
+
+/* Use this to re-enable object pools.
+static void *
+cpSpaceArbiterSetTrans(cpShape **shapes, cpSpace *space)
+{
+ if(space.pooledArbiters.num == 0){
+ // arbiter pool is exhausted, make more
+ int count = CP_BUFFER_BYTES/sizeof(cpArbiter);
+ cpAssertHard(count, "Internal Error: Buffer size too small.");
+
+ cpArbiter *buffer = (cpArbiter *)cpcalloc(1, CP_BUFFER_BYTES);
+ cpArrayPush(space.allocatedBuffers, buffer);
+
+ for(int i=0; i b.collisionCode){
+ var temp = a;
+ a = b;
+ b = temp;
+ }
+
+ // Narrow-phase collision detection.
+ //cpContact *contacts = cpContactBufferGetArray(space);
+ //int numContacts = cpCollideShapes(a, b, contacts);
+ var contacts = collideShapes(a, b);
+ if(contacts.length === 0) return; // Shapes are not colliding.
+ //cpSpacePushContacts(space, numContacts);
+
+ // Get an arbiter from space.arbiterSet for the two shapes.
+ // This is where the persistent contact magic comes from.
+ var arbHash = hashPair(a.hashid, b.hashid);
+ var arb = space.cachedArbiters[arbHash];
+ if (!arb){
+ arb = space.cachedArbiters[arbHash] = new Arbiter(a, b);
+ }
+
+ arb.update(contacts, handler, a, b);
+
+ // Call the begin function first if it's the first step
+ if(arb.state == 'first coll' && !handler.begin(arb, space)){
+ arb.ignore(); // permanently ignore the collision until separation
+ }
+
+ if(
+ // Ignore the arbiter if it has been flagged
+ (arb.state !== 'ignore') &&
+ // Call preSolve
+ handler.preSolve(arb, space) &&
+ // Process, but don't add collisions for sensors.
+ !sensor
+ ){
+ space.arbiters.push(arb);
+ } else {
+ //cpSpacePopContacts(space, numContacts);
+
+ arb.contacts = null;
+
+ // Normally arbiters are set as used after calling the post-solve callback.
+ // However, post-solve callbacks are not called for sensors or arbiters rejected from pre-solve.
+ if(arb.state !== 'ignore') arb.state = 'normal';
+ }
+
+ // Time stamp the arbiter so we know it was used recently.
+ arb.stamp = space.stamp;
+ };
+};
+
+// Hashset filter func to throw away old arbiters.
+Space.prototype.arbiterSetFilter = function(arb)
+{
+ var ticks = this.stamp - arb.stamp;
+
+ var a = arb.body_a, b = arb.body_b;
+
+ // TODO should make an arbiter state for this so it doesn't require filtering arbiters for
+ // dangling body pointers on body removal.
+ // Preserve arbiters on sensors and rejected arbiters for sleeping objects.
+ // This prevents errant separate callbacks from happenening.
+ if(
+ (a.isStatic() || a.isSleeping()) &&
+ (b.isStatic() || b.isSleeping())
+ ){
+ return true;
+ }
+
+ // Arbiter was used last frame, but not this one
+ if(ticks >= 1 && arb.state != 'cached'){
+ arb.callSeparate(this);
+ arb.state = 'cached';
+ }
+
+ if(ticks >= this.collisionPersistence){
+ arb.contacts = null;
+
+ //cpArrayPush(this.pooledArbiters, arb);
+ return false;
+ }
+
+ return true;
+};
+
+// **** All Important cpSpaceStep() Function
+
+var updateFunc = function(shape)
+{
+ var body = shape.body;
+ shape.update(body.p, body.rot);
+};
+
+/// Step the space forward in time by @c dt.
+Space.prototype.step = function(dt)
+{
+ // don't step if the timestep is 0!
+ if(dt === 0) return;
+
+ assert(vzero.x === 0 && vzero.y === 0, "vzero is invalid");
+
+ this.stamp++;
+
+ var prev_dt = this.curr_dt;
+ this.curr_dt = dt;
+
+ var i;
+ var j;
+ var hash;
+ var bodies = this.bodies;
+ var constraints = this.constraints;
+ var arbiters = this.arbiters;
+
+ // Reset and empty the arbiter lists.
+ for(i=0; imaxForce*(dt))
+
+// a and b are bodies.
+var relative_velocity = function(a, b, r1, r2){
+ //var v1_sum = vadd(a.v, vmult(vperp(r1), a.w));
+ var v1_sumx = a.vx + (-r1.y) * a.w;
+ var v1_sumy = a.vy + ( r1.x) * a.w;
+
+ //var v2_sum = vadd(b.v, vmult(vperp(r2), b.w));
+ var v2_sumx = b.vx + (-r2.y) * b.w;
+ var v2_sumy = b.vy + ( r2.x) * b.w;
+
+// return vsub(v2_sum, v1_sum);
+ return new Vect(v2_sumx - v1_sumx, v2_sumy - v1_sumy);
+};
+
+var normal_relative_velocity = function(a, b, r1, r2, n){
+ //return vdot(relative_velocity(a, b, r1, r2), n);
+ var v1_sumx = a.vx + (-r1.y) * a.w;
+ var v1_sumy = a.vy + ( r1.x) * a.w;
+ var v2_sumx = b.vx + (-r2.y) * b.w;
+ var v2_sumy = b.vy + ( r2.x) * b.w;
+
+ return vdot2(v2_sumx - v1_sumx, v2_sumy - v1_sumy, n.x, n.y);
+};
+
+/*
+var apply_impulse = function(body, j, r){
+ body.v = vadd(body.v, vmult(j, body.m_inv));
+ body.w += body.i_inv*vcross(r, j);
+};
+
+var apply_impulses = function(a, b, r1, r2, j)
+{
+ apply_impulse(a, vneg(j), r1);
+ apply_impulse(b, j, r2);
+};
+*/
+
+var apply_impulse = function(body, jx, jy, r){
+// body.v = body.v.add(vmult(j, body.m_inv));
+ body.vx += jx * body.m_inv;
+ body.vy += jy * body.m_inv;
+// body.w += body.i_inv*vcross(r, j);
+ body.w += body.i_inv*(r.x*jy - r.y*jx);
+};
+
+var apply_impulses = function(a, b, r1, r2, jx, jy)
+{
+ apply_impulse(a, -jx, -jy, r1);
+ apply_impulse(b, jx, jy, r2);
+};
+
+var apply_bias_impulse = function(body, jx, jy, r)
+{
+ //body.v_bias = vadd(body.v_bias, vmult(j, body.m_inv));
+ body.v_biasx += jx * body.m_inv;
+ body.v_biasy += jy * body.m_inv;
+ body.w_bias += body.i_inv*vcross2(r.x, r.y, jx, jy);
+};
+
+/*
+var apply_bias_impulses = function(a, b, r1, r2, j)
+{
+ apply_bias_impulse(a, vneg(j), r1);
+ apply_bias_impulse(b, j, r2);
+};*/
+
+var k_scalar_body = function(body, r, n)
+{
+ var rcn = vcross(r, n);
+ return body.m_inv + body.i_inv*rcn*rcn;
+};
+
+var k_scalar = function(a, b, r1, r2, n)
+{
+ var value = k_scalar_body(a, r1, n) + k_scalar_body(b, r2, n);
+ assertSoft(value !== 0, "Unsolvable collision or constraint.");
+
+ return value;
+};
+
+// k1 and k2 are modified by the function to contain the outputs.
+var k_tensor = function(a, b, r1, r2, k1, k2)
+{
+ // calculate mass matrix
+ // If I wasn't lazy and wrote a proper matrix class, this wouldn't be so gross...
+ var k11, k12, k21, k22;
+ var m_sum = a.m_inv + b.m_inv;
+
+ // start with I*m_sum
+ k11 = m_sum; k12 = 0;
+ k21 = 0; k22 = m_sum;
+
+ // add the influence from r1
+ var a_i_inv = a.i_inv;
+ var r1xsq = r1.x * r1.x * a_i_inv;
+ var r1ysq = r1.y * r1.y * a_i_inv;
+ var r1nxy = -r1.x * r1.y * a_i_inv;
+ k11 += r1ysq; k12 += r1nxy;
+ k21 += r1nxy; k22 += r1xsq;
+
+ // add the influnce from r2
+ var b_i_inv = b.i_inv;
+ var r2xsq = r2.x * r2.x * b_i_inv;
+ var r2ysq = r2.y * r2.y * b_i_inv;
+ var r2nxy = -r2.x * r2.y * b_i_inv;
+ k11 += r2ysq; k12 += r2nxy;
+ k21 += r2nxy; k22 += r2xsq;
+
+ // invert
+ var determinant = k11*k22 - k12*k21;
+ assertSoft(determinant !== 0, "Unsolvable constraint.");
+
+ var det_inv = 1/determinant;
+
+ k1.x = k22*det_inv; k1.y = -k12*det_inv;
+ k2.x = -k21*det_inv; k2.y = k11*det_inv;
+};
+
+var mult_k = function(vr, k1, k2)
+{
+ return new Vect(vdot(vr, k1), vdot(vr, k2));
+};
+
+var bias_coef = function(errorBias, dt)
+{
+ return 1 - Math.pow(errorBias, dt);
+};
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+// TODO: Comment me!
+
+// a and b are bodies that the constraint applies to.
+var Constraint = cp.Constraint = function(a, b)
+{
+ /// The first body connected to this constraint.
+ this.a = a;
+ /// The second body connected to this constraint.
+ this.b = b;
+
+ this.space = null;
+
+ this.next_a = null;
+ this.next_b = null;
+
+ /// The maximum force that this constraint is allowed to use.
+ this.maxForce = Infinity;
+ /// The rate at which joint error is corrected.
+ /// Defaults to pow(1 - 0.1, 60) meaning that it will
+ /// correct 10% of the error every 1/60th of a second.
+ this.errorBias = Math.pow(1 - 0.1, 60);
+ /// The maximum rate at which joint error is corrected.
+ this.maxBias = Infinity;
+};
+
+Constraint.prototype.activateBodies = function()
+{
+ if(this.a) this.a.activate();
+ if(this.b) this.b.activate();
+};
+
+/// These methods are overridden by the constraint itself.
+Constraint.prototype.preStep = function(dt) {};
+Constraint.prototype.applyCachedImpulse = function(dt_coef) {};
+Constraint.prototype.applyImpulse = function() {};
+Constraint.prototype.getImpulse = function() { return 0; };
+
+/// Function called before the solver runs. This can be overridden by the user
+/// to customize the constraint.
+/// Animate your joint anchors, update your motor torque, etc.
+Constraint.prototype.preSolve = function(space) {};
+
+/// Function called after the solver runs. This can be overridden by the user
+/// to customize the constraint.
+/// Use the applied impulse to perform effects like breakable joints.
+Constraint.prototype.postSolve = function(space) {};
+
+Constraint.prototype.next = function(body)
+{
+ return (this.a === body ? this.next_a : this.next_b);
+};
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+var PinJoint = cp.PinJoint = function(a, b, anchr1, anchr2)
+{
+ Constraint.call(this, a, b);
+
+ this.anchr1 = anchr1;
+ this.anchr2 = anchr2;
+
+ // STATIC_BODY_CHECK
+ var p1 = (a ? vadd(a.p, vrotate(anchr1, a.rot)) : anchr1);
+ var p2 = (b ? vadd(b.p, vrotate(anchr2, b.rot)) : anchr2);
+ this.dist = vlength(vsub(p2, p1));
+
+ assertSoft(this.dist > 0, "You created a 0 length pin joint. A pivot joint will be much more stable.");
+
+ this.r1 = this.r2 = null;
+ this.n = null;
+ this.nMass = 0;
+
+ this.jnAcc = this.jnMax = 0;
+ this.bias = 0;
+};
+
+PinJoint.prototype = Object.create(Constraint.prototype);
+
+PinJoint.prototype.preStep = function(dt)
+{
+ var a = this.a;
+ var b = this.b;
+
+ this.r1 = vrotate(this.anchr1, a.rot);
+ this.r2 = vrotate(this.anchr2, b.rot);
+
+ var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1));
+ var dist = vlength(delta);
+ this.n = vmult(delta, 1/(dist ? dist : Infinity));
+
+ // calculate mass normal
+ this.nMass = 1/k_scalar(a, b, this.r1, this.r2, this.n);
+
+ // calculate bias velocity
+ var maxBias = this.maxBias;
+ this.bias = clamp(-bias_coef(this.errorBias, dt)*(dist - this.dist)/dt, -maxBias, maxBias);
+
+ // compute max impulse
+ this.jnMax = this.maxForce * dt;
+};
+
+PinJoint.prototype.applyCachedImpulse = function(dt_coef)
+{
+ var j = vmult(this.n, this.jnAcc*dt_coef);
+ apply_impulses(this.a, this.b, this.r1, this.r2, j.x, j.y);
+};
+
+PinJoint.prototype.applyImpulse = function()
+{
+ var a = this.a;
+ var b = this.b;
+ var n = this.n;
+
+ // compute relative velocity
+ var vrn = normal_relative_velocity(a, b, this.r1, this.r2, n);
+
+ // compute normal impulse
+ var jn = (this.bias - vrn)*this.nMass;
+ var jnOld = this.jnAcc;
+ this.jnAcc = clamp(jnOld + jn, -this.jnMax, this.jnMax);
+ jn = this.jnAcc - jnOld;
+
+ // apply impulse
+ apply_impulses(a, b, this.r1, this.r2, n.x*jn, n.y*jn);
+};
+
+PinJoint.prototype.getImpulse = function()
+{
+ return Math.abs(this.jnAcc);
+};
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+var SlideJoint = cp.SlideJoint = function(a, b, anchr1, anchr2, min, max)
+{
+ Constraint.call(this, a, b);
+
+ this.anchr1 = anchr1;
+ this.anchr2 = anchr2;
+ this.min = min;
+ this.max = max;
+
+ this.r1 = this.r2 = this.n = null;
+ this.nMass = 0;
+
+ this.jnAcc = this.jnMax = 0;
+ this.bias = 0;
+};
+
+SlideJoint.prototype = Object.create(Constraint.prototype);
+
+SlideJoint.prototype.preStep = function(dt)
+{
+ var a = this.a;
+ var b = this.b;
+
+ this.r1 = vrotate(this.anchr1, a.rot);
+ this.r2 = vrotate(this.anchr2, b.rot);
+
+ var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1));
+ var dist = vlength(delta);
+ var pdist = 0;
+ if(dist > this.max) {
+ pdist = dist - this.max;
+ this.n = vnormalize_safe(delta);
+ } else if(dist < this.min) {
+ pdist = this.min - dist;
+ this.n = vneg(vnormalize_safe(delta));
+ } else {
+ this.n = vzero;
+ this.jnAcc = 0;
+ }
+
+ // calculate mass normal
+ this.nMass = 1/k_scalar(a, b, this.r1, this.r2, this.n);
+
+ // calculate bias velocity
+ var maxBias = this.maxBias;
+ this.bias = clamp(-bias_coef(this.errorBias, dt)*pdist/dt, -maxBias, maxBias);
+
+ // compute max impulse
+ this.jnMax = this.maxForce * dt;
+};
+
+SlideJoint.prototype.applyCachedImpulse = function(dt_coef)
+{
+ var jn = this.jnAcc * dt_coef;
+ apply_impulses(this.a, this.b, this.r1, this.r2, this.n.x * jn, this.n.y * jn);
+};
+
+SlideJoint.prototype.applyImpulse = function()
+{
+ if(this.n.x === 0 && this.n.y === 0) return; // early exit
+
+ var a = this.a;
+ var b = this.b;
+
+ var n = this.n;
+ var r1 = this.r1;
+ var r2 = this.r2;
+
+ // compute relative velocity
+ var vr = relative_velocity(a, b, r1, r2);
+ var vrn = vdot(vr, n);
+
+ // compute normal impulse
+ var jn = (this.bias - vrn)*this.nMass;
+ var jnOld = this.jnAcc;
+ this.jnAcc = clamp(jnOld + jn, -this.jnMax, 0);
+ jn = this.jnAcc - jnOld;
+
+ // apply impulse
+ apply_impulses(a, b, this.r1, this.r2, n.x * jn, n.y * jn);
+};
+
+SlideJoint.prototype.getImpulse = function()
+{
+ return Math.abs(this.jnAcc);
+};
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+// Pivot joints can also be created with (a, b, pivot);
+var PivotJoint = cp.PivotJoint = function(a, b, anchr1, anchr2)
+{
+ Constraint.call(this, a, b);
+
+ if(typeof anchr2 === 'undefined') {
+ var pivot = anchr1;
+
+ anchr1 = (a ? a.world2Local(pivot) : pivot);
+ anchr2 = (b ? b.world2Local(pivot) : pivot);
+ }
+
+ this.anchr1 = anchr1;
+ this.anchr2 = anchr2;
+
+ this.r1 = this.r2 = vzero;
+
+ this.k1 = new Vect(0,0); this.k2 = new Vect(0,0);
+
+ this.jAcc = vzero;
+
+ this.jMaxLen = 0;
+ this.bias = vzero;
+};
+
+PivotJoint.prototype = Object.create(Constraint.prototype);
+
+PivotJoint.prototype.preStep = function(dt)
+{
+ var a = this.a;
+ var b = this.b;
+
+ this.r1 = vrotate(this.anchr1, a.rot);
+ this.r2 = vrotate(this.anchr2, b.rot);
+
+ // Calculate mass tensor. Result is stored into this.k1 & this.k2.
+ k_tensor(a, b, this.r1, this.r2, this.k1, this.k2);
+
+ // compute max impulse
+ this.jMaxLen = this.maxForce * dt;
+
+ // calculate bias velocity
+ var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1));
+ this.bias = vclamp(vmult(delta, -bias_coef(this.errorBias, dt)/dt), this.maxBias);
+};
+
+PivotJoint.prototype.applyCachedImpulse = function(dt_coef)
+{
+ apply_impulses(this.a, this.b, this.r1, this.r2, this.jAcc.x * dt_coef, this.jAcc.y * dt_coef);
+};
+
+PivotJoint.prototype.applyImpulse = function()
+{
+ var a = this.a;
+ var b = this.b;
+
+ var r1 = this.r1;
+ var r2 = this.r2;
+
+ // compute relative velocity
+ var vr = relative_velocity(a, b, r1, r2);
+
+ // compute normal impulse
+ var j = mult_k(vsub(this.bias, vr), this.k1, this.k2);
+ var jOld = this.jAcc;
+ this.jAcc = vclamp(vadd(this.jAcc, j), this.jMaxLen);
+
+ // apply impulse
+ apply_impulses(a, b, this.r1, this.r2, this.jAcc.x - jOld.x, this.jAcc.y - jOld.y);
+};
+
+PivotJoint.prototype.getImpulse = function()
+{
+ return vlength(this.jAcc);
+};
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+var GrooveJoint = cp.GrooveJoint = function(a, b, groove_a, groove_b, anchr2)
+{
+ Constraint.call(this, a, b);
+
+ this.grv_a = groove_a;
+ this.grv_b = groove_b;
+ this.grv_n = vperp(vnormalize(vsub(groove_b, groove_a)));
+ this.anchr2 = anchr2;
+
+ this.grv_tn = null;
+ this.clamp = 0;
+ this.r1 = this.r2 = null;
+
+ this.k1 = new Vect(0,0);
+ this.k2 = new Vect(0,0);
+
+ this.jAcc = vzero;
+ this.jMaxLen = 0;
+ this.bias = null;
+};
+
+GrooveJoint.prototype = Object.create(Constraint.prototype);
+
+GrooveJoint.prototype.preStep = function(dt)
+{
+ var a = this.a;
+ var b = this.b;
+
+ // calculate endpoints in worldspace
+ var ta = a.local2World(this.grv_a);
+ var tb = a.local2World(this.grv_b);
+
+ // calculate axis
+ var n = vrotate(this.grv_n, a.rot);
+ var d = vdot(ta, n);
+
+ this.grv_tn = n;
+ this.r2 = vrotate(this.anchr2, b.rot);
+
+ // calculate tangential distance along the axis of r2
+ var td = vcross(vadd(b.p, this.r2), n);
+ // calculate clamping factor and r2
+ if(td <= vcross(ta, n)){
+ this.clamp = 1;
+ this.r1 = vsub(ta, a.p);
+ } else if(td >= vcross(tb, n)){
+ this.clamp = -1;
+ this.r1 = vsub(tb, a.p);
+ } else {
+ this.clamp = 0;
+ this.r1 = vsub(vadd(vmult(vperp(n), -td), vmult(n, d)), a.p);
+ }
+
+ // Calculate mass tensor
+ k_tensor(a, b, this.r1, this.r2, this.k1, this.k2);
+
+ // compute max impulse
+ this.jMaxLen = this.maxForce * dt;
+
+ // calculate bias velocity
+ var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1));
+ this.bias = vclamp(vmult(delta, -bias_coef(this.errorBias, dt)/dt), this.maxBias);
+};
+
+GrooveJoint.prototype.applyCachedImpulse = function(dt_coef)
+{
+ apply_impulses(this.a, this.b, this.r1, this.r2, this.jAcc.x * dt_coef, this.jAcc.y * dt_coef);
+};
+
+GrooveJoint.prototype.grooveConstrain = function(j){
+ var n = this.grv_tn;
+ var jClamp = (this.clamp*vcross(j, n) > 0) ? j : vproject(j, n);
+ return vclamp(jClamp, this.jMaxLen);
+};
+
+GrooveJoint.prototype.applyImpulse = function()
+{
+ var a = this.a;
+ var b = this.b;
+
+ var r1 = this.r1;
+ var r2 = this.r2;
+
+ // compute impulse
+ var vr = relative_velocity(a, b, r1, r2);
+
+ var j = mult_k(vsub(this.bias, vr), this.k1, this.k2);
+ var jOld = this.jAcc;
+ this.jAcc = this.grooveConstrain(vadd(jOld, j));
+
+ // apply impulse
+ apply_impulses(a, b, this.r1, this.r2, this.jAcc.x - jOld.x, this.jAcc.y - jOld.y);
+};
+
+GrooveJoint.prototype.getImpulse = function()
+{
+ return vlength(this.jAcc);
+};
+
+GrooveJoint.prototype.setGrooveA = function(value)
+{
+ this.grv_a = value;
+ this.grv_n = vperp(vnormalize(vsub(this.grv_b, value)));
+
+ this.activateBodies();
+};
+
+GrooveJoint.prototype.setGrooveB = function(value)
+{
+ this.grv_b = value;
+ this.grv_n = vperp(vnormalize(vsub(value, this.grv_a)));
+
+ this.activateBodies();
+};
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+var defaultSpringForce = function(spring, dist){
+ return (spring.restLength - dist)*spring.stiffness;
+};
+
+var DampedSpring = cp.DampedSpring = function(a, b, anchr1, anchr2, restLength, stiffness, damping)
+{
+ Constraint.call(this, a, b);
+
+ this.anchr1 = anchr1;
+ this.anchr2 = anchr2;
+
+ this.restLength = restLength;
+ this.stiffness = stiffness;
+ this.damping = damping;
+ this.springForceFunc = defaultSpringForce;
+
+ this.target_vrn = this.v_coef = 0;
+
+ this.r1 = this.r2 = null;
+ this.nMass = 0;
+ this.n = null;
+};
+
+DampedSpring.prototype = Object.create(Constraint.prototype);
+
+DampedSpring.prototype.preStep = function(dt)
+{
+ var a = this.a;
+ var b = this.b;
+
+ this.r1 = vrotate(this.anchr1, a.rot);
+ this.r2 = vrotate(this.anchr2, b.rot);
+
+ var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1));
+ var dist = vlength(delta);
+ this.n = vmult(delta, 1/(dist ? dist : Infinity));
+
+ var k = k_scalar(a, b, this.r1, this.r2, this.n);
+ assertSoft(k !== 0, "Unsolvable this.");
+ this.nMass = 1/k;
+
+ this.target_vrn = 0;
+ this.v_coef = 1 - Math.exp(-this.damping*dt*k);
+
+ // apply this force
+ var f_spring = this.springForceFunc(this, dist);
+ apply_impulses(a, b, this.r1, this.r2, this.n.x * f_spring * dt, this.n.y * f_spring * dt);
+};
+
+DampedSpring.prototype.applyCachedImpulse = function(dt_coef){};
+
+DampedSpring.prototype.applyImpulse = function()
+{
+ var a = this.a;
+ var b = this.b;
+
+ var n = this.n;
+ var r1 = this.r1;
+ var r2 = this.r2;
+
+ // compute relative velocity
+ var vrn = normal_relative_velocity(a, b, r1, r2, n);
+
+ // compute velocity loss from drag
+ var v_damp = (this.target_vrn - vrn)*this.v_coef;
+ this.target_vrn = vrn + v_damp;
+
+ v_damp *= this.nMass;
+ apply_impulses(a, b, this.r1, this.r2, this.n.x * v_damp, this.n.y * v_damp);
+};
+
+DampedSpring.prototype.getImpulse = function()
+{
+ return 0;
+};
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+var defaultSpringTorque = function(spring, relativeAngle){
+ return (relativeAngle - spring.restAngle)*spring.stiffness;
+}
+
+var DampedRotarySpring = cp.DampedRotarySpring = function(a, b, restAngle, stiffness, damping)
+{
+ Constraint.call(this, a, b);
+
+ this.restAngle = restAngle;
+ this.stiffness = stiffness;
+ this.damping = damping;
+ this.springTorqueFunc = defaultSpringTorque;
+
+ this.target_wrn = 0;
+ this.w_coef = 0;
+ this.iSum = 0;
+};
+
+DampedRotarySpring.prototype = Object.create(Constraint.prototype);
+
+DampedRotarySpring.prototype.preStep = function(dt)
+{
+ var a = this.a;
+ var b = this.b;
+
+ var moment = a.i_inv + b.i_inv;
+ assertSoft(moment !== 0, "Unsolvable spring.");
+ this.iSum = 1/moment;
+
+ this.w_coef = 1 - Math.exp(-this.damping*dt*moment);
+ this.target_wrn = 0;
+
+ // apply this torque
+ var j_spring = this.springTorqueFunc(this, a.a - b.a)*dt;
+ a.w -= j_spring*a.i_inv;
+ b.w += j_spring*b.i_inv;
+};
+
+// DampedRotarySpring.prototype.applyCachedImpulse = function(dt_coef){};
+
+DampedRotarySpring.prototype.applyImpulse = function()
+{
+ var a = this.a;
+ var b = this.b;
+
+ // compute relative velocity
+ var wrn = a.w - b.w;//normal_relative_velocity(a, b, r1, r2, n) - this.target_vrn;
+
+ // compute velocity loss from drag
+ // not 100% certain spring is derived correctly, though it makes sense
+ var w_damp = (this.target_wrn - wrn)*this.w_coef;
+ this.target_wrn = wrn + w_damp;
+
+ //apply_impulses(a, b, this.r1, this.r2, vmult(this.n, v_damp*this.nMass));
+ var j_damp = w_damp*this.iSum;
+ a.w += j_damp*a.i_inv;
+ b.w -= j_damp*b.i_inv;
+};
+
+// DampedRotarySpring.prototype.getImpulse = function(){ return 0; };
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+var RotaryLimitJoint = cp.RotaryLimitJoint = function(a, b, min, max)
+{
+ Constraint.call(this, a, b);
+
+ this.min = min;
+ this.max = max;
+
+ this.jAcc = 0;
+
+ this.iSum = this.bias = this.jMax = 0;
+};
+
+RotaryLimitJoint.prototype = Object.create(Constraint.prototype);
+
+RotaryLimitJoint.prototype.preStep = function(dt)
+{
+ var a = this.a;
+ var b = this.b;
+
+ var dist = b.a - a.a;
+ var pdist = 0;
+ if(dist > this.max) {
+ pdist = this.max - dist;
+ } else if(dist < this.min) {
+ pdist = this.min - dist;
+ }
+
+ // calculate moment of inertia coefficient.
+ this.iSum = 1/(1/a.i + 1/b.i);
+
+ // calculate bias velocity
+ var maxBias = this.maxBias;
+ this.bias = clamp(-bias_coef(this.errorBias, dt)*pdist/dt, -maxBias, maxBias);
+
+ // compute max impulse
+ this.jMax = this.maxForce * dt;
+
+ // If the bias is 0, the joint is not at a limit. Reset the impulse.
+ if(!this.bias) this.jAcc = 0;
+};
+
+RotaryLimitJoint.prototype.applyCachedImpulse = function(dt_coef)
+{
+ var a = this.a;
+ var b = this.b;
+
+ var j = this.jAcc*dt_coef;
+ a.w -= j*a.i_inv;
+ b.w += j*b.i_inv;
+};
+
+RotaryLimitJoint.prototype.applyImpulse = function()
+{
+ if(!this.bias) return; // early exit
+
+ var a = this.a;
+ var b = this.b;
+
+ // compute relative rotational velocity
+ var wr = b.w - a.w;
+
+ // compute normal impulse
+ var j = -(this.bias + wr)*this.iSum;
+ var jOld = this.jAcc;
+ if(this.bias < 0){
+ this.jAcc = clamp(jOld + j, 0, this.jMax);
+ } else {
+ this.jAcc = clamp(jOld + j, -this.jMax, 0);
+ }
+ j = this.jAcc - jOld;
+
+ // apply impulse
+ a.w -= j*a.i_inv;
+ b.w += j*b.i_inv;
+};
+
+RotaryLimitJoint.prototype.getImpulse = function()
+{
+ return Math.abs(joint.jAcc);
+};
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+var RatchetJoint = cp.RatchetJoint = function(a, b, phase, ratchet)
+{
+ Constraint.call(this, a, b);
+
+ this.angle = 0;
+ this.phase = phase;
+ this.ratchet = ratchet;
+
+ // STATIC_BODY_CHECK
+ this.angle = (b ? b.a : 0) - (a ? a.a : 0);
+
+ this.iSum = this.bias = this.jAcc = this.jMax = 0;
+};
+
+RatchetJoint.prototype = Object.create(Constraint.prototype);
+
+RatchetJoint.prototype.preStep = function(dt)
+{
+ var a = this.a;
+ var b = this.b;
+
+ var angle = this.angle;
+ var phase = this.phase;
+ var ratchet = this.ratchet;
+
+ var delta = b.a - a.a;
+ var diff = angle - delta;
+ var pdist = 0;
+
+ if(diff*ratchet > 0){
+ pdist = diff;
+ } else {
+ this.angle = Math.floor((delta - phase)/ratchet)*ratchet + phase;
+ }
+
+ // calculate moment of inertia coefficient.
+ this.iSum = 1/(a.i_inv + b.i_inv);
+
+ // calculate bias velocity
+ var maxBias = this.maxBias;
+ this.bias = clamp(-bias_coef(this.errorBias, dt)*pdist/dt, -maxBias, maxBias);
+
+ // compute max impulse
+ this.jMax = this.maxForce * dt;
+
+ // If the bias is 0, the joint is not at a limit. Reset the impulse.
+ if(!this.bias) this.jAcc = 0;
+};
+
+RatchetJoint.prototype.applyCachedImpulse = function(dt_coef)
+{
+ var a = this.a;
+ var b = this.b;
+
+ var j = this.jAcc*dt_coef;
+ a.w -= j*a.i_inv;
+ b.w += j*b.i_inv;
+};
+
+RatchetJoint.prototype.applyImpulse = function()
+{
+ if(!this.bias) return; // early exit
+
+ var a = this.a;
+ var b = this.b;
+
+ // compute relative rotational velocity
+ var wr = b.w - a.w;
+ var ratchet = this.ratchet;
+
+ // compute normal impulse
+ var j = -(this.bias + wr)*this.iSum;
+ var jOld = this.jAcc;
+ this.jAcc = clamp((jOld + j)*ratchet, 0, this.jMax*Math.abs(ratchet))/ratchet;
+ j = this.jAcc - jOld;
+
+ // apply impulse
+ a.w -= j*a.i_inv;
+ b.w += j*b.i_inv;
+};
+
+RatchetJoint.prototype.getImpulse = function(joint)
+{
+ return Math.abs(joint.jAcc);
+};
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+var GearJoint = cp.GearJoint = function(a, b, phase, ratio)
+{
+ Constraint.call(this, a, b);
+
+ this.phase = phase;
+ this.ratio = ratio;
+ this.ratio_inv = 1/ratio;
+
+ this.jAcc = 0;
+
+ this.iSum = this.bias = this.jMax = 0;
+};
+
+GearJoint.prototype = Object.create(Constraint.prototype);
+
+GearJoint.prototype.preStep = function(dt)
+{
+ var a = this.a;
+ var b = this.b;
+
+ // calculate moment of inertia coefficient.
+ this.iSum = 1/(a.i_inv*this.ratio_inv + this.ratio*b.i_inv);
+
+ // calculate bias velocity
+ var maxBias = this.maxBias;
+ this.bias = clamp(-bias_coef(this.errorBias, dt)*(b.a*this.ratio - a.a - this.phase)/dt, -maxBias, maxBias);
+
+ // compute max impulse
+ this.jMax = this.maxForce * dt;
+};
+
+GearJoint.prototype.applyCachedImpulse = function(dt_coef)
+{
+ var a = this.a;
+ var b = this.b;
+
+ var j = this.jAcc*dt_coef;
+ a.w -= j*a.i_inv*this.ratio_inv;
+ b.w += j*b.i_inv;
+};
+
+GearJoint.prototype.applyImpulse = function()
+{
+ var a = this.a;
+ var b = this.b;
+
+ // compute relative rotational velocity
+ var wr = b.w*this.ratio - a.w;
+
+ // compute normal impulse
+ var j = (this.bias - wr)*this.iSum;
+ var jOld = this.jAcc;
+ this.jAcc = clamp(jOld + j, -this.jMax, this.jMax);
+ j = this.jAcc - jOld;
+
+ // apply impulse
+ a.w -= j*a.i_inv*this.ratio_inv;
+ b.w += j*b.i_inv;
+};
+
+GearJoint.prototype.getImpulse = function()
+{
+ return Math.abs(this.jAcc);
+};
+
+GearJoint.prototype.setRatio = function(value)
+{
+ this.ratio = value;
+ this.ratio_inv = 1/value;
+ this.activateBodies();
+};
+
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+var SimpleMotor = cp.SimpleMotor = function(a, b, rate)
+{
+ Constraint.call(this, a, b);
+
+ this.rate = rate;
+
+ this.jAcc = 0;
+
+ this.iSum = this.jMax = 0;
+};
+
+SimpleMotor.prototype = Object.create(Constraint.prototype);
+
+SimpleMotor.prototype.preStep = function(dt)
+{
+ // calculate moment of inertia coefficient.
+ this.iSum = 1/(this.a.i_inv + this.b.i_inv);
+
+ // compute max impulse
+ this.jMax = this.maxForce * dt;
+};
+
+SimpleMotor.prototype.applyCachedImpulse = function(dt_coef)
+{
+ var a = this.a;
+ var b = this.b;
+
+ var j = this.jAcc*dt_coef;
+ a.w -= j*a.i_inv;
+ b.w += j*b.i_inv;
+};
+
+SimpleMotor.prototype.applyImpulse = function()
+{
+ var a = this.a;
+ var b = this.b;
+
+ // compute relative rotational velocity
+ var wr = b.w - a.w + this.rate;
+
+ // compute normal impulse
+ var j = -wr*this.iSum;
+ var jOld = this.jAcc;
+ this.jAcc = clamp(jOld + j, -this.jMax, this.jMax);
+ j = this.jAcc - jOld;
+
+ // apply impulse
+ a.w -= j*a.i_inv;
+ b.w += j*b.i_inv;
+};
+
+SimpleMotor.prototype.getImpulse = function()
+{
+ return Math.abs(this.jAcc);
+};
+
+})();
diff --git a/frameworks/cocos2d-html5/external/gaf/GAFBoot.js b/frameworks/cocos2d-html5/external/gaf/GAFBoot.js
new file mode 100644
index 0000000..0baccc7
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/GAFBoot.js
@@ -0,0 +1,24 @@
+var gaf = gaf || {};
+gaf._tmp = gaf._tmp || {};
+gaf._initialized = false;
+
+gaf.CCGAFLoader = function()
+{
+ this.load = function(realUrl, url, item, cb)
+ {
+ if(!gaf._initialized)
+ {
+ gaf._setup();
+ }
+ var loader = new gaf.Loader();
+ loader.LoadFile(realUrl, function(data){cb(null, data)});
+ };
+};
+
+gaf._setup = function()
+{
+ gaf._setupShaders();
+ gaf._initialized = true;
+};
+
+cc.loader.register('.gaf', new gaf.CCGAFLoader());
diff --git a/frameworks/cocos2d-html5/external/gaf/GAFMacros.js b/frameworks/cocos2d-html5/external/gaf/GAFMacros.js
new file mode 100644
index 0000000..ef34cc8
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/GAFMacros.js
@@ -0,0 +1,33 @@
+var gaf = gaf || {};
+
+gaf.COMPRESSION_NONE = 0x00474146;
+gaf.COMPRESSION_ZIP = 0x00474143;
+
+gaf.IDNONE = 0xffffffff;
+gaf.FIRST_FRAME_INDEX = 0;
+
+gaf.EFFECT_DROP_SHADOW = 0;
+gaf.EFFECT_BLUR = 1;
+gaf.EFFECT_GLOW = 2;
+gaf.EFFECT_COLOR_MATRIX = 6;
+
+gaf.ACTION_STOP = 0;
+gaf.ACTION_PLAY = 1;
+gaf.ACTION_GO_TO_AND_STOP = 2;
+gaf.ACTION_GO_TO_AND_PLAY = 3;
+gaf.ACTION_DISPATCH_EVENT = 4;
+
+gaf.PI_FRAME = 0;
+gaf.PI_EVENT_TYPE = 0;
+
+gaf.TYPE_TEXTURE = 0;
+gaf.TYPE_TEXT_FIELD = 1;
+gaf.TYPE_TIME_LINE = 2;
+
+gaf.UNIFORM_BLUR_TEXEL_OFFSET = "u_step";
+gaf.UNIFORM_GLOW_TEXEL_OFFSET = "u_step";
+gaf.UNIFORM_GLOW_COLOR = "u_glowColor";
+gaf.UNIFORM_ALPHA_TINT_MULT = "colorTransformMult";
+gaf.UNIFORM_ALPHA_TINT_OFFSET = "colorTransformOffsets";
+gaf.UNIFORM_ALPHA_COLOR_MATRIX_BODY = "colorMatrix";
+gaf.UNIFORM_ALPHA_COLOR_MATRIX_APPENDIX = "colorMatrix2";
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFAsset.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFAsset.js
new file mode 100644
index 0000000..23804e6
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFAsset.js
@@ -0,0 +1,429 @@
+var gaf = gaf || {};
+
+gaf.Asset = cc.Class.extend
+({
+ _className: "GAFAsset",
+
+ // Private members
+ _header: null,
+ _timeLines: null,
+ _textFields: null,
+ _protos: null,
+ _objects: null,
+ _masks: null,
+
+ _rootTimeLine: null,
+ _textureLoadDelegate: null,
+ _sceneFps: 60,
+ _sceneWidth: 0,
+ _sceneHeight: 0,
+ _sceneColor: 0,
+ _gafData: null,
+ _desiredAtlasScale: 1,
+ _usedAtlasScale: 0,
+
+ _atlases: null,
+ _onLoadTasks: null,
+ _atlasScales: null,
+ _textureLoaded: false, // For async loading with cc.event manager
+ _atlasesToLoad: null, // Atlases that are not yet loaded
+ _gafName: null,
+
+ /**
+ * @method initWithGAFFile
+ * @param {String} filePath - path to .gaf file
+ * @param {String function(String)} textureLoadDelegate - is used to change atlas path, e.g. to load `atlas.tga` instead of `atlas.png`
+ * @return {bool}
+ */
+ initWithGAFFile: function (filePath, textureLoadDelegate) {
+ var self = this;
+ this._textureLoadDelegate = textureLoadDelegate;
+ this._gafName = filePath;
+ var gafData = cc.loader.getRes(filePath);
+ if(!gafData)
+ {
+ cc.loader.load(filePath, function(err, data){
+ if(!err)
+ {
+ self._init(data[0]);
+ }
+ });
+ }
+ else {
+ return this._init(gafData);
+ }
+ return false;
+ },
+
+ /**
+ * @method initWithGAFBundle
+ * @param {String} zipFilePath - path to the archive with .gaf and its textures
+ * @param {String} entryFile - name of the .gaf file in archive
+ * @param {function({path:String})} delegate - is used to change atlas path, e.g. to load `atlas.tga` instead of `atlas.png`
+ * @return {bool}
+ */
+ initWithGAFBundle: function (zipFilePath, entryFile, delegate)
+ {
+ cc.assert(false, "initWithGAFBundle is not yet implemented");
+ return false;
+ },
+
+ /**
+ * @method setRootTimelineWithName
+ * @param {String} name
+ */
+ setRootTimelineWithName: function (name)
+ {
+ for(var i = 0, end = this._timeLines.length; i < end; ++i)
+ {
+ var object = this._timeLines[i];
+ if (object && object.getLinkageName() === name)
+ {
+ this._setRootTimeline(object);
+ return;
+ }
+ }
+ },
+
+/* addEventListener: function(name, listener)
+ {},*/
+
+ isAssetVersionPlayable: function ()
+ {
+ return true;
+ },
+
+ /**
+ * Desired atlas scale.
+ * Default is 1.0f
+ * @returns {number}
+ */
+ desiredAtlasScale : function(){
+ return this._desiredAtlasScale;
+ },
+
+ /**
+ * Sets desired atlas scale. Will choose nearest atlas scale from available.
+ * Default is 1.0f
+ * @param scale
+ */
+ setDesiredAtlasScale : function(desiredAtlasScale){
+ this._desiredAtlasScale = desiredAtlasScale;
+ for(var currentScale in this._atlasScales)if(this._atlasScales.hasOwnProperty(currentScale))
+ {
+ if( (this._usedAtlasScale === 0) ||
+ (Math.abs(this._usedAtlasScale - desiredAtlasScale) > Math.abs(currentScale - desiredAtlasScale) ))
+ {
+ this._usedAtlasScale = currentScale;
+ }
+
+ }
+ },
+
+ /**
+ * @method createObject
+ * @return {gaf.Object}
+ */
+ createObject: function ()
+ {
+ return this._instantiateGaf(this._gafData);
+ },
+
+ /**
+ * @method createObjectAndRun
+ * @param {boolean} arg0 - run looped
+ * @return {gaf.Object}
+ */
+ createObjectAndRun: function (looped)
+ {
+ cc.assert(arguments.length === 1, "GAFAsset::createObjectAndRun should have one param");
+ var object = this._instantiateGaf(this._gafData);
+ object.setLooped(looped, true);
+ object.start();
+ return object;
+ },
+
+ /**
+ * @method setTextureLoadDelegate
+ * @param {function} delegate
+ */
+ setTextureLoadDelegate: function (delegate)
+ {
+ debugger;
+ },
+
+
+ /**
+ * @method getSceneFps
+ * @return {uint}
+ */
+ getSceneFps: function ()
+ {
+ return this._sceneFps;
+ },
+
+ /**
+ * @method getSceneWidth
+ * @return {uint}
+ */
+ getSceneWidth: function ()
+ {
+ debugger;
+ },
+
+ /**
+ * @method getSceneHeight
+ * @return {uint}
+ */
+ getSceneHeight: function ()
+ {
+ debugger;
+ },
+
+ /**
+ * @method getSceneColor
+ * @return {cc.color4b}
+ */
+ getSceneColor: function ()
+ {
+ debugger;
+ },
+
+ /**
+ * @method setSceneFps
+ * @param {uint} fps
+ */
+ setSceneFps: function (fps)
+ {
+ this._sceneFps = fps;
+ },
+
+ /**
+ * @method setSceneWidth
+ * @param {uint} width
+ */
+ setSceneWidth: function (width)
+ {
+ debugger;
+ },
+
+ /**
+ * @method setSceneHeight
+ * @param {uint} height
+ */
+ setSceneHeight: function (height)
+ {
+ debugger;
+ },
+
+ /**
+ * @method setSceneColor
+ * @param {color4b_object} arg0
+ */
+ setSceneColor: function (color4B)
+ {
+ debugger;
+ },
+
+ /**
+ * @method getHeader
+ * @return {GAFHeader}
+ */
+ getHeader: function ()
+ {
+ return this._header;
+ },
+
+ getGAFFileName: function()
+ {
+ return this._gafName;
+ },
+
+ // Private
+
+ ctor : function()
+ {
+ this._header = {};
+ this._timeLines = [];
+ this._textFields = [];
+ this._objects = [];
+ this._masks = [];
+ this._protos = [];
+ this._atlases = {};
+ this._onLoadTasks = [];
+ this._atlasScales = {};
+ this._atlasesToLoad = {};
+
+ if(arguments.length > 0)
+ this.initWithGAFFile.apply(this, arguments);
+ },
+
+ _getProtos: function()
+ {
+ return this._protos;
+ },
+
+ _setRootTimeline : function(timeLine)
+ {
+ this._rootTimeLine = timeLine;
+ this._header.pivot = timeLine.getPivot();
+ this._header.frameSize = timeLine.getRect();
+ },
+
+ _setHeader : function (gafHeader)
+ {
+ for(var prop in gafHeader)
+ {
+ if(gafHeader.hasOwnProperty(prop))
+ {
+ this._header[prop] = gafHeader[prop];
+ }
+ }
+ },
+
+ _getMajorVerison : function()
+ {
+ return this._header.versionMajor;
+ },
+
+ _init : function(gafData)
+ {
+ var self = this;
+ this._gafData = gafData;
+ this._setHeader(gafData.header);
+ this._timeLinesToLink = [];
+ if(this._getMajorVerison() < 4)
+ {
+ this._pushTimeLine(new gaf._TimeLineProto(this, this._header.framesCount, this._header.frameSize, this._header.pivot));
+ }
+ gaf._AssetPreload.Tags(this, gafData.tags, this._rootTimeLine);
+
+ //Link and create
+ this._objects.forEach(function(item)
+ {
+ switch(item.type)
+ {
+ case gaf.TYPE_TEXTURE:
+ // Create gaf sprite proto if it is not yet created
+ if(!self._protos[item.objectId])
+ {
+ self._protos[item.objectId] = new gaf._SpriteProto(self, self._atlasScales, item.elementAtlasIdRef);
+ }
+ break;
+ case gaf.TYPE_TIME_LINE:
+ // All time line protos are already created, just copy reference
+ self._protos[item.objectId] = self._timeLines[item.elementAtlasIdRef];
+ break;
+ case gaf.TYPE_TEXT_FIELD:
+ // All text field protos are already created, just copy reference
+ self._protos[item.objectId] = self._textFields[item.elementAtlasIdRef];
+ break;
+ default:
+ cc.log("Unknown object type: " + item.type);
+ break;
+ }
+ });
+ this._masks.forEach(function(item)
+ {
+ if(self._protos[item.objectId])
+ {
+ return; // this is continue
+ }
+ var proto = null;
+ switch(item.type)
+ {
+ case gaf.TYPE_TEXTURE:
+ // Create gaf sprite proto if it is not yet created
+ proto = new gaf._SpriteProto(self, self._atlasScales, item.elementAtlasIdRef);
+ break;
+ case gaf.TYPE_TIME_LINE:
+ // All time line protos are already created, just copy reference
+ proto = self._timeLines[item.elementAtlasIdRef];
+ break;
+ case gaf.TYPE_TEXT_FIELD:
+ // All text field protos are already created, just copy reference
+ proto = self._textFields[item.elementAtlasIdRef];
+ break;
+ }
+ self._protos[item.objectId] = new gaf._MaskProto(self, proto, item.elementAtlasIdRef);
+ });
+ this.setDesiredAtlasScale(this._desiredAtlasScale);
+
+ if(Object.keys(this._atlasesToLoad).length === 0)
+ {
+ this._textureLoaded = true;
+ this.dispatchEvent("load");
+ }
+ },
+
+ _pushTimeLine : function(timeLine)
+ {
+ this._timeLines[timeLine.getId()] = timeLine;
+
+ if(timeLine.getId() === 0)
+ {
+ this._setRootTimeline(timeLine);
+ }
+ },
+
+ _instantiateGaf : function()
+ {
+ var root = null;
+ root = this._rootTimeLine._gafConstruct();
+ return root;
+ },
+
+ _onAtlasLoaded : function(id, atlas)
+ {
+ this._atlases[id] = atlas;
+ delete this._atlasesToLoad[id];
+ if(Object.keys(this._atlasesToLoad).length === 0)
+ {
+ this._onLoadTasks.forEach(function(fn){fn()});
+ this._onLoadTasks.length = 0;
+ this._textureLoaded = true;
+ this.dispatchEvent("load");
+ }
+ },
+
+ isLoaded : function()
+ {
+ return this._textureLoaded;
+ },
+
+ _getSearchPaths: function(imageUrl)
+ {
+ var extendedPath = this.getGAFFileName().split('/');
+ extendedPath[extendedPath.length-1] = imageUrl;
+ var alternativeUrl = extendedPath.join('/');
+
+ return [imageUrl, alternativeUrl];
+ }
+});
+
+/**
+ * @method initWithGAFFile
+ * @param {String} gafFilePath - path to .gaf file
+ * @param {function({path:String})} delegate - is used to change atlas path, e.g. to load `atlas.tga` instead of `atlas.png`
+ * @return {gaf.Asset}
+ */
+gaf.Asset.create = function (gafFilePath, delegate)
+{
+ return new gaf.Asset(gafFilePath, delegate);
+};
+
+/**
+ * @method createWithBundle
+ * @param {String} zipFilePath - path to the archive with .gaf and its textures
+ * @param {String} entryFile - name of the .gaf file in archive
+ * @param {function({path:String})} delegate - is used to change atlas path, e.g. to load `atlas.tga` instead of `atlas.png`
+ * @return {gaf.Asset}
+ */
+gaf.Asset.createWithBundle = function (zipFilePath, entryFile, delegate)
+{
+ var asset = new gaf.Asset();
+ asset.initWithGAFBundle(zipFilePath, entryFile, delegate);
+ return asset;
+};
+
+cc.EventHelper.prototype.apply(gaf.Asset.prototype);
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFAssetPreload.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFAssetPreload.js
new file mode 100644
index 0000000..8514e09
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFAssetPreload.js
@@ -0,0 +1,270 @@
+
+gaf.CGAffineTransformCocosFormatFromFlashFormat = function(transform)
+{
+ var t = {};
+ t.a = transform.a;
+ t.b = -transform.b;
+ t.c = -transform.c;
+ t.d = transform.d;
+ t.tx = transform.tx;
+ t.ty = -transform.ty;
+ return t;
+};
+
+gaf._AssetPreload = function()
+{
+ this["0"] = this.End;
+ this["1"] = this.Atlases;
+ this["2"] = this.AnimationMasks;
+ this["3"] = this.AnimationObjects;
+ this["4"] = this.AnimationFrames;
+ this["5"] = this.NamedParts;
+ this["6"] = this.Sequences;
+ this["7"] = this.TextFields;
+ this["8"] = this.Atlases; // 2
+ this["9"] = this.Stage;
+ this["10"] = this.AnimationObjects; //2
+ this["11"] = this.AnimationMasks; // 2
+ this["12"] = this.AnimationFrames; // 2
+ this["13"] = this.TimeLine;
+};
+
+gaf._AssetPreload.prototype.End = function(asset, content, timeLine){
+ if(timeLine)
+ {
+ timeLine.getFps = function()
+ {
+ return asset.getSceneFps();
+ };
+ }
+};
+
+gaf._AssetPreload.prototype.Tag = function(asset, tag, timeLine)
+{
+ (this[tag.tagId]).call(this, asset, tag.content, timeLine);
+};
+
+gaf._AssetPreload.prototype.Tags = function(asset, tags, timeLine)
+{
+ var self = this;
+ tags.forEach(function(tag)
+ {
+ self.Tag(asset, tag, timeLine);
+ });
+};
+
+gaf._AssetPreload.prototype.AtlasCreateFrames = function(elements, asset, spriteFrames)
+{
+ elements.forEach(function (item) {
+ var texture = asset._atlases[item.atlasId];
+ var rect = cc.rect(item.origin.x, item.origin.y, item.size.x, item.size.y);
+ var frame = new cc.SpriteFrame(texture, rect);
+ frame._gafAnchor =
+ {
+ x: (0 - (0 - (item.pivot.x / item.size.x))),
+ y: (0 + (1 - (item.pivot.y / item.size.y)))
+ };
+ spriteFrames[item.elementAtlasId] = frame;
+ // 9 grid
+ });
+};
+
+
+
+gaf._AssetPreload.prototype.Atlases = function(asset, content, timeLine)
+{
+ var spriteFrames = asset._atlasScales[content.scale] = asset._atlasScales[content.scale] || [];
+ var csf = cc.Director._getInstance().getContentScaleFactor();
+
+ content.atlases.forEach(function(item)
+ {
+ var atlasId = item.id;
+ var finalizeLoading = function()
+ {
+ gaf._AssetPreload.AtlasCreateFrames(content.elements, asset, spriteFrames);
+ };
+
+ var atlasPath = "";
+ item.sources.forEach(function(atlasSource)
+ {
+ if(atlasSource.csf === csf)
+ {
+ atlasPath = atlasSource.source;
+ }
+ });
+ cc.assert(atlasPath, "GAF Error. Texture for current CSF not found. Reconvert animation with correct parameters.");
+
+ if(asset._textureLoadDelegate)
+ {
+ atlasPath = asset._textureLoadDelegate(atlasPath);
+ }
+
+ var loaded = false;
+ var paths = asset._getSearchPaths(atlasPath);
+ for(var i = 0, len = paths.length; i < len; ++i){
+ var path = paths[i];
+ var atlas = cc.textureCache.getTextureForKey(path);
+ if(atlas && atlas.isLoaded())
+ {
+ atlas.handleLoadedTexture(true);
+ loaded = true;
+ asset._atlases[atlasId] = atlas;
+ finalizeLoading();
+ break;
+ }
+ }
+ // Need to load atlases async
+ if(!loaded)
+ {
+ var success = function (atlas) {
+ atlas.handleLoadedTexture(true);
+ asset._onAtlasLoaded(atlasId, atlas);
+ };
+
+ var fail = function () {
+ cc.log("GAF Error. Couldn't find `" + atlasPath + "` required by `" + asset.getGAFFileName() + "`");
+ };
+
+ if(!asset._atlasesToLoad.hasOwnProperty(atlasId))
+ {
+ gaf._AtlasLoader.loadArray(paths, success, fail);
+ asset._atlasesToLoad[atlasId] = {};
+ }
+ asset._onLoadTasks.push(finalizeLoading);
+ }
+ });
+};
+
+gaf._AssetPreload.prototype.AnimationObjects = function(asset, content, timeLine)
+{
+ content.forEach(function(item)
+ {
+ item.type = (item.type === undefined) ? gaf.TYPE_TEXTURE : item.type;
+ timeLine._objects.push(item.objectId);
+ asset._objects[item.objectId] = item;
+ });
+};
+
+gaf._AssetPreload.prototype.convertTint = function(mat, alpha)
+{
+ if(!mat)
+ return null;
+ return {
+ mult:
+ {
+ r: mat.redMultiplier * 255,
+ g: mat.greenMultiplier * 255,
+ b: mat.blueMultiplier * 255,
+ a: alpha * 255
+ },
+ offset:
+ {
+ r: mat.redOffset * 255,
+ g: mat.greenOffset * 255,
+ b: mat.blueOffset * 255,
+ a: mat.alphaOffset * 255
+ }
+ };
+};
+
+gaf._AssetPreload.prototype.convertState = function(state)
+{
+ return {
+ hasColorTransform: state.hasColorTransform,
+ hasMask: state.hasMask,
+ hasEffect: state.hasEffect,
+ objectIdRef: state.objectIdRef,
+ depth: state.depth,
+ alpha: state.alpha * 255,
+ matrix: gaf.CGAffineTransformCocosFormatFromFlashFormat(state.matrix),
+ colorTransform: this.convertTint(state.colorTransform, state.alpha),
+ effect: state.effect,
+ maskObjectIdRef: state.maskObjectIdRef
+ };
+};
+
+gaf._AssetPreload.prototype.AnimationFrames = function(asset, content, timeLine)
+{
+ var self = this;
+ cc.assert(timeLine, "Error. Time Line should not be null.");
+ var statesForId = {};
+ var frames = [];
+ var lastFrame = {};
+ for(var i = 0, len = content.length; i < len; ++i)
+ {
+ var frame = content[i];
+ if(frame.state)
+ {
+ frame.state.forEach(function (state)
+ {
+ if (state.alpha !== 0)
+ {
+ statesForId[state.objectIdRef] = self.convertState(state);
+ }
+ else
+ {
+ statesForId[state.objectIdRef] = null;
+ }
+ });
+ }
+ var stateArray = [];
+ for(var obj in statesForId){ if(statesForId.hasOwnProperty(obj) && statesForId[obj])
+ {
+ stateArray.push(statesForId[obj]);
+ }}
+ lastFrame = frame;
+ frames[frame.frame - 1] = {states: stateArray, actions: frame.actions || null};
+ }
+ timeLine.getFrames = function(){return frames};
+};
+
+gaf._AssetPreload.prototype.NamedParts = function(asset, content, timeLine)
+{
+ var parts = {};
+ content.forEach(function(item)
+ {
+ parts[item.name] = item.objectId;
+ });
+ timeLine.getNamedParts = function(){return parts};
+};
+
+gaf._AssetPreload.prototype.Sequences = function(asset, content, timeLine)
+{
+ var sequences = {};
+ content.forEach(function(item){
+ sequences[item.id] = {start: item.start - 1, end: item.end};
+ });
+ timeLine.getSequences = function(){return sequences};
+};
+
+gaf._AssetPreload.prototype.TextFields = function(asset, content, timeLine)
+{
+ debugger;
+};
+
+gaf._AssetPreload.prototype.Stage = function(asset, content, timeLine)
+{
+ asset._sceneFps = content.fps;
+ asset._sceneColor = content.color;
+ asset._sceneWidth = content.width;
+ asset._sceneHeight = content.height;
+};
+
+gaf._AssetPreload.prototype.AnimationMasks = function(asset, content, timeLine)
+{
+ content.forEach(function(item)
+ {
+ item.type = (item.type === undefined) ? gaf.TYPE_TEXTURE : item.type;
+ timeLine._objects.push(item.objectId);
+ asset._masks[item.objectId] = item;
+ });
+};
+
+gaf._AssetPreload.prototype.TimeLine = function(asset, content, timeLine)
+{
+ var result = new gaf._TimeLineProto(asset, content.animationFrameCount, content.boundingBox, content.pivotPoint, content.id, content.linkageName);
+ asset._pushTimeLine(result);
+ this.Tags(asset, content.tags, result);
+};
+
+gaf._AssetPreload = new gaf._AssetPreload();
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFAtlasLoader.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFAtlasLoader.js
new file mode 100644
index 0000000..152bba0
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFAtlasLoader.js
@@ -0,0 +1,50 @@
+/**
+ * Created by admiral on 19.02.2015.
+ */
+
+gaf._AtlasLoader = {};
+gaf._AtlasLoader.execute = function(condition, success, fail)
+{
+ condition() ? success() : fail();
+};
+
+gaf._AtlasLoader.checkAtlas = function(atlas) // curried function
+{
+ return function(){return atlas && typeof atlas !== "string" && atlas.isLoaded()};
+};
+
+gaf._AtlasLoader.load = function(path, success, fail)
+{
+ cc.textureCache.addImage(path, function(atlas){
+ gaf._AtlasLoader.execute(
+ gaf._AtlasLoader.checkAtlas(atlas),
+ function(){success(atlas)},
+ fail
+ );
+ });
+};
+
+gaf._AtlasLoader.loadFront = function(arr, success, fail)
+{
+ // Call recursively this function for each element starting from the first
+ // stops on first success, or fails after last element
+ return function()
+ {
+ if (arr.length > 0){
+ gaf._AtlasLoader.load(
+ arr[0],
+ success,
+ gaf._AtlasLoader.loadFront(
+ arr.slice(1),
+ success,
+ fail
+ ));}
+ else
+ fail();
+ }
+};
+
+gaf._AtlasLoader.loadArray = function(array, success, fail)
+{
+ gaf._AtlasLoader.loadFront(array, success, fail)();
+};
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFDataReader.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFDataReader.js
new file mode 100644
index 0000000..3affbe1
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFDataReader.js
@@ -0,0 +1,229 @@
+gaf.DataReader = function(data) {
+ this.dataRaw = data;
+ this.buf = new DataView(data);
+ this.offset = [0];
+};
+
+gaf.DataReader.prototype.constructor = gaf.DataReader;
+
+gaf.DataReader.prototype.newOffset = function(size){
+ this.offset[this.offset.length - 1] += size;
+ if(this.getOffset() > this.maxOffset()){
+ throw new Error("GAF format error");
+ }
+ return this.offset[this.offset.length - 1] - size;
+};
+
+gaf.DataReader.prototype.maxOffset = function(){
+ if(this.offset.length == 1){
+ return this.buf.byteLength;
+ }
+ else{
+ return this.offset[this.offset.length - 2];
+ }
+};
+
+gaf.DataReader.prototype.getOffset = function(size){
+ return this.offset[this.offset.length - 1];
+};
+
+gaf.DataReader.prototype.Ubyte = function() {
+ return this.buf.getUint8(this.newOffset(1));
+};
+
+gaf.DataReader.prototype.Boolean = function() {
+ var result = this.buf.getUint8(this.newOffset(1));
+ if(result > 1){
+ throw new Error("GAF format error");
+ }
+ return result;
+};
+
+gaf.DataReader.prototype.Uint = function() {
+ return this.buf.getUint32(this.newOffset(4), true);
+};
+
+gaf.DataReader.prototype.Int = function() {
+ return this.buf.getInt32(this.newOffset(4), true);
+};
+
+gaf.DataReader.prototype.color = function() {
+ return {
+ b: this.Ubyte(),
+ g: this.Ubyte(),
+ r: this.Ubyte(),
+ a: this.Ubyte()
+ };
+};
+
+gaf.DataReader.prototype.Ushort = function() {
+ return this.buf.getUint16(this.newOffset(2), true);
+};
+
+gaf.DataReader.prototype.Float = function() {
+ return this.buf.getFloat32(this.newOffset(4), true);
+};
+
+gaf.DataReader.prototype.String = function() {
+ var strLen = this.Ushort();
+ var from = this.newOffset(strLen);
+ var to = this.getOffset();
+
+ try
+ {
+ var str = this.dataRaw.slice(from, to);
+ }
+ catch(e)
+ {
+ // Internet Explorer 10 T.T
+ if(e.message == "Object doesn't support property or method 'slice'")
+ {
+ str = [];
+ for(var i = from; i < to; ++i)
+ str.push(this.buf.getUint8(i));
+ }
+ else
+ {
+ throw(e);
+ }
+ }
+ return decodeURIComponent(escape(String.fromCharCode.apply(null, new Uint8Array(str))));
+
+};
+
+gaf.DataReader.prototype.startNestedBuffer = function(length) {
+ this.offset.push(this.offset[this.offset.length-1]);
+ this.offset[this.offset.length-2] += length;
+};
+
+gaf.DataReader.prototype.endNestedBuffer = function() {
+ if (this.offset.length == 1) throw new Error('No nested buffer available');
+ this.offset.pop();
+};
+
+gaf.DataReader.prototype.Point = function(){
+ return {
+ x: this.Float(),
+ y: this.Float()
+ };
+};
+
+gaf.DataReader.prototype.Rect = function(){
+ return {
+ x: this.Float(),
+ y: this.Float(),
+ width: this.Float(),
+ height: this.Float()
+ };
+};
+
+gaf.DataReader.prototype.Matrix = function(){
+ return {
+ a: this.Float(),
+ b: this.Float(),
+ c: this.Float(),
+ d: this.Float(),
+ tx: this.Float(),
+ ty: this.Float()
+ };
+};
+
+gaf.DataReader.prototype.seek = function(pos){
+ this.offset[this.offset.length-1] = pos;
+};
+
+gaf.DataReader.prototype.tell = function(){
+ return this.offset[this.offset.length-1];
+};
+
+/* Creates a fields parsing function
+* @ returns a function that will read from DataReader `field` of type `type`
+* @`key` - key for read data to be stored
+* @`data` - data to store. Can be DataReader function name or a function that will return a value
+* Note. Parameters pair `key` and `data` can be repeated any number of times*/
+
+gaf.DataReader.prototype.fields = function(){
+ var self = this;
+ var arguments_ = arguments;
+ return function(){
+ arguments.callee.result = {};
+ var i = 0;
+ if(arguments_.length % 2){
+ throw new Error('Number of arguments is not even');
+ }
+ while(i < arguments_.length){
+ var field = arguments_[i++];
+ var func = arguments_[i++];
+ if(typeof func === 'function'){
+ arguments.callee.result[field] = func();
+ }
+ else if (func in self && typeof self[func] === 'function'){
+ arguments.callee.result[field] = self[func].call(self);
+ }
+ else{
+ throw new Error('Object DataReader has no function `' + func + '`');
+ }
+ }
+ return arguments.callee.result;
+ }
+};
+
+/*
+* Creates a parsing function
+* @ returns function that will execute expression if caller's `result` field has `key` equal to `value` parameter
+* @ `key` - key in caller's `result` element
+* @ `value` - expected value of the `key` or a comparator function
+* @ `func` - function to execute if condition is true
+* */
+
+gaf.DataReader.prototype.condition = function(key, value, func){
+ var arguments_ = arguments;
+ return function() {
+ if(arguments_.length != 3){
+ throw new Error('Condition function');
+ }
+ var parent = arguments.callee.caller;
+ if(!('result' in parent)){
+ throw new Error('Condition function caller has no key `result`');
+ }
+ var container = parent.result;
+ var field = arguments_[0];
+ var value = arguments_[1];
+ var exec = arguments_[2];
+
+ var evaluate = null;
+ if(typeof value === 'function'){
+ evaluate = function(){return value(container[field]);};
+ }
+ else{
+ evaluate = function(){return value == container[field];};
+ }
+ if(evaluate()){
+ return exec();
+ }
+ else{
+ return null;
+ }
+ }
+};
+
+/*
+* Creates an array parsing function
+* @ returns function that will execute `func` number of times read from DataReader
+* @ `type` - type of count number
+* @ `func` - function to be executed
+* */
+
+gaf.DataReader.prototype.array = function(){
+ var self = this;
+ var arguments_ = arguments;
+ return function() {
+ arguments.callee.result = [];
+ var length = self[arguments_[0]].call(self);
+ for (var i = 0; i < length; ++i) {
+ var r = arguments_[1].call();
+ arguments.callee.result.push(r);
+ }
+ return arguments.callee.result;
+ }
+};
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFLoader.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFLoader.js
new file mode 100644
index 0000000..3e40c33
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFLoader.js
@@ -0,0 +1,75 @@
+var gaf = gaf || {};
+
+//@Private class
+gaf.Loader = function(){
+
+ var readHeaderBegin = function(stream, header){
+ header.compression = stream.Uint();
+ header.versionMajor = stream.Ubyte();
+ header.versionMinor = stream.Ubyte();
+ header.fileLength = stream.Uint();
+ };
+
+ var readHeaderEndV3 = function(stream, header) {
+ header.framesCount = stream.Ushort();
+ header.frameSize = stream.Rect();
+ header.pivot = stream.Point();
+ };
+
+ var readHeaderEndV4 = function(stream, header){
+ var scaleCount = stream.Uint();
+ header.scaleValues = [];
+ for(var i = 0; i < scaleCount; ++i){
+ header.scaleValues.push(stream.Float());
+ }
+ var csfCount = stream.Uint();
+ header.csfValues = [];
+ for(var i = 0; i < csfCount; ++i){
+ header.csfValues.push(stream.Float());
+ }
+ };
+
+ this.LoadFile = function(filePath, onLoaded){
+ var oReq = new XMLHttpRequest();
+ oReq.open("GET", filePath, true);
+ var self = this;
+ oReq.responseType = "arraybuffer";
+ oReq.onload = function(oEvent) {
+ var gaf_data = new gaf.DataReader(oReq.response);
+ var gafFile = self.LoadStream(gaf_data);
+ if(onLoaded)
+ onLoaded(gafFile);
+ };
+ oReq.send();
+ };
+
+ this.LoadStream = function(stream){
+ var header = {};
+ readHeaderBegin(stream, header);
+ if(header.compression == gaf.COMPRESSION_NONE) { // GAF
+ }
+ else if(header.compression == gaf.COMPRESSION_ZIP){ // GAC
+ var compressed = stream.dataRaw.slice(stream.tell());
+
+ var inflate = new window.Zlib.Inflate(new Uint8Array(compressed));
+ var decompressed = inflate.decompress();
+ stream = new gaf.DataReader(decompressed.buffer);
+ }
+ else{
+ throw new Error("GAF syntax error.");
+ }
+
+ if(header.versionMajor < 4){
+ readHeaderEndV3(stream, header);
+ }
+ else{
+ readHeaderEndV4(stream, header);
+ }
+
+ var tags = gaf.ReadTags(stream);
+ return {
+ header: header,
+ tags: tags
+ };
+ };
+};
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFMask.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFMask.js
new file mode 100644
index 0000000..34ca206
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFMask.js
@@ -0,0 +1,36 @@
+
+gaf.Mask = gaf.Object.extend
+({
+ _className: "GAFMask",
+ _clippingNode: null,
+
+ ctor : function(gafSpriteProto)
+ {
+ this._super();
+ cc.assert(gafSpriteProto, "Error! Missing mandatory parameter.");
+ this._gafproto = gafSpriteProto;
+ },
+
+ _init : function()
+ {
+ var maskNodeProto = this._gafproto.getMaskNodeProto();
+ cc.assert(maskNodeProto, "Error. Mask node for id ref " + this._gafproto.getIdRef() + " not found.");
+ this._maskNode = maskNodeProto._gafConstruct();
+ this._clippingNode = cc.ClippingNode.create(this._maskNode);
+ this._clippingNode.setAlphaThreshold(0.5);
+ this.addChild(this._clippingNode);
+ },
+
+ setExternalTransform : function(affineTransform)
+ {
+ if(!cc.affineTransformEqualToTransform(this._maskNode._additionalTransform, affineTransform))
+ {
+ this._maskNode.setAdditionalTransform(affineTransform);
+ }
+ },
+
+ _getNode : function()
+ {
+ return this._clippingNode;
+ }
+});
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFMaskProto.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFMaskProto.js
new file mode 100644
index 0000000..6074fd1
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFMaskProto.js
@@ -0,0 +1,16 @@
+
+gaf._MaskProto = function(asset, mask, idRef)
+{
+ this.getIdRef = function(){return idRef};
+ this.getMaskNodeProto = function() {return mask};
+
+ /*
+ * Will construct GAFMask
+ */
+ this._gafConstruct = function()
+ {
+ var ret = new gaf.Mask(this);
+ ret._init();
+ return ret;
+ };
+};
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFObject.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFObject.js
new file mode 100644
index 0000000..7d5375a
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFObject.js
@@ -0,0 +1,426 @@
+var gaf = gaf || {};
+
+gaf._stateHasCtx = function(state)
+{
+ // Check for tint color offset
+ if( state.hasColorTransform &&
+ (state.colorTransform.offset.r > 0 ||
+ state.colorTransform.offset.g > 0 ||
+ state.colorTransform.offset.b > 0 ||
+ state.colorTransform.offset.a > 0)
+ )
+ {
+ return true;
+ }
+
+ // Check for color transform filter
+ if(state.hasEffect)
+ {
+ for(var i = 0, total = state.effect.length; i < total; ++i)
+ {
+ if(state.effect[i].type === gaf.EFFECT_COLOR_MATRIX)
+ return true;
+ }
+ }
+ return false;
+};
+
+gaf.Object = cc.Node.extend
+({
+ _asset : null,
+ _className : "GAFObject",
+ _id : gaf.IDNONE,
+ _gafproto : null,
+ _parentTimeLine : null,
+ _lastVisibleInFrame : 0,
+ _filterStack : null,
+ _cascadeColorMult : null,
+ _cascadeColorOffset : null,
+ _needsCtx : false,
+ _usedAtlasScale: 1,
+
+ // Public methods
+ ctor: function(scale)
+ {
+ if(arguments.length == 1)
+ {
+ this._usedAtlasScale = scale;
+ }
+ this._super();
+ this._cascadeColorMult = cc.color(255, 255, 255, 255);
+ this._cascadeColorOffset = cc.color(0, 0, 0, 0);
+ this._filterStack = [];
+ },
+
+ /**
+ * @method setAnimationStartedNextLoopDelegate
+ * @param {function(Object)} delegate
+ */
+ setAnimationStartedNextLoopDelegate : function (delegate) {},
+
+ /**
+ * @method setAnimationFinishedPlayDelegate
+ * @param {function(Object)} delegate
+ */
+ setAnimationFinishedPlayDelegate : function (delegate) {},
+
+ /**
+ * @method setLooped
+ * @param {bool} looped
+ */
+ setLooped : function (looped) {},
+
+ /**
+ * @method getBoundingBoxForCurrentFrame
+ * @return {cc.Rect}
+ */
+ getBoundingBoxForCurrentFrame : function () {return null;},
+
+ /**
+ * @method setFps
+ * @param {uint} fps
+ */
+ setFps : function (fps) {},
+
+ /**
+ * @method getObjectByName
+ * @param {String} name - name of the object to find
+ * @return {gaf.Object}
+ */
+ getObjectByName : function (name) {return null;},
+
+ /**
+ * @method clearSequence
+ */
+ clearSequence : function () {},
+
+ /**
+ * @method getIsAnimationRunning
+ * @return {bool}
+ */
+ getIsAnimationRunning : function () {return false;},
+
+ /**
+ * @method getSequences
+ * @return [string] - list of sequences if has any
+ */
+ getSequences : function(){return [];},
+
+
+ /**
+ * @method gotoAndStop
+ * @param {uint|String} value - label ot frame number
+ * @return {bool}
+ */
+ gotoAndStop : function (value) {},
+
+ /**
+ * @method getStartFrame
+ * @param {String} frameLabel
+ * @return {uint}
+ */
+ getStartFrame : function (frameLabel) {return gaf.IDNONE;},
+
+ /**
+ * @method setFramePlayedDelegate
+ * @param {function(Object, frame)} delegate
+ */
+ setFramePlayedDelegate : function (delegate) {},
+
+ /**
+ * @method getCurrentFrameIndex
+ * @return {uint}
+ */
+ getCurrentFrameIndex : function () {
+ return gaf.IDNONE;
+ },
+
+ /**
+ * @method getTotalFrameCount
+ * @return {uint}
+ */
+ getTotalFrameCount : function () {return 0;},
+
+ /**
+ * @method start
+ */
+ start : function () {},
+
+ /**
+ * @method stop
+ */
+ stop : function () {},
+
+ /**
+ * @method isVisibleInCurrentFrame
+ * @return {bool}
+ */
+ isVisibleInCurrentFrame : function ()
+ {
+ /*if (this._parentTimeLine &&
+ ((this._parentTimeLine.getCurrentFrameIndex() + 1) != this._lastVisibleInFrame))
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }*/
+ return !(this._parentTimeLine && ((this._parentTimeLine.getCurrentFrameIndex() + 1) != this._lastVisibleInFrame));
+ },
+
+ /**
+ * @method isDone
+ * @return {bool}
+ */
+ isDone : function () {return true;},
+
+ /**
+ * @method playSequence
+ * @param {String} name - name of the sequence to play
+ * @param {bool} looped - play looped
+ * @param {bool} resume - whether to resume animation if stopped. True by default
+ * @return {bool}
+ */
+ playSequence : function (name, looped, resume) {return false;},
+
+ /**
+ * @method isReversed
+ * @return {bool}
+ */
+ isReversed : function () {return false;},
+
+ /**
+ * @method setSequenceDelegate
+ * @param {function(Object, sequenceName)} delegate
+ */
+ setSequenceDelegate : function (delegate) {},
+
+ /**
+ * @method setFrame
+ * @param {uint} index
+ * @return {bool}
+ */
+ setFrame : function (index) {return false;},
+
+ /**
+ * @method setControlDelegate
+ * @param {function} func
+ */
+ setControlDelegate : function (func) {},
+
+ /**
+ * @method getEndFrame
+ * @param {String} frameLabel
+ * @return {uint}
+ */
+ getEndFrame : function (frameLabel) {return gaf.IDNONE;},
+
+ /**
+ * @method pauseAnimation
+ */
+ pauseAnimation : function () {},
+
+ /**
+ * @method gotoAndPlay
+ * @param {uint|String} value - label ot frame number
+ * @return {bool}
+ */
+ gotoAndPlay : function (value) {},
+
+ /**
+ * @method isLooped
+ * @return {bool}
+ */
+ isLooped : function () {return false;},
+
+ /**
+ * @method resumeAnimation
+ */
+ resumeAnimation : function () {},
+
+ /**
+ * @method setReversed
+ * @param {bool} reversed
+ */
+ setReversed : function (reversed) {},
+
+ /**
+ * @method hasSequences
+ * @return {bool}
+ */
+ hasSequences : function () {return false;},
+
+ /**
+ * @method getFps
+ * @return {uint}
+ */
+ getFps : function () {return 60;},
+
+ /**
+ * @method setLocator
+ * @param {bool} locator
+ * Locator object will not draw itself, but its children will be drawn
+ */
+ setLocator : function (locator){},
+
+ setExternalTransform : function(affineTransform)
+ {
+ if(!cc.affineTransformEqualToTransform(this._additionalTransform, affineTransform))
+ {
+ this.setAdditionalTransform(affineTransform);
+ }
+ },
+
+ getExternalTransform : function()
+ {
+ return this._additionalTransform;
+ },
+
+ setAnimationRunning: function () {},
+
+ ////////////////
+ // Private
+ ////////////////
+ _enableTick: function(val){},
+
+ _resetState : function()
+ {},
+
+ _updateVisibility : function(state, parent)
+ {
+ var alphaOffset = state.hasColorTransform ? state.colorTransform.offset.a : 0;
+ this.setOpacity(state.alpha + alphaOffset);
+ //return this.isVisible();
+ },
+
+ // @Override
+ isVisible : function()
+ {
+ return this.getOpacity() > 0;
+ },
+
+ // @Override
+ visit: function(parentCmd)
+ {
+ if(this.isVisibleInCurrentFrame())
+ {
+ this._super(parentCmd);
+ }
+ },
+
+ _getFilters : function(){return null},
+
+ _processAnimation : function(){},
+
+
+ _applyState : function(state, parent)
+ {
+ this._applyStateSuper(state, parent);
+ },
+
+ _applyStateSuper : function(state, parent)
+ {
+ this._needsCtx = parent._needsCtx;
+ this._filterStack.length = 0; // clear
+ this._parentTimeLine = parent; // only gaf time line can call applyState. Assign it as parent
+ if(this._usedAtlasScale != 1)
+ {
+ var newMat = cc.clone(state.matrix);
+ newMat.tx *= this._usedAtlasScale;
+ newMat.ty *= this._usedAtlasScale;
+ this.setExternalTransform(newMat); // apply transformations of the state
+ }
+ else
+ {
+ this.setExternalTransform(state.matrix); // apply transformations of the state
+ }
+ // Cascade filters
+ // TODO: apply more than one filter
+ if (state.hasEffect) {
+ this._filterStack = this._filterStack.concat(state.effect);
+ this._needsCtx = true;
+ }
+ if (parent._filterStack && parent._filterStack.length > 0) {
+ this._filterStack = this._filterStack.concat(parent._filterStack);
+ }
+
+ if(this._filterStack.length > 0 && this._filterStack[0].type === gaf.EFFECT_COLOR_MATRIX)
+ {
+ this._needsCtx = true;
+ }
+
+ // Cascade color transformations
+
+ // If state has a tint, then we should process it
+ if (state.hasColorTransform)
+ {
+ this._cascadeColorMult.r = state.colorTransform.mult.r * parent._cascadeColorMult.r / 255;
+ this._cascadeColorMult.g = state.colorTransform.mult.g * parent._cascadeColorMult.g / 255;
+ this._cascadeColorMult.b = state.colorTransform.mult.b * parent._cascadeColorMult.b / 255;
+ this._cascadeColorMult.a = state.colorTransform.mult.a * parent._cascadeColorMult.a / 255;
+
+ this._cascadeColorOffset.r = state.colorTransform.offset.r + parent._cascadeColorOffset.r;
+ this._cascadeColorOffset.g = state.colorTransform.offset.g + parent._cascadeColorOffset.g;
+ this._cascadeColorOffset.b = state.colorTransform.offset.b + parent._cascadeColorOffset.b;
+ this._cascadeColorOffset.a = state.colorTransform.offset.a + parent._cascadeColorOffset.a;
+ }
+ else
+ {
+ this._cascadeColorMult.r = parent._cascadeColorMult.r;
+ this._cascadeColorMult.g = parent._cascadeColorMult.g;
+ this._cascadeColorMult.b = parent._cascadeColorMult.b;
+ this._cascadeColorMult.a = state.alpha * (parent._cascadeColorMult.a / 255);
+
+ this._cascadeColorOffset.r = parent._cascadeColorOffset.r;
+ this._cascadeColorOffset.g = parent._cascadeColorOffset.g;
+ this._cascadeColorOffset.b = parent._cascadeColorOffset.b;
+ this._cascadeColorOffset.a = parent._cascadeColorOffset.a;
+ }
+
+ if (this._cascadeColorOffset.r > 0 ||
+ this._cascadeColorOffset.g > 0 ||
+ this._cascadeColorOffset.b > 0 ||
+ this._cascadeColorOffset.a > 0)
+ {
+ this._needsCtx = true;
+ }
+ },
+
+ _initRendererCmd: function()
+ {
+ this._renderCmd = cc.renderer.getRenderCmd(this);
+ this._renderCmd._visit = this._renderCmd.visit;
+ var self = this;
+ this._renderCmd.visit = function(parentCmd) {
+ if(self.isVisibleInCurrentFrame()){
+ this._visit(parentCmd);
+ }
+ }
+ },
+
+ _getNode : function()
+ {
+ return this;
+ },
+
+ setAnchorPoint : function(point, y)
+ {
+ if (y === undefined)
+ {
+ this._super(point.x, point.y - 1);
+ }
+ else
+ {
+ this._super(point, y - 1);
+ }
+ }
+
+});
+
+gaf.Object._createNullObject = function()
+{
+ var ret = new gaf.Object();
+ ret.isVisible = function(){return true};
+ return ret;
+};
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFShaderManager.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFShaderManager.js
new file mode 100644
index 0000000..49b7ffb
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFShaderManager.js
@@ -0,0 +1,63 @@
+
+gaf._glShaderInit = function() {
+ gaf._Uniforms = {
+ ColorTransformMult: -1,
+ ColorTransformOffset: -1,
+ ColorMatrixBody: -1,
+ ColorMatrixAppendix: -1,
+ BlurTexelOffset: -1,
+ GlowTexelOffset: -1,
+ GlowColor: -1
+ };
+
+ gaf._shaderCreate = function (fs, vs) {
+ var program = new cc.GLProgram();
+ var result = program.initWithVertexShaderByteArray(vs, fs);
+ cc.assert(result, "Shader init error");
+ program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
+ program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
+ program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
+ result = program.link();
+ cc.assert(result, "Shader linking error");
+ program.updateUniforms();
+ return program;
+ };
+
+ gaf._shaderCreateAlpha = function () {
+ var program = gaf._shaderCreate(gaf.SHADER_COLOR_MATRIX_FRAG, cc.SHADER_POSITION_TEXTURE_COLOR_VERT);
+ gaf._Uniforms.ColorTransformMult = program.getUniformLocationForName(gaf.UNIFORM_ALPHA_TINT_MULT);
+ gaf._Uniforms.ColorTransformOffset = program.getUniformLocationForName(gaf.UNIFORM_ALPHA_TINT_OFFSET);
+ gaf._Uniforms.ColorMatrixBody = program.getUniformLocationForName(gaf.UNIFORM_ALPHA_COLOR_MATRIX_BODY);
+ gaf._Uniforms.ColorMatrixAppendix = program.getUniformLocationForName(gaf.UNIFORM_ALPHA_COLOR_MATRIX_APPENDIX);
+ return program;
+ };
+
+ gaf._shaderCreateBlur = function () {
+ var program = gaf._shaderCreate(gaf.SHADER_GAUSSIAN_BLUR_FRAG, cc.SHADER_POSITION_TEXTURE_COLOR_VERT);
+ gaf._Uniforms.BlurTexelOffset = program._glContext.getUniformLocation(program._programObj, gaf.UNIFORM_BLUR_TEXEL_OFFSET);
+
+ return program;
+ };
+
+ gaf._shaderCreateGlow = function () {
+ var program = gaf._shaderCreate(gaf.SHADER_GLOW_FRAG, cc.SHADER_POSITION_TEXTURE_COLOR_VERT);
+ gaf._Uniforms.GlowTexelOffset = program._glContext.getUniformLocation(program._programObj, gaf.UNIFORM_GLOW_TEXEL_OFFSET);
+ gaf._Uniforms.GlowColor = program._glContext.getUniformLocation(program._programObj, gaf.UNIFORM_GLOW_COLOR);
+ return program;
+ };
+
+ gaf._Shaders = {
+ Alpha: gaf._shaderCreateAlpha(),
+ Blur: gaf._shaderCreateBlur(),
+ Glow: gaf._shaderCreateGlow()
+ };
+};
+
+gaf._setupShaders = function() {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ gaf._glShaderInit();
+ }
+ else {
+ delete gaf._glShaderInit;
+ }
+};
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFShaders.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFShaders.js
new file mode 100644
index 0000000..7d91537
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFShaders.js
@@ -0,0 +1,58 @@
+gaf.SHADER_GAUSSIAN_BLUR_FRAG =
+ "varying mediump vec2 v_texCoord;\n"
+ + "uniform mediump vec2 u_step;\n"
+ + "void main()\n"
+ + "{ \n"
+ + " mediump vec4 sum = vec4(0.0); \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 4.0) * 0.05; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 3.0) * 0.09; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 2.0) * 0.12; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 1.0) * 0.15; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 0.0) * 0.18; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 1.0) * 0.15; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 2.0) * 0.12; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 3.0) * 0.09; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 4.0) * 0.05; \n"
+ + " gl_FragColor = sum; \n"
+ + "} \n";
+
+gaf.SHADER_GLOW_FRAG =
+ "varying mediump vec2 v_texCoord;\n"
+ + "uniform mediump vec2 u_step;\n"
+ + "uniform mediump vec4 u_glowColor;\n"
+ + "void main()\n"
+ + "{ \n"
+ + " mediump vec4 sum = vec4(0.0); \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 4.0) * 0.05; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 3.0) * 0.09; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 2.0) * 0.12; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 1.0) * 0.15; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 0.0) * 0.18; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 1.0) * 0.15; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 2.0) * 0.12; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 3.0) * 0.09; \n"
+ + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 4.0) * 0.05; \n"
+ + " gl_FragColor = sum * u_glowColor; \n"
+ + "} \n";
+
+gaf.SHADER_COLOR_MATRIX_FRAG =
+ "varying mediump vec2 v_texCoord;\n"
+ + "varying mediump vec4 v_fragmentColor;\n"
+ + "uniform mediump vec4 colorTransformMult;\n"
+ + "uniform mediump vec4 colorTransformOffsets;\n"
+ + "uniform mediump mat4 colorMatrix;\n"
+ + "uniform mediump vec4 colorMatrix2;\n"
+ + "void main()\n"
+ + "{ \n"
+ + " vec4 texColor = texture2D(CC_Texture0, v_texCoord); \n"
+ + " const float kMinimalAlphaAllowed = 1.0e-8; \n"
+ + " if (texColor.a > kMinimalAlphaAllowed) \n"
+ + " { \n"
+ + " texColor = vec4(texColor.rgb / texColor.a, texColor.a); \n"
+ + " vec4 ctxColor = texColor * colorTransformMult + colorTransformOffsets; \n"
+ + " vec4 adjustColor = colorMatrix * ctxColor + colorMatrix2; \n"
+ + " adjustColor *= v_fragmentColor; \n"
+ + " texColor = vec4(adjustColor.rgb * adjustColor.a, adjustColor.a); \n"
+ + " } \n"
+ + " gl_FragColor = texColor; \n"
+ + "}\n";
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFSprite.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFSprite.js
new file mode 100644
index 0000000..2387bf9
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFSprite.js
@@ -0,0 +1,100 @@
+
+gaf.Sprite = gaf.Object.extend
+({
+ _className: "GAFSprite",
+
+ _hasCtx: false,
+ _hasFilter: false,
+
+ ctor : function(gafSpriteProto, usedScale)
+ {
+ this._super(usedScale);
+ cc.assert(gafSpriteProto, "Error! Missing mandatory parameter.");
+ this._gafproto = gafSpriteProto;
+ },
+
+ // Private
+
+ _init : function()
+ {
+ var frame = this._gafproto.getFrame();
+ cc.assert(frame instanceof cc.SpriteFrame, "Error. Wrong object type.");
+
+ // Create sprite with custom render command from frame
+ this._sprite = new cc.Sprite();
+ this._sprite._renderCmd = this._gafCreateRenderCmd(this._sprite);
+ this._sprite.initWithSpriteFrame(frame);
+
+ this._sprite.setAnchorPoint(this._gafproto.getAnchor());
+ this.addChild(this._sprite);
+ //this._sprite.setCascadeColorEnabled(true);
+ //this._sprite.setCascadeOpacityEnabled(true);
+ this._sprite.setOpacityModifyRGB(true);
+
+ if(cc._renderType === cc.game.RENDER_TYPE_WEBGL)
+ this._sprite.setBlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
+ },
+
+ _applyState : function(state, parent)
+ {
+ this._applyStateSuper(state, parent);
+ if(this._needsCtx)
+ {
+ // Enable ctx state if wasn't enabled
+ if(!this._hasCtx)
+ {
+ this._enableCtx();
+ this._hasCtx = true;
+ }
+ // Set ctx shader
+ this._applyCtxState(state);
+ }
+ else
+ {
+ // Disable ctx state if was enabled
+ if(this._hasCtx)
+ {
+ this._disableCtx();
+ this._hasCtx = false;
+ }
+ // Apply color
+ if(!cc.colorEqual(this._sprite._realColor, this._cascadeColorMult))
+ {
+ this._sprite.setColor(this._cascadeColorMult);
+ }
+ // Apply opacity
+ if(this._sprite.getOpacity() != this._cascadeColorMult.a)
+ {
+ this._sprite.setOpacity(this._cascadeColorMult.a);
+ }
+
+ }
+ },
+
+ _enableCtx: function()
+ {
+ this._sprite._renderCmd._enableCtx();
+ },
+
+ _disableCtx: function()
+ {
+ this._sprite._renderCmd._disableCtx();
+ },
+
+ _applyCtxState: function(state){
+ this._sprite._renderCmd._applyCtxState(this);
+ },
+
+ getBoundingBoxForCurrentFrame: function ()
+ {
+ var result = this._sprite.getBoundingBox();
+ return cc._rectApplyAffineTransformIn(result, this.getNodeToParentTransform());
+ },
+
+ _gafCreateRenderCmd: function(item){
+ if(cc._renderType === cc.game.RENDER_TYPE_CANVAS)
+ return new gaf.Sprite.CanvasRenderCmd(item);
+ else
+ return new gaf.Sprite.WebGLRenderCmd(item);
+ }
+});
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFSpriteCanvasRenderCmd.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFSpriteCanvasRenderCmd.js
new file mode 100644
index 0000000..bb807cc
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFSpriteCanvasRenderCmd.js
@@ -0,0 +1,233 @@
+
+(function() {
+ gaf.Sprite.CanvasRenderCmd = function (renderable) {
+ cc.Sprite.CanvasRenderCmd.call(this, renderable);
+ this._hasTintMult = false;
+ this._hasTintOffset = false;
+ this._hasCtx = false;
+ this._tintMult = cc.color(255,255,255,255);
+ this._tintOffset = cc.color(0,0,0,0);
+ this._textureDirty = false;
+ };
+ var proto = gaf.Sprite.CanvasRenderCmd.prototype = Object.create(cc.Sprite.CanvasRenderCmd.prototype);
+ proto.constructor = gaf.Sprite.CanvasRenderCmd;
+
+ proto._disableCtx = function(){
+ this._hasTintOffset = false;
+ this._hasCtx = false;
+ this._textureDirty = true;
+ this.setDirtyFlag(cc.Node._dirtyFlags.colorDirty);
+ this._tintMult = cc.color(255,255,255,255);
+ this._tintOffset = cc.color(0,0,0,0);
+ };
+
+ proto._enableCtx = function(){
+
+ };
+
+ proto._applyCtxState = function(gafObject){
+
+ var tintMult = gafObject._cascadeColorMult;
+ var tintOffset = gafObject._cascadeColorOffset;
+ var opacity = tintMult.a;
+
+ // Apply opacity
+ if(this._node.getOpacity() != opacity)
+ {
+ this._node.setOpacity(opacity);
+ }
+
+ // Check Tint multiplicator
+ var multDirty = !cc.colorEqual(this._tintMult, tintMult);
+ if(multDirty)
+ {
+ this._node.setColor(tintMult);
+ this._tintMult = tintMult;
+ this._hasTintMult =
+ (tintMult.r !== 255 ||
+ tintMult.g !== 255 ||
+ tintMult.b !== 255 );
+ }
+
+ // Check Tint offset
+ var offfsetDirty =
+ (this._tintOffset.r != tintOffset.r) ||
+ (this._tintOffset.g != tintOffset.g) ||
+ (this._tintOffset.b != tintOffset.b) ||
+ (this._tintOffset.a != tintOffset.a);
+
+ if(offfsetDirty)
+ {
+ this._tintOffset = tintOffset;
+ this._hasTintOffset =
+ (tintOffset.r !== 0 ||
+ tintOffset.g !== 0 ||
+ tintOffset.b !== 0 ||
+ tintOffset.a !== 0 );
+ }
+
+ // Update dirty flag
+ this._textureDirty = multDirty || offfsetDirty;
+ if(this._textureDirty)
+ {
+ this.setDirtyFlag(cc.Node._dirtyFlags.colorDirty);
+ }
+
+
+ this._hasCtx = gafObject._filterStack.length > 0 && gafObject._filterStack[0].type === gaf.EFFECT_COLOR_MATRIX;
+
+ };
+
+ proto.rendering = function(ctx, scaleX, scaleY)
+ {
+ var node = this._node;
+ var locTextureCoord = this._textureCoord,
+ alpha = (this._displayedOpacity / 255);
+
+ if ((node._texture && ((locTextureCoord.width === 0 || locTextureCoord.height === 0) //set texture but the texture isn't loaded.
+ || !node._texture._textureLoaded)) || alpha === 0)
+ return;
+
+ var wrapper = ctx || cc._renderContext,
+ context = wrapper.getContext();
+ var locX = node._offsetPosition.x,
+ locHeight = node._rect.height,
+ locWidth = node._rect.width,
+ locY = -node._offsetPosition.y - locHeight,
+ image;
+
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+ wrapper.setCompositeOperation(this._blendFuncStr);
+ wrapper.setGlobalAlpha(alpha);
+
+ if(node._flippedX || node._flippedY)
+ wrapper.save();
+ if (node._flippedX) {
+ locX = -locX - locWidth;
+ context.scale(-1, 1);
+ }
+ if (node._flippedY) {
+ locY = node._offsetPosition.y;
+ context.scale(1, -1);
+ }
+
+ image = node._texture._htmlElementObj;
+
+ if (this._colorized) {
+ context.drawImage(image,
+ 0, 0, locTextureCoord.width,locTextureCoord.height,
+ locX * scaleX,locY * scaleY, locWidth * scaleX, locHeight * scaleY);
+ } else {
+ context.drawImage(image,
+ locTextureCoord.renderX, locTextureCoord.renderY, locTextureCoord.width, locTextureCoord.height,
+ locX * scaleX, locY * scaleY, locWidth * scaleX, locHeight * scaleY);
+ }
+
+ if(node._flippedX || node._flippedY)
+ wrapper.restore();
+ cc.g_NumberOfDraws++;
+ };
+
+ if(cc.sys._supportCanvasNewBlendModes){
+ proto._updateColor = function () {
+ var displayedColor = this._displayedColor, node = this._node;
+ this._hasTintMult |= (displayedColor.r !== 255 || displayedColor.g !== 255 || displayedColor.b !== 255);
+
+ // If no color changes
+ if(this._textureDirty)
+ {
+ this._textureDirty = false;
+ if (this._colorized) {
+ this._colorized = false;
+ node.texture = this._originalTexture;
+ }
+ }
+ else
+ {
+ return;
+ }
+
+ var locElement, locTexture = node._texture, locRect = this._textureCoord;
+ if(this._hasTintMult)
+ {
+ if (locTexture && locRect.validRect && this._originalTexture) {
+ locElement = locTexture.getHtmlElementObj();
+ if (!locElement)
+ return;
+
+ this._colorized = true;
+ if (this._hasTintOffset || this._hasCtx) displayedColor = this._tintMult;
+
+ locElement = cc.Sprite.CanvasRenderCmd._generateTintImageWithMultiply(this._originalTexture._htmlElementObj, displayedColor, locRect);
+ locTexture = new cc.Texture2D();
+ locTexture.initWithElement(locElement);
+ locTexture.handleLoadedTexture();
+ node.texture = locTexture;
+ }
+ }
+
+ locTexture = node._texture;
+ if(this._hasTintOffset)
+ {
+ var cacheTextureForColor = cc.textureCache.getTextureColors(this._originalTexture.getHtmlElementObj());
+ if (locTexture && locRect.validRect && this._originalTexture) {
+ locElement = locTexture.getHtmlElementObj();
+ if (!locElement)
+ return;
+ if(this._colorized)
+ var texRect = cc.rect(0,0,locRect.width, locRect.height);
+ else
+ texRect = locRect;
+ locElement = this._gafGenerateTintImage(node.texture._htmlElementObj, texRect, cacheTextureForColor, this._tintOffset, locRect);
+ locTexture = new cc.Texture2D();
+ locTexture.initWithElement(locElement);
+ locTexture.handleLoadedTexture();
+ node.texture = locTexture;
+ this._colorized = true;
+ }
+ }
+
+
+ };
+
+ proto._gafGenerateTintImage = function(texture, texRect, tintedImgCache, color, rect, renderCanvas){
+ if (!rect)
+ rect = cc.rect(0, 0, texture.width, texture.height);
+
+ // Create a new buffer if required
+ var w = Math.min(rect.width, tintedImgCache[0].width);
+ var h = Math.min(rect.height, tintedImgCache[0].height);
+ var buff = renderCanvas, ctx;
+ if (!buff) {
+ buff = document.createElement("canvas");
+ buff.width = w;
+ buff.height = h;
+ ctx = buff.getContext("2d");
+ } else {
+ ctx = buff.getContext("2d");
+ ctx.clearRect(0, 0, w, h);
+ }
+ ctx.save();
+
+ // draw a channel with alpha of the original image
+ ctx.globalCompositeOperation = 'source-over';
+ //ctx.globalAlpha = 1;
+ ctx.drawImage(tintedImgCache[2], rect.x, rect.y, w, h, 0, 0, w, h);
+
+ // draw a rect of specified color
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.fillStyle = 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',1)';
+ ctx.fillRect(0, 0, w, h);
+
+ // add the desired image to the drawn
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.drawImage(texture, texRect.x, texRect.y, w, h, 0, 0, w, h);
+
+
+ ctx.restore();
+ return buff;
+
+ };
+ }
+
+})();
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFSpriteProto.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFSpriteProto.js
new file mode 100644
index 0000000..6e33fa7
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFSpriteProto.js
@@ -0,0 +1,36 @@
+
+gaf._SpriteProto = function(asset, atlasFrames, elementAtlasIdRef)
+{
+ //this._anchor = atlasFrame._gafAnchor;
+ //delete atlasFrame._gafAnchor;
+
+ this.getFrames = function(){return atlasFrames};
+ this.getIdRef = function(){return elementAtlasIdRef};
+ //this.getAnchor = function() {return this._anchor};
+ this.getAsset = function() {return asset};
+
+ /*
+ * Will construct GAFSprite
+ */
+ this._gafConstruct = function()
+ {
+ var usedScale = this.getAsset()._usedAtlasScale;
+ var ret = new gaf.Sprite(this, usedScale);
+ ret._init();
+ return ret;
+ };
+};
+
+gaf._SpriteProto.prototype.getFrame = function()
+{
+ var usedScale = this.getAsset()._usedAtlasScale;
+ cc.assert(usedScale, "Error. Atlas scale zero.");
+ var frames = this.getFrames()[usedScale];
+ cc.assert(frames, "Error. No frames found for used scale `"+usedScale+"`");
+ return frames[this.getIdRef()];
+};
+
+gaf._SpriteProto.prototype.getAnchor = function()
+{
+ return this.getFrame()._gafAnchor;
+};
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFSpriteWebGLRenderCmd.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFSpriteWebGLRenderCmd.js
new file mode 100644
index 0000000..eabe25b
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFSpriteWebGLRenderCmd.js
@@ -0,0 +1,132 @@
+
+(function(){
+ gaf.Sprite.WebGLRenderCmd = function (renderable) {
+ cc.Sprite.WebGLRenderCmd.call(this, renderable);
+ this._defualtShader = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR);
+ this._customShader = gaf._Shaders.Alpha;
+
+ //this._shaderProgram = this._defualtShader;
+
+ this._tintMult = null;
+ this._tintOffset = null;
+ this._ctxMatrixBody = null;
+ this._ctxMatrixAppendix = null;
+ };
+
+ var proto = gaf.Sprite.WebGLRenderCmd.prototype = Object.create(cc.Sprite.WebGLRenderCmd.prototype);
+ proto.constructor = gaf.Sprite.WebGLRenderCmd;
+
+ proto._identityVec = [1.0, 1.0, 1.0, 1.0];
+ proto._zeroVec = [0.0, 0.0, 0.0, 0.0];
+ proto._identityMat = [
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1
+ ];
+
+ proto._disableCtx = function(){
+ this.setShaderProgram(this._defualtShader);
+ };
+
+ proto._enableCtx = function(){
+ this.setShaderProgram(this._customShader);
+ };
+
+ proto._applyCtxState = function(gafObject){
+ var tintMult = gafObject._cascadeColorMult;
+ this._tintMult = [
+ tintMult.r / 255,
+ tintMult.g / 255,
+ tintMult.b / 255,
+ tintMult.a / 255
+ ];
+
+ var tintOffset = gafObject._cascadeColorOffset;
+ this._tintOffset = [
+ tintOffset.r / 255,
+ tintOffset.g / 255,
+ tintOffset.b / 255,
+ tintOffset.a / 255
+ ];
+
+ var filterStack = gafObject._filterStack;
+ if(filterStack && filterStack.length > 0 && filterStack[0].type === gaf.EFFECT_COLOR_MATRIX)
+ {
+ var m = filterStack[0].colorMatrix;
+ this._ctxMatrixBody = [
+ m.rr, m.rg, m.rb, m.ra,
+ m.gr, m.gg, m.gb, m.ga,
+ m.br, m.bg, m.bb, m.ba,
+ m.ar, m.ag, m.ab, m.aa
+ ];
+ this._ctxMatrixAppendix = [
+ m.r / 255,
+ m.g / 255,
+ m.b / 255,
+ m.a / 255
+ ];
+ }
+ else
+ {
+ this._ctxMatrixBody = null;
+ this._ctxMatrixAppendix = null;
+ }
+ };
+
+ proto._setUniforms = function()
+ {
+ if(this._shaderProgram === this._customShader)
+ {
+ this._shaderProgram.use();
+ {
+ this._shaderProgram.setUniformLocationWith4fv(
+ gaf._Uniforms.ColorTransformMult,
+ this._tintMult,
+ 1
+ );
+ this._shaderProgram.setUniformLocationWith4fv(
+ gaf._Uniforms.ColorTransformOffset,
+ this._tintOffset,
+ 1
+ );
+ }
+
+ if(this._ctxMatrixBody && this._ctxMatrixAppendix)
+ {
+ this._shaderProgram.setUniformLocationWithMatrix4fv(
+ gaf._Uniforms.ColorMatrixBody,
+ this._ctxMatrixBody,
+ 1
+ );
+ this._shaderProgram.setUniformLocationWith4fv(
+ gaf._Uniforms.ColorMatrixAppendix,
+ this._ctxMatrixAppendix,
+ 1
+ );
+ }
+ else
+ {
+ this._shaderProgram.setUniformLocationWithMatrix4fv(
+ gaf._Uniforms.ColorMatrixBody,
+ this._identityMat,
+ 1
+ );
+ this._shaderProgram.setUniformLocationWith4fv(
+ gaf._Uniforms.ColorMatrixAppendix,
+ this._zeroVec,
+ 1
+ );
+ }
+ }
+ };
+
+ proto.rendering = function(ctx)
+ {
+ this._setUniforms();
+
+ // Super call
+ cc.Sprite.WebGLRenderCmd.prototype.rendering.call(this, ctx);
+ };
+
+})();
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFTags.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFTags.js
new file mode 100644
index 0000000..09f8186
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFTags.js
@@ -0,0 +1,378 @@
+
+gaf.ReadSingleTag = function(stream){
+ var tagId = stream.Ushort();
+ var tag = gaf.Tags[tagId];
+ var result = {};
+ if(typeof tag === "undefined"){
+ console.log("GAF. Non implemented tag detected.");
+ gaf.Tags.Default.parse(stream, tagId);
+ }
+ else{
+ //console.log("tag " + tag.tagName);
+ result = tag.parse(stream, tagId);
+ }
+ return result;
+};
+
+gaf.ReadTags = function(stream){
+ var tags = [];
+ try {
+ do {
+ var tag = gaf.ReadSingleTag(stream);
+ tags.push(tag);
+ } while (tag.tagId != 0);
+ }
+ catch (e){
+ if (e instanceof Error && e.message == "GAF format error"){
+ console.log("GAF format error:\n" + e.stack);
+ // Tag will be closed and parser will continue from where it should.
+ }
+ else{
+ console.log(e.stack);
+ throw e;
+ }
+ }
+ return tags;
+};
+
+
+gaf.Tag = function(){
+ this.Default = Object.create(gaf.Tag.base);
+ this["0"] = Object.create(gaf.Tag.End);
+ this["1"] = Object.create(gaf.Tag.DefineAtlas);
+ this["2"] = Object.create(gaf.Tag.DefineAnimationMasks);
+ this["3"] = Object.create(gaf.Tag.DefineAnimationObjects);
+ this["4"] = Object.create(gaf.Tag.DefineAnimationFrames);
+ this["5"] = Object.create(gaf.Tag.DefineNamedParts);
+ this["6"] = Object.create(gaf.Tag.DefineSequences);
+ this["7"] = Object.create(gaf.Tag.DefineTextFields);
+ this["8"] = Object.create(gaf.Tag.DefineAtlas2);
+ this["9"] = Object.create(gaf.Tag.DefineStage);
+ this["10"] = Object.create(gaf.Tag.DefineAnimationObjects2);
+ this["11"] = Object.create(gaf.Tag.DefineAnimationMasks2);
+ this["12"] = Object.create(gaf.Tag.DefineAnimationFrames2);
+ this["13"] = Object.create(gaf.Tag.DefineTimeline);
+};
+
+gaf.Tag.base = function() {};
+gaf.Tag.base.parse = function(stream, tagId){
+ var size = stream.Uint();
+
+ stream.startNestedBuffer(size);
+ var result = this.doParse(stream);
+ stream.endNestedBuffer();
+
+ result.tagName = this.tagName;
+ result.tagId = tagId;
+ return result;
+};
+gaf.Tag.base.doParse = function(stream){
+ return {};
+ };
+
+gaf.Tag.End = Object.create(gaf.Tag.base);
+gaf.Tag.End.tagName = "TagEnd";
+
+gaf.Tag.DefineAtlas = Object.create(gaf.Tag.base);
+gaf.Tag.DefineAtlas.tagName = "TagDefineAtlas";
+gaf.Tag.DefineAtlas.doParse = function (s) {
+ var exec = s.fields(
+ 'scale', 'Float',
+ 'atlases', s.array('Ubyte', s.fields(
+ 'id', 'Uint',
+ 'sources', s.array('Ubyte', s.fields(
+ 'source', 'String',
+ 'csf', 'Float'
+ ))
+ )),
+ 'elements', s.array('Uint', s.fields(
+ 'pivot', 'Point',
+ 'origin', 'Point',
+ 'scale', 'Float',
+ 'size', 'Point',
+ 'atlasId', 'Uint',
+ 'elementAtlasId', 'Uint'
+ ))
+ );
+ return {'content': exec()};
+};
+
+gaf.Tag.DefineAnimationMasks = Object.create(gaf.Tag.base);
+gaf.Tag.DefineAnimationMasks.tagName = "TagDefineAnimationMasks";
+gaf.Tag.DefineAnimationMasks.doParse = function (s) {
+ var exec = s.array('Uint', s.fields(
+ 'objectId', 'Uint',
+ 'elementAtlasIdRef', 'Uint'
+ ));
+ var result = {'content': exec()};
+ debugger;
+ return result;
+};
+
+gaf.Tag.DefineAnimationObjects = Object.create(gaf.Tag.base);
+gaf.Tag.DefineAnimationObjects.tagName = "TagDefineAnimationObjects";
+gaf.Tag.DefineAnimationObjects.doParse = function (s) {
+ var exec = s.array('Uint', s.fields(
+ 'objectId', 'Uint',
+ 'elementAtlasIdRef', 'Uint'
+ ));
+ return {'content': exec()};
+};
+
+gaf.Tag.DefineAnimationFrames = Object.create(gaf.Tag.base);
+gaf.Tag.DefineAnimationFrames.tagName = "TagDefineAnimationFrames";
+gaf.Tag.DefineAnimationFrames.doParse = function(s){
+ var exec = s.array('Uint', s.fields(
+ 'frame', 'Uint',
+ 'state', s.array('Uint', s.fields(
+ 'hasColorTransform', 'Ubyte',
+ 'hasMask', 'Ubyte',
+ 'hasEffect', 'Ubyte',
+ 'objectIdRef', 'Uint',
+ 'depth', 'Int',
+ 'alpha', 'Float',
+ 'matrix', 'Matrix',
+ 'colorTransform', s.condition('hasColorTransform', 1, s.fields(
+ 'alphaOffset', 'Float',
+ 'redMultiplier', 'Float',
+ 'redOffset', 'Float',
+ 'greenMultiplier', 'Float',
+ 'greenOffset', 'Float',
+ 'blueMultiplier', 'Float',
+ 'blueOffset', 'Float'
+ )),
+ 'effect', s.condition('hasEffect', 1, s.array('Ubyte', gaf.Tag._readFilter(s))),
+ 'maskObjectIdRef', s.condition('hasMask', 1, s.fields(
+ 'maskObjectIdRef', 'Uint'
+ ))
+ ))
+ ));
+ return {'content': exec()};
+};
+
+gaf.Tag.DefineNamedParts = Object.create(gaf.Tag.base);
+gaf.Tag.DefineNamedParts.tagName = "TagDefineNamedParts";
+gaf.Tag.DefineNamedParts.doParse = function(s) {
+ var exec = s.array('Uint', s.fields(
+ 'objectId', 'Uint',
+ 'name', 'String'
+ ));
+ return {'content': exec()};
+};
+
+gaf.Tag.DefineSequences = Object.create(gaf.Tag.base);
+gaf.Tag.DefineSequences.tagName = "TagDefineSequences";
+gaf.Tag.DefineSequences.doParse = function(s) {
+ var exec = s.array('Uint', s.fields(
+ 'id', 'String',
+ 'start', 'Ushort',
+ 'end', 'Ushort'
+ ));
+ return {'content': exec()};
+};
+
+gaf.Tag.DefineTextFields = Object.create(gaf.Tag.base);
+gaf.Tag.DefineTextFields.tagName = "TagDefineTextFields";
+gaf.Tag.DefineTextFields.doParse = function(s) {
+ var exec = s.array('Uint', s.fields(
+ 'id', 'Uint',
+ 'pivot', 'Point',
+ 'end', 'Ushort',
+ 'width', 'Float',
+ 'height', 'Float',
+ 'text', 'String',
+ 'embedFonts', 'Boolean',
+ 'multiline', 'Boolean',
+ 'wordWrap', 'Boolean',
+ 'hasRestrict', 'Boolean',
+ 'restrict', s.condition('hasRestrict', 1, function (){return s['String'];}),
+ 'editable', 'Boolean',
+ 'selectable', 'Boolean',
+ 'displayAsPassword', 'Boolean',
+ 'maxChars', 'Uint',
+ 'align', 'Uint',
+ 'blockIndent', 'Uint',
+ 'bold', 'Boolean',
+ 'bullet', 'Boolean',
+ 'color', 'color',
+ 'font', 'String',
+ 'indent', 'Uint',
+ 'italic', 'Boolean',
+ 'kerning', 'Boolean',
+ 'leading', 'Uint',
+ 'leftMargin', 'Uint',
+ 'letterSpacing', 'Float',
+ 'rightMargin', 'Uint',
+ 'size', 'Uint',
+ 'tabStops', s.array('Uint', s.fields(
+ 'value', 'Uint'
+ )),
+ 'target', 'string',
+ 'underline', 'Boolean',
+ 'url', 'String'
+ ));
+ return {'content': exec()};
+};
+
+gaf.Tag.DefineAtlas2 = Object.create(gaf.Tag.base);
+gaf.Tag.DefineAtlas2.tagName = "TagDefineAtlas2";
+gaf.Tag.DefineAtlas2.doParse = function(s) {
+ var exec = s.fields(
+ 'scale', 'Float',
+ 'atlases', s.array('Ubyte', s.fields(
+ 'id', 'Uint',
+ 'sources', s.array('Ubyte', s.fields(
+ 'source', 'String',
+ 'csf', 'Float'
+ ))
+ )),
+ 'elements', s.array('Uint', s.fields(
+ 'pivot', 'Point',
+ 'origin', 'Point',
+ 'scale', 'Float',
+ 'size', 'Point',
+ 'atlasId', 'Uint',
+ 'elementAtlasId', 'Uint',
+ 'hasScale9Grid', 'Boolean',
+ 'scale9GridRect', s.condition('hasScale9Grid', 1, function(){return s.Rect();})
+ ))
+ );
+ return {'content': exec()};
+};
+
+gaf.Tag.DefineStage = Object.create(gaf.Tag.base);
+gaf.Tag.DefineStage.tagName = "TagDefineStage";
+gaf.Tag.DefineStage.doParse = function(s) {
+ var exec = s.fields(
+ 'fps', 'Ubyte',
+ 'color', 'color',
+ 'width', 'Ushort',
+ 'height', 'Ushort'
+ );
+ return {'content': exec()};
+};
+
+gaf.Tag.DefineAnimationObjects2 = Object.create(gaf.Tag.base);
+gaf.Tag.DefineAnimationObjects2.tagName = "TagDefineAnimationObjects2";
+gaf.Tag.DefineAnimationObjects2.doParse = function(s) {
+ var exec = s.array('Uint', s.fields(
+ 'objectId', 'Uint',
+ 'elementAtlasIdRef', 'Uint',
+ 'type', 'Ushort'
+ ));
+ return {'content': exec()};
+};
+
+gaf.Tag.DefineAnimationMasks2 = Object.create(gaf.Tag.base);
+gaf.Tag.DefineAnimationMasks2.tagName = "TagDefineAnimationMasks2";
+gaf.Tag.DefineAnimationMasks2.doParse = function(s) {
+ var exec = s.array('Uint', s.fields(
+ 'objectId', 'Uint',
+ 'elementAtlasIdRef', 'Uint',
+ 'type', 'Ushort'
+ ));
+ return {'content': exec()};
+};
+
+gaf.Tag.DefineAnimationFrames2 = Object.create(gaf.Tag.base);
+gaf.Tag.DefineAnimationFrames2.tagName = "TagDefineAnimationFrames2";
+gaf.Tag.DefineAnimationFrames2.doParse = function(s) {
+ var exec = s.array('Uint', s.fields(
+ 'frame', 'Uint',
+ 'hasChangesInDisplayList', 'Boolean',
+ 'hasActions', 'Boolean',
+ 'state', s.condition('hasChangesInDisplayList', 1, s.array('Uint', s.fields(
+ 'hasColorTransform', 'Boolean',
+ 'hasMask', 'Boolean',
+ 'hasEffect', 'Boolean',
+ 'objectIdRef', 'Uint',
+ 'depth', 'Int',
+ 'alpha', 'Float',
+ 'matrix', 'Matrix',
+ 'colorTransform', s.condition('hasColorTransform', 1, s.fields(
+ 'alphaOffset', 'Float',
+ 'redMultiplier', 'Float',
+ 'redOffset', 'Float',
+ 'greenMultiplier', 'Float',
+ 'greenOffset', 'Float',
+ 'blueMultiplier', 'Float',
+ 'blueOffset', 'Float'
+ )),
+ 'effect', s.condition('hasEffect', 1, s.array('Ubyte', gaf.Tag._readFilter(s))),
+ 'maskObjectIdRef', s.condition('hasMask', 1, function(){return s.Uint()})
+ ))),
+ 'actions', s.condition('hasActions', 1, s.array('Uint', s.fields(
+ 'type', 'Uint',
+ 'scope', 'String',
+ 'params', gaf.Tag._readActionArguments(s)
+ )))
+ ));
+ return {'content': exec()};
+};
+
+gaf.Tag.DefineTimeline = Object.create(gaf.Tag.base);
+gaf.Tag.DefineTimeline.tagName = "TagDefineTimeline";
+gaf.Tag.DefineTimeline.doParse = function(s) {
+ var exec = s.fields(
+ 'id', 'Uint',
+ 'animationFrameCount', 'Uint',
+ 'boundingBox', 'Rect',
+ 'pivotPoint', 'Point',
+ 'hasLinkage', 'Boolean',
+ 'linkageName', s.condition('hasLinkage', 1, function () {
+ return s.String();
+ })
+ );
+ var result = {'content': exec()};
+ result.content.tags = gaf.ReadTags(s);
+ return result;
+};
+
+gaf.Tag._readActionArguments = function(s){
+ return function(){
+ var size = s.Uint();
+ var ret = [];
+ s.startNestedBuffer(size);
+ while(s.maxOffset() < s.tell()){
+ ret.push(s.String());
+ }
+ s.endNestedBuffer();
+ return ret;
+ };
+};
+
+gaf.Tag._readFilter = function(s){
+ return s.fields(
+ 'type', 'Uint',
+ 'dropShadow', s.condition('type', gaf.EFFECT_DROP_SHADOW, s.fields( // DropShadow
+ 'color', 'color',
+ 'blurX', 'Float',
+ 'blurY', 'Float',
+ 'angle', 'Float',
+ 'distance', 'Float',
+ 'strength', 'Float',
+ 'inner', 'Boolean',
+ 'knockout', 'Boolean'
+ )),
+ 'blur', s.condition('type', gaf.EFFECT_BLUR, s.fields( // Blur
+ 'blurX', 'Float',
+ 'blurY', 'Float'
+ )),
+ 'glow', s.condition('type', gaf.EFFECT_GLOW, s.fields( // Glow
+ 'color', 'color',
+ 'blurX', 'Float',
+ 'blurY', 'Float',
+ 'strength', 'Float',
+ 'inner', 'Boolean',
+ 'knockout', 'Boolean'
+ )),
+ 'colorMatrix', s.condition('type', gaf.EFFECT_COLOR_MATRIX, s.fields( // ColorMatrix
+ 'rr', 'Float', 'gr', 'Float', 'br', 'Float', 'ar', 'Float', 'r', 'Float',
+ 'rg', 'Float', 'gg', 'Float', 'bg', 'Float', 'ag', 'Float', 'g', 'Float',
+ 'rb', 'Float', 'gb', 'Float', 'bb', 'Float', 'ab', 'Float', 'b', 'Float',
+ 'ra', 'Float', 'ga', 'Float', 'ba', 'Float', 'aa', 'Float', 'a', 'Float'
+ ))
+ )
+};
+
+gaf.Tags = new gaf.Tag();
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFTextField.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFTextField.js
new file mode 100644
index 0000000..04f9744
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFTextField.js
@@ -0,0 +1,6 @@
+
+gaf.TextField = gaf.Object.extend
+({
+ _className: "GAFTextField"
+
+});
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFTimeLine.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFTimeLine.js
new file mode 100644
index 0000000..ef9387a
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFTimeLine.js
@@ -0,0 +1,547 @@
+
+gaf.TimeLine = gaf.Object.extend
+({
+ _className: "GAFTimeLine",
+ _objects: null,
+ _container: null,
+ _animationStartedNextLoopDelegate: null,
+ _animationFinishedPlayDelegate: null,
+ _framePlayedDelegate: null,
+ _sequenceDelegate: null,
+ _fps: 60,
+ _frameTime: 1/60,
+ _currentSequenceStart: gaf.FIRST_FRAME_INDEX,
+ _currentSequenceEnd: gaf.FIRST_FRAME_INDEX,
+ _totalFrameCount: 0,
+ _isRunning: false,
+ _isLooped: false,
+ _isReversed: false,
+ _timeDelta: 0,
+ _animationsSelectorScheduled: false,
+ _currentFrame: gaf.FIRST_FRAME_INDEX,
+
+
+ setAnimationStartedNextLoopDelegate: function (delegate)
+ {
+ this._animationStartedNextLoopDelegate = delegate;
+ },
+ setAnimationFinishedPlayDelegate: function (delegate)
+ {
+ this._animationFinishedPlayDelegate = delegate;
+ },
+ setLooped: function (looped, recursively)
+ {
+ this._isLooped = looped;
+ if (recursively)
+ {
+ this._objects.forEach(function (item)
+ {
+ item.setLooped(looped, recursively);
+ });
+ }
+ },
+ getBoundingBoxForCurrentFrame: function ()
+ {
+ var result = null;//cc.rect();
+ var isFirstObj = true;
+ this._objects.forEach(function (item) {
+ if(item.isVisibleInCurrentFrame() && item.isVisible())
+ {
+ var bb = item.getBoundingBoxForCurrentFrame();
+ if(!bb)
+ {
+ bb = item.getBoundingBox();
+ }
+ if (isFirstObj)
+ {
+ isFirstObj = false;
+ result = bb;
+ }
+ else
+ {
+ result = cc.rectUnion(result, bb);
+ }
+ }
+ });
+ return cc._rectApplyAffineTransformIn(result, this._container.getNodeToParentTransform());
+ },
+ setFps: function (fps)
+ {
+ cc.assert(fps !== 0, 'Error! Fps is set to zero.');
+ this._fps = fps;
+ this._frameTime = 1/fps;
+ },
+ getObjectByName: function (name)
+ {
+ var elements = name.split('.');
+ var result = null;
+ var retId = -1;
+ var timeLine = this;
+ var BreakException = {};
+ try
+ {
+ elements.forEach(function(element)
+ {
+ var parts = timeLine._gafproto.getNamedParts();
+ if(parts.hasOwnProperty(element))
+ {
+ retId = parts[element];
+ }
+ else
+ {
+ // Sequence is incorrect
+ BreakException.lastElement = element;
+ throw BreakException;
+ }
+ result = timeLine._objects[retId];
+ timeLine = result;
+ });
+ }
+ catch (e)
+ {
+ if (e!==BreakException)
+ {
+ throw e;
+ }
+ cc.log("Sequence incorrect: `" + name + "` At: `" + BreakException.lastElement + "`");
+ return null;
+ }
+ return result;
+ },
+ clearSequence: function ()
+ {
+ this._currentSequenceStart = gaf.FIRST_FRAME_INDEX;
+ this._currentSequenceEnd = this._gafproto.getTotalFrames();
+ },
+ getIsAnimationRunning: function ()
+ {
+ return this._isRunning;
+ },
+ gotoAndStop: function (value)
+ {
+ var frame = 0;
+ if (typeof value === 'string')
+ {
+ frame = this.getStartFrame(value);
+ }
+ else
+ {
+ frame = value;
+ }
+ if (this.setFrame(frame))
+ {
+ this.setAnimationRunning(false, false);
+ return true;
+ }
+ return false;
+ },
+ gotoAndPlay: function (value)
+ {
+ var frame = 0;
+ if (typeof value === 'string')
+ {
+ frame = this.getStartFrame(value);
+ }
+ else
+ {
+ frame = value;
+ }
+ if (this.setFrame(frame))
+ {
+ this.setAnimationRunning(true, false);
+ return true;
+ }
+ return false;
+ },
+ getStartFrame: function (frameLabel)
+ {
+ var seq = this._gafproto.getSequences()[frameLabel];
+ if (seq)
+ {
+ return seq.start;
+ }
+ return gaf.IDNONE;
+ },
+ getEndFrame: function (frameLabel)
+ {
+ var seq = this._gafproto.getSequences()[frameLabel];
+ if (seq)
+ {
+ return seq.end;
+ }
+ return gaf.IDNONE;
+ },
+ setFramePlayedDelegate: function (delegate)
+ {
+ this._framePlayedDelegate = delegate;
+ },
+ getCurrentFrameIndex: function ()
+ {
+ return this._showingFrame;
+ },
+ getTotalFrameCount: function ()
+ {
+ return this._gafproto.getTotalFrames();
+ },
+ start: function ()
+ {
+ this._enableTick(true);
+ if (!this._isRunning)
+ {
+ this._currentFrame = gaf.FIRST_FRAME_INDEX;
+ this.setAnimationRunning(true, true);
+ }
+ },
+ stop: function ()
+ {
+ this._enableTick(false);
+ if (this._isRunning)
+ {
+ this._currentFrame = gaf.FIRST_FRAME_INDEX;
+ this.setAnimationRunning(false, true);
+ }
+ },
+ isDone: function ()
+ {
+ if (this._isLooped)
+ {
+ return false;
+ }
+ else
+ {
+ if (!this._isReversed)
+ {
+ return this._currentFrame > this._totalFrameCount;
+ }
+ else
+ {
+ return this._currentFrame < gaf.FIRST_FRAME_INDEX - 1;
+ }
+ }
+ },
+ getSequences: function()
+ {
+ return this._gafproto.getSequences();
+ },
+ playSequence: function (name, looped)
+ {
+ var s = this.getStartFrame(name);
+ var e = this.getEndFrame(name);
+ if (gaf.IDNONE === s || gaf.IDNONE === e)
+ {
+ return false;
+ }
+ this._currentSequenceStart = s;
+ this._currentSequenceEnd = e;
+ if (this._currentFrame < this._currentSequenceStart || this._currentFrame > this._currentSequenceEnd)
+ {
+ this._currentFrame = this._currentSequenceStart;
+ }
+ else
+ {
+ this._currentFrame = this._currentSequenceStart;
+ }
+ this.setLooped(looped, false);
+ this.resumeAnimation();
+ return true;
+ },
+ isReversed: function ()
+ {
+ return this._isReversed;
+ },
+ setSequenceDelegate: function (delegate)
+ {
+ this._sequenceDelegate = delegate;
+ },
+ setFrame: function (index)
+ {
+ if (index >= gaf.FIRST_FRAME_INDEX && index < this._totalFrameCount)
+ {
+ this._showingFrame = index;
+ this._currentFrame = index;
+ this._processAnimation();
+ return true;
+ }
+ return false;
+ },
+
+ pauseAnimation: function ()
+ {
+ if (this._isRunning)
+ {
+ this.setAnimationRunning(false, false);
+ }
+ },
+ isLooped: function ()
+ {
+ return this._isLooped;
+ },
+ resumeAnimation: function ()
+ {
+ if (!this._isRunning)
+ {
+ this.setAnimationRunning(true, false);
+ }
+ },
+ setReversed: function (reversed)
+ {
+ this._isReversed = reversed;
+ },
+ hasSequences: function ()
+ {
+ return this._gafproto.getSequences().length > 0;
+ },
+ getFps: function ()
+ {
+ return this._fps;
+ },
+
+
+ // Private
+
+ ctor: function(gafTimeLineProto, scale)
+ {
+ this._super(scale);
+ this._objects = [];
+ cc.assert(gafTimeLineProto, "Error! Missing mandatory parameter.");
+ this._gafproto = gafTimeLineProto;
+ },
+
+ setExternalTransform: function(affineTransform)
+ {
+ if(!cc.affineTransformEqualToTransform(this._container._additionalTransform, affineTransform))
+ {
+ this._container.setAdditionalTransform(affineTransform);
+ }
+ },
+
+ _init: function()
+ {
+ this.setContentSize(this._gafproto.getBoundingBox());
+ this._currentSequenceEnd = this._gafproto.getTotalFrames();
+ this._totalFrameCount = this._currentSequenceEnd;
+ this.setFps(this._gafproto.getFps());
+ this._container = new cc.Node();
+ this.addChild(this._container);
+
+ var self = this;
+ var asset = this._gafproto.getAsset();
+
+ // Construct objects for current time line
+ this._gafproto.getObjects().forEach(function(object)
+ {
+ var objectProto = asset._getProtos()[object];
+ cc.assert(objectProto, "Error. GAF proto for type: " + object.type + " and reference id: " + object + " not found.");
+ self._objects[object] = objectProto._gafConstruct();
+ });
+ },
+
+ _enableTick: function(val)
+ {
+ if (!this._animationsSelectorScheduled && val)
+ {
+ this.schedule(this._processAnimations);
+ this._animationsSelectorScheduled = true;
+ }
+ else if (this._animationsSelectorScheduled && !val)
+ {
+ this.unschedule(this._processAnimations);
+ this._animationsSelectorScheduled = false;
+ }
+ },
+
+ _processAnimations: function (dt)
+ {
+ this._timeDelta += dt;
+ while (this._timeDelta >= this._frameTime)
+ {
+ this._timeDelta -= this._frameTime;
+ this._step();
+ }
+ },
+
+ _step: function ()
+ {
+ this._showingFrame = this._currentFrame;
+
+ if(!this.getIsAnimationRunning())
+ {
+ this._processAnimation();
+ return;
+ }
+
+ if(this._sequenceDelegate)
+ {
+ var seq;
+ if(!this._isReversed)
+ {
+ seq = this._getSequenceByLastFrame(this._currentFrame);
+ }
+ else
+ {
+ seq = this._getSequenceByFirstFrame(this._currentFrame + 1);
+ }
+
+ if (seq)
+ {
+ this._sequenceDelegate(this, seq);
+ }
+ }
+ if (this._isCurrentFrameLastInSequence())
+ {
+ if(this._isLooped)
+ {
+ if(this._animationStartedNextLoopDelegate)
+ this._animationStartedNextLoopDelegate(this);
+ }
+ else
+ {
+ this.setAnimationRunning(false, false);
+ if(this._animationFinishedPlayDelegate)
+ this._animationFinishedPlayDelegate(this);
+ }
+ }
+ this._processAnimation();
+ this._currentFrame = this._nextFrame();
+ },
+
+ _isCurrentFrameLastInSequence: function()
+ {
+ if (this._isReversed)
+ return this._currentFrame == this._currentSequenceStart;
+ return this._currentFrame == this._currentSequenceEnd - 1;
+ },
+
+ _nextFrame: function()
+ {
+ if (this._isCurrentFrameLastInSequence())
+ {
+ if (!this._isLooped)
+ return this._currentFrame;
+
+ if (this._isReversed)
+ return this._currentSequenceEnd - 1;
+ else
+ return this._currentSequenceStart;
+ }
+
+ return this._currentFrame + (this._isReversed ? -1 : 1);
+ },
+
+ _processAnimation: function ()
+ {
+ //var id = this._gafproto.getId();
+ this._realizeFrame(this._container, this._currentFrame);
+ if (this._framePlayedDelegate)
+ {
+ this._framePlayedDelegate(this, this._currentFrame);
+ }
+ },
+ _realizeFrame: function(out, frameIndex)
+ {
+ var self = this;
+ var objects = self._objects;
+ var frames = self._gafproto.getFrames();
+ if(frameIndex > frames.length)
+ {
+ return;
+ }
+ var currentFrame = frames[frameIndex];
+ if(!currentFrame)
+ {
+ return;
+ }
+ var states = currentFrame.states;
+ for(var stateIdx = 0, total = states.length; stateIdx < total; ++stateIdx)
+ {
+ var state = states[stateIdx];
+ var object = objects[state.objectIdRef];
+ if(!object)
+ {
+ return;
+ }
+ if(state.alpha < 0)
+ {
+ object._resetState();
+ }
+ object._updateVisibility(state, self);
+ if(!object.isVisible())
+ {
+ continue;
+ }
+ object._applyState(state, self);
+ var parent = out;
+ if(state.hasMask)
+ {
+ parent = objects[state.maskObjectIdRef]._getNode();
+ cc.assert(parent, "Error! Mask not found.");
+ }
+ object._lastVisibleInFrame = 1 + frameIndex;
+ gaf.TimeLine.rearrangeSubobject(parent, object, state.depth);
+ if(object._step)
+ {
+ object._step();
+ }
+ }
+ },
+ setAnimationRunning: function (value, recursively)
+ {
+ this._isRunning = value;
+ if(recursively)
+ {
+ this._objects.forEach(function (obj)
+ {
+ if (obj && obj.setAnimationRunning)
+ {
+ obj.setAnimationRunning(value, recursively);
+ }
+ });
+ }
+ },
+
+ _getSequenceByLastFrame: function(){
+ var sequences = this._gafproto.getSequences();
+ for(var item in sequences){
+ if(sequences.hasOwnProperty(item)){
+ if(sequences[item].end === frame + 1)
+ {
+ return item;
+ }
+ }
+ }
+ return "";
+ },
+
+ _resetState : function()
+ {
+ this._super();
+ this._currentFrame = this._currentSequenceStart;
+ },
+
+ _getSequenceByFirstFrame: function(){
+ var sequences = this._gafproto.getSequences();
+ for(var item in sequences){
+ if(sequences.hasOwnProperty(item)){
+ if(sequences[item].start === frame)
+ {
+ return item;
+ }
+ }
+ }
+ return "";
+ }
+});
+
+gaf.TimeLine.rearrangeSubobject = function(out, object, depth)
+{
+ var parent = object.getParent();
+ if (parent !== out)
+ {
+ object.removeFromParent(false);
+ out.addChild(object, depth);
+ }
+ else
+ {
+ object.setLocalZOrder(depth);
+ }
+};
diff --git a/frameworks/cocos2d-html5/external/gaf/Library/GAFTimeLineProto.js b/frameworks/cocos2d-html5/external/gaf/Library/GAFTimeLineProto.js
new file mode 100644
index 0000000..9d78b21
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/Library/GAFTimeLineProto.js
@@ -0,0 +1,32 @@
+
+gaf._TimeLineProto = function(asset, animationFrameCount, boundingBox, pivotPoint, id, linkageName)
+{
+ id = typeof id != 'undefined' ? id : 0;
+ linkageName = linkageName || "";
+
+ this._objects = [];
+
+ this.getTotalFrames = function(){return animationFrameCount};
+ this.getBoundingBox = function() {return boundingBox};
+ this.getId = function() {return id};
+ this.getLinkageName = function() {return linkageName};
+ this.getPivot = function(){return pivotPoint};
+ this.getRect = function(){return boundingBox};
+ this.getNamedParts = function() {return {}}; // Map name -> id
+ this.getSequences = function() {return {}}; // Map name -> {start, end}
+ this.getFrames = function(){return []}; // Array {states, actions}
+ this.getFps = function(){return 60};
+ this.getObjects = function(){return this._objects};
+ this.getAsset = function(){return asset};
+
+ /*
+ * Will construct GAFTimeLine
+ */
+ this._gafConstruct = function()
+ {
+ var usedScale = this.getAsset()._usedAtlasScale;
+ var ret = new gaf.TimeLine(this, usedScale);
+ ret._init();
+ return ret;
+ };
+};
diff --git a/frameworks/cocos2d-html5/external/gaf/gaf_viewer.css b/frameworks/cocos2d-html5/external/gaf/gaf_viewer.css
new file mode 100644
index 0000000..6093316
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/gaf_viewer.css
@@ -0,0 +1,42 @@
+#drop_zone {
+ border: 2px dashed #bbb;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ padding: 25px;
+ text-align: center;
+ font: 20pt bold 'Vollkorn';
+ color: #bbb;
+
+}
+.renderjson a {
+ text-decoration: none;
+}
+.renderjson .disclosure {
+ color: crimson;
+ font-size: 150%;
+}
+.renderjson .syntax {
+ color: grey;
+}
+.renderjson .string {
+ color: darkred;
+}
+.renderjson .number {
+ color: darkcyan;
+}
+.renderjson .boolean {
+ color: blueviolet;
+}
+.renderjson .key {
+ color: darkblue;
+}
+.renderjson .keyword {
+ color: blue;
+}
+.renderjson .object.syntax {
+ color: lightseagreen;
+}
+.renderjson .array.syntax {
+ color: orange;
+}
diff --git a/frameworks/cocos2d-html5/external/gaf/gaf_viewer.html b/frameworks/cocos2d-html5/external/gaf/gaf_viewer.html
new file mode 100644
index 0000000..2c66aeb
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/gaf_viewer.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Drop GAF here
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/external/gaf/gaf_viewer.js b/frameworks/cocos2d-html5/external/gaf/gaf_viewer.js
new file mode 100644
index 0000000..98d247c
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/gaf/gaf_viewer.js
@@ -0,0 +1,219 @@
+ /*
+ * Created by Teivaz on 29.11.2014.
+ * Thanks to David Caldwell for `renderjson`
+ */
+function handleFileSelect(evt) {
+ evt.stopPropagation();
+ evt.preventDefault();
+
+ var files = evt.dataTransfer.files;
+
+ var output = [];
+ for (var i = 0, f; f = files[i]; i++) {
+ var name = escape(f.name);
+ var ext = name.split('.').pop();
+ if (ext == 'gaf') {
+ var reader = new FileReader();
+ reader.onload = (function(theFile) {
+ return function(req) {
+ var arrayBuffer = new gaf.DataReader(req.target.result);
+ var loader = new gaf.Loader();
+ var data = loader.LoadStream(arrayBuffer);
+ document.getElementById('list').appendChild(renderjson(data));
+ };
+ })(f);
+ reader.readAsArrayBuffer(f);
+ }
+ }
+}
+
+function handleDragOver(evt) {
+ evt.stopPropagation();
+ evt.preventDefault();
+ evt.dataTransfer.dropEffect = 'copy';
+}
+
+var dropZone = document.getElementById('drop_zone');
+dropZone.addEventListener('dragover', handleDragOver, false);
+dropZone.addEventListener('drop', handleFileSelect, false);
+
+var module;
+(module || {}).exports = renderjson = (function() {
+ var themetext = function( /* [class, text]+ */ ) {
+ var spans = [];
+ while (arguments.length)
+ spans.push(append(span(Array.prototype.shift.call(arguments)),
+ text(Array.prototype.shift.call(arguments))));
+ return spans;
+ };
+ var append = function( /* el, ... */ ) {
+ var el = Array.prototype.shift.call(arguments);
+ for (var a = 0; a < arguments.length; a++)
+ if (arguments[a].constructor == Array)
+ append.apply(this, [el].concat(arguments[a]));
+ else
+ el.appendChild(arguments[a]);
+ return el;
+ };
+ var prepend = function(el, child) {
+ el.insertBefore(child, el.firstChild);
+ return el;
+ };
+ var isempty = function(obj) {
+ for (var k in obj)
+ if (obj.hasOwnProperty(k)) return false;
+ return true;
+ };
+ var text = function(txt) {
+ return document.createTextNode(txt)
+ };
+ var div = function() {
+ return document.createElement("div")
+ };
+ var span = function(classname) {
+ var s = document.createElement("span");
+ if (classname) s.className = classname;
+ return s;
+ };
+ var A = function A(txt, classname, callback) {
+ var a = document.createElement("a");
+ if (classname) a.className = classname;
+ a.appendChild(text(txt));
+ a.href = '#';
+ a.onclick = function() {
+ callback();
+ return false;
+ };
+ return a;
+ };
+
+ function _renderjson(json, indent, dont_indent, show_level, sort_objects) {
+ var my_indent = dont_indent ? "" : indent;
+
+ if (json === null) return themetext(null, my_indent, "keyword", "null");
+ if (json === void 0) return themetext(null, my_indent, "keyword", "undefined");
+ if (typeof(json) != "object") // Strings, numbers and bools
+ return themetext(null, my_indent, typeof(json), JSON.stringify(json));
+
+ var disclosure = function(open, close, type, builder) {
+ var content;
+ var empty = span(type);
+ var show = function() {
+ if (!content) append(empty.parentNode,
+ content = prepend(builder(),
+ A(renderjson.hide, "disclosure",
+ function() {
+ content.style.display = "none";
+ empty.style.display = "inline";
+ })));
+ content.style.display = "inline";
+ empty.style.display = "none";
+ };
+
+ function isColor(a){
+ return a.hasOwnProperty('a') && a.hasOwnProperty('r') && a.hasOwnProperty('g') && a.hasOwnProperty('b');
+ }
+
+ var color_rect = span();
+ if (json.hasOwnProperty("tagName"))
+ var placeholder = json.tagName;
+ else if (json.hasOwnProperty("header"))
+ placeholder = " GAF v" + json.header.versionMajor + "." + json.header.versionMinor + " ";
+ else if (json.constructor == Array)
+ placeholder = " " + json.length + " ";
+ else if (json.hasOwnProperty("id"))
+ placeholder = " id:" + json.id + " ... ";
+ else if (json.hasOwnProperty("objectId"))
+ placeholder = " id:" + json.objectId + " ... ";
+ else if (json.hasOwnProperty("frame"))
+ placeholder = " frame:" + json.frame + " ... ";
+ else if(isColor(json)){
+ color_rect.style.backgroundColor = "rgba("+json.r+","+json.g+","+json.b+","+json.a / 255.0+")";// parseInt(json.r).toString(16) + parseInt(json.g).toString(16) + parseInt(json.b).toString(16);
+ color_rect.style.height = '10px';
+ color_rect.style.width = '10px';
+ color_rect.style.display = 'inline-block';
+ color_rect.style.margin = '0 4px';
+ color_rect.style.border = '1px solid #7f7f7f';
+ }
+
+ placeholder = placeholder || ' ... ';
+ append(empty,
+ A(renderjson.show, "disclosure", show),
+ color_rect,
+ themetext(type + " syntax", open),
+ A(placeholder, null, show),
+ themetext(type + " syntax", close));
+
+ var el = append(span(), text(my_indent.slice(0, -1)), empty);
+ if (show_level > 0)
+ show();
+ return el;
+ };
+
+ if (json.constructor == Array) {
+ if (json.length == 0) return themetext(null, my_indent, "array syntax", "[]");
+
+ return disclosure("[", "]", "array", function() {
+ var as = append(span("array"), themetext("array syntax", "[", null, "\n"));
+ for (var i = 0; i < json.length; i++)
+ append(as,
+ _renderjson(json[i], indent + " ", false, show_level - 1, sort_objects),
+ i != json.length - 1 ? themetext("syntax", ",") : [],
+ text("\n"));
+ append(as, themetext(null, indent, "array syntax", "]"));
+ return as;
+ });
+ }
+
+ // object
+ if (isempty(json))
+ return themetext(null, my_indent, "object syntax", "{}");
+
+
+ return disclosure("{", "}", "object", function() {
+ var os = append(span("object"), themetext("object syntax", "{", null, "\n"));
+ for (var k in json) var last = k;
+ var keys = Object.keys(json);
+ if (sort_objects)
+ keys = keys.sort();
+ for (var i in keys) {
+ var k = keys[i];
+ append(os, themetext(null, indent + " ", "key", '"' + k + '"', "object syntax", ': '),
+ _renderjson(json[k], indent + " ", true, show_level - 1, sort_objects),
+ k != last ? themetext("syntax", ",") : [],
+ text("\n"));
+ }
+ append(os, themetext(null, indent, "object syntax", "}"));
+ return os;
+ });
+ }
+
+ var renderjson = function renderjson(json) {
+ var pre = append(document.createElement("pre"), _renderjson(json, "", false, renderjson.show_to_level, renderjson.sort_objects));
+ pre.className = "renderjson";
+ return pre;
+ };
+ renderjson.set_icons = function(show, hide) {
+ renderjson.show = show;
+ renderjson.hide = hide;
+ return renderjson;
+ };
+ renderjson.set_show_to_level = function(level) {
+ renderjson.show_to_level = typeof level == "string" &&
+ level.toLowerCase() === "all" ? Number.MAX_VALUE : level;
+ return renderjson;
+ };
+ renderjson.set_sort_objects = function(sort_bool) {
+ renderjson.sort_objects = sort_bool;
+ return renderjson;
+ };
+ // Backwards compatibility. Use set_show_to_level() for new code.
+ renderjson.set_show_by_default = function(show) {
+ renderjson.show_to_level = show ? Number.MAX_VALUE : 0;
+ return renderjson;
+ };
+ renderjson.set_icons('⊕', '⊖');
+ renderjson.set_show_by_default(false);
+ renderjson.set_sort_objects(false);
+ return renderjson;
+})();
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/external/pluginx/Plugin.js b/frameworks/cocos2d-html5/external/pluginx/Plugin.js
new file mode 100644
index 0000000..e2bc145
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/pluginx/Plugin.js
@@ -0,0 +1,253 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * plugin manager
+ * @class
+ *
+ */
+(function(){
+
+ if(cc === undefined){
+ return;
+ }
+
+ //Native plugin usage
+ var PluginManager = function(){};
+
+ PluginManager.prototype = {
+ constructor: PluginManager,
+
+ /**
+ * @returns {PluginManager}
+ * @expose
+ */
+ getInstance: function(){
+ return this;
+ },
+
+ /**
+ * @param {String} pluginName
+ * @expose
+ */
+ loadPlugin: function(pluginName){
+
+ },
+
+ /**
+ *
+ * @param pluginName
+ * @expose
+ */
+ unloadPlugin: function(pluginName){
+
+ }
+ };
+
+ var PluginAssembly = function(){};
+
+ PluginAssembly.prototype = {
+ constructor: PluginAssembly,
+
+ /**
+ * @param {Boolean} debug
+ * @expose
+ */
+ setDebugMode: function(debug){},
+
+ /**
+ * @param {String} appKey
+ * @expose
+ */
+ startSession: function(appKey){},
+
+ /**
+ * @param {Boolean} Capture
+ * @expose
+ */
+ setCaptureUncaughtException: function(Capture){},
+
+ /**
+ * @param {String} funName
+ * @param {All} Params
+ * @expose
+ */
+ callFuncWithParam: function(funName){
+ if(typeof this[funName] === 'function'){
+ return this[funName].apply(this, Array.prototype.splice.call(arguments, 1));
+ }else{
+ cc.log("function is not define");
+ }
+ },
+
+ /**
+ * @param {String} funName
+ * @param {All} Params
+ * @expose
+ */
+ callStringFuncWithParam: function(funName){
+ this.callFuncWithParam.apply(arguments);
+ },
+
+ /**
+ * @returns {String}
+ * @expose
+ */
+ getPluginName: function(){
+ return this._name;
+ },
+
+ /**
+ * @returns {String}
+ * @expose
+ */
+ getPluginVersion: function(){
+ return this._version;
+ }
+ };
+
+ /** @expose */
+ PluginAssembly.extend = function(name, porp){
+ var p, prototype = {};
+ for(p in PluginAssembly.prototype){
+ prototype[p] = PluginAssembly.prototype[p];
+ }
+ for(p in porp){
+ prototype[p] = porp[p];
+ }
+ var tmp = eval("(function " + name + "Plugin(){})");
+ prototype.constructor = tmp;
+ tmp.prototype = prototype;
+ return tmp;
+ };
+
+ //Param
+ var Param = function(type, value){
+ var paramType = plugin.PluginParam.ParamType,tmpValue;
+ switch(type){
+ case paramType.TypeInt:
+ tmpValue = parseInt(value);
+ break;
+ case paramType.TypeFloat:
+ tmpValue = parseFloat(value);
+ break;
+ case paramType.TypeBool:
+ tmpValue = Boolean(value);
+ break;
+ case paramType.TypeString:
+ tmpValue = String(value);
+ break;
+ case paramType.TypeStringMap:
+ tmpValue = value//JSON.stringify(value);
+ break;
+ default:
+ tmpValue = value;
+ }
+ return tmpValue
+ };
+
+ /** @expose */
+ Param.ParamType = {
+ /** @expose */
+ TypeInt:1,
+ /** @expose */
+ TypeFloat:2,
+ /** @expose */
+ TypeBool:3,
+ /** @expose */
+ TypeString:4,
+ /** @expose */
+ TypeStringMap:5
+ };
+
+ /** @expose */
+ Param.AdsResultCode = {
+ /** @expose */
+ AdsReceived:0,
+ /** @expose */
+ FullScreenViewShown:1,
+ /** @expose */
+ FullScreenViewDismissed:2,
+ /** @expose */
+ PointsSpendSucceed:3,
+ /** @expose */
+ PointsSpendFailed:4,
+ /** @expose */
+ NetworkError:5,
+ /** @expose */
+ UnknownError:6
+ };
+
+ /** @expose */
+ Param.PayResultCode = {
+ /** @expose */
+ PaySuccess:0,
+ /** @expose */
+ PayFail:1,
+ /** @expose */
+ PayCancel:2,
+ /** @expose */
+ PayTimeOut:3
+ };
+
+ /** @expose */
+ Param.ShareResultCode = {
+ /** @expose */
+ ShareSuccess:0,
+ /** @expose */
+ ShareFail:1,
+ /** @expose */
+ ShareCancel:2,
+ /** @expose */
+ ShareTimeOut:3
+ };
+
+ /** @expose */
+ var PluginList = {};
+
+ /** @expose */
+ var Plugin = {
+
+ /** @expose */
+ extend: function(name, extend){
+ var config = (cc.game.config && cc.game.config.plugin) || {};
+ PluginList[name] = new (PluginAssembly.extend(name, extend));
+ typeof PluginList[name].ctor === "function" && PluginList[name].ctor(config[name]);
+ },
+
+ /** @expose */
+ PluginList: PluginList,
+
+ /** @expose */
+ PluginParam: Param,
+
+ /** @expose */
+ PluginManager: new PluginManager()
+
+ };
+
+ /** @expose */
+ window.plugin = Plugin;
+
+})();
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/external/pluginx/platform/facebook.js b/frameworks/cocos2d-html5/external/pluginx/platform/facebook.js
new file mode 100644
index 0000000..1901159
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/pluginx/platform/facebook.js
@@ -0,0 +1,557 @@
+/****************************************************************************
+ Copyright (c) 2013-2014 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+/**
+ * Facebook SDK for Web Platform
+ * FacebookAgent...
+ *
+ * @property {String} name - plugin name
+ * @property {String} version - API version
+ */
+plugin.extend('facebook', {
+ name: "",
+ version: "",
+ _userInfo: null,
+ _isLoggedIn: false,
+
+ /**
+ * HTTP methods constants
+ * @constant
+ * @type {Object}
+ */
+ HttpMethod: {
+ 'GET': 'get',
+ 'POST': 'post',
+ 'DELETE': 'delete'
+ },
+
+ /**
+ * Succeed code returned in callbacks
+ * @constant
+ * @type {Number}
+ */
+ CODE_SUCCEED: 0,
+
+ /**
+ * App event names constants
+ * @constant
+ * @type {Object}
+ */
+ AppEvent: {
+ 'ACTIVATED_APP': FB.AppEvents.EventNames.ACTIVATED_APP,
+ 'COMPLETED_REGISTRATION': FB.AppEvents.EventNames.COMPLETED_REGISTRATION,
+ 'VIEWED_CONTENT': FB.AppEvents.EventNames.VIEWED_CONTENT,
+ 'SEARCHED': FB.AppEvents.EventNames.SEARCHED,
+ 'RATED': FB.AppEvents.EventNames.RATED,
+ 'COMPLETED_TUTORIAL': FB.AppEvents.EventNames.COMPLETED_TUTORIAL,
+ 'ADDED_TO_CART': FB.AppEvents.EventNames.ADDED_TO_CART,
+ 'ADDED_TO_WISHLIST': FB.AppEvents.EventNames.ADDED_TO_WISHLIST,
+ 'INITIATED_CHECKOUT': FB.AppEvents.EventNames.INITIATED_CHECKOUT,
+ 'ADDED_PAYMENT_INFO': FB.AppEvents.EventNames.ADDED_PAYMENT_INFO,
+ 'PURCHASED': FB.AppEvents.EventNames.PURCHASED,
+ 'ACHIEVED_LEVEL': FB.AppEvents.EventNames.ACHIEVED_LEVEL,
+ 'UNLOCKED_ACHIEVEMENT': FB.AppEvents.EventNames.UNLOCKED_ACHIEVEMENT,
+ 'SPENT_CREDITS': FB.AppEvents.EventNames.SPENT_CREDITS
+ },
+
+ /**
+ * App event parameter names constants
+ * @constant
+ * @type {Object}
+ */
+ AppEventParam: {
+ 'CURRENCY': FB.AppEvents.ParameterNames.CURRENCY,
+ 'REGISTRATION_METHOD': FB.AppEvents.ParameterNames.REGISTRATION_METHOD,
+ 'CONTENT_TYPE': FB.AppEvents.ParameterNames.CONTENT_TYPE,
+ 'CONTENT_ID': FB.AppEvents.ParameterNames.CONTENT_ID,
+ 'SEARCH_STRING': FB.AppEvents.ParameterNames.SEARCH_STRING,
+ 'SUCCESS': FB.AppEvents.ParameterNames.SUCCESS,
+ 'MAX_RATING_VALUE': FB.AppEvents.ParameterNames.MAX_RATING_VALUE,
+ 'PAYMENT_INFO_AVAILABLE': FB.AppEvents.ParameterNames.PAYMENT_INFO_AVAILABLE,
+ 'NUM_ITEMS': FB.AppEvents.ParameterNames.NUM_ITEMS,
+ 'LEVEL': FB.AppEvents.ParameterNames.LEVEL,
+ 'DESCRIPTION': FB.AppEvents.ParameterNames.DESCRIPTION
+ },
+
+ /**
+ * App event parameter values constants
+ * @constant
+ * @type {Object}
+ */
+ AppEventParamValue: {
+ 'VALUE_YES': "1",
+ 'VALUE_NO': "0"
+ },
+
+ _checkLoginStatus: function() {
+ var self = this;
+ FB.getLoginStatus(function (response) {
+ if (response && response.status === 'connected') {
+ //login
+ self._isLoggedIn = true;
+ //save user info
+ self._userInfo = response['authResponse'];
+ } else {
+ // Reset cached status
+ self._isLoggedIn = false;
+ self._userInfo = {};
+ }
+ });
+ },
+
+ ctor: function (config) {
+ this.name = "facebook";
+ this.version = "1.0";
+ this._userInfo = {};
+ this._isLoggedIn = false;
+
+ if (!FB) {
+ return;
+ }
+
+ //This configuration will be read from the project.json.
+ FB.init(config);
+ this._checkLoginStatus();
+
+ plugin.FacebookAgent = this;
+ },
+ /**
+ * Gets the current object
+ * @returns {FacebookAgent}
+ */
+ getInstance: function () {
+ return this;
+ },
+ /**
+ * Login to facebook
+ * @param {Function} callback
+ * @param {Array} permissions
+ * @example
+ * //example
+ * plugin.FacebookAgent.login();
+ */
+ login: function (permissions, callback) {
+ var self = this;
+ if (typeof permissions == 'function') {
+ callback = permissions;
+ permissions = [];
+ }
+ if (permissions.every(function (item) {
+ if (item != 'public_profile')
+ return true;
+ })) {
+ permissions.push("public_profile");
+ }
+ var permissionsStr = permissions.join(',');
+ FB.login(function (response) {
+ if (response['authResponse']) {
+ //save user info
+ self._isLoggedIn = true;
+ self._userInfo = response['authResponse'];
+ var permissList = response['authResponse']['grantedScopes'].split(",");
+ typeof callback === 'function' && callback(0, {
+ accessToken: response['authResponse']['accessToken'],
+ permissions: permissList
+ });
+ } else {
+ self._isLoggedIn = false;
+ self._userInfo = {};
+ typeof callback === 'function' && callback(response['error_code'] || 1, {
+ error_message: response['error_message'] || "Unknown error"
+ });
+ }
+ }, {
+ scope: permissionsStr,
+ return_scopes: true
+ });
+ },
+ /**
+ * Checking login status
+ * @return {Bool} Whether user is logged in
+ * @example
+ * //example
+ * plugin.FacebookAgent.isLoggedIn(type, msg);
+ */
+ isLoggedIn: function () {
+ //this._checkLoginStatus();
+ return this._isLoggedIn;
+ },
+
+ /**
+ * Logout of facebook
+ * @param {Function} callback
+ * @example
+ * //example
+ * plugin.FacebookAgent.logout(callback);
+ */
+ logout: function (callback) {
+ var self = this;
+ FB.logout(function (response) {
+ if (response['authResponse']) {
+ // user is now logged out
+ self._isLoggedIn = false;
+ self._userInfo = {};
+ typeof callback === 'function' && callback(0, {"isLoggedIn": false});
+ } else {
+ typeof callback === 'function' && callback(response['error_code'] || 1, {
+ error_message: response['error_message'] || "Unknown error"
+ });
+ }
+ });
+ },
+
+ /**
+ * Acquiring new permissions
+ * @deprecated since v3.0
+ * @param permissions
+ * @param callback
+ * @example
+ * //example
+ * plugin.FacebookAgent.requestPermissions(["manage_pages"], callback);
+ */
+ _requestPermissions: function (permissions, callback) {
+ var permissionsStr = permissions.join(',');
+ var self = this;
+ FB.login(function (response) {
+ if (response['authResponse']) {
+ var permissList = response['authResponse']['grantedScopes'].split(",");
+ //save user info
+ self._isLoggedIn = true;
+ self._userInfo = response['authResponse'];
+ typeof callback === 'function' && callback(0, {
+ permissions: permissList
+ });
+ } else {
+ self._isLoggedIn = false;
+ self._userInfo = {};
+ typeof callback === 'function' && callback(response['error_code'] || 1, {
+ error_message: response['error_message'] || "Unknown error"
+ });
+ }
+ }, {
+ scope: permissionsStr,
+ return_scopes: true
+ });
+ },
+
+ /**
+ * Acquiring AccessToken
+ * @return {String}
+ * @example
+ * //example
+ * var accessToken = plugin.FacebookAgent.getAccessToken();
+ */
+ getAccessToken: function () {
+ return this._userInfo ? this._userInfo['accessToken'] : null;
+ },
+
+ /**
+ * Acquiring User ID
+ * @return {String}
+ * @example
+ * //example
+ * var userID = plugin.FacebookAgent.getUserID();
+ */
+ getUserID: function () {
+ return this._userInfo ? this._userInfo['userID'] : null;
+ },
+
+ _share: function (info, callback) {
+ FB.ui({
+ method: 'share',
+ name: info['title'],
+ caption: info['caption'],
+ description: info['text'],
+ href: info['link'],
+ picture: info['imageUrl']
+ },
+ function (response) {
+ if (response) {
+ if (response['post_id'])
+ typeof callback === 'function' && callback(0, {
+ didComplete: true,
+ post_id: response['post_id']
+ });
+ else
+ typeof callback === 'function' && callback(response['error_code'] || 1, {
+ error_message: response['error_message'] || "Unknown error"
+ });
+ } else {
+ typeof callback === 'function' && callback(1, {
+ error_message: "Unknown error"
+ });
+ }
+ });
+ },
+
+ /**
+ * Request a web dialog for Facebook sharing
+ * @param info
+ * @param callback
+ */
+ dialog: function (info, callback) {
+ if (!info) {
+ typeof callback === 'function' && callback(1, {
+ error_message: "No info parameter provided"
+ });
+ return;
+ }
+ if (!this.canPresentDialog(info)) {
+ typeof callback === 'function' && callback(1, {
+ error_message: "The requested dialog: " + info['dialog'] + " can not be presented on Web"
+ });
+ return;
+ }
+
+ // Preprocess properties
+ info['name'] = info['name'] || info['site'];
+ delete info['site'];
+
+ info['href'] = info['href'] || info['link'] || info['siteUrl'];
+ delete info['siteUrl'];
+ delete info['link'];
+
+ info['picture'] = info['picture'] || info['image'] || info['photo'] || info['imageUrl'] || info['imagePath'];
+ delete info['imageUrl'];
+ delete info['imagePath'];
+ delete info['photo'];
+ delete info['image'];
+
+ info['caption'] = info['title'] || info['caption'];
+ delete info['title'];
+
+ info['description'] = info['text'] || info['description'];
+ delete info['text'];
+
+ var method = info['dialog'];
+ delete info['dialog'];
+
+ if (method === 'shareLink' || method == 'feedDialog') {
+ info['method'] = 'share';
+ } else if (method == 'messageLink') {
+ info['method'] = 'send';
+ info['link'] = info['href'];
+ } else if (method == 'shareOpenGraph') {
+ info['method'] = 'share_open_graph';
+
+ if (info['url']) {
+ var obj = {};
+ if (info["preview_property_name"])
+ obj[info["preview_property_name"]] = info["url"];
+ else
+ obj["object"] = info["url"];
+
+ for (var p in info) {
+ if (p != "method" && p != "action_type" && p != "action_properties") {
+ info[p] && (obj[p] = info[p]);
+ delete info[p];
+ }
+ }
+
+ info['action_properties'] = JSON.stringify(obj);
+ }
+ }
+
+ FB.ui(info,
+ function (response) {
+ if (response && typeof callback === 'function') {
+ if (response['post_id'] || response['success']) {
+ callback(0, {
+ didComplete: true,
+ post_id: response['post_id'] || ""
+ });
+ }
+ else {
+ if (response['error_code']) {
+ callback(response['error_code'], {
+ error_message : response['error_message'] || 'Unknown error'
+ });
+ }
+ else callback(0, response);
+ }
+ } else if (response == undefined && typeof callback === 'function') {
+ callback(1, {
+ error_message: "Unknown error"
+ });
+ }
+ });
+ },
+
+ /**
+ * Check whether the share request can be achieved
+ * @param info
+ */
+ canPresentDialog: function (info) {
+ if (info && info['dialog'] && (
+ info['dialog'] === 'shareLink' ||
+ info['dialog'] === 'feedDialog' ||
+ info['dialog'] === 'shareOpenGraph' ||
+ info['dialog'] === 'messageLink'))
+ return true;
+ else
+ return false;
+ },
+ /**
+ * FB.api
+ * @param {String} path
+ * @param {Number} httpmethod
+ * @param {Object} params
+ * @param {Function} callback
+ */
+ api: function (path, httpmethod, params, callback) {
+ if (typeof params === 'function') {
+ callback = params;
+ params = {};
+ }
+ FB.api(path, httpmethod, params, function (response) {
+ if (response.error) {
+ typeof callback === 'function' && callback(response['error']['code'], {
+ error_message: response['error']['message'] || 'Unknown error'
+ })
+ } else {
+ typeof callback === 'function' && callback(0, response);
+ }
+ });
+ },
+
+ _getPermissionList: function (callback) {
+ FB.api("/me/permissions", function (response) {
+ if (response['data']) {
+ var permissionList = [];
+ for (var i = 0; i < response['data'].length; i++) {
+ if (response['data'][i]["status"] == "granted") {
+ permissionList.push(response['data'][i]['permission']);
+ }
+ }
+ typeof callback == 'function' && callback(0, {
+ permissions: permissionList
+ });
+ } else {
+ if (!response['error'])
+ response['error'] = {};
+ typeof callback == 'function' && callback(response['error']['code'] || 1, {
+ error_message: response['error']['message'] || 'Unknown error'
+ });
+ }
+ })
+ },
+
+ destroyInstance: function () {
+ },
+ canvas:{
+ /**
+ * Payment request
+ * @param {Object} info
+ * @param {Function} callback
+ */
+ pay: function (info, callback) {
+ /*
+ * Reference document
+ * https://developers.facebook.com/docs/payments/reference/paydialog
+ */
+ info['method'] = 'pay';
+ info['action'] = 'purchaseitem';
+
+ FB.ui(info, function (response) {
+ if (response['error_code']) {
+ callback(response['error_code'] || 1, {
+ error_message: response['error_message'] || response['error_msg'] || 'Unknown error'
+ });
+ } else {
+ callback(0, response);
+ }
+ })
+ }
+ },
+
+ /**
+ * Send an app requests to friends
+ * @param {Object} info
+ * @param {Function} callback
+ */
+ appRequest: function (info, callback) {
+ if (!info) {
+ typeof callback === 'function' && callback(1, {
+ error_message: "No info parameter provided"
+ });
+ return;
+ }
+
+ info['method'] = "apprequests";
+
+ FB.ui(info,
+ function (response) {
+ if (response) {
+ if (response['error_code']) {
+ typeof callback === 'function' && callback(response['error_code'], {
+ error_message : response['error_message'] || 'Unknown error'
+ });
+ }
+ else {
+ typeof callback === 'function' && callback(0, response);
+ }
+ } else {
+ typeof callback === 'function' && callback(1, {
+ error_message: "Unknown error"
+ });
+ }
+ });
+ },
+
+ /**
+ * Log an event
+ * @param {String} eventName
+ * @param {Number} valueToSum
+ * @param {Object} parameters
+ */
+ logEvent: function (eventName, valueToSum, parameters) {
+ if (eventName == undefined) return;
+ if (valueToSum === undefined && parameters === undefined) {
+ FB.AppEvents.logEvent(eventName, null, null);
+ } else if (typeof valueToSum === "number" && parameters === undefined) {
+ FB.AppEvents.logEvent(eventName, valueToSum);
+ } else if (typeof valueToSum === "object" && parameters === undefined) {
+ FB.AppEvents.logEvent(eventName, null, valueToSum);
+ } else {
+ FB.AppEvents.logEvent(eventName, valueToSum, parameters);
+ }
+ },
+
+ /**
+ * Activate App
+ */
+ activateApp: function () {
+ FB.AppEvents.activateApp();
+ },
+
+ /**
+ * Log a purchase
+ * @param {Number} amount Amount of the purchase
+ * @param {String} currency The currency
+ * @param {Object} param Supplemental parameters
+ */
+ logPurchase:function(amount, currency, param){
+ FB.AppEvents.logPurchase(amount, currency, param);
+ }
+});
diff --git a/frameworks/cocos2d-html5/external/pluginx/platform/facebook_sdk.js b/frameworks/cocos2d-html5/external/pluginx/platform/facebook_sdk.js
new file mode 100644
index 0000000..bc05068
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/pluginx/platform/facebook_sdk.js
@@ -0,0 +1,151 @@
+
+/*1411456395,,JIT Construction: v1425205,zh_CN*/
+
+/**
+ * Copyright Facebook Inc.
+ *
+ * Licensed under the Apache License, Version 2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+try {window.FB || (function(window) {
+ var self = window, document = window.document;
+ var setTimeout = window.setTimeout, setInterval = window.setInterval,clearTimeout = window.clearTimeout,clearInterval = window.clearInterval;var __DEV__ = 0;
+ function emptyFunction() {};
+ var __w, __t;
+ __t=function(a){return a[0];};__w=function(a){return a;};
+ var require,__d;(function(a){var b={},c={},d=['global','require','requireDynamic','requireLazy','module','exports'];require=function(e,f){if(c.hasOwnProperty(e))return c[e];if(!b.hasOwnProperty(e)){if(f)return null;throw new Error('Module '+e+' has not been defined');}var g=b[e],h=g.deps,i=g.factory.length,j,k=[];for(var l=0;l1?Number(arguments[1]):0;if(isNaN(j))j=0;var k=Math.min(Math.max(j,0),i.length);return i.indexOf(String(h),j)==k;};g.endsWith=function(h){var i=String(this);if(this==null)throw new TypeError('String.prototype.endsWith called on null or undefined');var j=i.length,k=String(h),l=arguments.length>1?Number(arguments[1]):j;if(isNaN(l))l=0;var m=Math.min(Math.max(l,0),j),n=m-k.length;if(n<0)return false;return i.lastIndexOf(k,n)==n;};g.contains=function(h){if(this==null)throw new TypeError('String.prototype.contains called on null or undefined');var i=String(this),j=arguments.length>1?Number(arguments[1]):0;if(isNaN(j))j=0;return i.indexOf(String(h),j)!=-1;};g.repeat=function(h){if(this==null)throw new TypeError('String.prototype.repeat called on null or undefined');var i=String(this),j=h?Number(h):0;if(isNaN(j))j=0;if(j<0||j===Infinity)throw RangeError();if(j===1)return i;if(j===0)return '';var k='';while(j){if(j&1)k+=i;if((j>>=1))i+=i;}return k;};e.exports=g;},null);
+ __d("ES5Array",[],function(a,b,c,d,e,f){var g={};g.isArray=function(h){return Object.prototype.toString.call(h)=='[object Array]';};e.exports=g;},null);
+ __d("ie8DontEnum",[],function(a,b,c,d,e,f){var g=['toString','toLocaleString','valueOf','hasOwnProperty','isPrototypeOf','prototypeIsEnumerable','constructor'],h=({}).hasOwnProperty,i=function(){};if(({toString:true}).propertyIsEnumerable('toString'))i=function(j,k){for(var l=0;l1)))/4)-ca((ga-1901+ha)/100)+ca((ga-1601+ha)/400);};}if(typeof JSON=="object"&&JSON){k.stringify=JSON.stringify;k.parse=JSON.parse;}if((m=typeof k.stringify=="function"&&!ea)){(ba=function(){return 1;}).toJSON=ba;try{m=k.stringify(0)==="0"&&k.stringify(new Number())==="0"&&k.stringify(new String())=='""'&&k.stringify(g)===j&&k.stringify(j)===j&&k.stringify()===j&&k.stringify(ba)==="1"&&k.stringify([ba])=="[1]"&&k.stringify([j])=="[null]"&&k.stringify(null)=="null"&&k.stringify([j,g,null])=="[null,null,null]"&&k.stringify({result:[ba,true,false,null,"\0\b\n\f\r\t"]})==l&&k.stringify(null,ba)==="1"&&k.stringify([1,2],null,1)=="[\n 1,\n 2\n]"&&k.stringify(new Date(-8.64e+15))=='"-271821-04-20T00:00:00.000Z"'&&k.stringify(new Date(8.64e+15))=='"+275760-09-13T00:00:00.000Z"'&&k.stringify(new Date(-62198755200000))=='"-000001-01-01T00:00:00.000Z"'&&k.stringify(new Date(-1))=='"1969-12-31T23:59:59.999Z"';}catch(fa){m=false;}}if(typeof k.parse=="function")try{if(k.parse("0")===0&&!k.parse(false)){ba=k.parse(l);if((r=ba.A.length==5&&ba.A[0]==1)){try{r=!k.parse('"\t"');}catch(fa){}if(r)try{r=k.parse("01")!=1;}catch(fa){}}}}catch(fa){r=false;}ba=l=null;if(!m||!r){if(!(h={}.hasOwnProperty))h=function(ga){var ha={},ia;if((ha.__proto__=null,ha.__proto__={toString:1},ha).toString!=g){h=function(ja){var ka=this.__proto__,la=ja in (this.__proto__=null,this);this.__proto__=ka;return la;};}else{ia=ha.constructor;h=function(ja){var ka=(this.constructor||ia).prototype;return ja in this&&!(ja in ka&&this[ja]===ka[ja]);};}ha=null;return h.call(this,ga);};i=function(ga,ha){var ia=0,ja,ka,la,ma;(ja=function(){this.valueOf=0;}).prototype.valueOf=0;ka=new ja();for(la in ka)if(h.call(ka,la))ia++;ja=ka=null;if(!ia){ka=["valueOf","toString","toLocaleString","propertyIsEnumerable","isPrototypeOf","hasOwnProperty","constructor"];ma=function(na,oa){var pa=g.call(na)=="[object Function]",qa,ra;for(qa in na)if(!(pa&&qa=="prototype")&&h.call(na,qa))oa(qa);for(ra=ka.length;qa=ka[--ra];h.call(na,qa)&&oa(qa));};}else if(ia==2){ma=function(na,oa){var pa={},qa=g.call(na)=="[object Function]",ra;for(ra in na)if(!(qa&&ra=="prototype")&&!h.call(pa,ra)&&(pa[ra]=1)&&h.call(na,ra))oa(ra);};}else ma=function(na,oa){var pa=g.call(na)=="[object Function]",qa,ra;for(qa in na)if(!(pa&&qa=="prototype")&&h.call(na,qa)&&!(ra=qa==="constructor"))oa(qa);if(ra||h.call(na,(qa="constructor")))oa(qa);};return ma(ga,ha);};if(!m){n={"\\":"\\\\",'"':'\\"',"\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t"};o=function(ga,ha){return ("000000"+(ha||0)).slice(-ga);};p=function(ga){var ha='"',ia=0,ja;for(;ja=ga.charAt(ia);ia++)ha+='\\"\b\f\n\r\t'.indexOf(ja)>-1?n[ja]:ja<" "?"\\u00"+o(2,ja.charCodeAt(0).toString(16)):ja;return ha+'"';};q=function(ga,ha,ia,ja,ka,la,ma){var na=ha[ga],oa,pa,qa,ra,sa,ta,ua,va,wa,xa,ya,za,ab,bb,cb;if(typeof na=="object"&&na){oa=g.call(na);if(oa=="[object Date]"&&!h.call(na,"toJSON")){if(na>-1/0&&na<1/0){if(ea){ra=ca(na/86400000);for(pa=ca(ra/365.2425)+1970-1;ea(pa+1,0)<=ra;pa++);for(qa=ca((ra-ea(pa,0))/30.42);ea(pa,qa+1)<=ra;qa++);ra=1+ra-ea(pa,qa);sa=(na%86400000+86400000)%86400000;ta=ca(sa/3600000)%24;ua=ca(sa/60000)%60;va=ca(sa/1000)%60;wa=sa%1000;}else{pa=na.getUTCFullYear();qa=na.getUTCMonth();ra=na.getUTCDate();ta=na.getUTCHours();ua=na.getUTCMinutes();va=na.getUTCSeconds();wa=na.getUTCMilliseconds();}na=(pa<=0||pa>=10000?(pa<0?"-":"+")+o(6,pa<0?-pa:pa):o(4,pa))+"-"+o(2,qa+1)+"-"+o(2,ra)+"T"+o(2,ta)+":"+o(2,ua)+":"+o(2,va)+"."+o(3,wa)+"Z";}else na=null;}else if(typeof na.toJSON=="function"&&((oa!="[object Number]"&&oa!="[object String]"&&oa!="[object Array]")||h.call(na,"toJSON")))na=na.toJSON(ga);}if(ia)na=ia.call(ha,ga,na);if(na===null)return "null";oa=g.call(na);if(oa=="[object Boolean]"){return ""+na;}else if(oa=="[object Number]"){return na>-1/0&&na<1/0?""+na:"null";}else if(oa=="[object String]")return p(na);if(typeof na=="object"){for(ab=ma.length;ab--;)if(ma[ab]===na)throw TypeError();ma.push(na);xa=[];bb=la;la+=ka;if(oa=="[object Array]"){for(za=0,ab=na.length;za0)for(ja="",ia>10&&(ia=10);ja.length-1){z++;}else if("{}[]:,".indexOf(ia)>-1){z++;return ia;}else if(ia=='"'){for(ja="@",z++;z-1){ja+=t[ia];z++;}else if(ia=="u"){ka=++z;for(la=z+4;z="0"&&ia<="9"||ia>="a"&&ia<="f"||ia>="A"&&ia<="F"))u();}ja+=s("0x"+ga.slice(ka,z));}else u();}else{if(ia=='"')break;ja+=ia;z++;}}if(ga.charAt(z)=='"'){z++;return ja;}u();}else{ka=z;if(ia=="-"){ma=true;ia=ga.charAt(++z);}if(ia>="0"&&ia<="9"){if(ia=="0"&&(ia=ga.charAt(z+1),ia>="0"&&ia<="9"))u();ma=false;for(;z="0"&&ia<="9");z++);if(ga.charAt(z)=="."){la=++z;for(;la="0"&&ia<="9");la++);if(la==z)u();z=la;}ia=ga.charAt(z);if(ia=="e"||ia=="E"){ia=ga.charAt(++z);if(ia=="+"||ia=="-")z++;for(la=z;la="0"&&ia<="9");la++);if(la==z)u();z=la;}return +ga.slice(ka,z);}if(ma)u();if(ga.slice(z,z+4)=="true"){z+=4;return true;}else if(ga.slice(z,z+5)=="false"){z+=5;return false;}else if(ga.slice(z,z+4)=="null"){z+=4;return null;}u();}}return "$";};w=function(ga){var ha,ia,ja;if(ga=="$")u();if(typeof ga=="string"){if(ga.charAt(0)=="@")return ga.slice(1);if(ga=="["){ha=[];for(;;ia||(ia=true)){ga=v();if(ga=="]")break;if(ia)if(ga==","){ga=v();if(ga=="]")u();}else u();if(ga==",")u();ha.push(w(ga));}return ha;}else if(ga=="{"){ha={};for(;;ia||(ia=true)){ga=v();if(ga=="}")break;if(ia)if(ga==","){ga=v();if(ga=="}")u();}else u();if(ga==","||typeof ga!="string"||ga.charAt(0)!="@"||v()!=":")u();ha[ga.slice(1)]=w(v());}return ha;}u();}return ga;};y=function(ga,ha,ia){var ja=x(ga,ha,ia);if(ja===j){delete ga[ha];}else ga[ha]=ja;};x=function(ga,ha,ia){var ja=ga[ha],ka;if(typeof ja=="object"&&ja)if(g.call(ja)=="[object Array]"){for(ka=ja.length;ka--;)y(ja,ka,ia);}else i(ja,function(la){y(ja,la,ia);});return ia.call(ga,ha,ja);};k.parse=function(ga,ha){z=0;aa=ga;var ia=w(v());if(v()!="$")u();z=aa=null;return ha&&g.call(ha)=="[object Function]"?x((ba={},ba[""]=ia,ba),"",ha):ia;};}}}).call(this);},null);
+ __d("ES6Object",["ie8DontEnum"],function(a,b,c,d,e,f,g){var h=({}).hasOwnProperty,i={assign:function(j){var k=Array.prototype.slice.call(arguments,1);if(j==null)throw new TypeError('Object.assign target cannot be null or undefined');j=Object(j);for(var l=0;l>>0;for(var l=0;l9999?'+':''))+('00000'+Math.abs(i)).slice(0<=i&&i<=9999?-4:-6);return i+'-'+g(this.getUTCMonth()+1)+'-'+g(this.getUTCDate())+'T'+g(this.getUTCHours())+':'+g(this.getUTCMinutes())+':'+g(this.getUTCSeconds())+'.'+(this.getUTCMilliseconds()/1000).toFixed(3).slice(2,5)+'Z';}};e.exports=h;},null);
+ __d("ES6Number",[],function(a,b,c,d,e,f){var g={isFinite:function(h){return (typeof h=='number')&&isFinite(h);},isNaN:function(h){return (typeof h=='number')&&isNaN(h);}};e.exports=g;},null);
+ __d("ES",["ES5ArrayPrototype","ES5FunctionPrototype","ES5StringPrototype","ES5Array","ES5Object","ES5Date","JSON3","ES6Object","ES6ArrayPrototype","ES6DatePrototype","ES6Number"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q){var r=({}).toString,s={'JSON.stringify':m.stringify,'JSON.parse':m.parse},t={'Array.prototype':g,'Function.prototype':h,'String.prototype':i,Object:k,Array:j,Date:l},u={Object:n,'Array.prototype':o,'Date.prototype':p,Number:q};function v(x){for(var y in x){if(!x.hasOwnProperty(y))continue;var z=x[y],aa=y.split('.'),ba=aa.length==2?window[aa[0]][aa[1]]:window[y];for(var ca in z){if(!z.hasOwnProperty(ca))continue;var da=ba[ca];s[y+'.'+ca]=da&&/\{\s+\[native code\]\s\}/.test(da)?da:z[ca];}}}v(t);v(u);function w(x,y,z){var aa=Array.prototype.slice.call(arguments,3),ba=z?r.call(x).slice(8,-1)+'.prototype':x,ca=s[ba+'.'+y]||x[y];if(typeof ca==='function')return ca.apply(x,aa);}e.exports=w;},null);
+ var ES = require('ES');
+ __d("JSSDKRuntimeConfig",[],{"locale":"zh_CN","rtl":false,"revision":"1425205"});__d("JSSDKConfig",[],{"bustCache":true,"tagCountLogRate":0.01,"errorHandling":{"rate":4},"usePluginPipe":true,"features":{"allow_non_canvas_app_events":false,"event_subscriptions_log":{"rate":0.01,"value":10000},"kill_fragment":true,"xfbml_profile_pic_server":true,"error_handling":{"rate":4},"e2e_ping_tracking":{"rate":1.0e-6},"xd_timeout":{"rate":4,"value":30000},"use_bundle":true,"launch_payment_dialog_via_pac":{"rate":100}},"api":{"mode":"warn","whitelist":["Canvas","Canvas.Prefetcher","Canvas.Prefetcher.addStaticResource","Canvas.Prefetcher.setCollectionMode","Canvas.getPageInfo","Canvas.hideFlashElement","Canvas.scrollTo","Canvas.setAutoGrow","Canvas.setDoneLoading","Canvas.setSize","Canvas.setUrlHandler","Canvas.showFlashElement","Canvas.startTimer","Canvas.stopTimer","Data","Data.process","Data.query","Data.query:wait","Data.waitOn","Data.waitOn:wait","Event","Event.subscribe","Event.unsubscribe","Music.flashCallback","Music.init","Music.send","Payment","Payment.cancelFlow","Payment.continueFlow","Payment.init","Payment.lockForProcessing","Payment.unlockForProcessing","Payment.parse","Payment.setSize","ThirdPartyProvider","ThirdPartyProvider.init","ThirdPartyProvider.sendData","UA","UA.nativeApp","XFBML","XFBML.RecommendationsBar","XFBML.RecommendationsBar.markRead","XFBML.parse","addFriend","api","getAccessToken","getAuthResponse","getLoginStatus","getUserID","init","login","logout","publish","share","ui","ui:subscribe","AppEvents","AppEvents.activateApp","AppEvents.logEvent","AppEvents.logPurchase","AppEvents.EventNames","AppEvents.ParameterNames"]},"initSitevars":{"enableMobileComments":1,"iframePermissions":{"read_stream":false,"manage_mailbox":false,"manage_friendlists":false,"read_mailbox":false,"publish_checkins":true,"status_update":true,"photo_upload":true,"video_upload":true,"sms":false,"create_event":true,"rsvp_event":true,"offline_access":true,"email":true,"xmpp_login":false,"create_note":true,"share_item":true,"export_stream":false,"publish_stream":true,"publish_likes":true,"ads_management":false,"contact_email":true,"access_private_data":false,"read_insights":false,"read_requests":false,"read_friendlists":true,"manage_pages":false,"physical_login":false,"manage_groups":false,"read_deals":false}}});__d("UrlMapConfig",[],{"www":"www.facebook.com","m":"m.facebook.com","connect":"connect.facebook.net","business":"business.facebook.com","api_https":"api.facebook.com","api_read_https":"api-read.facebook.com","graph_https":"graph.facebook.com","fbcdn_http":"static.ak.fbcdn.net","fbcdn_https":"fbstatic-a.akamaihd.net","cdn_http":"static.ak.facebook.com","cdn_https":"s-static.ak.facebook.com"});__d("JSSDKXDConfig",[],{"XdUrl":"\/connect\/xd_arbiter.php?version=41","XdBundleUrl":"\/connect\/xd_arbiter\/ZEbdHPQfV3x.js?version=41","Flash":{"path":"https:\/\/connect.facebook.net\/rsrc.php\/v1\/yR\/r\/ks_9ZXiQ0GL.swf"},"useCdn":true});__d("JSSDKCssConfig",[],{"rules":".fb_hidden{position:absolute;top:-10000px;z-index:10001}.fb_invisible{display:none}.fb_reset{background:none;border:0;border-spacing:0;color:#000;cursor:auto;direction:ltr;font-family:\"lucida grande\", tahoma, verdana, arial, sans-serif;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:1;margin:0;overflow:visible;padding:0;text-align:left;text-decoration:none;text-indent:0;text-shadow:none;text-transform:none;visibility:visible;white-space:normal;word-spacing:normal}.fb_reset>div{overflow:hidden}.fb_link img{border:none}\n.fb_dialog{background:rgba(82, 82, 82, .7);position:absolute;top:-10000px;z-index:10001}.fb_reset .fb_dialog_legacy{overflow:visible}.fb_dialog_advanced{padding:10px;-moz-border-radius:8px;-webkit-border-radius:8px;border-radius:8px}.fb_dialog_content{background:#fff;color:#333}.fb_dialog_close_icon{background:url(http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/yq\/r\/IE9JII6Z1Ys.png) no-repeat scroll 0 0 transparent;_background-image:url(http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/yL\/r\/s816eWC-2sl.gif);cursor:pointer;display:block;height:15px;position:absolute;right:18px;top:17px;width:15px}.fb_dialog_mobile .fb_dialog_close_icon{top:5px;left:5px;right:auto}.fb_dialog_padding{background-color:transparent;position:absolute;width:1px;z-index:-1}.fb_dialog_close_icon:hover{background:url(http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/yq\/r\/IE9JII6Z1Ys.png) no-repeat scroll 0 -15px transparent;_background-image:url(http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/yL\/r\/s816eWC-2sl.gif)}.fb_dialog_close_icon:active{background:url(http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/yq\/r\/IE9JII6Z1Ys.png) no-repeat scroll 0 -30px transparent;_background-image:url(http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/yL\/r\/s816eWC-2sl.gif)}.fb_dialog_loader{background-color:#f2f2f2;border:1px solid #606060;font-size:25px;padding:20px}.fb_dialog_top_left,.fb_dialog_top_right,.fb_dialog_bottom_left,.fb_dialog_bottom_right{height:10px;width:10px;overflow:hidden;position:absolute}.fb_dialog_top_left{background:url(http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/ye\/r\/8YeTNIlTZjm.png) no-repeat 0 0;left:-10px;top:-10px}.fb_dialog_top_right{background:url(http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/ye\/r\/8YeTNIlTZjm.png) no-repeat 0 -10px;right:-10px;top:-10px}.fb_dialog_bottom_left{background:url(http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/ye\/r\/8YeTNIlTZjm.png) no-repeat 0 -20px;bottom:-10px;left:-10px}.fb_dialog_bottom_right{background:url(http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/ye\/r\/8YeTNIlTZjm.png) no-repeat 0 -30px;right:-10px;bottom:-10px}.fb_dialog_vert_left,.fb_dialog_vert_right,.fb_dialog_horiz_top,.fb_dialog_horiz_bottom{position:absolute;background:#525252;filter:alpha(opacity=70);opacity:.7}.fb_dialog_vert_left,.fb_dialog_vert_right{width:10px;height:100\u0025}.fb_dialog_vert_left{margin-left:-10px}.fb_dialog_vert_right{right:0;margin-right:-10px}.fb_dialog_horiz_top,.fb_dialog_horiz_bottom{width:100\u0025;height:10px}.fb_dialog_horiz_top{margin-top:-10px}.fb_dialog_horiz_bottom{bottom:0;margin-bottom:-10px}.fb_dialog_iframe{line-height:0}.fb_dialog_content .dialog_title{background:#6d84b4;border:1px solid #3b5998;color:#fff;font-size:15px;font-weight:bold;margin:0}.fb_dialog_content .dialog_title>span{background:url(http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/yd\/r\/Cou7n-nqK52.gif) no-repeat 5px 50\u0025;float:left;padding:5px 0 7px 26px}body.fb_hidden{-webkit-transform:none;height:100\u0025;margin:0;overflow:visible;position:absolute;top:-10000px;left:0;width:100\u0025}.fb_dialog.fb_dialog_mobile.loading{background:url(http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/ya\/r\/3rhSv5V8j3o.gif) white no-repeat 50\u0025 50\u0025;min-height:100\u0025;min-width:100\u0025;overflow:hidden;position:absolute;top:0;z-index:10001}.fb_dialog.fb_dialog_mobile.loading.centered{max-height:590px;min-height:590px;max-width:500px;min-width:500px}#fb-root #fb_dialog_ipad_overlay{background:rgba(0, 0, 0, .45);position:absolute;left:0;top:0;width:100\u0025;min-height:100\u0025;z-index:10000}#fb-root #fb_dialog_ipad_overlay.hidden{display:none}.fb_dialog.fb_dialog_mobile.loading iframe{visibility:hidden}.fb_dialog_content .dialog_header{-webkit-box-shadow:white 0 1px 1px -1px inset;background:-webkit-gradient(linear, 0\u0025 0\u0025, 0\u0025 100\u0025, from(#738ABA), to(#2C4987));border-bottom:1px solid;border-color:#1d4088;color:#fff;font:14px Helvetica, sans-serif;font-weight:bold;text-overflow:ellipsis;text-shadow:rgba(0, 30, 84, .296875) 0 -1px 0;vertical-align:middle;white-space:nowrap}.fb_dialog_content .dialog_header table{-webkit-font-smoothing:subpixel-antialiased;height:43px;width:100\u0025}.fb_dialog_content .dialog_header td.header_left{font-size:13px;padding-left:5px;vertical-align:middle;width:60px}.fb_dialog_content .dialog_header td.header_right{font-size:13px;padding-right:5px;vertical-align:middle;width:60px}.fb_dialog_content .touchable_button{background:-webkit-gradient(linear, 0\u0025 0\u0025, 0\u0025 100\u0025, from(#4966A6), color-stop(.5, #355492), to(#2A4887));border:1px solid #29447e;-webkit-background-clip:padding-box;-webkit-border-radius:3px;-webkit-box-shadow:rgba(0, 0, 0, .117188) 0 1px 1px inset, rgba(255, 255, 255, .167969) 0 1px 0;display:inline-block;margin-top:3px;max-width:85px;line-height:18px;padding:4px 12px;position:relative}.fb_dialog_content .dialog_header .touchable_button input{border:none;background:none;color:#fff;font:12px Helvetica, sans-serif;font-weight:bold;margin:2px -12px;padding:2px 6px 3px 6px;text-shadow:rgba(0, 30, 84, .296875) 0 -1px 0}.fb_dialog_content .dialog_header .header_center{color:#fff;font-size:17px;font-weight:bold;line-height:18px;text-align:center;vertical-align:middle}.fb_dialog_content .dialog_content{background:url(http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/y9\/r\/jKEcVPZFk-2.gif) no-repeat 50\u0025 50\u0025;border:1px solid #555;border-bottom:0;border-top:0;height:150px}.fb_dialog_content .dialog_footer{background:#f2f2f2;border:1px solid #555;border-top-color:#ccc;height:40px}#fb_dialog_loader_close{float:left}.fb_dialog.fb_dialog_mobile .fb_dialog_close_button{text-shadow:rgba(0, 30, 84, .296875) 0 -1px 0}.fb_dialog.fb_dialog_mobile .fb_dialog_close_icon{visibility:hidden}\n.fb_iframe_widget{display:inline-block;position:relative}.fb_iframe_widget span{display:inline-block;position:relative;text-align:justify}.fb_iframe_widget iframe{position:absolute}.fb_iframe_widget_lift{z-index:1}.fb_hide_iframes iframe{position:relative;left:-10000px}.fb_iframe_widget_loader{position:relative;display:inline-block}.fb_iframe_widget_fluid{display:inline}.fb_iframe_widget_fluid span{width:100\u0025}.fb_iframe_widget_loader iframe{min-height:32px;z-index:2;zoom:1}.fb_iframe_widget_loader .FB_Loader{background:url(http:\/\/static.ak.fbcdn.net\/rsrc.php\/v2\/y9\/r\/jKEcVPZFk-2.gif) no-repeat;height:32px;width:32px;margin-left:-16px;position:absolute;left:50\u0025;z-index:4}\n.fbpluginrecommendationsbarleft,.fbpluginrecommendationsbarright{position:fixed !important;bottom:0;z-index:999}.fbpluginrecommendationsbarleft{left:10px}.fbpluginrecommendationsbarright{right:10px}","components":["css:fb.css.base","css:fb.css.dialog","css:fb.css.iframewidget","css:fb.css.plugin.recommendationsbar"]});__d("ApiClientConfig",[],{"FlashRequest":{"swfUrl":"https:\/\/connect.facebook.net\/rsrc.php\/v1\/yW\/r\/PvklbuW2Ycn.swf"}});__d("JSSDKCanvasPrefetcherConfig",[],{"blacklist":[144959615576466],"sampleRate":500});__d("JSSDKPluginPipeConfig",[],{"threshold":0,"enabledApps":{"209753825810663":1,"187288694643718":1}});
+ __d("QueryString",[],function(a,b,c,d,e,f){function g(k){var l=[];ES(ES('Object','keys',false,k).sort(),'forEach',true,function(m){var n=k[m];if(typeof n==='undefined')return;if(n===null){l.push(m);return;}l.push(encodeURIComponent(m)+'='+encodeURIComponent(n));});return l.join('&');}function h(k,l){var m={};if(k==='')return m;var n=k.split('&');for(var o=0;oh);},ie64:function(){return x.ie()&&r;},firefox:function(){return w()||i;},opera:function(){return w()||j;},webkit:function(){return w()||k;},safari:function(){return x.webkit();},chrome:function(){return w()||l;},windows:function(){return w()||o;},osx:function(){return w()||n;},linux:function(){return w()||p;},iphone:function(){return w()||s;},mobile:function(){return w()||(s||t||q||v);},nativeApp:function(){return w()||u;},android:function(){return w()||q;},ipad:function(){return w()||t;}};e.exports=x;},null);
+ __d("hasNamePropertyBug",["guid","UserAgent_DEPRECATED"],function(a,b,c,d,e,f,g,h){var i=h.ie()?undefined:false;function j(){var l=document.createElement("form"),m=l.appendChild(document.createElement("input"));m.name=g();i=m!==l.elements[m.name];l=m=null;return i;}function k(){return typeof i==='undefined'?j():i;}e.exports=k;},null);
+ __d("wrapFunction",[],function(a,b,c,d,e,f){var g={};function h(i,j,k){j=j||'default';return function(){var l=j in g?g[j](i,k):i;return l.apply(this,arguments);};}h.setWrapper=function(i,j){j=j||'default';g[j]=i;};e.exports=h;},null);
+ __d("DOMEventListener",["wrapFunction"],function(a,b,c,d,e,f,g){var h,i;if(window.addEventListener){h=function(k,l,m){m.wrapper=g(m,'entry','DOMEventListener.add '+l);k.addEventListener(l,m.wrapper,false);};i=function(k,l,m){k.removeEventListener(l,m.wrapper,false);};}else if(window.attachEvent){h=function(k,l,m){m.wrapper=g(m,'entry','DOMEventListener.add '+l);k.attachEvent('on'+l,m.wrapper);};i=function(k,l,m){k.detachEvent('on'+l,m.wrapper);};}else i=h=function(){};var j={add:function(k,l,m){h(k,l,m);return {remove:function(){i(k,l,m);k=null;}};},remove:i};e.exports=j;},null);
+ __d("sdk.createIframe",["guid","hasNamePropertyBug","DOMEventListener"],function(a,b,c,d,e,f,g,h,i){function j(k){k=ES('Object','assign',false,{},k);var l,m=k.name||g(),n=k.root,o=k.style||{border:'none'},p=k.url,q=k.onload,r=k.onerror;if(h()){l=document.createElement('');}else{l=document.createElement("iframe");l.name=m;}delete k.style;delete k.name;delete k.url;delete k.root;delete k.onload;delete k.onerror;var s=ES('Object','assign',false,{frameBorder:0,allowTransparency:true,scrolling:'no'},k);if(s.width)l.width=s.width+'px';if(s.height)l.height=s.height+'px';delete s.height;delete s.width;for(var t in s)if(s.hasOwnProperty(t))l.setAttribute(t,s[t]);ES('Object','assign',false,l.style,o);l.src="javascript:false";n.appendChild(l);if(q)var u=i.add(l,'load',function(){u.remove();q();});if(r)var v=i.add(l,'error',function(){v.remove();r();});l.src=p;return l;}e.exports=j;},null);
+ __d("DOMWrapper",[],function(a,b,c,d,e,f){var g,h,i={setRoot:function(j){g=j;},getRoot:function(){return g||document.body;},setWindow:function(j){h=j;},getWindow:function(){return h||self;}};e.exports=i;},null);
+ __d("sdk.feature",["JSSDKConfig"],function(a,b,c,d,e,f,g){function h(i,j){if(g.features&&i in g.features){var k=g.features[i];if(typeof k==='object'&&typeof k.rate==='number'){if(k.rate&&Math.random()*100<=k.rate){return k.value||true;}else return k.value?null:false;}else return k;}return typeof j!=='undefined'?j:null;}e.exports=h;},null);
+ __d("sdk.getContextType",["UserAgent_DEPRECATED","sdk.Runtime"],function(a,b,c,d,e,f,g,h){function i(){if(g.nativeApp())return 3;if(g.mobile())return 2;if(h.isEnvironment(h.ENVIRONMENTS.CANVAS))return 5;return 1;}e.exports=i;},null);
+ __d("sdk.domReady",[],function(a,b,c,d,e,f){var g,h="readyState" in document?/loaded|complete/.test(document.readyState):!!document.body;function i(){if(!g)return;var l;while(l=g.shift())l();g=null;}function j(l){if(g){g.push(l);return;}else l();}if(!h){g=[];if(document.addEventListener){document.addEventListener('DOMContentLoaded',i,false);window.addEventListener('load',i,false);}else if(document.attachEvent){document.attachEvent('onreadystatechange',i);window.attachEvent('onload',i);}if(document.documentElement.doScroll&&window==window.top){var k=function(){try{document.documentElement.doScroll('left');}catch(l){setTimeout(k,0);return;}i();};k();}}e.exports=j;},3);
+ __d("Log",["sprintf"],function(a,b,c,d,e,f,g){var h={DEBUG:3,INFO:2,WARNING:1,ERROR:0};function i(k,l){var m=Array.prototype.slice.call(arguments,2),n=g.apply(null,m),o=window.console;if(o&&j.level>=l)o[k in o?k:'log'](n);}var j={level:-1,Level:h,debug:ES(i,'bind',true,null,'debug',h.DEBUG),info:ES(i,'bind',true,null,'info',h.INFO),warn:ES(i,'bind',true,null,'warn',h.WARNING),error:ES(i,'bind',true,null,'error',h.ERROR)};e.exports=j;},null);
+ __d("sdk.Content",["sdk.domReady","Log","UserAgent_DEPRECATED"],function(a,b,c,d,e,f,g,h,i){var j,k,l={append:function(m,n){if(!n)if(!j){j=n=document.getElementById('fb-root');if(!n){h.warn('The "fb-root" div has not been created, auto-creating');j=n=document.createElement('div');n.id='fb-root';if(i.ie()||!document.body){g(function(){document.body.appendChild(n);});}else document.body.appendChild(n);}n.className+=' fb_reset';}else n=j;if(typeof m=='string'){var o=document.createElement('div');n.appendChild(o).innerHTML=m;return o;}else return n.appendChild(m);},appendHidden:function(m){if(!n){var n=document.createElement('div'),o=n.style;o.position='absolute';o.top='-10000px';o.width=o.height=0;n=l.append(n);}return l.append(m,n);},submitToTarget:function(m,n){var o=document.createElement('form');o.action=m.url;o.target=m.target;o.method=(n)?'GET':'POST';l.appendHidden(o);for(var p in m.params)if(m.params.hasOwnProperty(p)){var q=m.params[p];if(q!==null&&q!==undefined){var r=document.createElement('input');r.name=p;r.value=q;o.appendChild(r);}}o.submit();o.parentNode.removeChild(o);}};e.exports=l;},null);
+ __d("dotAccess",[],function(a,b,c,d,e,f){function g(h,i,j){var k=i.split('.');do{var l=k.shift();h=h[l]||j&&(h[l]={});}while(k.length&&h);return h;}e.exports=g;},null);
+ __d("GlobalCallback",["DOMWrapper","dotAccess","guid","wrapFunction"],function(a,b,c,d,e,f,g,h,i,j){var k,l,m={setPrefix:function(n){k=h(g.getWindow(),n,true);l=n;},create:function(n,o){if(!k)this.setPrefix('__globalCallbacks');var p=i();k[p]=j(n,'entry',o||'GlobalCallback');return l+'.'+p;},remove:function(n){var o=n.substring(l.length+1);delete k[o];}};e.exports=m;},null);
+ __d("insertIframe",["guid","GlobalCallback"],function(a,b,c,d,e,f,g,h){function i(j){j.id=j.id||g();j.name=j.name||g();var k=false,l=false,m=function(){if(k&&!l){l=true;j.onload&&j.onload(j.root.firstChild);}},n=h.create(m);if(document.attachEvent){var o=('');j.root.innerHTML=('');k=true;setTimeout(function(){j.root.innerHTML=o;j.root.firstChild.src=j.url;j.onInsert&&j.onInsert(j.root.firstChild);},0);}else{var p=document.createElement('iframe');p.id=j.id;p.name=j.name;p.onload=m;p.scrolling='no';p.style.border='none';p.style.overflow='hidden';if(j.title)p.title=j.title;if(j.className)p.className=j.className;if(j.height!==undefined)p.style.height=j.height+'px';if(j.width!==undefined)if(j.width=='100%'){p.style.width=j.width;}else p.style.width=j.width+'px';j.root.appendChild(p);k=true;p.src=j.url;j.onInsert&&j.onInsert(p);}}e.exports=i;},null);
+ __d("Miny",[],function(a,b,c,d,e,f){var g='Miny1',h={encode:[],decode:{}},i='wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_'.split('');function j(n){for(var o=h.encode.length;o2000)if(p.payload&&typeof p.payload==='string'){var t=j.encode(p.payload);if(t&&t.length>>18),g.charCodeAt((l>>>12)&63),g.charCodeAt((l>>>6)&63),g.charCodeAt(l&63));}var i='>___?456789:;<=_______'+'\0\1\2\3\4\5\6\7\b\t\n\13\f\r\16\17\20\21\22\23\24\25\26\27\30\31'+'______\32\33\34\35\36\37 !"#$%&\'()*+,-./0123';function j(l){l=(i.charCodeAt(l.charCodeAt(0)-43)<<18)|(i.charCodeAt(l.charCodeAt(1)-43)<<12)|(i.charCodeAt(l.charCodeAt(2)-43)<<6)|i.charCodeAt(l.charCodeAt(3)-43);return String.fromCharCode(l>>>16,(l>>>8)&255,l&255);}var k={encode:function(l){l=unescape(encodeURI(l));var m=(l.length+2)%3;l=(l+'\0\0'.slice(m)).replace(/[\s\S]{3}/g,h);return l.slice(0,l.length+m-2)+'=='.slice(m);},decode:function(l){l=l.replace(/[^A-Za-z0-9+\/]/g,'');var m=(l.length+3)&3;l=(l+'AAA'.slice(m)).replace(/..../g,j);l=l.slice(0,l.length+m-3);try{return decodeURIComponent(escape(l));}catch(n){throw new Error('Not valid UTF-8');}},encodeObject:function(l){return k.encode(ES('JSON','stringify',false,l));},decodeObject:function(l){return ES('JSON','parse',false,k.decode(l));},encodeNums:function(l){return String.fromCharCode.apply(String,ES(l,'map',true,function(m){return g.charCodeAt((m|-(m>63))&-(m>0)&63);}));}};e.exports=k;},null);
+ __d("sdk.SignedRequest",["Base64"],function(a,b,c,d,e,f,g){function h(j){if(!j)return null;var k=j.split('.',2)[1].replace(/\-/g,'+').replace(/\_/g,'/');return g.decodeObject(k);}var i={parse:h};e.exports=i;},null);
+ __d("URIRFC3986",[],function(a,b,c,d,e,f){var g=new RegExp('^'+'([^:/?#]+:)?'+'(//'+'([^\\\\/?#@]*@)?'+'('+'\\[[A-Fa-f0-9:.]+\\]|'+'[^\\/?#:]*'+')'+'(:[0-9]*)?'+')?'+'([^?#]*)'+'(\\?[^#]*)?'+'(#.*)?'),h={parse:function(i){if(ES(i,'trim',true)==='')return null;var j=i.match(g),k={};k.uri=j[0]?j[0]:null;k.scheme=j[1]?j[1].substr(0,j[1].length-1):null;k.authority=j[2]?j[2].substr(2):null;k.userinfo=j[3]?j[3].substr(0,j[3].length-1):null;k.host=j[2]?j[4]:null;k.port=j[5]?(j[5].substr(1)?parseInt(j[5].substr(1),10):null):null;k.path=j[6]?j[6]:null;k.query=j[7]?j[7].substr(1):null;k.fragment=j[8]?j[8].substr(1):null;k.isGenericURI=k.authority===null&&!!k.scheme;return k;}};e.exports=h;},null);
+ __d("createObjectFrom",[],function(a,b,c,d,e,f){function g(h,i){var j={},k=ES('Array','isArray',false,i);if(typeof i=='undefined')i=true;for(var l=h.length;l--;)j[h[l]]=k?i[l]:i;return j;}e.exports=g;},null);
+ __d("URISchemes",["createObjectFrom"],function(a,b,c,d,e,f,g){var h=g(['fb','fbcf','fbconnect','fb-messenger','fbrpc','file','ftp','http','https','mailto','ms-app','itms','itms-apps','itms-services','market','svn+ssh','fbstaging','tel','sms']),i={isAllowed:function(j){if(!j)return true;return h.hasOwnProperty(j.toLowerCase());}};e.exports=i;},null);
+ __d("copyProperties",[],function(a,b,c,d,e,f){function g(h,i,j,k,l,m,n){h=h||{};var o=[i,j,k,l,m],p=0,q;while(o[p]){q=o[p++];for(var r in q)h[r]=q[r];if(q.hasOwnProperty&&q.hasOwnProperty('toString')&&(typeof q.toString!='undefined')&&(h.toString!==q.toString))h.toString=q.toString;}return h;}e.exports=g;},null);
+ __d("eprintf",[],function(a,b,c,d,e,f){var g=function(h){var i=ES(Array.prototype.slice.call(arguments),'map',true,function(l){return String(l);}),j=h.split('%s').length-1;if(j!==i.length-1)return g('eprintf args number mismatch: %s',ES('JSON','stringify',false,i));var k=1;return h.replace(/%s/g,function(l){return String(i[k++]);});};e.exports=g;},null);
+ __d("ex",["eprintf"],function(a,b,c,d,e,f,g){var h=function(){var i=Array.prototype.slice.call(arguments,0);i=ES(i,'map',true,function(j){return String(j);});if(i[0].split('%s').length!==i.length)return h('ex args number mismatch: %s',ES('JSON','stringify',false,i));return h._prefix+ES('JSON','stringify',false,i)+h._suffix;};h._prefix='';e.exports=h;},null);
+ __d("invariant",[],function(a,b,c,d,e,f){"use strict";var g=function(h,i,j,k,l,m,n,o){if(!h){var p;if(i===undefined){p=new Error('Minified exception occurred; use the non-minified dev environment '+'for the full error message and additional helpful warnings.');}else{var q=[j,k,l,m,n,o],r=0;p=new Error('Invariant Violation: '+i.replace(/%s/g,function(){return q[r++];}));}p.framesToPop=1;throw p;}};e.exports=g;},null);
+ __d("URIBase",["URIRFC3986","URISchemes","copyProperties","ex","invariant"],function(a,b,c,d,e,f,g,h,i,j,k){var l=new RegExp('[\\x00-\\x2c\\x2f\\x3b-\\x40\\x5c\\x5e\\x60\\x7b-\\x7f'+'\\uFDD0-\\uFDEF\\uFFF0-\\uFFFF'+'\\u2047\\u2048\\uFE56\\uFE5F\\uFF03\\uFF0F\\uFF1F]'),m=new RegExp('^(?:[^/]*:|'+'[\\x00-\\x1f]*/[\\x00-\\x1f]*/)');function n(p,q,r,s){if(!q)return true;if(q instanceof o){p.setProtocol(q.getProtocol());p.setDomain(q.getDomain());p.setPort(q.getPort());p.setPath(q.getPath());p.setQueryData(s.deserialize(s.serialize(q.getQueryData())));p.setFragment(q.getFragment());p.setForceFragmentSeparator(q.getForceFragmentSeparator());return true;}q=ES(q.toString(),'trim',true);var t=g.parse(q)||{};if(!r&&!h.isAllowed(t.scheme))return false;p.setProtocol(t.scheme||'');if(!r&&l.test(t.host))return false;p.setDomain(t.host||'');p.setPort(t.port||'');p.setPath(t.path||'');if(r){p.setQueryData(s.deserialize(t.query)||{});}else try{p.setQueryData(s.deserialize(t.query)||{});}catch(u){return false;}p.setFragment(t.fragment||'');if(t.fragment==='')p.setForceFragmentSeparator(true);if(t.userinfo!==null)if(r){throw new Error(j('URI.parse: invalid URI (userinfo is not allowed in a URI): %s',p.toString()));}else return false;if(!p.getDomain()&&ES(p.getPath(),'indexOf',true,'\\')!==-1)if(r){throw new Error(j('URI.parse: invalid URI (no domain but multiple back-slashes): %s',p.toString()));}else return false;if(!p.getProtocol()&&m.test(q))if(r){throw new Error(j('URI.parse: invalid URI (unsafe protocol-relative URLs): %s',p.toString()));}else return false;return true;}function o(p,q){"use strict";k(q);this.$URIBase0=q;this.$URIBase1='';this.$URIBase2='';this.$URIBase3='';this.$URIBase4='';this.$URIBase5='';this.$URIBase6={};this.$URIBase7=false;n(this,p,true,q);}o.prototype.setProtocol=function(p){"use strict";k(h.isAllowed(p));this.$URIBase1=p;return this;};o.prototype.getProtocol=function(p){"use strict";return this.$URIBase1;};o.prototype.setSecure=function(p){"use strict";return this.setProtocol(p?'https':'http');};o.prototype.isSecure=function(){"use strict";return this.getProtocol()==='https';};o.prototype.setDomain=function(p){"use strict";if(l.test(p))throw new Error(j('URI.setDomain: unsafe domain specified: %s for url %s',p,this.toString()));this.$URIBase2=p;return this;};o.prototype.getDomain=function(){"use strict";return this.$URIBase2;};o.prototype.setPort=function(p){"use strict";this.$URIBase3=p;return this;};o.prototype.getPort=function(){"use strict";return this.$URIBase3;};o.prototype.setPath=function(p){"use strict";this.$URIBase4=p;return this;};o.prototype.getPath=function(){"use strict";return this.$URIBase4;};o.prototype.addQueryData=function(p,q){"use strict";if(Object.prototype.toString.call(p)==='[object Object]'){i(this.$URIBase6,p);}else this.$URIBase6[p]=q;return this;};o.prototype.setQueryData=function(p){"use strict";this.$URIBase6=p;return this;};o.prototype.getQueryData=function(){"use strict";return this.$URIBase6;};o.prototype.removeQueryData=function(p){"use strict";if(!ES('Array','isArray',false,p))p=[p];for(var q=0,r=p.length;q0||this.getFragment());};o.prototype.toString=function(){"use strict";var p='';if(this.$URIBase1)p+=this.$URIBase1+'://';if(this.$URIBase2)p+=this.$URIBase2;if(this.$URIBase3)p+=':'+this.$URIBase3;if(this.$URIBase4){p+=this.$URIBase4;}else if(p)p+='/';var q=this.$URIBase0.serialize(this.$URIBase6);if(q)p+='?'+q;if(this.$URIBase5){p+='#'+this.$URIBase5;}else if(this.$URIBase7)p+='#';return p;};o.prototype.getOrigin=function(){"use strict";return this.$URIBase1+'://'+this.$URIBase2+(this.$URIBase3?':'+this.$URIBase3:'');};o.isValidURI=function(p,q){return n(new o(null,q),p,false,q);};e.exports=o;},null);
+ __d("sdk.URI",["Assert","QueryString","URIBase"],function(a,b,c,d,e,f,g,h,i){var j=/\.facebook\.com$/,k={serialize:function(o){return o?h.encode(o):'';},deserialize:function(o){return o?h.decode(o):{};}};for(var l in i)if(i.hasOwnProperty(l))n[l]=i[l];var m=i===null?null:i.prototype;n.prototype=ES('Object','create',false,m);n.prototype.constructor=n;n.__superConstructor__=i;function n(o){"use strict";g.isString(o,'The passed argument was of invalid type.');if(!(this instanceof n))return new n(o);i.call(this,o,k);}n.prototype.isFacebookURI=function(){"use strict";return j.test(this.getDomain());};n.prototype.valueOf=function(){"use strict";return this.toString();};e.exports=n;},null);
+ __d("sdk.Event",[],function(a,b,c,d,e,f){var g={SUBSCRIBE:'event.subscribe',UNSUBSCRIBE:'event.unsubscribe',subscribers:function(){if(!this._subscribersMap)this._subscribersMap={};return this._subscribersMap;},subscribe:function(h,i){var j=this.subscribers();if(!j[h]){j[h]=[i];}else if(ES(j[h],'indexOf',true,i)==-1)j[h].push(i);if(h!=this.SUBSCRIBE&&h!=this.UNSUBSCRIBE)this.fire(this.SUBSCRIBE,h,j[h]);},unsubscribe:function(h,i){var j=this.subscribers()[h];if(j)ES(j,'forEach',true,function(k,l){if(k==i)j.splice(l,1);});if(h!=this.SUBSCRIBE&&h!=this.UNSUBSCRIBE)this.fire(this.UNSUBSCRIBE,h,j);},monitor:function(h,i){if(!i()){var j=this,k=function(){if(i.apply(i,arguments))j.unsubscribe(h,k);};this.subscribe(h,k);}},clear:function(h){delete this.subscribers()[h];},fire:function(h){var i=Array.prototype.slice.call(arguments,1),j=this.subscribers()[h];if(j)ES(j,'forEach',true,function(k){if(k)k.apply(this,i);});}};e.exports=g;},null);
+ __d("Queue",["copyProperties"],function(a,b,c,d,e,f,g){var h={};function i(j){"use strict";this._opts=g({interval:0,processor:null},j);this._queue=[];this._stopped=true;}i.prototype._dispatch=function(j){"use strict";if(this._stopped||this._queue.length===0)return;if(!this._opts.processor){this._stopped=true;throw new Error('No processor available');}if(this._opts.interval){this._opts.processor.call(this,this._queue.shift());this._timeout=setTimeout(ES(this._dispatch,'bind',true,this),this._opts.interval);}else while(this._queue.length)this._opts.processor.call(this,this._queue.shift());};i.prototype.enqueue=function(j){"use strict";if(this._opts.processor&&!this._stopped){this._opts.processor.call(this,j);}else this._queue.push(j);return this;};i.prototype.start=function(j){"use strict";if(j)this._opts.processor=j;this._stopped=false;this._dispatch();return this;};i.prototype.isStarted=function(){"use strict";return !this._stopped;};i.prototype.dispatch=function(){"use strict";this._dispatch(true);};i.prototype.stop=function(j){"use strict";this._stopped=true;if(j)clearTimeout(this._timeout);return this;};i.prototype.merge=function(j,k){"use strict";this._queue[k?'unshift':'push'].apply(this._queue,j._queue);j._queue=[];this._dispatch();return this;};i.prototype.getLength=function(){"use strict";return this._queue.length;};i.get=function(j,k){"use strict";var l;if(j in h){l=h[j];}else l=h[j]=new i(k);return l;};i.exists=function(j){"use strict";return j in h;};i.remove=function(j){"use strict";return delete h[j];};e.exports=i;},null);
+ __d("JSONRPC",["Log"],function(a,b,c,d,e,f,g){function h(i){"use strict";this.$JSONRPC0=0;this.$JSONRPC1={};this.remote=ES(function(j){this.$JSONRPC2=j;return this.remote;},'bind',true,this);this.local={};this.$JSONRPC3=i;}h.prototype.stub=function(i){"use strict";this.remote[i]=ES(function(){var j=Array.prototype.slice.call(arguments,0),k={jsonrpc:'2.0',method:i};if(typeof j[j.length-1]=='function'){k.id=++this.$JSONRPC0;this.$JSONRPC1[k.id]=j.pop();}k.params=j;this.$JSONRPC3(ES('JSON','stringify',false,k),this.$JSONRPC2||{method:i});},'bind',true,this);};h.prototype.read=function(i,j){"use strict";var k=ES('JSON','parse',false,i),l=k.id;if(!k.method){if(!this.$JSONRPC1[l]){g.warn('Could not find callback %s',l);return;}var m=this.$JSONRPC1[l];delete this.$JSONRPC1[l];delete k.id;delete k.jsonrpc;m(k);return;}var n=this,o=this.local[k.method],p;if(l){p=function(s,t){var u={jsonrpc:'2.0',id:l};u[s]=t;setTimeout(function(){n.$JSONRPC3(ES('JSON','stringify',false,u),j);},0);};}else p=function(){};if(!o){g.error('Method "%s" has not been defined',k.method);p('error',{code:-32601,message:'Method not found',data:k.method});return;}k.params.push(ES(p,'bind',true,null,'result'));k.params.push(ES(p,'bind',true,null,'error'));try{var r=o.apply(j||null,k.params);if(typeof r!=='undefined')p('result',r);}catch(q){g.error('Invokation of RPC method %s resulted in the error: %s',k.method,q.message);p('error',{code:-32603,message:'Internal error',data:q.message});}};e.exports=h;},null);
+ __d("sdk.RPC",["Assert","JSONRPC","Queue"],function(a,b,c,d,e,f,g,h,i){var j=new i(),k=new h(function(m){j.enqueue(m);}),l={local:k.local,remote:k.remote,stub:ES(k.stub,'bind',true,k),setInQueue:function(m){g.isInstanceOf(i,m);m.start(function(n){k.read(n);});},getOutQueue:function(){return j;}};e.exports=l;},null);
+ __d("sdk.Scribe",["QueryString","sdk.Runtime","UrlMap"],function(a,b,c,d,e,f,g,h,i){function j(l,m){if(typeof m.extra=='object')m.extra.revision=h.getRevision();(new Image()).src=g.appendToUrl(i.resolve('www',true)+'/common/scribe_endpoint.php',{c:l,m:ES('JSON','stringify',false,m)});}var k={log:j};e.exports=k;},null);
+ __d("emptyFunction",["copyProperties"],function(a,b,c,d,e,f,g){function h(j){return function(){return j;};}function i(){}g(i,{thatReturns:h,thatReturnsFalse:h(false),thatReturnsTrue:h(true),thatReturnsNull:h(null),thatReturnsThis:function(){return this;},thatReturnsArgument:function(j){return j;}});e.exports=i;},null);
+ __d("htmlSpecialChars",[],function(a,b,c,d,e,f){var g=/&/g,h=//g,j=/"/g,k=/'/g;function l(m){if(typeof m=='undefined'||m===null||!m.toString)return '';if(m===false){return '0';}else if(m===true)return '1';return m.toString().replace(g,'&').replace(j,'"').replace(k,''').replace(h,'<').replace(i,'>');}e.exports=l;},null);
+ __d("Flash",["DOMEventListener","DOMWrapper","QueryString","UserAgent_DEPRECATED","copyProperties","guid","htmlSpecialChars"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n={},o,p=h.getWindow().document;function q(v){var w=p.getElementById(v);if(w)w.parentNode.removeChild(w);delete n[v];}function r(){for(var v in n)if(n.hasOwnProperty(v))q(v);}function s(v){return v.replace(/\d+/g,function(w){return '000'.substring(w.length)+w;});}function t(v){if(!o){if(j.ie()>=9)g.add(window,'unload',r);o=true;}n[v]=v;}var u={embed:function(v,w,x,y){var z=l();v=m(v).replace(/&/g,'&');x=k({allowscriptaccess:'always',flashvars:y,movie:v},x||{});if(typeof x.flashvars=='object')x.flashvars=i.encode(x.flashvars);var aa=[];for(var ba in x)if(x.hasOwnProperty(ba)&&x[ba])aa.push(' ');var ca=w.appendChild(p.createElement('span')),da=''+aa.join('')+' ';ca.innerHTML=da;var ea=ca.firstChild;t(z);return ea;},remove:q,getVersion:function(){var v='Shockwave Flash',w='application/x-shockwave-flash',x='ShockwaveFlash.ShockwaveFlash',y;if(navigator.plugins&&typeof navigator.plugins[v]=='object'){var z=navigator.plugins[v].description;if(z&&navigator.mimeTypes&&navigator.mimeTypes[w]&&navigator.mimeTypes[w].enabledPlugin)y=z.match(/\d+/g);}if(!y)try{y=(new ActiveXObject(x)).GetVariable('$version').match(/(\d+),(\d+),(\d+),(\d+)/);y=Array.prototype.slice.call(y,1);}catch(aa){}return y;},checkMinVersion:function(v){var w=u.getVersion();if(!w)return false;return s(w.join('.'))>=s(v);},isAvailable:function(){return !!u.getVersion();}};e.exports=u;},null);
+ __d("XDM",["DOMEventListener","DOMWrapper","emptyFunction","Flash","GlobalCallback","guid","Log","UserAgent_DEPRECATED","wrapFunction"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p={},q={transports:[]},r=h.getWindow();function s(u){var v={},w=u.length,x=q.transports;while(w--)v[u[w]]=1;w=x.length;while(w--){var y=x[w],z=p[y];if(!v[y]&&z.isAvailable())return y;}}var t={register:function(u,v){m.debug('Registering %s as XDM provider',u);q.transports.push(u);p[u]=v;},create:function(u){if(!u.whenReady&&!u.onMessage){m.error('An instance without whenReady or onMessage makes no sense');throw new Error('An instance without whenReady or '+'onMessage makes no sense');}if(!u.channel){m.warn('Missing channel name, selecting at random');u.channel=l();}if(!u.whenReady)u.whenReady=i;if(!u.onMessage)u.onMessage=i;var v=u.transport||s(u.blacklist||[]),w=p[v];if(w&&w.isAvailable()){m.debug('%s is available',v);w.init(u);return v;}}};t.register('flash',(function(){var u=false,v,w=false,x=15000,y;return {isAvailable:function(){return j.checkMinVersion('8.0.24');},init:function(z){m.debug('init flash: '+z.channel);var aa={send:function(da,ea,fa,ga){m.debug('sending to: %s (%s)',ea,ga);v.postMessage(da,ea,ga);}};if(u){z.whenReady(aa);return;}var ba=z.root.appendChild(r.document.createElement('div')),ca=k.create(function(){k.remove(ca);clearTimeout(y);m.info('xdm.swf called the callback');var da=k.create(function(ea,fa){ea=decodeURIComponent(ea);fa=decodeURIComponent(fa);m.debug('received message %s from %s',ea,fa);z.onMessage(ea,fa);},'xdm.swf:onMessage');v.init(z.channel,da);z.whenReady(aa);},'xdm.swf:load');v=j.embed(z.flashUrl,ba,null,{protocol:location.protocol.replace(':',''),host:location.host,callback:ca,log:w});y=setTimeout(function(){m.warn('The Flash component did not load within %s ms - '+'verify that the container is not set to hidden or invisible '+'using CSS as this will cause some browsers to not load '+'the components',x);},x);u=true;}};})());t.register('postmessage',(function(){var u=false;return {isAvailable:function(){return !!r.postMessage;},init:function(v){m.debug('init postMessage: '+v.channel);var w='_FB_'+v.channel,x={send:function(y,z,aa,ba){if(r===aa){m.error('Invalid windowref, equal to window (self)');throw new Error();}m.debug('sending to: %s (%s)',z,ba);var ca=function(){aa.postMessage('_FB_'+ba+y,z);};if(n.ie()==8||n.ieCompatibilityMode()){setTimeout(ca,0);}else ca();}};if(u){v.whenReady(x);return;}g.add(r,'message',o(function(event){var y=event.data,z=event.origin||'native';if(!/^(https?:\/\/|native$)/.test(z)){m.debug('Received message from invalid origin type: %s',z);return;}if(typeof y!='string'){m.warn('Received message of type %s from %s, expected a string',typeof y,z);return;}m.debug('received message %s from %s',y,z);if(y.substring(0,w.length)==w)y=y.substring(w.length);v.onMessage(y,z);},'entry','onMessage'));v.whenReady(x);u=true;}};})());e.exports=t;},null);
+ __d("isFacebookURI",[],function(a,b,c,d,e,f){var g=null,h=['http','https'];function i(j){if(!g)g=new RegExp('(^|\\.)facebook\\.com$','i');if(j.isEmpty())return false;if(!j.getDomain()&&!j.getProtocol())return true;return (ES(h,'indexOf',true,j.getProtocol())!==-1&&g.test(j.getDomain()));}e.exports=i;},null);
+ __d("sdk.XD",["sdk.Content","sdk.Event","Log","QueryString","Queue","sdk.RPC","sdk.Runtime","sdk.Scribe","sdk.URI","UrlMap","JSSDKXDConfig","XDM","isFacebookURI","sdk.createIframe","sdk.feature","guid"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v){var w=new k(),x=new k(),y=new k(),z,aa,ba=v(),ca=q.useCdn?'cdn':'www',da=u('use_bundle')?q.XdBundleUrl:q.XdUrl,ea=p.resolve(ca,false)+da,fa=p.resolve(ca,true)+da,ga=v(),ha=location.protocol+'//'+location.host,ia,ja=false,ka='Facebook Cross Domain Communication Frame',la={},ma=new k();l.setInQueue(ma);function na(ta){i.info('Remote XD can talk to facebook.com (%s)',ta);m.setEnvironment(ta==='canvas'?m.ENVIRONMENTS.CANVAS:m.ENVIRONMENTS.PAGETAB);}function oa(ta,ua){if(!ua){i.error('No senderOrigin');throw new Error();}var va=/^https?/.exec(ua)[0];switch(ta.xd_action){case 'proxy_ready':var wa,xa;if(va=='https'){wa=y;xa=aa;}else{wa=x;xa=z;}if(ta.registered){na(ta.registered);w=wa.merge(w);}i.info('Proxy ready, starting queue %s containing %s messages',va+'ProxyQueue',wa.getLength());wa.start(function(za){ia.send(typeof za==='string'?za:j.encode(za),ua,xa.contentWindow,ga+'_'+va);});break;case 'plugin_ready':i.info('Plugin %s ready, protocol: %s',ta.name,va);la[ta.name]={protocol:va};if(k.exists(ta.name)){var ya=k.get(ta.name);i.debug('Enqueuing %s messages for %s in %s',ya.getLength(),ta.name,va+'ProxyQueue');(va=='https'?y:x).merge(ya);}break;}if(ta.data)pa(ta.data,ua);}function pa(ta,ua){if(ua&&ua!=='native'&&!s(o(ua)))return;if(typeof ta=='string'){if(/^FB_RPC:/.test(ta)){ma.enqueue(ta.substring(7));return;}if(ta.substring(0,1)=='{'){try{ta=ES('JSON','parse',false,ta);}catch(va){i.warn('Failed to decode %s as JSON',ta);return;}}else ta=j.decode(ta);}if(!ua)if(ta.xd_sig==ba)ua=ta.xd_origin;if(ta.xd_action){oa(ta,ua);return;}if(ta.access_token)m.setSecure(/^https/.test(ha));if(ta.cb){var wa=sa._callbacks[ta.cb];if(!sa._forever[ta.cb])delete sa._callbacks[ta.cb];if(wa)wa(ta);}}function qa(ta,ua){if(ta=='facebook'){ua.relation='parent.parent';w.enqueue(ua);}else{ua.relation='parent.frames["'+ta+'"]';var va=la[ta];if(va){i.debug('Enqueuing message for plugin %s in %s',ta,va.protocol+'ProxyQueue');(va.protocol=='https'?y:x).enqueue(ua);}else{i.debug('Buffering message for plugin %s',ta);k.get(ta).enqueue(ua);}}}l.getOutQueue().start(function(ta){qa('facebook','FB_RPC:'+ta);});function ra(ta){if(ja)return;var ua=g.appendHidden(document.createElement('div')),va=r.create({blacklist:null,root:ua,channel:ga,flashUrl:q.Flash.path,whenReady:function(wa){ia=wa;var xa={channel:ga,origin:location.protocol+'//'+location.host,transport:va,xd_name:ta},ya='#'+j.encode(xa);if(m.getSecure()!==true)z=t({url:ea+ya,name:'fb_xdm_frame_http',id:'fb_xdm_frame_http',root:ua,'aria-hidden':true,title:ka,tabindex:-1});aa=t({url:fa+ya,name:'fb_xdm_frame_https',id:'fb_xdm_frame_https',root:ua,'aria-hidden':true,title:ka,tabindex:-1});},onMessage:pa});if(!va)n.log('jssdk_error',{appId:m.getClientID(),error:'XD_TRANSPORT',extra:{message:'Failed to create a valid transport'}});ja=true;}var sa={rpc:l,_callbacks:{},_forever:{},_channel:ga,_origin:ha,onMessage:pa,recv:pa,init:ra,sendToFacebook:qa,inform:function(ta,ua,va,wa){qa('facebook',{method:ta,params:ES('JSON','stringify',false,ua||{}),behavior:wa||'p',relation:va});},handler:function(ta,ua,va,wa){var xa='#'+j.encode({cb:this.registerCallback(ta,va,wa),origin:ha+'/'+ga,domain:location.hostname,relation:ua||'opener'});return (location.protocol=='https:'?fa:ea)+xa;},registerCallback:function(ta,ua,va){va=va||v();if(ua)sa._forever[va]=true;sa._callbacks[va]=ta;return va;}};h.subscribe('init:post',function(ta){ra(ta.xdProxyName);var ua=u('xd_timeout');if(ua)setTimeout(function(){var va=aa&&(!!z==x.isStarted()&&!!aa==y.isStarted());if(!va)n.log('jssdk_error',{appId:m.getClientID(),error:'XD_INITIALIZATION',extra:{message:'Failed to initialize in '+ua+'ms'}});},ua);});e.exports=sa;},null);
+ __d("sdk.Auth",["sdk.Cookie","sdk.createIframe","DOMWrapper","sdk.feature","sdk.getContextType","guid","sdk.Impressions","Log","ObservableMixin","sdk.Runtime","sdk.SignedRequest","UrlMap","sdk.URI","sdk.XD"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t){var u,v,w=new o();function x(da,ea){var fa=p.getUserID(),ga='';if(da)if(da.userID){ga=da.userID;}else if(da.signedRequest){var ha=q.parse(da.signedRequest);if(ha&&ha.user_id)ga=ha.user_id;}var ia=p.getLoginStatus(),ja=(ia==='unknown'&&da)||(p.getUseCookie()&&p.getCookieUserID()!==ga),ka=fa&&!da,la=da&&fa&&fa!=ga,ma=da!=u,na=ea!=(ia||'unknown');p.setLoginStatus(ea);p.setAccessToken(da&&da.accessToken||null);p.setUserID(ga);u=da;var oa={authResponse:da,status:ea};if(ka||la)w.inform('logout',oa);if(ja||la)w.inform('login',oa);if(ma)w.inform('authresponse.change',oa);if(na)w.inform('status.change',oa);return oa;}function y(){return u;}function z(da,ea,fa){return function(ga){var ha;if(ga&&ga.access_token){var ia=q.parse(ga.signed_request);ea={accessToken:ga.access_token,userID:ia.user_id,expiresIn:parseInt(ga.expires_in,10),signedRequest:ga.signed_request};if(ga.granted_scopes)ea.grantedScopes=ga.granted_scopes;if(p.getUseCookie()){var ja=ea.expiresIn===0?0:ES('Date','now',false)+ea.expiresIn*1000,ka=g.getDomain();if(!ka&&ga.base_domain)g.setDomain('.'+ga.base_domain);g.setSignedRequestCookie(ga.signed_request,ja);}ha='connected';x(ea,ha);}else if(fa==='logout'||fa==='login_status'){if(ga.error&&ga.error==='not_authorized'){ha='not_authorized';}else ha='unknown';x(null,ha);if(p.getUseCookie())g.clearSignedRequestCookie();}if(ga&&ga.https==1)p.setSecure(true);if(da)da({authResponse:ea,status:p.getLoginStatus()});return ea;};}function aa(da){var ea,fa=ES('Date','now',false);if(v){clearTimeout(v);v=null;}var ga=z(da,u,'login_status'),ha=s(r.resolve('www',true)+'/connect/ping').setQueryData({client_id:p.getClientID(),response_type:'token,signed_request,code',domain:location.hostname,origin:k(),redirect_uri:t.handler(function(ia){if(j('e2e_ping_tracking',true)){var ja={init:fa,close:ES('Date','now',false),method:'ping'};n.debug('e2e: %s',ES('JSON','stringify',false,ja));m.log(114,{payload:ja});}ea.parentNode.removeChild(ea);if(ga(ia))v=setTimeout(function(){aa(function(){});},1200000);},'parent'),sdk:'joey',kid_directed_site:p.getKidDirectedSite()});ea=h({root:i.getRoot(),name:l(),url:ha.toString(),style:{display:'none'}});}var ba;function ca(da,ea){if(!p.getClientID()){n.warn('FB.getLoginStatus() called before calling FB.init().');return;}if(da)if(!ea&&ba=='loaded'){da({status:p.getLoginStatus(),authResponse:y()});return;}else w.subscribe('FB.loginStatus',da);if(!ea&&ba=='loading')return;ba='loading';var fa=function(ga){ba='loaded';w.inform('FB.loginStatus',ga);w.clearSubscribers('FB.loginStatus');};aa(fa);}ES('Object','assign',false,w,{getLoginStatus:ca,fetchLoginStatus:aa,setAuthResponse:x,getAuthResponse:y,parseSignedRequest:q.parse,xdResponseWrapper:z});e.exports=w;},null);
+ __d("toArray",["invariant"],function(a,b,c,d,e,f,g){function h(i){var j=i.length;g(!ES('Array','isArray',false,i)&&(typeof i==='object'||typeof i==='function'));g(typeof j==='number');g(j===0||(j-1) in i);if(i.hasOwnProperty)try{return Array.prototype.slice.call(i);}catch(k){}var l=Array(j);for(var m=0;m=0;}function q(z,aa){g.isTruthy(z,'element not specified');g.isString(aa);if(!p(z,aa))z.className=n(z,'className')+' '+aa;}function r(z,aa){g.isTruthy(z,'element not specified');g.isString(aa);var ba=new RegExp('\\s*'+aa,'g');z.className=ES(n(z,'className').replace(ba,''),'trim',true);}function s(z,aa,ba){g.isString(z);aa=aa||document.body;ba=ba||'*';if(aa.querySelectorAll)return h(aa.querySelectorAll(ba+'.'+z));var ca=aa.getElementsByTagName(ba),da=[];for(var ea=0,fa=ca.length;ea2000){h.remove(n.callback);return false;}p.onerror=function(){q({error:{type:'http',message:'unknown error'}});};var r=function(){setTimeout(function(){q({error:{type:'http',message:'unknown error'}});},0);};if(p.addEventListener){p.addEventListener('load',r,false);}else p.onreadystatechange=function(){if(/loaded|complete/.test(this.readyState))r();};p.src=l;g.getRoot().appendChild(p);return true;}var k={execute:j};e.exports=k;},null);
+ __d("ApiClient",["ArgumentError","Assert","CORSRequest","FlashRequest","flattenObject","JSONPRequest","Log","ObservableMixin","sprintf","sdk.URI","UrlMap","ApiClientConfig","invariant"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s){var t,u,v,w={get:true,post:true,'delete':true,put:true},x={fql_query:true,fql_multiquery:true,friends_get:true,notifications_get:true,stream_get:true,users_getinfo:true},y=[],z=[],aa=null,ba=50,ca=105440539523;function da(la,ma,na,oa){if(v)na=ES('Object','assign',false,{},v,na);na.access_token=na.access_token||t;na.pretty=na.pretty||0;na=k(na);var pa={jsonp:l,cors:i,flash:j},qa;if(na.transport){qa=[na.transport];delete na.transport;}else qa=['jsonp','cors','flash'];for(var ra=0;ra0);var la=y,ma=z;y=[];z=[];aa=null;ga('/','POST',{batch:ES('JSON','stringify',false,la),include_headers:false,batch_app_id:u||ca},function(na){if(ES('Array','isArray',false,na)){ES(na,'forEach',true,function(oa,pa){ma[pa](ES('JSON','parse',false,oa.body));});}else ES(ma,'forEach',true,function(oa){return oa({error:{message:'Fatal: batch call failed.'}});});});}function ja(la,ma){h.isObject(la);h.isString(la.method,'method missing');if(!ma)m.warn('No callback passed to the ApiClient');var na=la.method.toLowerCase().replace('.','_');la.format='json-strings';la.api_key=u;var oa=na in x?'api_read':'api',pa=q.resolve(oa)+'/restserver.php',qa=ES(ea,'bind',true,null,ma,'/restserver.php','get',la);da(pa,'get',la,qa);}var ka=ES('Object','assign',false,new n(),{setAccessToken:function(la){t=la;},setClientID:function(la){u=la;},setDefaultParams:function(la){v=la;},rest:ja,graph:ga,scheduleBatchCall:ha});j.setSwfUrl(r.FlashRequest.swfUrl);e.exports=ka;},null);
+ __d("sdk.PlatformVersioning",["sdk.Runtime","ManagedError"],function(a,b,c,d,e,f,g,h){var i=/^v\d+\.\d\d?$/,j={REGEX:i,assertVersionIsSet:function(){if(!g.getVersion())throw new h('init not called with valid version');},assertValidVersion:function(k){if(!i.test(k))throw new h('invalid version specified');}};e.exports=j;},null);
+ __d("sdk.api",["ApiClient","sdk.PlatformVersioning","sdk.Runtime","sdk.URI"],function(a,b,c,d,e,f,g,h,i,j){var k;i.subscribe('ClientID.change',function(m){g.setClientID(m);});i.subscribe('AccessToken.change',function(m){k=m;g.setAccessToken(m);});g.setDefaultParams({sdk:'joey'});g.subscribe('request.complete',function(m,n,o,p){var q=false;if(p&&typeof p=='object')if(p.error){if(p.error=='invalid_token'||(p.error.type=='OAuthException'&&p.error.code==190))q=true;}else if(p.error_code)if(p.error_code=='190')q=true;if(q&&k===i.getAccessToken())i.setAccessToken(null);});g.subscribe('request.complete',function(m,n,o,p){if(((m=='/me/permissions'&&n==='delete')||(m=='/restserver.php'&&o.method=='Auth.revokeAuthorization'))&&p===true)i.setAccessToken(null);});function l(m){if(typeof m==='string'){if(i.getIsVersioned()){h.assertVersionIsSet();if(!/https?/.test(m)&&m.charAt(0)!=='/')m='/'+m;m=j(m).setDomain(null).setProtocol(null).toString();if(!h.REGEX.test(m.substring(1,ES(m,'indexOf',true,'/',1))))m='/'+i.getVersion()+m;var n=[m].concat(Array.prototype.slice.call(arguments,1));g.graph.apply(g,n);}else g.graph.apply(g,arguments);}else g.rest.apply(g,arguments);}e.exports=l;},null);
+ __d("legacy:fb.api",["FB","sdk.api"],function(a,b,c,d,e,f,g,h){g.provide('',{api:h});},3);
+ __d("merge",[],function(a,b,c,d,e,f){"use strict";var g=function(h,i){return ES('Object','assign',false,{},h,i);};e.exports=g;},null);
+ __d("sdk.AppEvents",["Assert","sdk.Impressions","merge","sdk.Runtime"],function(a,b,c,d,e,f,g,h,i,j){var k={COMPLETED_REGISTRATION:'fb_mobile_complete_registration',VIEWED_CONTENT:'fb_mobile_content_view',SEARCHED:'fb_mobile_search',RATED:'fb_mobile_rate',COMPLETED_TUTORIAL:'fb_mobile_tutorial_completion',ADDED_TO_CART:'fb_mobile_add_to_cart',ADDED_TO_WISHLIST:'fb_mobile_add_to_wishlist',INITIATED_CHECKOUT:'fb_mobile_initiated_checkout',ADDED_PAYMENT_INFO:'fb_mobile_add_payment_info',ACHIEVED_LEVEL:'fb_mobile_level_achieved',UNLOCKED_ACHIEVEMENT:'fb_mobile_achievement_unlocked',SPENT_CREDITS:'fb_mobile_spent_credits'},l={ACTIVATED_APP:'fb_mobile_activate_app',PURCHASED:'fb_mobile_purchase'},m={CURRENCY:'fb_currency',REGISTRATION_METHOD:'fb_registration_method',CONTENT_TYPE:'fb_content_type',CONTENT_ID:'fb_content_id',SEARCH_STRING:'fb_search_string',SUCCESS:'fb_success',MAX_RATING_VALUE:'fb_max_rating_value',PAYMENT_INFO_AVAILABLE:'fb_payment_info_available',NUM_ITEMS:'fb_num_items',LEVEL:'fb_level',DESCRIPTION:'fb_description'},n=40,o='^[0-9a-zA-Z_]+[0-9a-zA-Z _-]*$';function p(t,u,v,w){g.isTrue(q(u),'Invalid event name: '+u+'. '+'It must be between 1 and '+n+' characters, '+'and must be contain only alphanumerics, _, - or spaces, '+'starting with alphanumeric or _.');var x={ae:1,ev:u,vts:v,canvas:j.isCanvasEnvironment()?1:0};if(w)x.cd=w;h.impression({api_key:t,payload:ES('JSON','stringify',false,x)});}function q(t){if(t===null||t.length===0||t.length>n||!(new RegExp(o)).test(t))return false;return true;}function r(t,u,v,w){var x={};x[m.CURRENCY]=v;p(t,l.PURCHASED,u,i(w,x));}function s(t){p(t,l.ACTIVATED_APP);}e.exports={activateApp:s,logEvent:p,logPurchase:r,isValidEventName:q,EventNames:k,ParameterNames:m};},null);
+ __d("legacy:fb.appevents",["Assert","sdk.AppEvents","FB","sdk.feature","sdk.Runtime"],function(a,b,c,d,e,f,g,h,i,j,k){i.provide('AppEvents',{logEvent:function(l,m,n){g.isTrue(j('allow_non_canvas_app_events')||k.isCanvasEnvironment(),'You can only use this function in Facebook Canvas environment');g.isString(l,'Invalid eventName');g.maybeNumber(m,'Invalid valueToSum');g.maybeObject(n,'Invalid params');var o=k.getClientID();g.isTrue(o!==null&&o.length>0,'You need to call FB.init() with App ID first.');h.logEvent(o,l,m,n);},logPurchase:function(l,m,n){g.isTrue(j('allow_non_canvas_app_events')||k.isCanvasEnvironment(),'You can only use this function in Facebook Canvas environment');g.isNumber(l,'Invalid purchaseAmount');g.isString(m,'Invalid currency');g.maybeObject(n,'Invalid params');var o=k.getClientID();g.isTrue(o!==null&&o.length>0,'You need to call FB.init() with App ID first.');h.logPurchase(o,l,m,n);},activateApp:function(){g.isTrue(j('allow_non_canvas_app_events')||k.isCanvasEnvironment(),'You can only use this function in Facebook Canvas environment');var l=k.getClientID();g.isTrue(l!==null&&l.length>0,'You need to call FB.init() with App ID first.');h.activateApp(l);},EventNames:h.EventNames,ParameterNames:h.ParameterNames});},3);
+ __d("sdk.Canvas.Environment",["sdk.RPC"],function(a,b,c,d,e,f,g){function h(k){g.remote.getPageInfo(function(l){k(l.result);});}function i(k,l){g.remote.scrollTo({x:k||0,y:l||0});}g.stub('getPageInfo');g.stub('scrollTo');var j={getPageInfo:h,scrollTo:i};e.exports=j;},null);
+ __d("sdk.Intl",["Log"],function(a,b,c,d,e,f,g){var h=('['+'.!?'+'\u3002'+'\uFF01'+'\uFF1F'+'\u0964'+'\u2026'+'\u0EAF'+'\u1801'+'\u0E2F'+'\uFF0E'+']');function i(l){if(typeof l!='string')return false;return !!l.match(new RegExp(h+'['+')"'+"'"+'\u00BB'+'\u0F3B'+'\u0F3D'+'\u2019'+'\u201D'+'\u203A'+'\u3009'+'\u300B'+'\u300D'+'\u300F'+'\u3011'+'\u3015'+'\u3017'+'\u3019'+'\u301B'+'\u301E'+'\u301F'+'\uFD3F'+'\uFF07'+'\uFF09'+'\uFF3D'+'\\s'+']*$'));}function j(l,m){if(m!==undefined)if(typeof m!='object'){g.error('The second arg to FB.Intl.tx() must be an Object for '+'FB.Intl.tx('+l+', ...)');}else{var n;for(var o in m)if(m.hasOwnProperty(o)){if(i(m[o])){n=new RegExp('\\{'+o+'\\}'+h+'*','g');}else n=new RegExp('\\{'+o+'\\}','g');l=l.replace(n,m[o]);}}return l;}function k(){throw new Error('Placeholder function');}k._=j;e.exports={tx:k};},null);
+ __d("sdk.Dialog",["sdk.Canvas.Environment","sdk.Content","sdk.DOM","DOMEventListener","sdk.Intl","ObservableMixin","sdk.Runtime","Type","UserAgent_DEPRECATED","sdk.feature"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){var q=590,r=500,s=240,t=575,u=function(){var y;if(p('dialog_resize_refactor')){var z=v();y=z&&(z.height>=q||z.width>=r);}else y=!!o.ipad();u=function(){return y;};return y;};function v(){if(p('dialog_resize_refactor')){var y=i.getViewportInfo();if(y.height&&y.width)return {width:Math.min(y.width,q),height:Math.min(y.height,r)};}return null;}var w=n.extend({constructor:function y(z,aa){this.parent();this.id=z;this.display=aa;this._e2e={};if(!x._dialogs){x._dialogs={};x._addOrientationHandler();}x._dialogs[z]=this;this.trackEvent('init');},trackEvent:function(y,z){if(this._e2e[y])return this;this._e2e[y]=z||ES('Date','now',false);if(y=='close')this.inform('e2e:end',this._e2e);return this;},trackEvents:function(y){if(typeof y==='string')y=ES('JSON','parse',false,y);for(var z in y)if(y.hasOwnProperty(z))this.trackEvent(z,y[z]);return this;}},l),x={newInstance:function(y,z){return new w(y,z);},_dialogs:null,_lastYOffset:0,_loaderEl:null,_overlayEl:null,_stack:[],_active:null,get:function(y){return x._dialogs[y];},_findRoot:function(y){while(y){if(i.containsCss(y,'fb_dialog'))return y;y=y.parentNode;}},_createWWWLoader:function(y){y=y?y:460;return x.create({content:(''+'
'+''),width:y});},_createMobileLoader:function(){var y=o.nativeApp()?'':(''+' '+' '+' '+' '+' '+' '+' '+'
');return x.create({classes:'loading'+(u()?' centered':''),content:('')});},_restoreBodyPosition:function(){if(!u()){var y=document.getElementsByTagName('body')[0];i.removeCss(y,'fb_hidden');}},_showTabletOverlay:function(){if(!u())return;if(!x._overlayEl){x._overlayEl=document.createElement('div');x._overlayEl.setAttribute('id','fb_dialog_ipad_overlay');h.append(x._overlayEl,null);}x._overlayEl.className='';},_hideTabletOverlay:function(){if(u())x._overlayEl.className='hidden';},showLoader:function(y,z){x._showTabletOverlay();if(!x._loaderEl)x._loaderEl=x._findRoot(o.mobile()?x._createMobileLoader():x._createWWWLoader(z));if(!y)y=function(){};var aa=document.getElementById('fb_dialog_loader_close');i.removeCss(aa,'fb_hidden');aa.onclick=function(){x._hideLoader();x._restoreBodyPosition();x._hideTabletOverlay();y();};var ba=document.getElementById('fb_dialog_ipad_overlay');if(ba)ba.ontouchstart=aa.onclick;x._makeActive(x._loaderEl);},_hideLoader:function(){if(x._loaderEl&&x._loaderEl==x._active)x._loaderEl.style.top='-10000px';},_makeActive:function(y){x._setDialogSizes();x._lowerActive();x._active=y;if(m.isEnvironment(m.ENVIRONMENTS.CANVAS))g.getPageInfo(function(z){x._centerActive(z);});x._centerActive();},_lowerActive:function(){if(!x._active)return;x._active.style.top='-10000px';x._active=null;},_removeStacked:function(y){x._stack=ES(x._stack,'filter',true,function(z){return z!=y;});},_centerActive:function(y){var z=x._active;if(!z)return;var aa=i.getViewportInfo(),ba=parseInt(z.offsetWidth,10),ca=parseInt(z.offsetHeight,10),da=aa.scrollLeft+(aa.width-ba)/2,ea=(aa.height-ca)/2.5;if(dafa)ga=fa;ga+=aa.scrollTop;if(o.mobile()){var ha=100;if(u()){ha+=(aa.height-ca)/2;}else{var ia=document.getElementsByTagName('body')[0];i.addCss(ia,'fb_hidden');if(p('dialog_resize_refactor'))ia.style.width='auto';ga=10000;}var ja=i.getByClass('fb_dialog_padding',z);if(ja.length)ja[0].style.height=ha+'px';}z.style.left=(da>0?da:0)+'px';z.style.top=(ga>0?ga:0)+'px';},_setDialogSizes:function(){if(!o.mobile()||u())return;for(var y in x._dialogs)if(x._dialogs.hasOwnProperty(y)){var z=document.getElementById(y);if(z){z.style.width=x.getDefaultSize().width+'px';z.style.height=x.getDefaultSize().height+'px';}}},getDefaultSize:function(){if(o.mobile()){var y=v();if(y)return y;if(o.ipad())return {width:r,height:q};if(o.android()){return {width:screen.availWidth,height:screen.availHeight};}else{var z=window.innerWidth,aa=window.innerHeight,ba=z/aa>1.2;return {width:z,height:Math.max(aa,(ba?screen.width:screen.height))};}}return {width:t,height:s};},_handleOrientationChange:function(y){var z=p('dialog_resize_refactor',false)?i.getViewportInfo().width:screen.availWidth;if(o.android()&&z==x._availScreenWidth){setTimeout(x._handleOrientationChange,50);return;}x._availScreenWidth=z;if(u()){x._centerActive();}else{var aa=x.getDefaultSize().width;for(var ba in x._dialogs)if(x._dialogs.hasOwnProperty(ba)){var ca=document.getElementById(ba);if(ca)ca.style.width=aa+'px';}}},_addOrientationHandler:function(){if(!o.mobile())return;var y="onorientationchange" in window?'orientationchange':'resize';x._availScreenWidth=p('dialog_resize_refactor',false)?i.getViewportInfo().width:screen.availWidth;j.add(window,y,x._handleOrientationChange);},create:function(y){y=y||{};var z=document.createElement('div'),aa=document.createElement('div'),ba='fb_dialog';if(y.closeIcon&&y.onClose){var ca=document.createElement('a');ca.className='fb_dialog_close_icon';ca.onclick=y.onClose;z.appendChild(ca);}ba+=' '+(y.classes||'');if(o.ie()){ba+=' fb_dialog_legacy';ES(['vert_left','vert_right','horiz_top','horiz_bottom','top_left','top_right','bottom_left','bottom_right'],'forEach',true,function(fa){var ga=document.createElement('span');ga.className='fb_dialog_'+fa;z.appendChild(ga);});}else ba+=o.mobile()?' fb_dialog_mobile':' fb_dialog_advanced';if(y.content)h.append(y.content,aa);z.className=ba;var da=parseInt(y.width,10);if(!isNaN(da))z.style.width=da+'px';aa.className='fb_dialog_content';z.appendChild(aa);if(o.mobile()){var ea=document.createElement('div');ea.className='fb_dialog_padding';z.appendChild(ea);}h.append(z);if(y.visible)x.show(z);return aa;},show:function(y){var z=x._findRoot(y);if(z){x._removeStacked(z);x._hideLoader();x._makeActive(z);x._stack.push(z);if('fbCallID' in y)x.get(y.fbCallID).inform('iframe_show').trackEvent('show');}},hide:function(y){var z=x._findRoot(y);x._hideLoader();if(z==x._active){x._lowerActive();x._restoreBodyPosition();x._hideTabletOverlay();if('fbCallID' in y)x.get(y.fbCallID).inform('iframe_hide').trackEvent('hide');}},remove:function(y){y=x._findRoot(y);if(y){var z=x._active==y;x._removeStacked(y);if(z){x._hideLoader();if(x._stack.length>0){x.show(x._stack.pop());}else{x._lowerActive();x._restoreBodyPosition();x._hideTabletOverlay();}}else if(x._active===null&&x._stack.length>0)x.show(x._stack.pop());setTimeout(function(){y.parentNode.removeChild(y);},3000);}},isActive:function(y){var z=x._findRoot(y);return z&&z===x._active;}};e.exports=x;},null);
+ __d("sdk.Frictionless",["sdk.Auth","sdk.api","sdk.Event","sdk.Dialog"],function(a,b,c,d,e,f,g,h,i,j){var k={_allowedRecipients:{},_useFrictionless:false,_updateRecipients:function(){k._allowedRecipients={};h('/me/apprequestformerrecipients',function(l){if(!l||l.error)return;ES(l.data,'forEach',true,function(m){k._allowedRecipients[m.recipient_id]=true;});});},init:function(){k._useFrictionless=true;g.getLoginStatus(function(l){if(l.status=='connected')k._updateRecipients();});i.subscribe('auth.login',function(l){if(l.authResponse)k._updateRecipients();});},_processRequestResponse:function(l,m){return function(n){var o=n&&n.updated_frictionless;if(k._useFrictionless&&o)k._updateRecipients();if(n){if(!m&&n.frictionless){j._hideLoader();j._restoreBodyPosition();j._hideIPadOverlay();}delete n.frictionless;delete n.updated_frictionless;}l&&l(n);};},isAllowed:function(l){if(!l)return false;if(typeof l==='number')return l in k._allowedRecipients;if(typeof l==='string')l=l.split(',');l=ES(l,'map',true,function(o){return ES(String(o),'trim',true);});var m=true,n=false;ES(l,'forEach',true,function(o){m=m&&o in k._allowedRecipients;n=true;});return m&&n;}};i.subscribe('init:post',function(l){if(l.frictionlessRequests)k.init();});e.exports=k;},null);
+ __d("sdk.Native",["Log","UserAgent_DEPRECATED"],function(a,b,c,d,e,f,g,h){var i='fbNativeReady',j={onready:function(k){if(!h.nativeApp()){g.error('FB.Native.onready only works when the page is rendered '+'in a WebView of the native Facebook app. Test if this is the '+'case calling FB.UA.nativeApp()');return;}if(window.__fbNative&&!this.nativeReady)ES('Object','assign',false,this,window.__fbNative);if(this.nativeReady){k();}else{var l=function(m){window.removeEventListener(i,l);this.onready(k);};window.addEventListener(i,l,false);}}};e.exports=j;},null);
+ __d("resolveURI",[],function(a,b,c,d,e,f){function g(h){if(!h)return window.location.href;h=h.replace(/&/g,'&').replace(/"/g,'"');var i=document.createElement('div');i.innerHTML=' ';return i.firstChild.href;}e.exports=g;},null);
+ __d("sdk.UIServer",["sdk.Auth","sdk.Content","createObjectFrom","sdk.Dialog","sdk.DOM","sdk.Event","flattenObject","sdk.Frictionless","sdk.getContextType","guid","insertIframe","Log","sdk.Native","QueryString","resolveURI","sdk.RPC","sdk.Runtime","JSSDKConfig","UrlMap","UserAgent_DEPRECATED","sdk.XD"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa){var ba={transform:function(ea){if(ea.params.display==='touch'&&ea.params.access_token&&window.postMessage){ea.params.channel=da._xdChannelHandler(ea.id,'parent');if(!z.nativeApp())ea.params.in_iframe=1;return ea;}else return da.genericTransform(ea);},getXdRelation:function(ea){var fa=ea.display;if(fa==='touch'&&window.postMessage&&ea.in_iframe)return 'parent';return da.getXdRelation(ea);}},ca={'stream.share':{size:{width:670,height:340},url:'sharer.php',transform:function(ea){if(!ea.params.u)ea.params.u=window.location.toString();ea.params.display='popup';return ea;}},apprequests:{transform:function(ea){ea=ba.transform(ea);ea.params.frictionless=n&&n._useFrictionless;if(ea.params.frictionless){if(n.isAllowed(ea.params.to)){ea.params.display='iframe';ea.params.in_iframe=true;ea.hideLoader=true;}ea.cb=n._processRequestResponse(ea.cb,ea.hideLoader);}ea.closeIcon=false;return ea;},getXdRelation:ba.getXdRelation},feed:ba,'permissions.oauth':{url:'dialog/oauth',size:{width:(z.mobile()?null:475),height:(z.mobile()?null:183)},transform:function(ea){if(!w.getClientID()){r.error('FB.login() called before FB.init().');return;}if(g.getAuthResponse()&&!ea.params.scope&&!ea.params.auth_type){r.error('FB.login() called when user is already connected.');ea.cb&&ea.cb({status:w.getLoginStatus(),authResponse:g.getAuthResponse()});return;}var fa=ea.cb,ga=ea.id;delete ea.cb;var ha=ES('Object','keys',false,ES('Object','assign',false,ea.params.response_type?i(ea.params.response_type.split(',')):{},{token:true,signed_request:true})).join(',');if(ea.params.display==='async'){ES('Object','assign',false,ea.params,{client_id:w.getClientID(),origin:o(),response_type:ha,domain:location.hostname});ea.cb=g.xdResponseWrapper(fa,g.getAuthResponse(),'permissions.oauth');}else ES('Object','assign',false,ea.params,{client_id:w.getClientID(),redirect_uri:u(da.xdHandler(fa,ga,'opener',g.getAuthResponse(),'permissions.oauth')),origin:o(),response_type:ha,domain:location.hostname});return ea;}},'auth.logout':{url:'logout.php',transform:function(ea){if(!w.getClientID()){r.error('FB.logout() called before calling FB.init().');}else if(!g.getAuthResponse()){r.error('FB.logout() called without an access token.');}else{ea.params.next=da.xdHandler(ea.cb,ea.id,'parent',g.getAuthResponse(),'logout');return ea;}}},'login.status':{url:'dialog/oauth',transform:function(ea){var fa=ea.cb,ga=ea.id;delete ea.cb;ES('Object','assign',false,ea.params,{client_id:w.getClientID(),redirect_uri:da.xdHandler(fa,ga,'parent',g.getAuthResponse(),'login_status'),origin:o(),response_type:'token,signed_request,code',domain:location.hostname});return ea;}}},da={Methods:ca,_loadedNodes:{},_defaultCb:{},_resultToken:'"xxRESULTTOKENxx"',genericTransform:function(ea){if(ea.params.display=='dialog'||ea.params.display=='iframe')ES('Object','assign',false,ea.params,{display:'iframe',channel:da._xdChannelHandler(ea.id,'parent.parent')},true);return ea;},checkOauthDisplay:function(ea){var fa=ea.scope||ea.perms||w.getScope();if(!fa)return ea.display;var ga=fa.split(/\s|,/g);for(var ha=0;ha2000;},getDisplayMode:function(ea,fa){if(fa.display==='hidden'||fa.display==='none')return fa.display;var ga=w.isEnvironment(w.ENVIRONMENTS.CANVAS)||w.isEnvironment(w.ENVIRONMENTS.PAGETAB);if(ga&&!fa.display)return 'async';if(z.mobile()||fa.display==='touch')return 'touch';if(!w.getAccessToken()&&(fa.display=='iframe'||fa.display=='dialog')&&!ea.loggedOutIframe){r.error('"dialog" mode can only be used when the user is connected.');return 'popup';}if(ea.connectDisplay&&!ga)return ea.connectDisplay;return fa.display||(w.getAccessToken()?'dialog':'popup');},getXdRelation:function(ea){var fa=ea.display;if(fa==='popup'||fa==='touch')return 'opener';if(fa==='dialog'||fa==='iframe'||fa==='hidden'||fa==='none')return 'parent';if(fa==='async')return 'parent.frames['+window.name+']';},popup:function(ea){var fa=typeof window.screenX!='undefined'?window.screenX:window.screenLeft,ga=typeof window.screenY!='undefined'?window.screenY:window.screenTop,ha=typeof window.outerWidth!='undefined'?window.outerWidth:document.documentElement.clientWidth,ia=typeof window.outerHeight!='undefined'?window.outerHeight:(document.documentElement.clientHeight-22),ja=z.mobile()?null:ea.size.width,ka=z.mobile()?null:ea.size.height,la=(fa<0)?window.screen.width+fa:fa,ma=parseInt(la+((ha-ja)/2),10),na=parseInt(ga+((ia-ka)/2.5),10),oa=[];if(ja!==null)oa.push('width='+ja);if(ka!==null)oa.push('height='+ka);oa.push('left='+ma);oa.push('top='+na);oa.push('scrollbars=1');if(ea.name=='permissions.request'||ea.name=='permissions.oauth')oa.push('location=1,toolbar=0');oa=oa.join(',');var pa;if(ea.post){pa=window.open('about:blank',ea.id,oa);if(pa){da.setLoadedNode(ea,pa,'popup');h.submitToTarget({url:ea.url,target:ea.id,params:ea.params});}}else{pa=window.open(ea.url,ea.id,oa);if(pa)da.setLoadedNode(ea,pa,'popup');}if(!pa)return;if(ea.id in da._defaultCb)da._popupMonitor();},setLoadedNode:function(ea,fa,ga){if(ea.params&&ea.params.display!='popup')fa.fbCallID=ea.id;fa={node:fa,type:ga,fbCallID:ea.id};da._loadedNodes[ea.id]=fa;},getLoadedNode:function(ea){var fa=typeof ea=='object'?ea.id:ea,ga=da._loadedNodes[fa];return ga?ga.node:null;},hidden:function(ea){ea.className='FB_UI_Hidden';ea.root=h.appendHidden('');da._insertIframe(ea);},iframe:function(ea){ea.className='FB_UI_Dialog';var fa=function(){da._triggerDefault(ea.id);};ea.root=j.create({onClose:fa,closeIcon:ea.closeIcon===undefined?true:ea.closeIcon,classes:(z.ipad()?'centered':'')});if(!ea.hideLoader)j.showLoader(fa,ea.size.width);k.addCss(ea.root,'fb_dialog_iframe');da._insertIframe(ea);},touch:function(ea){if(ea.params&&ea.params.in_iframe){if(ea.ui_created){j.showLoader(function(){da._triggerDefault(ea.id);},0);}else da.iframe(ea);}else if(z.nativeApp()&&!ea.ui_created){ea.frame=ea.id;s.onready(function(){da.setLoadedNode(ea,s.open(ea.url+'#cb='+ea.frameName),'native');});da._popupMonitor();}else if(!ea.ui_created)da.popup(ea);},async:function(ea){ea.params.redirect_uri=location.protocol+'//'+location.host+location.pathname;delete ea.params.access_token;v.remote.showDialog(ea.params,function(fa){var ga=fa.result;if(ga&&ga.e2e){var ha=j.get(ea.id);ha.trackEvents(ga.e2e);ha.trackEvent('close');delete ga.e2e;}ea.cb(ga);});},getDefaultSize:function(){return j.getDefaultSize();},_insertIframe:function(ea){da._loadedNodes[ea.id]=false;var fa=function(ga){if(ea.id in da._loadedNodes)da.setLoadedNode(ea,ga,'iframe');};if(ea.post){q({url:'about:blank',root:ea.root,className:ea.className,width:ea.size.width,height:ea.size.height,id:ea.id,onInsert:fa,onload:function(ga){h.submitToTarget({url:ea.url,target:ga.name,params:ea.params});}});}else q({url:ea.url,root:ea.root,className:ea.className,width:ea.size.width,height:ea.size.height,id:ea.id,name:ea.frameName,onInsert:fa});},_handleResizeMessage:function(ea,fa){var ga=da.getLoadedNode(ea);if(!ga)return;if(fa.height)ga.style.height=fa.height+'px';if(fa.width)ga.style.width=fa.width+'px';aa.inform('resize.ack',fa||{},'parent.frames['+ga.name+']');if(!j.isActive(ga))j.show(ga);},_triggerDefault:function(ea){da._xdRecv({frame:ea},da._defaultCb[ea]||function(){});},_popupMonitor:function(){var ea;for(var fa in da._loadedNodes)if(da._loadedNodes.hasOwnProperty(fa)&&fa in da._defaultCb){var ga=da._loadedNodes[fa];if(ga.type!='popup'&&ga.type!='native')continue;var ha=ga.node;try{if(ha.closed){da._triggerDefault(fa);}else ea=true;}catch(ia){}}if(ea&&!da._popupInterval){da._popupInterval=setInterval(da._popupMonitor,100);}else if(!ea&&da._popupInterval){clearInterval(da._popupInterval);da._popupInterval=null;}},_xdChannelHandler:function(ea,fa){return aa.handler(function(ga){var ha=da.getLoadedNode(ea);if(!ha)return;if(ga.type=='resize'){da._handleResizeMessage(ea,ga);}else if(ga.type=='hide'){j.hide(ha);}else if(ga.type=='rendered'){var ia=j._findRoot(ha);j.show(ia);}else if(ga.type=='fireevent')l.fire(ga.event);},fa,true,null);},_xdNextHandler:function(ea,fa,ga,ha){if(ha)da._defaultCb[fa]=ea;return aa.handler(function(ia){da._xdRecv(ia,ea);},ga)+'&frame='+fa;},_xdRecv:function(ea,fa){var ga=da.getLoadedNode(ea.frame);if(ga)if(ga.close){try{ga.close();if(/iPhone.*Version\/(5|6)/.test(navigator.userAgent)&&RegExp.$1!=='5')window.focus();da._popupCount--;}catch(ha){}}else if(k.containsCss(ga,'FB_UI_Hidden')){setTimeout(function(){ga.parentNode.parentNode.removeChild(ga.parentNode);},3000);}else if(k.containsCss(ga,'FB_UI_Dialog'))j.remove(ga);delete da._loadedNodes[ea.frame];delete da._defaultCb[ea.frame];if(ea.e2e){var ia=j.get(ea.frame);ia.trackEvents(ea.e2e);ia.trackEvent('close');delete ea.e2e;}fa(ea);},_xdResult:function(ea,fa,ga,ha){return (da._xdNextHandler(function(ia){ea&&ea(ia.result&&ia.result!=da._resultToken&&ES('JSON','parse',false,ia.result));},fa,ga,ha)+'&result='+encodeURIComponent(da._resultToken));},xdHandler:function(ea,fa,ga,ha,ia){return da._xdNextHandler(g.xdResponseWrapper(ea,ha,ia),fa,ga,true);}};v.stub('showDialog');e.exports=da;},null);
+ __d("sdk.ui",["Assert","sdk.Impressions","Log","sdk.PlatformVersioning","sdk.Runtime","sdk.UIServer","sdk.feature"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){function n(o,p){g.isObject(o);g.maybeFunction(p);if(k.getIsVersioned()){j.assertVersionIsSet();if(o.version){j.assertValidVersion(o.version);}else o.version=k.getVersion();}o=ES('Object','assign',false,{},o);if(!o.method){i.error('"method" is a required parameter for FB.ui().');return null;}if(o.method=='pay.prompt')o.method='pay';var q=o.method;if(o.redirect_uri){i.warn('When using FB.ui, you should not specify a redirect_uri.');delete o.redirect_uri;}if((q=='permissions.request'||q=='permissions.oauth')&&(o.display=='iframe'||o.display=='dialog'))o.display=l.checkOauthDisplay(o);var r=m('e2e_tracking',true);if(r)o.e2e={};var s=l.prepareCall(o,p||function(){});if(!s)return null;var t=s.params.display;if(t==='dialog'){t='iframe';}else if(t==='none')t='hidden';var u=l[t];if(!u){i.error('"display" must be one of "popup", '+'"dialog", "iframe", "touch", "async", "hidden", or "none"');return null;}if(r)s.dialog.subscribe('e2e:end',function(v){v.method=q;v.display=t;i.debug('e2e: %s',ES('JSON','stringify',false,v));h.log(114,{payload:v});});u(s);return s.dialog;}e.exports=n;},null);
+ __d("legacy:fb.auth",["sdk.Auth","sdk.Cookie","copyProperties","sdk.Event","FB","Log","sdk.Runtime","sdk.SignedRequest","sdk.ui"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){k.provide('',{getLoginStatus:function(){return g.getLoginStatus.apply(g,arguments);},getAuthResponse:function(){return g.getAuthResponse();},getAccessToken:function(){return m.getAccessToken()||null;},getUserID:function(){return m.getUserID()||m.getCookieUserID();},login:function(p,q){if(q&&q.perms&&!q.scope){q.scope=q.perms;delete q.perms;l.warn('OAuth2 specification states that \'perms\' '+'should now be called \'scope\'. Please update.');}var r=m.isEnvironment(m.ENVIRONMENTS.CANVAS)||m.isEnvironment(m.ENVIRONMENTS.PAGETAB);o(i({method:'permissions.oauth',display:r?'async':'popup',domain:location.hostname},q||{}),p);},logout:function(p){o({method:'auth.logout',display:'hidden'},p);}});g.subscribe('logout',ES(j.fire,'bind',true,j,'auth.logout'));g.subscribe('login',ES(j.fire,'bind',true,j,'auth.login'));g.subscribe('authresponse.change',ES(j.fire,'bind',true,j,'auth.authResponseChange'));g.subscribe('status.change',ES(j.fire,'bind',true,j,'auth.statusChange'));j.subscribe('init:post',function(p){if(p.status)g.getLoginStatus();if(m.getClientID())if(p.authResponse){g.setAuthResponse(p.authResponse,'connected');}else if(m.getUseCookie()){var q=h.loadSignedRequest(),r;if(q){try{r=n.parse(q);}catch(s){h.clearSignedRequestCookie();}if(r&&r.user_id)m.setCookieUserID(r.user_id);}h.loadMeta();}});},3);
+ __d("sdk.Canvas.IframeHandling",["DOMWrapper","sdk.RPC"],function(a,b,c,d,e,f,g,h){var i=null,j;function k(){var o=g.getWindow().document,p=o.body,q=o.documentElement,r=Math.max(p.offsetTop,0),s=Math.max(q.offsetTop,0),t=p.scrollHeight+r,u=p.offsetHeight+r,v=q.scrollHeight+s,w=q.offsetHeight+s;return Math.max(t,u,v,w);}function l(o){if(typeof o!='object')o={};var p=0,q=0;if(!o.height){o.height=k();p=16;q=4;}if(!o.frame)o.frame=window.name||'iframe_canvas';if(j){var r=j.height,s=o.height-r;if(s<=q&&s>=-p)return false;}j=o;h.remote.setSize(o);return true;}function m(o,p){if(p===undefined&&typeof o==='number'){p=o;o=true;}if(o||o===undefined){if(i===null)i=setInterval(function(){l();},p||100);l();}else if(i!==null){clearInterval(i);i=null;}}h.stub('setSize');var n={setSize:l,setAutoGrow:m};e.exports=n;},null);
+ __d("sdk.Canvas.Navigation",["sdk.RPC"],function(a,b,c,d,e,f,g){function h(j){g.local.navigate=function(k){j({path:k});};g.remote.setNavigationEnabled(true);}g.stub('setNavigationEnabled');var i={setUrlHandler:h};e.exports=i;},null);
+ __d("sdk.Canvas.Plugin",["sdk.api","sdk.RPC","Log","UserAgent_DEPRECATED","sdk.Runtime","createArrayFrom"],function(a,b,c,d,e,f,g,h,i,j,k,l){var m='CLSID:D27CDB6E-AE6D-11CF-96B8-444553540000',n='CLSID:444785F1-DE89-4295-863A-D46C3A781394',o=null,p=!(j.osx()>=10.9&&(j.chrome()>=31||j.webkit()>=537.71||j.firefox()>=25));function q(aa){aa._hideunity_savedstyle={};aa._hideunity_savedstyle.left=aa.style.left;aa._hideunity_savedstyle.position=aa.style.position;aa._hideunity_savedstyle.width=aa.style.width;aa._hideunity_savedstyle.height=aa.style.height;aa.style.left='-10000px';aa.style.position='absolute';aa.style.width='1px';aa.style.height='1px';}function r(aa){if(aa._hideunity_savedstyle){aa.style.left=aa._hideunity_savedstyle.left;aa.style.position=aa._hideunity_savedstyle.position;aa.style.width=aa._hideunity_savedstyle.width;aa.style.height=aa._hideunity_savedstyle.height;}}function s(aa){aa._old_visibility=aa.style.visibility;aa.style.visibility='hidden';}function t(aa){aa.style.visibility=aa._old_visibility||'';delete aa._old_visibility;}function u(aa){var ba=aa.type?aa.type.toLowerCase():null,ca=ba==='application/x-shockwave-flash'||(aa.classid&&aa.classid.toUpperCase()==m);if(!ca)return false;var da=/opaque|transparent/i;if(da.test(aa.getAttribute('wmode')))return false;for(var ea=0;ea1/l||m=='*'||~ES(m,'indexOf',true,j.getClientID()))return;setTimeout(p,30000);}function r(u){n=u;}function s(u){o.push(u);}var t={COLLECT_AUTOMATIC:k.AUTOMATIC,COLLECT_MANUAL:k.MANUAL,addStaticResource:s,setCollectionMode:r,_maybeSample:q};e.exports=t;},null);
+ __d("legacy:fb.canvas.prefetcher",["FB","sdk.Canvas.Prefetcher","sdk.Event","sdk.Runtime"],function(a,b,c,d,e,f,g,h,i,j){g.provide('Canvas.Prefetcher',h);i.subscribe('init:post',function(k){if(j.isEnvironment(j.ENVIRONMENTS.CANVAS))h._maybeSample();});},3);
+ __d("legacy:fb.canvas.presence",["sdk.RPC","sdk.Event"],function(a,b,c,d,e,f,g,h){h.subscribe(h.SUBSCRIBE,i);h.subscribe(h.UNSUBSCRIBE,j);g.stub('useFriendsOnline');function i(k,l){if(k!='canvas.friendsOnlineUpdated')return;if(l.length===1)g.remote.useFriendsOnline(true);}function j(k,l){if(k!='canvas.friendsOnlineUpdated')return;if(l.length===0)g.remote.useFriendsOnline(false);}},3);
+ __d("legacy:fb.event",["FB","sdk.Event","sdk.Runtime","sdk.Scribe","sdk.feature"],function(a,b,c,d,e,f,g,h,i,j,k){var l=[],m=null,n=k('event_subscriptions_log',false);g.provide('Event',{subscribe:function(o,p){if(n){l.push(o);if(!m)m=setTimeout(function(){j.log('jssdk_error',{appId:i.getClientID(),error:'EVENT_SUBSCRIPTIONS_LOG',extra:{line:0,name:'EVENT_SUBSCRIPTIONS_LOG',script:'N/A',stack:'N/A',message:l.sort().join(',')}});l.length=0;m=null;},n);}return h.subscribe(o,p);},unsubscribe:ES(h.unsubscribe,'bind',true,h)});},3);
+ __d("legacy:fb.frictionless",["FB","sdk.Frictionless"],function(a,b,c,d,e,f,g,h){g.provide('Frictionless',h);},3);
+ __d("sdk.init",["sdk.Cookie","sdk.ErrorHandling","sdk.Event","Log","ManagedError","sdk.PlatformVersioning","QueryString","sdk.Runtime","sdk.URI","createArrayFrom"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){function q(s){var t=(typeof s=='number'&&s>0)||(typeof s=='string'&&/^[0-9a-f]{21,}$|^[0-9]{1,21}$/.test(s));if(t)return s.toString();j.warn('Invalid App Id: Must be a number or numeric string representing '+'the application id.');return null;}function r(s){if(n.getInitialized())j.warn('FB.init has already been called - this could indicate a problem');if(n.getIsVersioned()){if(Object.prototype.toString.call(s)!=='[object Object]')throw new k('Invalid argument');if(s.authResponse)j.warn('Setting authResponse is not supported');if(!s.version)s.version=o(location.href).getQueryData().sdk_version;l.assertValidVersion(s.version);n.setVersion(s.version);}else{if(/number|string/.test(typeof s)){j.warn('FB.init called with invalid parameters');s={apiKey:s};}s=ES('Object','assign',false,{status:true},s||{});}var t=q(s.appId||s.apiKey);if(t!==null)n.setClientID(t);if('scope' in s)n.setScope(s.scope);if(s.cookie){n.setUseCookie(true);if(typeof s.cookie==='string')g.setDomain(s.cookie);}if(s.kidDirectedSite)n.setKidDirectedSite(true);n.setInitialized(true);i.fire('init:post',s);}setTimeout(function(){var s=/(connect\.facebook\.net|\.facebook\.com\/assets.php).*?#(.*)/;ES(p(document.getElementsByTagName('script')),'forEach',true,function(t){if(t.src){var u=s.exec(t.src);if(u){var v=m.decode(u[2]);for(var w in v)if(v.hasOwnProperty(w)){var x=v[w];if(x=='0')v[w]=0;}r(v);}}});if(window.fbAsyncInit&&!window.fbAsyncInit.hasRun){window.fbAsyncInit.hasRun=true;h.unguard(window.fbAsyncInit)();}},0);e.exports=r;},null);
+ __d("legacy:fb.init",["FB","sdk.init"],function(a,b,c,d,e,f,g,h){g.provide('',{init:h});},3);
+ __d("legacy:fb.pay",["copyProperties","sdk.Runtime","sdk.UIServer","sdk.XD","sdk.feature","FB"],function(a,b,c,d,e,f,g,h,i,j,k){b('FB');var l={error_code:1383001,error_message:'An unknown error caused the dialog to be closed'},m=function(n){return function(o){if(o&&typeof o.response==='string'){n(ES('JSON','parse',false,o.response));}else if(typeof o==='object'){n(o);}else n(l);};};g(i.Methods,{pay:{size:{width:555,height:120},connectDisplay:'popup',transform:function(n){if(k('launch_payment_dialog_via_pac')){n.cb=m(n.cb);return n;}else{n.cb=m(n.cb);if(!h.isEnvironment(h.ENVIRONMENTS.CANVAS)){n.params.order_info=ES('JSON','stringify',false,n.params.order_info);return n;}var o=j.handler(n.cb,'parent.frames['+(window.name||'iframe_canvas')+']');n.params.channel=o;n.params.uiserver=true;j.inform('Pay.Prompt',n.params);}}}});},3);
+ __d("legacy:fb.ui",["FB","sdk.ui"],function(a,b,c,d,e,f,g,h){g.provide('',{ui:h});},3);
+ __d("runOnce",[],function(a,b,c,d,e,f){function g(h){var i,j;return function(){if(!i){i=true;j=h();}return j;};}e.exports=g;},null);
+ __d("XFBML",["Assert","createArrayFrom","sdk.DOM","sdk.feature","sdk.Impressions","Log","ObservableMixin","runOnce","UserAgent_DEPRECATED"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p={},q={},r=0,s=new m();function t(ba,ca){return ba[ca]+'';}function u(ba){return ba.scopeName?(ba.scopeName+':'+ba.nodeName):'';}function v(ba){return p[t(ba,'nodeName').toLowerCase()]||p[u(ba).toLowerCase()];}function w(ba){var ca=ES(ES(t(ba,'className'),'trim',true).split(/\s+/),'filter',true,function(da){return q.hasOwnProperty(da);});if(ca.length===0)return undefined;if(ba.getAttribute('fb-xfbml-state')||!ba.childNodes||ba.childNodes.length===0||(ba.childNodes.length===1&&ba.childNodes[0].nodeType===3)||(ba.children.length===1&&t(ba.children[0],'className')==='fb-xfbml-parse-ignore'))return q[ca[0]];}function x(ba){var ca={};ES(h(ba.attributes),'forEach',true,function(da){ca[t(da,'name')]=t(da,'value');});return ca;}function y(ba,ca,da){var ea=document.createElement('div');i.addCss(ba,ca+'-'+da);ES(h(ba.childNodes),'forEach',true,function(fa){ea.appendChild(fa);});ES(h(ba.attributes),'forEach',true,function(fa){ea.setAttribute(fa.name,fa.value);});ba.parentNode.replaceChild(ea,ba);return ea;}function z(ba,ca,da){g.isTrue(ba&&ba.nodeType&&ba.nodeType===1&&!!ba.getElementsByTagName,'Invalid DOM node passed to FB.XFBML.parse()');g.isFunction(ca,'Invalid callback passed to FB.XFBML.parse()');var ea=++r;l.info('XFBML Parsing Start %s',ea);var fa=1,ga=0,ha=function(){fa--;if(fa===0){l.info('XFBML Parsing Finish %s, %s tags found',ea,ga);ca();s.inform('render',ea,ga);}g.isTrue(fa>=0,'onrender() has been called too many times');};ES(h(ba.getElementsByTagName('*')),'forEach',true,function(ja){if(!da&&ja.getAttribute('fb-xfbml-state'))return;if(ja.nodeType!==1)return;var ka=v(ja)||w(ja);if(!ka)return;if(o.ie()<9&&ja.scopeName)ja=y(ja,ka.xmlns,ka.localName);fa++;ga++;var la=new ka.ctor(ja,ka.xmlns,ka.localName,x(ja));la.subscribe('render',n(function(){ja.setAttribute('fb-xfbml-state','rendered');ha();}));var ma=function(){if(ja.getAttribute('fb-xfbml-state')=='parsed'){s.subscribe('render.queue',ma);}else{ja.setAttribute('fb-xfbml-state','parsed');la.process();}};ma();});s.inform('parse',ea,ga);var ia=30000;setTimeout(function(){if(fa>0)l.warn('%s tags failed to render in %s ms',fa,ia);},ia);ha();}s.subscribe('render',function(){var ba=s.getSubscribers('render.queue');s.clearSubscribers('render.queue');ES(ba,'forEach',true,function(ca){ca();});});ES('Object','assign',false,s,{registerTag:function(ba){var ca=ba.xmlns+':'+ba.localName;g.isUndefined(p[ca],ca+' already registered');p[ca]=ba;q[ba.xmlns+'-'+ba.localName]=ba;},parse:function(ba,ca){z(ba||document.body,ca||function(){},true);},parseNew:function(){z(document.body,function(){},false);}});if(j('log_tag_count')){var aa=function(ba,ca){s.unsubscribe('parse',aa);setTimeout(ES(k.log,'bind',true,null,102,{tag_count:ca}),5000);};s.subscribe('parse',aa);}e.exports=s;},null);
+ __d("PluginPipe",["sdk.Content","sdk.feature","guid","insertIframe","Miny","ObservableMixin","JSSDKPluginPipeConfig","sdk.Runtime","UrlMap","UserAgent_DEPRECATED","XFBML"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q){var r=new l(),s=m.threshold,t=[];function u(){return !!(h('plugin_pipe')&&n.getSecure()!==undefined&&(p.chrome()||p.firefox())&&m.enabledApps[n.getClientID()]);}function v(){var x=t;t=[];if(x.length<=s){ES(x,'forEach',true,function(aa){j(aa.config);});return;}var y=x.length+1;function z(){y--;if(y===0)w(x);}ES(x,'forEach',true,function(aa){var ba={};for(var ca in aa.config)ba[ca]=aa.config[ca];ba.url=o.resolve('www',n.getSecure())+'/plugins/plugin_pipe_shell.php';ba.onload=z;j(ba);});z();}q.subscribe('parse',v);function w(x){var y=document.createElement('span');g.appendHidden(y);var z={};ES(x,'forEach',true,function(ea){z[ea.config.name]={plugin:ea.tag,params:ea.params};});var aa=ES('JSON','stringify',false,z),ba=k.encode(aa);ES(x,'forEach',true,function(ea){var fa=document.getElementsByName(ea.config.name)[0];fa.onload=ea.config.onload;});var ca=o.resolve('www',n.getSecure())+'/plugins/pipe.php',da=i();j({url:'about:blank',root:y,name:da,className:'fb_hidden fb_invisible',onload:function(){g.submitToTarget({url:ca,target:da,params:{plugins:ba.length-1)?n:l;});},isValid:function(){for(var k=this.dom;k;k=k.parentNode)if(k==document.body)return true;},clear:function(){g.html(this.dom,'');}},i);e.exports=j;},null);
+ __d("sdk.XFBML.IframeWidget",["sdk.Arbiter","sdk.Auth","sdk.Content","sdk.DOM","sdk.Event","sdk.XFBML.Element","guid","insertIframe","QueryString","sdk.Runtime","sdk.ui","UrlMap","sdk.XD"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s){var t=l.extend({_iframeName:null,_showLoader:true,_refreshOnAuthChange:false,_allowReProcess:false,_fetchPreCachedLoader:false,_visibleAfter:'load',_widgetPipeEnabled:false,_borderReset:false,_repositioned:false,getUrlBits:function(){throw new Error('Inheriting class needs to implement getUrlBits().');},setupAndValidate:function(){return true;},oneTimeSetup:function(){},getSize:function(){},getIframeName:function(){return this._iframeName;},getIframeTitle:function(){return 'Facebook Social Plugin';},getChannelUrl:function(){if(!this._channelUrl){var x=this;this._channelUrl=s.handler(function(y){x.fire('xd.'+y.type,y);},'parent.parent',true);}return this._channelUrl;},getIframeNode:function(){return this.dom.getElementsByTagName('iframe')[0];},arbiterInform:function(event,x,y){s.sendToFacebook(this.getIframeName(),{method:event,params:ES('JSON','stringify',false,x||{}),behavior:y||g.BEHAVIOR_PERSISTENT});},_arbiterInform:function(event,x,y){var z='parent.frames["'+this.getIframeNode().name+'"]';s.inform(event,x,z,y);},getDefaultWebDomain:function(){return r.resolve('www');},process:function(x){if(this._done){if(!this._allowReProcess&&!x)return;this.clear();}else this._oneTimeSetup();this._done=true;this._iframeName=this.getIframeName()||this._iframeName||m();if(!this.setupAndValidate()){this.fire('render');return;}if(this._showLoader)this._addLoader();j.addCss(this.dom,'fb_iframe_widget');if(this._visibleAfter!='immediate'){j.addCss(this.dom,'fb_hide_iframes');}else this.subscribe('iframe.onload',ES(this.fire,'bind',true,this,'render'));var y=this.getSize()||{},z=this.getFullyQualifiedURL();if(y.width=='100%')j.addCss(this.dom,'fb_iframe_widget_fluid');this.clear();n({url:z,root:this.dom.appendChild(document.createElement('span')),name:this._iframeName,title:this.getIframeTitle(),className:p.getRtl()?'fb_rtl':'fb_ltr',height:y.height,width:y.width,onload:ES(this.fire,'bind',true,this,'iframe.onload')});this._resizeFlow(y);this.loaded=false;this.subscribe('iframe.onload',ES(function(){this.loaded=true;if(!this._isResizeHandled)j.addCss(this.dom,'fb_hide_iframes');},'bind',true,this));},generateWidgetPipeIframeName:function(){u++;return 'fb_iframe_'+u;},getFullyQualifiedURL:function(){var x=this._getURL();x+='?'+o.encode(this._getQS());if(x.length>2000){x='about:blank';var y=ES(function(){this._postRequest();this.unsubscribe('iframe.onload',y);},'bind',true,this);this.subscribe('iframe.onload',y);}return x;},_getWidgetPipeShell:function(){return r.resolve('www')+'/common/widget_pipe_shell.php';},_oneTimeSetup:function(){this.subscribe('xd.resize',ES(this._handleResizeMsg,'bind',true,this));this.subscribe('xd.resize',ES(this._bubbleResizeEvent,'bind',true,this));this.subscribe('xd.resize.iframe',ES(this._resizeIframe,'bind',true,this));this.subscribe('xd.resize.flow',ES(this._resizeFlow,'bind',true,this));this.subscribe('xd.resize.flow',ES(this._bubbleResizeEvent,'bind',true,this));this.subscribe('xd.refreshLoginStatus',function(){h.getLoginStatus(function(){},true);});this.subscribe('xd.logout',function(){q({method:'auth.logout',display:'hidden'},function(){});});if(this._refreshOnAuthChange)this._setupAuthRefresh();if(this._visibleAfter=='load')this.subscribe('iframe.onload',ES(this._makeVisible,'bind',true,this));this.subscribe('xd.verify',ES(function(x){this.arbiterInform('xd/verify',x.token);},'bind',true,this));this.oneTimeSetup();},_makeVisible:function(){this._removeLoader();j.removeCss(this.dom,'fb_hide_iframes');this.fire('render');},_setupAuthRefresh:function(){h.getLoginStatus(ES(function(x){var y=x.status;k.subscribe('auth.statusChange',ES(function(z){if(!this.isValid())return;if(y=='unknown'||z.status=='unknown')this.process(true);y=z.status;},'bind',true,this));},'bind',true,this));},_handleResizeMsg:function(x){if(!this.isValid())return;this._resizeIframe(x);this._resizeFlow(x);if(!this._borderReset){this.getIframeNode().style.border='none';this._borderReset=true;}this._isResizeHandled=true;this._makeVisible();},_bubbleResizeEvent:function(x){var y={height:x.height,width:x.width,pluginID:this.getAttribute('plugin-id')};k.fire('xfbml.resize',y);},_resizeIframe:function(x){var y=this.getIframeNode();if(x.reposition==="true")this._repositionIframe(x);x.height&&(y.style.height=x.height+'px');x.width&&(y.style.width=x.width+'px');this._updateIframeZIndex();},_resizeFlow:function(x){var y=this.dom.getElementsByTagName('span')[0];x.height&&(y.style.height=x.height+'px');x.width&&(y.style.width=x.width+'px');this._updateIframeZIndex();},_updateIframeZIndex:function(){var x=this.dom.getElementsByTagName('span')[0],y=this.getIframeNode(),z=y.style.height===x.style.height&&y.style.width===x.style.width,aa=z?'removeCss':'addCss';j[aa](y,'fb_iframe_widget_lift');},_repositionIframe:function(x){var y=this.getIframeNode(),z=parseInt(j.getStyle(y,'width'),10),aa=j.getPosition(y).x,ba=j.getViewportInfo().width,ca=parseInt(x.width,10);if(aa+ca>ba&&aa>ca){y.style.left=z-ca+'px';this.arbiterInform('xd/reposition',{type:'horizontal'});this._repositioned=true;}else if(this._repositioned){y.style.left='0px';this.arbiterInform('xd/reposition',{type:'restore'});this._repositioned=false;}},_addLoader:function(){if(!this._loaderDiv){j.addCss(this.dom,'fb_iframe_widget_loader');this._loaderDiv=document.createElement('div');this._loaderDiv.className='FB_Loader';this.dom.appendChild(this._loaderDiv);}},_removeLoader:function(){if(this._loaderDiv){j.removeCss(this.dom,'fb_iframe_widget_loader');if(this._loaderDiv.parentNode)this._loaderDiv.parentNode.removeChild(this._loaderDiv);this._loaderDiv=null;}},_getQS:function(){return ES('Object','assign',false,{api_key:p.getClientID(),locale:p.getLocale(),sdk:'joey',kid_directed_site:p.getKidDirectedSite(),ref:this.getAttribute('ref')},this.getUrlBits().params);},_getURL:function(){var x=this.getDefaultWebDomain(),y='';return x+'/plugins/'+y+this.getUrlBits().name+'.php';},_postRequest:function(){i.submitToTarget({url:this._getURL(),target:this.getIframeNode().name,params:this._getQS()});}}),u=0,v={};function w(){var x={};for(var y in v){var z=v[y];x[y]={widget:z.getUrlBits().name,params:z._getQS()};}return x;}e.exports=t;},null);
+ __d("sdk.XFBML.Comments",["sdk.Event","sdk.XFBML.IframeWidget","QueryString","sdk.Runtime","JSSDKConfig","UrlMap","UserAgent_DEPRECATED"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n=h.extend({_visibleAfter:'immediate',_refreshOnAuthChange:true,setupAndValidate:function(){var o={channel_url:this.getChannelUrl(),colorscheme:this.getAttribute('colorscheme'),skin:this.getAttribute('skin'),numposts:this.getAttribute('num-posts',10),width:this._getLengthAttribute('width'),href:this.getAttribute('href'),permalink:this.getAttribute('permalink'),publish_feed:this.getAttribute('publish_feed'),order_by:this.getAttribute('order_by'),mobile:this._getBoolAttribute('mobile')};if(!o.width&&!o.permalink)o.width=550;if(k.initSitevars.enableMobileComments&&m.mobile()&&o.mobile!==false){o.mobile=true;delete o.width;}if(!o.skin)o.skin=o.colorscheme;if(!o.href){o.migrated=this.getAttribute('migrated');o.xid=this.getAttribute('xid');o.title=this.getAttribute('title',document.title);o.url=this.getAttribute('url',document.URL);o.quiet=this.getAttribute('quiet');o.reverse=this.getAttribute('reverse');o.simple=this.getAttribute('simple');o.css=this.getAttribute('css');o.notify=this.getAttribute('notify');if(!o.xid){var p=ES(document.URL,'indexOf',true,'#');if(p>0){o.xid=encodeURIComponent(document.URL.substring(0,p));}else o.xid=encodeURIComponent(document.URL);}if(o.migrated)o.href=l.resolve('www')+'/plugins/comments_v1.php?'+'app_id='+j.getClientID()+'&xid='+encodeURIComponent(o.xid)+'&url='+encodeURIComponent(o.url);}else{var q=this.getAttribute('fb_comment_id');if(!q){q=i.decode(document.URL.substring(ES(document.URL,'indexOf',true,'?')+1)).fb_comment_id;if(q&&ES(q,'indexOf',true,'#')>0)q=q.substring(0,ES(q,'indexOf',true,'#'));}if(q){o.fb_comment_id=q;this.subscribe('render',ES(function(){if(!window.location.hash)window.location.hash=this.getIframeNode().id;},'bind',true,this));}}this._attr=o;return true;},oneTimeSetup:function(){this.subscribe('xd.addComment',ES(this._handleCommentMsg,'bind',true,this));this.subscribe('xd.commentCreated',ES(this._handleCommentCreatedMsg,'bind',true,this));this.subscribe('xd.commentRemoved',ES(this._handleCommentRemovedMsg,'bind',true,this));},getSize:function(){if(!this._attr.permalink)return {width:this._attr.mobile?'100%':this._attr.width,height:160};},getUrlBits:function(){return {name:'comments',params:this._attr};},getDefaultWebDomain:function(){return l.resolve(this._attr.mobile?'m':'www',true);},_handleCommentMsg:function(o){if(!this.isValid())return;g.fire('comments.add',{post:o.post,user:o.user,widget:this});},_handleCommentCreatedMsg:function(o){if(!this.isValid())return;var p={href:o.href,commentID:o.commentID,parentCommentID:o.parentCommentID,message:o.message};g.fire('comment.create',p);},_handleCommentRemovedMsg:function(o){if(!this.isValid())return;var p={href:o.href,commentID:o.commentID};g.fire('comment.remove',p);}});e.exports=n;},null);
+ __d("sdk.XFBML.CommentsCount",["ApiClient","sdk.DOM","sdk.XFBML.Element","sprintf"],function(a,b,c,d,e,f,g,h,i,j){var k=i.extend({process:function(){h.addCss(this.dom,'fb_comments_count_zero');var l=this.getAttribute('href',window.location.href);g.scheduleBatchCall('/v2.1/'+encodeURIComponent(l),{fields:'share'},ES(function(m){var n=(m.share&&m.share.comment_count)||0;h.html(this.dom,j('',n));if(n>0)h.removeCss(this.dom,'fb_comments_count_zero');this.fire('render');},'bind',true,this));}});e.exports=k;},null);
+ __d("safeEval",[],function(a,b,c,d,e,f){function g(h,i){if(h===null||typeof h==='undefined')return;if(typeof h!=='string')return h;if(/^\w+$/.test(h)&&typeof window[h]==='function')return window[h].apply(null,i||[]);return Function('return eval("'+h.replace(/"/g,'\\"')+'");').apply(null,i||[]);}e.exports=g;},null);
+ __d("sdk.Helper",["sdk.ErrorHandling","sdk.Event","UrlMap","safeEval","sprintf"],function(a,b,c,d,e,f,g,h,i,j,k){var l={isUser:function(m){return m<2.2e+09||(m>=1e+14&&m<=100099999989999)||(m>=8.9e+13&&m<=89999999999999);},upperCaseFirstChar:function(m){if(m.length>0){return m.substr(0,1).toUpperCase()+m.substr(1);}else return m;},getProfileLink:function(m,n,o){if(!o&&m)o=k('%s/profile.php?id=%s',i.resolve('www'),m.uid||m.id);if(o)n=k('%s ',o,n);return n;},invokeHandler:function(m,n,o){if(m)if(typeof m==='string'){g.unguard(j)(m,o);}else if(m.apply)g.unguard(m).apply(n,o||[]);},fireEvent:function(m,n){var o=n._attr.href;n.fire(m,o);h.fire(m,o,n);},executeFunctionByName:function(m){var n=Array.prototype.slice.call(arguments,1),o=m.split("."),p=o.pop(),q=window;for(var r=0;r"'\/]/g,h={'&':'&','<':'<','>':'>','"':'"',"'":''','/':'/'};function i(j){return j.replace(g,function(k){return h[k];});}e.exports=i;},null);
+ __d("sdk.XFBML.Name",["ApiClient","escapeHTML","sdk.Event","sdk.XFBML.Element","sdk.Helper","Log","sdk.Runtime"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n=({}).hasOwnProperty,o=j.extend({process:function(){ES('Object','assign',false,this,{_uid:this.getAttribute('uid'),_firstnameonly:this._getBoolAttribute('first-name-only'),_lastnameonly:this._getBoolAttribute('last-name-only'),_possessive:this._getBoolAttribute('possessive'),_reflexive:this._getBoolAttribute('reflexive'),_objective:this._getBoolAttribute('objective'),_linked:this._getBoolAttribute('linked',true),_subjectId:this.getAttribute('subject-id')});if(!this._uid){l.error('"uid" is a required attribute for ');this.fire('render');return;}var p=[];if(this._firstnameonly){p.push('first_name');}else if(this._lastnameonly){p.push('last_name');}else p.push('name');if(this._subjectId){p.push('gender');if(this._subjectId==m.getUserID())this._reflexive=true;}i.monitor('auth.statusChange',ES(function(){if(!this.isValid()){this.fire('render');return true;}if(!this._uid||this._uid=='loggedinuser')this._uid=m.getUserID();if(!this._uid)return;g.scheduleBatchCall('/v1.0/'+this._uid,{fields:p.join(',')},ES(function(q){if(n.call(q,'error')){l.warn('The name is not found for ID: '+this._uid);return;}if(this._subjectId==this._uid){this._renderPronoun(q);}else this._renderOther(q);this.fire('render');},'bind',true,this));},'bind',true,this));},_renderPronoun:function(p){var q='',r=this._objective;if(this._subjectId){r=true;if(this._subjectId===this._uid)this._reflexive=true;}if(this._uid==m.getUserID()&&this._getBoolAttribute('use-you',true)){if(this._possessive){if(this._reflexive){q='your own';}else q='your';}else if(this._reflexive){q='yourself';}else q='you';}else switch(p.gender){case 'male':if(this._possessive){q=this._reflexive?'his own':'his';}else if(this._reflexive){q='himself';}else if(r){q='him';}else q='he';break;case 'female':if(this._possessive){q=this._reflexive?'her own':'her';}else if(this._reflexive){q='herself';}else if(r){q='her';}else q='she';break;default:if(this._getBoolAttribute('use-they',true)){if(this._possessive){if(this._reflexive){q='their own';}else q='their';}else if(this._reflexive){q='themselves';}else if(r){q='them';}else q='they';}else if(this._possessive){if(this._reflexive){q='his/her own';}else q='his/her';}else if(this._reflexive){q='himself/herself';}else if(r){q='him/her';}else q='he/she';break;}if(this._getBoolAttribute('capitalize',false))q=k.upperCaseFirstChar(q);this.dom.innerHTML=q;},_renderOther:function(p){var q='',r='';if(this._uid==m.getUserID()&&this._getBoolAttribute('use-you',true)){if(this._reflexive){if(this._possessive){q='your own';}else q='yourself';}else if(this._possessive){q='your';}else q='you';}else if(p){if(null===p.first_name)p.first_name='';if(null===p.last_name)p.last_name='';if(this._firstnameonly&&p.first_name!==undefined){q=h(p.first_name);}else if(this._lastnameonly&&p.last_name!==undefined)q=h(p.last_name);if(!q)q=h(p.name);if(q!==''&&this._possessive)q+='\'s';}if(!q)q=h(this.getAttribute('if-cant-see','Facebook User'));if(q){if(this._getBoolAttribute('capitalize',false))q=k.upperCaseFirstChar(q);if(p&&this._linked){r=k.getProfileLink(p,q,this.getAttribute('href',null));}else r=q;}this.dom.innerHTML=r;}});e.exports=o;},null);
+ __d("sdk.XFBML.RecommendationsBar",["sdk.Arbiter","DOMEventListener","sdk.Event","sdk.XFBML.IframeWidget","resolveURI","sdk.Runtime"],function(a,b,c,d,e,f,g,h,i,j,k,l){var m=j.extend({getUrlBits:function(){return {name:'recommendations_bar',params:this._attr};},setupAndValidate:function(){function n(w,x){var y=0,z=null;function aa(){x();z=null;y=ES('Date','now',false);}return function(){if(!z){var ba=ES('Date','now',false);if(ba-y=this._attr.trigger;}}});e.exports=m;},null);
+ __d("sdk.XFBML.Registration",["sdk.Auth","sdk.Helper","sdk.XFBML.IframeWidget","sdk.Runtime","UrlMap"],function(a,b,c,d,e,f,g,h,i,j,k){var l=i.extend({_visibleAfter:'immediate',_baseHeight:167,_fieldHeight:28,_skinnyWidth:520,_skinnyBaseHeight:173,_skinnyFieldHeight:52,setupAndValidate:function(){this._attr={action:this.getAttribute('action'),border_color:this.getAttribute('border-color'),channel_url:this.getChannelUrl(),client_id:j.getClientID(),fb_only:this._getBoolAttribute('fb-only',false),fb_register:this._getBoolAttribute('fb-register',false),fields:this.getAttribute('fields'),height:this._getPxAttribute('height'),redirect_uri:this.getAttribute('redirect-uri',window.location.href),no_footer:this._getBoolAttribute('no-footer'),no_header:this._getBoolAttribute('no-header'),onvalidate:this.getAttribute('onvalidate'),width:this._getPxAttribute('width',600),target:this.getAttribute('target')};if(this._attr.onvalidate)this.subscribe('xd.validate',ES(function(m){var n=ES('JSON','parse',false,m.value),o=ES(function(q){this.arbiterInform('Registration.Validation',{errors:q,id:m.id});},'bind',true,this),p=h.executeFunctionByName(this._attr.onvalidate,n,o);if(p)o(p);},'bind',true,this));this.subscribe('xd.authLogin',ES(this._onAuthLogin,'bind',true,this));this.subscribe('xd.authLogout',ES(this._onAuthLogout,'bind',true,this));return true;},getSize:function(){return {width:this._attr.width,height:this._getHeight()};},_getHeight:function(){if(this._attr.height)return this._attr.height;var m;if(!this._attr.fields){m=['name'];}else try{m=ES('JSON','parse',false,this._attr.fields);}catch(n){m=this._attr.fields.split(/,/);}if(this._attr.width 0 && !this.encoding) {
+ var pack = this.packetBuffer.shift();
+ this.packet(pack);
+ }
+ };
+
+ /**
+ * Clean up transport subscriptions and packet buffer.
+ *
+ * @api private
+ */
+
+ Manager.prototype.cleanup = function(){
+ var sub;
+ while (sub = this.subs.shift()) sub.destroy();
+
+ this.packetBuffer = [];
+ this.encoding = false;
+
+ this.decoder.destroy();
+ };
+
+ /**
+ * Close the current socket.
+ *
+ * @api private
+ */
+
+ Manager.prototype.close =
+ Manager.prototype.disconnect = function(){
+ this.skipReconnect = true;
+ this.backoff.reset();
+ this.readyState = 'closed';
+ this.engine && this.engine.close();
+ };
+
+ /**
+ * Called upon engine close.
+ *
+ * @api private
+ */
+
+ Manager.prototype.onclose = function(reason){
+ debug('close');
+ this.cleanup();
+ this.backoff.reset();
+ this.readyState = 'closed';
+ this.emit('close', reason);
+ if (this._reconnection && !this.skipReconnect) {
+ this.reconnect();
+ }
+ };
+
+ /**
+ * Attempt a reconnection.
+ *
+ * @api private
+ */
+
+ Manager.prototype.reconnect = function(){
+ if (this.reconnecting || this.skipReconnect) return this;
+
+ var self = this;
+
+ if (this.backoff.attempts >= this._reconnectionAttempts) {
+ debug('reconnect failed');
+ this.backoff.reset();
+ this.emitAll('reconnect_failed');
+ this.reconnecting = false;
+ } else {
+ var delay = this.backoff.duration();
+ debug('will wait %dms before reconnect attempt', delay);
+
+ this.reconnecting = true;
+ var timer = setTimeout(function(){
+ if (self.skipReconnect) return;
+
+ debug('attempting reconnect');
+ self.emitAll('reconnect_attempt', self.backoff.attempts);
+ self.emitAll('reconnecting', self.backoff.attempts);
+
+ // check again for the case socket closed in above events
+ if (self.skipReconnect) return;
+
+ self.open(function(err){
+ if (err) {
+ debug('reconnect attempt error');
+ self.reconnecting = false;
+ self.reconnect();
+ self.emitAll('reconnect_error', err.data);
+ } else {
+ debug('reconnect success');
+ self.onreconnect();
+ }
+ });
+ }, delay);
+
+ this.subs.push({
+ destroy: function(){
+ clearTimeout(timer);
+ }
+ });
+ }
+ };
+
+ /**
+ * Called upon successful reconnect.
+ *
+ * @api private
+ */
+
+ Manager.prototype.onreconnect = function(){
+ var attempt = this.backoff.attempts;
+ this.reconnecting = false;
+ this.backoff.reset();
+ this.updateSocketIds();
+ this.emitAll('reconnect', attempt);
+ };
+
+},{"./on":4,"./socket":5,"./url":6,"backo2":7,"component-bind":8,"component-emitter":9,"debug":10,"engine.io-client":11,"indexof":42,"object-component":43,"socket.io-parser":46}],4:[function(_dereq_,module,exports){
+
+ /**
+ * Module exports.
+ */
+
+ module.exports = on;
+
+ /**
+ * Helper for subscriptions.
+ *
+ * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`
+ * @param {String} event name
+ * @param {Function} callback
+ * @api public
+ */
+
+ function on(obj, ev, fn) {
+ obj.on(ev, fn);
+ return {
+ destroy: function(){
+ obj.removeListener(ev, fn);
+ }
+ };
+ }
+
+},{}],5:[function(_dereq_,module,exports){
+
+ /**
+ * Module dependencies.
+ */
+
+ var parser = _dereq_('socket.io-parser');
+ var Emitter = _dereq_('component-emitter');
+ var toArray = _dereq_('to-array');
+ var on = _dereq_('./on');
+ var bind = _dereq_('component-bind');
+ var debug = _dereq_('debug')('socket.io-client:socket');
+ var hasBin = _dereq_('has-binary');
+
+ /**
+ * Module exports.
+ */
+
+ module.exports = exports = Socket;
+
+ /**
+ * Internal events (blacklisted).
+ * These events can't be emitted by the user.
+ *
+ * @api private
+ */
+
+ var events = {
+ connect: 1,
+ connect_error: 1,
+ connect_timeout: 1,
+ disconnect: 1,
+ error: 1,
+ reconnect: 1,
+ reconnect_attempt: 1,
+ reconnect_failed: 1,
+ reconnect_error: 1,
+ reconnecting: 1
+ };
+
+ /**
+ * Shortcut to `Emitter#emit`.
+ */
+
+ var emit = Emitter.prototype.emit;
+
+ /**
+ * `Socket` constructor.
+ *
+ * @api public
+ */
+
+ function Socket(io, nsp){
+ this.io = io;
+ this.nsp = nsp;
+ this.json = this; // compat
+ this.ids = 0;
+ this.acks = {};
+ if (this.io.autoConnect) this.open();
+ this.receiveBuffer = [];
+ this.sendBuffer = [];
+ this.connected = false;
+ this.disconnected = true;
+ }
+
+ /**
+ * Mix in `Emitter`.
+ */
+
+ Emitter(Socket.prototype);
+
+ /**
+ * Subscribe to open, close and packet events
+ *
+ * @api private
+ */
+
+ Socket.prototype.subEvents = function() {
+ if (this.subs) return;
+
+ var io = this.io;
+ this.subs = [
+ on(io, 'open', bind(this, 'onopen')),
+ on(io, 'packet', bind(this, 'onpacket')),
+ on(io, 'close', bind(this, 'onclose'))
+ ];
+ };
+
+ /**
+ * "Opens" the socket.
+ *
+ * @api public
+ */
+
+ Socket.prototype.open =
+ Socket.prototype.connect = function(){
+ if (this.connected) return this;
+
+ this.subEvents();
+ this.io.open(); // ensure open
+ if ('open' == this.io.readyState) this.onopen();
+ return this;
+ };
+
+ /**
+ * Sends a `message` event.
+ *
+ * @return {Socket} self
+ * @api public
+ */
+
+ Socket.prototype.send = function(){
+ var args = toArray(arguments);
+ args.unshift('message');
+ this.emit.apply(this, args);
+ return this;
+ };
+
+ /**
+ * Override `emit`.
+ * If the event is in `events`, it's emitted normally.
+ *
+ * @param {String} event name
+ * @return {Socket} self
+ * @api public
+ */
+
+ Socket.prototype.emit = function(ev){
+ if (events.hasOwnProperty(ev)) {
+ emit.apply(this, arguments);
+ return this;
+ }
+
+ var args = toArray(arguments);
+ var parserType = parser.EVENT; // default
+ if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary
+ var packet = { type: parserType, data: args };
+
+ // event ack callback
+ if ('function' == typeof args[args.length - 1]) {
+ debug('emitting packet with ack id %d', this.ids);
+ this.acks[this.ids] = args.pop();
+ packet.id = this.ids++;
+ }
+
+ if (this.connected) {
+ this.packet(packet);
+ } else {
+ this.sendBuffer.push(packet);
+ }
+
+ return this;
+ };
+
+ /**
+ * Sends a packet.
+ *
+ * @param {Object} packet
+ * @api private
+ */
+
+ Socket.prototype.packet = function(packet){
+ packet.nsp = this.nsp;
+ this.io.packet(packet);
+ };
+
+ /**
+ * Called upon engine `open`.
+ *
+ * @api private
+ */
+
+ Socket.prototype.onopen = function(){
+ debug('transport is open - connecting');
+
+ // write connect packet if necessary
+ if ('/' != this.nsp) {
+ this.packet({ type: parser.CONNECT });
+ }
+ };
+
+ /**
+ * Called upon engine `close`.
+ *
+ * @param {String} reason
+ * @api private
+ */
+
+ Socket.prototype.onclose = function(reason){
+ debug('close (%s)', reason);
+ this.connected = false;
+ this.disconnected = true;
+ delete this.id;
+ this.emit('disconnect', reason);
+ };
+
+ /**
+ * Called with socket packet.
+ *
+ * @param {Object} packet
+ * @api private
+ */
+
+ Socket.prototype.onpacket = function(packet){
+ if (packet.nsp != this.nsp) return;
+
+ switch (packet.type) {
+ case parser.CONNECT:
+ this.onconnect();
+ break;
+
+ case parser.EVENT:
+ this.onevent(packet);
+ break;
+
+ case parser.BINARY_EVENT:
+ this.onevent(packet);
+ break;
+
+ case parser.ACK:
+ this.onack(packet);
+ break;
+
+ case parser.BINARY_ACK:
+ this.onack(packet);
+ break;
+
+ case parser.DISCONNECT:
+ this.ondisconnect();
+ break;
+
+ case parser.ERROR:
+ this.emit('error', packet.data);
+ break;
+ }
+ };
+
+ /**
+ * Called upon a server event.
+ *
+ * @param {Object} packet
+ * @api private
+ */
+
+ Socket.prototype.onevent = function(packet){
+ var args = packet.data || [];
+ debug('emitting event %j', args);
+
+ if (null != packet.id) {
+ debug('attaching ack callback to event');
+ args.push(this.ack(packet.id));
+ }
+
+ if (this.connected) {
+ emit.apply(this, args);
+ } else {
+ this.receiveBuffer.push(args);
+ }
+ };
+
+ /**
+ * Produces an ack callback to emit with an event.
+ *
+ * @api private
+ */
+
+ Socket.prototype.ack = function(id){
+ var self = this;
+ var sent = false;
+ return function(){
+ // prevent double callbacks
+ if (sent) return;
+ sent = true;
+ var args = toArray(arguments);
+ debug('sending ack %j', args);
+
+ var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;
+ self.packet({
+ type: type,
+ id: id,
+ data: args
+ });
+ };
+ };
+
+ /**
+ * Called upon a server acknowlegement.
+ *
+ * @param {Object} packet
+ * @api private
+ */
+
+ Socket.prototype.onack = function(packet){
+ debug('calling ack %s with %j', packet.id, packet.data);
+ var fn = this.acks[packet.id];
+ fn.apply(this, packet.data);
+ delete this.acks[packet.id];
+ };
+
+ /**
+ * Called upon server connect.
+ *
+ * @api private
+ */
+
+ Socket.prototype.onconnect = function(){
+ this.connected = true;
+ this.disconnected = false;
+ this.emit('connect');
+ this.emitBuffered();
+ };
+
+ /**
+ * Emit buffered events (received and emitted).
+ *
+ * @api private
+ */
+
+ Socket.prototype.emitBuffered = function(){
+ var i;
+ for (i = 0; i < this.receiveBuffer.length; i++) {
+ emit.apply(this, this.receiveBuffer[i]);
+ }
+ this.receiveBuffer = [];
+
+ for (i = 0; i < this.sendBuffer.length; i++) {
+ this.packet(this.sendBuffer[i]);
+ }
+ this.sendBuffer = [];
+ };
+
+ /**
+ * Called upon server disconnect.
+ *
+ * @api private
+ */
+
+ Socket.prototype.ondisconnect = function(){
+ debug('server disconnect (%s)', this.nsp);
+ this.destroy();
+ this.onclose('io server disconnect');
+ };
+
+ /**
+ * Called upon forced client/server side disconnections,
+ * this method ensures the manager stops tracking us and
+ * that reconnections don't get triggered for this.
+ *
+ * @api private.
+ */
+
+ Socket.prototype.destroy = function(){
+ if (this.subs) {
+ // clean subscriptions to avoid reconnections
+ for (var i = 0; i < this.subs.length; i++) {
+ this.subs[i].destroy();
+ }
+ this.subs = null;
+ }
+
+ this.io.destroy(this);
+ };
+
+ /**
+ * Disconnects the socket manually.
+ *
+ * @return {Socket} self
+ * @api public
+ */
+
+ Socket.prototype.close =
+ Socket.prototype.disconnect = function(){
+ if (this.connected) {
+ debug('performing disconnect (%s)', this.nsp);
+ this.packet({ type: parser.DISCONNECT });
+ }
+
+ // remove socket from pool
+ this.destroy();
+
+ if (this.connected) {
+ // fire events
+ this.onclose('io client disconnect');
+ }
+ return this;
+ };
+
+},{"./on":4,"component-bind":8,"component-emitter":9,"debug":10,"has-binary":38,"socket.io-parser":46,"to-array":50}],6:[function(_dereq_,module,exports){
+ (function (global){
+
+ /**
+ * Module dependencies.
+ */
+
+ var parseuri = _dereq_('parseuri');
+ var debug = _dereq_('debug')('socket.io-client:url');
+
+ /**
+ * Module exports.
+ */
+
+ module.exports = url;
+
+ /**
+ * URL parser.
+ *
+ * @param {String} url
+ * @param {Object} An object meant to mimic window.location.
+ * Defaults to window.location.
+ * @api public
+ */
+
+ function url(uri, loc){
+ var obj = uri;
+
+ // default to window.location
+ var loc = loc || global.location;
+ if (null == uri) uri = loc.protocol + '//' + loc.host;
+
+ // relative path support
+ if ('string' == typeof uri) {
+ if ('/' == uri.charAt(0)) {
+ if ('/' == uri.charAt(1)) {
+ uri = loc.protocol + uri;
+ } else {
+ uri = loc.hostname + uri;
+ }
+ }
+
+ if (!/^(https?|wss?):\/\//.test(uri)) {
+ debug('protocol-less url %s', uri);
+ if ('undefined' != typeof loc) {
+ uri = loc.protocol + '//' + uri;
+ } else {
+ uri = 'https://' + uri;
+ }
+ }
+
+ // parse
+ debug('parse %s', uri);
+ obj = parseuri(uri);
+ }
+
+ // make sure we treat `localhost:80` and `localhost` equally
+ if (!obj.port) {
+ if (/^(http|ws)$/.test(obj.protocol)) {
+ obj.port = '80';
+ }
+ else if (/^(http|ws)s$/.test(obj.protocol)) {
+ obj.port = '443';
+ }
+ }
+
+ obj.path = obj.path || '/';
+
+ // define unique id
+ obj.id = obj.protocol + '://' + obj.host + ':' + obj.port;
+ // define href
+ obj.href = obj.protocol + '://' + obj.host + (loc && loc.port == obj.port ? '' : (':' + obj.port));
+
+ return obj;
+ }
+
+ }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"debug":10,"parseuri":44}],7:[function(_dereq_,module,exports){
+
+ /**
+ * Expose `Backoff`.
+ */
+
+ module.exports = Backoff;
+
+ /**
+ * Initialize backoff timer with `opts`.
+ *
+ * - `min` initial timeout in milliseconds [100]
+ * - `max` max timeout [10000]
+ * - `jitter` [0]
+ * - `factor` [2]
+ *
+ * @param {Object} opts
+ * @api public
+ */
+
+ function Backoff(opts) {
+ opts = opts || {};
+ this.ms = opts.min || 100;
+ this.max = opts.max || 10000;
+ this.factor = opts.factor || 2;
+ this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
+ this.attempts = 0;
+ }
+
+ /**
+ * Return the backoff duration.
+ *
+ * @return {Number}
+ * @api public
+ */
+
+ Backoff.prototype.duration = function(){
+ var ms = this.ms * Math.pow(this.factor, this.attempts++);
+ if (this.jitter) {
+ var rand = Math.random();
+ var deviation = Math.floor(rand * this.jitter * ms);
+ ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;
+ }
+ return Math.min(ms, this.max) | 0;
+ };
+
+ /**
+ * Reset the number of attempts.
+ *
+ * @api public
+ */
+
+ Backoff.prototype.reset = function(){
+ this.attempts = 0;
+ };
+
+ /**
+ * Set the minimum duration
+ *
+ * @api public
+ */
+
+ Backoff.prototype.setMin = function(min){
+ this.ms = min;
+ };
+
+ /**
+ * Set the maximum duration
+ *
+ * @api public
+ */
+
+ Backoff.prototype.setMax = function(max){
+ this.max = max;
+ };
+
+ /**
+ * Set the jitter
+ *
+ * @api public
+ */
+
+ Backoff.prototype.setJitter = function(jitter){
+ this.jitter = jitter;
+ };
+
+
+},{}],8:[function(_dereq_,module,exports){
+ /**
+ * Slice reference.
+ */
+
+ var slice = [].slice;
+
+ /**
+ * Bind `obj` to `fn`.
+ *
+ * @param {Object} obj
+ * @param {Function|String} fn or string
+ * @return {Function}
+ * @api public
+ */
+
+ module.exports = function(obj, fn){
+ if ('string' == typeof fn) fn = obj[fn];
+ if ('function' != typeof fn) throw new Error('bind() requires a function');
+ var args = slice.call(arguments, 2);
+ return function(){
+ return fn.apply(obj, args.concat(slice.call(arguments)));
+ }
+ };
+
+},{}],9:[function(_dereq_,module,exports){
+
+ /**
+ * Expose `Emitter`.
+ */
+
+ module.exports = Emitter;
+
+ /**
+ * Initialize a new `Emitter`.
+ *
+ * @api public
+ */
+
+ function Emitter(obj) {
+ if (obj) return mixin(obj);
+ };
+
+ /**
+ * Mixin the emitter properties.
+ *
+ * @param {Object} obj
+ * @return {Object}
+ * @api private
+ */
+
+ function mixin(obj) {
+ for (var key in Emitter.prototype) {
+ obj[key] = Emitter.prototype[key];
+ }
+ return obj;
+ }
+
+ /**
+ * Listen on the given `event` with `fn`.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+ Emitter.prototype.on =
+ Emitter.prototype.addEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+ (this._callbacks[event] = this._callbacks[event] || [])
+ .push(fn);
+ return this;
+ };
+
+ /**
+ * Adds an `event` listener that will be invoked a single
+ * time then automatically removed.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+ Emitter.prototype.once = function(event, fn){
+ var self = this;
+ this._callbacks = this._callbacks || {};
+
+ function on() {
+ self.off(event, on);
+ fn.apply(this, arguments);
+ }
+
+ on.fn = fn;
+ this.on(event, on);
+ return this;
+ };
+
+ /**
+ * Remove the given callback for `event` or all
+ * registered callbacks.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+ Emitter.prototype.off =
+ Emitter.prototype.removeListener =
+ Emitter.prototype.removeAllListeners =
+ Emitter.prototype.removeEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+
+ // all
+ if (0 == arguments.length) {
+ this._callbacks = {};
+ return this;
+ }
+
+ // specific event
+ var callbacks = this._callbacks[event];
+ if (!callbacks) return this;
+
+ // remove all handlers
+ if (1 == arguments.length) {
+ delete this._callbacks[event];
+ return this;
+ }
+
+ // remove specific handler
+ var cb;
+ for (var i = 0; i < callbacks.length; i++) {
+ cb = callbacks[i];
+ if (cb === fn || cb.fn === fn) {
+ callbacks.splice(i, 1);
+ break;
+ }
+ }
+ return this;
+ };
+
+ /**
+ * Emit `event` with the given args.
+ *
+ * @param {String} event
+ * @param {Mixed} ...
+ * @return {Emitter}
+ */
+
+ Emitter.prototype.emit = function(event){
+ this._callbacks = this._callbacks || {};
+ var args = [].slice.call(arguments, 1)
+ , callbacks = this._callbacks[event];
+
+ if (callbacks) {
+ callbacks = callbacks.slice(0);
+ for (var i = 0, len = callbacks.length; i < len; ++i) {
+ callbacks[i].apply(this, args);
+ }
+ }
+
+ return this;
+ };
+
+ /**
+ * Return array of callbacks for `event`.
+ *
+ * @param {String} event
+ * @return {Array}
+ * @api public
+ */
+
+ Emitter.prototype.listeners = function(event){
+ this._callbacks = this._callbacks || {};
+ return this._callbacks[event] || [];
+ };
+
+ /**
+ * Check if this emitter has `event` handlers.
+ *
+ * @param {String} event
+ * @return {Boolean}
+ * @api public
+ */
+
+ Emitter.prototype.hasListeners = function(event){
+ return !! this.listeners(event).length;
+ };
+
+},{}],10:[function(_dereq_,module,exports){
+
+ /**
+ * Expose `debug()` as the module.
+ */
+
+ module.exports = debug;
+
+ /**
+ * Create a debugger with the given `name`.
+ *
+ * @param {String} name
+ * @return {Type}
+ * @api public
+ */
+
+ function debug(name) {
+ if (!debug.enabled(name)) return function(){};
+
+ return function(fmt){
+ fmt = coerce(fmt);
+
+ var curr = new Date;
+ var ms = curr - (debug[name] || curr);
+ debug[name] = curr;
+
+ fmt = name
+ + ' '
+ + fmt
+ + ' +' + debug.humanize(ms);
+
+ // This hackery is required for IE8
+ // where `console.log` doesn't have 'apply'
+ window.console
+ && console.log
+ && Function.prototype.apply.call(console.log, console, arguments);
+ }
+ }
+
+ /**
+ * The currently active debug mode names.
+ */
+
+ debug.names = [];
+ debug.skips = [];
+
+ /**
+ * Enables a debug mode by name. This can include modes
+ * separated by a colon and wildcards.
+ *
+ * @param {String} name
+ * @api public
+ */
+
+ debug.enable = function(name) {
+ try {
+ localStorage.debug = name;
+ } catch(e){}
+
+ var split = (name || '').split(/[\s,]+/)
+ , len = split.length;
+
+ for (var i = 0; i < len; i++) {
+ name = split[i].replace('*', '.*?');
+ if (name[0] === '-') {
+ debug.skips.push(new RegExp('^' + name.substr(1) + '$'));
+ }
+ else {
+ debug.names.push(new RegExp('^' + name + '$'));
+ }
+ }
+ };
+
+ /**
+ * Disable debug output.
+ *
+ * @api public
+ */
+
+ debug.disable = function(){
+ debug.enable('');
+ };
+
+ /**
+ * Humanize the given `ms`.
+ *
+ * @param {Number} m
+ * @return {String}
+ * @api private
+ */
+
+ debug.humanize = function(ms) {
+ var sec = 1000
+ , min = 60 * 1000
+ , hour = 60 * min;
+
+ if (ms >= hour) return (ms / hour).toFixed(1) + 'h';
+ if (ms >= min) return (ms / min).toFixed(1) + 'm';
+ if (ms >= sec) return (ms / sec | 0) + 's';
+ return ms + 'ms';
+ };
+
+ /**
+ * Returns true if the given mode name is enabled, false otherwise.
+ *
+ * @param {String} name
+ * @return {Boolean}
+ * @api public
+ */
+
+ debug.enabled = function(name) {
+ for (var i = 0, len = debug.skips.length; i < len; i++) {
+ if (debug.skips[i].test(name)) {
+ return false;
+ }
+ }
+ for (var i = 0, len = debug.names.length; i < len; i++) {
+ if (debug.names[i].test(name)) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ /**
+ * Coerce `val`.
+ */
+
+ function coerce(val) {
+ if (val instanceof Error) return val.stack || val.message;
+ return val;
+ }
+
+// persist
+
+ try {
+ if (window.localStorage) debug.enable(localStorage.debug);
+ } catch(e){}
+
+},{}],11:[function(_dereq_,module,exports){
+
+ module.exports = _dereq_('./lib/');
+
+},{"./lib/":12}],12:[function(_dereq_,module,exports){
+
+ module.exports = _dereq_('./socket');
+
+ /**
+ * Exports parser
+ *
+ * @api public
+ *
+ */
+ module.exports.parser = _dereq_('engine.io-parser');
+
+},{"./socket":13,"engine.io-parser":25}],13:[function(_dereq_,module,exports){
+ (function (global){
+ /**
+ * Module dependencies.
+ */
+
+ var transports = _dereq_('./transports');
+ var Emitter = _dereq_('component-emitter');
+ var debug = _dereq_('debug')('engine.io-client:socket');
+ var index = _dereq_('indexof');
+ var parser = _dereq_('engine.io-parser');
+ var parseuri = _dereq_('parseuri');
+ var parsejson = _dereq_('parsejson');
+ var parseqs = _dereq_('parseqs');
+
+ /**
+ * Module exports.
+ */
+
+ module.exports = Socket;
+
+ /**
+ * Noop function.
+ *
+ * @api private
+ */
+
+ function noop(){}
+
+ /**
+ * Socket constructor.
+ *
+ * @param {String|Object} uri or options
+ * @param {Object} options
+ * @api public
+ */
+
+ function Socket(uri, opts){
+ if (!(this instanceof Socket)) return new Socket(uri, opts);
+
+ opts = opts || {};
+
+ if (uri && 'object' == typeof uri) {
+ opts = uri;
+ uri = null;
+ }
+
+ if (uri) {
+ uri = parseuri(uri);
+ opts.host = uri.host;
+ opts.secure = uri.protocol == 'https' || uri.protocol == 'wss';
+ opts.port = uri.port;
+ if (uri.query) opts.query = uri.query;
+ }
+
+ this.secure = null != opts.secure ? opts.secure :
+ (global.location && 'https:' == location.protocol);
+
+ if (opts.host) {
+ var pieces = opts.host.split(':');
+ opts.hostname = pieces.shift();
+ if (pieces.length) {
+ opts.port = pieces.pop();
+ } else if (!opts.port) {
+ // if no port is specified manually, use the protocol default
+ opts.port = this.secure ? '443' : '80';
+ }
+ }
+
+ this.agent = opts.agent || false;
+ this.hostname = opts.hostname ||
+ (global.location ? location.hostname : 'localhost');
+ this.port = opts.port || (global.location && location.port ?
+ location.port :
+ (this.secure ? 443 : 80));
+ this.query = opts.query || {};
+ if ('string' == typeof this.query) this.query = parseqs.decode(this.query);
+ this.upgrade = false !== opts.upgrade;
+ this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/';
+ this.forceJSONP = !!opts.forceJSONP;
+ this.jsonp = false !== opts.jsonp;
+ this.forceBase64 = !!opts.forceBase64;
+ this.enablesXDR = !!opts.enablesXDR;
+ this.timestampParam = opts.timestampParam || 't';
+ this.timestampRequests = opts.timestampRequests;
+ this.transports = opts.transports || ['polling', 'websocket'];
+ this.readyState = '';
+ this.writeBuffer = [];
+ this.callbackBuffer = [];
+ this.policyPort = opts.policyPort || 843;
+ this.rememberUpgrade = opts.rememberUpgrade || false;
+ this.binaryType = null;
+ this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;
+
+ // SSL options for Node.js client
+ this.pfx = opts.pfx || null;
+ this.key = opts.key || null;
+ this.passphrase = opts.passphrase || null;
+ this.cert = opts.cert || null;
+ this.ca = opts.ca || null;
+ this.ciphers = opts.ciphers || null;
+ this.rejectUnauthorized = opts.rejectUnauthorized || null;
+
+ this.open();
+ }
+
+ Socket.priorWebsocketSuccess = false;
+
+ /**
+ * Mix in `Emitter`.
+ */
+
+ Emitter(Socket.prototype);
+
+ /**
+ * Protocol version.
+ *
+ * @api public
+ */
+
+ Socket.protocol = parser.protocol; // this is an int
+
+ /**
+ * Expose deps for legacy compatibility
+ * and standalone browser access.
+ */
+
+ Socket.Socket = Socket;
+ Socket.Transport = _dereq_('./transport');
+ Socket.transports = _dereq_('./transports');
+ Socket.parser = _dereq_('engine.io-parser');
+
+ /**
+ * Creates transport of the given type.
+ *
+ * @param {String} transport name
+ * @return {Transport}
+ * @api private
+ */
+
+ Socket.prototype.createTransport = function (name) {
+ debug('creating transport "%s"', name);
+ var query = clone(this.query);
+
+ // append engine.io protocol identifier
+ query.EIO = parser.protocol;
+
+ // transport name
+ query.transport = name;
+
+ // session id if we already have one
+ if (this.id) query.sid = this.id;
+
+ var transport = new transports[name]({
+ agent: this.agent,
+ hostname: this.hostname,
+ port: this.port,
+ secure: this.secure,
+ path: this.path,
+ query: query,
+ forceJSONP: this.forceJSONP,
+ jsonp: this.jsonp,
+ forceBase64: this.forceBase64,
+ enablesXDR: this.enablesXDR,
+ timestampRequests: this.timestampRequests,
+ timestampParam: this.timestampParam,
+ policyPort: this.policyPort,
+ socket: this,
+ pfx: this.pfx,
+ key: this.key,
+ passphrase: this.passphrase,
+ cert: this.cert,
+ ca: this.ca,
+ ciphers: this.ciphers,
+ rejectUnauthorized: this.rejectUnauthorized
+ });
+
+ return transport;
+ };
+
+ function clone (obj) {
+ var o = {};
+ for (var i in obj) {
+ if (obj.hasOwnProperty(i)) {
+ o[i] = obj[i];
+ }
+ }
+ return o;
+ }
+
+ /**
+ * Initializes transport to use and starts probe.
+ *
+ * @api private
+ */
+ Socket.prototype.open = function () {
+ var transport;
+ if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') != -1) {
+ transport = 'websocket';
+ } else if (0 == this.transports.length) {
+ // Emit error on next tick so it can be listened to
+ var self = this;
+ setTimeout(function() {
+ self.emit('error', 'No transports available');
+ }, 0);
+ return;
+ } else {
+ transport = this.transports[0];
+ }
+ this.readyState = 'opening';
+
+ // Retry with the next transport if the transport is disabled (jsonp: false)
+ var transport;
+ try {
+ transport = this.createTransport(transport);
+ } catch (e) {
+ this.transports.shift();
+ this.open();
+ return;
+ }
+
+ transport.open();
+ this.setTransport(transport);
+ };
+
+ /**
+ * Sets the current transport. Disables the existing one (if any).
+ *
+ * @api private
+ */
+
+ Socket.prototype.setTransport = function(transport){
+ debug('setting transport %s', transport.name);
+ var self = this;
+
+ if (this.transport) {
+ debug('clearing existing transport %s', this.transport.name);
+ this.transport.removeAllListeners();
+ }
+
+ // set up transport
+ this.transport = transport;
+
+ // set up transport listeners
+ transport
+ .on('drain', function(){
+ self.onDrain();
+ })
+ .on('packet', function(packet){
+ self.onPacket(packet);
+ })
+ .on('error', function(e){
+ self.onError(e);
+ })
+ .on('close', function(){
+ self.onClose('transport close');
+ });
+ };
+
+ /**
+ * Probes a transport.
+ *
+ * @param {String} transport name
+ * @api private
+ */
+
+ Socket.prototype.probe = function (name) {
+ debug('probing transport "%s"', name);
+ var transport = this.createTransport(name, { probe: 1 })
+ , failed = false
+ , self = this;
+
+ Socket.priorWebsocketSuccess = false;
+
+ function onTransportOpen(){
+ if (self.onlyBinaryUpgrades) {
+ var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;
+ failed = failed || upgradeLosesBinary;
+ }
+ if (failed) return;
+
+ debug('probe transport "%s" opened', name);
+ transport.send([{ type: 'ping', data: 'probe' }]);
+ transport.once('packet', function (msg) {
+ if (failed) return;
+ if ('pong' == msg.type && 'probe' == msg.data) {
+ debug('probe transport "%s" pong', name);
+ self.upgrading = true;
+ self.emit('upgrading', transport);
+ if (!transport) return;
+ Socket.priorWebsocketSuccess = 'websocket' == transport.name;
+
+ debug('pausing current transport "%s"', self.transport.name);
+ self.transport.pause(function () {
+ if (failed) return;
+ if ('closed' == self.readyState) return;
+ debug('changing transport and sending upgrade packet');
+
+ cleanup();
+
+ self.setTransport(transport);
+ transport.send([{ type: 'upgrade' }]);
+ self.emit('upgrade', transport);
+ transport = null;
+ self.upgrading = false;
+ self.flush();
+ });
+ } else {
+ debug('probe transport "%s" failed', name);
+ var err = new Error('probe error');
+ err.transport = transport.name;
+ self.emit('upgradeError', err);
+ }
+ });
+ }
+
+ function freezeTransport() {
+ if (failed) return;
+
+ // Any callback called by transport should be ignored since now
+ failed = true;
+
+ cleanup();
+
+ transport.close();
+ transport = null;
+ }
+
+ //Handle any error that happens while probing
+ function onerror(err) {
+ var error = new Error('probe error: ' + err);
+ error.transport = transport.name;
+
+ freezeTransport();
+
+ debug('probe transport "%s" failed because of error: %s', name, err);
+
+ self.emit('upgradeError', error);
+ }
+
+ function onTransportClose(){
+ onerror("transport closed");
+ }
+
+ //When the socket is closed while we're probing
+ function onclose(){
+ onerror("socket closed");
+ }
+
+ //When the socket is upgraded while we're probing
+ function onupgrade(to){
+ if (transport && to.name != transport.name) {
+ debug('"%s" works - aborting "%s"', to.name, transport.name);
+ freezeTransport();
+ }
+ }
+
+ //Remove all listeners on the transport and on self
+ function cleanup(){
+ transport.removeListener('open', onTransportOpen);
+ transport.removeListener('error', onerror);
+ transport.removeListener('close', onTransportClose);
+ self.removeListener('close', onclose);
+ self.removeListener('upgrading', onupgrade);
+ }
+
+ transport.once('open', onTransportOpen);
+ transport.once('error', onerror);
+ transport.once('close', onTransportClose);
+
+ this.once('close', onclose);
+ this.once('upgrading', onupgrade);
+
+ transport.open();
+
+ };
+
+ /**
+ * Called when connection is deemed open.
+ *
+ * @api public
+ */
+
+ Socket.prototype.onOpen = function () {
+ debug('socket open');
+ this.readyState = 'open';
+ Socket.priorWebsocketSuccess = 'websocket' == this.transport.name;
+ this.emit('open');
+ this.flush();
+
+ // we check for `readyState` in case an `open`
+ // listener already closed the socket
+ if ('open' == this.readyState && this.upgrade && this.transport.pause) {
+ debug('starting upgrade probes');
+ for (var i = 0, l = this.upgrades.length; i < l; i++) {
+ this.probe(this.upgrades[i]);
+ }
+ }
+ };
+
+ /**
+ * Handles a packet.
+ *
+ * @api private
+ */
+
+ Socket.prototype.onPacket = function (packet) {
+ if ('opening' == this.readyState || 'open' == this.readyState) {
+ debug('socket receive: type "%s", data "%s"', packet.type, packet.data);
+
+ this.emit('packet', packet);
+
+ // Socket is live - any packet counts
+ this.emit('heartbeat');
+
+ switch (packet.type) {
+ case 'open':
+ this.onHandshake(parsejson(packet.data));
+ break;
+
+ case 'pong':
+ this.setPing();
+ break;
+
+ case 'error':
+ var err = new Error('server error');
+ err.code = packet.data;
+ this.emit('error', err);
+ break;
+
+ case 'message':
+ this.emit('data', packet.data);
+ this.emit('message', packet.data);
+ break;
+ }
+ } else {
+ debug('packet received with socket readyState "%s"', this.readyState);
+ }
+ };
+
+ /**
+ * Called upon handshake completion.
+ *
+ * @param {Object} handshake obj
+ * @api private
+ */
+
+ Socket.prototype.onHandshake = function (data) {
+ this.emit('handshake', data);
+ this.id = data.sid;
+ this.transport.query.sid = data.sid;
+ this.upgrades = this.filterUpgrades(data.upgrades);
+ this.pingInterval = data.pingInterval;
+ this.pingTimeout = data.pingTimeout;
+ this.onOpen();
+ // In case open handler closes socket
+ if ('closed' == this.readyState) return;
+ this.setPing();
+
+ // Prolong liveness of socket on heartbeat
+ this.removeListener('heartbeat', this.onHeartbeat);
+ this.on('heartbeat', this.onHeartbeat);
+ };
+
+ /**
+ * Resets ping timeout.
+ *
+ * @api private
+ */
+
+ Socket.prototype.onHeartbeat = function (timeout) {
+ clearTimeout(this.pingTimeoutTimer);
+ var self = this;
+ self.pingTimeoutTimer = setTimeout(function () {
+ if ('closed' == self.readyState) return;
+ self.onClose('ping timeout');
+ }, timeout || (self.pingInterval + self.pingTimeout));
+ };
+
+ /**
+ * Pings server every `this.pingInterval` and expects response
+ * within `this.pingTimeout` or closes connection.
+ *
+ * @api private
+ */
+
+ Socket.prototype.setPing = function () {
+ var self = this;
+ clearTimeout(self.pingIntervalTimer);
+ self.pingIntervalTimer = setTimeout(function () {
+ debug('writing ping packet - expecting pong within %sms', self.pingTimeout);
+ self.ping();
+ self.onHeartbeat(self.pingTimeout);
+ }, self.pingInterval);
+ };
+
+ /**
+ * Sends a ping packet.
+ *
+ * @api public
+ */
+
+ Socket.prototype.ping = function () {
+ this.sendPacket('ping');
+ };
+
+ /**
+ * Called on `drain` event
+ *
+ * @api private
+ */
+
+ Socket.prototype.onDrain = function() {
+ for (var i = 0; i < this.prevBufferLen; i++) {
+ if (this.callbackBuffer[i]) {
+ this.callbackBuffer[i]();
+ }
+ }
+
+ this.writeBuffer.splice(0, this.prevBufferLen);
+ this.callbackBuffer.splice(0, this.prevBufferLen);
+
+ // setting prevBufferLen = 0 is very important
+ // for example, when upgrading, upgrade packet is sent over,
+ // and a nonzero prevBufferLen could cause problems on `drain`
+ this.prevBufferLen = 0;
+
+ if (this.writeBuffer.length == 0) {
+ this.emit('drain');
+ } else {
+ this.flush();
+ }
+ };
+
+ /**
+ * Flush write buffers.
+ *
+ * @api private
+ */
+
+ Socket.prototype.flush = function () {
+ if ('closed' != this.readyState && this.transport.writable &&
+ !this.upgrading && this.writeBuffer.length) {
+ debug('flushing %d packets in socket', this.writeBuffer.length);
+ this.transport.send(this.writeBuffer);
+ // keep track of current length of writeBuffer
+ // splice writeBuffer and callbackBuffer on `drain`
+ this.prevBufferLen = this.writeBuffer.length;
+ this.emit('flush');
+ }
+ };
+
+ /**
+ * Sends a message.
+ *
+ * @param {String} message.
+ * @param {Function} callback function.
+ * @return {Socket} for chaining.
+ * @api public
+ */
+
+ Socket.prototype.write =
+ Socket.prototype.send = function (msg, fn) {
+ this.sendPacket('message', msg, fn);
+ return this;
+ };
+
+ /**
+ * Sends a packet.
+ *
+ * @param {String} packet type.
+ * @param {String} data.
+ * @param {Function} callback function.
+ * @api private
+ */
+
+ Socket.prototype.sendPacket = function (type, data, fn) {
+ if ('closing' == this.readyState || 'closed' == this.readyState) {
+ return;
+ }
+
+ var packet = { type: type, data: data };
+ this.emit('packetCreate', packet);
+ this.writeBuffer.push(packet);
+ this.callbackBuffer.push(fn);
+ this.flush();
+ };
+
+ /**
+ * Closes the connection.
+ *
+ * @api private
+ */
+
+ Socket.prototype.close = function () {
+ if ('opening' == this.readyState || 'open' == this.readyState) {
+ this.readyState = 'closing';
+
+ var self = this;
+
+ function close() {
+ self.onClose('forced close');
+ debug('socket closing - telling transport to close');
+ self.transport.close();
+ }
+
+ function cleanupAndClose() {
+ self.removeListener('upgrade', cleanupAndClose);
+ self.removeListener('upgradeError', cleanupAndClose);
+ close();
+ }
+
+ function waitForUpgrade() {
+ // wait for upgrade to finish since we can't send packets while pausing a transport
+ self.once('upgrade', cleanupAndClose);
+ self.once('upgradeError', cleanupAndClose);
+ }
+
+ if (this.writeBuffer.length) {
+ this.once('drain', function() {
+ if (this.upgrading) {
+ waitForUpgrade();
+ } else {
+ close();
+ }
+ });
+ } else if (this.upgrading) {
+ waitForUpgrade();
+ } else {
+ close();
+ }
+ }
+
+ return this;
+ };
+
+ /**
+ * Called upon transport error
+ *
+ * @api private
+ */
+
+ Socket.prototype.onError = function (err) {
+ debug('socket error %j', err);
+ Socket.priorWebsocketSuccess = false;
+ this.emit('error', err);
+ this.onClose('transport error', err);
+ };
+
+ /**
+ * Called upon transport close.
+ *
+ * @api private
+ */
+
+ Socket.prototype.onClose = function (reason, desc) {
+ if ('opening' == this.readyState || 'open' == this.readyState || 'closing' == this.readyState) {
+ debug('socket close with reason: "%s"', reason);
+ var self = this;
+
+ // clear timers
+ clearTimeout(this.pingIntervalTimer);
+ clearTimeout(this.pingTimeoutTimer);
+
+ // clean buffers in next tick, so developers can still
+ // grab the buffers on `close` event
+ setTimeout(function() {
+ self.writeBuffer = [];
+ self.callbackBuffer = [];
+ self.prevBufferLen = 0;
+ }, 0);
+
+ // stop event from firing again for transport
+ this.transport.removeAllListeners('close');
+
+ // ensure transport won't stay open
+ this.transport.close();
+
+ // ignore further transport communication
+ this.transport.removeAllListeners();
+
+ // set ready state
+ this.readyState = 'closed';
+
+ // clear session id
+ this.id = null;
+
+ // emit close event
+ this.emit('close', reason, desc);
+ }
+ };
+
+ /**
+ * Filters upgrades, returning only those matching client transports.
+ *
+ * @param {Array} server upgrades
+ * @api private
+ *
+ */
+
+ Socket.prototype.filterUpgrades = function (upgrades) {
+ var filteredUpgrades = [];
+ for (var i = 0, j = upgrades.length; i';
+ iframe = document.createElement(html);
+ } catch (e) {
+ iframe = document.createElement('iframe');
+ iframe.name = self.iframeId;
+ iframe.src = 'javascript:0';
+ }
+
+ iframe.id = self.iframeId;
+
+ self.form.appendChild(iframe);
+ self.iframe = iframe;
+ }
+
+ initIframe();
+
+ // escape \n to prevent it from being converted into \r\n by some UAs
+ // double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side
+ data = data.replace(rEscapedNewline, '\\\n');
+ this.area.value = data.replace(rNewline, '\\n');
+
+ try {
+ this.form.submit();
+ } catch(e) {}
+
+ if (this.iframe.attachEvent) {
+ this.iframe.onreadystatechange = function(){
+ if (self.iframe.readyState == 'complete') {
+ complete();
+ }
+ };
+ } else {
+ this.iframe.onload = complete;
+ }
+ };
+
+ }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"./polling":18,"component-inherit":21}],17:[function(_dereq_,module,exports){
+ (function (global){
+ /**
+ * Module requirements.
+ */
+
+ var XMLHttpRequest = _dereq_('xmlhttprequest');
+ var Polling = _dereq_('./polling');
+ var Emitter = _dereq_('component-emitter');
+ var inherit = _dereq_('component-inherit');
+ var debug = _dereq_('debug')('engine.io-client:polling-xhr');
+
+ /**
+ * Module exports.
+ */
+
+ module.exports = XHR;
+ module.exports.Request = Request;
+
+ /**
+ * Empty function
+ */
+
+ function empty(){}
+
+ /**
+ * XHR Polling constructor.
+ *
+ * @param {Object} opts
+ * @api public
+ */
+
+ function XHR(opts){
+ Polling.call(this, opts);
+
+ if (global.location) {
+ var isSSL = 'https:' == location.protocol;
+ var port = location.port;
+
+ // some user agents have empty `location.port`
+ if (!port) {
+ port = isSSL ? 443 : 80;
+ }
+
+ this.xd = opts.hostname != global.location.hostname ||
+ port != opts.port;
+ this.xs = opts.secure != isSSL;
+ }
+ }
+
+ /**
+ * Inherits from Polling.
+ */
+
+ inherit(XHR, Polling);
+
+ /**
+ * XHR supports binary
+ */
+
+ XHR.prototype.supportsBinary = true;
+
+ /**
+ * Creates a request.
+ *
+ * @param {String} method
+ * @api private
+ */
+
+ XHR.prototype.request = function(opts){
+ opts = opts || {};
+ opts.uri = this.uri();
+ opts.xd = this.xd;
+ opts.xs = this.xs;
+ opts.agent = this.agent || false;
+ opts.supportsBinary = this.supportsBinary;
+ opts.enablesXDR = this.enablesXDR;
+
+ // SSL options for Node.js client
+ opts.pfx = this.pfx;
+ opts.key = this.key;
+ opts.passphrase = this.passphrase;
+ opts.cert = this.cert;
+ opts.ca = this.ca;
+ opts.ciphers = this.ciphers;
+ opts.rejectUnauthorized = this.rejectUnauthorized;
+
+ return new Request(opts);
+ };
+
+ /**
+ * Sends data.
+ *
+ * @param {String} data to send.
+ * @param {Function} called upon flush.
+ * @api private
+ */
+
+ XHR.prototype.doWrite = function(data, fn){
+ var isBinary = typeof data !== 'string' && data !== undefined;
+ var req = this.request({ method: 'POST', data: data, isBinary: isBinary });
+ var self = this;
+ req.on('success', fn);
+ req.on('error', function(err){
+ self.onError('xhr post error', err);
+ });
+ this.sendXhr = req;
+ };
+
+ /**
+ * Starts a poll cycle.
+ *
+ * @api private
+ */
+
+ XHR.prototype.doPoll = function(){
+ debug('xhr poll');
+ var req = this.request();
+ var self = this;
+ req.on('data', function(data){
+ self.onData(data);
+ });
+ req.on('error', function(err){
+ self.onError('xhr poll error', err);
+ });
+ this.pollXhr = req;
+ };
+
+ /**
+ * Request constructor
+ *
+ * @param {Object} options
+ * @api public
+ */
+
+ function Request(opts){
+ this.method = opts.method || 'GET';
+ this.uri = opts.uri;
+ this.xd = !!opts.xd;
+ this.xs = !!opts.xs;
+ this.async = false !== opts.async;
+ this.data = undefined != opts.data ? opts.data : null;
+ this.agent = opts.agent;
+ this.isBinary = opts.isBinary;
+ this.supportsBinary = opts.supportsBinary;
+ this.enablesXDR = opts.enablesXDR;
+
+ // SSL options for Node.js client
+ this.pfx = opts.pfx;
+ this.key = opts.key;
+ this.passphrase = opts.passphrase;
+ this.cert = opts.cert;
+ this.ca = opts.ca;
+ this.ciphers = opts.ciphers;
+ this.rejectUnauthorized = opts.rejectUnauthorized;
+
+ this.create();
+ }
+
+ /**
+ * Mix in `Emitter`.
+ */
+
+ Emitter(Request.prototype);
+
+ /**
+ * Creates the XHR object and sends the request.
+ *
+ * @api private
+ */
+
+ Request.prototype.create = function(){
+ var opts = { agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR };
+
+ // SSL options for Node.js client
+ opts.pfx = this.pfx;
+ opts.key = this.key;
+ opts.passphrase = this.passphrase;
+ opts.cert = this.cert;
+ opts.ca = this.ca;
+ opts.ciphers = this.ciphers;
+ opts.rejectUnauthorized = this.rejectUnauthorized;
+
+ var xhr = this.xhr = new XMLHttpRequest(opts);
+ var self = this;
+
+ try {
+ debug('xhr open %s: %s', this.method, this.uri);
+ xhr.open(this.method, this.uri, this.async);
+ if (this.supportsBinary) {
+ // This has to be done after open because Firefox is stupid
+ // http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension
+ xhr.responseType = 'arraybuffer';
+ }
+
+ if ('POST' == this.method) {
+ try {
+ if (this.isBinary) {
+ xhr.setRequestHeader('Content-type', 'application/octet-stream');
+ } else {
+ xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');
+ }
+ } catch (e) {}
+ }
+
+ // ie6 check
+ if ('withCredentials' in xhr) {
+ xhr.withCredentials = true;
+ }
+
+ if (this.hasXDR()) {
+ xhr.onload = function(){
+ self.onLoad();
+ };
+ xhr.onerror = function(){
+ self.onError(xhr.responseText);
+ };
+ } else {
+ xhr.onreadystatechange = function(){
+ if (4 != xhr.readyState) return;
+ if (200 == xhr.status || 1223 == xhr.status) {
+ self.onLoad();
+ } else {
+ // make sure the `error` event handler that's user-set
+ // does not throw in the same tick and gets caught here
+ setTimeout(function(){
+ self.onError(xhr.status);
+ }, 0);
+ }
+ };
+ }
+
+ debug('xhr data %s', this.data);
+ xhr.send(this.data);
+ } catch (e) {
+ // Need to defer since .create() is called directly fhrom the constructor
+ // and thus the 'error' event can only be only bound *after* this exception
+ // occurs. Therefore, also, we cannot throw here at all.
+ setTimeout(function() {
+ self.onError(e);
+ }, 0);
+ return;
+ }
+
+ if (global.document) {
+ this.index = Request.requestsCount++;
+ Request.requests[this.index] = this;
+ }
+ };
+
+ /**
+ * Called upon successful response.
+ *
+ * @api private
+ */
+
+ Request.prototype.onSuccess = function(){
+ this.emit('success');
+ this.cleanup();
+ };
+
+ /**
+ * Called if we have data.
+ *
+ * @api private
+ */
+
+ Request.prototype.onData = function(data){
+ this.emit('data', data);
+ this.onSuccess();
+ };
+
+ /**
+ * Called upon error.
+ *
+ * @api private
+ */
+
+ Request.prototype.onError = function(err){
+ this.emit('error', err);
+ this.cleanup(true);
+ };
+
+ /**
+ * Cleans up house.
+ *
+ * @api private
+ */
+
+ Request.prototype.cleanup = function(fromError){
+ if ('undefined' == typeof this.xhr || null === this.xhr) {
+ return;
+ }
+ // xmlhttprequest
+ if (this.hasXDR()) {
+ this.xhr.onload = this.xhr.onerror = empty;
+ } else {
+ this.xhr.onreadystatechange = empty;
+ }
+
+ if (fromError) {
+ try {
+ this.xhr.abort();
+ } catch(e) {}
+ }
+
+ if (global.document) {
+ delete Request.requests[this.index];
+ }
+
+ this.xhr = null;
+ };
+
+ /**
+ * Called upon load.
+ *
+ * @api private
+ */
+
+ Request.prototype.onLoad = function(){
+ var data;
+ try {
+ var contentType;
+ try {
+ contentType = this.xhr.getResponseHeader('Content-Type').split(';')[0];
+ } catch (e) {}
+ if (contentType === 'application/octet-stream') {
+ data = this.xhr.response;
+ } else {
+ if (!this.supportsBinary) {
+ data = this.xhr.responseText;
+ } else {
+ data = 'ok';
+ }
+ }
+ } catch (e) {
+ this.onError(e);
+ }
+ if (null != data) {
+ this.onData(data);
+ }
+ };
+
+ /**
+ * Check if it has XDomainRequest.
+ *
+ * @api private
+ */
+
+ Request.prototype.hasXDR = function(){
+ return 'undefined' !== typeof global.XDomainRequest && !this.xs && this.enablesXDR;
+ };
+
+ /**
+ * Aborts the request.
+ *
+ * @api public
+ */
+
+ Request.prototype.abort = function(){
+ this.cleanup();
+ };
+
+ /**
+ * Aborts pending requests when unloading the window. This is needed to prevent
+ * memory leaks (e.g. when using IE) and to ensure that no spurious error is
+ * emitted.
+ */
+
+ if (global.document) {
+ Request.requestsCount = 0;
+ Request.requests = {};
+ if (global.attachEvent) {
+ global.attachEvent('onunload', unloadHandler);
+ } else if (global.addEventListener) {
+ global.addEventListener('beforeunload', unloadHandler, false);
+ }
+ }
+
+ function unloadHandler() {
+ for (var i in Request.requests) {
+ if (Request.requests.hasOwnProperty(i)) {
+ Request.requests[i].abort();
+ }
+ }
+ }
+
+ }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"./polling":18,"component-emitter":9,"component-inherit":21,"debug":22,"xmlhttprequest":20}],18:[function(_dereq_,module,exports){
+ /**
+ * Module dependencies.
+ */
+
+ var Transport = _dereq_('../transport');
+ var parseqs = _dereq_('parseqs');
+ var parser = _dereq_('engine.io-parser');
+ var inherit = _dereq_('component-inherit');
+ var debug = _dereq_('debug')('engine.io-client:polling');
+
+ /**
+ * Module exports.
+ */
+
+ module.exports = Polling;
+
+ /**
+ * Is XHR2 supported?
+ */
+
+ var hasXHR2 = (function() {
+ var XMLHttpRequest = _dereq_('xmlhttprequest');
+ var xhr = new XMLHttpRequest({ xdomain: false });
+ return null != xhr.responseType;
+ })();
+
+ /**
+ * Polling interface.
+ *
+ * @param {Object} opts
+ * @api private
+ */
+
+ function Polling(opts){
+ var forceBase64 = (opts && opts.forceBase64);
+ if (!hasXHR2 || forceBase64) {
+ this.supportsBinary = false;
+ }
+ Transport.call(this, opts);
+ }
+
+ /**
+ * Inherits from Transport.
+ */
+
+ inherit(Polling, Transport);
+
+ /**
+ * Transport name.
+ */
+
+ Polling.prototype.name = 'polling';
+
+ /**
+ * Opens the socket (triggers polling). We write a PING message to determine
+ * when the transport is open.
+ *
+ * @api private
+ */
+
+ Polling.prototype.doOpen = function(){
+ this.poll();
+ };
+
+ /**
+ * Pauses polling.
+ *
+ * @param {Function} callback upon buffers are flushed and transport is paused
+ * @api private
+ */
+
+ Polling.prototype.pause = function(onPause){
+ var pending = 0;
+ var self = this;
+
+ this.readyState = 'pausing';
+
+ function pause(){
+ debug('paused');
+ self.readyState = 'paused';
+ onPause();
+ }
+
+ if (this.polling || !this.writable) {
+ var total = 0;
+
+ if (this.polling) {
+ debug('we are currently polling - waiting to pause');
+ total++;
+ this.once('pollComplete', function(){
+ debug('pre-pause polling complete');
+ --total || pause();
+ });
+ }
+
+ if (!this.writable) {
+ debug('we are currently writing - waiting to pause');
+ total++;
+ this.once('drain', function(){
+ debug('pre-pause writing complete');
+ --total || pause();
+ });
+ }
+ } else {
+ pause();
+ }
+ };
+
+ /**
+ * Starts polling cycle.
+ *
+ * @api public
+ */
+
+ Polling.prototype.poll = function(){
+ debug('polling');
+ this.polling = true;
+ this.doPoll();
+ this.emit('poll');
+ };
+
+ /**
+ * Overloads onData to detect payloads.
+ *
+ * @api private
+ */
+
+ Polling.prototype.onData = function(data){
+ var self = this;
+ debug('polling got data %s', data);
+ var callback = function(packet, index, total) {
+ // if its the first message we consider the transport open
+ if ('opening' == self.readyState) {
+ self.onOpen();
+ }
+
+ // if its a close packet, we close the ongoing requests
+ if ('close' == packet.type) {
+ self.onClose();
+ return false;
+ }
+
+ // otherwise bypass onData and handle the message
+ self.onPacket(packet);
+ };
+
+ // decode payload
+ parser.decodePayload(data, this.socket.binaryType, callback);
+
+ // if an event did not trigger closing
+ if ('closed' != this.readyState) {
+ // if we got data we're not polling
+ this.polling = false;
+ this.emit('pollComplete');
+
+ if ('open' == this.readyState) {
+ this.poll();
+ } else {
+ debug('ignoring poll - transport state "%s"', this.readyState);
+ }
+ }
+ };
+
+ /**
+ * For polling, send a close packet.
+ *
+ * @api private
+ */
+
+ Polling.prototype.doClose = function(){
+ var self = this;
+
+ function close(){
+ debug('writing close packet');
+ self.write([{ type: 'close' }]);
+ }
+
+ if ('open' == this.readyState) {
+ debug('transport open - closing');
+ close();
+ } else {
+ // in case we're trying to close while
+ // handshaking is in progress (GH-164)
+ debug('transport not open - deferring close');
+ this.once('open', close);
+ }
+ };
+
+ /**
+ * Writes a packets payload.
+ *
+ * @param {Array} data packets
+ * @param {Function} drain callback
+ * @api private
+ */
+
+ Polling.prototype.write = function(packets){
+ var self = this;
+ this.writable = false;
+ var callbackfn = function() {
+ self.writable = true;
+ self.emit('drain');
+ };
+
+ var self = this;
+ parser.encodePayload(packets, this.supportsBinary, function(data) {
+ self.doWrite(data, callbackfn);
+ });
+ };
+
+ /**
+ * Generates uri for connection.
+ *
+ * @api private
+ */
+
+ Polling.prototype.uri = function(){
+ var query = this.query || {};
+ var schema = this.secure ? 'https' : 'http';
+ var port = '';
+
+ // cache busting is forced
+ if (false !== this.timestampRequests) {
+ query[this.timestampParam] = +new Date + '-' + Transport.timestamps++;
+ }
+
+ if (!this.supportsBinary && !query.sid) {
+ query.b64 = 1;
+ }
+
+ query = parseqs.encode(query);
+
+ // avoid port if default for schema
+ if (this.port && (('https' == schema && this.port != 443) ||
+ ('http' == schema && this.port != 80))) {
+ port = ':' + this.port;
+ }
+
+ // prepend ? to query
+ if (query.length) {
+ query = '?' + query;
+ }
+
+ return schema + '://' + this.hostname + port + this.path + query;
+ };
+
+},{"../transport":14,"component-inherit":21,"debug":22,"engine.io-parser":25,"parseqs":35,"xmlhttprequest":20}],19:[function(_dereq_,module,exports){
+ /**
+ * Module dependencies.
+ */
+
+ var Transport = _dereq_('../transport');
+ var parser = _dereq_('engine.io-parser');
+ var parseqs = _dereq_('parseqs');
+ var inherit = _dereq_('component-inherit');
+ var debug = _dereq_('debug')('engine.io-client:websocket');
+
+ /**
+ * `ws` exposes a WebSocket-compatible interface in
+ * Node, or the `WebSocket` or `MozWebSocket` globals
+ * in the browser.
+ */
+
+ var WebSocket = _dereq_('ws');
+
+ /**
+ * Module exports.
+ */
+
+ module.exports = WS;
+
+ /**
+ * WebSocket transport constructor.
+ *
+ * @api {Object} connection options
+ * @api public
+ */
+
+ function WS(opts){
+ var forceBase64 = (opts && opts.forceBase64);
+ if (forceBase64) {
+ this.supportsBinary = false;
+ }
+ Transport.call(this, opts);
+ }
+
+ /**
+ * Inherits from Transport.
+ */
+
+ inherit(WS, Transport);
+
+ /**
+ * Transport name.
+ *
+ * @api public
+ */
+
+ WS.prototype.name = 'websocket';
+
+ /*
+ * WebSockets support binary
+ */
+
+ WS.prototype.supportsBinary = true;
+
+ /**
+ * Opens socket.
+ *
+ * @api private
+ */
+
+ WS.prototype.doOpen = function(){
+ if (!this.check()) {
+ // let probe timeout
+ return;
+ }
+
+ var self = this;
+ var uri = this.uri();
+ var protocols = void(0);
+ var opts = { agent: this.agent };
+
+ // SSL options for Node.js client
+ opts.pfx = this.pfx;
+ opts.key = this.key;
+ opts.passphrase = this.passphrase;
+ opts.cert = this.cert;
+ opts.ca = this.ca;
+ opts.ciphers = this.ciphers;
+ opts.rejectUnauthorized = this.rejectUnauthorized;
+
+ this.ws = new WebSocket(uri, protocols, opts);
+
+ if (this.ws.binaryType === undefined) {
+ this.supportsBinary = false;
+ }
+
+ this.ws.binaryType = 'arraybuffer';
+ this.addEventListeners();
+ };
+
+ /**
+ * Adds event listeners to the socket
+ *
+ * @api private
+ */
+
+ WS.prototype.addEventListeners = function(){
+ var self = this;
+
+ this.ws.onopen = function(){
+ self.onOpen();
+ };
+ this.ws.onclose = function(){
+ self.onClose();
+ };
+ this.ws.onmessage = function(ev){
+ self.onData(ev.data);
+ };
+ this.ws.onerror = function(e){
+ self.onError('websocket error', e);
+ };
+ };
+
+ /**
+ * Override `onData` to use a timer on iOS.
+ * See: https://gist.github.com/mloughran/2052006
+ *
+ * @api private
+ */
+
+ if ('undefined' != typeof navigator
+ && /iPad|iPhone|iPod/i.test(navigator.userAgent)) {
+ WS.prototype.onData = function(data){
+ var self = this;
+ setTimeout(function(){
+ Transport.prototype.onData.call(self, data);
+ }, 0);
+ };
+ }
+
+ /**
+ * Writes data to socket.
+ *
+ * @param {Array} array of packets.
+ * @api private
+ */
+
+ WS.prototype.write = function(packets){
+ var self = this;
+ this.writable = false;
+ // encodePacket efficient as it uses WS framing
+ // no need for encodePayload
+ for (var i = 0, l = packets.length; i < l; i++) {
+ parser.encodePacket(packets[i], this.supportsBinary, function(data) {
+ //Sometimes the websocket has already been closed but the browser didn't
+ //have a chance of informing us about it yet, in that case send will
+ //throw an error
+ try {
+ self.ws.send(data);
+ } catch (e){
+ debug('websocket closed before onclose event');
+ }
+ });
+ }
+
+ function ondrain() {
+ self.writable = true;
+ self.emit('drain');
+ }
+ // fake drain
+ // defer to next tick to allow Socket to clear writeBuffer
+ setTimeout(ondrain, 0);
+ };
+
+ /**
+ * Called upon close
+ *
+ * @api private
+ */
+
+ WS.prototype.onClose = function(){
+ Transport.prototype.onClose.call(this);
+ };
+
+ /**
+ * Closes socket.
+ *
+ * @api private
+ */
+
+ WS.prototype.doClose = function(){
+ if (typeof this.ws !== 'undefined') {
+ this.ws.close();
+ }
+ };
+
+ /**
+ * Generates uri for connection.
+ *
+ * @api private
+ */
+
+ WS.prototype.uri = function(){
+ var query = this.query || {};
+ var schema = this.secure ? 'wss' : 'ws';
+ var port = '';
+
+ // avoid port if default for schema
+ if (this.port && (('wss' == schema && this.port != 443)
+ || ('ws' == schema && this.port != 80))) {
+ port = ':' + this.port;
+ }
+
+ // append timestamp to URI
+ if (this.timestampRequests) {
+ query[this.timestampParam] = +new Date;
+ }
+
+ // communicate binary support capabilities
+ if (!this.supportsBinary) {
+ query.b64 = 1;
+ }
+
+ query = parseqs.encode(query);
+
+ // prepend ? to query
+ if (query.length) {
+ query = '?' + query;
+ }
+
+ return schema + '://' + this.hostname + port + this.path + query;
+ };
+
+ /**
+ * Feature detection for WebSocket.
+ *
+ * @return {Boolean} whether this transport is available.
+ * @api public
+ */
+
+ WS.prototype.check = function(){
+ return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name);
+ };
+
+},{"../transport":14,"component-inherit":21,"debug":22,"engine.io-parser":25,"parseqs":35,"ws":37}],20:[function(_dereq_,module,exports){
+// browser shim for xmlhttprequest module
+ var hasCORS = _dereq_('has-cors');
+
+ module.exports = function(opts) {
+ var xdomain = opts.xdomain;
+
+ // scheme must be same when usign XDomainRequest
+ // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
+ var xscheme = opts.xscheme;
+
+ // XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.
+ // https://github.com/Automattic/engine.io-client/pull/217
+ var enablesXDR = opts.enablesXDR;
+
+ // XMLHttpRequest can be disabled on IE
+ try {
+ if ('undefined' != typeof XMLHttpRequest && (!xdomain || hasCORS)) {
+ return new XMLHttpRequest();
+ }
+ } catch (e) { }
+
+ // Use XDomainRequest for IE8 if enablesXDR is true
+ // because loading bar keeps flashing when using jsonp-polling
+ // https://github.com/yujiosaka/socke.io-ie8-loading-example
+ try {
+ if ('undefined' != typeof XDomainRequest && !xscheme && enablesXDR) {
+ return new XDomainRequest();
+ }
+ } catch (e) { }
+
+ if (!xdomain) {
+ try {
+ return new ActiveXObject('Microsoft.XMLHTTP');
+ } catch(e) { }
+ }
+ }
+
+},{"has-cors":40}],21:[function(_dereq_,module,exports){
+
+ module.exports = function(a, b){
+ var fn = function(){};
+ fn.prototype = b.prototype;
+ a.prototype = new fn;
+ a.prototype.constructor = a;
+ };
+},{}],22:[function(_dereq_,module,exports){
+
+ /**
+ * This is the web browser implementation of `debug()`.
+ *
+ * Expose `debug()` as the module.
+ */
+
+ exports = module.exports = _dereq_('./debug');
+ exports.log = log;
+ exports.formatArgs = formatArgs;
+ exports.save = save;
+ exports.load = load;
+ exports.useColors = useColors;
+
+ /**
+ * Colors.
+ */
+
+ exports.colors = [
+ 'lightseagreen',
+ 'forestgreen',
+ 'goldenrod',
+ 'dodgerblue',
+ 'darkorchid',
+ 'crimson'
+ ];
+
+ /**
+ * Currently only WebKit-based Web Inspectors, Firefox >= v31,
+ * and the Firebug extension (any Firefox version) are known
+ * to support "%c" CSS customizations.
+ *
+ * TODO: add a `localStorage` variable to explicitly enable/disable colors
+ */
+
+ function useColors() {
+ // is webkit? http://stackoverflow.com/a/16459606/376773
+ return ('WebkitAppearance' in document.documentElement.style) ||
+ // is firebug? http://stackoverflow.com/a/398120/376773
+ (window.console && (console.firebug || (console.exception && console.table))) ||
+ // is firefox >= v31?
+ // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
+ (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31);
+ }
+
+ /**
+ * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
+ */
+
+ exports.formatters.j = function(v) {
+ return JSON.stringify(v);
+ };
+
+
+ /**
+ * Colorize log arguments if enabled.
+ *
+ * @api public
+ */
+
+ function formatArgs() {
+ var args = arguments;
+ var useColors = this.useColors;
+
+ args[0] = (useColors ? '%c' : '')
+ + this.namespace
+ + (useColors ? ' %c' : ' ')
+ + args[0]
+ + (useColors ? '%c ' : ' ')
+ + '+' + exports.humanize(this.diff);
+
+ if (!useColors) return args;
+
+ var c = 'color: ' + this.color;
+ args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));
+
+ // the final "%c" is somewhat tricky, because there could be other
+ // arguments passed either before or after the %c, so we need to
+ // figure out the correct index to insert the CSS into
+ var index = 0;
+ var lastC = 0;
+ args[0].replace(/%[a-z%]/g, function(match) {
+ if ('%' === match) return;
+ index++;
+ if ('%c' === match) {
+ // we only are interested in the *last* %c
+ // (the user may have provided their own)
+ lastC = index;
+ }
+ });
+
+ args.splice(lastC, 0, c);
+ return args;
+ }
+
+ /**
+ * Invokes `console.log()` when available.
+ * No-op when `console.log` is not a "function".
+ *
+ * @api public
+ */
+
+ function log() {
+ // This hackery is required for IE8,
+ // where the `console.log` function doesn't have 'apply'
+ return 'object' == typeof console
+ && 'function' == typeof console.log
+ && Function.prototype.apply.call(console.log, console, arguments);
+ }
+
+ /**
+ * Save `namespaces`.
+ *
+ * @param {String} namespaces
+ * @api private
+ */
+
+ function save(namespaces) {
+ try {
+ if (null == namespaces) {
+ localStorage.removeItem('debug');
+ } else {
+ localStorage.debug = namespaces;
+ }
+ } catch(e) {}
+ }
+
+ /**
+ * Load `namespaces`.
+ *
+ * @return {String} returns the previously persisted debug modes
+ * @api private
+ */
+
+ function load() {
+ var r;
+ try {
+ r = localStorage.debug;
+ } catch(e) {}
+ return r;
+ }
+
+ /**
+ * Enable namespaces listed in `localStorage.debug` initially.
+ */
+
+ exports.enable(load());
+
+},{"./debug":23}],23:[function(_dereq_,module,exports){
+
+ /**
+ * This is the common logic for both the Node.js and web browser
+ * implementations of `debug()`.
+ *
+ * Expose `debug()` as the module.
+ */
+
+ exports = module.exports = debug;
+ exports.coerce = coerce;
+ exports.disable = disable;
+ exports.enable = enable;
+ exports.enabled = enabled;
+ exports.humanize = _dereq_('ms');
+
+ /**
+ * The currently active debug mode names, and names to skip.
+ */
+
+ exports.names = [];
+ exports.skips = [];
+
+ /**
+ * Map of special "%n" handling functions, for the debug "format" argument.
+ *
+ * Valid key names are a single, lowercased letter, i.e. "n".
+ */
+
+ exports.formatters = {};
+
+ /**
+ * Previously assigned color.
+ */
+
+ var prevColor = 0;
+
+ /**
+ * Previous log timestamp.
+ */
+
+ var prevTime;
+
+ /**
+ * Select a color.
+ *
+ * @return {Number}
+ * @api private
+ */
+
+ function selectColor() {
+ return exports.colors[prevColor++ % exports.colors.length];
+ }
+
+ /**
+ * Create a debugger with the given `namespace`.
+ *
+ * @param {String} namespace
+ * @return {Function}
+ * @api public
+ */
+
+ function debug(namespace) {
+
+ // define the `disabled` version
+ function disabled() {
+ }
+ disabled.enabled = false;
+
+ // define the `enabled` version
+ function enabled() {
+
+ var self = enabled;
+
+ // set `diff` timestamp
+ var curr = +new Date();
+ var ms = curr - (prevTime || curr);
+ self.diff = ms;
+ self.prev = prevTime;
+ self.curr = curr;
+ prevTime = curr;
+
+ // add the `color` if not set
+ if (null == self.useColors) self.useColors = exports.useColors();
+ if (null == self.color && self.useColors) self.color = selectColor();
+
+ var args = Array.prototype.slice.call(arguments);
+
+ args[0] = exports.coerce(args[0]);
+
+ if ('string' !== typeof args[0]) {
+ // anything else let's inspect with %o
+ args = ['%o'].concat(args);
+ }
+
+ // apply any `formatters` transformations
+ var index = 0;
+ args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {
+ // if we encounter an escaped % then don't increase the array index
+ if (match === '%') return match;
+ index++;
+ var formatter = exports.formatters[format];
+ if ('function' === typeof formatter) {
+ var val = args[index];
+ match = formatter.call(self, val);
+
+ // now we need to remove `args[index]` since it's inlined in the `format`
+ args.splice(index, 1);
+ index--;
+ }
+ return match;
+ });
+
+ if ('function' === typeof exports.formatArgs) {
+ args = exports.formatArgs.apply(self, args);
+ }
+ var logFn = enabled.log || exports.log || console.log.bind(console);
+ logFn.apply(self, args);
+ }
+ enabled.enabled = true;
+
+ var fn = exports.enabled(namespace) ? enabled : disabled;
+
+ fn.namespace = namespace;
+
+ return fn;
+ }
+
+ /**
+ * Enables a debug mode by namespaces. This can include modes
+ * separated by a colon and wildcards.
+ *
+ * @param {String} namespaces
+ * @api public
+ */
+
+ function enable(namespaces) {
+ exports.save(namespaces);
+
+ var split = (namespaces || '').split(/[\s,]+/);
+ var len = split.length;
+
+ for (var i = 0; i < len; i++) {
+ if (!split[i]) continue; // ignore empty strings
+ namespaces = split[i].replace(/\*/g, '.*?');
+ if (namespaces[0] === '-') {
+ exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
+ } else {
+ exports.names.push(new RegExp('^' + namespaces + '$'));
+ }
+ }
+ }
+
+ /**
+ * Disable debug output.
+ *
+ * @api public
+ */
+
+ function disable() {
+ exports.enable('');
+ }
+
+ /**
+ * Returns true if the given mode name is enabled, false otherwise.
+ *
+ * @param {String} name
+ * @return {Boolean}
+ * @api public
+ */
+
+ function enabled(name) {
+ var i, len;
+ for (i = 0, len = exports.skips.length; i < len; i++) {
+ if (exports.skips[i].test(name)) {
+ return false;
+ }
+ }
+ for (i = 0, len = exports.names.length; i < len; i++) {
+ if (exports.names[i].test(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Coerce `val`.
+ *
+ * @param {Mixed} val
+ * @return {Mixed}
+ * @api private
+ */
+
+ function coerce(val) {
+ if (val instanceof Error) return val.stack || val.message;
+ return val;
+ }
+
+},{"ms":24}],24:[function(_dereq_,module,exports){
+ /**
+ * Helpers.
+ */
+
+ var s = 1000;
+ var m = s * 60;
+ var h = m * 60;
+ var d = h * 24;
+ var y = d * 365.25;
+
+ /**
+ * Parse or format the given `val`.
+ *
+ * Options:
+ *
+ * - `long` verbose formatting [false]
+ *
+ * @param {String|Number} val
+ * @param {Object} options
+ * @return {String|Number}
+ * @api public
+ */
+
+ module.exports = function(val, options){
+ options = options || {};
+ if ('string' == typeof val) return parse(val);
+ return options.long
+ ? long(val)
+ : short(val);
+ };
+
+ /**
+ * Parse the given `str` and return milliseconds.
+ *
+ * @param {String} str
+ * @return {Number}
+ * @api private
+ */
+
+ function parse(str) {
+ var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);
+ if (!match) return;
+ var n = parseFloat(match[1]);
+ var type = (match[2] || 'ms').toLowerCase();
+ switch (type) {
+ case 'years':
+ case 'year':
+ case 'y':
+ return n * y;
+ case 'days':
+ case 'day':
+ case 'd':
+ return n * d;
+ case 'hours':
+ case 'hour':
+ case 'h':
+ return n * h;
+ case 'minutes':
+ case 'minute':
+ case 'm':
+ return n * m;
+ case 'seconds':
+ case 'second':
+ case 's':
+ return n * s;
+ case 'ms':
+ return n;
+ }
+ }
+
+ /**
+ * Short format for `ms`.
+ *
+ * @param {Number} ms
+ * @return {String}
+ * @api private
+ */
+
+ function short(ms) {
+ if (ms >= d) return Math.round(ms / d) + 'd';
+ if (ms >= h) return Math.round(ms / h) + 'h';
+ if (ms >= m) return Math.round(ms / m) + 'm';
+ if (ms >= s) return Math.round(ms / s) + 's';
+ return ms + 'ms';
+ }
+
+ /**
+ * Long format for `ms`.
+ *
+ * @param {Number} ms
+ * @return {String}
+ * @api private
+ */
+
+ function long(ms) {
+ return plural(ms, d, 'day')
+ || plural(ms, h, 'hour')
+ || plural(ms, m, 'minute')
+ || plural(ms, s, 'second')
+ || ms + ' ms';
+ }
+
+ /**
+ * Pluralization helper.
+ */
+
+ function plural(ms, n, name) {
+ if (ms < n) return;
+ if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
+ return Math.ceil(ms / n) + ' ' + name + 's';
+ }
+
+},{}],25:[function(_dereq_,module,exports){
+ (function (global){
+ /**
+ * Module dependencies.
+ */
+
+ var keys = _dereq_('./keys');
+ var hasBinary = _dereq_('has-binary');
+ var sliceBuffer = _dereq_('arraybuffer.slice');
+ var base64encoder = _dereq_('base64-arraybuffer');
+ var after = _dereq_('after');
+ var utf8 = _dereq_('utf8');
+
+ /**
+ * Check if we are running an android browser. That requires us to use
+ * ArrayBuffer with polling transports...
+ *
+ * http://ghinda.net/jpeg-blob-ajax-android/
+ */
+
+ var isAndroid = navigator.userAgent.match(/Android/i);
+
+ /**
+ * Check if we are running in PhantomJS.
+ * Uploading a Blob with PhantomJS does not work correctly, as reported here:
+ * https://github.com/ariya/phantomjs/issues/11395
+ * @type boolean
+ */
+ var isPhantomJS = /PhantomJS/i.test(navigator.userAgent);
+
+ /**
+ * When true, avoids using Blobs to encode payloads.
+ * @type boolean
+ */
+ var dontSendBlobs = isAndroid || isPhantomJS;
+
+ /**
+ * Current protocol version.
+ */
+
+ exports.protocol = 3;
+
+ /**
+ * Packet types.
+ */
+
+ var packets = exports.packets = {
+ open: 0 // non-ws
+ , close: 1 // non-ws
+ , ping: 2
+ , pong: 3
+ , message: 4
+ , upgrade: 5
+ , noop: 6
+ };
+
+ var packetslist = keys(packets);
+
+ /**
+ * Premade error packet.
+ */
+
+ var err = { type: 'error', data: 'parser error' };
+
+ /**
+ * Create a blob api even for blob builder when vendor prefixes exist
+ */
+
+ var Blob = _dereq_('blob');
+
+ /**
+ * Encodes a packet.
+ *
+ * [ ]
+ *
+ * Example:
+ *
+ * 5hello world
+ * 3
+ * 4
+ *
+ * Binary is encoded in an identical principle
+ *
+ * @api private
+ */
+
+ exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) {
+ if ('function' == typeof supportsBinary) {
+ callback = supportsBinary;
+ supportsBinary = false;
+ }
+
+ if ('function' == typeof utf8encode) {
+ callback = utf8encode;
+ utf8encode = null;
+ }
+
+ var data = (packet.data === undefined)
+ ? undefined
+ : packet.data.buffer || packet.data;
+
+ if (global.ArrayBuffer && data instanceof ArrayBuffer) {
+ return encodeArrayBuffer(packet, supportsBinary, callback);
+ } else if (Blob && data instanceof global.Blob) {
+ return encodeBlob(packet, supportsBinary, callback);
+ }
+
+ // might be an object with { base64: true, data: dataAsBase64String }
+ if (data && data.base64) {
+ return encodeBase64Object(packet, callback);
+ }
+
+ // Sending data as a utf-8 string
+ var encoded = packets[packet.type];
+
+ // data fragment is optional
+ if (undefined !== packet.data) {
+ encoded += utf8encode ? utf8.encode(String(packet.data)) : String(packet.data);
+ }
+
+ return callback('' + encoded);
+
+ };
+
+ function encodeBase64Object(packet, callback) {
+ // packet data is an object { base64: true, data: dataAsBase64String }
+ var message = 'b' + exports.packets[packet.type] + packet.data.data;
+ return callback(message);
+ }
+
+ /**
+ * Encode packet helpers for binary types
+ */
+
+ function encodeArrayBuffer(packet, supportsBinary, callback) {
+ if (!supportsBinary) {
+ return exports.encodeBase64Packet(packet, callback);
+ }
+
+ var data = packet.data;
+ var contentArray = new Uint8Array(data);
+ var resultBuffer = new Uint8Array(1 + data.byteLength);
+
+ resultBuffer[0] = packets[packet.type];
+ for (var i = 0; i < contentArray.length; i++) {
+ resultBuffer[i+1] = contentArray[i];
+ }
+
+ return callback(resultBuffer.buffer);
+ }
+
+ function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {
+ if (!supportsBinary) {
+ return exports.encodeBase64Packet(packet, callback);
+ }
+
+ var fr = new FileReader();
+ fr.onload = function() {
+ packet.data = fr.result;
+ exports.encodePacket(packet, supportsBinary, true, callback);
+ };
+ return fr.readAsArrayBuffer(packet.data);
+ }
+
+ function encodeBlob(packet, supportsBinary, callback) {
+ if (!supportsBinary) {
+ return exports.encodeBase64Packet(packet, callback);
+ }
+
+ if (dontSendBlobs) {
+ return encodeBlobAsArrayBuffer(packet, supportsBinary, callback);
+ }
+
+ var length = new Uint8Array(1);
+ length[0] = packets[packet.type];
+ var blob = new Blob([length.buffer, packet.data]);
+
+ return callback(blob);
+ }
+
+ /**
+ * Encodes a packet with binary data in a base64 string
+ *
+ * @param {Object} packet, has `type` and `data`
+ * @return {String} base64 encoded message
+ */
+
+ exports.encodeBase64Packet = function(packet, callback) {
+ var message = 'b' + exports.packets[packet.type];
+ if (Blob && packet.data instanceof Blob) {
+ var fr = new FileReader();
+ fr.onload = function() {
+ var b64 = fr.result.split(',')[1];
+ callback(message + b64);
+ };
+ return fr.readAsDataURL(packet.data);
+ }
+
+ var b64data;
+ try {
+ b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data));
+ } catch (e) {
+ // iPhone Safari doesn't let you apply with typed arrays
+ var typed = new Uint8Array(packet.data);
+ var basic = new Array(typed.length);
+ for (var i = 0; i < typed.length; i++) {
+ basic[i] = typed[i];
+ }
+ b64data = String.fromCharCode.apply(null, basic);
+ }
+ message += global.btoa(b64data);
+ return callback(message);
+ };
+
+ /**
+ * Decodes a packet. Changes format to Blob if requested.
+ *
+ * @return {Object} with `type` and `data` (if any)
+ * @api private
+ */
+
+ exports.decodePacket = function (data, binaryType, utf8decode) {
+ // String data
+ if (typeof data == 'string' || data === undefined) {
+ if (data.charAt(0) == 'b') {
+ return exports.decodeBase64Packet(data.substr(1), binaryType);
+ }
+
+ if (utf8decode) {
+ try {
+ data = utf8.decode(data);
+ } catch (e) {
+ return err;
+ }
+ }
+ var type = data.charAt(0);
+
+ if (Number(type) != type || !packetslist[type]) {
+ return err;
+ }
+
+ if (data.length > 1) {
+ return { type: packetslist[type], data: data.substring(1) };
+ } else {
+ return { type: packetslist[type] };
+ }
+ }
+
+ var asArray = new Uint8Array(data);
+ var type = asArray[0];
+ var rest = sliceBuffer(data, 1);
+ if (Blob && binaryType === 'blob') {
+ rest = new Blob([rest]);
+ }
+ return { type: packetslist[type], data: rest };
+ };
+
+ /**
+ * Decodes a packet encoded in a base64 string
+ *
+ * @param {String} base64 encoded message
+ * @return {Object} with `type` and `data` (if any)
+ */
+
+ exports.decodeBase64Packet = function(msg, binaryType) {
+ var type = packetslist[msg.charAt(0)];
+ if (!global.ArrayBuffer) {
+ return { type: type, data: { base64: true, data: msg.substr(1) } };
+ }
+
+ var data = base64encoder.decode(msg.substr(1));
+
+ if (binaryType === 'blob' && Blob) {
+ data = new Blob([data]);
+ }
+
+ return { type: type, data: data };
+ };
+
+ /**
+ * Encodes multiple messages (payload).
+ *
+ * :data
+ *
+ * Example:
+ *
+ * 11:hello world2:hi
+ *
+ * If any contents are binary, they will be encoded as base64 strings. Base64
+ * encoded strings are marked with a b before the length specifier
+ *
+ * @param {Array} packets
+ * @api private
+ */
+
+ exports.encodePayload = function (packets, supportsBinary, callback) {
+ if (typeof supportsBinary == 'function') {
+ callback = supportsBinary;
+ supportsBinary = null;
+ }
+
+ var isBinary = hasBinary(packets);
+
+ if (supportsBinary && isBinary) {
+ if (Blob && !dontSendBlobs) {
+ return exports.encodePayloadAsBlob(packets, callback);
+ }
+
+ return exports.encodePayloadAsArrayBuffer(packets, callback);
+ }
+
+ if (!packets.length) {
+ return callback('0:');
+ }
+
+ function setLengthHeader(message) {
+ return message.length + ':' + message;
+ }
+
+ function encodeOne(packet, doneCallback) {
+ exports.encodePacket(packet, !isBinary ? false : supportsBinary, true, function(message) {
+ doneCallback(null, setLengthHeader(message));
+ });
+ }
+
+ map(packets, encodeOne, function(err, results) {
+ return callback(results.join(''));
+ });
+ };
+
+ /**
+ * Async array map using after
+ */
+
+ function map(ary, each, done) {
+ var result = new Array(ary.length);
+ var next = after(ary.length, done);
+
+ var eachWithIndex = function(i, el, cb) {
+ each(el, function(error, msg) {
+ result[i] = msg;
+ cb(error, result);
+ });
+ };
+
+ for (var i = 0; i < ary.length; i++) {
+ eachWithIndex(i, ary[i], next);
+ }
+ }
+
+ /*
+ * Decodes data when a payload is maybe expected. Possible binary contents are
+ * decoded from their base64 representation
+ *
+ * @param {String} data, callback method
+ * @api public
+ */
+
+ exports.decodePayload = function (data, binaryType, callback) {
+ if (typeof data != 'string') {
+ return exports.decodePayloadAsBinary(data, binaryType, callback);
+ }
+
+ if (typeof binaryType === 'function') {
+ callback = binaryType;
+ binaryType = null;
+ }
+
+ var packet;
+ if (data == '') {
+ // parser error - ignoring payload
+ return callback(err, 0, 1);
+ }
+
+ var length = ''
+ , n, msg;
+
+ for (var i = 0, l = data.length; i < l; i++) {
+ var chr = data.charAt(i);
+
+ if (':' != chr) {
+ length += chr;
+ } else {
+ if ('' == length || (length != (n = Number(length)))) {
+ // parser error - ignoring payload
+ return callback(err, 0, 1);
+ }
+
+ msg = data.substr(i + 1, n);
+
+ if (length != msg.length) {
+ // parser error - ignoring payload
+ return callback(err, 0, 1);
+ }
+
+ if (msg.length) {
+ packet = exports.decodePacket(msg, binaryType, true);
+
+ if (err.type == packet.type && err.data == packet.data) {
+ // parser error in individual packet - ignoring payload
+ return callback(err, 0, 1);
+ }
+
+ var ret = callback(packet, i + n, l);
+ if (false === ret) return;
+ }
+
+ // advance cursor
+ i += n;
+ length = '';
+ }
+ }
+
+ if (length != '') {
+ // parser error - ignoring payload
+ return callback(err, 0, 1);
+ }
+
+ };
+
+ /**
+ * Encodes multiple messages (payload) as binary.
+ *
+ * <1 = binary, 0 = string>[...]
+ *
+ * Example:
+ * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers
+ *
+ * @param {Array} packets
+ * @return {ArrayBuffer} encoded payload
+ * @api private
+ */
+
+ exports.encodePayloadAsArrayBuffer = function(packets, callback) {
+ if (!packets.length) {
+ return callback(new ArrayBuffer(0));
+ }
+
+ function encodeOne(packet, doneCallback) {
+ exports.encodePacket(packet, true, true, function(data) {
+ return doneCallback(null, data);
+ });
+ }
+
+ map(packets, encodeOne, function(err, encodedPackets) {
+ var totalLength = encodedPackets.reduce(function(acc, p) {
+ var len;
+ if (typeof p === 'string'){
+ len = p.length;
+ } else {
+ len = p.byteLength;
+ }
+ return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2
+ }, 0);
+
+ var resultArray = new Uint8Array(totalLength);
+
+ var bufferIndex = 0;
+ encodedPackets.forEach(function(p) {
+ var isString = typeof p === 'string';
+ var ab = p;
+ if (isString) {
+ var view = new Uint8Array(p.length);
+ for (var i = 0; i < p.length; i++) {
+ view[i] = p.charCodeAt(i);
+ }
+ ab = view.buffer;
+ }
+
+ if (isString) { // not true binary
+ resultArray[bufferIndex++] = 0;
+ } else { // true binary
+ resultArray[bufferIndex++] = 1;
+ }
+
+ var lenStr = ab.byteLength.toString();
+ for (var i = 0; i < lenStr.length; i++) {
+ resultArray[bufferIndex++] = parseInt(lenStr[i]);
+ }
+ resultArray[bufferIndex++] = 255;
+
+ var view = new Uint8Array(ab);
+ for (var i = 0; i < view.length; i++) {
+ resultArray[bufferIndex++] = view[i];
+ }
+ });
+
+ return callback(resultArray.buffer);
+ });
+ };
+
+ /**
+ * Encode as Blob
+ */
+
+ exports.encodePayloadAsBlob = function(packets, callback) {
+ function encodeOne(packet, doneCallback) {
+ exports.encodePacket(packet, true, true, function(encoded) {
+ var binaryIdentifier = new Uint8Array(1);
+ binaryIdentifier[0] = 1;
+ if (typeof encoded === 'string') {
+ var view = new Uint8Array(encoded.length);
+ for (var i = 0; i < encoded.length; i++) {
+ view[i] = encoded.charCodeAt(i);
+ }
+ encoded = view.buffer;
+ binaryIdentifier[0] = 0;
+ }
+
+ var len = (encoded instanceof ArrayBuffer)
+ ? encoded.byteLength
+ : encoded.size;
+
+ var lenStr = len.toString();
+ var lengthAry = new Uint8Array(lenStr.length + 1);
+ for (var i = 0; i < lenStr.length; i++) {
+ lengthAry[i] = parseInt(lenStr[i]);
+ }
+ lengthAry[lenStr.length] = 255;
+
+ if (Blob) {
+ var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]);
+ doneCallback(null, blob);
+ }
+ });
+ }
+
+ map(packets, encodeOne, function(err, results) {
+ return callback(new Blob(results));
+ });
+ };
+
+ /*
+ * Decodes data when a payload is maybe expected. Strings are decoded by
+ * interpreting each byte as a key code for entries marked to start with 0. See
+ * description of encodePayloadAsBinary
+ *
+ * @param {ArrayBuffer} data, callback method
+ * @api public
+ */
+
+ exports.decodePayloadAsBinary = function (data, binaryType, callback) {
+ if (typeof binaryType === 'function') {
+ callback = binaryType;
+ binaryType = null;
+ }
+
+ var bufferTail = data;
+ var buffers = [];
+
+ var numberTooLong = false;
+ while (bufferTail.byteLength > 0) {
+ var tailArray = new Uint8Array(bufferTail);
+ var isString = tailArray[0] === 0;
+ var msgLength = '';
+
+ for (var i = 1; ; i++) {
+ if (tailArray[i] == 255) break;
+
+ if (msgLength.length > 310) {
+ numberTooLong = true;
+ break;
+ }
+
+ msgLength += tailArray[i];
+ }
+
+ if(numberTooLong) return callback(err, 0, 1);
+
+ bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length);
+ msgLength = parseInt(msgLength);
+
+ var msg = sliceBuffer(bufferTail, 0, msgLength);
+ if (isString) {
+ try {
+ msg = String.fromCharCode.apply(null, new Uint8Array(msg));
+ } catch (e) {
+ // iPhone Safari doesn't let you apply to typed arrays
+ var typed = new Uint8Array(msg);
+ msg = '';
+ for (var i = 0; i < typed.length; i++) {
+ msg += String.fromCharCode(typed[i]);
+ }
+ }
+ }
+
+ buffers.push(msg);
+ bufferTail = sliceBuffer(bufferTail, msgLength);
+ }
+
+ var total = buffers.length;
+ buffers.forEach(function(buffer, i) {
+ callback(exports.decodePacket(buffer, binaryType, true), i, total);
+ });
+ };
+
+ }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"./keys":26,"after":27,"arraybuffer.slice":28,"base64-arraybuffer":29,"blob":30,"has-binary":31,"utf8":33}],26:[function(_dereq_,module,exports){
+
+ /**
+ * Gets the keys for an object.
+ *
+ * @return {Array} keys
+ * @api private
+ */
+
+ module.exports = Object.keys || function keys (obj){
+ var arr = [];
+ var has = Object.prototype.hasOwnProperty;
+
+ for (var i in obj) {
+ if (has.call(obj, i)) {
+ arr.push(i);
+ }
+ }
+ return arr;
+ };
+
+},{}],27:[function(_dereq_,module,exports){
+ module.exports = after
+
+ function after(count, callback, err_cb) {
+ var bail = false
+ err_cb = err_cb || noop
+ proxy.count = count
+
+ return (count === 0) ? callback() : proxy
+
+ function proxy(err, result) {
+ if (proxy.count <= 0) {
+ throw new Error('after called too many times')
+ }
+ --proxy.count
+
+ // after first error, rest are passed to err_cb
+ if (err) {
+ bail = true
+ callback(err)
+ // future error callbacks will go to error handler
+ callback = err_cb
+ } else if (proxy.count === 0 && !bail) {
+ callback(null, result)
+ }
+ }
+ }
+
+ function noop() {}
+
+},{}],28:[function(_dereq_,module,exports){
+ /**
+ * An abstraction for slicing an arraybuffer even when
+ * ArrayBuffer.prototype.slice is not supported
+ *
+ * @api public
+ */
+
+ module.exports = function(arraybuffer, start, end) {
+ var bytes = arraybuffer.byteLength;
+ start = start || 0;
+ end = end || bytes;
+
+ if (arraybuffer.slice) { return arraybuffer.slice(start, end); }
+
+ if (start < 0) { start += bytes; }
+ if (end < 0) { end += bytes; }
+ if (end > bytes) { end = bytes; }
+
+ if (start >= bytes || start >= end || bytes === 0) {
+ return new ArrayBuffer(0);
+ }
+
+ var abv = new Uint8Array(arraybuffer);
+ var result = new Uint8Array(end - start);
+ for (var i = start, ii = 0; i < end; i++, ii++) {
+ result[ii] = abv[i];
+ }
+ return result.buffer;
+ };
+
+},{}],29:[function(_dereq_,module,exports){
+ /*
+ * base64-arraybuffer
+ * https://github.com/niklasvh/base64-arraybuffer
+ *
+ * Copyright (c) 2012 Niklas von Hertzen
+ * Licensed under the MIT license.
+ */
+ (function(chars){
+ "use strict";
+
+ exports.encode = function(arraybuffer) {
+ var bytes = new Uint8Array(arraybuffer),
+ i, len = bytes.length, base64 = "";
+
+ for (i = 0; i < len; i+=3) {
+ base64 += chars[bytes[i] >> 2];
+ base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
+ base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
+ base64 += chars[bytes[i + 2] & 63];
+ }
+
+ if ((len % 3) === 2) {
+ base64 = base64.substring(0, base64.length - 1) + "=";
+ } else if (len % 3 === 1) {
+ base64 = base64.substring(0, base64.length - 2) + "==";
+ }
+
+ return base64;
+ };
+
+ exports.decode = function(base64) {
+ var bufferLength = base64.length * 0.75,
+ len = base64.length, i, p = 0,
+ encoded1, encoded2, encoded3, encoded4;
+
+ if (base64[base64.length - 1] === "=") {
+ bufferLength--;
+ if (base64[base64.length - 2] === "=") {
+ bufferLength--;
+ }
+ }
+
+ var arraybuffer = new ArrayBuffer(bufferLength),
+ bytes = new Uint8Array(arraybuffer);
+
+ for (i = 0; i < len; i+=4) {
+ encoded1 = chars.indexOf(base64[i]);
+ encoded2 = chars.indexOf(base64[i+1]);
+ encoded3 = chars.indexOf(base64[i+2]);
+ encoded4 = chars.indexOf(base64[i+3]);
+
+ bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
+ bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
+ bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
+ }
+
+ return arraybuffer;
+ };
+ })("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
+
+},{}],30:[function(_dereq_,module,exports){
+ (function (global){
+ /**
+ * Create a blob builder even when vendor prefixes exist
+ */
+
+ var BlobBuilder = global.BlobBuilder
+ || global.WebKitBlobBuilder
+ || global.MSBlobBuilder
+ || global.MozBlobBuilder;
+
+ /**
+ * Check if Blob constructor is supported
+ */
+
+ var blobSupported = (function() {
+ try {
+ var b = new Blob(['hi']);
+ return b.size == 2;
+ } catch(e) {
+ return false;
+ }
+ })();
+
+ /**
+ * Check if BlobBuilder is supported
+ */
+
+ var blobBuilderSupported = BlobBuilder
+ && BlobBuilder.prototype.append
+ && BlobBuilder.prototype.getBlob;
+
+ function BlobBuilderConstructor(ary, options) {
+ options = options || {};
+
+ var bb = new BlobBuilder();
+ for (var i = 0; i < ary.length; i++) {
+ bb.append(ary[i]);
+ }
+ return (options.type) ? bb.getBlob(options.type) : bb.getBlob();
+ };
+
+ module.exports = (function() {
+ if (blobSupported) {
+ return global.Blob;
+ } else if (blobBuilderSupported) {
+ return BlobBuilderConstructor;
+ } else {
+ return undefined;
+ }
+ })();
+
+ }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],31:[function(_dereq_,module,exports){
+ (function (global){
+
+ /*
+ * Module requirements.
+ */
+
+ var isArray = _dereq_('isarray');
+
+ /**
+ * Module exports.
+ */
+
+ module.exports = hasBinary;
+
+ /**
+ * Checks for binary data.
+ *
+ * Right now only Buffer and ArrayBuffer are supported..
+ *
+ * @param {Object} anything
+ * @api public
+ */
+
+ function hasBinary(data) {
+
+ function _hasBinary(obj) {
+ if (!obj) return false;
+
+ if ( (global.Buffer && global.Buffer.isBuffer(obj)) ||
+ (global.ArrayBuffer && obj instanceof ArrayBuffer) ||
+ (global.Blob && obj instanceof Blob) ||
+ (global.File && obj instanceof File)
+ ) {
+ return true;
+ }
+
+ if (isArray(obj)) {
+ for (var i = 0; i < obj.length; i++) {
+ if (_hasBinary(obj[i])) {
+ return true;
+ }
+ }
+ } else if (obj && 'object' == typeof obj) {
+ if (obj.toJSON) {
+ obj = obj.toJSON();
+ }
+
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key) && _hasBinary(obj[key])) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ return _hasBinary(data);
+ }
+
+ }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"isarray":32}],32:[function(_dereq_,module,exports){
+ module.exports = Array.isArray || function (arr) {
+ return Object.prototype.toString.call(arr) == '[object Array]';
+ };
+
+},{}],33:[function(_dereq_,module,exports){
+ (function (global){
+ /*! http://mths.be/utf8js v2.0.0 by @mathias */
+ ;(function(root) {
+
+ // Detect free variables `exports`
+ var freeExports = typeof exports == 'object' && exports;
+
+ // Detect free variable `module`
+ var freeModule = typeof module == 'object' && module &&
+ module.exports == freeExports && module;
+
+ // Detect free variable `global`, from Node.js or Browserified code,
+ // and use it as `root`
+ var freeGlobal = typeof global == 'object' && global;
+ if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
+ root = freeGlobal;
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ var stringFromCharCode = String.fromCharCode;
+
+ // Taken from http://mths.be/punycode
+ function ucs2decode(string) {
+ var output = [];
+ var counter = 0;
+ var length = string.length;
+ var value;
+ var extra;
+ while (counter < length) {
+ value = string.charCodeAt(counter++);
+ if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
+ // high surrogate, and there is a next character
+ extra = string.charCodeAt(counter++);
+ if ((extra & 0xFC00) == 0xDC00) { // low surrogate
+ output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
+ } else {
+ // unmatched surrogate; only append this code unit, in case the next
+ // code unit is the high surrogate of a surrogate pair
+ output.push(value);
+ counter--;
+ }
+ } else {
+ output.push(value);
+ }
+ }
+ return output;
+ }
+
+ // Taken from http://mths.be/punycode
+ function ucs2encode(array) {
+ var length = array.length;
+ var index = -1;
+ var value;
+ var output = '';
+ while (++index < length) {
+ value = array[index];
+ if (value > 0xFFFF) {
+ value -= 0x10000;
+ output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
+ value = 0xDC00 | value & 0x3FF;
+ }
+ output += stringFromCharCode(value);
+ }
+ return output;
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ function createByte(codePoint, shift) {
+ return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80);
+ }
+
+ function encodeCodePoint(codePoint) {
+ if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence
+ return stringFromCharCode(codePoint);
+ }
+ var symbol = '';
+ if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence
+ symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0);
+ }
+ else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence
+ symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0);
+ symbol += createByte(codePoint, 6);
+ }
+ else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence
+ symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0);
+ symbol += createByte(codePoint, 12);
+ symbol += createByte(codePoint, 6);
+ }
+ symbol += stringFromCharCode((codePoint & 0x3F) | 0x80);
+ return symbol;
+ }
+
+ function utf8encode(string) {
+ var codePoints = ucs2decode(string);
+
+ // console.log(JSON.stringify(codePoints.map(function(x) {
+ // return 'U+' + x.toString(16).toUpperCase();
+ // })));
+
+ var length = codePoints.length;
+ var index = -1;
+ var codePoint;
+ var byteString = '';
+ while (++index < length) {
+ codePoint = codePoints[index];
+ byteString += encodeCodePoint(codePoint);
+ }
+ return byteString;
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ function readContinuationByte() {
+ if (byteIndex >= byteCount) {
+ throw Error('Invalid byte index');
+ }
+
+ var continuationByte = byteArray[byteIndex] & 0xFF;
+ byteIndex++;
+
+ if ((continuationByte & 0xC0) == 0x80) {
+ return continuationByte & 0x3F;
+ }
+
+ // If we end up here, its not a continuation byte
+ throw Error('Invalid continuation byte');
+ }
+
+ function decodeSymbol() {
+ var byte1;
+ var byte2;
+ var byte3;
+ var byte4;
+ var codePoint;
+
+ if (byteIndex > byteCount) {
+ throw Error('Invalid byte index');
+ }
+
+ if (byteIndex == byteCount) {
+ return false;
+ }
+
+ // Read first byte
+ byte1 = byteArray[byteIndex] & 0xFF;
+ byteIndex++;
+
+ // 1-byte sequence (no continuation bytes)
+ if ((byte1 & 0x80) == 0) {
+ return byte1;
+ }
+
+ // 2-byte sequence
+ if ((byte1 & 0xE0) == 0xC0) {
+ var byte2 = readContinuationByte();
+ codePoint = ((byte1 & 0x1F) << 6) | byte2;
+ if (codePoint >= 0x80) {
+ return codePoint;
+ } else {
+ throw Error('Invalid continuation byte');
+ }
+ }
+
+ // 3-byte sequence (may include unpaired surrogates)
+ if ((byte1 & 0xF0) == 0xE0) {
+ byte2 = readContinuationByte();
+ byte3 = readContinuationByte();
+ codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;
+ if (codePoint >= 0x0800) {
+ return codePoint;
+ } else {
+ throw Error('Invalid continuation byte');
+ }
+ }
+
+ // 4-byte sequence
+ if ((byte1 & 0xF8) == 0xF0) {
+ byte2 = readContinuationByte();
+ byte3 = readContinuationByte();
+ byte4 = readContinuationByte();
+ codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) |
+ (byte3 << 0x06) | byte4;
+ if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) {
+ return codePoint;
+ }
+ }
+
+ throw Error('Invalid UTF-8 detected');
+ }
+
+ var byteArray;
+ var byteCount;
+ var byteIndex;
+ function utf8decode(byteString) {
+ byteArray = ucs2decode(byteString);
+ byteCount = byteArray.length;
+ byteIndex = 0;
+ var codePoints = [];
+ var tmp;
+ while ((tmp = decodeSymbol()) !== false) {
+ codePoints.push(tmp);
+ }
+ return ucs2encode(codePoints);
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ var utf8 = {
+ 'version': '2.0.0',
+ 'encode': utf8encode,
+ 'decode': utf8decode
+ };
+
+ // Some AMD build optimizers, like r.js, check for specific condition patterns
+ // like the following:
+ if (
+ typeof define == 'function' &&
+ typeof define.amd == 'object' &&
+ define.amd
+ ) {
+ define(function() {
+ return utf8;
+ });
+ } else if (freeExports && !freeExports.nodeType) {
+ if (freeModule) { // in Node.js or RingoJS v0.8.0+
+ freeModule.exports = utf8;
+ } else { // in Narwhal or RingoJS v0.7.0-
+ var object = {};
+ var hasOwnProperty = object.hasOwnProperty;
+ for (var key in utf8) {
+ hasOwnProperty.call(utf8, key) && (freeExports[key] = utf8[key]);
+ }
+ }
+ } else { // in Rhino or a web browser
+ root.utf8 = utf8;
+ }
+
+ }(this));
+
+ }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],34:[function(_dereq_,module,exports){
+ (function (global){
+ /**
+ * JSON parse.
+ *
+ * @see Based on jQuery#parseJSON (MIT) and JSON2
+ * @api private
+ */
+
+ var rvalidchars = /^[\],:{}\s]*$/;
+ var rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
+ var rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
+ var rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g;
+ var rtrimLeft = /^\s+/;
+ var rtrimRight = /\s+$/;
+
+ module.exports = function parsejson(data) {
+ if ('string' != typeof data || !data) {
+ return null;
+ }
+
+ data = data.replace(rtrimLeft, '').replace(rtrimRight, '');
+
+ // Attempt to parse using the native JSON parser first
+ if (global.JSON && JSON.parse) {
+ return JSON.parse(data);
+ }
+
+ if (rvalidchars.test(data.replace(rvalidescape, '@')
+ .replace(rvalidtokens, ']')
+ .replace(rvalidbraces, ''))) {
+ return (new Function('return ' + data))();
+ }
+ };
+ }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],35:[function(_dereq_,module,exports){
+ /**
+ * Compiles a querystring
+ * Returns string representation of the object
+ *
+ * @param {Object}
+ * @api private
+ */
+
+ exports.encode = function (obj) {
+ var str = '';
+
+ for (var i in obj) {
+ if (obj.hasOwnProperty(i)) {
+ if (str.length) str += '&';
+ str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
+ }
+ }
+
+ return str;
+ };
+
+ /**
+ * Parses a simple querystring into an object
+ *
+ * @param {String} qs
+ * @api private
+ */
+
+ exports.decode = function(qs){
+ var qry = {};
+ var pairs = qs.split('&');
+ for (var i = 0, l = pairs.length; i < l; i++) {
+ var pair = pairs[i].split('=');
+ qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
+ }
+ return qry;
+ };
+
+},{}],36:[function(_dereq_,module,exports){
+ /**
+ * Parses an URI
+ *
+ * @author Steven Levithan (MIT license)
+ * @api private
+ */
+
+ var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
+
+ var parts = [
+ 'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
+ ];
+
+ module.exports = function parseuri(str) {
+ var src = str,
+ b = str.indexOf('['),
+ e = str.indexOf(']');
+
+ if (b != -1 && e != -1) {
+ str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
+ }
+
+ var m = re.exec(str || ''),
+ uri = {},
+ i = 14;
+
+ while (i--) {
+ uri[parts[i]] = m[i] || '';
+ }
+
+ if (b != -1 && e != -1) {
+ uri.source = src;
+ uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
+ uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
+ uri.ipv6uri = true;
+ }
+
+ return uri;
+ };
+
+},{}],37:[function(_dereq_,module,exports){
+
+ /**
+ * Module dependencies.
+ */
+
+ var global = (function() { return this; })();
+
+ /**
+ * WebSocket constructor.
+ */
+
+ var WebSocket = global.WebSocket || global.MozWebSocket;
+
+ /**
+ * Module exports.
+ */
+
+ module.exports = WebSocket ? ws : null;
+
+ /**
+ * WebSocket constructor.
+ *
+ * The third `opts` options object gets ignored in web browsers, since it's
+ * non-standard, and throws a TypeError if passed to the constructor.
+ * See: https://github.com/einaros/ws/issues/227
+ *
+ * @param {String} uri
+ * @param {Array} protocols (optional)
+ * @param {Object) opts (optional)
+ * @api public
+ */
+
+ function ws(uri, protocols, opts) {
+ var instance;
+ if (protocols) {
+ instance = new WebSocket(uri, protocols);
+ } else {
+ instance = new WebSocket(uri);
+ }
+ return instance;
+ }
+
+ if (WebSocket) ws.prototype = WebSocket.prototype;
+
+},{}],38:[function(_dereq_,module,exports){
+ (function (global){
+
+ /*
+ * Module requirements.
+ */
+
+ var isArray = _dereq_('isarray');
+
+ /**
+ * Module exports.
+ */
+
+ module.exports = hasBinary;
+
+ /**
+ * Checks for binary data.
+ *
+ * Right now only Buffer and ArrayBuffer are supported..
+ *
+ * @param {Object} anything
+ * @api public
+ */
+
+ function hasBinary(data) {
+
+ function _hasBinary(obj) {
+ if (!obj) return false;
+
+ if ( (global.Buffer && global.Buffer.isBuffer(obj)) ||
+ (global.ArrayBuffer && obj instanceof ArrayBuffer) ||
+ (global.Blob && obj instanceof Blob) ||
+ (global.File && obj instanceof File)
+ ) {
+ return true;
+ }
+
+ if (isArray(obj)) {
+ for (var i = 0; i < obj.length; i++) {
+ if (_hasBinary(obj[i])) {
+ return true;
+ }
+ }
+ } else if (obj && 'object' == typeof obj) {
+ if (obj.toJSON) {
+ obj = obj.toJSON();
+ }
+
+ for (var key in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, key) && _hasBinary(obj[key])) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ return _hasBinary(data);
+ }
+
+ }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"isarray":39}],39:[function(_dereq_,module,exports){
+ module.exports=_dereq_(32)
+},{}],40:[function(_dereq_,module,exports){
+
+ /**
+ * Module dependencies.
+ */
+
+ var global = _dereq_('global');
+
+ /**
+ * Module exports.
+ *
+ * Logic borrowed from Modernizr:
+ *
+ * - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js
+ */
+
+ try {
+ module.exports = 'XMLHttpRequest' in global &&
+ 'withCredentials' in new global.XMLHttpRequest();
+ } catch (err) {
+ // if XMLHttp support is disabled in IE then it will throw
+ // when trying to create
+ module.exports = false;
+ }
+
+},{"global":41}],41:[function(_dereq_,module,exports){
+
+ /**
+ * Returns `this`. Execute this without a "context" (i.e. without it being
+ * attached to an object of the left-hand side), and `this` points to the
+ * "global" scope of the current JS execution.
+ */
+
+ module.exports = (function () { return this; })();
+
+},{}],42:[function(_dereq_,module,exports){
+
+ var indexOf = [].indexOf;
+
+ module.exports = function(arr, obj){
+ if (indexOf) return arr.indexOf(obj);
+ for (var i = 0; i < arr.length; ++i) {
+ if (arr[i] === obj) return i;
+ }
+ return -1;
+ };
+},{}],43:[function(_dereq_,module,exports){
+
+ /**
+ * HOP ref.
+ */
+
+ var has = Object.prototype.hasOwnProperty;
+
+ /**
+ * Return own keys in `obj`.
+ *
+ * @param {Object} obj
+ * @return {Array}
+ * @api public
+ */
+
+ exports.keys = Object.keys || function(obj){
+ var keys = [];
+ for (var key in obj) {
+ if (has.call(obj, key)) {
+ keys.push(key);
+ }
+ }
+ return keys;
+ };
+
+ /**
+ * Return own values in `obj`.
+ *
+ * @param {Object} obj
+ * @return {Array}
+ * @api public
+ */
+
+ exports.values = function(obj){
+ var vals = [];
+ for (var key in obj) {
+ if (has.call(obj, key)) {
+ vals.push(obj[key]);
+ }
+ }
+ return vals;
+ };
+
+ /**
+ * Merge `b` into `a`.
+ *
+ * @param {Object} a
+ * @param {Object} b
+ * @return {Object} a
+ * @api public
+ */
+
+ exports.merge = function(a, b){
+ for (var key in b) {
+ if (has.call(b, key)) {
+ a[key] = b[key];
+ }
+ }
+ return a;
+ };
+
+ /**
+ * Return length of `obj`.
+ *
+ * @param {Object} obj
+ * @return {Number}
+ * @api public
+ */
+
+ exports.length = function(obj){
+ return exports.keys(obj).length;
+ };
+
+ /**
+ * Check if `obj` is empty.
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api public
+ */
+
+ exports.isEmpty = function(obj){
+ return 0 == exports.length(obj);
+ };
+},{}],44:[function(_dereq_,module,exports){
+ /**
+ * Parses an URI
+ *
+ * @author Steven Levithan (MIT license)
+ * @api private
+ */
+
+ var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
+
+ var parts = [
+ 'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host'
+ , 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
+ ];
+
+ module.exports = function parseuri(str) {
+ var m = re.exec(str || '')
+ , uri = {}
+ , i = 14;
+
+ while (i--) {
+ uri[parts[i]] = m[i] || '';
+ }
+
+ return uri;
+ };
+
+},{}],45:[function(_dereq_,module,exports){
+ (function (global){
+ /*global Blob,File*/
+
+ /**
+ * Module requirements
+ */
+
+ var isArray = _dereq_('isarray');
+ var isBuf = _dereq_('./is-buffer');
+
+ /**
+ * Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder.
+ * Anything with blobs or files should be fed through removeBlobs before coming
+ * here.
+ *
+ * @param {Object} packet - socket.io event packet
+ * @return {Object} with deconstructed packet and list of buffers
+ * @api public
+ */
+
+ exports.deconstructPacket = function(packet){
+ var buffers = [];
+ var packetData = packet.data;
+
+ function _deconstructPacket(data) {
+ if (!data) return data;
+
+ if (isBuf(data)) {
+ var placeholder = { _placeholder: true, num: buffers.length };
+ buffers.push(data);
+ return placeholder;
+ } else if (isArray(data)) {
+ var newData = new Array(data.length);
+ for (var i = 0; i < data.length; i++) {
+ newData[i] = _deconstructPacket(data[i]);
+ }
+ return newData;
+ } else if ('object' == typeof data && !(data instanceof Date)) {
+ var newData = {};
+ for (var key in data) {
+ newData[key] = _deconstructPacket(data[key]);
+ }
+ return newData;
+ }
+ return data;
+ }
+
+ var pack = packet;
+ pack.data = _deconstructPacket(packetData);
+ pack.attachments = buffers.length; // number of binary 'attachments'
+ return {packet: pack, buffers: buffers};
+ };
+
+ /**
+ * Reconstructs a binary packet from its placeholder packet and buffers
+ *
+ * @param {Object} packet - event packet with placeholders
+ * @param {Array} buffers - binary buffers to put in placeholder positions
+ * @return {Object} reconstructed packet
+ * @api public
+ */
+
+ exports.reconstructPacket = function(packet, buffers) {
+ var curPlaceHolder = 0;
+
+ function _reconstructPacket(data) {
+ if (data && data._placeholder) {
+ var buf = buffers[data.num]; // appropriate buffer (should be natural order anyway)
+ return buf;
+ } else if (isArray(data)) {
+ for (var i = 0; i < data.length; i++) {
+ data[i] = _reconstructPacket(data[i]);
+ }
+ return data;
+ } else if (data && 'object' == typeof data) {
+ for (var key in data) {
+ data[key] = _reconstructPacket(data[key]);
+ }
+ return data;
+ }
+ return data;
+ }
+
+ packet.data = _reconstructPacket(packet.data);
+ packet.attachments = undefined; // no longer useful
+ return packet;
+ };
+
+ /**
+ * Asynchronously removes Blobs or Files from data via
+ * FileReader's readAsArrayBuffer method. Used before encoding
+ * data as msgpack. Calls callback with the blobless data.
+ *
+ * @param {Object} data
+ * @param {Function} callback
+ * @api private
+ */
+
+ exports.removeBlobs = function(data, callback) {
+ function _removeBlobs(obj, curKey, containingObject) {
+ if (!obj) return obj;
+
+ // convert any blob
+ if ((global.Blob && obj instanceof Blob) ||
+ (global.File && obj instanceof File)) {
+ pendingBlobs++;
+
+ // async filereader
+ var fileReader = new FileReader();
+ fileReader.onload = function() { // this.result == arraybuffer
+ if (containingObject) {
+ containingObject[curKey] = this.result;
+ }
+ else {
+ bloblessData = this.result;
+ }
+
+ // if nothing pending its callback time
+ if(! --pendingBlobs) {
+ callback(bloblessData);
+ }
+ };
+
+ fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer
+ } else if (isArray(obj)) { // handle array
+ for (var i = 0; i < obj.length; i++) {
+ _removeBlobs(obj[i], i, obj);
+ }
+ } else if (obj && 'object' == typeof obj && !isBuf(obj)) { // and object
+ for (var key in obj) {
+ _removeBlobs(obj[key], key, obj);
+ }
+ }
+ }
+
+ var pendingBlobs = 0;
+ var bloblessData = data;
+ _removeBlobs(bloblessData);
+ if (!pendingBlobs) {
+ callback(bloblessData);
+ }
+ };
+
+ }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"./is-buffer":47,"isarray":48}],46:[function(_dereq_,module,exports){
+
+ /**
+ * Module dependencies.
+ */
+
+ var debug = _dereq_('debug')('socket.io-parser');
+ var json = _dereq_('json3');
+ var isArray = _dereq_('isarray');
+ var Emitter = _dereq_('component-emitter');
+ var binary = _dereq_('./binary');
+ var isBuf = _dereq_('./is-buffer');
+
+ /**
+ * Protocol version.
+ *
+ * @api public
+ */
+
+ exports.protocol = 4;
+
+ /**
+ * Packet types.
+ *
+ * @api public
+ */
+
+ exports.types = [
+ 'CONNECT',
+ 'DISCONNECT',
+ 'EVENT',
+ 'BINARY_EVENT',
+ 'ACK',
+ 'BINARY_ACK',
+ 'ERROR'
+ ];
+
+ /**
+ * Packet type `connect`.
+ *
+ * @api public
+ */
+
+ exports.CONNECT = 0;
+
+ /**
+ * Packet type `disconnect`.
+ *
+ * @api public
+ */
+
+ exports.DISCONNECT = 1;
+
+ /**
+ * Packet type `event`.
+ *
+ * @api public
+ */
+
+ exports.EVENT = 2;
+
+ /**
+ * Packet type `ack`.
+ *
+ * @api public
+ */
+
+ exports.ACK = 3;
+
+ /**
+ * Packet type `error`.
+ *
+ * @api public
+ */
+
+ exports.ERROR = 4;
+
+ /**
+ * Packet type 'binary event'
+ *
+ * @api public
+ */
+
+ exports.BINARY_EVENT = 5;
+
+ /**
+ * Packet type `binary ack`. For acks with binary arguments.
+ *
+ * @api public
+ */
+
+ exports.BINARY_ACK = 6;
+
+ /**
+ * Encoder constructor.
+ *
+ * @api public
+ */
+
+ exports.Encoder = Encoder;
+
+ /**
+ * Decoder constructor.
+ *
+ * @api public
+ */
+
+ exports.Decoder = Decoder;
+
+ /**
+ * A socket.io Encoder instance
+ *
+ * @api public
+ */
+
+ function Encoder() {}
+
+ /**
+ * Encode a packet as a single string if non-binary, or as a
+ * buffer sequence, depending on packet type.
+ *
+ * @param {Object} obj - packet object
+ * @param {Function} callback - function to handle encodings (likely engine.write)
+ * @return Calls callback with Array of encodings
+ * @api public
+ */
+
+ Encoder.prototype.encode = function(obj, callback){
+ debug('encoding packet %j', obj);
+
+ if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {
+ encodeAsBinary(obj, callback);
+ }
+ else {
+ var encoding = encodeAsString(obj);
+ callback([encoding]);
+ }
+ };
+
+ /**
+ * Encode packet as string.
+ *
+ * @param {Object} packet
+ * @return {String} encoded
+ * @api private
+ */
+
+ function encodeAsString(obj) {
+ var str = '';
+ var nsp = false;
+
+ // first is type
+ str += obj.type;
+
+ // attachments if we have them
+ if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {
+ str += obj.attachments;
+ str += '-';
+ }
+
+ // if we have a namespace other than `/`
+ // we append it followed by a comma `,`
+ if (obj.nsp && '/' != obj.nsp) {
+ nsp = true;
+ str += obj.nsp;
+ }
+
+ // immediately followed by the id
+ if (null != obj.id) {
+ if (nsp) {
+ str += ',';
+ nsp = false;
+ }
+ str += obj.id;
+ }
+
+ // json data
+ if (null != obj.data) {
+ if (nsp) str += ',';
+ str += json.stringify(obj.data);
+ }
+
+ debug('encoded %j as %s', obj, str);
+ return str;
+ }
+
+ /**
+ * Encode packet as 'buffer sequence' by removing blobs, and
+ * deconstructing packet into object with placeholders and
+ * a list of buffers.
+ *
+ * @param {Object} packet
+ * @return {Buffer} encoded
+ * @api private
+ */
+
+ function encodeAsBinary(obj, callback) {
+
+ function writeEncoding(bloblessData) {
+ var deconstruction = binary.deconstructPacket(bloblessData);
+ var pack = encodeAsString(deconstruction.packet);
+ var buffers = deconstruction.buffers;
+
+ buffers.unshift(pack); // add packet info to beginning of data list
+ callback(buffers); // write all the buffers
+ }
+
+ binary.removeBlobs(obj, writeEncoding);
+ }
+
+ /**
+ * A socket.io Decoder instance
+ *
+ * @return {Object} decoder
+ * @api public
+ */
+
+ function Decoder() {
+ this.reconstructor = null;
+ }
+
+ /**
+ * Mix in `Emitter` with Decoder.
+ */
+
+ Emitter(Decoder.prototype);
+
+ /**
+ * Decodes an ecoded packet string into packet JSON.
+ *
+ * @param {String} obj - encoded packet
+ * @return {Object} packet
+ * @api public
+ */
+
+ Decoder.prototype.add = function(obj) {
+ var packet;
+ if ('string' == typeof obj) {
+ packet = decodeString(obj);
+ if (exports.BINARY_EVENT == packet.type || exports.BINARY_ACK == packet.type) { // binary packet's json
+ this.reconstructor = new BinaryReconstructor(packet);
+
+ // no attachments, labeled binary but no binary data to follow
+ if (this.reconstructor.reconPack.attachments === 0) {
+ this.emit('decoded', packet);
+ }
+ } else { // non-binary full packet
+ this.emit('decoded', packet);
+ }
+ }
+ else if (isBuf(obj) || obj.base64) { // raw binary data
+ if (!this.reconstructor) {
+ throw new Error('got binary data when not reconstructing a packet');
+ } else {
+ packet = this.reconstructor.takeBinaryData(obj);
+ if (packet) { // received final buffer
+ this.reconstructor = null;
+ this.emit('decoded', packet);
+ }
+ }
+ }
+ else {
+ throw new Error('Unknown type: ' + obj);
+ }
+ };
+
+ /**
+ * Decode a packet String (JSON data)
+ *
+ * @param {String} str
+ * @return {Object} packet
+ * @api private
+ */
+
+ function decodeString(str) {
+ var p = {};
+ var i = 0;
+
+ // look up type
+ p.type = Number(str.charAt(0));
+ if (null == exports.types[p.type]) return error();
+
+ // look up attachments if type binary
+ if (exports.BINARY_EVENT == p.type || exports.BINARY_ACK == p.type) {
+ var buf = '';
+ while (str.charAt(++i) != '-') {
+ buf += str.charAt(i);
+ if (i == str.length) break;
+ }
+ if (buf != Number(buf) || str.charAt(i) != '-') {
+ throw new Error('Illegal attachments');
+ }
+ p.attachments = Number(buf);
+ }
+
+ // look up namespace (if any)
+ if ('/' == str.charAt(i + 1)) {
+ p.nsp = '';
+ while (++i) {
+ var c = str.charAt(i);
+ if (',' == c) break;
+ p.nsp += c;
+ if (i == str.length) break;
+ }
+ } else {
+ p.nsp = '/';
+ }
+
+ // look up id
+ var next = str.charAt(i + 1);
+ if ('' !== next && Number(next) == next) {
+ p.id = '';
+ while (++i) {
+ var c = str.charAt(i);
+ if (null == c || Number(c) != c) {
+ --i;
+ break;
+ }
+ p.id += str.charAt(i);
+ if (i == str.length) break;
+ }
+ p.id = Number(p.id);
+ }
+
+ // look up json data
+ if (str.charAt(++i)) {
+ try {
+ p.data = json.parse(str.substr(i));
+ } catch(e){
+ return error();
+ }
+ }
+
+ debug('decoded %s as %j', str, p);
+ return p;
+ }
+
+ /**
+ * Deallocates a parser's resources
+ *
+ * @api public
+ */
+
+ Decoder.prototype.destroy = function() {
+ if (this.reconstructor) {
+ this.reconstructor.finishedReconstruction();
+ }
+ };
+
+ /**
+ * A manager of a binary event's 'buffer sequence'. Should
+ * be constructed whenever a packet of type BINARY_EVENT is
+ * decoded.
+ *
+ * @param {Object} packet
+ * @return {BinaryReconstructor} initialized reconstructor
+ * @api private
+ */
+
+ function BinaryReconstructor(packet) {
+ this.reconPack = packet;
+ this.buffers = [];
+ }
+
+ /**
+ * Method to be called when binary data received from connection
+ * after a BINARY_EVENT packet.
+ *
+ * @param {Buffer | ArrayBuffer} binData - the raw binary data received
+ * @return {null | Object} returns null if more binary data is expected or
+ * a reconstructed packet object if all buffers have been received.
+ * @api private
+ */
+
+ BinaryReconstructor.prototype.takeBinaryData = function(binData) {
+ this.buffers.push(binData);
+ if (this.buffers.length == this.reconPack.attachments) { // done with buffer list
+ var packet = binary.reconstructPacket(this.reconPack, this.buffers);
+ this.finishedReconstruction();
+ return packet;
+ }
+ return null;
+ };
+
+ /**
+ * Cleans up binary packet reconstruction variables.
+ *
+ * @api private
+ */
+
+ BinaryReconstructor.prototype.finishedReconstruction = function() {
+ this.reconPack = null;
+ this.buffers = [];
+ };
+
+ function error(data){
+ return {
+ type: exports.ERROR,
+ data: 'parser error'
+ };
+ }
+
+},{"./binary":45,"./is-buffer":47,"component-emitter":9,"debug":10,"isarray":48,"json3":49}],47:[function(_dereq_,module,exports){
+ (function (global){
+
+ module.exports = isBuf;
+
+ /**
+ * Returns true if obj is a buffer or an arraybuffer.
+ *
+ * @api private
+ */
+
+ function isBuf(obj) {
+ return (global.Buffer && global.Buffer.isBuffer(obj)) ||
+ (global.ArrayBuffer && obj instanceof ArrayBuffer);
+ }
+
+ }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],48:[function(_dereq_,module,exports){
+ module.exports=_dereq_(32)
+},{}],49:[function(_dereq_,module,exports){
+ /*! JSON v3.2.6 | http://bestiejs.github.io/json3 | Copyright 2012-2013, Kit Cambridge | http://kit.mit-license.org */
+ ;(function (window) {
+ // Convenience aliases.
+ var getClass = {}.toString, isProperty, forEach, undef;
+
+ // Detect the `define` function exposed by asynchronous module loaders. The
+ // strict `define` check is necessary for compatibility with `r.js`.
+ var isLoader = typeof define === "function" && define.amd;
+
+ // Detect native implementations.
+ var nativeJSON = typeof JSON == "object" && JSON;
+
+ // Set up the JSON 3 namespace, preferring the CommonJS `exports` object if
+ // available.
+ var JSON3 = typeof exports == "object" && exports && !exports.nodeType && exports;
+
+ if (JSON3 && nativeJSON) {
+ // Explicitly delegate to the native `stringify` and `parse`
+ // implementations in CommonJS environments.
+ JSON3.stringify = nativeJSON.stringify;
+ JSON3.parse = nativeJSON.parse;
+ } else {
+ // Export for web browsers, JavaScript engines, and asynchronous module
+ // loaders, using the global `JSON` object if available.
+ JSON3 = window.JSON = nativeJSON || {};
+ }
+
+ // Test the `Date#getUTC*` methods. Based on work by @Yaffle.
+ var isExtended = new Date(-3509827334573292);
+ try {
+ // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical
+ // results for certain dates in Opera >= 10.53.
+ isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 &&
+ // Safari < 2.0.2 stores the internal millisecond time value correctly,
+ // but clips the values returned by the date methods to the range of
+ // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).
+ isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;
+ } catch (exception) {}
+
+ // Internal: Determines whether the native `JSON.stringify` and `parse`
+ // implementations are spec-compliant. Based on work by Ken Snyder.
+ function has(name) {
+ if (has[name] !== undef) {
+ // Return cached feature test result.
+ return has[name];
+ }
+
+ var isSupported;
+ if (name == "bug-string-char-index") {
+ // IE <= 7 doesn't support accessing string characters using square
+ // bracket notation. IE 8 only supports this for primitives.
+ isSupported = "a"[0] != "a";
+ } else if (name == "json") {
+ // Indicates whether both `JSON.stringify` and `JSON.parse` are
+ // supported.
+ isSupported = has("json-stringify") && has("json-parse");
+ } else {
+ var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';
+ // Test `JSON.stringify`.
+ if (name == "json-stringify") {
+ var stringify = JSON3.stringify, stringifySupported = typeof stringify == "function" && isExtended;
+ if (stringifySupported) {
+ // A test function object with a custom `toJSON` method.
+ (value = function () {
+ return 1;
+ }).toJSON = value;
+ try {
+ stringifySupported =
+ // Firefox 3.1b1 and b2 serialize string, number, and boolean
+ // primitives as object literals.
+ stringify(0) === "0" &&
+ // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object
+ // literals.
+ stringify(new Number()) === "0" &&
+ stringify(new String()) == '""' &&
+ // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or
+ // does not define a canonical JSON representation (this applies to
+ // objects with `toJSON` properties as well, *unless* they are nested
+ // within an object or array).
+ stringify(getClass) === undef &&
+ // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and
+ // FF 3.1b3 pass this test.
+ stringify(undef) === undef &&
+ // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,
+ // respectively, if the value is omitted entirely.
+ stringify() === undef &&
+ // FF 3.1b1, 2 throw an error if the given value is not a number,
+ // string, array, object, Boolean, or `null` literal. This applies to
+ // objects with custom `toJSON` methods as well, unless they are nested
+ // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`
+ // methods entirely.
+ stringify(value) === "1" &&
+ stringify([value]) == "[1]" &&
+ // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of
+ // `"[null]"`.
+ stringify([undef]) == "[null]" &&
+ // YUI 3.0.0b1 fails to serialize `null` literals.
+ stringify(null) == "null" &&
+ // FF 3.1b1, 2 halts serialization if an array contains a function:
+ // `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3
+ // elides non-JSON values from objects and arrays, unless they
+ // define custom `toJSON` methods.
+ stringify([undef, getClass, null]) == "[null,null,null]" &&
+ // Simple serialization test. FF 3.1b1 uses Unicode escape sequences
+ // where character escape codes are expected (e.g., `\b` => `\u0008`).
+ stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized &&
+ // FF 3.1b1 and b2 ignore the `filter` and `width` arguments.
+ stringify(null, value) === "1" &&
+ stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" &&
+ // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly
+ // serialize extended years.
+ stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' &&
+ // The milliseconds are optional in ES 5, but required in 5.1.
+ stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' &&
+ // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative
+ // four-digit years instead of six-digit years. Credits: @Yaffle.
+ stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' &&
+ // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond
+ // values less than 1000. Credits: @Yaffle.
+ stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"';
+ } catch (exception) {
+ stringifySupported = false;
+ }
+ }
+ isSupported = stringifySupported;
+ }
+ // Test `JSON.parse`.
+ if (name == "json-parse") {
+ var parse = JSON3.parse;
+ if (typeof parse == "function") {
+ try {
+ // FF 3.1b1, b2 will throw an exception if a bare literal is provided.
+ // Conforming implementations should also coerce the initial argument to
+ // a string prior to parsing.
+ if (parse("0") === 0 && !parse(false)) {
+ // Simple parsing test.
+ value = parse(serialized);
+ var parseSupported = value["a"].length == 5 && value["a"][0] === 1;
+ if (parseSupported) {
+ try {
+ // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.
+ parseSupported = !parse('"\t"');
+ } catch (exception) {}
+ if (parseSupported) {
+ try {
+ // FF 4.0 and 4.0.1 allow leading `+` signs and leading
+ // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow
+ // certain octal literals.
+ parseSupported = parse("01") !== 1;
+ } catch (exception) {}
+ }
+ if (parseSupported) {
+ try {
+ // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal
+ // points. These environments, along with FF 3.1b1 and 2,
+ // also allow trailing commas in JSON objects and arrays.
+ parseSupported = parse("1.") !== 1;
+ } catch (exception) {}
+ }
+ }
+ }
+ } catch (exception) {
+ parseSupported = false;
+ }
+ }
+ isSupported = parseSupported;
+ }
+ }
+ return has[name] = !!isSupported;
+ }
+
+ if (!has("json")) {
+ // Common `[[Class]]` name aliases.
+ var functionClass = "[object Function]";
+ var dateClass = "[object Date]";
+ var numberClass = "[object Number]";
+ var stringClass = "[object String]";
+ var arrayClass = "[object Array]";
+ var booleanClass = "[object Boolean]";
+
+ // Detect incomplete support for accessing string characters by index.
+ var charIndexBuggy = has("bug-string-char-index");
+
+ // Define additional utility methods if the `Date` methods are buggy.
+ if (!isExtended) {
+ var floor = Math.floor;
+ // A mapping between the months of the year and the number of days between
+ // January 1st and the first of the respective month.
+ var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
+ // Internal: Calculates the number of days between the Unix epoch and the
+ // first day of the given month.
+ var getDay = function (year, month) {
+ return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);
+ };
+ }
+
+ // Internal: Determines if a property is a direct property of the given
+ // object. Delegates to the native `Object#hasOwnProperty` method.
+ if (!(isProperty = {}.hasOwnProperty)) {
+ isProperty = function (property) {
+ var members = {}, constructor;
+ if ((members.__proto__ = null, members.__proto__ = {
+ // The *proto* property cannot be set multiple times in recent
+ // versions of Firefox and SeaMonkey.
+ "toString": 1
+ }, members).toString != getClass) {
+ // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but
+ // supports the mutable *proto* property.
+ isProperty = function (property) {
+ // Capture and break the object's prototype chain (see section 8.6.2
+ // of the ES 5.1 spec). The parenthesized expression prevents an
+ // unsafe transformation by the Closure Compiler.
+ var original = this.__proto__, result = property in (this.__proto__ = null, this);
+ // Restore the original prototype chain.
+ this.__proto__ = original;
+ return result;
+ };
+ } else {
+ // Capture a reference to the top-level `Object` constructor.
+ constructor = members.constructor;
+ // Use the `constructor` property to simulate `Object#hasOwnProperty` in
+ // other environments.
+ isProperty = function (property) {
+ var parent = (this.constructor || constructor).prototype;
+ return property in this && !(property in parent && this[property] === parent[property]);
+ };
+ }
+ members = null;
+ return isProperty.call(this, property);
+ };
+ }
+
+ // Internal: A set of primitive types used by `isHostType`.
+ var PrimitiveTypes = {
+ 'boolean': 1,
+ 'number': 1,
+ 'string': 1,
+ 'undefined': 1
+ };
+
+ // Internal: Determines if the given object `property` value is a
+ // non-primitive.
+ var isHostType = function (object, property) {
+ var type = typeof object[property];
+ return type == 'object' ? !!object[property] : !PrimitiveTypes[type];
+ };
+
+ // Internal: Normalizes the `for...in` iteration algorithm across
+ // environments. Each enumerated key is yielded to a `callback` function.
+ forEach = function (object, callback) {
+ var size = 0, Properties, members, property;
+
+ // Tests for bugs in the current environment's `for...in` algorithm. The
+ // `valueOf` property inherits the non-enumerable flag from
+ // `Object.prototype` in older versions of IE, Netscape, and Mozilla.
+ (Properties = function () {
+ this.valueOf = 0;
+ }).prototype.valueOf = 0;
+
+ // Iterate over a new instance of the `Properties` class.
+ members = new Properties();
+ for (property in members) {
+ // Ignore all properties inherited from `Object.prototype`.
+ if (isProperty.call(members, property)) {
+ size++;
+ }
+ }
+ Properties = members = null;
+
+ // Normalize the iteration algorithm.
+ if (!size) {
+ // A list of non-enumerable properties inherited from `Object.prototype`.
+ members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"];
+ // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable
+ // properties.
+ forEach = function (object, callback) {
+ var isFunction = getClass.call(object) == functionClass, property, length;
+ var hasProperty = !isFunction && typeof object.constructor != 'function' && isHostType(object, 'hasOwnProperty') ? object.hasOwnProperty : isProperty;
+ for (property in object) {
+ // Gecko <= 1.0 enumerates the `prototype` property of functions under
+ // certain conditions; IE does not.
+ if (!(isFunction && property == "prototype") && hasProperty.call(object, property)) {
+ callback(property);
+ }
+ }
+ // Manually invoke the callback for each non-enumerable property.
+ for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property));
+ };
+ } else if (size == 2) {
+ // Safari <= 2.0.4 enumerates shadowed properties twice.
+ forEach = function (object, callback) {
+ // Create a set of iterated properties.
+ var members = {}, isFunction = getClass.call(object) == functionClass, property;
+ for (property in object) {
+ // Store each property name to prevent double enumeration. The
+ // `prototype` property of functions is not enumerated due to cross-
+ // environment inconsistencies.
+ if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {
+ callback(property);
+ }
+ }
+ };
+ } else {
+ // No bugs detected; use the standard `for...in` algorithm.
+ forEach = function (object, callback) {
+ var isFunction = getClass.call(object) == functionClass, property, isConstructor;
+ for (property in object) {
+ if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) {
+ callback(property);
+ }
+ }
+ // Manually invoke the callback for the `constructor` property due to
+ // cross-environment inconsistencies.
+ if (isConstructor || isProperty.call(object, (property = "constructor"))) {
+ callback(property);
+ }
+ };
+ }
+ return forEach(object, callback);
+ };
+
+ // Public: Serializes a JavaScript `value` as a JSON string. The optional
+ // `filter` argument may specify either a function that alters how object and
+ // array members are serialized, or an array of strings and numbers that
+ // indicates which properties should be serialized. The optional `width`
+ // argument may be either a string or number that specifies the indentation
+ // level of the output.
+ if (!has("json-stringify")) {
+ // Internal: A map of control characters and their escaped equivalents.
+ var Escapes = {
+ 92: "\\\\",
+ 34: '\\"',
+ 8: "\\b",
+ 12: "\\f",
+ 10: "\\n",
+ 13: "\\r",
+ 9: "\\t"
+ };
+
+ // Internal: Converts `value` into a zero-padded string such that its
+ // length is at least equal to `width`. The `width` must be <= 6.
+ var leadingZeroes = "000000";
+ var toPaddedString = function (width, value) {
+ // The `|| 0` expression is necessary to work around a bug in
+ // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`.
+ return (leadingZeroes + (value || 0)).slice(-width);
+ };
+
+ // Internal: Double-quotes a string `value`, replacing all ASCII control
+ // characters (characters with code unit values between 0 and 31) with
+ // their escaped equivalents. This is an implementation of the
+ // `Quote(value)` operation defined in ES 5.1 section 15.12.3.
+ var unicodePrefix = "\\u00";
+ var quote = function (value) {
+ var result = '"', index = 0, length = value.length, isLarge = length > 10 && charIndexBuggy, symbols;
+ if (isLarge) {
+ symbols = value.split("");
+ }
+ for (; index < length; index++) {
+ var charCode = value.charCodeAt(index);
+ // If the character is a control character, append its Unicode or
+ // shorthand escape sequence; otherwise, append the character as-is.
+ switch (charCode) {
+ case 8: case 9: case 10: case 12: case 13: case 34: case 92:
+ result += Escapes[charCode];
+ break;
+ default:
+ if (charCode < 32) {
+ result += unicodePrefix + toPaddedString(2, charCode.toString(16));
+ break;
+ }
+ result += isLarge ? symbols[index] : charIndexBuggy ? value.charAt(index) : value[index];
+ }
+ }
+ return result + '"';
+ };
+
+ // Internal: Recursively serializes an object. Implements the
+ // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.
+ var serialize = function (property, object, callback, properties, whitespace, indentation, stack) {
+ var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result;
+ try {
+ // Necessary for host object support.
+ value = object[property];
+ } catch (exception) {}
+ if (typeof value == "object" && value) {
+ className = getClass.call(value);
+ if (className == dateClass && !isProperty.call(value, "toJSON")) {
+ if (value > -1 / 0 && value < 1 / 0) {
+ // Dates are serialized according to the `Date#toJSON` method
+ // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15
+ // for the ISO 8601 date time string format.
+ if (getDay) {
+ // Manually compute the year, month, date, hours, minutes,
+ // seconds, and milliseconds if the `getUTC*` methods are
+ // buggy. Adapted from @Yaffle's `date-shim` project.
+ date = floor(value / 864e5);
+ for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);
+ for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);
+ date = 1 + date - getDay(year, month);
+ // The `time` value specifies the time within the day (see ES
+ // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used
+ // to compute `A modulo B`, as the `%` operator does not
+ // correspond to the `modulo` operation for negative numbers.
+ time = (value % 864e5 + 864e5) % 864e5;
+ // The hours, minutes, seconds, and milliseconds are obtained by
+ // decomposing the time within the day. See section 15.9.1.10.
+ hours = floor(time / 36e5) % 24;
+ minutes = floor(time / 6e4) % 60;
+ seconds = floor(time / 1e3) % 60;
+ milliseconds = time % 1e3;
+ } else {
+ year = value.getUTCFullYear();
+ month = value.getUTCMonth();
+ date = value.getUTCDate();
+ hours = value.getUTCHours();
+ minutes = value.getUTCMinutes();
+ seconds = value.getUTCSeconds();
+ milliseconds = value.getUTCMilliseconds();
+ }
+ // Serialize extended years correctly.
+ value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +
+ "-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) +
+ // Months, dates, hours, minutes, and seconds should have two
+ // digits; milliseconds should have three.
+ "T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) +
+ // Milliseconds are optional in ES 5.0, but required in 5.1.
+ "." + toPaddedString(3, milliseconds) + "Z";
+ } else {
+ value = null;
+ }
+ } else if (typeof value.toJSON == "function" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, "toJSON"))) {
+ // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the
+ // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3
+ // ignores all `toJSON` methods on these objects unless they are
+ // defined directly on an instance.
+ value = value.toJSON(property);
+ }
+ }
+ if (callback) {
+ // If a replacement function was provided, call it to obtain the value
+ // for serialization.
+ value = callback.call(object, property, value);
+ }
+ if (value === null) {
+ return "null";
+ }
+ className = getClass.call(value);
+ if (className == booleanClass) {
+ // Booleans are represented literally.
+ return "" + value;
+ } else if (className == numberClass) {
+ // JSON numbers must be finite. `Infinity` and `NaN` are serialized as
+ // `"null"`.
+ return value > -1 / 0 && value < 1 / 0 ? "" + value : "null";
+ } else if (className == stringClass) {
+ // Strings are double-quoted and escaped.
+ return quote("" + value);
+ }
+ // Recursively serialize objects and arrays.
+ if (typeof value == "object") {
+ // Check for cyclic structures. This is a linear search; performance
+ // is inversely proportional to the number of unique nested objects.
+ for (length = stack.length; length--;) {
+ if (stack[length] === value) {
+ // Cyclic structures cannot be serialized by `JSON.stringify`.
+ throw TypeError();
+ }
+ }
+ // Add the object to the stack of traversed objects.
+ stack.push(value);
+ results = [];
+ // Save the current indentation level and indent one additional level.
+ prefix = indentation;
+ indentation += whitespace;
+ if (className == arrayClass) {
+ // Recursively serialize array elements.
+ for (index = 0, length = value.length; index < length; index++) {
+ element = serialize(index, value, callback, properties, whitespace, indentation, stack);
+ results.push(element === undef ? "null" : element);
+ }
+ result = results.length ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]";
+ } else {
+ // Recursively serialize object members. Members are selected from
+ // either a user-specified list of property names, or the object
+ // itself.
+ forEach(properties || value, function (property) {
+ var element = serialize(property, value, callback, properties, whitespace, indentation, stack);
+ if (element !== undef) {
+ // According to ES 5.1 section 15.12.3: "If `gap` {whitespace}
+ // is not the empty string, let `member` {quote(property) + ":"}
+ // be the concatenation of `member` and the `space` character."
+ // The "`space` character" refers to the literal space
+ // character, not the `space` {width} argument provided to
+ // `JSON.stringify`.
+ results.push(quote(property) + ":" + (whitespace ? " " : "") + element);
+ }
+ });
+ result = results.length ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}";
+ }
+ // Remove the object from the traversed object stack.
+ stack.pop();
+ return result;
+ }
+ };
+
+ // Public: `JSON.stringify`. See ES 5.1 section 15.12.3.
+ JSON3.stringify = function (source, filter, width) {
+ var whitespace, callback, properties, className;
+ if (typeof filter == "function" || typeof filter == "object" && filter) {
+ if ((className = getClass.call(filter)) == functionClass) {
+ callback = filter;
+ } else if (className == arrayClass) {
+ // Convert the property names array into a makeshift set.
+ properties = {};
+ for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1));
+ }
+ }
+ if (width) {
+ if ((className = getClass.call(width)) == numberClass) {
+ // Convert the `width` to an integer and create a string containing
+ // `width` number of space characters.
+ if ((width -= width % 1) > 0) {
+ for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " ");
+ }
+ } else if (className == stringClass) {
+ whitespace = width.length <= 10 ? width : width.slice(0, 10);
+ }
+ }
+ // Opera <= 7.54u2 discards the values associated with empty string keys
+ // (`""`) only if they are used directly within an object member list
+ // (e.g., `!("" in { "": 1})`).
+ return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []);
+ };
+ }
+
+ // Public: Parses a JSON source string.
+ if (!has("json-parse")) {
+ var fromCharCode = String.fromCharCode;
+
+ // Internal: A map of escaped control characters and their unescaped
+ // equivalents.
+ var Unescapes = {
+ 92: "\\",
+ 34: '"',
+ 47: "/",
+ 98: "\b",
+ 116: "\t",
+ 110: "\n",
+ 102: "\f",
+ 114: "\r"
+ };
+
+ // Internal: Stores the parser state.
+ var Index, Source;
+
+ // Internal: Resets the parser state and throws a `SyntaxError`.
+ var abort = function() {
+ Index = Source = null;
+ throw SyntaxError();
+ };
+
+ // Internal: Returns the next token, or `"$"` if the parser has reached
+ // the end of the source string. A token may be a string, number, `null`
+ // literal, or Boolean literal.
+ var lex = function () {
+ var source = Source, length = source.length, value, begin, position, isSigned, charCode;
+ while (Index < length) {
+ charCode = source.charCodeAt(Index);
+ switch (charCode) {
+ case 9: case 10: case 13: case 32:
+ // Skip whitespace tokens, including tabs, carriage returns, line
+ // feeds, and space characters.
+ Index++;
+ break;
+ case 123: case 125: case 91: case 93: case 58: case 44:
+ // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at
+ // the current position.
+ value = charIndexBuggy ? source.charAt(Index) : source[Index];
+ Index++;
+ return value;
+ case 34:
+ // `"` delimits a JSON string; advance to the next character and
+ // begin parsing the string. String tokens are prefixed with the
+ // sentinel `@` character to distinguish them from punctuators and
+ // end-of-string tokens.
+ for (value = "@", Index++; Index < length;) {
+ charCode = source.charCodeAt(Index);
+ if (charCode < 32) {
+ // Unescaped ASCII control characters (those with a code unit
+ // less than the space character) are not permitted.
+ abort();
+ } else if (charCode == 92) {
+ // A reverse solidus (`\`) marks the beginning of an escaped
+ // control character (including `"`, `\`, and `/`) or Unicode
+ // escape sequence.
+ charCode = source.charCodeAt(++Index);
+ switch (charCode) {
+ case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114:
+ // Revive escaped control characters.
+ value += Unescapes[charCode];
+ Index++;
+ break;
+ case 117:
+ // `\u` marks the beginning of a Unicode escape sequence.
+ // Advance to the first character and validate the
+ // four-digit code point.
+ begin = ++Index;
+ for (position = Index + 4; Index < position; Index++) {
+ charCode = source.charCodeAt(Index);
+ // A valid sequence comprises four hexdigits (case-
+ // insensitive) that form a single hexadecimal value.
+ if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) {
+ // Invalid Unicode escape sequence.
+ abort();
+ }
+ }
+ // Revive the escaped character.
+ value += fromCharCode("0x" + source.slice(begin, Index));
+ break;
+ default:
+ // Invalid escape sequence.
+ abort();
+ }
+ } else {
+ if (charCode == 34) {
+ // An unescaped double-quote character marks the end of the
+ // string.
+ break;
+ }
+ charCode = source.charCodeAt(Index);
+ begin = Index;
+ // Optimize for the common case where a string is valid.
+ while (charCode >= 32 && charCode != 92 && charCode != 34) {
+ charCode = source.charCodeAt(++Index);
+ }
+ // Append the string as-is.
+ value += source.slice(begin, Index);
+ }
+ }
+ if (source.charCodeAt(Index) == 34) {
+ // Advance to the next character and return the revived string.
+ Index++;
+ return value;
+ }
+ // Unterminated string.
+ abort();
+ default:
+ // Parse numbers and literals.
+ begin = Index;
+ // Advance past the negative sign, if one is specified.
+ if (charCode == 45) {
+ isSigned = true;
+ charCode = source.charCodeAt(++Index);
+ }
+ // Parse an integer or floating-point value.
+ if (charCode >= 48 && charCode <= 57) {
+ // Leading zeroes are interpreted as octal literals.
+ if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) {
+ // Illegal octal literal.
+ abort();
+ }
+ isSigned = false;
+ // Parse the integer component.
+ for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++);
+ // Floats cannot contain a leading decimal point; however, this
+ // case is already accounted for by the parser.
+ if (source.charCodeAt(Index) == 46) {
+ position = ++Index;
+ // Parse the decimal component.
+ for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);
+ if (position == Index) {
+ // Illegal trailing decimal.
+ abort();
+ }
+ Index = position;
+ }
+ // Parse exponents. The `e` denoting the exponent is
+ // case-insensitive.
+ charCode = source.charCodeAt(Index);
+ if (charCode == 101 || charCode == 69) {
+ charCode = source.charCodeAt(++Index);
+ // Skip past the sign following the exponent, if one is
+ // specified.
+ if (charCode == 43 || charCode == 45) {
+ Index++;
+ }
+ // Parse the exponential component.
+ for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);
+ if (position == Index) {
+ // Illegal empty exponent.
+ abort();
+ }
+ Index = position;
+ }
+ // Coerce the parsed value to a JavaScript number.
+ return +source.slice(begin, Index);
+ }
+ // A negative sign may only precede numbers.
+ if (isSigned) {
+ abort();
+ }
+ // `true`, `false`, and `null` literals.
+ if (source.slice(Index, Index + 4) == "true") {
+ Index += 4;
+ return true;
+ } else if (source.slice(Index, Index + 5) == "false") {
+ Index += 5;
+ return false;
+ } else if (source.slice(Index, Index + 4) == "null") {
+ Index += 4;
+ return null;
+ }
+ // Unrecognized token.
+ abort();
+ }
+ }
+ // Return the sentinel `$` character if the parser has reached the end
+ // of the source string.
+ return "$";
+ };
+
+ // Internal: Parses a JSON `value` token.
+ var get = function (value) {
+ var results, hasMembers;
+ if (value == "$") {
+ // Unexpected end of input.
+ abort();
+ }
+ if (typeof value == "string") {
+ if ((charIndexBuggy ? value.charAt(0) : value[0]) == "@") {
+ // Remove the sentinel `@` character.
+ return value.slice(1);
+ }
+ // Parse object and array literals.
+ if (value == "[") {
+ // Parses a JSON array, returning a new JavaScript array.
+ results = [];
+ for (;; hasMembers || (hasMembers = true)) {
+ value = lex();
+ // A closing square bracket marks the end of the array literal.
+ if (value == "]") {
+ break;
+ }
+ // If the array literal contains elements, the current token
+ // should be a comma separating the previous element from the
+ // next.
+ if (hasMembers) {
+ if (value == ",") {
+ value = lex();
+ if (value == "]") {
+ // Unexpected trailing `,` in array literal.
+ abort();
+ }
+ } else {
+ // A `,` must separate each array element.
+ abort();
+ }
+ }
+ // Elisions and leading commas are not permitted.
+ if (value == ",") {
+ abort();
+ }
+ results.push(get(value));
+ }
+ return results;
+ } else if (value == "{") {
+ // Parses a JSON object, returning a new JavaScript object.
+ results = {};
+ for (;; hasMembers || (hasMembers = true)) {
+ value = lex();
+ // A closing curly brace marks the end of the object literal.
+ if (value == "}") {
+ break;
+ }
+ // If the object literal contains members, the current token
+ // should be a comma separator.
+ if (hasMembers) {
+ if (value == ",") {
+ value = lex();
+ if (value == "}") {
+ // Unexpected trailing `,` in object literal.
+ abort();
+ }
+ } else {
+ // A `,` must separate each object member.
+ abort();
+ }
+ }
+ // Leading commas are not permitted, object property names must be
+ // double-quoted strings, and a `:` must separate each property
+ // name and value.
+ if (value == "," || typeof value != "string" || (charIndexBuggy ? value.charAt(0) : value[0]) != "@" || lex() != ":") {
+ abort();
+ }
+ results[value.slice(1)] = get(lex());
+ }
+ return results;
+ }
+ // Unexpected token encountered.
+ abort();
+ }
+ return value;
+ };
+
+ // Internal: Updates a traversed object member.
+ var update = function(source, property, callback) {
+ var element = walk(source, property, callback);
+ if (element === undef) {
+ delete source[property];
+ } else {
+ source[property] = element;
+ }
+ };
+
+ // Internal: Recursively traverses a parsed JSON object, invoking the
+ // `callback` function for each value. This is an implementation of the
+ // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.
+ var walk = function (source, property, callback) {
+ var value = source[property], length;
+ if (typeof value == "object" && value) {
+ // `forEach` can't be used to traverse an array in Opera <= 8.54
+ // because its `Object#hasOwnProperty` implementation returns `false`
+ // for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`).
+ if (getClass.call(value) == arrayClass) {
+ for (length = value.length; length--;) {
+ update(value, length, callback);
+ }
+ } else {
+ forEach(value, function (property) {
+ update(value, property, callback);
+ });
+ }
+ }
+ return callback.call(source, property, value);
+ };
+
+ // Public: `JSON.parse`. See ES 5.1 section 15.12.2.
+ JSON3.parse = function (source, callback) {
+ var result, value;
+ Index = 0;
+ Source = "" + source;
+ result = get(lex());
+ // If a JSON string contains multiple tokens, it is invalid.
+ if (lex() != "$") {
+ abort();
+ }
+ // Reset the parser state.
+ Index = Source = null;
+ return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[""] = result, value), "", callback) : result;
+ };
+ }
+ }
+
+ // Export for asynchronous module loaders.
+ if (isLoader) {
+ define(function () {
+ return JSON3;
+ });
+ }
+ }(this));
+
+},{}],50:[function(_dereq_,module,exports){
+ module.exports = toArray
+
+ function toArray(list, index) {
+ var array = []
+
+ index = index || 0
+
+ for (var i = index || 0; i < list.length; i++) {
+ array[i - index] = list[i]
+ }
+
+ return array
+ }
+
+},{}]},{},[1])
+(1)
+});
diff --git a/frameworks/cocos2d-html5/external/socketio/socket.io.min.js b/frameworks/cocos2d-html5/external/socketio/socket.io.min.js
new file mode 100644
index 0000000..28e8fee
--- /dev/null
+++ b/frameworks/cocos2d-html5/external/socketio/socket.io.min.js
@@ -0,0 +1,3 @@
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.io=e()}}(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o0&&!this.encoding){var pack=this.packetBuffer.shift();this.packet(pack)}};Manager.prototype.cleanup=function(){var sub;while(sub=this.subs.shift())sub.destroy();this.packetBuffer=[];this.encoding=false;this.decoder.destroy()};Manager.prototype.close=Manager.prototype.disconnect=function(){this.skipReconnect=true;this.backoff.reset();this.readyState="closed";this.engine&&this.engine.close()};Manager.prototype.onclose=function(reason){debug("close");this.cleanup();this.backoff.reset();this.readyState="closed";this.emit("close",reason);if(this._reconnection&&!this.skipReconnect){this.reconnect()}};Manager.prototype.reconnect=function(){if(this.reconnecting||this.skipReconnect)return this;var self=this;if(this.backoff.attempts>=this._reconnectionAttempts){debug("reconnect failed");this.backoff.reset();this.emitAll("reconnect_failed");this.reconnecting=false}else{var delay=this.backoff.duration();debug("will wait %dms before reconnect attempt",delay);this.reconnecting=true;var timer=setTimeout(function(){if(self.skipReconnect)return;debug("attempting reconnect");self.emitAll("reconnect_attempt",self.backoff.attempts);self.emitAll("reconnecting",self.backoff.attempts);if(self.skipReconnect)return;self.open(function(err){if(err){debug("reconnect attempt error");self.reconnecting=false;self.reconnect();self.emitAll("reconnect_error",err.data)}else{debug("reconnect success");self.onreconnect()}})},delay);this.subs.push({destroy:function(){clearTimeout(timer)}})}};Manager.prototype.onreconnect=function(){var attempt=this.backoff.attempts;this.reconnecting=false;this.backoff.reset();this.updateSocketIds();this.emitAll("reconnect",attempt)}},{"./on":4,"./socket":5,"./url":6,backo2:7,"component-bind":8,"component-emitter":9,debug:10,"engine.io-client":11,indexof:42,"object-component":43,"socket.io-parser":46}],4:[function(_dereq_,module,exports){module.exports=on;function on(obj,ev,fn){obj.on(ev,fn);return{destroy:function(){obj.removeListener(ev,fn)}}}},{}],5:[function(_dereq_,module,exports){var parser=_dereq_("socket.io-parser");var Emitter=_dereq_("component-emitter");var toArray=_dereq_("to-array");var on=_dereq_("./on");var bind=_dereq_("component-bind");var debug=_dereq_("debug")("socket.io-client:socket");var hasBin=_dereq_("has-binary");module.exports=exports=Socket;var events={connect:1,connect_error:1,connect_timeout:1,disconnect:1,error:1,reconnect:1,reconnect_attempt:1,reconnect_failed:1,reconnect_error:1,reconnecting:1};var emit=Emitter.prototype.emit;function Socket(io,nsp){this.io=io;this.nsp=nsp;this.json=this;this.ids=0;this.acks={};if(this.io.autoConnect)this.open();this.receiveBuffer=[];this.sendBuffer=[];this.connected=false;this.disconnected=true}Emitter(Socket.prototype);Socket.prototype.subEvents=function(){if(this.subs)return;var io=this.io;this.subs=[on(io,"open",bind(this,"onopen")),on(io,"packet",bind(this,"onpacket")),on(io,"close",bind(this,"onclose"))]};Socket.prototype.open=Socket.prototype.connect=function(){if(this.connected)return this;this.subEvents();this.io.open();if("open"==this.io.readyState)this.onopen();return this};Socket.prototype.send=function(){var args=toArray(arguments);args.unshift("message");this.emit.apply(this,args);return this};Socket.prototype.emit=function(ev){if(events.hasOwnProperty(ev)){emit.apply(this,arguments);return this}var args=toArray(arguments);var parserType=parser.EVENT;if(hasBin(args)){parserType=parser.BINARY_EVENT}var packet={type:parserType,data:args};if("function"==typeof args[args.length-1]){debug("emitting packet with ack id %d",this.ids);this.acks[this.ids]=args.pop();packet.id=this.ids++}if(this.connected){this.packet(packet)}else{this.sendBuffer.push(packet)}return this};Socket.prototype.packet=function(packet){packet.nsp=this.nsp;this.io.packet(packet)};Socket.prototype.onopen=function(){debug("transport is open - connecting");if("/"!=this.nsp){this.packet({type:parser.CONNECT})}};Socket.prototype.onclose=function(reason){debug("close (%s)",reason);this.connected=false;this.disconnected=true;delete this.id;this.emit("disconnect",reason)};Socket.prototype.onpacket=function(packet){if(packet.nsp!=this.nsp)return;switch(packet.type){case parser.CONNECT:this.onconnect();break;case parser.EVENT:this.onevent(packet);break;case parser.BINARY_EVENT:this.onevent(packet);break;case parser.ACK:this.onack(packet);break;case parser.BINARY_ACK:this.onack(packet);break;case parser.DISCONNECT:this.ondisconnect();break;case parser.ERROR:this.emit("error",packet.data);break}};Socket.prototype.onevent=function(packet){var args=packet.data||[];debug("emitting event %j",args);if(null!=packet.id){debug("attaching ack callback to event");args.push(this.ack(packet.id))}if(this.connected){emit.apply(this,args)}else{this.receiveBuffer.push(args)}};Socket.prototype.ack=function(id){var self=this;var sent=false;return function(){if(sent)return;sent=true;var args=toArray(arguments);debug("sending ack %j",args);var type=hasBin(args)?parser.BINARY_ACK:parser.ACK;self.packet({type:type,id:id,data:args})}};Socket.prototype.onack=function(packet){debug("calling ack %s with %j",packet.id,packet.data);var fn=this.acks[packet.id];fn.apply(this,packet.data);delete this.acks[packet.id]};Socket.prototype.onconnect=function(){this.connected=true;this.disconnected=false;this.emit("connect");this.emitBuffered()};Socket.prototype.emitBuffered=function(){var i;for(i=0;i0&&opts.jitter<=1?opts.jitter:0;this.attempts=0}Backoff.prototype.duration=function(){var ms=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var rand=Math.random();var deviation=Math.floor(rand*this.jitter*ms);ms=(Math.floor(rand*10)&1)==0?ms-deviation:ms+deviation}return Math.min(ms,this.max)|0};Backoff.prototype.reset=function(){this.attempts=0};Backoff.prototype.setMin=function(min){this.ms=min};Backoff.prototype.setMax=function(max){this.max=max};Backoff.prototype.setJitter=function(jitter){this.jitter=jitter}},{}],8:[function(_dereq_,module,exports){var slice=[].slice;module.exports=function(obj,fn){if("string"==typeof fn)fn=obj[fn];if("function"!=typeof fn)throw new Error("bind() requires a function");var args=slice.call(arguments,2);return function(){return fn.apply(obj,args.concat(slice.call(arguments)))}}},{}],9:[function(_dereq_,module,exports){module.exports=Emitter;function Emitter(obj){if(obj)return mixin(obj)}function mixin(obj){for(var key in Emitter.prototype){obj[key]=Emitter.prototype[key]}return obj}Emitter.prototype.on=Emitter.prototype.addEventListener=function(event,fn){this._callbacks=this._callbacks||{};(this._callbacks[event]=this._callbacks[event]||[]).push(fn);return this};Emitter.prototype.once=function(event,fn){var self=this;this._callbacks=this._callbacks||{};function on(){self.off(event,on);fn.apply(this,arguments)}on.fn=fn;this.on(event,on);return this};Emitter.prototype.off=Emitter.prototype.removeListener=Emitter.prototype.removeAllListeners=Emitter.prototype.removeEventListener=function(event,fn){this._callbacks=this._callbacks||{};if(0==arguments.length){this._callbacks={};return this}var callbacks=this._callbacks[event];if(!callbacks)return this;if(1==arguments.length){delete this._callbacks[event];return this}var cb;for(var i=0;i=hour)return(ms/hour).toFixed(1)+"h";if(ms>=min)return(ms/min).toFixed(1)+"m";if(ms>=sec)return(ms/sec|0)+"s";return ms+"ms"};debug.enabled=function(name){for(var i=0,len=debug.skips.length;i';iframe=document.createElement(html)}catch(e){iframe=document.createElement("iframe");iframe.name=self.iframeId;iframe.src="javascript:0"}iframe.id=self.iframeId;self.form.appendChild(iframe);self.iframe=iframe}initIframe();data=data.replace(rEscapedNewline,"\\\n");this.area.value=data.replace(rNewline,"\\n");try{this.form.submit()}catch(e){}if(this.iframe.attachEvent){this.iframe.onreadystatechange=function(){if(self.iframe.readyState=="complete"){complete()}}}else{this.iframe.onload=complete}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./polling":18,"component-inherit":21}],17:[function(_dereq_,module,exports){(function(global){var XMLHttpRequest=_dereq_("xmlhttprequest");var Polling=_dereq_("./polling");var Emitter=_dereq_("component-emitter");var inherit=_dereq_("component-inherit");var debug=_dereq_("debug")("engine.io-client:polling-xhr");module.exports=XHR;module.exports.Request=Request;function empty(){}function XHR(opts){Polling.call(this,opts);if(global.location){var isSSL="https:"==location.protocol;var port=location.port;if(!port){port=isSSL?443:80}this.xd=opts.hostname!=global.location.hostname||port!=opts.port;this.xs=opts.secure!=isSSL}}inherit(XHR,Polling);XHR.prototype.supportsBinary=true;XHR.prototype.request=function(opts){opts=opts||{};opts.uri=this.uri();opts.xd=this.xd;opts.xs=this.xs;opts.agent=this.agent||false;opts.supportsBinary=this.supportsBinary;opts.enablesXDR=this.enablesXDR;opts.pfx=this.pfx;opts.key=this.key;opts.passphrase=this.passphrase;opts.cert=this.cert;opts.ca=this.ca;opts.ciphers=this.ciphers;opts.rejectUnauthorized=this.rejectUnauthorized;return new Request(opts)};XHR.prototype.doWrite=function(data,fn){var isBinary=typeof data!=="string"&&data!==undefined;var req=this.request({method:"POST",data:data,isBinary:isBinary});var self=this;req.on("success",fn);req.on("error",function(err){self.onError("xhr post error",err)});this.sendXhr=req};XHR.prototype.doPoll=function(){debug("xhr poll");var req=this.request();var self=this;req.on("data",function(data){self.onData(data)});req.on("error",function(err){self.onError("xhr poll error",err)});this.pollXhr=req};function Request(opts){this.method=opts.method||"GET";this.uri=opts.uri;this.xd=!!opts.xd;this.xs=!!opts.xs;this.async=false!==opts.async;this.data=undefined!=opts.data?opts.data:null;this.agent=opts.agent;this.isBinary=opts.isBinary;this.supportsBinary=opts.supportsBinary;this.enablesXDR=opts.enablesXDR;this.pfx=opts.pfx;this.key=opts.key;this.passphrase=opts.passphrase;this.cert=opts.cert;this.ca=opts.ca;this.ciphers=opts.ciphers;this.rejectUnauthorized=opts.rejectUnauthorized;this.create()}Emitter(Request.prototype);Request.prototype.create=function(){var opts={agent:this.agent,xdomain:this.xd,xscheme:this.xs,enablesXDR:this.enablesXDR};opts.pfx=this.pfx;opts.key=this.key;opts.passphrase=this.passphrase;opts.cert=this.cert;opts.ca=this.ca;opts.ciphers=this.ciphers;opts.rejectUnauthorized=this.rejectUnauthorized;var xhr=this.xhr=new XMLHttpRequest(opts);var self=this;try{debug("xhr open %s: %s",this.method,this.uri);xhr.open(this.method,this.uri,this.async);if(this.supportsBinary){xhr.responseType="arraybuffer"}if("POST"==this.method){try{if(this.isBinary){xhr.setRequestHeader("Content-type","application/octet-stream")}else{xhr.setRequestHeader("Content-type","text/plain;charset=UTF-8")}}catch(e){}}if("withCredentials"in xhr){xhr.withCredentials=true}if(this.hasXDR()){xhr.onload=function(){self.onLoad()};xhr.onerror=function(){self.onError(xhr.responseText)}}else{xhr.onreadystatechange=function(){if(4!=xhr.readyState)return;if(200==xhr.status||1223==xhr.status){self.onLoad()}else{setTimeout(function(){self.onError(xhr.status)},0)}}}debug("xhr data %s",this.data);xhr.send(this.data)}catch(e){setTimeout(function(){self.onError(e)},0);return}if(global.document){this.index=Request.requestsCount++;Request.requests[this.index]=this}};Request.prototype.onSuccess=function(){this.emit("success");this.cleanup()};Request.prototype.onData=function(data){this.emit("data",data);this.onSuccess()};Request.prototype.onError=function(err){this.emit("error",err);this.cleanup(true)};Request.prototype.cleanup=function(fromError){if("undefined"==typeof this.xhr||null===this.xhr){return}if(this.hasXDR()){this.xhr.onload=this.xhr.onerror=empty}else{this.xhr.onreadystatechange=empty}if(fromError){try{this.xhr.abort()}catch(e){}}if(global.document){delete Request.requests[this.index]}this.xhr=null};Request.prototype.onLoad=function(){var data;try{var contentType;try{contentType=this.xhr.getResponseHeader("Content-Type").split(";")[0]}catch(e){}if(contentType==="application/octet-stream"){data=this.xhr.response}else{if(!this.supportsBinary){data=this.xhr.responseText}else{data="ok"}}}catch(e){this.onError(e)}if(null!=data){this.onData(data)}};Request.prototype.hasXDR=function(){return"undefined"!==typeof global.XDomainRequest&&!this.xs&&this.enablesXDR};Request.prototype.abort=function(){this.cleanup()};if(global.document){Request.requestsCount=0;Request.requests={};if(global.attachEvent){global.attachEvent("onunload",unloadHandler)}else if(global.addEventListener){global.addEventListener("beforeunload",unloadHandler,false)}}function unloadHandler(){for(var i in Request.requests){if(Request.requests.hasOwnProperty(i)){Request.requests[i].abort()}}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./polling":18,"component-emitter":9,"component-inherit":21,debug:22,xmlhttprequest:20}],18:[function(_dereq_,module,exports){var Transport=_dereq_("../transport");var parseqs=_dereq_("parseqs");var parser=_dereq_("engine.io-parser");var inherit=_dereq_("component-inherit");var debug=_dereq_("debug")("engine.io-client:polling");module.exports=Polling;var hasXHR2=function(){var XMLHttpRequest=_dereq_("xmlhttprequest");var xhr=new XMLHttpRequest({xdomain:false});return null!=xhr.responseType}();function Polling(opts){var forceBase64=opts&&opts.forceBase64;if(!hasXHR2||forceBase64){this.supportsBinary=false}Transport.call(this,opts)}inherit(Polling,Transport);Polling.prototype.name="polling";Polling.prototype.doOpen=function(){this.poll()};Polling.prototype.pause=function(onPause){var pending=0;var self=this;this.readyState="pausing";function pause(){debug("paused");self.readyState="paused";onPause()}if(this.polling||!this.writable){var total=0;if(this.polling){debug("we are currently polling - waiting to pause");total++;this.once("pollComplete",function(){debug("pre-pause polling complete");--total||pause()})}if(!this.writable){debug("we are currently writing - waiting to pause");total++;this.once("drain",function(){debug("pre-pause writing complete");--total||pause()})}}else{pause()}};Polling.prototype.poll=function(){debug("polling");this.polling=true;this.doPoll();this.emit("poll")};Polling.prototype.onData=function(data){var self=this;debug("polling got data %s",data);var callback=function(packet,index,total){if("opening"==self.readyState){self.onOpen()}if("close"==packet.type){self.onClose();return false}self.onPacket(packet)};parser.decodePayload(data,this.socket.binaryType,callback);if("closed"!=this.readyState){this.polling=false;this.emit("pollComplete");if("open"==this.readyState){this.poll()}else{debug('ignoring poll - transport state "%s"',this.readyState)}}};Polling.prototype.doClose=function(){var self=this;function close(){debug("writing close packet");self.write([{type:"close"}])}if("open"==this.readyState){debug("transport open - closing");close()}else{debug("transport not open - deferring close");this.once("open",close)}};Polling.prototype.write=function(packets){var self=this;this.writable=false;var callbackfn=function(){self.writable=true;self.emit("drain")};var self=this;parser.encodePayload(packets,this.supportsBinary,function(data){self.doWrite(data,callbackfn)})};Polling.prototype.uri=function(){var query=this.query||{};var schema=this.secure?"https":"http";var port="";if(false!==this.timestampRequests){query[this.timestampParam]=+new Date+"-"+Transport.timestamps++}if(!this.supportsBinary&&!query.sid){query.b64=1}query=parseqs.encode(query);if(this.port&&("https"==schema&&this.port!=443||"http"==schema&&this.port!=80)){port=":"+this.port}if(query.length){query="?"+query}return schema+"://"+this.hostname+port+this.path+query}},{"../transport":14,"component-inherit":21,debug:22,"engine.io-parser":25,parseqs:35,xmlhttprequest:20}],19:[function(_dereq_,module,exports){var Transport=_dereq_("../transport");var parser=_dereq_("engine.io-parser");var parseqs=_dereq_("parseqs");var inherit=_dereq_("component-inherit");var debug=_dereq_("debug")("engine.io-client:websocket");var WebSocket=_dereq_("ws");module.exports=WS;function WS(opts){var forceBase64=opts&&opts.forceBase64;if(forceBase64){this.supportsBinary=false}Transport.call(this,opts)}inherit(WS,Transport);WS.prototype.name="websocket";WS.prototype.supportsBinary=true;WS.prototype.doOpen=function(){if(!this.check()){return}var self=this;var uri=this.uri();var protocols=void 0;var opts={agent:this.agent};opts.pfx=this.pfx;opts.key=this.key;opts.passphrase=this.passphrase;opts.cert=this.cert;opts.ca=this.ca;opts.ciphers=this.ciphers;opts.rejectUnauthorized=this.rejectUnauthorized;this.ws=new WebSocket(uri,protocols,opts);if(this.ws.binaryType===undefined){this.supportsBinary=false}this.ws.binaryType="arraybuffer";this.addEventListeners()};WS.prototype.addEventListeners=function(){var self=this;this.ws.onopen=function(){self.onOpen()};this.ws.onclose=function(){self.onClose()};this.ws.onmessage=function(ev){self.onData(ev.data)};this.ws.onerror=function(e){self.onError("websocket error",e)}};if("undefined"!=typeof navigator&&/iPad|iPhone|iPod/i.test(navigator.userAgent)){WS.prototype.onData=function(data){var self=this;setTimeout(function(){Transport.prototype.onData.call(self,data)},0)}}WS.prototype.write=function(packets){var self=this;this.writable=false;for(var i=0,l=packets.length;i=31}exports.formatters.j=function(v){return JSON.stringify(v)};function formatArgs(){var args=arguments;var useColors=this.useColors;args[0]=(useColors?"%c":"")+this.namespace+(useColors?" %c":" ")+args[0]+(useColors?"%c ":" ")+"+"+exports.humanize(this.diff);if(!useColors)return args;var c="color: "+this.color;args=[args[0],c,"color: inherit"].concat(Array.prototype.slice.call(args,1));var index=0;var lastC=0;args[0].replace(/%[a-z%]/g,function(match){if("%"===match)return;index++;if("%c"===match){lastC=index}});args.splice(lastC,0,c);return args}function log(){return"object"==typeof console&&"function"==typeof console.log&&Function.prototype.apply.call(console.log,console,arguments)}function save(namespaces){try{if(null==namespaces){localStorage.removeItem("debug")}else{localStorage.debug=namespaces}}catch(e){}}function load(){var r;try{r=localStorage.debug}catch(e){}return r}exports.enable(load())},{"./debug":23}],23:[function(_dereq_,module,exports){exports=module.exports=debug;exports.coerce=coerce;exports.disable=disable;exports.enable=enable;exports.enabled=enabled;exports.humanize=_dereq_("ms");exports.names=[];exports.skips=[];exports.formatters={};var prevColor=0;var prevTime;function selectColor(){return exports.colors[prevColor++%exports.colors.length]}function debug(namespace){function disabled(){}disabled.enabled=false;function enabled(){var self=enabled;var curr=+new Date;var ms=curr-(prevTime||curr);self.diff=ms;self.prev=prevTime;self.curr=curr;prevTime=curr;if(null==self.useColors)self.useColors=exports.useColors();if(null==self.color&&self.useColors)self.color=selectColor();var args=Array.prototype.slice.call(arguments);args[0]=exports.coerce(args[0]);if("string"!==typeof args[0]){args=["%o"].concat(args)}var index=0;args[0]=args[0].replace(/%([a-z%])/g,function(match,format){if(match==="%")return match;index++;var formatter=exports.formatters[format];if("function"===typeof formatter){var val=args[index];match=formatter.call(self,val);args.splice(index,1);index--}return match});if("function"===typeof exports.formatArgs){args=exports.formatArgs.apply(self,args)}var logFn=enabled.log||exports.log||console.log.bind(console);logFn.apply(self,args)}enabled.enabled=true;var fn=exports.enabled(namespace)?enabled:disabled;fn.namespace=namespace;return fn}function enable(namespaces){exports.save(namespaces);var split=(namespaces||"").split(/[\s,]+/);var len=split.length;for(var i=0;i=d)return Math.round(ms/d)+"d";if(ms>=h)return Math.round(ms/h)+"h";if(ms>=m)return Math.round(ms/m)+"m";if(ms>=s)return Math.round(ms/s)+"s";return ms+"ms"}function long(ms){return plural(ms,d,"day")||plural(ms,h,"hour")||plural(ms,m,"minute")||plural(ms,s,"second")||ms+" ms"}function plural(ms,n,name){if(ms1){return{type:packetslist[type],data:data.substring(1)}}else{return{type:packetslist[type]}}}var asArray=new Uint8Array(data);var type=asArray[0];var rest=sliceBuffer(data,1);if(Blob&&binaryType==="blob"){rest=new Blob([rest])}return{type:packetslist[type],data:rest}};exports.decodeBase64Packet=function(msg,binaryType){var type=packetslist[msg.charAt(0)];if(!global.ArrayBuffer){return{type:type,data:{base64:true,data:msg.substr(1)}}}var data=base64encoder.decode(msg.substr(1));if(binaryType==="blob"&&Blob){data=new Blob([data])}return{type:type,data:data}};exports.encodePayload=function(packets,supportsBinary,callback){if(typeof supportsBinary=="function"){callback=supportsBinary;supportsBinary=null}var isBinary=hasBinary(packets);if(supportsBinary&&isBinary){if(Blob&&!dontSendBlobs){return exports.encodePayloadAsBlob(packets,callback)}return exports.encodePayloadAsArrayBuffer(packets,callback)}if(!packets.length){return callback("0:")}function setLengthHeader(message){return message.length+":"+message}function encodeOne(packet,doneCallback){exports.encodePacket(packet,!isBinary?false:supportsBinary,true,function(message){doneCallback(null,setLengthHeader(message))})}map(packets,encodeOne,function(err,results){return callback(results.join(""))})};function map(ary,each,done){var result=new Array(ary.length);var next=after(ary.length,done);var eachWithIndex=function(i,el,cb){each(el,function(error,msg){result[i]=msg;cb(error,result)})};for(var i=0;i0){var tailArray=new Uint8Array(bufferTail);var isString=tailArray[0]===0;var msgLength="";for(var i=1;;i++){if(tailArray[i]==255)break;if(msgLength.length>310){numberTooLong=true;break}msgLength+=tailArray[i]}if(numberTooLong)return callback(err,0,1);bufferTail=sliceBuffer(bufferTail,2+msgLength.length);msgLength=parseInt(msgLength);var msg=sliceBuffer(bufferTail,0,msgLength);if(isString){try{msg=String.fromCharCode.apply(null,new Uint8Array(msg))}catch(e){var typed=new Uint8Array(msg);msg="";for(var i=0;ibytes){end=bytes}if(start>=bytes||start>=end||bytes===0){return new ArrayBuffer(0)}var abv=new Uint8Array(arraybuffer);var result=new Uint8Array(end-start);for(var i=start,ii=0;i>2];base64+=chars[(bytes[i]&3)<<4|bytes[i+1]>>4];base64+=chars[(bytes[i+1]&15)<<2|bytes[i+2]>>6];base64+=chars[bytes[i+2]&63]}if(len%3===2){base64=base64.substring(0,base64.length-1)+"="}else if(len%3===1){base64=base64.substring(0,base64.length-2)+"=="}return base64};exports.decode=function(base64){var bufferLength=base64.length*.75,len=base64.length,i,p=0,encoded1,encoded2,encoded3,encoded4;if(base64[base64.length-1]==="="){bufferLength--;if(base64[base64.length-2]==="="){bufferLength--}}var arraybuffer=new ArrayBuffer(bufferLength),bytes=new Uint8Array(arraybuffer);for(i=0;i>4;bytes[p++]=(encoded2&15)<<4|encoded3>>2;bytes[p++]=(encoded3&3)<<6|encoded4&63}return arraybuffer}})("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")},{}],30:[function(_dereq_,module,exports){(function(global){var BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder||global.MSBlobBuilder||global.MozBlobBuilder;var blobSupported=function(){try{var b=new Blob(["hi"]);return b.size==2}catch(e){return false}}();var blobBuilderSupported=BlobBuilder&&BlobBuilder.prototype.append&&BlobBuilder.prototype.getBlob;function BlobBuilderConstructor(ary,options){options=options||{};var bb=new BlobBuilder;for(var i=0;i=55296&&value<=56319&&counter65535){value-=65536;
+ output+=stringFromCharCode(value>>>10&1023|55296);value=56320|value&1023}output+=stringFromCharCode(value)}return output}function createByte(codePoint,shift){return stringFromCharCode(codePoint>>shift&63|128)}function encodeCodePoint(codePoint){if((codePoint&4294967168)==0){return stringFromCharCode(codePoint)}var symbol="";if((codePoint&4294965248)==0){symbol=stringFromCharCode(codePoint>>6&31|192)}else if((codePoint&4294901760)==0){symbol=stringFromCharCode(codePoint>>12&15|224);symbol+=createByte(codePoint,6)}else if((codePoint&4292870144)==0){symbol=stringFromCharCode(codePoint>>18&7|240);symbol+=createByte(codePoint,12);symbol+=createByte(codePoint,6)}symbol+=stringFromCharCode(codePoint&63|128);return symbol}function utf8encode(string){var codePoints=ucs2decode(string);var length=codePoints.length;var index=-1;var codePoint;var byteString="";while(++index=byteCount){throw Error("Invalid byte index")}var continuationByte=byteArray[byteIndex]&255;byteIndex++;if((continuationByte&192)==128){return continuationByte&63}throw Error("Invalid continuation byte")}function decodeSymbol(){var byte1;var byte2;var byte3;var byte4;var codePoint;if(byteIndex>byteCount){throw Error("Invalid byte index")}if(byteIndex==byteCount){return false}byte1=byteArray[byteIndex]&255;byteIndex++;if((byte1&128)==0){return byte1}if((byte1&224)==192){var byte2=readContinuationByte();codePoint=(byte1&31)<<6|byte2;if(codePoint>=128){return codePoint}else{throw Error("Invalid continuation byte")}}if((byte1&240)==224){byte2=readContinuationByte();byte3=readContinuationByte();codePoint=(byte1&15)<<12|byte2<<6|byte3;if(codePoint>=2048){return codePoint}else{throw Error("Invalid continuation byte")}}if((byte1&248)==240){byte2=readContinuationByte();byte3=readContinuationByte();byte4=readContinuationByte();codePoint=(byte1&15)<<18|byte2<<12|byte3<<6|byte4;if(codePoint>=65536&&codePoint<=1114111){return codePoint}}throw Error("Invalid UTF-8 detected")}var byteArray;var byteCount;var byteIndex;function utf8decode(byteString){byteArray=ucs2decode(byteString);byteCount=byteArray.length;byteIndex=0;var codePoints=[];var tmp;while((tmp=decodeSymbol())!==false){codePoints.push(tmp)}return ucs2encode(codePoints)}var utf8={version:"2.0.0",encode:utf8encode,decode:utf8decode};if(typeof define=="function"&&typeof define.amd=="object"&&define.amd){define(function(){return utf8})}else if(freeExports&&!freeExports.nodeType){if(freeModule){freeModule.exports=utf8}else{var object={};var hasOwnProperty=object.hasOwnProperty;for(var key in utf8){hasOwnProperty.call(utf8,key)&&(freeExports[key]=utf8[key])}}}else{root.utf8=utf8}})(this)}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],34:[function(_dereq_,module,exports){(function(global){var rvalidchars=/^[\],:{}\s]*$/;var rvalidescape=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;var rvalidtokens=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;var rvalidbraces=/(?:^|:|,)(?:\s*\[)+/g;var rtrimLeft=/^\s+/;var rtrimRight=/\s+$/;module.exports=function parsejson(data){if("string"!=typeof data||!data){return null}data=data.replace(rtrimLeft,"").replace(rtrimRight,"");if(global.JSON&&JSON.parse){return JSON.parse(data)}if(rvalidchars.test(data.replace(rvalidescape,"@").replace(rvalidtokens,"]").replace(rvalidbraces,""))){return new Function("return "+data)()}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],35:[function(_dereq_,module,exports){exports.encode=function(obj){var str="";for(var i in obj){if(obj.hasOwnProperty(i)){if(str.length)str+="&";str+=encodeURIComponent(i)+"="+encodeURIComponent(obj[i])}}return str};exports.decode=function(qs){var qry={};var pairs=qs.split("&");for(var i=0,l=pairs.length;i1)))/4)-floor((year-1901+month)/100)+floor((year-1601+month)/400)}}if(!(isProperty={}.hasOwnProperty)){isProperty=function(property){var members={},constructor;if((members.__proto__=null,members.__proto__={toString:1},members).toString!=getClass){isProperty=function(property){var original=this.__proto__,result=property in(this.__proto__=null,this);this.__proto__=original;return result}}else{constructor=members.constructor;isProperty=function(property){var parent=(this.constructor||constructor).prototype;return property in this&&!(property in parent&&this[property]===parent[property])}}members=null;return isProperty.call(this,property)}}var PrimitiveTypes={"boolean":1,number:1,string:1,undefined:1};var isHostType=function(object,property){var type=typeof object[property];return type=="object"?!!object[property]:!PrimitiveTypes[type]};forEach=function(object,callback){var size=0,Properties,members,property;(Properties=function(){this.valueOf=0}).prototype.valueOf=0;members=new Properties;for(property in members){if(isProperty.call(members,property)){size++}}Properties=members=null;if(!size){members=["valueOf","toString","toLocaleString","propertyIsEnumerable","isPrototypeOf","hasOwnProperty","constructor"];forEach=function(object,callback){var isFunction=getClass.call(object)==functionClass,property,length;var hasProperty=!isFunction&&typeof object.constructor!="function"&&isHostType(object,"hasOwnProperty")?object.hasOwnProperty:isProperty;for(property in object){if(!(isFunction&&property=="prototype")&&hasProperty.call(object,property)){callback(property)}}for(length=members.length;property=members[--length];hasProperty.call(object,property)&&callback(property));}}else if(size==2){forEach=function(object,callback){var members={},isFunction=getClass.call(object)==functionClass,property;for(property in object){if(!(isFunction&&property=="prototype")&&!isProperty.call(members,property)&&(members[property]=1)&&isProperty.call(object,property)){callback(property)}}}}else{forEach=function(object,callback){var isFunction=getClass.call(object)==functionClass,property,isConstructor;for(property in object){if(!(isFunction&&property=="prototype")&&isProperty.call(object,property)&&!(isConstructor=property==="constructor")){callback(property)}}if(isConstructor||isProperty.call(object,property="constructor")){callback(property)}}}return forEach(object,callback)};if(!has("json-stringify")){var Escapes={92:"\\\\",34:'\\"',8:"\\b",12:"\\f",10:"\\n",13:"\\r",9:"\\t"};var leadingZeroes="000000";var toPaddedString=function(width,value){return(leadingZeroes+(value||0)).slice(-width)};var unicodePrefix="\\u00";var quote=function(value){var result='"',index=0,length=value.length,isLarge=length>10&&charIndexBuggy,symbols;if(isLarge){symbols=value.split("")}for(;index-1/0&&value<1/0){if(getDay){date=floor(value/864e5);for(year=floor(date/365.2425)+1970-1;getDay(year+1,0)<=date;year++);for(month=floor((date-getDay(year,0))/30.42);getDay(year,month+1)<=date;month++);date=1+date-getDay(year,month);time=(value%864e5+864e5)%864e5;hours=floor(time/36e5)%24;minutes=floor(time/6e4)%60;seconds=floor(time/1e3)%60;milliseconds=time%1e3}else{year=value.getUTCFullYear();month=value.getUTCMonth();date=value.getUTCDate();hours=value.getUTCHours();minutes=value.getUTCMinutes();seconds=value.getUTCSeconds();milliseconds=value.getUTCMilliseconds()}value=(year<=0||year>=1e4?(year<0?"-":"+")+toPaddedString(6,year<0?-year:year):toPaddedString(4,year))+"-"+toPaddedString(2,month+1)+"-"+toPaddedString(2,date)+"T"+toPaddedString(2,hours)+":"+toPaddedString(2,minutes)+":"+toPaddedString(2,seconds)+"."+toPaddedString(3,milliseconds)+"Z"}else{value=null}}else if(typeof value.toJSON=="function"&&(className!=numberClass&&className!=stringClass&&className!=arrayClass||isProperty.call(value,"toJSON"))){value=value.toJSON(property)}}if(callback){value=callback.call(object,property,value)}if(value===null){return"null"}className=getClass.call(value);if(className==booleanClass){return""+value}else if(className==numberClass){return value>-1/0&&value<1/0?""+value:"null"}else if(className==stringClass){return quote(""+value)}if(typeof value=="object"){for(length=stack.length;length--;){if(stack[length]===value){throw TypeError()}}stack.push(value);results=[];prefix=indentation;indentation+=whitespace;if(className==arrayClass){for(index=0,length=value.length;index0){for(whitespace="",width>10&&(width=10);whitespace.length=48&&charCode<=57||charCode>=97&&charCode<=102||charCode>=65&&charCode<=70)){abort()}}value+=fromCharCode("0x"+source.slice(begin,Index));break;default:abort()}}else{if(charCode==34){break}charCode=source.charCodeAt(Index);begin=Index;while(charCode>=32&&charCode!=92&&charCode!=34){charCode=source.charCodeAt(++Index)}value+=source.slice(begin,Index)}}if(source.charCodeAt(Index)==34){Index++;return value}abort();default:begin=Index;if(charCode==45){isSigned=true;charCode=source.charCodeAt(++Index)}if(charCode>=48&&charCode<=57){if(charCode==48&&(charCode=source.charCodeAt(Index+1),charCode>=48&&charCode<=57)){abort()}isSigned=false;for(;Index=48&&charCode<=57);Index++);if(source.charCodeAt(Index)==46){position=++Index;for(;position=48&&charCode<=57);position++);if(position==Index){abort()}Index=position}charCode=source.charCodeAt(Index);if(charCode==101||charCode==69){charCode=source.charCodeAt(++Index);if(charCode==43||charCode==45){Index++}for(position=Index;position=48&&charCode<=57);position++);if(position==Index){abort()}Index=position}return+source.slice(begin,Index)}if(isSigned){abort()}if(source.slice(Index,Index+4)=="true"){Index+=4;return true}else if(source.slice(Index,Index+5)=="false"){Index+=5;return false}else if(source.slice(Index,Index+4)=="null"){Index+=4;return null}abort()}}return"$"};var get=function(value){var results,hasMembers;if(value=="$"){abort()}if(typeof value=="string"){if((charIndexBuggy?value.charAt(0):value[0])=="@"){return value.slice(1)}if(value=="["){results=[];for(;;hasMembers||(hasMembers=true)){value=lex();if(value=="]"){break}if(hasMembers){if(value==","){value=lex();if(value=="]"){abort()}}else{abort()}}if(value==","){abort()}results.push(get(value))}return results}else if(value=="{"){results={};for(;;hasMembers||(hasMembers=true)){value=lex();if(value=="}"){break}if(hasMembers){if(value==","){value=lex();if(value=="}"){abort()}}else{abort()}}if(value==","||typeof value!="string"||(charIndexBuggy?value.charAt(0):value[0])!="@"||lex()!=":"){abort()}results[value.slice(1)]=get(lex())}return results}abort()}return value};var update=function(source,property,callback){var element=walk(source,property,callback);if(element===undef){delete source[property]}else{source[property]=element}};var walk=function(source,property,callback){var value=source[property],length;if(typeof value=="object"&&value){if(getClass.call(value)==arrayClass){for(length=value.length;length--;){update(value,length,callback)}}else{forEach(value,function(property){update(value,property,callback)})}}return callback.call(source,property,value)};JSON3.parse=function(source,callback){var result,value;Index=0;Source=""+source;result=get(lex());if(lex()!="$"){abort()}Index=Source=null;return callback&&getClass.call(callback)==functionClass?walk((value={},value[""]=result,value),"",callback):result}}}if(isLoader){define(function(){return JSON3})}})(this)},{}],50:[function(_dereq_,module,exports){module.exports=toArray;function toArray(list,index){var array=[];index=index||0;for(var i=index||0;i
+ * jsb.fileUtils is the native file utils' singleton object,
+ * please refer to Cocos2d-x's API to know how to use it.
+ * Only available in JSB
+ * @class
+ * @name jsb.fileUtils
+ * @extend cc.Class
+ */
+jsb.fileUtils = /** @lends jsb.fileUtils# */{
+
+ /**
+ * @function fullPathForFilename
+ * @param {String} arg0
+ * @return {String}
+ */
+ fullPathForFilename : function (str)
+ {
+ return ;
+ },
+
+ /**
+ * @function getStringFromFile
+ * @param {String} arg0
+ * @return {String}
+ */
+ getStringFromFile : function (str)
+ {
+ return ;
+ },
+
+ /**
+ * @function removeFile
+ * @param {String} arg0
+ * @return {bool}
+ */
+ removeFile : function (str)
+ {
+ return false;
+ },
+
+ /**
+ * @function isAbsolutePath
+ * @param {String} arg0
+ * @return {bool}
+ */
+ isAbsolutePath : function (str)
+ {
+ return false;
+ },
+
+ /**
+ * @function renameFile
+ * @param {String} arg0
+ * @param {String} arg1
+ * @param {String} arg2
+ * @return {bool}
+ */
+ renameFile : function (arg0,arg1,arg2)
+ {
+ return false;
+ },
+
+ /**
+ * @function loadFilenameLookupDictionaryFromFile
+ * @param {String} arg0
+ */
+ loadFilenameLookupDictionaryFromFile : function (str)
+ {
+ },
+
+ /**
+ * @function isPopupNotify
+ * @return {bool}
+ */
+ isPopupNotify : function ()
+ {
+ return false;
+ },
+
+ /**
+ * @function getValueVectorFromFile
+ * @param {String} arg0
+ * @return {Array}
+ */
+ getValueVectorFromFile : function (str)
+ {
+ return new Array();
+ },
+
+ /**
+ * @function getSearchPaths
+ * @return {Array}
+ */
+ getSearchPaths : function ()
+ {
+ return new Array();
+ },
+
+ /**
+ * @function writeToFile
+ * @param {map_object} arg0
+ * @param {String} arg1
+ * @return {bool}
+ */
+ writeToFile : function (map, str)
+ {
+ return false;
+ },
+
+ /**
+ * @function getValueMapFromFile
+ * @param {String} arg0
+ * @return {map_object}
+ */
+ getValueMapFromFile : function (str)
+ {
+ return map_object;
+ },
+
+ /**
+ * @function getFileSize
+ * @param {String} arg0
+ * @return {long}
+ */
+ getFileSize : function (str)
+ {
+ return 0;
+ },
+
+ /**
+ * @function removeDirectory
+ * @param {String} arg0
+ * @return {bool}
+ */
+ removeDirectory : function (str)
+ {
+ return false;
+ },
+
+ /**
+ * @function setSearchPaths
+ * @param {Array} arg0
+ */
+ setSearchPaths : function (array)
+ {
+ },
+
+ /**
+ * @function writeStringToFile
+ * @param {String} arg0
+ * @param {String} arg1
+ * @return {bool}
+ */
+ writeStringToFile : function (arg0,arg1)
+ {
+ return false;
+ },
+
+ /**
+ * @function setSearchResolutionsOrder
+ * @param {Array} arg0
+ */
+ setSearchResolutionsOrder : function (array)
+ {
+ },
+
+ /**
+ * @function addSearchResolutionsOrder
+ * @param {String} arg0
+ */
+ addSearchResolutionsOrder : function (str)
+ {
+ },
+
+ /**
+ * @function addSearchPath
+ * @param {String} arg0
+ */
+ addSearchPath : function (str)
+ {
+ },
+
+ /**
+ * @function isFileExist
+ * @param {String} arg0
+ * @return {bool}
+ */
+ isFileExist : function (str)
+ {
+ return false;
+ },
+
+ /**
+ * @function purgeCachedEntries
+ */
+ purgeCachedEntries : function ()
+ {
+ },
+
+ /**
+ * @function fullPathFromRelativeFile
+ * @param {String} arg0
+ * @param {String} arg1
+ * @return {String}
+ */
+ fullPathFromRelativeFile : function (arg0,arg1)
+ {
+ return ;
+ },
+
+ /**
+ * @function isDirectoryExist
+ * @param {String} arg0
+ * @return {bool}
+ */
+ isDirectoryExist : function (str)
+ {
+ return false;
+ },
+
+ /**
+ * @function getSearchResolutionsOrder
+ * @return {Array}
+ */
+ getSearchResolutionsOrder : function ()
+ {
+ return new Array();
+ },
+
+ /**
+ * @function createDirectory
+ * @param {String} arg0
+ * @return {bool}
+ */
+ createDirectory : function (str)
+ {
+ return false;
+ },
+
+ /**
+ * @function createDirectories
+ * @param {String} arg0
+ * @return {bool}
+ */
+ createDirectories : function (str)
+ {
+ return false;
+ },
+
+ /**
+ * @function getWritablePath
+ * @return {String}
+ */
+ getWritablePath : function ()
+ {
+ return ;
+ }
+
+};
+
+/**
+ * @class
+ */
+jsb.EventAssetsManager = cc.Class.extend(/** @lends jsb.EventAssetsManager# */{
+
+ /**
+ * @function getAssetsManager
+ * @return {cc.AssetsManager}
+ */
+ getAssetsManager : function (
+ )
+ {
+ return cc.AssetsManager;
+ },
+
+ /**
+ * @function getAssetId
+ * @return {String}
+ */
+ getAssetId : function (
+ )
+ {
+ return ;
+ },
+
+ /**
+ * @function getCURLECode
+ * @return {int}
+ */
+ getCURLECode : function (
+ )
+ {
+ return 0;
+ },
+
+ /**
+ * @function getMessage
+ * @return {String}
+ */
+ getMessage : function (
+ )
+ {
+ return ;
+ },
+
+ /**
+ * @function getCURLMCode
+ * @return {int}
+ */
+ getCURLMCode : function (
+ )
+ {
+ return 0;
+ },
+
+ /**
+ * @function getPercentByFile
+ * @return {float}
+ */
+ getPercentByFile : function (
+ )
+ {
+ return 0;
+ },
+
+ /**
+ * @function getEventCode
+ * @return {number} cc.EventAssetsManager.EventCode
+ */
+ getEventCode : function (
+ )
+ {
+ return 0;
+ },
+
+ /**
+ * @function getPercent
+ * @return {float}
+ */
+ getPercent : function (
+ )
+ {
+ return 0;
+ },
+
+ /**
+ * @function EventAssetsManager
+ * @constructor
+ * @param {String} arg0
+ * @param {cc.AssetsManager} arg1
+ * @param {number} arg2 cc.EventAssetsManager::EventCode
+ * @param {float} arg3
+ * @param {float} arg4
+ * @param {String} arg5
+ * @param {String} arg6
+ * @param {int} arg7
+ * @param {int} arg8
+ */
+ EventAssetsManager : function (
+ arg0,
+ assetsmanager,
+ eventcode,
+ arg3,
+ arg4,
+ arg5,
+ arg6,
+ arg7,
+ arg8
+ )
+ {
+ }
+});
+
+
+/**
+ * @class
+ */
+jsb.EventListenerAssetsManager = cc.Class.extend(/** @lends jsb.EventListenerAssetsManager# */{
+
+ /**
+ * @function init
+ * @param {cc.AssetsManager} arg0
+ * @param {function} arg1
+ * @return {bool}
+ */
+ init : function (
+ assetsmanager,
+ func
+ )
+ {
+ return false;
+ },
+
+ /**
+ * @function create
+ * @param {cc.AssetsManager} arg0
+ * @param {function} arg1
+ * @return {cc.EventListenerAssetsManager}
+ */
+ create : function (
+ assetsmanager,
+ func
+ )
+ {
+ return cc.EventListenerAssetsManager;
+ },
+
+ /**
+ * @function EventListenerAssetsManager
+ * @constructor
+ */
+ EventListenerAssetsManager : function (
+ )
+ {
+ }
+
+});
+
+/**
+ * @class
+ * jsb.AssetsManager is the native AssetsManager for your game resources or scripts.
+ * please refer to this document to know how to use it: http://www.cocos2d-x.org/docs/manual/framework/html5/v3/assets-manager/en
+ * Only available in JSB
+ */
+jsb.AssetsManager = cc.Class.extend(/** @lends jsb.AssetsManager# */{
+
+ /**
+ * @function getState
+ * @return {number} jsb.AssetsManager::State
+ */
+ getState : function ()
+ {
+ return 0;
+ },
+
+ /**
+ * @function checkUpdate
+ */
+ checkUpdate : function ()
+ {
+ },
+
+ /**
+ * @function getStoragePath
+ * @return {String}
+ */
+ getStoragePath : function ()
+ {
+ return ;
+ },
+
+ /**
+ * @function update
+ */
+ update : function ()
+ {
+ },
+
+ /**
+ * @function getLocalManifest
+ * @return {object} jsb.Manifest
+ */
+ getLocalManifest : function ()
+ {
+ return cc.Manifest;
+ },
+
+ /**
+ * @function getRemoteManifest
+ * @return {jsb.Manifest}
+ */
+ getRemoteManifest : function ()
+ {
+ return cc.Manifest;
+ },
+
+ /**
+ * @function downloadFailedAssets
+ */
+ downloadFailedAssets : function ()
+ {
+ },
+
+ /**
+ * @function create
+ * @param {String} arg0
+ * @param {String} arg1
+ * @return {jsb.AssetsManager}
+ */
+ create : function (arg0,arg1)
+ {
+ return cc.AssetsManager;
+ },
+
+ /**
+ * @function AssetsManager
+ * @constructor
+ * @param {String} arg0
+ * @param {String} arg1
+ */
+ ctor : function (arg0,arg1)
+ {
+ }
+
+});
+
+/**
+ * @class
+ */
+jsb.Manifest = cc.Class.extend(/** @lends jsb.Manifest# */{
+
+ /**
+ * @function getManifestFileUrl
+ * @return {String}
+ */
+ getManifestFileUrl : function ()
+ {
+ return ;
+ },
+
+ /**
+ * @function isVersionLoaded
+ * @return {bool}
+ */
+ isVersionLoaded : function ()
+ {
+ return false;
+ },
+
+ /**
+ * @function isLoaded
+ * @return {bool}
+ */
+ isLoaded : function ()
+ {
+ return false;
+ },
+
+ /**
+ * @function getPackageUrl
+ * @return {String}
+ */
+ getPackageUrl : function ()
+ {
+ return ;
+ },
+
+ /**
+ * @function getVersion
+ * @return {String}
+ */
+ getVersion : function ()
+ {
+ return ;
+ },
+
+ /**
+ * @function getVersionFileUrl
+ * @return {String}
+ */
+ getVersionFileUrl : function ()
+ {
+ return ;
+ }
+});
+
+/**
+ * jsb.reflection is a bridge to let you invoke Java static functions.
+ * please refer to this document to know how to use it: http://www.cocos2d-x.org/docs/manual/framework/html5/v3/reflection/en
+ * Only available on iOS/Mac/Android platform
+ * @class
+ * @name jsb.reflection
+ */
+jsb.reflection = /** @lends jsb.reflection# */{
+ /**
+ * @function
+ */
+ callStaticMethod : function(){
+ }
+};
diff --git a/frameworks/cocos2d-html5/licenses/LICENSE_cocos2d-html5.txt b/frameworks/cocos2d-html5/licenses/LICENSE_cocos2d-html5.txt
new file mode 100644
index 0000000..eb8e4cf
--- /dev/null
+++ b/frameworks/cocos2d-html5/licenses/LICENSE_cocos2d-html5.txt
@@ -0,0 +1,23 @@
+cocos2d-html5 http://www.cocos2d-x.org
+
+Copyright (c) 2010-2011 - cocos2d-x community
+(see each file to see the different copyright owners)
+
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/licenses/LICENSE_cocos2d-x.txt b/frameworks/cocos2d-html5/licenses/LICENSE_cocos2d-x.txt
new file mode 100644
index 0000000..b0e4d70
--- /dev/null
+++ b/frameworks/cocos2d-html5/licenses/LICENSE_cocos2d-x.txt
@@ -0,0 +1,23 @@
+cocos2d-x http://www.cocos2d-x.org
+
+Copyright (c) 2010-2011 - cocos2d-x community
+(see each file to see the different copyright owners)
+
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/licenses/LICENSE_zlib.js.txt b/frameworks/cocos2d-html5/licenses/LICENSE_zlib.js.txt
new file mode 100644
index 0000000..489fd64
--- /dev/null
+++ b/frameworks/cocos2d-html5/licenses/LICENSE_zlib.js.txt
@@ -0,0 +1,28 @@
+/**
+ * @license
+ * zlib.js
+ * JavaScript Zlib Library
+ * https://github.com/imaya/zlib.js
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2012 imaya
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
diff --git a/frameworks/cocos2d-html5/moduleConfig.json b/frameworks/cocos2d-html5/moduleConfig.json
new file mode 100644
index 0000000..55a9e81
--- /dev/null
+++ b/frameworks/cocos2d-html5/moduleConfig.json
@@ -0,0 +1,494 @@
+{
+ "module" : {
+ "actions" : [
+ "core",
+
+ "cocos2d/actions/CCAction.js",
+ "cocos2d/actions/CCActionInterval.js",
+ "cocos2d/actions/CCActionInstant.js",
+ "cocos2d/actions/CCActionEase.js",
+ "cocos2d/actions/CCActionCatmullRom.js",
+ "cocos2d/actions/CCActionTween.js"
+ ],
+ "actions3d" : [
+ "core", "kazmath", "shaders", "actions", "effects", "render-texture",
+
+ "cocos2d/actions3d/CCActionGrid.js",
+ "cocos2d/actions3d/CCActionGrid3D.js",
+ "cocos2d/actions3d/CCActionTiledGrid.js",
+ "cocos2d/actions3d/CCActionPageTurn3D.js"
+ ],
+ "audio" : [
+ "core",
+
+ "cocos2d/audio/CCAudio.js"
+ ],
+ "clipping-nodes" : [
+ "core", "shape-nodes",
+
+ "cocos2d/clipping-nodes/CCClippingNode.js",
+ "cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js",
+ "cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js"
+ ],
+ "compression" : [
+ "core",
+
+ "cocos2d/compression/ZipUtils.js",
+ "cocos2d/compression/base64.js"
+ ],
+ "core" : [
+ "cocos2d/core/event-manager/CCEventHelper.js",
+ "CCDebugger.js",
+ "cocos2d/core/utils/BinaryLoader.js",
+ "Base64Images.js",
+ "cocos2d/core/platform/CCClass.js",
+ "cocos2d/core/platform/CCCommon.js",
+ "cocos2d/core/cocoa/CCGeometry.js",
+ "cocos2d/core/platform/CCSAXParser.js",
+ "cocos2d/core/platform/CCLoaders.js",
+ "cocos2d/core/platform/CCConfig.js",
+ "cocos2d/core/platform/miniFramework.js",
+ "cocos2d/core/platform/CCMacro.js",
+ "cocos2d/core/platform/CCTypes.js",
+ "cocos2d/core/platform/CCEGLView.js",
+ "cocos2d/core/platform/CCScreen.js",
+ "cocos2d/core/platform/CCVisibleRect.js",
+
+ "cocos2d/core/platform/CCInputManager.js",
+ "cocos2d/core/platform/CCInputExtension.js",
+
+ "cocos2d/core/cocoa/CCAffineTransform.js",
+ "cocos2d/core/support/CCPointExtension.js",
+ "cocos2d/core/support/CCVertex.js",
+ "cocos2d/core/support/TransformUtils.js",
+ "cocos2d/core/event-manager/CCTouch.js",
+
+ "cocos2d/core/event-manager/CCEvent.js",
+ "cocos2d/core/event-manager/CCEventListener.js",
+ "cocos2d/core/event-manager/CCEventManager.js",
+ "cocos2d/core/event-manager/CCEventExtension.js",
+
+ "cocos2d/core/renderer/GlobalVertexBuffer.js",
+ "cocos2d/core/renderer/RendererCanvas.js",
+ "cocos2d/core/renderer/RendererWebGL.js",
+ "cocos2d/core/renderer/DirtyRegion.js",
+ "cocos2d/core/base-nodes/BaseNodesPropertyDefine.js",
+ "cocos2d/core/base-nodes/CCNode.js",
+ "cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js",
+ "cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js",
+ "cocos2d/core/base-nodes/CCAtlasNode.js",
+ "cocos2d/core/base-nodes/CCAtlasNodeCanvasRenderCmd.js",
+ "cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js",
+
+ "cocos2d/core/textures/TexturesWebGL.js",
+ "cocos2d/core/textures/TexturesPropertyDefine.js",
+ "cocos2d/core/textures/CCTexture2D.js",
+ "cocos2d/core/textures/CCTextureCache.js",
+ "cocos2d/core/textures/CCTextureAtlas.js",
+
+ "cocos2d/core/scenes/CCScene.js",
+ "cocos2d/core/scenes/CCLoaderScene.js",
+
+ "cocos2d/core/layers/CCLayer.js",
+ "cocos2d/core/layers/CCLayerCanvasRenderCmd.js",
+ "cocos2d/core/layers/CCLayerWebGLRenderCmd.js",
+
+ "cocos2d/core/sprites/SpritesPropertyDefine.js",
+ "cocos2d/core/sprites/CCSprite.js",
+ "cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js",
+ "cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js",
+ "cocos2d/core/sprites/CCSpriteBatchNode.js",
+ "cocos2d/core/sprites/CCBakeSprite.js",
+ "cocos2d/core/sprites/CCAnimation.js",
+ "cocos2d/core/sprites/CCAnimationCache.js",
+ "cocos2d/core/sprites/CCSpriteFrame.js",
+ "cocos2d/core/sprites/CCSpriteFrameCache.js",
+ "cocos2d/core/CCConfiguration.js",
+
+ "cocos2d/core/CCDirector.js",
+ "cocos2d/core/CCDirectorCanvas.js",
+ "cocos2d/core/CCDirectorWebGL.js",
+
+ "cocos2d/core/CCScheduler.js",
+ "cocos2d/core/CCDrawingPrimitivesCanvas.js",
+ "cocos2d/core/CCDrawingPrimitivesWebGL.js",
+
+ "cocos2d/core/labelttf/LabelTTFPropertyDefine.js",
+ "cocos2d/core/labelttf/CCLabelTTF.js",
+ "cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js",
+ "cocos2d/core/labelttf/CCLabelTTFWebGLRenderCmd.js",
+
+ "cocos2d/core/CCActionManager.js",
+
+ "cocos2d/core/utils/CCProfiler.js"
+ ],
+ "effects" : [
+ "core",
+
+ "cocos2d/effects/CCGrid.js",
+ "cocos2d/effects/CCGrabber.js"
+ ],
+ "kazmath" : [
+ "core",
+
+ "cocos2d/kazmath/utility.js",
+ "cocos2d/kazmath/vec2.js",
+ "cocos2d/kazmath/vec3.js",
+ "cocos2d/kazmath/vec4.js",
+ "cocos2d/kazmath/ray2.js",
+ "cocos2d/kazmath/mat3.js",
+ "cocos2d/kazmath/mat4.js",
+ "cocos2d/kazmath/plane.js",
+ "cocos2d/kazmath/quaternion.js",
+ "cocos2d/kazmath/aabb.js",
+ "cocos2d/kazmath/gl/mat4stack.js",
+ "cocos2d/kazmath/gl/matrix.js"
+ ],
+ "kazmathSIMD" : [
+ "kazmath",
+
+ "cocos2d/kazmath/vec3SIMD.js",
+ "cocos2d/kazmath/mat4SIMD.js",
+ "cocos2d/kazmath/SIMDPolyfill.js"
+ ],
+ "labels" : [
+ "core",
+ "cocos2d/labels/CCLabelBMFont.js",
+ "cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js",
+ "cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js",
+ "cocos2d/labels/CCLabelAtlas.js",
+ "cocos2d/labels/CCLabelAtlasCanvasRenderCmd.js",
+ "cocos2d/labels/CCLabelAtlasWebGLRenderCmd.js"
+ ],
+ "menus" : [
+ "core", "actions",
+
+ "cocos2d/menus/CCMenuItem.js",
+ "cocos2d/menus/CCMenu.js"
+ ],
+ "motion-streak" : [
+ "core", "shaders", "kazmath", "labels",
+
+ "cocos2d/motion-streak/CCMotionStreak.js",
+ "cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js"
+ ],
+ "node-grid" : [
+ "core",
+
+ "cocos2d/node-grid/CCNodeGrid.js",
+ "cocos2d/node-grid/CCNodeGridWebGLRenderCmd.js"
+ ],
+ "parallax" : [
+ "core",
+
+ "cocos2d/parallax/CCParallaxNode.js",
+ "cocos2d/parallax/CCParallaxNodeRenderCmd.js"
+ ],
+ "particle" : [
+ "core", "compression",
+
+ "cocos2d/particle/CCPNGReader.js",
+ "cocos2d/particle/CCTIFFReader.js",
+ "cocos2d/particle/CCParticleSystem.js",
+ "cocos2d/particle/CCParticleSystemCanvasRenderCmd.js",
+ "cocos2d/particle/CCParticleSystemWebGLRenderCmd.js",
+ "cocos2d/particle/CCParticleExamples.js",
+ "cocos2d/particle/CCParticleBatchNode.js",
+ "cocos2d/particle/CCParticleBatchNodeCanvasRenderCmd.js",
+ "cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js"
+ ],
+ "physics" : [
+ "core", "shape-nodes",
+
+ "cocos2d/physics/CCPhysicsSprite.js",
+ "cocos2d/physics/CCPhysicsDebugNode.js",
+ "cocos2d/physics/CCPhysicsDebugNodeCanvasRenderCmd.js",
+ "cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js",
+ "cocos2d/physics/CCPhysicsSpriteCanvasRenderCmd.js",
+ "cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js"
+ ],
+ "progress-timer" : [
+ "core", "actions",
+
+ "cocos2d/progress-timer/CCProgressTimer.js",
+ "cocos2d/progress-timer/CCActionProgressTimer.js",
+ "cocos2d/progress-timer/CCProgressTimerCanvasRenderCmd.js",
+ "cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js"
+ ],
+ "render-texture" : [
+ "core",
+
+ "cocos2d/render-texture/CCRenderTexture.js",
+ "cocos2d/render-texture/CCRenderTextureCanvasRenderCmd.js",
+ "cocos2d/render-texture/CCRenderTextureWebGLRenderCmd.js"
+ ],
+ "shaders" : [
+ "core", "kazmath",
+
+ "cocos2d/shaders/CCShaders.js",
+ "cocos2d/shaders/CCShaderCache.js",
+ "cocos2d/shaders/CCGLProgram.js",
+ "cocos2d/shaders/CCGLProgramState.js",
+ "cocos2d/shaders/CCGLStateCache.js"
+ ],
+ "shape-nodes" : [
+ "core",
+
+ "cocos2d/shape-nodes/CCDrawNode.js",
+ "cocos2d/shape-nodes/CCDrawNodeCanvasRenderCmd.js",
+ "cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js"
+ ],
+ "text-input" : [
+ "core",
+
+ "cocos2d/text-input/CCIMEDispatcher.js",
+ "cocos2d/text-input/CCTextFieldTTF.js"
+ ],
+ "tilemap" : [
+ "core", "compression",
+
+ "cocos2d/compression/gzip.js",
+ "cocos2d/compression/zlib.min.js",
+
+ "cocos2d/tilemap/CCTGAlib.js",
+ "cocos2d/tilemap/CCTMXTiledMap.js",
+ "cocos2d/tilemap/CCTMXXMLParser.js",
+ "cocos2d/tilemap/CCTMXObjectGroup.js",
+ "cocos2d/tilemap/CCTMXLayer.js",
+ "cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js",
+ "cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js"
+ ],
+ "transitions" : [
+ "core", "actions", "render-texture", "progress-timer",
+
+ "cocos2d/transitions/CCTransition.js",
+ "cocos2d/transitions/CCTransitionProgress.js",
+ "cocos2d/transitions/CCTransitionPageTurn.js"
+ ],
+
+ "base4webgl" : ["core", "kazmath", "shaders"],
+ "cocos2d" : [
+ "core", "kazmath", "shaders", "render-texture", "motion-streak", "node-grid",
+ "clipping-nodes", "effects", "shape-nodes", "actions", "actions3d",
+ "progress-timer", "transitions", "labels", "compression", "particle",
+ "text-input", "menus", "tilemap", "parallax", "audio"
+ ],
+
+ "ccbreader" : [
+ "core", "audio", "gui", "menus", "particle", "actions", "labels",
+
+ "extensions/ccb-reader/CCNodeLoader.js",
+ "extensions/ccb-reader/CCBReaderUtil.js",
+ "extensions/ccb-reader/CCControlLoader.js",
+ "extensions/ccb-reader/CCSpriteLoader.js",
+ "extensions/ccb-reader/CCNodeLoaderLibrary.js",
+ "extensions/ccb-reader/CCBReader.js",
+ "extensions/ccb-reader/CCBValue.js",
+ "extensions/ccb-reader/CCBKeyframe.js",
+ "extensions/ccb-reader/CCBSequence.js",
+ "extensions/ccb-reader/CCBRelativePositioning.js",
+ "extensions/ccb-reader/CCBAnimationManager.js"
+ ],
+ "editbox" : [
+ "core", "gui",
+
+ "extensions/editbox/CCEditBox.js"
+ ],
+ "ccpool" : [
+ "core",
+
+ "extensions/ccpool/CCPool.js"
+ ],
+ "ccui" : [
+ "core", "actions", "labels", "text-input","clipping-nodes",
+ "extensions/ccui/base-classes/CCProtectedNode.js",
+ "extensions/ccui/base-classes/CCProtectedNodeCanvasRenderCmd.js",
+ "extensions/ccui/base-classes/CCProtectedNodeWebGLRenderCmd.js",
+ "extensions/ccui/system/CocosGUI.js",
+ "extensions/ccui/base-classes/UIWidget.js",
+ "extensions/ccui/base-classes/UIWidgetRenderCmd.js",
+ "extensions/ccui/base-classes/UIScale9Sprite.js",
+ "extensions/ccui/base-classes/UIScale9SpriteCanvasRenderCmd.js",
+ "extensions/ccui/base-classes/UIScale9SpriteWebGLRenderCmd.js",
+ "extensions/ccui/layouts/UILayout.js",
+ "extensions/ccui/layouts/UILayoutCanvasRenderCmd.js",
+ "extensions/ccui/layouts/UILayoutWebGLRenderCmd.js",
+ "extensions/ccui/layouts/UILayoutParameter.js",
+ "extensions/ccui/layouts/UILayoutManager.js",
+ "extensions/ccui/layouts/UIHBox.js",
+ "extensions/ccui/layouts/UIRelativeBox.js",
+ "extensions/ccui/layouts/UIVBox.js",
+ "extensions/ccui/system/UIHelper.js",
+ "extensions/ccui/uiwidgets/UIButton.js",
+ "extensions/ccui/uiwidgets/UICheckBox.js",
+ "extensions/ccui/uiwidgets/UIImageView.js",
+ "extensions/ccui/uiwidgets/UILoadingBar.js",
+ "extensions/ccui/uiwidgets/UISlider.js",
+ "extensions/ccui/uiwidgets/UIText.js",
+ "extensions/ccui/uiwidgets/UITextAtlas.js",
+ "extensions/ccui/uiwidgets/UITextBMFont.js",
+ "extensions/ccui/uiwidgets/UITextField.js",
+ "extensions/ccui/uiwidgets/UIVideoPlayer.js",
+ "extensions/ccui/uiwidgets/UIRichText.js",
+ "extensions/ccui/uiwidgets/UIWebView.js",
+ "extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js",
+ "extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js",
+ "extensions/ccui/uiwidgets/scroll-widget/UIListView.js",
+ "extensions/ccui/uiwidgets/scroll-widget/UIPageView.js",
+ "extensions/ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js",
+ "extensions/ccui/uiwidgets/scroll-widget/UIScrollViewCanvasRenderCmd.js",
+ "extensions/ccui/uiwidgets/scroll-widget/UIScrollViewWebGLRenderCmd.js"
+ ],
+ "cocostudio" : [
+ "core", "tilemap", "particle", "shape-nodes", "ccui",
+
+ "extensions/cocostudio/components/CCComponent.js",
+ "extensions/cocostudio/components/CCComponentContainer.js",
+ "extensions/ccui/layouts/UILayoutComponent.js",
+ "extensions/cocostudio/CocoStudio.js",
+
+ "extensions/cocostudio/armature/utils/CCArmatureDefine.js",
+ "extensions/cocostudio/armature/utils/CCDataReaderHelper.js",
+ "extensions/cocostudio/armature/utils/CCSpriteFrameCacheHelper.js",
+ "extensions/cocostudio/armature/utils/CCTransformHelp.js",
+ "extensions/cocostudio/armature/utils/CCTweenFunction.js",
+ "extensions/cocostudio/armature/utils/CCUtilMath.js",
+ "extensions/cocostudio/armature/utils/CCArmatureDataManager.js",
+ "extensions/cocostudio/armature/datas/CCDatas.js",
+ "extensions/cocostudio/armature/display/CCDecorativeDisplay.js",
+ "extensions/cocostudio/armature/display/CCDisplayFactory.js",
+ "extensions/cocostudio/armature/display/CCDisplayManager.js",
+ "extensions/cocostudio/armature/display/CCSkin.js",
+ "extensions/cocostudio/armature/display/CCSkinRenderCmd.js",
+ "extensions/cocostudio/armature/animation/CCProcessBase.js",
+ "extensions/cocostudio/armature/animation/CCArmatureAnimation.js",
+ "extensions/cocostudio/armature/animation/CCTween.js",
+ "extensions/cocostudio/armature/physics/CCColliderDetector.js",
+ "extensions/cocostudio/armature/CCArmature.js",
+ "extensions/cocostudio/armature/CCArmatureCanvasRenderCmd.js",
+ "extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js",
+ "extensions/cocostudio/armature/CCBone.js",
+
+ "extensions/cocostudio/action/CCActionFrame.js",
+ "extensions/cocostudio/action/CCActionManager.js",
+ "extensions/cocostudio/action/CCActionNode.js",
+ "extensions/cocostudio/action/CCActionObject.js",
+
+ "extensions/cocostudio/components/CCComAttribute.js",
+ "extensions/cocostudio/components/CCComAudio.js",
+ "extensions/cocostudio/components/CCComController.js",
+ "extensions/cocostudio/components/CCComRender.js",
+
+ "extensions/cocostudio/trigger/ObjectFactory.js",
+ "extensions/cocostudio/trigger/TriggerBase.js",
+ "extensions/cocostudio/trigger/TriggerMng.js",
+ "extensions/cocostudio/trigger/TriggerObj.js",
+
+ "extensions/cocostudio/timeline/ActionTimeline.js",
+ "extensions/cocostudio/timeline/Frame.js",
+ "extensions/cocostudio/timeline/Timeline.js",
+
+ "extensions/cocostudio/timeline/CCSkinNode.js",
+ "extensions/cocostudio/timeline/CCBoneNode.js",
+ "extensions/cocostudio/timeline/CCSkeletonNode.js",
+
+ "extensions/cocostudio/loader/load.js",
+ "extensions/cocostudio/loader/parsers/scene-1.x.js",
+ "extensions/cocostudio/loader/parsers/uiParser-1.x.js",
+ "extensions/cocostudio/loader/parsers/action-1.x.js",
+ "extensions/cocostudio/loader/parsers/action-2.x.js",
+ "extensions/cocostudio/loader/parsers/timelineParser-1.x.js",
+ "extensions/cocostudio/loader/parsers/timelineParser-2.x.js",
+ "extensions/cocostudio/loader/parsers/compatible.js"
+
+
+ ],
+ "gui" : [
+ "core", "clipping-nodes", "render-texture", "actions", "progress-timer",
+
+ "extensions/gui/control-extension/CCControl.js",
+ "extensions/gui/control-extension/CCControlButton.js",
+ "extensions/gui/control-extension/CCControlUtils.js",
+ "extensions/gui/control-extension/CCInvocation.js",
+ "extensions/gui/control-extension/CCMenuPassive.js",
+ "extensions/gui/control-extension/CCControlSaturationBrightnessPicker.js",
+ "extensions/gui/control-extension/CCControlHuePicker.js",
+ "extensions/gui/control-extension/CCControlColourPicker.js",
+ "extensions/gui/control-extension/CCControlSlider.js",
+ "extensions/gui/control-extension/CCControlSwitch.js",
+ "extensions/gui/control-extension/CCControlStepper.js",
+ "extensions/gui/control-extension/CCControlPotentiometer.js",
+ "extensions/gui/scrollview/CCScrollView.js",
+ "extensions/gui/scrollview/CCScrollViewCanvasRenderCmd.js",
+ "extensions/gui/scrollview/CCScrollViewWebGLRenderCmd.js",
+ "extensions/gui/scrollview/CCSorting.js",
+ "extensions/gui/scrollview/CCTableView.js"
+ ],
+
+ "pluginx" : [
+ "core",
+
+ "external/pluginx/Plugin.js"
+ ],
+ "plugin-facebook" : [
+ "external/pluginx/platform/facebook_sdk.js",
+ "external/pluginx/platform/facebook.js"
+ ],
+
+ "spine":[
+ "core",
+
+ "extensions/spine/Spine.js",
+ "extensions/spine/CCSkeleton.js",
+ "extensions/spine/CCSkeletonAnimation.js",
+ "extensions/spine/CCSkeletonTexture.js",
+ "extensions/spine/CCSkeletonCanvasRenderCmd.js",
+ "extensions/spine/CCSkeletonWebGLRenderCmd.js"
+ ],
+ "gaf":[
+ "core",
+
+ "external/gaf/GAFMacros.js",
+ "external/gaf/GAFBoot.js",
+ "external/gaf/Library/GAFAssetPreload.js",
+ "external/gaf/Library/GAFAsset.js",
+ "external/gaf/Library/GAFObject.js",
+ "external/gaf/Library/GAFTimeLine.js",
+ "external/gaf/Library/GAFTextField.js",
+ "external/gaf/Library/GAFSprite.js",
+ "external/gaf/Library/GAFMask.js",
+ "external/gaf/Library/GAFSpriteCanvasRenderCmd.js",
+ "external/gaf/Library/GAFSpriteWebGLRenderCmd.js",
+ "external/gaf/Library/GAFTimeLineProto.js",
+ "external/gaf/Library/GAFSpriteProto.js",
+ "external/gaf/Library/GAFMaskProto.js",
+ "external/gaf/Library/GAFTags.js",
+ "external/gaf/Library/GAFLoader.js",
+ "external/gaf/Library/GAFDataReader.js",
+ "external/gaf/Library/GAFShaders.js",
+ "external/gaf/Library/GAFShaderManager.js",
+ "external/gaf/Library/GAFAtlasLoader.js"
+ ],
+ "extensions" : ["gui", "ccbreader", "editbox", "cocostudio", "spine", "ccpool"],
+
+ "box2d" : [
+ "core", "physics",
+
+ "external/box2d/box2d.js"
+ ],
+ "chipmunk" : [
+ "core", "physics",
+
+ "external/chipmunk/chipmunk.js"
+ ],
+ "runtime":[
+ "core",
+ "extensions/runtime/CCLoaderLayer.js"
+ ],
+ "socketio" : [
+ "external/socketio/socket.io.min.js"
+ ],
+ "external" : ["box2d", "chipmunk", "socketio", "pluginx", "gaf"]
+ },
+ "bootFile" : "CCBoot.js"
+}
diff --git a/frameworks/cocos2d-html5/template/index.html b/frameworks/cocos2d-html5/template/index.html
new file mode 100644
index 0000000..e0f577b
--- /dev/null
+++ b/frameworks/cocos2d-html5/template/index.html
@@ -0,0 +1,29 @@
+
+
+
+
+ Cocos2d-html5 Hello World test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/template/main.js b/frameworks/cocos2d-html5/template/main.js
new file mode 100644
index 0000000..b0afefa
--- /dev/null
+++ b/frameworks/cocos2d-html5/template/main.js
@@ -0,0 +1,21 @@
+cc.game.onStart = function(){
+ if(!cc.sys.isNative && document.getElementById("cocosLoading")) //If referenced loading.js, please remove it
+ document.body.removeChild(document.getElementById("cocosLoading"));
+
+ var designSize = cc.size(480, 800);
+ var screenSize = cc.view.getFrameSize();
+
+ if(!cc.sys.isNative && screenSize.height < 800){
+ designSize = cc.size(320, 480);
+ cc.loader.resPath = "res/Normal";
+ }else{
+ cc.loader.resPath = "res/HD";
+ }
+ cc.view.setDesignResolutionSize(designSize.width, designSize.height, cc.ResolutionPolicy.SHOW_ALL);
+
+ //load resources
+ cc.LoaderScene.preload(g_resources, function () {
+ cc.director.runScene(new MyScene());
+ }, this);
+};
+cc.game.run();
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/template/project.json b/frameworks/cocos2d-html5/template/project.json
new file mode 100644
index 0000000..a4a9435
--- /dev/null
+++ b/frameworks/cocos2d-html5/template/project.json
@@ -0,0 +1,16 @@
+{
+ "debugMode" : 1,
+ "noCache": false,
+ "showFPS" : true,
+ "frameRate" : 60,
+ "id" : "gameCanvas",
+ "renderMode" : 0,
+ "engineDir":"../",
+
+ "modules" : ["cocos2d"],
+
+ "jsList" : [
+ "src/resource.js",
+ "src/myApp.js"
+ ]
+}
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/template/res/HD/CloseNormal.png b/frameworks/cocos2d-html5/template/res/HD/CloseNormal.png
new file mode 100644
index 0000000..5657a13
Binary files /dev/null and b/frameworks/cocos2d-html5/template/res/HD/CloseNormal.png differ
diff --git a/frameworks/cocos2d-html5/template/res/HD/CloseSelected.png b/frameworks/cocos2d-html5/template/res/HD/CloseSelected.png
new file mode 100644
index 0000000..e4c82da
Binary files /dev/null and b/frameworks/cocos2d-html5/template/res/HD/CloseSelected.png differ
diff --git a/frameworks/cocos2d-html5/template/res/HD/HelloWorld.jpg b/frameworks/cocos2d-html5/template/res/HD/HelloWorld.jpg
new file mode 100644
index 0000000..1252ec6
Binary files /dev/null and b/frameworks/cocos2d-html5/template/res/HD/HelloWorld.jpg differ
diff --git a/frameworks/cocos2d-html5/template/res/Normal/CloseNormal.png b/frameworks/cocos2d-html5/template/res/Normal/CloseNormal.png
new file mode 100644
index 0000000..8c7d4ff
Binary files /dev/null and b/frameworks/cocos2d-html5/template/res/Normal/CloseNormal.png differ
diff --git a/frameworks/cocos2d-html5/template/res/Normal/CloseSelected.png b/frameworks/cocos2d-html5/template/res/Normal/CloseSelected.png
new file mode 100644
index 0000000..25e3ab3
Binary files /dev/null and b/frameworks/cocos2d-html5/template/res/Normal/CloseSelected.png differ
diff --git a/frameworks/cocos2d-html5/template/res/Normal/HelloWorld.jpg b/frameworks/cocos2d-html5/template/res/Normal/HelloWorld.jpg
new file mode 100644
index 0000000..76e04b5
Binary files /dev/null and b/frameworks/cocos2d-html5/template/res/Normal/HelloWorld.jpg differ
diff --git a/frameworks/cocos2d-html5/template/res/favicon.ico b/frameworks/cocos2d-html5/template/res/favicon.ico
new file mode 100644
index 0000000..1ad6a09
Binary files /dev/null and b/frameworks/cocos2d-html5/template/res/favicon.ico differ
diff --git a/frameworks/cocos2d-html5/template/res/loading.js b/frameworks/cocos2d-html5/template/res/loading.js
new file mode 100644
index 0000000..d17a700
--- /dev/null
+++ b/frameworks/cocos2d-html5/template/res/loading.js
@@ -0,0 +1 @@
+(function(){var createStyle=function(){return".cocosLoading{position:absolute;margin:-30px -60px;padding:0;top:50%;left:50%}"+".cocosLoading ul{margin:0;padding:0;}"+".cocosLoading span{color:#FFF;text-align:center;display:block;}"+".cocosLoading li{list-style:none;float:left;border-radius:15px;width:15px;height:15px;background:#FFF;margin:5px 0 0 10px}"+".cocosLoading li .ball,.cocosLoading li .unball{background-color:#2187e7;background-image:-moz-linear-gradient(90deg,#2187e7 25%,#a0eaff);background-image:-webkit-linear-gradient(90deg,#2187e7 25%,#a0eaff);width:15px;height:15px;border-radius:50px}"+".cocosLoading li .ball{transform:scale(0);-moz-transform:scale(0);-webkit-transform:scale(0);animation:showDot 1s linear forwards;-moz-animation:showDot 1s linear forwards;-webkit-animation:showDot 1s linear forwards}"+".cocosLoading li .unball{transform:scale(1);-moz-transform:scale(1);-webkit-transform:scale(1);animation:hideDot 1s linear forwards;-moz-animation:hideDot 1s linear forwards;-webkit-animation:hideDot 1s linear forwards}"+"@keyframes showDot{0%{transform:scale(0,0)}100%{transform:scale(1,1)}}"+"@-moz-keyframes showDot{0%{-moz-transform:scale(0,0)}100%{-moz-transform:scale(1,1)}}"+"@-webkit-keyframes showDot{0%{-webkit-transform:scale(0,0)}100%{-webkit-transform:scale(1,1)}}"+"@keyframes hideDot{0%{transform:scale(1,1)}100%{transform:scale(0,0)}}"+"@-moz-keyframes hideDot{0%{-moz-transform:scale(1,1)}100%{-moz-transform:scale(0,0)}}"+"@-webkit-keyframes hideDot{0%{-webkit-transform:scale(1,1)}100%{-webkit-transform:scale(0,0)}}"};var createDom=function(id,num){id=id||"cocosLoading";num=num||5;var i,item;var div=document.createElement("div");div.className="cocosLoading";div.id=id;var bar=document.createElement("ul");var list=[];for(i=0;i=list.length){direction=!direction;index=0;time=1000}else{time=300}animation()},time)};animation()};(function(){var bgColor=document.body.style.background;document.body.style.background="#000";var style=document.createElement("style");style.type="text/css";style.innerHTML=createStyle();document.head.appendChild(style);var list=createDom();startAnimation(list,function(){var div=document.getElementById("cocosLoading");if(!div){document.body.style.background=bgColor}return !!div})})()})();
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/template/src/myApp.js b/frameworks/cocos2d-html5/template/src/myApp.js
new file mode 100644
index 0000000..f91b7c4
--- /dev/null
+++ b/frameworks/cocos2d-html5/template/src/myApp.js
@@ -0,0 +1,57 @@
+var MyLayer = cc.Layer.extend({
+ helloLabel:null,
+ sprite:null,
+
+ init:function () {
+
+ //////////////////////////////
+ // 1. super init first
+ this._super();
+
+ /////////////////////////////
+ // 2. add a menu item with "X" image, which is clicked to quit the program
+ // you may modify it.
+ // ask director the window size
+ var size = cc.director.getWinSize();
+
+ // add a "close" icon to exit the progress. it's an autorelease object
+ var closeItem = new cc.MenuItemImage(
+ s_CloseNormal,
+ s_CloseSelected,
+ function () {
+ cc.log("close");
+ },this);
+ closeItem.setAnchorPoint(0.5, 0.5);
+
+ var menu = new cc.Menu(closeItem);
+ menu.setPosition(0, 0);
+ this.addChild(menu, 1);
+ closeItem.setPosition(size.width - 20, 20);
+
+ /////////////////////////////
+ // 3. add your codes below...
+ // add a label shows "Hello World"
+ // create and initialize a label
+ this.helloLabel = new cc.LabelTTF("Hello World", "Impact", 38);
+ // position the label on the center of the screen
+ this.helloLabel.setPosition(size.width / 2, size.height - 40);
+ // add the label as a child to this layer
+ this.addChild(this.helloLabel, 5);
+
+ // add "Helloworld" splash screen"
+ this.sprite = new cc.Sprite(s_HelloWorld);
+ this.sprite.setAnchorPoint(0.5, 0.5);
+ this.sprite.setPosition(size.width / 2, size.height / 2);
+ this.sprite.setScale(size.height / this.sprite.getContentSize().height);
+ this.addChild(this.sprite, 0);
+ }
+});
+
+var MyScene = cc.Scene.extend({
+ onEnter:function () {
+ this._super();
+ var layer = new MyLayer();
+ this.addChild(layer);
+ layer.init();
+ }
+});
diff --git a/frameworks/cocos2d-html5/template/src/resource.js b/frameworks/cocos2d-html5/template/src/resource.js
new file mode 100644
index 0000000..9428408
--- /dev/null
+++ b/frameworks/cocos2d-html5/template/src/resource.js
@@ -0,0 +1,20 @@
+var s_HelloWorld = "HelloWorld.jpg";
+var s_CloseNormal = "CloseNormal.png";
+var s_CloseSelected = "CloseSelected.png";
+
+var g_resources = [
+ //image
+ s_HelloWorld,
+ s_CloseNormal,
+ s_CloseSelected
+
+ //plist
+
+ //fnt
+
+ //tmx
+
+ //bgm
+
+ //effect
+];
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/tools/XmlCheck.js b/frameworks/cocos2d-html5/tools/XmlCheck.js
new file mode 100644
index 0000000..159933c
--- /dev/null
+++ b/frameworks/cocos2d-html5/tools/XmlCheck.js
@@ -0,0 +1,143 @@
+const fs = require("fs");
+const path = require("path");
+const modules = JSON.parse(fs.readFileSync("../moduleConfig.json"));
+
+var contains = [
+ "../cocos2d",
+ "../extensions",
+ "../external",
+ "../Base64Images.js",
+ "../CCBoot.js",
+ "../CCDebugger.js"
+];
+(function(){
+ var i = 0;
+ function read(name){
+ if(fs.existsSync(name)){
+ var stat = fs.statSync(name);
+ if(stat.isDirectory()){
+ contains.splice(i--, 1);
+ var fileList = fs.readdirSync(name);
+ for(var n=0; n((.|\r\n|\r|\n)*?)\<\/sources/g, function(a, b){
+ a.replace(/file name\=\"(.*)\"\/\>/g, function(c, d){
+ arr[index] && arr[index].push("../" + d);
+ });
+ index++;
+ });
+})();
+console.log(" The number of files in the XML file : %s", xmlFile.length);
+
+contains = contains.map(function(a){
+ return path.normalize(a);
+});
+moduleFile = moduleFile.map(function(a){
+ return path.normalize(a);
+});
+xmlFile = xmlFile.map(function(a){
+ return path.normalize(a);
+});
+xmlFile2 = xmlFile2.map(function(a){
+ return path.normalize(a);
+});
+
+console.log("\x1B[0m\x1B[33m");
+console.log(" warn : moduleConfig missing...");
+contains.forEach(function(a){
+ if(!moduleFile.some(function(b){return b==a}))
+ console.log(" " + a);
+});
+
+
+console.log("\x1B[0m\x1B[92m");
+console.log(" warn : engine dir missing...");
+moduleFile.forEach(function(a){
+ if(!contains.some(function(b){return b==a}))
+ console.log(" " + a);
+});
+
+
+console.log("\x1B[0m\x1B[96m");
+console.log(" warn : xml(all) file missing...");
+contains.forEach(function(a){
+ if(!xmlFile.some(function(b){return b==a}))
+ console.log(" " + a);
+});
+
+
+console.log("\x1B[0m\x1B[91m");
+console.log(" warn : xml(all) redundant files...");
+xmlFile.forEach(function(a){
+ if(!contains.some(function(b){return b==a}))
+ console.log(" " + a);
+});
+
+
+console.log("\x1B[0m\x1B[94m");
+console.log(" warn : xml(core) maybe missing files...");
+xmlFile2.forEach(function(a){
+ var basename = path.basename(a);
+ basename = basename.substr(0, basename.indexOf("."));
+ contains.forEach(function(b){
+ if(b.indexOf(basename) > -1 && a != b){
+ if(
+ b.indexOf("extensions") == -1 &&
+ !xmlFile2.some(function(c){return b == c;})
+ )
+ console.log(" " + b);
+ }
+ });
+});
+
+
+console.log("\x1B[0m\x1B[35m");
+console.log(" warn : xml(core) redundant files...");
+xmlFile2.forEach(function(a){
+ if(!contains.some(function(b){return b==a}))
+ console.log(" " + a);
+});
+console.log("\x1B[0m");
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/tools/build.xml b/frameworks/cocos2d-html5/tools/build.xml
new file mode 100644
index 0000000..519f986
--- /dev/null
+++ b/frameworks/cocos2d-html5/tools/build.xml
@@ -0,0 +1,377 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frameworks/cocos2d-html5/tools/compiler/compiler.jar b/frameworks/cocos2d-html5/tools/compiler/compiler.jar
new file mode 100644
index 0000000..ffd565c
Binary files /dev/null and b/frameworks/cocos2d-html5/tools/compiler/compiler.jar differ
diff --git a/frameworks/cocos2d-html5/tools/core4cc.js b/frameworks/cocos2d-html5/tools/core4cc.js
new file mode 100644
index 0000000..3aea755
--- /dev/null
+++ b/frameworks/cocos2d-html5/tools/core4cc.js
@@ -0,0 +1,245 @@
+var fs = require("fs");
+var path = require("path");
+var exec = require('child_process').exec;
+var spawn = require('child_process').spawn;
+var url = require('url');
+
+var core4cc = {};
+module.exports = core4cc;
+
+/**
+ * Desc:merge js code from client to server.
+ * @param src src path
+ * @param targetDir target path
+ * @param requireArr dependencies
+ * @param name
+ */
+core4cc.trans2Module = function(src, targetDir, requireArr, name){
+ if(!fs.existsSync(targetDir)) fs.mkdirSync(targetDir);
+ var srcBaseName = path.basename(src);
+ name = name || path.basename(src, ".js");
+ var content = fs.readFileSync(src).toString();
+ var requireStr = "";
+ for(var i = 0, li = requireArr.length; i < li; ++i){
+ var strs = requireArr[i].split("->");
+ requireStr = requireStr + "var " + strs[0] + " = require('" + strs[1] + "');\r\n";
+ }
+ fs.writeFileSync(targetDir + srcBaseName, requireStr + content + "\r\nmodule.exports = " + name + ";");
+};
+
+/**
+ * Desc:merge js arr to one
+ * @param srcs
+ * @param target
+ * @param requireArr
+ * @param name
+ */
+core4cc.merge2Module = function(srcs, target, requireArr, name){
+ var targetDir = path.dirname(target);
+ if(!fs.existsSync(targetDir)) fs.mkdirSync(targetDir);
+ var content = "";
+ for(var i = 0, li = srcs.length; i < li; ++i){
+ content += fs.readFileSync(srcs[i]).toString() + "\r\n";
+ }
+ var requireStr = "";
+ for(var i = 0, li = requireArr.length; i < li; ++i){
+ var strs = requireArr[i].split("->");
+ requireStr = requireStr + "var " + strs[0] + " = require('" + strs[1] + "');\r\n";
+ }
+ fs.writeFileSync(target, requireStr + content + "\r\nmodule.exports = " + name + ";");
+};
+
+/**
+ * dESC: Get key name by the file name.
+ * @param name
+ * @returns {String}
+ */
+core4cc.getKeyName = function(name){
+ var key = name.replace(/[.]/g, "_");
+ key = key.replace(/[\-\(\)]/g, "_");
+ var r = key.match(/^[0-9]/);
+ if(r != null) key = "_" + key;
+ return key.replace(/\s/g, "");
+};
+/**
+ * Desc: Returns array for dependencies.
+ * @param temp
+ * @returns {Array}
+ * @private
+ */
+core4cc.getDependencies = function(temp){
+ var dependencies = [];
+ for(var key in temp){
+ dependencies.push(key);
+ };
+ return dependencies;
+};
+
+/**
+ * Desc: unzip
+ * @param srcZip
+ * @param targetDir
+ * @param cb
+ */
+core4cc.unzip = function(srcZip, targetDir, cb){
+ var execCode = "unzip " + srcZip + " -d " + targetDir;
+ exec(execCode, function(err, data, info){
+ if(err) return cb(err);
+ else cb(null);
+ });
+};
+
+
+
+/**
+ * Desc: Download resources.
+ * @param downLoadDir
+ * @param fileUrl
+ * @param cb
+ */
+core4cc.download = function(downLoadDir, fileUrl, cb) {
+ // extract the file name
+ var fileName = url.parse(fileUrl).pathname.split('/').pop();
+ // create an instance of writable stream
+ var file = fs.createWriteStream(path.join(downLoadDir, fileName));
+ // execute curl using child_process' spawn function
+ var curl = spawn('curl', [fileUrl]);
+ // add a 'data' event listener for the spawn instance
+ curl.stdout.on('data', function(data) { file.write(data); });
+ // add an 'end' event listener to close the writeable stream
+ curl.stdout.on('end', function(data) {
+ file.end();
+ console.log(fileName + ' downloaded to ' + downLoadDir);
+ cb(null);
+ });
+ // when the spawn child process exits, check if there were any errors and close the writeable stream
+ curl.on('exit', function(code) {
+ if (code != 0) {
+ console.error('Failed: ' + code);
+ cb("error")
+ }
+ });
+};
+
+/**
+ * Desc: Remove dir recursively.
+ * @param filePath
+ * @param ignores
+ */
+core4cc.rmdirSyncRecursive = function(filePath, ignores) {
+ var files = [];
+ if( fs.existsSync(filePath) ) {
+ if(ignores && ignores.length > 0 && ignores.indexOf(filePath) >= 0) return;
+ if(!fs.statSync(filePath).isDirectory()) return fs.unlinkSync(filePath);
+ files = fs.readdirSync(filePath);
+ for(var i = 0, li = files.length; i < li; i++){
+ var curPath = path.join(filePath, files[i]);
+ core4cc.rmdirSyncRecursive(curPath, ignores); // recurse
+ }
+ files = fs.readdirSync(filePath);//read again
+ if(files.length == 0) fs.rmdirSync(filePath);
+ }
+};
+
+/**
+ * Desc: Create dir recursively.
+ * @param arr
+ * @param index
+ * @param cb
+ * @returns {*}
+ */
+core4cc.mkdirRecursive = function(arr, index, cb){
+ if(index >= arr.length) cb();
+ var dir = path.join(process.cwd(), arr.slice(0, index +1).join(path.sep));
+ if(fs.existsSync(dir)) return core4cc.mkdirRecursive(arr, index+1, cb);
+ fs.mkdir(dir, function(){
+ core4cc.mkdirRecursive(arr, index+1, cb);
+ });
+}
+/**
+ * Desc: create dir sync recursively.
+ * @param targetPath
+ */
+core4cc.mkdirSyncRecursive = function(targetPath){
+ if(targetPath == null || targetPath == "") return;
+ targetPath = core4cc.isAbsolute(targetPath) ? path.normalize(targetPath) : path.join(process.cwd(), targetPath);
+ if(fs.existsSync(targetPath)) return;
+
+ var arr = targetPath.split(path.sep);
+ var index = arr.length - 1;
+ var tempStr = arr[index];
+ while(tempStr == "" && arr.length > 0){
+ index--;
+ tempStr = arr[index];
+ }
+ if(tempStr == "") return;
+ var newPath = targetPath.substring(0, targetPath.length - tempStr.length - 1);
+ if(!fs.existsSync(newPath)) core4cc.mkdirSyncRecursive(newPath);
+ fs.mkdirSync(targetPath);
+}
+/**
+ * Desc: Returns true if the filePath is absolute.
+ * @param filePath
+ * @returns {boolean}
+ */
+core4cc.isAbsolute = function(filePath){
+ filePath = path.normalize(filePath);
+ if(filePath.substring(0, 1) == "/") return true;
+ if(filePath.search(/[\w]+:/) == 0) return true;
+ return false;
+};
+
+/**
+ * Desc: Copy files in srcPath to targetPath, then replace info by config.
+ * @param srcPath
+ * @param targetPath
+ * @param handler
+ * @private
+ */
+core4cc.copyFiles = function(srcPath, targetPath, handler){
+ if(!fs.statSync(srcPath).isDirectory()) return fs.writeFileSync(targetPath, fs.readFileSync(srcPath));//copy if it`s a file
+
+ if(!fs.existsSync(targetPath)) fs.mkdirSync(targetPath);
+ var files = fs.readdirSync(srcPath);
+ for(var i = 0, li = files.length; i < li; i++){
+ var file = files[i];
+ if(fs.statSync(path.join(srcPath, file)).isDirectory()){//make dir if it`s a dir
+ var dir = path.join(targetPath, file, "./");
+ if(!fs.existsSync(dir)) fs.mkdirSync(dir);
+ core4cc.copyFiles(path.join(srcPath, file + "/"), dir, handler);//goes on
+ }else{
+ var filePath = path.join(targetPath, file);
+ fs.writeFileSync(filePath, fs.readFileSync(path.join(srcPath, file)));//copy if it`s a file
+ if(handler) {
+ handler.fmt(filePath);
+ }
+ }
+ }
+}
+
+/**
+ * Desc: Get string for command.
+ * e.g. aaaa ---> aaaa
+ * "a a" ---> a a
+ * @param str
+ * @returns {*}
+ */
+core4cc.getStr4Cmd = function(str){
+ if(!str) return null;
+ if(str.length < 2) return str;
+ return str.substring(0, 1) == '"' && str.substring(str.length - 1) == '"' ? str.substring(1, str.length - 1) : str;
+}
+/**
+ * Desc: Merge data by default value
+ * @param data
+ * @param defData default value
+ * @returns {{}|*}
+ */
+core4cc.mergeData = function(data, defData){
+ data = data || {};
+ if(defData == null) return data;;
+ for (var key in defData) {
+ if(data[key] == null && defData[key] != null) data[key] = defData[key];
+ }
+ return data;
+}
diff --git a/frameworks/cocos2d-html5/tools/genBuildXml.js b/frameworks/cocos2d-html5/tools/genBuildXml.js
new file mode 100644
index 0000000..e16ff3e
--- /dev/null
+++ b/frameworks/cocos2d-html5/tools/genBuildXml.js
@@ -0,0 +1,89 @@
+/**
+ * Put the `tools` in the root of your project, then run this script with nodejs.
+ * @type {exports|*}
+ */
+
+var fs = require("fs");
+var path = require("path");
+
+
+module.exports = function(projectDir, projectJson, buildOpt){
+ var engineDir = projectJson.engineDir || "frameworks/cocos2d-html5";
+ var realEngineDir = path.join(projectDir, engineDir);
+ var realPublishDir = path.join(projectDir, "publish/html5");
+ var realToolsDir = path.dirname(__filename);
+ var moduleConfig = require(path.join(realEngineDir, "moduleConfig.json"));
+ var ccModuleMap = moduleConfig.module;
+ var modules = projectJson.modules || ["core"];
+ var renderMode = projectJson.renderMode || 0;
+ var mainJs = projectJson.main || "main.js";
+
+
+ var ccJsList = [moduleConfig.bootFile];
+ var userJsList = projectJson.jsList || [];
+
+ if(renderMode != 1 && modules.indexOf("base4webgl") < 0){
+ modules.splice(0, 0, "base4webgl");
+ }
+
+
+ //cache for js and module that has added into jsList to be loaded.
+ var _jsAddedCache = {};
+ function _getJsListOfModule(moduleMap, moduleName){
+ var jsAddedCache = _jsAddedCache;
+ if(jsAddedCache[moduleName]) return null;
+ jsAddedCache[moduleName] = true;
+ var jsList = [];
+ var tempList = moduleMap[moduleName];
+ if(!tempList) throw new Error("can not find module [" + moduleName + "]");
+ for(var i = 0, li = tempList.length; i < li; i++){
+ var item = tempList[i];
+ if(jsAddedCache[item]) continue;
+ var extname = path.extname(item);
+ if(!extname) {
+ var arr = _getJsListOfModule(moduleMap, item);
+ if(arr) jsList = jsList.concat(arr);
+ }else if(extname.toLowerCase() == ".js") jsList.push(item);
+ jsAddedCache[item] = true;
+ }
+ return jsList;
+ };
+
+
+
+ for(var i = 0, li = modules.length; i < li; i++){
+ var item = modules[i];
+ var arr = _getJsListOfModule(ccModuleMap, item, "");
+ if(arr) ccJsList = ccJsList.concat(arr);
+ }
+
+ var externalList = [];
+ function getFileArrStr(jsList){
+ var str = "";
+ for(var i = 0, li = jsList.length; i < li; i++){
+ if(/^external/.test(jsList[i]) && !/Plugin/.test(jsList[i])){
+ externalList.push(jsList[i]);
+ }else{
+ str += ' ';
+ if(i < li - 1) str += '\r\n';
+ }
+ }
+ return str;
+ }
+
+ userJsList.push(mainJs);
+
+ var buildContent = fs.readFileSync(path.join(realToolsDir, "template/build.xml")).toString();
+ buildContent = buildContent.replace(/%projectDir%/gi, projectDir);
+ buildContent = buildContent.replace(/%engineDir%/gi, realEngineDir);
+ buildContent = buildContent.replace(/%publishDir%/gi, realPublishDir);
+ buildContent = buildContent.replace(/%outputFileName%/gi, buildOpt.outputFileName);
+ buildContent = buildContent.replace(/%toolsDir%/gi, realToolsDir);
+ buildContent = buildContent.replace(/%compilationLevel%/gi, buildOpt.compilationLevel);
+ buildContent = buildContent.replace(/%sourceMapCfg%/gi, buildOpt.sourceMapOpened ? 'sourceMapOutputFile="' + path.join(realPublishDir, "sourcemap") + '" sourceMapFormat="V3"' : "");
+ buildContent = buildContent.replace(/%ccJsList%/gi, getFileArrStr(ccJsList));
+ buildContent = buildContent.replace(/%userJsList%/gi, getFileArrStr(userJsList));
+ fs.writeFileSync(path.join(realPublishDir, "build.xml"), buildContent);
+
+ return externalList;
+};
diff --git a/frameworks/cocos2d-html5/tools/jsdoc_toolkit/build.xml b/frameworks/cocos2d-html5/tools/jsdoc_toolkit/build.xml
new file mode 100644
index 0000000..fcbd830
--- /dev/null
+++ b/frameworks/cocos2d-html5/tools/jsdoc_toolkit/build.xml
@@ -0,0 +1,214 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/tools/publish.js b/frameworks/cocos2d-html5/tools/publish.js
new file mode 100644
index 0000000..4b28867
--- /dev/null
+++ b/frameworks/cocos2d-html5/tools/publish.js
@@ -0,0 +1,72 @@
+var exec = require("child_process").exec;
+var fs = require("fs");
+var path = require("path");
+var core4cc = require("./core4cc");
+console.log("Publishing...");
+
+var projectDir = path.join(__dirname, "../");
+
+var projectJson = require(path.join(projectDir, "project.json"));
+var engineDir = path.join(projectJson.engineDir || "frameworks/cocos2d-html5", "/");
+var realEngineDir = path.join(projectDir, engineDir, "/");
+
+var realPublishDir = path.join(projectDir, "publish/html5");
+
+var buildOpt = {
+ outputFileName : "game.min.js",
+// compilationLevel : "simple",
+ compilationLevel : "advanced",
+ sourceMapOpened : true
+};
+
+if(!fs.existsSync(realPublishDir)) core4cc.mkdirSyncRecursive(realPublishDir);
+
+var externalList = require("./genBuildXml")(projectDir, projectJson, buildOpt);
+
+var outputJsPath = path.join(realPublishDir, buildOpt.outputFileName);
+if(fs.existsSync(outputJsPath)) fs.unlinkSync(outputJsPath);
+
+exec("cd " + realPublishDir + " && ant", function(err, data, info){
+ console.log(info);
+ console.log(data);
+ if(err) {
+ console.error(err);
+ console.log(err[0]);
+ return console.log("Failed!")
+ }
+ var sourceMapPath = path.join(realPublishDir, "sourcemap");
+ if(fs.existsSync(sourceMapPath)){
+ var smContent = fs.readFileSync(sourceMapPath).toString();
+ smContent = smContent.replace(new RegExp(path.join(projectDir, "/").replace(/\\/g, "\\\\\\\\") , "gi"), path.join(path.relative(realPublishDir, projectDir), "/"));
+ smContent = smContent.replace(new RegExp(path.join(realEngineDir, "/").replace(/\\/g, "\\\\\\\\"), "gi"), path.join(path.relative(realPublishDir, realEngineDir), "/"));
+ fs.writeFileSync(sourceMapPath, smContent);
+ }
+
+ delete projectJson.engineDir;
+ delete projectJson.modules;
+ delete projectJson.jsList;
+ fs.writeFileSync(path.join(realPublishDir, "project.json"), JSON.stringify(projectJson, null, 4));
+
+ var publishResDir = path.join(realPublishDir, "res");
+ core4cc.rmdirSyncRecursive(publishResDir);
+ core4cc.copyFiles(path.join(projectDir, "res"), publishResDir);
+
+ var indexContent = fs.readFileSync(path.join(projectDir, "index.html")).toString();
+ var externalScript = "";
+ externalList.forEach(function(external){
+ externalScript += "\n";
+ });
+ indexContent = indexContent.replace(/";
+ });
+ indexContent += externalScript;
+ fs.writeFileSync(path.join(realPublishDir, "index.html"), indexContent);
+ console.log("Finished!")
+});
\ No newline at end of file
diff --git a/frameworks/cocos2d-html5/tools/readme for tools.txt b/frameworks/cocos2d-html5/tools/readme for tools.txt
new file mode 100644
index 0000000..c127317
--- /dev/null
+++ b/frameworks/cocos2d-html5/tools/readme for tools.txt
@@ -0,0 +1,8 @@
+Compiler:
+
+Default compiler is Google closure compiler. Please install Ant and Jre to build.
+The shell files and Closure Compiler which Ant needs are provided in tools folder and cocos2d folder.
+
+Reference wiki: http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Closure_Compiler
+For more on Google closure: https://developers.google.com/closure/compiler
+
diff --git a/frameworks/cocos2d-html5/tools/template/build.xml b/frameworks/cocos2d-html5/tools/template/build.xml
new file mode 100644
index 0000000..c2abc27
--- /dev/null
+++ b/frameworks/cocos2d-html5/tools/template/build.xml
@@ -0,0 +1,213 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frameworks/cocos2d-x/CMakeLists.txt b/frameworks/cocos2d-x/CMakeLists.txt
new file mode 100644
index 0000000..f429b75
--- /dev/null
+++ b/frameworks/cocos2d-x/CMakeLists.txt
@@ -0,0 +1,62 @@
+#/****************************************************************************
+# Copyright (c) 2013 cocos2d-x.org
+# Copyright (c) 2014 martell malone
+# Copyright (c) 2015-2017 Chukong Technologies Inc.
+#
+# http://www.cocos2d-x.org
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+# ****************************************************************************/
+
+# build engine library and all tests
+
+cmake_minimum_required(VERSION 3.6)
+
+project(Cocos2d-x)
+
+# cocos2dx root path
+set(COCOS2DX_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+set(CMAKE_MODULE_PATH ${COCOS2DX_ROOT_PATH}/cmake/Modules/)
+
+# prevent in-source-build
+include(PreventInSourceBuilds)
+AssureOutOfSourceBuilds()
+
+# works before build libcocos2d
+include(CocosBuildSet)
+
+# build options
+option(BUILD_TESTS "Build tests" ON)
+
+# default tests include lua, js test project, so we set those option on to build libs
+set(BUILD_LUA_LIBS ON)
+set(BUILD_JS_LIBS ON)
+
+add_subdirectory(${COCOS2DX_ROOT_PATH}/cocos ${ENGINE_BINARY_PATH}/cocos/core)
+
+# prevent tests project to build "cocos2d-x/cocos" again
+set(BUILD_ENGINE_DONE ON)
+# add engine all tests project
+if (BUILD_TESTS)
+ add_subdirectory(${COCOS2DX_ROOT_PATH}/tests/cpp-empty-test ${ENGINE_BINARY_PATH}/tests/cpp-empty-test)
+ add_subdirectory(${COCOS2DX_ROOT_PATH}/tests/cpp-tests ${ENGINE_BINARY_PATH}/tests/cpp-tests)
+ add_subdirectory(${COCOS2DX_ROOT_PATH}/tests/js-tests/project ${ENGINE_BINARY_PATH}/tests/js-tests)
+ add_subdirectory(${COCOS2DX_ROOT_PATH}/tests/lua-empty-test/project ${ENGINE_BINARY_PATH}/tests/lua-empty-test)
+ add_subdirectory(${COCOS2DX_ROOT_PATH}/tests/lua-tests/project ${ENGINE_BINARY_PATH}/tests/lua-test)
+endif()
diff --git a/frameworks/cocos2d-x/build/android-build.py b/frameworks/cocos2d-x/build/android-build.py
new file mode 100755
index 0000000..49d961c
--- /dev/null
+++ b/frameworks/cocos2d-x/build/android-build.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+
+# android-build.py
+# Build android
+
+import sys
+import os, os.path
+
+CPP_SAMPLES = ['cpp-empty-test', 'cpp-tests', 'game-controller-test']
+LUA_SAMPLES = ['lua-empty-test', 'lua-tests', 'lua-game-controller-test']
+JS_SAMPLES = ['js-tests']
+ALL_SAMPLES = CPP_SAMPLES + LUA_SAMPLES + JS_SAMPLES
+
+
+def calculate_build_targets(args):
+ ''' Calculate build targets from list of targets passed on command line.
+ 'all' for all tests
+ 'cpp' for all c++ tests
+ 'lua' for all lua tests
+ 'js' for all javascript tests
+ '''
+
+ targets = []
+ for arg in args:
+ if arg == 'all':
+ targets += ALL_SAMPLES
+ elif arg == 'cpp':
+ targets += CPP_SAMPLES
+ elif arg == 'lua':
+ targets += LUA_SAMPLES
+ elif arg == 'js':
+ targets += JS_SAMPLES
+ else:
+ targets.append(arg)
+
+ # remove duplicates
+ targets = set(targets)
+ return targets
+
+
+def do_build(app_android_root, build_mode, app_abi, platform):
+
+ command = 'cocos compile -p android -s %s --ndk-mode %s --app-abi %s' % (app_android_root, build_mode, app_abi)
+ if platform:
+ command += ' --ap %s' % platform
+ print command
+
+ if os.system(command) != 0:
+ raise Exception('Build dynamic library for project [ %s ] failed!' % app_android_root)
+
+
+def build_targets(targets, build_mode, app_abi, api_level):
+
+ if api_level:
+ platform = 'android-%s' % api_level
+ else:
+ platform = None
+
+ build_targets = calculate_build_targets(targets)
+
+ app_android_root = ''
+
+ cocos_root = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')
+
+ for target in build_targets:
+ app_android_root = os.path.join(cocos_root, 'tests', target)
+ do_build(app_android_root, build_mode, app_abi, platform)
+
+
+def main():
+ from argparse import ArgumentParser, RawTextHelpFormatter
+
+ description = '''
+ This script is mainly used for building tests built-in with cocos2d-x.
+
+ If you are new to cocos2d-x, we recommend you to start with cpp-empty-test or lua-empty-test.'''
+
+ parser = ArgumentParser(description=description, formatter_class=RawTextHelpFormatter)
+ parser.add_argument('-n', '--ndk', dest='app_abi', default='armeabi-v7a',
+ help='specifies Android ABI')
+ parser.add_argument('-p', '--platform', dest='api_level',
+ help='specifies Android API Level')
+ parser.add_argument('-b', '--build', dest='build_mode', metavar='BUILD_MODE', default='debug', choices=['debug', 'release'],
+ help='the build mode for java project, debug (default) or release. ' +
+ 'To get more information, please refer to ' +
+ 'http://developer.android.com/tools/building/building-cmdline.html')
+ parser.add_argument('targets', nargs='+', metavar='targets',
+ help='targets to build. A target is one of [cpp-empty-test|cpp-tests|lua-empty-test|lua-tests|js-tests|cpp|lua|js|all]',
+ choices=['cpp-empty-test', 'cpp-tests', 'lua-empty-test', 'lua-tests', 'js-tests', 'cpp', 'lua', 'js', 'all'])
+ args = parser.parse_args()
+
+ try:
+ build_targets(args.targets, args.build_mode, args.app_abi, args.api_level)
+ except Exception as e:
+ print e
+ sys.exit(1)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/frameworks/cocos2d-x/build/cocos2d-win32.sln b/frameworks/cocos2d-x/build/cocos2d-win32.sln
new file mode 100644
index 0000000..9526be0
--- /dev/null
+++ b/frameworks/cocos2d-x/build/cocos2d-win32.sln
@@ -0,0 +1,125 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 12.0.21005.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpp-tests", "..\tests\cpp-tests\proj.win32\cpp-tests.vcxproj", "{76A39BB2-9B84-4C65-98A5-654D86B86F2A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lua-tests", "..\tests\lua-tests\project\proj.win32\lua-tests.win32.vcxproj", "{4E6A7A0E-DDD8-4BAA-8B22-C964069364ED}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpp-empty-test", "..\tests\cpp-empty-test\proj.win32\cpp-empty-test.vcxproj", "{B8BF9E81-35FD-4582-BA1C-B85FA365BABB}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lua-empty-test", "..\tests\lua-empty-test\project\proj.win32\lua-empty-test.vcxproj", "{13E55395-94A2-4CD9-BFC2-1A051F80C17D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcocos2d", "..\cocos\2d\libcocos2d.vcxproj", "{98A51BA8-FC3A-415B-AC8F-8C7BD464E93E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libluacocos2d", "..\cocos\scripting\lua-bindings\proj.win32\libluacocos2d.vcxproj", "{9F2D6CE6-C893-4400-B50C-6DB70CC2562F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "External", "External", "{92D54E36-7916-48EF-A951-224DD3B25442}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libSpine", "..\cocos\editor-support\spine\proj.win32\libSpine.vcxproj", "{B7C2A162-DEC9-4418-972E-240AB3CBFCAE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "librecast", "..\external\recast\proj.win32\librecast.vcxproj", "{41E34993-647E-4282-8384-4AB1AE31A452}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjscocos2d", "..\cocos\scripting\js-bindings\proj.win32\libjscocos2d.vcxproj", "{39379840-825A-45A0-B363-C09FFEF864BD}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "js-tests", "..\tests\js-tests\project\proj.win32\js-tests.vcxproj", "{D0F06A44-A245-4D13-A498-0120C203B539}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "performance-tests", "..\tests\performance-tests\proj.win32\performance-tests.vcxproj", "{2778C02D-DDD0-4A92-A6AA-C3E2B7EDE3FF}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "game-controller-test", "..\tests\game-controller-test\proj.win32\game-controller-test.vcxproj", "{1FA2BD06-2F52-48F6-8468-C0CC33127F5E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM = Debug|ARM
+ Debug|Win32 = Debug|Win32
+ Release|ARM = Release|ARM
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {76A39BB2-9B84-4C65-98A5-654D86B86F2A}.Debug|ARM.ActiveCfg = Debug|Win32
+ {76A39BB2-9B84-4C65-98A5-654D86B86F2A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {76A39BB2-9B84-4C65-98A5-654D86B86F2A}.Debug|Win32.Build.0 = Debug|Win32
+ {76A39BB2-9B84-4C65-98A5-654D86B86F2A}.Release|ARM.ActiveCfg = Release|Win32
+ {76A39BB2-9B84-4C65-98A5-654D86B86F2A}.Release|Win32.ActiveCfg = Release|Win32
+ {76A39BB2-9B84-4C65-98A5-654D86B86F2A}.Release|Win32.Build.0 = Release|Win32
+ {4E6A7A0E-DDD8-4BAA-8B22-C964069364ED}.Debug|ARM.ActiveCfg = Debug|Win32
+ {4E6A7A0E-DDD8-4BAA-8B22-C964069364ED}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4E6A7A0E-DDD8-4BAA-8B22-C964069364ED}.Debug|Win32.Build.0 = Debug|Win32
+ {4E6A7A0E-DDD8-4BAA-8B22-C964069364ED}.Release|ARM.ActiveCfg = Release|Win32
+ {4E6A7A0E-DDD8-4BAA-8B22-C964069364ED}.Release|Win32.ActiveCfg = Release|Win32
+ {4E6A7A0E-DDD8-4BAA-8B22-C964069364ED}.Release|Win32.Build.0 = Release|Win32
+ {B8BF9E81-35FD-4582-BA1C-B85FA365BABB}.Debug|ARM.ActiveCfg = Debug|Win32
+ {B8BF9E81-35FD-4582-BA1C-B85FA365BABB}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B8BF9E81-35FD-4582-BA1C-B85FA365BABB}.Debug|Win32.Build.0 = Debug|Win32
+ {B8BF9E81-35FD-4582-BA1C-B85FA365BABB}.Release|ARM.ActiveCfg = Release|Win32
+ {B8BF9E81-35FD-4582-BA1C-B85FA365BABB}.Release|Win32.ActiveCfg = Release|Win32
+ {B8BF9E81-35FD-4582-BA1C-B85FA365BABB}.Release|Win32.Build.0 = Release|Win32
+ {13E55395-94A2-4CD9-BFC2-1A051F80C17D}.Debug|ARM.ActiveCfg = Debug|Win32
+ {13E55395-94A2-4CD9-BFC2-1A051F80C17D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {13E55395-94A2-4CD9-BFC2-1A051F80C17D}.Debug|Win32.Build.0 = Debug|Win32
+ {13E55395-94A2-4CD9-BFC2-1A051F80C17D}.Release|ARM.ActiveCfg = Release|Win32
+ {13E55395-94A2-4CD9-BFC2-1A051F80C17D}.Release|Win32.ActiveCfg = Release|Win32
+ {13E55395-94A2-4CD9-BFC2-1A051F80C17D}.Release|Win32.Build.0 = Release|Win32
+ {98A51BA8-FC3A-415B-AC8F-8C7BD464E93E}.Debug|ARM.ActiveCfg = Debug|Win32
+ {98A51BA8-FC3A-415B-AC8F-8C7BD464E93E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {98A51BA8-FC3A-415B-AC8F-8C7BD464E93E}.Debug|Win32.Build.0 = Debug|Win32
+ {98A51BA8-FC3A-415B-AC8F-8C7BD464E93E}.Release|ARM.ActiveCfg = Release|Win32
+ {98A51BA8-FC3A-415B-AC8F-8C7BD464E93E}.Release|Win32.ActiveCfg = Release|Win32
+ {98A51BA8-FC3A-415B-AC8F-8C7BD464E93E}.Release|Win32.Build.0 = Release|Win32
+ {9F2D6CE6-C893-4400-B50C-6DB70CC2562F}.Debug|ARM.ActiveCfg = Debug|Win32
+ {9F2D6CE6-C893-4400-B50C-6DB70CC2562F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9F2D6CE6-C893-4400-B50C-6DB70CC2562F}.Debug|Win32.Build.0 = Debug|Win32
+ {9F2D6CE6-C893-4400-B50C-6DB70CC2562F}.Release|ARM.ActiveCfg = Release|Win32
+ {9F2D6CE6-C893-4400-B50C-6DB70CC2562F}.Release|Win32.ActiveCfg = Release|Win32
+ {9F2D6CE6-C893-4400-B50C-6DB70CC2562F}.Release|Win32.Build.0 = Release|Win32
+ {B7C2A162-DEC9-4418-972E-240AB3CBFCAE}.Debug|ARM.ActiveCfg = Debug|Win32
+ {B7C2A162-DEC9-4418-972E-240AB3CBFCAE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B7C2A162-DEC9-4418-972E-240AB3CBFCAE}.Debug|Win32.Build.0 = Debug|Win32
+ {B7C2A162-DEC9-4418-972E-240AB3CBFCAE}.Release|ARM.ActiveCfg = Release|Win32
+ {B7C2A162-DEC9-4418-972E-240AB3CBFCAE}.Release|Win32.ActiveCfg = Release|Win32
+ {B7C2A162-DEC9-4418-972E-240AB3CBFCAE}.Release|Win32.Build.0 = Release|Win32
+ {41E34993-647E-4282-8384-4AB1AE31A452}.Debug|ARM.ActiveCfg = Debug|Win32
+ {41E34993-647E-4282-8384-4AB1AE31A452}.Debug|Win32.ActiveCfg = Debug|Win32
+ {41E34993-647E-4282-8384-4AB1AE31A452}.Debug|Win32.Build.0 = Debug|Win32
+ {41E34993-647E-4282-8384-4AB1AE31A452}.Release|ARM.ActiveCfg = Release|Win32
+ {41E34993-647E-4282-8384-4AB1AE31A452}.Release|Win32.ActiveCfg = Release|Win32
+ {41E34993-647E-4282-8384-4AB1AE31A452}.Release|Win32.Build.0 = Release|Win32
+ {39379840-825A-45A0-B363-C09FFEF864BD}.Debug|ARM.ActiveCfg = Debug|Win32
+ {39379840-825A-45A0-B363-C09FFEF864BD}.Debug|Win32.ActiveCfg = Debug|Win32
+ {39379840-825A-45A0-B363-C09FFEF864BD}.Debug|Win32.Build.0 = Debug|Win32
+ {39379840-825A-45A0-B363-C09FFEF864BD}.Release|ARM.ActiveCfg = Release|Win32
+ {39379840-825A-45A0-B363-C09FFEF864BD}.Release|Win32.ActiveCfg = Release|Win32
+ {39379840-825A-45A0-B363-C09FFEF864BD}.Release|Win32.Build.0 = Release|Win32
+ {D0F06A44-A245-4D13-A498-0120C203B539}.Debug|ARM.ActiveCfg = Debug|Win32
+ {D0F06A44-A245-4D13-A498-0120C203B539}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D0F06A44-A245-4D13-A498-0120C203B539}.Debug|Win32.Build.0 = Debug|Win32
+ {D0F06A44-A245-4D13-A498-0120C203B539}.Release|ARM.ActiveCfg = Release|Win32
+ {D0F06A44-A245-4D13-A498-0120C203B539}.Release|Win32.ActiveCfg = Release|Win32
+ {D0F06A44-A245-4D13-A498-0120C203B539}.Release|Win32.Build.0 = Release|Win32
+ {2778C02D-DDD0-4A92-A6AA-C3E2B7EDE3FF}.Debug|ARM.ActiveCfg = Debug|Win32
+ {2778C02D-DDD0-4A92-A6AA-C3E2B7EDE3FF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {2778C02D-DDD0-4A92-A6AA-C3E2B7EDE3FF}.Debug|Win32.Build.0 = Debug|Win32
+ {2778C02D-DDD0-4A92-A6AA-C3E2B7EDE3FF}.Release|ARM.ActiveCfg = Release|Win32
+ {2778C02D-DDD0-4A92-A6AA-C3E2B7EDE3FF}.Release|Win32.ActiveCfg = Release|Win32
+ {2778C02D-DDD0-4A92-A6AA-C3E2B7EDE3FF}.Release|Win32.Build.0 = Release|Win32
+ {1FA2BD06-2F52-48F6-8468-C0CC33127F5E}.Debug|ARM.ActiveCfg = Debug|Win32
+ {1FA2BD06-2F52-48F6-8468-C0CC33127F5E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1FA2BD06-2F52-48F6-8468-C0CC33127F5E}.Debug|Win32.Build.0 = Debug|Win32
+ {1FA2BD06-2F52-48F6-8468-C0CC33127F5E}.Release|ARM.ActiveCfg = Release|Win32
+ {1FA2BD06-2F52-48F6-8468-C0CC33127F5E}.Release|Win32.ActiveCfg = Release|Win32
+ {1FA2BD06-2F52-48F6-8468-C0CC33127F5E}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {B7C2A162-DEC9-4418-972E-240AB3CBFCAE} = {92D54E36-7916-48EF-A951-224DD3B25442}
+ {41E34993-647E-4282-8384-4AB1AE31A452} = {92D54E36-7916-48EF-A951-224DD3B25442}
+ EndGlobalSection
+ GlobalSection(DPCodeReviewSolutionGUID) = preSolution
+ DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000}
+ EndGlobalSection
+ GlobalSection(DPCodeReviewSolutionGUID) = preSolution
+ DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000}
+ EndGlobalSection
+EndGlobal
diff --git a/frameworks/cocos2d-x/build/cocos2d_libs.xcodeproj/project.pbxproj b/frameworks/cocos2d-x/build/cocos2d_libs.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..9919fa9
--- /dev/null
+++ b/frameworks/cocos2d-x/build/cocos2d_libs.xcodeproj/project.pbxproj
@@ -0,0 +1,13989 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 0C261F281BE7528900707478 /* Light3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C261F261BE7528900707478 /* Light3DReader.cpp */; };
+ 0C261F291BE7528900707478 /* Light3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C261F261BE7528900707478 /* Light3DReader.cpp */; };
+ 0C261F2A1BE7528900707478 /* Light3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C261F271BE7528900707478 /* Light3DReader.h */; };
+ 0C261F2B1BE7528900707478 /* Light3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C261F271BE7528900707478 /* Light3DReader.h */; };
+ 15AE180819AAD2F700C27E9E /* CCAABB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17E419AAD2F700C27E9E /* CCAABB.cpp */; };
+ 15AE180919AAD2F700C27E9E /* CCAABB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17E419AAD2F700C27E9E /* CCAABB.cpp */; };
+ 15AE180A19AAD2F700C27E9E /* CCAABB.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17E519AAD2F700C27E9E /* CCAABB.h */; };
+ 15AE180B19AAD2F700C27E9E /* CCAABB.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17E519AAD2F700C27E9E /* CCAABB.h */; };
+ 15AE180C19AAD2F700C27E9E /* CCAnimate3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17E619AAD2F700C27E9E /* CCAnimate3D.cpp */; };
+ 15AE180D19AAD2F700C27E9E /* CCAnimate3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17E619AAD2F700C27E9E /* CCAnimate3D.cpp */; };
+ 15AE180E19AAD2F700C27E9E /* CCAnimate3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17E719AAD2F700C27E9E /* CCAnimate3D.h */; };
+ 15AE180F19AAD2F700C27E9E /* CCAnimate3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17E719AAD2F700C27E9E /* CCAnimate3D.h */; };
+ 15AE181019AAD2F700C27E9E /* CCAnimation3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17E819AAD2F700C27E9E /* CCAnimation3D.cpp */; };
+ 15AE181119AAD2F700C27E9E /* CCAnimation3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17E819AAD2F700C27E9E /* CCAnimation3D.cpp */; };
+ 15AE181219AAD2F700C27E9E /* CCAnimation3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17E919AAD2F700C27E9E /* CCAnimation3D.h */; };
+ 15AE181319AAD2F700C27E9E /* CCAnimation3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17E919AAD2F700C27E9E /* CCAnimation3D.h */; };
+ 15AE181419AAD2F700C27E9E /* CCAnimationCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17EA19AAD2F700C27E9E /* CCAnimationCurve.h */; };
+ 15AE181519AAD2F700C27E9E /* CCAnimationCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17EA19AAD2F700C27E9E /* CCAnimationCurve.h */; };
+ 15AE181619AAD2F700C27E9E /* CCAttachNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17EC19AAD2F700C27E9E /* CCAttachNode.cpp */; };
+ 15AE181719AAD2F700C27E9E /* CCAttachNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17EC19AAD2F700C27E9E /* CCAttachNode.cpp */; };
+ 15AE181819AAD2F700C27E9E /* CCAttachNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17ED19AAD2F700C27E9E /* CCAttachNode.h */; };
+ 15AE181919AAD2F700C27E9E /* CCAttachNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17ED19AAD2F700C27E9E /* CCAttachNode.h */; };
+ 15AE181A19AAD2F700C27E9E /* CCBundle3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17EE19AAD2F700C27E9E /* CCBundle3D.cpp */; };
+ 15AE181B19AAD2F700C27E9E /* CCBundle3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17EE19AAD2F700C27E9E /* CCBundle3D.cpp */; };
+ 15AE181C19AAD2F700C27E9E /* CCBundle3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17EF19AAD2F700C27E9E /* CCBundle3D.h */; };
+ 15AE181D19AAD2F700C27E9E /* CCBundle3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17EF19AAD2F700C27E9E /* CCBundle3D.h */; };
+ 15AE181E19AAD2F700C27E9E /* CCBundle3DData.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F019AAD2F700C27E9E /* CCBundle3DData.h */; };
+ 15AE181F19AAD2F700C27E9E /* CCBundle3DData.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F019AAD2F700C27E9E /* CCBundle3DData.h */; };
+ 15AE182019AAD2F700C27E9E /* CCBundleReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F119AAD2F700C27E9E /* CCBundleReader.cpp */; };
+ 15AE182119AAD2F700C27E9E /* CCBundleReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F119AAD2F700C27E9E /* CCBundleReader.cpp */; };
+ 15AE182219AAD2F700C27E9E /* CCBundleReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F219AAD2F700C27E9E /* CCBundleReader.h */; };
+ 15AE182319AAD2F700C27E9E /* CCBundleReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F219AAD2F700C27E9E /* CCBundleReader.h */; };
+ 15AE182419AAD2F700C27E9E /* CCMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F319AAD2F700C27E9E /* CCMesh.cpp */; };
+ 15AE182519AAD2F700C27E9E /* CCMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F319AAD2F700C27E9E /* CCMesh.cpp */; };
+ 15AE182619AAD2F700C27E9E /* CCMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F419AAD2F700C27E9E /* CCMesh.h */; };
+ 15AE182719AAD2F700C27E9E /* CCMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F419AAD2F700C27E9E /* CCMesh.h */; };
+ 15AE182819AAD2F700C27E9E /* CCMeshSkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F519AAD2F700C27E9E /* CCMeshSkin.cpp */; };
+ 15AE182919AAD2F700C27E9E /* CCMeshSkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F519AAD2F700C27E9E /* CCMeshSkin.cpp */; };
+ 15AE182A19AAD2F700C27E9E /* CCMeshSkin.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F619AAD2F700C27E9E /* CCMeshSkin.h */; };
+ 15AE182B19AAD2F700C27E9E /* CCMeshSkin.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F619AAD2F700C27E9E /* CCMeshSkin.h */; };
+ 15AE182C19AAD2F700C27E9E /* CCMeshVertexIndexData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F719AAD2F700C27E9E /* CCMeshVertexIndexData.cpp */; };
+ 15AE182D19AAD2F700C27E9E /* CCMeshVertexIndexData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F719AAD2F700C27E9E /* CCMeshVertexIndexData.cpp */; };
+ 15AE182E19AAD2F700C27E9E /* CCMeshVertexIndexData.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F819AAD2F700C27E9E /* CCMeshVertexIndexData.h */; };
+ 15AE182F19AAD2F700C27E9E /* CCMeshVertexIndexData.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F819AAD2F700C27E9E /* CCMeshVertexIndexData.h */; };
+ 15AE183019AAD2F700C27E9E /* CCOBB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F919AAD2F700C27E9E /* CCOBB.cpp */; };
+ 15AE183119AAD2F700C27E9E /* CCOBB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F919AAD2F700C27E9E /* CCOBB.cpp */; };
+ 15AE183219AAD2F700C27E9E /* CCOBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17FA19AAD2F700C27E9E /* CCOBB.h */; };
+ 15AE183319AAD2F700C27E9E /* CCOBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17FA19AAD2F700C27E9E /* CCOBB.h */; };
+ 15AE183419AAD2F700C27E9E /* CCObjLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17FB19AAD2F700C27E9E /* CCObjLoader.cpp */; };
+ 15AE183519AAD2F700C27E9E /* CCObjLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17FB19AAD2F700C27E9E /* CCObjLoader.cpp */; };
+ 15AE183619AAD2F700C27E9E /* CCObjLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17FC19AAD2F700C27E9E /* CCObjLoader.h */; };
+ 15AE183719AAD2F700C27E9E /* CCObjLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17FC19AAD2F700C27E9E /* CCObjLoader.h */; };
+ 15AE183819AAD2F700C27E9E /* CCRay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17FD19AAD2F700C27E9E /* CCRay.cpp */; };
+ 15AE183919AAD2F700C27E9E /* CCRay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17FD19AAD2F700C27E9E /* CCRay.cpp */; };
+ 15AE183A19AAD2F700C27E9E /* CCRay.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17FE19AAD2F700C27E9E /* CCRay.h */; };
+ 15AE183B19AAD2F700C27E9E /* CCRay.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17FE19AAD2F700C27E9E /* CCRay.h */; };
+ 15AE183C19AAD2F700C27E9E /* CCSkeleton3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17FF19AAD2F700C27E9E /* CCSkeleton3D.cpp */; };
+ 15AE183D19AAD2F700C27E9E /* CCSkeleton3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17FF19AAD2F700C27E9E /* CCSkeleton3D.cpp */; };
+ 15AE183E19AAD2F700C27E9E /* CCSkeleton3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE180019AAD2F700C27E9E /* CCSkeleton3D.h */; };
+ 15AE183F19AAD2F700C27E9E /* CCSkeleton3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE180019AAD2F700C27E9E /* CCSkeleton3D.h */; };
+ 15AE184019AAD2F700C27E9E /* CCSprite3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE180119AAD2F700C27E9E /* CCSprite3D.cpp */; };
+ 15AE184119AAD2F700C27E9E /* CCSprite3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE180119AAD2F700C27E9E /* CCSprite3D.cpp */; };
+ 15AE184219AAD2F700C27E9E /* CCSprite3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE180219AAD2F700C27E9E /* CCSprite3D.h */; };
+ 15AE184319AAD2F700C27E9E /* CCSprite3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE180219AAD2F700C27E9E /* CCSprite3D.h */; };
+ 15AE184419AAD2F700C27E9E /* CCSprite3DMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE180319AAD2F700C27E9E /* CCSprite3DMaterial.cpp */; };
+ 15AE184519AAD2F700C27E9E /* CCSprite3DMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE180319AAD2F700C27E9E /* CCSprite3DMaterial.cpp */; };
+ 15AE184619AAD2F700C27E9E /* CCSprite3DMaterial.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE180419AAD2F700C27E9E /* CCSprite3DMaterial.h */; };
+ 15AE184719AAD2F700C27E9E /* CCSprite3DMaterial.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE180419AAD2F700C27E9E /* CCSprite3DMaterial.h */; };
+ 15AE184819AAD2F700C27E9E /* cocos3d.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE180519AAD2F700C27E9E /* cocos3d.h */; };
+ 15AE184919AAD2F700C27E9E /* cocos3d.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE180519AAD2F700C27E9E /* cocos3d.h */; };
+ 15AE184A19AAD30500C27E9E /* Export.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE11807A56F005B8026 /* Export.h */; };
+ 15AE184B19AAD30500C27E9E /* Export.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE11807A56F005B8026 /* Export.h */; };
+ 15AE184C19AAD30800C27E9E /* SimpleAudioEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE21807A56F005B8026 /* SimpleAudioEngine.h */; };
+ 15AE184D19AAD30800C27E9E /* SimpleAudioEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE21807A56F005B8026 /* SimpleAudioEngine.h */; };
+ 15AE185819AAD31200C27E9E /* CDAudioManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE41807A56F005B8026 /* CDAudioManager.h */; };
+ 15AE185919AAD31200C27E9E /* CDAudioManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FE51807A56F005B8026 /* CDAudioManager.m */; };
+ 15AE185A19AAD31200C27E9E /* CDConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE61807A56F005B8026 /* CDConfig.h */; };
+ 15AE185B19AAD31200C27E9E /* CDOpenALSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE71807A56F005B8026 /* CDOpenALSupport.h */; };
+ 15AE185C19AAD31200C27E9E /* CDOpenALSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FE81807A56F005B8026 /* CDOpenALSupport.m */; };
+ 15AE185D19AAD31200C27E9E /* CocosDenshion.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE91807A56F005B8026 /* CocosDenshion.h */; };
+ 15AE185E19AAD31200C27E9E /* CocosDenshion.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FEA1807A56F005B8026 /* CocosDenshion.m */; };
+ 15AE185F19AAD31200C27E9E /* SimpleAudioEngine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FEB1807A56F005B8026 /* SimpleAudioEngine.mm */; };
+ 15AE186019AAD31200C27E9E /* SimpleAudioEngine_objc.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FEC1807A56F005B8026 /* SimpleAudioEngine_objc.h */; };
+ 15AE186119AAD31200C27E9E /* SimpleAudioEngine_objc.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FED1807A56F005B8026 /* SimpleAudioEngine_objc.m */; };
+ 15AE186219AAD31D00C27E9E /* CDAudioManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FF41807A56F005B8026 /* CDAudioManager.h */; };
+ 15AE186319AAD31D00C27E9E /* CDAudioManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FF51807A56F005B8026 /* CDAudioManager.m */; };
+ 15AE186419AAD31D00C27E9E /* CDConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FF61807A56F005B8026 /* CDConfig.h */; };
+ 15AE186519AAD31D00C27E9E /* CDOpenALSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FF71807A56F005B8026 /* CDOpenALSupport.h */; };
+ 15AE186619AAD31D00C27E9E /* CDOpenALSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FF81807A56F005B8026 /* CDOpenALSupport.m */; };
+ 15AE186719AAD31D00C27E9E /* CDXMacOSXSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FF91807A56F005B8026 /* CDXMacOSXSupport.h */; };
+ 15AE186819AAD31D00C27E9E /* CDXMacOSXSupport.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FFA1807A56F005B8026 /* CDXMacOSXSupport.mm */; };
+ 15AE186919AAD31D00C27E9E /* CocosDenshion.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FFB1807A56F005B8026 /* CocosDenshion.h */; };
+ 15AE186A19AAD31D00C27E9E /* CocosDenshion.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FFC1807A56F005B8026 /* CocosDenshion.m */; };
+ 15AE186B19AAD31D00C27E9E /* SimpleAudioEngine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FFD1807A56F005B8026 /* SimpleAudioEngine.mm */; };
+ 15AE186C19AAD31D00C27E9E /* SimpleAudioEngine_objc.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FFE1807A56F005B8026 /* SimpleAudioEngine_objc.h */; };
+ 15AE186D19AAD31D00C27E9E /* SimpleAudioEngine_objc.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FFF1807A56F005B8026 /* SimpleAudioEngine_objc.m */; };
+ 15AE187A19AAD33D00C27E9E /* CCBAnimationManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71CFA180E26E600808F54 /* CCBAnimationManager.cpp */; };
+ 15AE187B19AAD33D00C27E9E /* CCBAnimationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71CFB180E26E600808F54 /* CCBAnimationManager.h */; };
+ 15AE187C19AAD33D00C27E9E /* CCBFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71CFC180E26E600808F54 /* CCBFileLoader.cpp */; };
+ 15AE187D19AAD33D00C27E9E /* CCBFileLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71CFD180E26E600808F54 /* CCBFileLoader.h */; };
+ 15AE187E19AAD33D00C27E9E /* CCBKeyframe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71CFE180E26E600808F54 /* CCBKeyframe.cpp */; };
+ 15AE187F19AAD33D00C27E9E /* CCBKeyframe.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71CFF180E26E600808F54 /* CCBKeyframe.h */; };
+ 15AE188019AAD33D00C27E9E /* CCBMemberVariableAssigner.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D00180E26E600808F54 /* CCBMemberVariableAssigner.h */; };
+ 15AE188119AAD33D00C27E9E /* CCBReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D01180E26E600808F54 /* CCBReader.cpp */; };
+ 15AE188219AAD33D00C27E9E /* CCBReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D02180E26E600808F54 /* CCBReader.h */; };
+ 15AE188319AAD33D00C27E9E /* CCBSelectorResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D03180E26E600808F54 /* CCBSelectorResolver.h */; };
+ 15AE188419AAD33D00C27E9E /* CCBSequence.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D04180E26E600808F54 /* CCBSequence.cpp */; };
+ 15AE188519AAD33D00C27E9E /* CCBSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D05180E26E600808F54 /* CCBSequence.h */; };
+ 15AE188619AAD33D00C27E9E /* CCBSequenceProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D06180E26E600808F54 /* CCBSequenceProperty.cpp */; };
+ 15AE188719AAD33D00C27E9E /* CCBSequenceProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D07180E26E600808F54 /* CCBSequenceProperty.h */; };
+ 15AE188819AAD33D00C27E9E /* CCControlButtonLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D0A180E26E600808F54 /* CCControlButtonLoader.cpp */; };
+ 15AE188919AAD33D00C27E9E /* CCControlButtonLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D0B180E26E600808F54 /* CCControlButtonLoader.h */; };
+ 15AE188A19AAD33D00C27E9E /* CCControlLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D0C180E26E600808F54 /* CCControlLoader.cpp */; };
+ 15AE188B19AAD33D00C27E9E /* CCControlLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D0D180E26E600808F54 /* CCControlLoader.h */; };
+ 15AE188C19AAD33D00C27E9E /* CCLabelBMFontLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D0E180E26E600808F54 /* CCLabelBMFontLoader.cpp */; };
+ 15AE188D19AAD33D00C27E9E /* CCLabelBMFontLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D0F180E26E600808F54 /* CCLabelBMFontLoader.h */; };
+ 15AE188E19AAD33D00C27E9E /* CCLabelTTFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D10180E26E600808F54 /* CCLabelTTFLoader.cpp */; };
+ 15AE188F19AAD33D00C27E9E /* CCLabelTTFLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D11180E26E600808F54 /* CCLabelTTFLoader.h */; };
+ 15AE189019AAD33D00C27E9E /* CCLayerColorLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D12180E26E600808F54 /* CCLayerColorLoader.cpp */; };
+ 15AE189119AAD33D00C27E9E /* CCLayerColorLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D13180E26E600808F54 /* CCLayerColorLoader.h */; };
+ 15AE189219AAD33D00C27E9E /* CCLayerGradientLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D14180E26E600808F54 /* CCLayerGradientLoader.cpp */; };
+ 15AE189319AAD33D00C27E9E /* CCLayerGradientLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D15180E26E600808F54 /* CCLayerGradientLoader.h */; };
+ 15AE189419AAD33D00C27E9E /* CCLayerLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D16180E26E600808F54 /* CCLayerLoader.cpp */; };
+ 15AE189519AAD33D00C27E9E /* CCLayerLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D17180E26E600808F54 /* CCLayerLoader.h */; };
+ 15AE189619AAD33D00C27E9E /* CCMenuItemImageLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D18180E26E600808F54 /* CCMenuItemImageLoader.cpp */; };
+ 15AE189719AAD33D00C27E9E /* CCMenuItemImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D19180E26E600808F54 /* CCMenuItemImageLoader.h */; };
+ 15AE189819AAD33D00C27E9E /* CCMenuItemLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D1A180E26E600808F54 /* CCMenuItemLoader.cpp */; };
+ 15AE189919AAD33D00C27E9E /* CCMenuItemLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D1B180E26E600808F54 /* CCMenuItemLoader.h */; };
+ 15AE189A19AAD33D00C27E9E /* CCMenuLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D1C180E26E600808F54 /* CCMenuLoader.h */; };
+ 15AE189B19AAD33D00C27E9E /* CCNode+CCBRelativePositioning.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D1D180E26E600808F54 /* CCNode+CCBRelativePositioning.cpp */; };
+ 15AE189C19AAD33D00C27E9E /* CCNode+CCBRelativePositioning.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D1E180E26E600808F54 /* CCNode+CCBRelativePositioning.h */; };
+ 15AE189D19AAD33D00C27E9E /* CCNodeLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D1F180E26E600808F54 /* CCNodeLoader.cpp */; };
+ 15AE189E19AAD33D00C27E9E /* CCNodeLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D20180E26E600808F54 /* CCNodeLoader.h */; };
+ 15AE189F19AAD33D00C27E9E /* CCNodeLoaderLibrary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D21180E26E600808F54 /* CCNodeLoaderLibrary.cpp */; };
+ 15AE18A019AAD33D00C27E9E /* CCNodeLoaderLibrary.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D22180E26E600808F54 /* CCNodeLoaderLibrary.h */; };
+ 15AE18A119AAD33D00C27E9E /* CCNodeLoaderListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D23180E26E600808F54 /* CCNodeLoaderListener.h */; };
+ 15AE18A219AAD33D00C27E9E /* CCParticleSystemQuadLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D24180E26E600808F54 /* CCParticleSystemQuadLoader.cpp */; };
+ 15AE18A319AAD33D00C27E9E /* CCParticleSystemQuadLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D25180E26E600808F54 /* CCParticleSystemQuadLoader.h */; };
+ 15AE18A419AAD33D00C27E9E /* CCScale9SpriteLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D26180E26E600808F54 /* CCScale9SpriteLoader.cpp */; };
+ 15AE18A519AAD33D00C27E9E /* CCScale9SpriteLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D27180E26E600808F54 /* CCScale9SpriteLoader.h */; };
+ 15AE18A619AAD33D00C27E9E /* CCScrollViewLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D28180E26E600808F54 /* CCScrollViewLoader.cpp */; };
+ 15AE18A719AAD33D00C27E9E /* CCScrollViewLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D29180E26E600808F54 /* CCScrollViewLoader.h */; };
+ 15AE18A819AAD33D00C27E9E /* CCSpriteLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D2A180E26E600808F54 /* CCSpriteLoader.cpp */; };
+ 15AE18A919AAD33D00C27E9E /* CCSpriteLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D2B180E26E600808F54 /* CCSpriteLoader.h */; };
+ 15AE18AA19AAD33D00C27E9E /* CocosBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D2C180E26E600808F54 /* CocosBuilder.h */; };
+ 15AE18AB19AAD33D00C27E9E /* CCBAnimationManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71CFA180E26E600808F54 /* CCBAnimationManager.cpp */; };
+ 15AE18AC19AAD33D00C27E9E /* CCBAnimationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71CFB180E26E600808F54 /* CCBAnimationManager.h */; };
+ 15AE18AD19AAD33D00C27E9E /* CCBFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71CFC180E26E600808F54 /* CCBFileLoader.cpp */; };
+ 15AE18AE19AAD33D00C27E9E /* CCBFileLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71CFD180E26E600808F54 /* CCBFileLoader.h */; };
+ 15AE18AF19AAD33D00C27E9E /* CCBKeyframe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71CFE180E26E600808F54 /* CCBKeyframe.cpp */; };
+ 15AE18B019AAD33D00C27E9E /* CCBKeyframe.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71CFF180E26E600808F54 /* CCBKeyframe.h */; };
+ 15AE18B119AAD33D00C27E9E /* CCBMemberVariableAssigner.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D00180E26E600808F54 /* CCBMemberVariableAssigner.h */; };
+ 15AE18B219AAD33D00C27E9E /* CCBReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D01180E26E600808F54 /* CCBReader.cpp */; };
+ 15AE18B319AAD33D00C27E9E /* CCBReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D02180E26E600808F54 /* CCBReader.h */; };
+ 15AE18B419AAD33D00C27E9E /* CCBSelectorResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D03180E26E600808F54 /* CCBSelectorResolver.h */; };
+ 15AE18B519AAD33D00C27E9E /* CCBSequence.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D04180E26E600808F54 /* CCBSequence.cpp */; };
+ 15AE18B619AAD33D00C27E9E /* CCBSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D05180E26E600808F54 /* CCBSequence.h */; };
+ 15AE18B719AAD33D00C27E9E /* CCBSequenceProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D06180E26E600808F54 /* CCBSequenceProperty.cpp */; };
+ 15AE18B819AAD33D00C27E9E /* CCBSequenceProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D07180E26E600808F54 /* CCBSequenceProperty.h */; };
+ 15AE18B919AAD33D00C27E9E /* CCControlButtonLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D0A180E26E600808F54 /* CCControlButtonLoader.cpp */; };
+ 15AE18BA19AAD33D00C27E9E /* CCControlButtonLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D0B180E26E600808F54 /* CCControlButtonLoader.h */; };
+ 15AE18BB19AAD33D00C27E9E /* CCControlLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D0C180E26E600808F54 /* CCControlLoader.cpp */; };
+ 15AE18BC19AAD33D00C27E9E /* CCControlLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D0D180E26E600808F54 /* CCControlLoader.h */; };
+ 15AE18BD19AAD33D00C27E9E /* CCLabelBMFontLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D0E180E26E600808F54 /* CCLabelBMFontLoader.cpp */; };
+ 15AE18BE19AAD33D00C27E9E /* CCLabelBMFontLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D0F180E26E600808F54 /* CCLabelBMFontLoader.h */; };
+ 15AE18BF19AAD33D00C27E9E /* CCLabelTTFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D10180E26E600808F54 /* CCLabelTTFLoader.cpp */; };
+ 15AE18C019AAD33D00C27E9E /* CCLabelTTFLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D11180E26E600808F54 /* CCLabelTTFLoader.h */; };
+ 15AE18C119AAD33D00C27E9E /* CCLayerColorLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D12180E26E600808F54 /* CCLayerColorLoader.cpp */; };
+ 15AE18C219AAD33D00C27E9E /* CCLayerColorLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D13180E26E600808F54 /* CCLayerColorLoader.h */; };
+ 15AE18C319AAD33D00C27E9E /* CCLayerGradientLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D14180E26E600808F54 /* CCLayerGradientLoader.cpp */; };
+ 15AE18C419AAD33D00C27E9E /* CCLayerGradientLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D15180E26E600808F54 /* CCLayerGradientLoader.h */; };
+ 15AE18C519AAD33D00C27E9E /* CCLayerLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D16180E26E600808F54 /* CCLayerLoader.cpp */; };
+ 15AE18C619AAD33D00C27E9E /* CCLayerLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D17180E26E600808F54 /* CCLayerLoader.h */; };
+ 15AE18C719AAD33D00C27E9E /* CCMenuItemImageLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D18180E26E600808F54 /* CCMenuItemImageLoader.cpp */; };
+ 15AE18C819AAD33D00C27E9E /* CCMenuItemImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D19180E26E600808F54 /* CCMenuItemImageLoader.h */; };
+ 15AE18C919AAD33D00C27E9E /* CCMenuItemLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D1A180E26E600808F54 /* CCMenuItemLoader.cpp */; };
+ 15AE18CA19AAD33D00C27E9E /* CCMenuItemLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D1B180E26E600808F54 /* CCMenuItemLoader.h */; };
+ 15AE18CB19AAD33D00C27E9E /* CCMenuLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D1C180E26E600808F54 /* CCMenuLoader.h */; };
+ 15AE18CC19AAD33D00C27E9E /* CCNode+CCBRelativePositioning.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D1D180E26E600808F54 /* CCNode+CCBRelativePositioning.cpp */; };
+ 15AE18CD19AAD33D00C27E9E /* CCNode+CCBRelativePositioning.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D1E180E26E600808F54 /* CCNode+CCBRelativePositioning.h */; };
+ 15AE18CE19AAD33D00C27E9E /* CCNodeLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D1F180E26E600808F54 /* CCNodeLoader.cpp */; };
+ 15AE18CF19AAD33D00C27E9E /* CCNodeLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D20180E26E600808F54 /* CCNodeLoader.h */; };
+ 15AE18D019AAD33D00C27E9E /* CCNodeLoaderLibrary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D21180E26E600808F54 /* CCNodeLoaderLibrary.cpp */; };
+ 15AE18D119AAD33D00C27E9E /* CCNodeLoaderLibrary.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D22180E26E600808F54 /* CCNodeLoaderLibrary.h */; };
+ 15AE18D219AAD33D00C27E9E /* CCNodeLoaderListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D23180E26E600808F54 /* CCNodeLoaderListener.h */; };
+ 15AE18D319AAD33D00C27E9E /* CCParticleSystemQuadLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D24180E26E600808F54 /* CCParticleSystemQuadLoader.cpp */; };
+ 15AE18D419AAD33D00C27E9E /* CCParticleSystemQuadLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D25180E26E600808F54 /* CCParticleSystemQuadLoader.h */; };
+ 15AE18D519AAD33D00C27E9E /* CCScale9SpriteLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D26180E26E600808F54 /* CCScale9SpriteLoader.cpp */; };
+ 15AE18D619AAD33D00C27E9E /* CCScale9SpriteLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D27180E26E600808F54 /* CCScale9SpriteLoader.h */; };
+ 15AE18D719AAD33D00C27E9E /* CCScrollViewLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D28180E26E600808F54 /* CCScrollViewLoader.cpp */; };
+ 15AE18D819AAD33D00C27E9E /* CCScrollViewLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D29180E26E600808F54 /* CCScrollViewLoader.h */; };
+ 15AE18D919AAD33D00C27E9E /* CCSpriteLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D2A180E26E600808F54 /* CCSpriteLoader.cpp */; };
+ 15AE18DA19AAD33D00C27E9E /* CCSpriteLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D2B180E26E600808F54 /* CCSpriteLoader.h */; };
+ 15AE18DB19AAD33D00C27E9E /* CocosBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D2C180E26E600808F54 /* CocosBuilder.h */; };
+ 15AE18DC19AAD35000C27E9E /* CocoLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29E99D1C1957BA7000046604 /* CocoLoader.cpp */; };
+ 15AE18DD19AAD35000C27E9E /* CocoLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 29E99D1D1957BA7000046604 /* CocoLoader.h */; };
+ 15AE18DE19AAD35000C27E9E /* TriggerObj.h in Headers */ = {isa = PBXBuildFile; fileRef = 06CAAAC1186AD63B0012A414 /* TriggerObj.h */; };
+ 15AE18DF19AAD35000C27E9E /* TriggerBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06CAAABC186AD63B0012A414 /* TriggerBase.cpp */; };
+ 15AE18E019AAD35000C27E9E /* TriggerBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 06CAAABD186AD63B0012A414 /* TriggerBase.h */; };
+ 15AE18E119AAD35000C27E9E /* TriggerMng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06CAAABE186AD63B0012A414 /* TriggerMng.cpp */; };
+ 15AE18E219AAD35000C27E9E /* TriggerMng.h in Headers */ = {isa = PBXBuildFile; fileRef = 06CAAABF186AD63B0012A414 /* TriggerMng.h */; };
+ 15AE18E319AAD35000C27E9E /* TriggerObj.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06CAAAC0186AD63B0012A414 /* TriggerObj.cpp */; };
+ 15AE18E419AAD35000C27E9E /* CCActionFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5948180E930E00EF57C3 /* CCActionFrame.cpp */; };
+ 15AE18E519AAD35000C27E9E /* CCActionFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5949180E930E00EF57C3 /* CCActionFrame.h */; };
+ 15AE18E619AAD35000C27E9E /* CCActionFrameEasing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C594A180E930E00EF57C3 /* CCActionFrameEasing.cpp */; };
+ 15AE18E719AAD35000C27E9E /* CCActionFrameEasing.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C594B180E930E00EF57C3 /* CCActionFrameEasing.h */; };
+ 15AE18E819AAD35000C27E9E /* CCActionManagerEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C594C180E930E00EF57C3 /* CCActionManagerEx.cpp */; };
+ 15AE18E919AAD35000C27E9E /* CCActionManagerEx.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C594D180E930E00EF57C3 /* CCActionManagerEx.h */; };
+ 15AE18EA19AAD35000C27E9E /* CCActionNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C594E180E930E00EF57C3 /* CCActionNode.cpp */; };
+ 15AE18EB19AAD35000C27E9E /* CCActionNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C594F180E930E00EF57C3 /* CCActionNode.h */; };
+ 15AE18EC19AAD35000C27E9E /* CCActionObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5950180E930E00EF57C3 /* CCActionObject.cpp */; };
+ 15AE18ED19AAD35000C27E9E /* CCActionObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5951180E930E00EF57C3 /* CCActionObject.h */; };
+ 15AE18EE19AAD35000C27E9E /* CCArmature.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5952180E930E00EF57C3 /* CCArmature.cpp */; };
+ 15AE18EF19AAD35000C27E9E /* CCArmature.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5953180E930E00EF57C3 /* CCArmature.h */; };
+ 15AE18F019AAD35000C27E9E /* CCArmatureAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5954180E930E00EF57C3 /* CCArmatureAnimation.cpp */; };
+ 15AE18F119AAD35000C27E9E /* CCArmatureAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5955180E930E00EF57C3 /* CCArmatureAnimation.h */; };
+ 15AE18F219AAD35000C27E9E /* CCArmatureDataManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5956180E930E00EF57C3 /* CCArmatureDataManager.cpp */; };
+ 15AE18F319AAD35000C27E9E /* CCArmatureDataManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5957180E930E00EF57C3 /* CCArmatureDataManager.h */; };
+ 15AE18F419AAD35000C27E9E /* CCArmatureDefine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5958180E930E00EF57C3 /* CCArmatureDefine.cpp */; };
+ 15AE18F519AAD35000C27E9E /* CCArmatureDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5959180E930E00EF57C3 /* CCArmatureDefine.h */; };
+ 15AE18F619AAD35000C27E9E /* CCBatchNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C595A180E930E00EF57C3 /* CCBatchNode.cpp */; };
+ 15AE18F719AAD35000C27E9E /* CCBatchNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C595B180E930E00EF57C3 /* CCBatchNode.h */; };
+ 15AE18F819AAD35000C27E9E /* CCBone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C595C180E930E00EF57C3 /* CCBone.cpp */; };
+ 15AE18F919AAD35000C27E9E /* CCBone.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C595D180E930E00EF57C3 /* CCBone.h */; };
+ 15AE18FA19AAD35000C27E9E /* CCColliderDetector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C595E180E930E00EF57C3 /* CCColliderDetector.cpp */; };
+ 15AE18FB19AAD35000C27E9E /* CCColliderDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C595F180E930E00EF57C3 /* CCColliderDetector.h */; };
+ 15AE18FC19AAD35000C27E9E /* CCComBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 373B910718787C0B00198F86 /* CCComBase.h */; };
+ 15AE18FD19AAD35000C27E9E /* CCComAttribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5960180E930E00EF57C3 /* CCComAttribute.cpp */; };
+ 15AE18FE19AAD35000C27E9E /* CCComAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5961180E930E00EF57C3 /* CCComAttribute.h */; };
+ 15AE18FF19AAD35000C27E9E /* CCComAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5962180E930E00EF57C3 /* CCComAudio.cpp */; };
+ 15AE190019AAD35000C27E9E /* CCComAudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5963180E930E00EF57C3 /* CCComAudio.h */; };
+ 15AE190119AAD35000C27E9E /* CCComController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5964180E930E00EF57C3 /* CCComController.cpp */; };
+ 15AE190219AAD35000C27E9E /* CCComController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5965180E930E00EF57C3 /* CCComController.h */; };
+ 15AE190319AAD35000C27E9E /* CCComRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5966180E930E00EF57C3 /* CCComRender.cpp */; };
+ 15AE190419AAD35000C27E9E /* CCComRender.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5967180E930E00EF57C3 /* CCComRender.h */; };
+ 15AE190519AAD35000C27E9E /* CCDataReaderHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5968180E930E00EF57C3 /* CCDataReaderHelper.cpp */; };
+ 15AE190619AAD35000C27E9E /* CCDataReaderHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5969180E930E00EF57C3 /* CCDataReaderHelper.h */; };
+ 15AE190719AAD35000C27E9E /* CCDatas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C596A180E930E00EF57C3 /* CCDatas.cpp */; };
+ 15AE190819AAD35000C27E9E /* CCDatas.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C596B180E930E00EF57C3 /* CCDatas.h */; };
+ 15AE190919AAD35000C27E9E /* CCDecorativeDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C596C180E930E00EF57C3 /* CCDecorativeDisplay.cpp */; };
+ 15AE190A19AAD35000C27E9E /* CCDecorativeDisplay.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C596D180E930E00EF57C3 /* CCDecorativeDisplay.h */; };
+ 15AE190B19AAD35000C27E9E /* CCDisplayFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C596E180E930E00EF57C3 /* CCDisplayFactory.cpp */; };
+ 15AE190C19AAD35000C27E9E /* CCDisplayFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C596F180E930E00EF57C3 /* CCDisplayFactory.h */; };
+ 15AE190D19AAD35000C27E9E /* CCDisplayManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5970180E930E00EF57C3 /* CCDisplayManager.cpp */; };
+ 15AE190E19AAD35000C27E9E /* CCDisplayManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5971180E930E00EF57C3 /* CCDisplayManager.h */; };
+ 15AE190F19AAD35000C27E9E /* CCInputDelegate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5972180E930E00EF57C3 /* CCInputDelegate.cpp */; };
+ 15AE191019AAD35000C27E9E /* CCInputDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5973180E930E00EF57C3 /* CCInputDelegate.h */; };
+ 15AE191119AAD35000C27E9E /* CCProcessBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5974180E930E00EF57C3 /* CCProcessBase.cpp */; };
+ 15AE191219AAD35000C27E9E /* CCProcessBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5975180E930E00EF57C3 /* CCProcessBase.h */; };
+ 15AE191319AAD35000C27E9E /* CCSGUIReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5976180E930E00EF57C3 /* CCSGUIReader.cpp */; };
+ 15AE191419AAD35000C27E9E /* CCSGUIReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5977180E930E00EF57C3 /* CCSGUIReader.h */; };
+ 15AE191519AAD35000C27E9E /* CCSkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5978180E930E00EF57C3 /* CCSkin.cpp */; };
+ 15AE191619AAD35000C27E9E /* CCSkin.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5979180E930E00EF57C3 /* CCSkin.h */; };
+ 15AE191719AAD35000C27E9E /* CCSpriteFrameCacheHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C597A180E930E00EF57C3 /* CCSpriteFrameCacheHelper.cpp */; };
+ 15AE191819AAD35000C27E9E /* CCSpriteFrameCacheHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C597B180E930E00EF57C3 /* CCSpriteFrameCacheHelper.h */; };
+ 15AE191919AAD35000C27E9E /* CCSSceneReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C597C180E930E00EF57C3 /* CCSSceneReader.cpp */; };
+ 15AE191A19AAD35000C27E9E /* CCSSceneReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C597D180E930E00EF57C3 /* CCSSceneReader.h */; };
+ 15AE191B19AAD35000C27E9E /* CCTransformHelp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C597E180E930E00EF57C3 /* CCTransformHelp.cpp */; };
+ 15AE191C19AAD35000C27E9E /* CCTransformHelp.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C597F180E930E00EF57C3 /* CCTransformHelp.h */; };
+ 15AE191D19AAD35000C27E9E /* CCTween.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5980180E930E00EF57C3 /* CCTween.cpp */; };
+ 15AE191E19AAD35000C27E9E /* CCTween.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5981180E930E00EF57C3 /* CCTween.h */; };
+ 15AE191F19AAD35000C27E9E /* CCUtilMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5984180E930E00EF57C3 /* CCUtilMath.cpp */; };
+ 15AE192019AAD35000C27E9E /* CCUtilMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5985180E930E00EF57C3 /* CCUtilMath.h */; };
+ 15AE192119AAD35000C27E9E /* CocoStudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5986180E930E00EF57C3 /* CocoStudio.h */; };
+ 15AE192219AAD35000C27E9E /* DictionaryHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5989180E930E00EF57C3 /* DictionaryHelper.cpp */; };
+ 15AE192319AAD35000C27E9E /* DictionaryHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C598A180E930E00EF57C3 /* DictionaryHelper.h */; };
+ 15AE192419AAD35100C27E9E /* CocoLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29E99D1C1957BA7000046604 /* CocoLoader.cpp */; };
+ 15AE192519AAD35100C27E9E /* CocoLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 29E99D1D1957BA7000046604 /* CocoLoader.h */; };
+ 15AE192619AAD35100C27E9E /* TriggerObj.h in Headers */ = {isa = PBXBuildFile; fileRef = 06CAAAC1186AD63B0012A414 /* TriggerObj.h */; };
+ 15AE192719AAD35100C27E9E /* TriggerBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06CAAABC186AD63B0012A414 /* TriggerBase.cpp */; };
+ 15AE192819AAD35100C27E9E /* TriggerBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 06CAAABD186AD63B0012A414 /* TriggerBase.h */; };
+ 15AE192919AAD35100C27E9E /* TriggerMng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06CAAABE186AD63B0012A414 /* TriggerMng.cpp */; };
+ 15AE192A19AAD35100C27E9E /* TriggerMng.h in Headers */ = {isa = PBXBuildFile; fileRef = 06CAAABF186AD63B0012A414 /* TriggerMng.h */; };
+ 15AE192B19AAD35100C27E9E /* TriggerObj.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06CAAAC0186AD63B0012A414 /* TriggerObj.cpp */; };
+ 15AE192C19AAD35100C27E9E /* CCActionFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5948180E930E00EF57C3 /* CCActionFrame.cpp */; };
+ 15AE192D19AAD35100C27E9E /* CCActionFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5949180E930E00EF57C3 /* CCActionFrame.h */; };
+ 15AE192E19AAD35100C27E9E /* CCActionFrameEasing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C594A180E930E00EF57C3 /* CCActionFrameEasing.cpp */; };
+ 15AE192F19AAD35100C27E9E /* CCActionFrameEasing.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C594B180E930E00EF57C3 /* CCActionFrameEasing.h */; };
+ 15AE193019AAD35100C27E9E /* CCActionManagerEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C594C180E930E00EF57C3 /* CCActionManagerEx.cpp */; };
+ 15AE193119AAD35100C27E9E /* CCActionManagerEx.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C594D180E930E00EF57C3 /* CCActionManagerEx.h */; };
+ 15AE193219AAD35100C27E9E /* CCActionNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C594E180E930E00EF57C3 /* CCActionNode.cpp */; };
+ 15AE193319AAD35100C27E9E /* CCActionNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C594F180E930E00EF57C3 /* CCActionNode.h */; };
+ 15AE193419AAD35100C27E9E /* CCActionObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5950180E930E00EF57C3 /* CCActionObject.cpp */; };
+ 15AE193519AAD35100C27E9E /* CCActionObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5951180E930E00EF57C3 /* CCActionObject.h */; };
+ 15AE193619AAD35100C27E9E /* CCArmature.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5952180E930E00EF57C3 /* CCArmature.cpp */; };
+ 15AE193719AAD35100C27E9E /* CCArmature.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5953180E930E00EF57C3 /* CCArmature.h */; };
+ 15AE193819AAD35100C27E9E /* CCArmatureAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5954180E930E00EF57C3 /* CCArmatureAnimation.cpp */; };
+ 15AE193919AAD35100C27E9E /* CCArmatureAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5955180E930E00EF57C3 /* CCArmatureAnimation.h */; };
+ 15AE193A19AAD35100C27E9E /* CCArmatureDataManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5956180E930E00EF57C3 /* CCArmatureDataManager.cpp */; };
+ 15AE193B19AAD35100C27E9E /* CCArmatureDataManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5957180E930E00EF57C3 /* CCArmatureDataManager.h */; };
+ 15AE193C19AAD35100C27E9E /* CCArmatureDefine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5958180E930E00EF57C3 /* CCArmatureDefine.cpp */; };
+ 15AE193D19AAD35100C27E9E /* CCArmatureDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5959180E930E00EF57C3 /* CCArmatureDefine.h */; };
+ 15AE193E19AAD35100C27E9E /* CCBatchNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C595A180E930E00EF57C3 /* CCBatchNode.cpp */; };
+ 15AE193F19AAD35100C27E9E /* CCBatchNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C595B180E930E00EF57C3 /* CCBatchNode.h */; };
+ 15AE194019AAD35100C27E9E /* CCBone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C595C180E930E00EF57C3 /* CCBone.cpp */; };
+ 15AE194119AAD35100C27E9E /* CCBone.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C595D180E930E00EF57C3 /* CCBone.h */; };
+ 15AE194219AAD35100C27E9E /* CCColliderDetector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C595E180E930E00EF57C3 /* CCColliderDetector.cpp */; };
+ 15AE194319AAD35100C27E9E /* CCColliderDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C595F180E930E00EF57C3 /* CCColliderDetector.h */; };
+ 15AE194419AAD35100C27E9E /* CCComBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 373B910718787C0B00198F86 /* CCComBase.h */; };
+ 15AE194519AAD35100C27E9E /* CCComAttribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5960180E930E00EF57C3 /* CCComAttribute.cpp */; };
+ 15AE194619AAD35100C27E9E /* CCComAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5961180E930E00EF57C3 /* CCComAttribute.h */; };
+ 15AE194719AAD35100C27E9E /* CCComAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5962180E930E00EF57C3 /* CCComAudio.cpp */; };
+ 15AE194819AAD35100C27E9E /* CCComAudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5963180E930E00EF57C3 /* CCComAudio.h */; };
+ 15AE194919AAD35100C27E9E /* CCComController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5964180E930E00EF57C3 /* CCComController.cpp */; };
+ 15AE194A19AAD35100C27E9E /* CCComController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5965180E930E00EF57C3 /* CCComController.h */; };
+ 15AE194B19AAD35100C27E9E /* CCComRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5966180E930E00EF57C3 /* CCComRender.cpp */; };
+ 15AE194C19AAD35100C27E9E /* CCComRender.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5967180E930E00EF57C3 /* CCComRender.h */; };
+ 15AE194D19AAD35100C27E9E /* CCDataReaderHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5968180E930E00EF57C3 /* CCDataReaderHelper.cpp */; };
+ 15AE194E19AAD35100C27E9E /* CCDataReaderHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5969180E930E00EF57C3 /* CCDataReaderHelper.h */; };
+ 15AE194F19AAD35100C27E9E /* CCDatas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C596A180E930E00EF57C3 /* CCDatas.cpp */; };
+ 15AE195019AAD35100C27E9E /* CCDatas.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C596B180E930E00EF57C3 /* CCDatas.h */; };
+ 15AE195119AAD35100C27E9E /* CCDecorativeDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C596C180E930E00EF57C3 /* CCDecorativeDisplay.cpp */; };
+ 15AE195219AAD35100C27E9E /* CCDecorativeDisplay.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C596D180E930E00EF57C3 /* CCDecorativeDisplay.h */; };
+ 15AE195319AAD35100C27E9E /* CCDisplayFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C596E180E930E00EF57C3 /* CCDisplayFactory.cpp */; };
+ 15AE195419AAD35100C27E9E /* CCDisplayFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C596F180E930E00EF57C3 /* CCDisplayFactory.h */; };
+ 15AE195519AAD35100C27E9E /* CCDisplayManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5970180E930E00EF57C3 /* CCDisplayManager.cpp */; };
+ 15AE195619AAD35100C27E9E /* CCDisplayManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5971180E930E00EF57C3 /* CCDisplayManager.h */; };
+ 15AE195719AAD35100C27E9E /* CCInputDelegate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5972180E930E00EF57C3 /* CCInputDelegate.cpp */; };
+ 15AE195819AAD35100C27E9E /* CCInputDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5973180E930E00EF57C3 /* CCInputDelegate.h */; };
+ 15AE195919AAD35100C27E9E /* CCProcessBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5974180E930E00EF57C3 /* CCProcessBase.cpp */; };
+ 15AE195A19AAD35100C27E9E /* CCProcessBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5975180E930E00EF57C3 /* CCProcessBase.h */; };
+ 15AE195B19AAD35100C27E9E /* CCSGUIReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5976180E930E00EF57C3 /* CCSGUIReader.cpp */; };
+ 15AE195C19AAD35100C27E9E /* CCSGUIReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5977180E930E00EF57C3 /* CCSGUIReader.h */; };
+ 15AE195D19AAD35100C27E9E /* CCSkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5978180E930E00EF57C3 /* CCSkin.cpp */; };
+ 15AE195E19AAD35100C27E9E /* CCSkin.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5979180E930E00EF57C3 /* CCSkin.h */; };
+ 15AE195F19AAD35100C27E9E /* CCSpriteFrameCacheHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C597A180E930E00EF57C3 /* CCSpriteFrameCacheHelper.cpp */; };
+ 15AE196019AAD35100C27E9E /* CCSpriteFrameCacheHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C597B180E930E00EF57C3 /* CCSpriteFrameCacheHelper.h */; };
+ 15AE196119AAD35100C27E9E /* CCSSceneReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C597C180E930E00EF57C3 /* CCSSceneReader.cpp */; };
+ 15AE196219AAD35100C27E9E /* CCSSceneReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C597D180E930E00EF57C3 /* CCSSceneReader.h */; };
+ 15AE196319AAD35100C27E9E /* CCTransformHelp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C597E180E930E00EF57C3 /* CCTransformHelp.cpp */; };
+ 15AE196419AAD35100C27E9E /* CCTransformHelp.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C597F180E930E00EF57C3 /* CCTransformHelp.h */; };
+ 15AE196519AAD35100C27E9E /* CCTween.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5980180E930E00EF57C3 /* CCTween.cpp */; };
+ 15AE196619AAD35100C27E9E /* CCTween.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5981180E930E00EF57C3 /* CCTween.h */; };
+ 15AE196719AAD35100C27E9E /* CCUtilMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5984180E930E00EF57C3 /* CCUtilMath.cpp */; };
+ 15AE196819AAD35100C27E9E /* CCUtilMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5985180E930E00EF57C3 /* CCUtilMath.h */; };
+ 15AE196919AAD35100C27E9E /* CocoStudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5986180E930E00EF57C3 /* CocoStudio.h */; };
+ 15AE196A19AAD35100C27E9E /* DictionaryHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5989180E930E00EF57C3 /* DictionaryHelper.cpp */; };
+ 15AE196B19AAD35100C27E9E /* DictionaryHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C598A180E930E00EF57C3 /* DictionaryHelper.h */; };
+ 15AE196C19AAD35700C27E9E /* CCActionTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0634A4C5194B19E400E608AF /* CCActionTimeline.cpp */; };
+ 15AE196D19AAD35700C27E9E /* CCActionTimeline.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4C6194B19E400E608AF /* CCActionTimeline.h */; };
+ 15AE196E19AAD35700C27E9E /* CCActionTimelineCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0634A4C7194B19E400E608AF /* CCActionTimelineCache.cpp */; };
+ 15AE196F19AAD35700C27E9E /* CCActionTimelineCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4C8194B19E400E608AF /* CCActionTimelineCache.h */; };
+ 15AE197019AAD35700C27E9E /* CCFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0634A4C9194B19E400E608AF /* CCFrame.cpp */; };
+ 15AE197119AAD35700C27E9E /* CCFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4CA194B19E400E608AF /* CCFrame.h */; };
+ 15AE197419AAD35700C27E9E /* CCTimeLine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0634A4CD194B19E400E608AF /* CCTimeLine.cpp */; };
+ 15AE197519AAD35700C27E9E /* CCTimeLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4CE194B19E400E608AF /* CCTimeLine.h */; };
+ 15AE197619AAD35700C27E9E /* CCTimelineMacro.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4CF194B19E400E608AF /* CCTimelineMacro.h */; };
+ 15AE197719AAD35700C27E9E /* CCActionTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0634A4C5194B19E400E608AF /* CCActionTimeline.cpp */; };
+ 15AE197819AAD35700C27E9E /* CCActionTimeline.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4C6194B19E400E608AF /* CCActionTimeline.h */; };
+ 15AE197919AAD35700C27E9E /* CCActionTimelineCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0634A4C7194B19E400E608AF /* CCActionTimelineCache.cpp */; };
+ 15AE197A19AAD35700C27E9E /* CCActionTimelineCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4C8194B19E400E608AF /* CCActionTimelineCache.h */; };
+ 15AE197B19AAD35700C27E9E /* CCFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0634A4C9194B19E400E608AF /* CCFrame.cpp */; };
+ 15AE197C19AAD35700C27E9E /* CCFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4CA194B19E400E608AF /* CCFrame.h */; };
+ 15AE197F19AAD35700C27E9E /* CCTimeLine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0634A4CD194B19E400E608AF /* CCTimeLine.cpp */; };
+ 15AE198019AAD35700C27E9E /* CCTimeLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4CE194B19E400E608AF /* CCTimeLine.h */; };
+ 15AE198119AAD35700C27E9E /* CCTimelineMacro.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4CF194B19E400E608AF /* CCTimelineMacro.h */; };
+ 15AE198219AAD36400C27E9E /* WidgetReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB9018C72017004AD434 /* WidgetReader.cpp */; };
+ 15AE198319AAD36400C27E9E /* WidgetReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB9118C72017004AD434 /* WidgetReader.h */; };
+ 15AE198419AAD36400C27E9E /* WidgetReaderProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB9218C72017004AD434 /* WidgetReaderProtocol.h */; };
+ 15AE198519AAD36400C27E9E /* WidgetReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB9018C72017004AD434 /* WidgetReader.cpp */; };
+ 15AE198619AAD36400C27E9E /* WidgetReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB9118C72017004AD434 /* WidgetReader.h */; };
+ 15AE198719AAD36400C27E9E /* WidgetReaderProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB9218C72017004AD434 /* WidgetReaderProtocol.h */; };
+ 15AE198819AAD36A00C27E9E /* ButtonReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB6A18C72017004AD434 /* ButtonReader.cpp */; };
+ 15AE198919AAD36A00C27E9E /* ButtonReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB6B18C72017004AD434 /* ButtonReader.h */; };
+ 15AE198A19AAD36A00C27E9E /* ButtonReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB6A18C72017004AD434 /* ButtonReader.cpp */; };
+ 15AE198B19AAD36A00C27E9E /* ButtonReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB6B18C72017004AD434 /* ButtonReader.h */; };
+ 15AE198C19AAD36E00C27E9E /* CheckBoxReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB6D18C72017004AD434 /* CheckBoxReader.cpp */; };
+ 15AE198D19AAD36E00C27E9E /* CheckBoxReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB6E18C72017004AD434 /* CheckBoxReader.h */; };
+ 15AE198E19AAD36E00C27E9E /* CheckBoxReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB6D18C72017004AD434 /* CheckBoxReader.cpp */; };
+ 15AE198F19AAD36E00C27E9E /* CheckBoxReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB6E18C72017004AD434 /* CheckBoxReader.h */; };
+ 15AE199019AAD37200C27E9E /* ImageViewReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7018C72017004AD434 /* ImageViewReader.cpp */; };
+ 15AE199119AAD37200C27E9E /* ImageViewReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7118C72017004AD434 /* ImageViewReader.h */; };
+ 15AE199219AAD37300C27E9E /* ImageViewReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7018C72017004AD434 /* ImageViewReader.cpp */; };
+ 15AE199319AAD37300C27E9E /* ImageViewReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7118C72017004AD434 /* ImageViewReader.h */; };
+ 15AE199419AAD39600C27E9E /* LayoutReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7318C72017004AD434 /* LayoutReader.cpp */; };
+ 15AE199519AAD39600C27E9E /* LayoutReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7418C72017004AD434 /* LayoutReader.h */; };
+ 15AE199619AAD39600C27E9E /* ListViewReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7618C72017004AD434 /* ListViewReader.cpp */; };
+ 15AE199719AAD39600C27E9E /* ListViewReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7718C72017004AD434 /* ListViewReader.h */; };
+ 15AE199819AAD39600C27E9E /* LoadingBarReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7918C72017004AD434 /* LoadingBarReader.cpp */; };
+ 15AE199919AAD39600C27E9E /* LoadingBarReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7A18C72017004AD434 /* LoadingBarReader.h */; };
+ 15AE199A19AAD39600C27E9E /* PageViewReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7C18C72017004AD434 /* PageViewReader.cpp */; };
+ 15AE199B19AAD39600C27E9E /* PageViewReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7D18C72017004AD434 /* PageViewReader.h */; };
+ 15AE199C19AAD39600C27E9E /* ScrollViewReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7F18C72017004AD434 /* ScrollViewReader.cpp */; };
+ 15AE199D19AAD39600C27E9E /* ScrollViewReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8018C72017004AD434 /* ScrollViewReader.h */; };
+ 15AE199E19AAD39600C27E9E /* SliderReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8218C72017004AD434 /* SliderReader.cpp */; };
+ 15AE199F19AAD39600C27E9E /* SliderReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8318C72017004AD434 /* SliderReader.h */; };
+ 15AE19A019AAD39600C27E9E /* TextAtlasReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8518C72017004AD434 /* TextAtlasReader.cpp */; };
+ 15AE19A119AAD39600C27E9E /* TextAtlasReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8618C72017004AD434 /* TextAtlasReader.h */; };
+ 15AE19A219AAD39600C27E9E /* TextBMFontReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8818C72017004AD434 /* TextBMFontReader.cpp */; };
+ 15AE19A319AAD39600C27E9E /* TextBMFontReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8918C72017004AD434 /* TextBMFontReader.h */; };
+ 15AE19A419AAD39600C27E9E /* TextFieldReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8B18C72017004AD434 /* TextFieldReader.cpp */; };
+ 15AE19A519AAD39600C27E9E /* TextFieldReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8C18C72017004AD434 /* TextFieldReader.h */; };
+ 15AE19A619AAD39600C27E9E /* TextReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8E18C72017004AD434 /* TextReader.cpp */; };
+ 15AE19A719AAD39600C27E9E /* TextReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8F18C72017004AD434 /* TextReader.h */; };
+ 15AE19A819AAD39700C27E9E /* LayoutReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7318C72017004AD434 /* LayoutReader.cpp */; };
+ 15AE19A919AAD39700C27E9E /* LayoutReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7418C72017004AD434 /* LayoutReader.h */; };
+ 15AE19AA19AAD39700C27E9E /* ListViewReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7618C72017004AD434 /* ListViewReader.cpp */; };
+ 15AE19AB19AAD39700C27E9E /* ListViewReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7718C72017004AD434 /* ListViewReader.h */; };
+ 15AE19AC19AAD39700C27E9E /* LoadingBarReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7918C72017004AD434 /* LoadingBarReader.cpp */; };
+ 15AE19AD19AAD39700C27E9E /* LoadingBarReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7A18C72017004AD434 /* LoadingBarReader.h */; };
+ 15AE19AE19AAD39700C27E9E /* PageViewReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7C18C72017004AD434 /* PageViewReader.cpp */; };
+ 15AE19AF19AAD39700C27E9E /* PageViewReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7D18C72017004AD434 /* PageViewReader.h */; };
+ 15AE19B019AAD39700C27E9E /* ScrollViewReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7F18C72017004AD434 /* ScrollViewReader.cpp */; };
+ 15AE19B119AAD39700C27E9E /* ScrollViewReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8018C72017004AD434 /* ScrollViewReader.h */; };
+ 15AE19B219AAD39700C27E9E /* SliderReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8218C72017004AD434 /* SliderReader.cpp */; };
+ 15AE19B319AAD39700C27E9E /* SliderReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8318C72017004AD434 /* SliderReader.h */; };
+ 15AE19B419AAD39700C27E9E /* TextAtlasReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8518C72017004AD434 /* TextAtlasReader.cpp */; };
+ 15AE19B519AAD39700C27E9E /* TextAtlasReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8618C72017004AD434 /* TextAtlasReader.h */; };
+ 15AE19B619AAD39700C27E9E /* TextBMFontReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8818C72017004AD434 /* TextBMFontReader.cpp */; };
+ 15AE19B719AAD39700C27E9E /* TextBMFontReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8918C72017004AD434 /* TextBMFontReader.h */; };
+ 15AE19B819AAD39700C27E9E /* TextFieldReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8B18C72017004AD434 /* TextFieldReader.cpp */; };
+ 15AE19B919AAD39700C27E9E /* TextFieldReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8C18C72017004AD434 /* TextFieldReader.h */; };
+ 15AE19BA19AAD39700C27E9E /* TextReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8E18C72017004AD434 /* TextReader.cpp */; };
+ 15AE19BB19AAD39700C27E9E /* TextReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8F18C72017004AD434 /* TextReader.h */; };
+ 15AE1B4D19AADA9900C27E9E /* UIListView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9FE18CF08D000240AA3 /* UIListView.cpp */; };
+ 15AE1B4E19AADA9900C27E9E /* UIListView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9FF18CF08D000240AA3 /* UIListView.h */; };
+ 15AE1B4F19AADA9900C27E9E /* UILoadingBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0018CF08D000240AA3 /* UILoadingBar.cpp */; };
+ 15AE1B5019AADA9900C27E9E /* UILoadingBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0118CF08D000240AA3 /* UILoadingBar.h */; };
+ 15AE1B5119AADA9900C27E9E /* UIPageView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0218CF08D000240AA3 /* UIPageView.cpp */; };
+ 15AE1B5219AADA9900C27E9E /* UIPageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0318CF08D000240AA3 /* UIPageView.h */; };
+ 15AE1B5319AADA9900C27E9E /* UIRichText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0418CF08D000240AA3 /* UIRichText.cpp */; };
+ 15AE1B5419AADA9900C27E9E /* UIRichText.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0518CF08D000240AA3 /* UIRichText.h */; };
+ 15AE1B5519AADA9900C27E9E /* UIScrollView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0718CF08D000240AA3 /* UIScrollView.cpp */; };
+ 15AE1B5619AADA9900C27E9E /* UIScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0818CF08D000240AA3 /* UIScrollView.h */; };
+ 15AE1B5719AADA9900C27E9E /* UISlider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0918CF08D000240AA3 /* UISlider.cpp */; };
+ 15AE1B5819AADA9900C27E9E /* UISlider.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0A18CF08D100240AA3 /* UISlider.h */; };
+ 15AE1B5919AADA9900C27E9E /* UIText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0B18CF08D100240AA3 /* UIText.cpp */; };
+ 15AE1B5A19AADA9900C27E9E /* UIText.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0C18CF08D100240AA3 /* UIText.h */; };
+ 15AE1B5B19AADA9900C27E9E /* UITextAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0D18CF08D100240AA3 /* UITextAtlas.cpp */; };
+ 15AE1B5C19AADA9900C27E9E /* UITextAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0E18CF08D100240AA3 /* UITextAtlas.h */; };
+ 15AE1B5D19AADA9900C27E9E /* UITextBMFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0F18CF08D100240AA3 /* UITextBMFont.cpp */; };
+ 15AE1B5E19AADA9900C27E9E /* UITextBMFont.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA1018CF08D100240AA3 /* UITextBMFont.h */; };
+ 15AE1B5F19AADA9900C27E9E /* UITextField.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA1118CF08D100240AA3 /* UITextField.cpp */; };
+ 15AE1B6019AADA9900C27E9E /* UITextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA1218CF08D100240AA3 /* UITextField.h */; };
+ 15AE1B6119AADA9900C27E9E /* UIButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F018CF08D000240AA3 /* UIButton.cpp */; };
+ 15AE1B6219AADA9900C27E9E /* UIButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F118CF08D000240AA3 /* UIButton.h */; };
+ 15AE1B6319AADA9900C27E9E /* UICheckBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F218CF08D000240AA3 /* UICheckBox.cpp */; };
+ 15AE1B6419AADA9900C27E9E /* UICheckBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F318CF08D000240AA3 /* UICheckBox.h */; };
+ 15AE1B6519AADA9900C27E9E /* UIImageView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F618CF08D000240AA3 /* UIImageView.cpp */; };
+ 15AE1B6619AADA9900C27E9E /* UIImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F718CF08D000240AA3 /* UIImageView.h */; };
+ 15AE1B6719AADA9900C27E9E /* UIScale9Sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2958244919873D8E00F9746D /* UIScale9Sprite.cpp */; };
+ 15AE1B6819AADA9900C27E9E /* UIScale9Sprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 2958244A19873D8E00F9746D /* UIScale9Sprite.h */; };
+ 15AE1B6919AADA9900C27E9E /* UIDeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = 29080DEB191B82CE0066F8DF /* UIDeprecated.h */; };
+ 15AE1B6A19AADA9900C27E9E /* UIDeprecated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29BDBA52195D597A003225C9 /* UIDeprecated.cpp */; };
+ 15AE1B6B19AADA9900C27E9E /* UIWidget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA1318CF08D100240AA3 /* UIWidget.cpp */; };
+ 15AE1B6C19AADA9900C27E9E /* UIWidget.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA1418CF08D100240AA3 /* UIWidget.h */; };
+ 15AE1B6D19AADA9900C27E9E /* UIHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F418CF08D000240AA3 /* UIHelper.cpp */; };
+ 15AE1B6E19AADA9900C27E9E /* UIHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F518CF08D000240AA3 /* UIHelper.h */; };
+ 15AE1B6F19AADA9900C27E9E /* GUIDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9EB18CF08D000240AA3 /* GUIDefine.h */; };
+ 15AE1B7019AADA9900C27E9E /* CocosGUI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9E918CF08D000240AA3 /* CocosGUI.cpp */; };
+ 15AE1B7119AADA9900C27E9E /* CocosGUI.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9EA18CF08D000240AA3 /* CocosGUI.h */; };
+ 15AE1B7219AADA9A00C27E9E /* UIListView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9FE18CF08D000240AA3 /* UIListView.cpp */; };
+ 15AE1B7319AADA9A00C27E9E /* UIListView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9FF18CF08D000240AA3 /* UIListView.h */; };
+ 15AE1B7419AADA9A00C27E9E /* UILoadingBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0018CF08D000240AA3 /* UILoadingBar.cpp */; };
+ 15AE1B7519AADA9A00C27E9E /* UILoadingBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0118CF08D000240AA3 /* UILoadingBar.h */; };
+ 15AE1B7619AADA9A00C27E9E /* UIPageView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0218CF08D000240AA3 /* UIPageView.cpp */; };
+ 15AE1B7719AADA9A00C27E9E /* UIPageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0318CF08D000240AA3 /* UIPageView.h */; };
+ 15AE1B7819AADA9A00C27E9E /* UIRichText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0418CF08D000240AA3 /* UIRichText.cpp */; };
+ 15AE1B7919AADA9A00C27E9E /* UIRichText.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0518CF08D000240AA3 /* UIRichText.h */; };
+ 15AE1B7A19AADA9A00C27E9E /* UIScrollView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0718CF08D000240AA3 /* UIScrollView.cpp */; };
+ 15AE1B7B19AADA9A00C27E9E /* UIScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0818CF08D000240AA3 /* UIScrollView.h */; };
+ 15AE1B7C19AADA9A00C27E9E /* UISlider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0918CF08D000240AA3 /* UISlider.cpp */; };
+ 15AE1B7D19AADA9A00C27E9E /* UISlider.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0A18CF08D100240AA3 /* UISlider.h */; };
+ 15AE1B7E19AADA9A00C27E9E /* UIText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0B18CF08D100240AA3 /* UIText.cpp */; };
+ 15AE1B7F19AADA9A00C27E9E /* UIText.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0C18CF08D100240AA3 /* UIText.h */; };
+ 15AE1B8019AADA9A00C27E9E /* UITextAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0D18CF08D100240AA3 /* UITextAtlas.cpp */; };
+ 15AE1B8119AADA9A00C27E9E /* UITextAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0E18CF08D100240AA3 /* UITextAtlas.h */; };
+ 15AE1B8219AADA9A00C27E9E /* UITextBMFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0F18CF08D100240AA3 /* UITextBMFont.cpp */; };
+ 15AE1B8319AADA9A00C27E9E /* UITextBMFont.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA1018CF08D100240AA3 /* UITextBMFont.h */; };
+ 15AE1B8419AADA9A00C27E9E /* UITextField.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA1118CF08D100240AA3 /* UITextField.cpp */; };
+ 15AE1B8519AADA9A00C27E9E /* UITextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA1218CF08D100240AA3 /* UITextField.h */; };
+ 15AE1B8619AADA9A00C27E9E /* UIButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F018CF08D000240AA3 /* UIButton.cpp */; };
+ 15AE1B8719AADA9A00C27E9E /* UIButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F118CF08D000240AA3 /* UIButton.h */; };
+ 15AE1B8819AADA9A00C27E9E /* UICheckBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F218CF08D000240AA3 /* UICheckBox.cpp */; };
+ 15AE1B8919AADA9A00C27E9E /* UICheckBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F318CF08D000240AA3 /* UICheckBox.h */; };
+ 15AE1B8A19AADA9A00C27E9E /* UIImageView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F618CF08D000240AA3 /* UIImageView.cpp */; };
+ 15AE1B8B19AADA9A00C27E9E /* UIImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F718CF08D000240AA3 /* UIImageView.h */; };
+ 15AE1B8C19AADA9A00C27E9E /* UIScale9Sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2958244919873D8E00F9746D /* UIScale9Sprite.cpp */; };
+ 15AE1B8D19AADA9A00C27E9E /* UIScale9Sprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 2958244A19873D8E00F9746D /* UIScale9Sprite.h */; };
+ 15AE1B8E19AADA9A00C27E9E /* UIDeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = 29080DEB191B82CE0066F8DF /* UIDeprecated.h */; };
+ 15AE1B8F19AADA9A00C27E9E /* UIDeprecated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29BDBA52195D597A003225C9 /* UIDeprecated.cpp */; };
+ 15AE1B9019AADA9A00C27E9E /* UIWidget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA1318CF08D100240AA3 /* UIWidget.cpp */; };
+ 15AE1B9119AADA9A00C27E9E /* UIWidget.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA1418CF08D100240AA3 /* UIWidget.h */; };
+ 15AE1B9219AADA9A00C27E9E /* UIHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F418CF08D000240AA3 /* UIHelper.cpp */; };
+ 15AE1B9319AADA9A00C27E9E /* UIHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F518CF08D000240AA3 /* UIHelper.h */; };
+ 15AE1B9419AADA9A00C27E9E /* GUIDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9EB18CF08D000240AA3 /* GUIDefine.h */; };
+ 15AE1B9519AADA9A00C27E9E /* CocosGUI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9E918CF08D000240AA3 /* CocosGUI.cpp */; };
+ 15AE1B9619AADA9A00C27E9E /* CocosGUI.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9EA18CF08D000240AA3 /* CocosGUI.h */; };
+ 15AE1B9719AADAA100C27E9E /* UIVideoPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EA0FB69191C841D00B170C8 /* UIVideoPlayer.h */; };
+ 15AE1B9819AADAA100C27E9E /* UIVideoPlayer-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3EA0FB6A191C841D00B170C8 /* UIVideoPlayer-ios.mm */; };
+ 15AE1B9919AADFDF00C27E9E /* UIHBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50E6D32E18E174130051CA34 /* UIHBox.cpp */; };
+ 15AE1B9A19AADFDF00C27E9E /* UIHBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E6D32F18E174130051CA34 /* UIHBox.h */; };
+ 15AE1B9B19AADFDF00C27E9E /* UIRelativeBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50E6D33018E174130051CA34 /* UIRelativeBox.cpp */; };
+ 15AE1B9C19AADFDF00C27E9E /* UIRelativeBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E6D33118E174130051CA34 /* UIRelativeBox.h */; };
+ 15AE1B9D19AADFDF00C27E9E /* UIVBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50E6D33218E174130051CA34 /* UIVBox.cpp */; };
+ 15AE1B9E19AADFDF00C27E9E /* UIVBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E6D33318E174130051CA34 /* UIVBox.h */; };
+ 15AE1B9F19AADFDF00C27E9E /* UILayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F818CF08D000240AA3 /* UILayout.cpp */; };
+ 15AE1BA019AADFDF00C27E9E /* UILayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F918CF08D000240AA3 /* UILayout.h */; };
+ 15AE1BA119AADFDF00C27E9E /* UILayoutParameter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9FC18CF08D000240AA3 /* UILayoutParameter.cpp */; };
+ 15AE1BA219AADFDF00C27E9E /* UILayoutParameter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9FD18CF08D000240AA3 /* UILayoutParameter.h */; };
+ 15AE1BA319AADFDF00C27E9E /* UILayoutManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29CB8F4A1929D1BB00C841D6 /* UILayoutManager.cpp */; };
+ 15AE1BA419AADFDF00C27E9E /* UILayoutManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 29CB8F4B1929D1BB00C841D6 /* UILayoutManager.h */; };
+ 15AE1BA519AADFDF00C27E9E /* UIHBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50E6D32E18E174130051CA34 /* UIHBox.cpp */; };
+ 15AE1BA619AADFDF00C27E9E /* UIHBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E6D32F18E174130051CA34 /* UIHBox.h */; };
+ 15AE1BA719AADFDF00C27E9E /* UIRelativeBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50E6D33018E174130051CA34 /* UIRelativeBox.cpp */; };
+ 15AE1BA819AADFDF00C27E9E /* UIRelativeBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E6D33118E174130051CA34 /* UIRelativeBox.h */; };
+ 15AE1BA919AADFDF00C27E9E /* UIVBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50E6D33218E174130051CA34 /* UIVBox.cpp */; };
+ 15AE1BAA19AADFDF00C27E9E /* UIVBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E6D33318E174130051CA34 /* UIVBox.h */; };
+ 15AE1BAB19AADFDF00C27E9E /* UILayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F818CF08D000240AA3 /* UILayout.cpp */; };
+ 15AE1BAC19AADFDF00C27E9E /* UILayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F918CF08D000240AA3 /* UILayout.h */; };
+ 15AE1BAD19AADFDF00C27E9E /* UILayoutParameter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9FC18CF08D000240AA3 /* UILayoutParameter.cpp */; };
+ 15AE1BAE19AADFDF00C27E9E /* UILayoutParameter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9FD18CF08D000240AA3 /* UILayoutParameter.h */; };
+ 15AE1BAF19AADFDF00C27E9E /* UILayoutManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29CB8F4A1929D1BB00C841D6 /* UILayoutManager.cpp */; };
+ 15AE1BB019AADFDF00C27E9E /* UILayoutManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 29CB8F4B1929D1BB00C841D6 /* UILayoutManager.h */; };
+ 15AE1BB219AADFEF00C27E9E /* HttpClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5363180E3374000584C8 /* HttpClient.h */; };
+ 15AE1BB319AADFEF00C27E9E /* HttpRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5364180E3374000584C8 /* HttpRequest.h */; };
+ 15AE1BB419AADFEF00C27E9E /* HttpResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5365180E3374000584C8 /* HttpResponse.h */; };
+ 15AE1BB519AADFEF00C27E9E /* SocketIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF5366180E3374000584C8 /* SocketIO.cpp */; };
+ 15AE1BB619AADFEF00C27E9E /* SocketIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5367180E3374000584C8 /* SocketIO.h */; };
+ 15AE1BB719AADFEF00C27E9E /* WebSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF5368180E3374000584C8 /* WebSocket.cpp */; };
+ 15AE1BB819AADFEF00C27E9E /* WebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5369180E3374000584C8 /* WebSocket.h */; };
+ 15AE1BBA19AADFF000C27E9E /* HttpClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5363180E3374000584C8 /* HttpClient.h */; };
+ 15AE1BBB19AADFF000C27E9E /* HttpRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5364180E3374000584C8 /* HttpRequest.h */; };
+ 15AE1BBC19AADFF000C27E9E /* HttpResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5365180E3374000584C8 /* HttpResponse.h */; };
+ 15AE1BBD19AADFF000C27E9E /* SocketIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF5366180E3374000584C8 /* SocketIO.cpp */; };
+ 15AE1BBE19AADFF000C27E9E /* SocketIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5367180E3374000584C8 /* SocketIO.h */; };
+ 15AE1BBF19AADFF000C27E9E /* WebSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF5368180E3374000584C8 /* WebSocket.cpp */; };
+ 15AE1BC019AADFF000C27E9E /* WebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5369180E3374000584C8 /* WebSocket.h */; };
+ 15AE1BC119AADFFB00C27E9E /* cocos-ext.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A167D21807AF4D005B8026 /* cocos-ext.h */; };
+ 15AE1BC219AADFFB00C27E9E /* ExtensionMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168321807AF4E005B8026 /* ExtensionMacros.h */; };
+ 15AE1BC319AADFFB00C27E9E /* cocos-ext.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A167D21807AF4D005B8026 /* cocos-ext.h */; };
+ 15AE1BC419AADFFB00C27E9E /* ExtensionMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168321807AF4E005B8026 /* ExtensionMacros.h */; };
+ 15AE1BC519AAE00000C27E9E /* AssetsManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF5351180E3060000584C8 /* AssetsManager.cpp */; };
+ 15AE1BC619AAE00000C27E9E /* AssetsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5352180E3060000584C8 /* AssetsManager.h */; };
+ 15AE1BC719AAE00000C27E9E /* AssetsManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF5351180E3060000584C8 /* AssetsManager.cpp */; };
+ 15AE1BC819AAE00000C27E9E /* AssetsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5352180E3060000584C8 /* AssetsManager.h */; };
+ 15AE1BC919AAE01E00C27E9E /* CCControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168351807AF4E005B8026 /* CCControl.cpp */; };
+ 15AE1BCA19AAE01E00C27E9E /* CCControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168361807AF4E005B8026 /* CCControl.h */; };
+ 15AE1BCB19AAE01E00C27E9E /* CCControlButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168371807AF4E005B8026 /* CCControlButton.cpp */; };
+ 15AE1BCC19AAE01E00C27E9E /* CCControlButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168381807AF4E005B8026 /* CCControlButton.h */; };
+ 15AE1BCD19AAE01E00C27E9E /* CCControlColourPicker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168391807AF4E005B8026 /* CCControlColourPicker.cpp */; };
+ 15AE1BCE19AAE01E00C27E9E /* CCControlColourPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1683A1807AF4E005B8026 /* CCControlColourPicker.h */; };
+ 15AE1BCF19AAE01E00C27E9E /* CCControlExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1683B1807AF4E005B8026 /* CCControlExtensions.h */; };
+ 15AE1BD019AAE01E00C27E9E /* CCControlHuePicker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1683C1807AF4E005B8026 /* CCControlHuePicker.cpp */; };
+ 15AE1BD119AAE01E00C27E9E /* CCControlHuePicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1683D1807AF4E005B8026 /* CCControlHuePicker.h */; };
+ 15AE1BD219AAE01E00C27E9E /* CCControlPotentiometer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1683E1807AF4E005B8026 /* CCControlPotentiometer.cpp */; };
+ 15AE1BD319AAE01E00C27E9E /* CCControlPotentiometer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1683F1807AF4E005B8026 /* CCControlPotentiometer.h */; };
+ 15AE1BD419AAE01E00C27E9E /* CCControlSaturationBrightnessPicker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168401807AF4E005B8026 /* CCControlSaturationBrightnessPicker.cpp */; };
+ 15AE1BD519AAE01E00C27E9E /* CCControlSaturationBrightnessPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168411807AF4E005B8026 /* CCControlSaturationBrightnessPicker.h */; };
+ 15AE1BD619AAE01E00C27E9E /* CCControlSlider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168421807AF4E005B8026 /* CCControlSlider.cpp */; };
+ 15AE1BD719AAE01E00C27E9E /* CCControlSlider.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168431807AF4E005B8026 /* CCControlSlider.h */; };
+ 15AE1BD819AAE01E00C27E9E /* CCControlStepper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168441807AF4E005B8026 /* CCControlStepper.cpp */; };
+ 15AE1BD919AAE01E00C27E9E /* CCControlStepper.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168451807AF4E005B8026 /* CCControlStepper.h */; };
+ 15AE1BDA19AAE01E00C27E9E /* CCControlSwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168461807AF4E005B8026 /* CCControlSwitch.cpp */; };
+ 15AE1BDB19AAE01E00C27E9E /* CCControlSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168471807AF4E005B8026 /* CCControlSwitch.h */; };
+ 15AE1BDC19AAE01E00C27E9E /* CCControlUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168481807AF4E005B8026 /* CCControlUtils.cpp */; };
+ 15AE1BDD19AAE01E00C27E9E /* CCControlUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168491807AF4E005B8026 /* CCControlUtils.h */; };
+ 15AE1BDE19AAE01E00C27E9E /* CCInvocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1684A1807AF4E005B8026 /* CCInvocation.cpp */; };
+ 15AE1BDF19AAE01E00C27E9E /* CCInvocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1684B1807AF4E005B8026 /* CCInvocation.h */; };
+ 15AE1BE219AAE01E00C27E9E /* CCScrollView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1685E1807AF4E005B8026 /* CCScrollView.cpp */; };
+ 15AE1BE319AAE01E00C27E9E /* CCScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1685F1807AF4E005B8026 /* CCScrollView.h */; };
+ 15AE1BE419AAE01E00C27E9E /* CCTableView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168621807AF4E005B8026 /* CCTableView.cpp */; };
+ 15AE1BE519AAE01E00C27E9E /* CCTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168631807AF4E005B8026 /* CCTableView.h */; };
+ 15AE1BE619AAE01E00C27E9E /* CCTableViewCell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168641807AF4E005B8026 /* CCTableViewCell.cpp */; };
+ 15AE1BE719AAE01E00C27E9E /* CCTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168651807AF4E005B8026 /* CCTableViewCell.h */; };
+ 15AE1BE819AAE01E00C27E9E /* CCControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168351807AF4E005B8026 /* CCControl.cpp */; };
+ 15AE1BE919AAE01E00C27E9E /* CCControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168361807AF4E005B8026 /* CCControl.h */; };
+ 15AE1BEA19AAE01E00C27E9E /* CCControlButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168371807AF4E005B8026 /* CCControlButton.cpp */; };
+ 15AE1BEB19AAE01E00C27E9E /* CCControlButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168381807AF4E005B8026 /* CCControlButton.h */; };
+ 15AE1BEC19AAE01E00C27E9E /* CCControlColourPicker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168391807AF4E005B8026 /* CCControlColourPicker.cpp */; };
+ 15AE1BED19AAE01E00C27E9E /* CCControlColourPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1683A1807AF4E005B8026 /* CCControlColourPicker.h */; };
+ 15AE1BEE19AAE01E00C27E9E /* CCControlExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1683B1807AF4E005B8026 /* CCControlExtensions.h */; };
+ 15AE1BEF19AAE01E00C27E9E /* CCControlHuePicker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1683C1807AF4E005B8026 /* CCControlHuePicker.cpp */; };
+ 15AE1BF019AAE01E00C27E9E /* CCControlHuePicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1683D1807AF4E005B8026 /* CCControlHuePicker.h */; };
+ 15AE1BF119AAE01E00C27E9E /* CCControlPotentiometer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1683E1807AF4E005B8026 /* CCControlPotentiometer.cpp */; };
+ 15AE1BF219AAE01E00C27E9E /* CCControlPotentiometer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1683F1807AF4E005B8026 /* CCControlPotentiometer.h */; };
+ 15AE1BF319AAE01E00C27E9E /* CCControlSaturationBrightnessPicker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168401807AF4E005B8026 /* CCControlSaturationBrightnessPicker.cpp */; };
+ 15AE1BF419AAE01E00C27E9E /* CCControlSaturationBrightnessPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168411807AF4E005B8026 /* CCControlSaturationBrightnessPicker.h */; };
+ 15AE1BF519AAE01E00C27E9E /* CCControlSlider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168421807AF4E005B8026 /* CCControlSlider.cpp */; };
+ 15AE1BF619AAE01E00C27E9E /* CCControlSlider.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168431807AF4E005B8026 /* CCControlSlider.h */; };
+ 15AE1BF719AAE01E00C27E9E /* CCControlStepper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168441807AF4E005B8026 /* CCControlStepper.cpp */; };
+ 15AE1BF819AAE01E00C27E9E /* CCControlStepper.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168451807AF4E005B8026 /* CCControlStepper.h */; };
+ 15AE1BF919AAE01E00C27E9E /* CCControlSwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168461807AF4E005B8026 /* CCControlSwitch.cpp */; };
+ 15AE1BFA19AAE01E00C27E9E /* CCControlSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168471807AF4E005B8026 /* CCControlSwitch.h */; };
+ 15AE1BFB19AAE01E00C27E9E /* CCControlUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168481807AF4E005B8026 /* CCControlUtils.cpp */; };
+ 15AE1BFC19AAE01E00C27E9E /* CCControlUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168491807AF4E005B8026 /* CCControlUtils.h */; };
+ 15AE1BFD19AAE01E00C27E9E /* CCInvocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1684A1807AF4E005B8026 /* CCInvocation.cpp */; };
+ 15AE1BFE19AAE01E00C27E9E /* CCInvocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1684B1807AF4E005B8026 /* CCInvocation.h */; };
+ 15AE1C0119AAE01E00C27E9E /* CCScrollView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1685E1807AF4E005B8026 /* CCScrollView.cpp */; };
+ 15AE1C0219AAE01E00C27E9E /* CCScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1685F1807AF4E005B8026 /* CCScrollView.h */; };
+ 15AE1C0319AAE01E00C27E9E /* CCTableView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168621807AF4E005B8026 /* CCTableView.cpp */; };
+ 15AE1C0419AAE01E00C27E9E /* CCTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168631807AF4E005B8026 /* CCTableView.h */; };
+ 15AE1C0519AAE01E00C27E9E /* CCTableViewCell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168641807AF4E005B8026 /* CCTableViewCell.cpp */; };
+ 15AE1C0619AAE01E00C27E9E /* CCTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168651807AF4E005B8026 /* CCTableViewCell.h */; };
+ 15AE1C1119AAE2C600C27E9E /* CCPhysicsDebugNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71EEC180E27CF00808F54 /* CCPhysicsDebugNode.cpp */; };
+ 15AE1C1219AAE2C600C27E9E /* CCPhysicsDebugNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71EED180E27CF00808F54 /* CCPhysicsDebugNode.h */; };
+ 15AE1C1319AAE2C600C27E9E /* CCPhysicsSprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71EEE180E27CF00808F54 /* CCPhysicsSprite.cpp */; };
+ 15AE1C1419AAE2C600C27E9E /* CCPhysicsSprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71EEF180E27CF00808F54 /* CCPhysicsSprite.h */; };
+ 15AE1C1519AAE2C700C27E9E /* CCPhysicsDebugNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71EEC180E27CF00808F54 /* CCPhysicsDebugNode.cpp */; };
+ 15AE1C1619AAE2C700C27E9E /* CCPhysicsDebugNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71EED180E27CF00808F54 /* CCPhysicsDebugNode.h */; };
+ 15AE1C1719AAE2C700C27E9E /* CCPhysicsSprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71EEE180E27CF00808F54 /* CCPhysicsSprite.cpp */; };
+ 15AE1C1819AAE2C700C27E9E /* CCPhysicsSprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71EEF180E27CF00808F54 /* CCPhysicsSprite.h */; };
+ 15AE1C1919AAE30900C27E9E /* libwebsockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1AAF5387180E35AC000584C8 /* libwebsockets.a */; };
+ 15AE1C1A19AAE3C800C27E9E /* libwebsockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1AAF5384180E35A3000584C8 /* libwebsockets.a */; };
+ 15B3707819EE414C00ABE682 /* AssetsManagerEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15B3706E19EE414C00ABE682 /* AssetsManagerEx.cpp */; };
+ 15B3707919EE414C00ABE682 /* AssetsManagerEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15B3706E19EE414C00ABE682 /* AssetsManagerEx.cpp */; };
+ 15B3707A19EE414C00ABE682 /* AssetsManagerEx.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B3706F19EE414C00ABE682 /* AssetsManagerEx.h */; };
+ 15B3707B19EE414C00ABE682 /* AssetsManagerEx.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B3706F19EE414C00ABE682 /* AssetsManagerEx.h */; };
+ 15B3707C19EE414C00ABE682 /* CCEventAssetsManagerEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15B3707019EE414C00ABE682 /* CCEventAssetsManagerEx.cpp */; };
+ 15B3707D19EE414C00ABE682 /* CCEventAssetsManagerEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15B3707019EE414C00ABE682 /* CCEventAssetsManagerEx.cpp */; };
+ 15B3707E19EE414C00ABE682 /* CCEventAssetsManagerEx.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B3707119EE414C00ABE682 /* CCEventAssetsManagerEx.h */; };
+ 15B3707F19EE414C00ABE682 /* CCEventAssetsManagerEx.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B3707119EE414C00ABE682 /* CCEventAssetsManagerEx.h */; };
+ 15B3708019EE414C00ABE682 /* CCEventListenerAssetsManagerEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15B3707219EE414C00ABE682 /* CCEventListenerAssetsManagerEx.cpp */; };
+ 15B3708119EE414C00ABE682 /* CCEventListenerAssetsManagerEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15B3707219EE414C00ABE682 /* CCEventListenerAssetsManagerEx.cpp */; };
+ 15B3708219EE414C00ABE682 /* CCEventListenerAssetsManagerEx.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B3707319EE414C00ABE682 /* CCEventListenerAssetsManagerEx.h */; };
+ 15B3708319EE414C00ABE682 /* CCEventListenerAssetsManagerEx.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B3707319EE414C00ABE682 /* CCEventListenerAssetsManagerEx.h */; };
+ 15B3708819EE414C00ABE682 /* Manifest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15B3707619EE414C00ABE682 /* Manifest.cpp */; };
+ 15B3708919EE414C00ABE682 /* Manifest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15B3707619EE414C00ABE682 /* Manifest.cpp */; };
+ 15B3708A19EE414C00ABE682 /* Manifest.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B3707719EE414C00ABE682 /* Manifest.h */; };
+ 15B3708B19EE414C00ABE682 /* Manifest.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B3707719EE414C00ABE682 /* Manifest.h */; };
+ 15EFA211198A2BB5000C57D3 /* CCProtectedNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15EFA20F198A2BB5000C57D3 /* CCProtectedNode.cpp */; };
+ 15EFA212198A2BB5000C57D3 /* CCProtectedNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15EFA20F198A2BB5000C57D3 /* CCProtectedNode.cpp */; };
+ 15EFA213198A2BB5000C57D3 /* CCProtectedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 15EFA210198A2BB5000C57D3 /* CCProtectedNode.h */; };
+ 15EFA214198A2BB5000C57D3 /* CCProtectedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 15EFA210198A2BB5000C57D3 /* CCProtectedNode.h */; };
+ 15FB20741AE7BF8600C31518 /* CCAutoPolygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20721AE7BF8600C31518 /* CCAutoPolygon.cpp */; };
+ 15FB20751AE7BF8600C31518 /* CCAutoPolygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20721AE7BF8600C31518 /* CCAutoPolygon.cpp */; };
+ 15FB20761AE7BF8600C31518 /* CCAutoPolygon.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20731AE7BF8600C31518 /* CCAutoPolygon.h */; };
+ 15FB20771AE7BF8600C31518 /* CCAutoPolygon.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20731AE7BF8600C31518 /* CCAutoPolygon.h */; };
+ 15FB20871AE7C57D00C31518 /* shapes.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB207A1AE7C57D00C31518 /* shapes.cc */; };
+ 15FB20881AE7C57D00C31518 /* shapes.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB207A1AE7C57D00C31518 /* shapes.cc */; };
+ 15FB20891AE7C57D00C31518 /* shapes.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB207B1AE7C57D00C31518 /* shapes.h */; };
+ 15FB208A1AE7C57D00C31518 /* shapes.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB207B1AE7C57D00C31518 /* shapes.h */; };
+ 15FB208B1AE7C57D00C31518 /* utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB207C1AE7C57D00C31518 /* utils.h */; };
+ 15FB208C1AE7C57D00C31518 /* utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB207C1AE7C57D00C31518 /* utils.h */; };
+ 15FB208D1AE7C57D00C31518 /* poly2tri.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB207D1AE7C57D00C31518 /* poly2tri.h */; };
+ 15FB208E1AE7C57D00C31518 /* poly2tri.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB207D1AE7C57D00C31518 /* poly2tri.h */; };
+ 15FB208F1AE7C57D00C31518 /* advancing_front.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB207F1AE7C57D00C31518 /* advancing_front.cc */; };
+ 15FB20901AE7C57D00C31518 /* advancing_front.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB207F1AE7C57D00C31518 /* advancing_front.cc */; };
+ 15FB20911AE7C57D00C31518 /* advancing_front.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20801AE7C57D00C31518 /* advancing_front.h */; };
+ 15FB20921AE7C57D00C31518 /* advancing_front.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20801AE7C57D00C31518 /* advancing_front.h */; };
+ 15FB20931AE7C57D00C31518 /* cdt.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20811AE7C57D00C31518 /* cdt.cc */; };
+ 15FB20941AE7C57D00C31518 /* cdt.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20811AE7C57D00C31518 /* cdt.cc */; };
+ 15FB20951AE7C57D00C31518 /* cdt.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20821AE7C57D00C31518 /* cdt.h */; };
+ 15FB20961AE7C57D00C31518 /* cdt.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20821AE7C57D00C31518 /* cdt.h */; };
+ 15FB20971AE7C57D00C31518 /* sweep.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20831AE7C57D00C31518 /* sweep.cc */; };
+ 15FB20981AE7C57D00C31518 /* sweep.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20831AE7C57D00C31518 /* sweep.cc */; };
+ 15FB20991AE7C57D00C31518 /* sweep.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20841AE7C57D00C31518 /* sweep.h */; };
+ 15FB209A1AE7C57D00C31518 /* sweep.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20841AE7C57D00C31518 /* sweep.h */; };
+ 15FB209B1AE7C57D00C31518 /* sweep_context.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20851AE7C57D00C31518 /* sweep_context.cc */; };
+ 15FB209C1AE7C57D00C31518 /* sweep_context.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20851AE7C57D00C31518 /* sweep_context.cc */; };
+ 15FB209D1AE7C57D00C31518 /* sweep_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20861AE7C57D00C31518 /* sweep_context.h */; };
+ 15FB209E1AE7C57D00C31518 /* sweep_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20861AE7C57D00C31518 /* sweep_context.h */; };
+ 182C5CAE1A95961600C30D34 /* CSParse3DBinary_generated.h in Headers */ = {isa = PBXBuildFile; fileRef = 182C5CAD1A95961600C30D34 /* CSParse3DBinary_generated.h */; };
+ 182C5CB21A95964700C30D34 /* Node3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 182C5CB01A95964700C30D34 /* Node3DReader.cpp */; };
+ 182C5CB31A95964700C30D34 /* Node3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 182C5CB11A95964700C30D34 /* Node3DReader.h */; };
+ 182C5CB41A95964C00C30D34 /* Node3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 182C5CB01A95964700C30D34 /* Node3DReader.cpp */; };
+ 182C5CB51A95964F00C30D34 /* Node3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 182C5CB11A95964700C30D34 /* Node3DReader.h */; };
+ 182C5CB61A95965500C30D34 /* CSParse3DBinary_generated.h in Headers */ = {isa = PBXBuildFile; fileRef = 182C5CAD1A95961600C30D34 /* CSParse3DBinary_generated.h */; };
+ 182C5CD61A98F30500C30D34 /* Sprite3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 182C5CD41A98F30500C30D34 /* Sprite3DReader.cpp */; };
+ 182C5CD71A98F30500C30D34 /* Sprite3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 182C5CD41A98F30500C30D34 /* Sprite3DReader.cpp */; };
+ 182C5CD81A98F30500C30D34 /* Sprite3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 182C5CD51A98F30500C30D34 /* Sprite3DReader.h */; };
+ 182C5CD91A98F30500C30D34 /* Sprite3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 182C5CD51A98F30500C30D34 /* Sprite3DReader.h */; };
+ 182C5CE51A9D725400C30D34 /* UserCameraReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 182C5CE31A9D725400C30D34 /* UserCameraReader.cpp */; };
+ 182C5CE61A9D725400C30D34 /* UserCameraReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 182C5CE31A9D725400C30D34 /* UserCameraReader.cpp */; };
+ 182C5CE71A9D725400C30D34 /* UserCameraReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 182C5CE41A9D725400C30D34 /* UserCameraReader.h */; };
+ 182C5CE81A9D725400C30D34 /* UserCameraReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 182C5CE41A9D725400C30D34 /* UserCameraReader.h */; };
+ 18956BB21A9DFBFD006E9155 /* Particle3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18956BB01A9DFBFD006E9155 /* Particle3DReader.cpp */; };
+ 18956BB31A9DFBFD006E9155 /* Particle3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18956BB01A9DFBFD006E9155 /* Particle3DReader.cpp */; };
+ 18956BB41A9DFBFD006E9155 /* Particle3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 18956BB11A9DFBFD006E9155 /* Particle3DReader.h */; };
+ 18956BB51A9DFBFD006E9155 /* Particle3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 18956BB11A9DFBFD006E9155 /* Particle3DReader.h */; };
+ 1A01C68418F57BE800EFE3A6 /* CCArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C67618F57BE800EFE3A6 /* CCArray.cpp */; };
+ 1A01C68518F57BE800EFE3A6 /* CCArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C67618F57BE800EFE3A6 /* CCArray.cpp */; };
+ 1A01C68618F57BE800EFE3A6 /* CCArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67718F57BE800EFE3A6 /* CCArray.h */; };
+ 1A01C68718F57BE800EFE3A6 /* CCArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67718F57BE800EFE3A6 /* CCArray.h */; };
+ 1A01C68818F57BE800EFE3A6 /* CCBool.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67818F57BE800EFE3A6 /* CCBool.h */; };
+ 1A01C68918F57BE800EFE3A6 /* CCBool.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67818F57BE800EFE3A6 /* CCBool.h */; };
+ 1A01C68A18F57BE800EFE3A6 /* CCDeprecated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C67918F57BE800EFE3A6 /* CCDeprecated.cpp */; };
+ 1A01C68B18F57BE800EFE3A6 /* CCDeprecated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C67918F57BE800EFE3A6 /* CCDeprecated.cpp */; };
+ 1A01C68C18F57BE800EFE3A6 /* CCDeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67A18F57BE800EFE3A6 /* CCDeprecated.h */; };
+ 1A01C68D18F57BE800EFE3A6 /* CCDeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67A18F57BE800EFE3A6 /* CCDeprecated.h */; };
+ 1A01C68E18F57BE800EFE3A6 /* CCDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C67B18F57BE800EFE3A6 /* CCDictionary.cpp */; };
+ 1A01C68F18F57BE800EFE3A6 /* CCDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C67B18F57BE800EFE3A6 /* CCDictionary.cpp */; };
+ 1A01C69018F57BE800EFE3A6 /* CCDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67C18F57BE800EFE3A6 /* CCDictionary.h */; };
+ 1A01C69118F57BE800EFE3A6 /* CCDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67C18F57BE800EFE3A6 /* CCDictionary.h */; };
+ 1A01C69218F57BE800EFE3A6 /* CCDouble.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67D18F57BE800EFE3A6 /* CCDouble.h */; };
+ 1A01C69318F57BE800EFE3A6 /* CCDouble.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67D18F57BE800EFE3A6 /* CCDouble.h */; };
+ 1A01C69418F57BE800EFE3A6 /* CCFloat.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67E18F57BE800EFE3A6 /* CCFloat.h */; };
+ 1A01C69518F57BE800EFE3A6 /* CCFloat.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67E18F57BE800EFE3A6 /* CCFloat.h */; };
+ 1A01C69618F57BE800EFE3A6 /* CCInteger.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67F18F57BE800EFE3A6 /* CCInteger.h */; };
+ 1A01C69718F57BE800EFE3A6 /* CCInteger.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67F18F57BE800EFE3A6 /* CCInteger.h */; };
+ 1A01C69818F57BE800EFE3A6 /* CCSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C68018F57BE800EFE3A6 /* CCSet.cpp */; };
+ 1A01C69918F57BE800EFE3A6 /* CCSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C68018F57BE800EFE3A6 /* CCSet.cpp */; };
+ 1A01C69A18F57BE800EFE3A6 /* CCSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C68118F57BE800EFE3A6 /* CCSet.h */; };
+ 1A01C69B18F57BE800EFE3A6 /* CCSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C68118F57BE800EFE3A6 /* CCSet.h */; };
+ 1A01C69C18F57BE800EFE3A6 /* CCString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C68218F57BE800EFE3A6 /* CCString.cpp */; };
+ 1A01C69D18F57BE800EFE3A6 /* CCString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C68218F57BE800EFE3A6 /* CCString.cpp */; };
+ 1A01C69E18F57BE800EFE3A6 /* CCString.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C68318F57BE800EFE3A6 /* CCString.h */; };
+ 1A01C69F18F57BE800EFE3A6 /* CCString.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C68318F57BE800EFE3A6 /* CCString.h */; };
+ 1A01C6A418F58F7500EFE3A6 /* CCNotificationCenter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C6A218F58F7500EFE3A6 /* CCNotificationCenter.cpp */; };
+ 1A01C6A518F58F7500EFE3A6 /* CCNotificationCenter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C6A218F58F7500EFE3A6 /* CCNotificationCenter.cpp */; };
+ 1A01C6A618F58F7500EFE3A6 /* CCNotificationCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C6A318F58F7500EFE3A6 /* CCNotificationCenter.h */; };
+ 1A01C6A718F58F7500EFE3A6 /* CCNotificationCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C6A318F58F7500EFE3A6 /* CCNotificationCenter.h */; };
+ 1A087AE81860400400196EF5 /* edtaa3func.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A087AE61860400400196EF5 /* edtaa3func.cpp */; };
+ 1A087AE91860400400196EF5 /* edtaa3func.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A087AE61860400400196EF5 /* edtaa3func.cpp */; };
+ 1A087AEA1860400400196EF5 /* edtaa3func.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A087AE71860400400196EF5 /* edtaa3func.h */; };
+ 1A087AEB1860400400196EF5 /* edtaa3func.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A087AE71860400400196EF5 /* edtaa3func.h */; };
+ 1A12775A18DFCC4F0005F345 /* CCTweenFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 2986667918B1B079000E39CA /* CCTweenFunction.h */; };
+ 1A12775B18DFCC540005F345 /* CCTweenFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 2986667918B1B079000E39CA /* CCTweenFunction.h */; };
+ 1A12775C18DFCC590005F345 /* CCTweenFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2986667818B1B079000E39CA /* CCTweenFunction.cpp */; };
+ 1A1645B0191B726C008C7C7F /* ConvertUTF.c in Sources */ = {isa = PBXBuildFile; fileRef = 1A1645AE191B726C008C7C7F /* ConvertUTF.c */; };
+ 1A1645B1191B726C008C7C7F /* ConvertUTF.c in Sources */ = {isa = PBXBuildFile; fileRef = 1A1645AE191B726C008C7C7F /* ConvertUTF.c */; };
+ 1A1645B2191B726C008C7C7F /* ConvertUTFWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1645AF191B726C008C7C7F /* ConvertUTFWrapper.cpp */; };
+ 1A1645B3191B726C008C7C7F /* ConvertUTFWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1645AF191B726C008C7C7F /* ConvertUTFWrapper.cpp */; };
+ 1A2B22B01E6E54D6001D5EC9 /* Uri.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A2B22AF1E6E54D6001D5EC9 /* Uri.h */; };
+ 1A2B22B21E6E54EC001D5EC9 /* Uri.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2B22B11E6E54EC001D5EC9 /* Uri.cpp */; };
+ 1A2B22B31E6E54EC001D5EC9 /* Uri.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2B22B11E6E54EC001D5EC9 /* Uri.cpp */; };
+ 1A2B22B41E6E54EC001D5EC9 /* Uri.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2B22B11E6E54EC001D5EC9 /* Uri.cpp */; };
+ 1A2B22B51E6E5828001D5EC9 /* Uri.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A2B22AF1E6E54D6001D5EC9 /* Uri.h */; };
+ 1A2B22B61E6E5829001D5EC9 /* Uri.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A2B22AF1E6E54D6001D5EC9 /* Uri.h */; };
+ 1A40D0DC1E8E4C76002E363A /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 1A40D0DA1E8E4C76002E363A /* md5.c */; };
+ 1A40D0DD1E8E4C76002E363A /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 1A40D0DA1E8E4C76002E363A /* md5.c */; };
+ 1A40D0DE1E8E4C76002E363A /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 1A40D0DA1E8E4C76002E363A /* md5.c */; };
+ 1A40D0DF1E8E4C76002E363A /* md5.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0DB1E8E4C76002E363A /* md5.h */; };
+ 1A40D0E01E8E4C76002E363A /* md5.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0DB1E8E4C76002E363A /* md5.h */; };
+ 1A40D0E11E8E4C76002E363A /* md5.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0DB1E8E4C76002E363A /* md5.h */; };
+ 1A40D1091E8E56C6002E363A /* allocators.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E21E8E56C6002E363A /* allocators.h */; };
+ 1A40D10A1E8E56C6002E363A /* allocators.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E21E8E56C6002E363A /* allocators.h */; };
+ 1A40D10B1E8E56C6002E363A /* allocators.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E21E8E56C6002E363A /* allocators.h */; };
+ 1A40D10C1E8E56C7002E363A /* document-wrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E31E8E56C6002E363A /* document-wrapper.h */; };
+ 1A40D10D1E8E56C7002E363A /* document-wrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E31E8E56C6002E363A /* document-wrapper.h */; };
+ 1A40D10E1E8E56C7002E363A /* document-wrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E31E8E56C6002E363A /* document-wrapper.h */; };
+ 1A40D10F1E8E56C7002E363A /* document.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E41E8E56C6002E363A /* document.h */; };
+ 1A40D1101E8E56C7002E363A /* document.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E41E8E56C6002E363A /* document.h */; };
+ 1A40D1111E8E56C7002E363A /* document.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E41E8E56C6002E363A /* document.h */; };
+ 1A40D1121E8E56C7002E363A /* encodedstream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E51E8E56C6002E363A /* encodedstream.h */; };
+ 1A40D1131E8E56C7002E363A /* encodedstream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E51E8E56C6002E363A /* encodedstream.h */; };
+ 1A40D1141E8E56C7002E363A /* encodedstream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E51E8E56C6002E363A /* encodedstream.h */; };
+ 1A40D1151E8E56C7002E363A /* encodings.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E61E8E56C6002E363A /* encodings.h */; };
+ 1A40D1161E8E56C7002E363A /* encodings.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E61E8E56C6002E363A /* encodings.h */; };
+ 1A40D1171E8E56C7002E363A /* encodings.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E61E8E56C6002E363A /* encodings.h */; };
+ 1A40D1181E8E56C7002E363A /* en.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E81E8E56C6002E363A /* en.h */; };
+ 1A40D1191E8E56C7002E363A /* en.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E81E8E56C6002E363A /* en.h */; };
+ 1A40D11A1E8E56C7002E363A /* en.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E81E8E56C6002E363A /* en.h */; };
+ 1A40D11B1E8E56C7002E363A /* error.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E91E8E56C6002E363A /* error.h */; };
+ 1A40D11C1E8E56C7002E363A /* error.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E91E8E56C6002E363A /* error.h */; };
+ 1A40D11D1E8E56C7002E363A /* error.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0E91E8E56C6002E363A /* error.h */; };
+ 1A40D11E1E8E56C7002E363A /* filereadstream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EA1E8E56C6002E363A /* filereadstream.h */; };
+ 1A40D11F1E8E56C7002E363A /* filereadstream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EA1E8E56C6002E363A /* filereadstream.h */; };
+ 1A40D1201E8E56C7002E363A /* filereadstream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EA1E8E56C6002E363A /* filereadstream.h */; };
+ 1A40D1211E8E56C7002E363A /* filewritestream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EB1E8E56C6002E363A /* filewritestream.h */; };
+ 1A40D1221E8E56C7002E363A /* filewritestream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EB1E8E56C6002E363A /* filewritestream.h */; };
+ 1A40D1231E8E56C7002E363A /* filewritestream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EB1E8E56C6002E363A /* filewritestream.h */; };
+ 1A40D1241E8E56C7002E363A /* fwd.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EC1E8E56C6002E363A /* fwd.h */; };
+ 1A40D1251E8E56C7002E363A /* fwd.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EC1E8E56C6002E363A /* fwd.h */; };
+ 1A40D1261E8E56C7002E363A /* fwd.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EC1E8E56C6002E363A /* fwd.h */; };
+ 1A40D1271E8E56C7002E363A /* biginteger.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EE1E8E56C6002E363A /* biginteger.h */; };
+ 1A40D1281E8E56C7002E363A /* biginteger.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EE1E8E56C6002E363A /* biginteger.h */; };
+ 1A40D1291E8E56C7002E363A /* biginteger.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EE1E8E56C6002E363A /* biginteger.h */; };
+ 1A40D12A1E8E56C7002E363A /* diyfp.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EF1E8E56C6002E363A /* diyfp.h */; };
+ 1A40D12B1E8E56C7002E363A /* diyfp.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EF1E8E56C6002E363A /* diyfp.h */; };
+ 1A40D12C1E8E56C7002E363A /* diyfp.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0EF1E8E56C6002E363A /* diyfp.h */; };
+ 1A40D12D1E8E56C7002E363A /* dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F01E8E56C6002E363A /* dtoa.h */; };
+ 1A40D12E1E8E56C7002E363A /* dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F01E8E56C6002E363A /* dtoa.h */; };
+ 1A40D12F1E8E56C7002E363A /* dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F01E8E56C6002E363A /* dtoa.h */; };
+ 1A40D1301E8E56C7002E363A /* ieee754.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F11E8E56C6002E363A /* ieee754.h */; };
+ 1A40D1311E8E56C7002E363A /* ieee754.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F11E8E56C6002E363A /* ieee754.h */; };
+ 1A40D1321E8E56C7002E363A /* ieee754.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F11E8E56C6002E363A /* ieee754.h */; };
+ 1A40D1331E8E56C7002E363A /* itoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F21E8E56C6002E363A /* itoa.h */; };
+ 1A40D1341E8E56C7002E363A /* itoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F21E8E56C6002E363A /* itoa.h */; };
+ 1A40D1351E8E56C7002E363A /* itoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F21E8E56C6002E363A /* itoa.h */; };
+ 1A40D1361E8E56C7002E363A /* meta.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F31E8E56C6002E363A /* meta.h */; };
+ 1A40D1371E8E56C7002E363A /* meta.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F31E8E56C6002E363A /* meta.h */; };
+ 1A40D1381E8E56C7002E363A /* meta.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F31E8E56C6002E363A /* meta.h */; };
+ 1A40D1391E8E56C7002E363A /* pow10.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F41E8E56C6002E363A /* pow10.h */; };
+ 1A40D13A1E8E56C7002E363A /* pow10.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F41E8E56C6002E363A /* pow10.h */; };
+ 1A40D13B1E8E56C7002E363A /* pow10.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F41E8E56C6002E363A /* pow10.h */; };
+ 1A40D13C1E8E56C7002E363A /* regex.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F51E8E56C6002E363A /* regex.h */; };
+ 1A40D13D1E8E56C7002E363A /* regex.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F51E8E56C6002E363A /* regex.h */; };
+ 1A40D13E1E8E56C7002E363A /* regex.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F51E8E56C6002E363A /* regex.h */; };
+ 1A40D13F1E8E56C7002E363A /* stack.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F61E8E56C6002E363A /* stack.h */; };
+ 1A40D1401E8E56C7002E363A /* stack.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F61E8E56C6002E363A /* stack.h */; };
+ 1A40D1411E8E56C7002E363A /* stack.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F61E8E56C6002E363A /* stack.h */; };
+ 1A40D1421E8E56C7002E363A /* strfunc.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F71E8E56C6002E363A /* strfunc.h */; };
+ 1A40D1431E8E56C7002E363A /* strfunc.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F71E8E56C6002E363A /* strfunc.h */; };
+ 1A40D1441E8E56C7002E363A /* strfunc.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F71E8E56C6002E363A /* strfunc.h */; };
+ 1A40D1451E8E56C7002E363A /* strtod.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F81E8E56C6002E363A /* strtod.h */; };
+ 1A40D1461E8E56C7002E363A /* strtod.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F81E8E56C6002E363A /* strtod.h */; };
+ 1A40D1471E8E56C7002E363A /* strtod.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F81E8E56C6002E363A /* strtod.h */; };
+ 1A40D1481E8E56C7002E363A /* swap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F91E8E56C6002E363A /* swap.h */; };
+ 1A40D1491E8E56C7002E363A /* swap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F91E8E56C6002E363A /* swap.h */; };
+ 1A40D14A1E8E56C7002E363A /* swap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0F91E8E56C6002E363A /* swap.h */; };
+ 1A40D14B1E8E56C7002E363A /* istreamwrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0FA1E8E56C6002E363A /* istreamwrapper.h */; };
+ 1A40D14C1E8E56C7002E363A /* istreamwrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0FA1E8E56C6002E363A /* istreamwrapper.h */; };
+ 1A40D14D1E8E56C7002E363A /* istreamwrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0FA1E8E56C6002E363A /* istreamwrapper.h */; };
+ 1A40D14E1E8E56C7002E363A /* memorybuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0FB1E8E56C6002E363A /* memorybuffer.h */; };
+ 1A40D14F1E8E56C7002E363A /* memorybuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0FB1E8E56C6002E363A /* memorybuffer.h */; };
+ 1A40D1501E8E56C7002E363A /* memorybuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0FB1E8E56C6002E363A /* memorybuffer.h */; };
+ 1A40D1511E8E56C7002E363A /* memorystream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0FC1E8E56C6002E363A /* memorystream.h */; };
+ 1A40D1521E8E56C7002E363A /* memorystream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0FC1E8E56C6002E363A /* memorystream.h */; };
+ 1A40D1531E8E56C7002E363A /* memorystream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D0FC1E8E56C6002E363A /* memorystream.h */; };
+ 1A40D15A1E8E56C7002E363A /* ostreamwrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1001E8E56C6002E363A /* ostreamwrapper.h */; };
+ 1A40D15B1E8E56C7002E363A /* ostreamwrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1001E8E56C6002E363A /* ostreamwrapper.h */; };
+ 1A40D15C1E8E56C7002E363A /* ostreamwrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1001E8E56C6002E363A /* ostreamwrapper.h */; };
+ 1A40D15D1E8E56C7002E363A /* pointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1011E8E56C6002E363A /* pointer.h */; };
+ 1A40D15E1E8E56C7002E363A /* pointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1011E8E56C6002E363A /* pointer.h */; };
+ 1A40D15F1E8E56C7002E363A /* pointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1011E8E56C6002E363A /* pointer.h */; };
+ 1A40D1601E8E56C7002E363A /* prettywriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1021E8E56C6002E363A /* prettywriter.h */; };
+ 1A40D1611E8E56C7002E363A /* prettywriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1021E8E56C6002E363A /* prettywriter.h */; };
+ 1A40D1621E8E56C7002E363A /* prettywriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1021E8E56C6002E363A /* prettywriter.h */; };
+ 1A40D1631E8E56C7002E363A /* rapidjson.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1031E8E56C6002E363A /* rapidjson.h */; };
+ 1A40D1641E8E56C7002E363A /* rapidjson.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1031E8E56C6002E363A /* rapidjson.h */; };
+ 1A40D1651E8E56C7002E363A /* rapidjson.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1031E8E56C6002E363A /* rapidjson.h */; };
+ 1A40D1661E8E56C7002E363A /* reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1041E8E56C6002E363A /* reader.h */; };
+ 1A40D1671E8E56C7002E363A /* reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1041E8E56C6002E363A /* reader.h */; };
+ 1A40D1681E8E56C7002E363A /* reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1041E8E56C6002E363A /* reader.h */; };
+ 1A40D1691E8E56C7002E363A /* schema.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1051E8E56C6002E363A /* schema.h */; };
+ 1A40D16A1E8E56C7002E363A /* schema.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1051E8E56C6002E363A /* schema.h */; };
+ 1A40D16B1E8E56C7002E363A /* schema.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1051E8E56C6002E363A /* schema.h */; };
+ 1A40D16C1E8E56C7002E363A /* stream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1061E8E56C6002E363A /* stream.h */; };
+ 1A40D16D1E8E56C7002E363A /* stream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1061E8E56C6002E363A /* stream.h */; };
+ 1A40D16E1E8E56C7002E363A /* stream.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1061E8E56C6002E363A /* stream.h */; };
+ 1A40D16F1E8E56C7002E363A /* stringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1071E8E56C6002E363A /* stringbuffer.h */; };
+ 1A40D1701E8E56C7002E363A /* stringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1071E8E56C6002E363A /* stringbuffer.h */; };
+ 1A40D1711E8E56C7002E363A /* stringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1071E8E56C6002E363A /* stringbuffer.h */; };
+ 1A40D1721E8E56C7002E363A /* writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1081E8E56C6002E363A /* writer.h */; };
+ 1A40D1731E8E56C7002E363A /* writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1081E8E56C6002E363A /* writer.h */; };
+ 1A40D1741E8E56C7002E363A /* writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A40D1081E8E56C6002E363A /* writer.h */; };
+ 1A41ABC21DF00CEC00B5584C /* AudioDecoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A41ABC11DF00CEC00B5584C /* AudioDecoder.mm */; };
+ 1A41ABC31DF00CEC00B5584C /* AudioDecoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A41ABC11DF00CEC00B5584C /* AudioDecoder.mm */; };
+ 1A41ABC41DF00CEC00B5584C /* AudioDecoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A41ABC11DF00CEC00B5584C /* AudioDecoder.mm */; };
+ 1A41ABC61DF00D1500B5584C /* AudioDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A41ABC51DF00D1500B5584C /* AudioDecoder.h */; };
+ 1A41ABC71DF00D1500B5584C /* AudioDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A41ABC51DF00D1500B5584C /* AudioDecoder.h */; };
+ 1A41ABC81DF00D1500B5584C /* AudioDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A41ABC51DF00D1500B5584C /* AudioDecoder.h */; };
+ 1A4C3ABA1E9B7A45001972CC /* CCStencilStateManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A4C3AB91E9B7A45001972CC /* CCStencilStateManager.h */; };
+ 1A570061180BC5A10088DEC7 /* CCAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570047180BC5A10088DEC7 /* CCAction.cpp */; };
+ 1A570062180BC5A10088DEC7 /* CCAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570047180BC5A10088DEC7 /* CCAction.cpp */; };
+ 1A570063180BC5A10088DEC7 /* CCAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570048180BC5A10088DEC7 /* CCAction.h */; };
+ 1A570064180BC5A10088DEC7 /* CCAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570048180BC5A10088DEC7 /* CCAction.h */; };
+ 1A570065180BC5A10088DEC7 /* CCActionCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570049180BC5A10088DEC7 /* CCActionCamera.cpp */; };
+ 1A570066180BC5A10088DEC7 /* CCActionCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570049180BC5A10088DEC7 /* CCActionCamera.cpp */; };
+ 1A570067180BC5A10088DEC7 /* CCActionCamera.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57004A180BC5A10088DEC7 /* CCActionCamera.h */; };
+ 1A570068180BC5A10088DEC7 /* CCActionCamera.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57004A180BC5A10088DEC7 /* CCActionCamera.h */; };
+ 1A570069180BC5A10088DEC7 /* CCActionCatmullRom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57004B180BC5A10088DEC7 /* CCActionCatmullRom.cpp */; };
+ 1A57006A180BC5A10088DEC7 /* CCActionCatmullRom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57004B180BC5A10088DEC7 /* CCActionCatmullRom.cpp */; };
+ 1A57006B180BC5A10088DEC7 /* CCActionCatmullRom.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57004C180BC5A10088DEC7 /* CCActionCatmullRom.h */; };
+ 1A57006C180BC5A10088DEC7 /* CCActionCatmullRom.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57004C180BC5A10088DEC7 /* CCActionCatmullRom.h */; };
+ 1A57006D180BC5A10088DEC7 /* CCActionEase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57004D180BC5A10088DEC7 /* CCActionEase.cpp */; };
+ 1A57006E180BC5A10088DEC7 /* CCActionEase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57004D180BC5A10088DEC7 /* CCActionEase.cpp */; };
+ 1A57006F180BC5A10088DEC7 /* CCActionEase.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57004E180BC5A10088DEC7 /* CCActionEase.h */; };
+ 1A570070180BC5A10088DEC7 /* CCActionEase.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57004E180BC5A10088DEC7 /* CCActionEase.h */; };
+ 1A570071180BC5A10088DEC7 /* CCActionGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57004F180BC5A10088DEC7 /* CCActionGrid.cpp */; };
+ 1A570072180BC5A10088DEC7 /* CCActionGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57004F180BC5A10088DEC7 /* CCActionGrid.cpp */; };
+ 1A570073180BC5A10088DEC7 /* CCActionGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570050180BC5A10088DEC7 /* CCActionGrid.h */; };
+ 1A570074180BC5A10088DEC7 /* CCActionGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570050180BC5A10088DEC7 /* CCActionGrid.h */; };
+ 1A570075180BC5A10088DEC7 /* CCActionGrid3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570051180BC5A10088DEC7 /* CCActionGrid3D.cpp */; };
+ 1A570076180BC5A10088DEC7 /* CCActionGrid3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570051180BC5A10088DEC7 /* CCActionGrid3D.cpp */; };
+ 1A570077180BC5A10088DEC7 /* CCActionGrid3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570052180BC5A10088DEC7 /* CCActionGrid3D.h */; };
+ 1A570078180BC5A10088DEC7 /* CCActionGrid3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570052180BC5A10088DEC7 /* CCActionGrid3D.h */; };
+ 1A570079180BC5A10088DEC7 /* CCActionInstant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570053180BC5A10088DEC7 /* CCActionInstant.cpp */; };
+ 1A57007A180BC5A10088DEC7 /* CCActionInstant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570053180BC5A10088DEC7 /* CCActionInstant.cpp */; };
+ 1A57007B180BC5A10088DEC7 /* CCActionInstant.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570054180BC5A10088DEC7 /* CCActionInstant.h */; };
+ 1A57007C180BC5A10088DEC7 /* CCActionInstant.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570054180BC5A10088DEC7 /* CCActionInstant.h */; };
+ 1A57007D180BC5A10088DEC7 /* CCActionInterval.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570055180BC5A10088DEC7 /* CCActionInterval.cpp */; };
+ 1A57007E180BC5A10088DEC7 /* CCActionInterval.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570055180BC5A10088DEC7 /* CCActionInterval.cpp */; };
+ 1A57007F180BC5A10088DEC7 /* CCActionInterval.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570056180BC5A10088DEC7 /* CCActionInterval.h */; };
+ 1A570080180BC5A10088DEC7 /* CCActionInterval.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570056180BC5A10088DEC7 /* CCActionInterval.h */; };
+ 1A570081180BC5A10088DEC7 /* CCActionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570057180BC5A10088DEC7 /* CCActionManager.cpp */; };
+ 1A570082180BC5A10088DEC7 /* CCActionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570057180BC5A10088DEC7 /* CCActionManager.cpp */; };
+ 1A570083180BC5A10088DEC7 /* CCActionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570058180BC5A10088DEC7 /* CCActionManager.h */; };
+ 1A570084180BC5A10088DEC7 /* CCActionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570058180BC5A10088DEC7 /* CCActionManager.h */; };
+ 1A570085180BC5A10088DEC7 /* CCActionPageTurn3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570059180BC5A10088DEC7 /* CCActionPageTurn3D.cpp */; };
+ 1A570086180BC5A10088DEC7 /* CCActionPageTurn3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570059180BC5A10088DEC7 /* CCActionPageTurn3D.cpp */; };
+ 1A570087180BC5A10088DEC7 /* CCActionPageTurn3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57005A180BC5A10088DEC7 /* CCActionPageTurn3D.h */; };
+ 1A570088180BC5A10088DEC7 /* CCActionPageTurn3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57005A180BC5A10088DEC7 /* CCActionPageTurn3D.h */; };
+ 1A570089180BC5A10088DEC7 /* CCActionProgressTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57005B180BC5A10088DEC7 /* CCActionProgressTimer.cpp */; };
+ 1A57008A180BC5A10088DEC7 /* CCActionProgressTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57005B180BC5A10088DEC7 /* CCActionProgressTimer.cpp */; };
+ 1A57008B180BC5A10088DEC7 /* CCActionProgressTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57005C180BC5A10088DEC7 /* CCActionProgressTimer.h */; };
+ 1A57008C180BC5A10088DEC7 /* CCActionProgressTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57005C180BC5A10088DEC7 /* CCActionProgressTimer.h */; };
+ 1A57008D180BC5A10088DEC7 /* CCActionTiledGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57005D180BC5A10088DEC7 /* CCActionTiledGrid.cpp */; };
+ 1A57008E180BC5A10088DEC7 /* CCActionTiledGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57005D180BC5A10088DEC7 /* CCActionTiledGrid.cpp */; };
+ 1A57008F180BC5A10088DEC7 /* CCActionTiledGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57005E180BC5A10088DEC7 /* CCActionTiledGrid.h */; };
+ 1A570090180BC5A10088DEC7 /* CCActionTiledGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57005E180BC5A10088DEC7 /* CCActionTiledGrid.h */; };
+ 1A570091180BC5A10088DEC7 /* CCActionTween.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57005F180BC5A10088DEC7 /* CCActionTween.cpp */; };
+ 1A570092180BC5A10088DEC7 /* CCActionTween.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57005F180BC5A10088DEC7 /* CCActionTween.cpp */; };
+ 1A570093180BC5A10088DEC7 /* CCActionTween.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570060180BC5A10088DEC7 /* CCActionTween.h */; };
+ 1A570094180BC5A10088DEC7 /* CCActionTween.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570060180BC5A10088DEC7 /* CCActionTween.h */; };
+ 1A570098180BC5C10088DEC7 /* CCAtlasNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570096180BC5C10088DEC7 /* CCAtlasNode.cpp */; };
+ 1A570099180BC5C10088DEC7 /* CCAtlasNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570096180BC5C10088DEC7 /* CCAtlasNode.cpp */; };
+ 1A57009A180BC5C10088DEC7 /* CCAtlasNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570097180BC5C10088DEC7 /* CCAtlasNode.h */; };
+ 1A57009B180BC5C10088DEC7 /* CCAtlasNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570097180BC5C10088DEC7 /* CCAtlasNode.h */; };
+ 1A57009E180BC5D20088DEC7 /* CCNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57009C180BC5D20088DEC7 /* CCNode.cpp */; };
+ 1A57009F180BC5D20088DEC7 /* CCNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57009C180BC5D20088DEC7 /* CCNode.cpp */; };
+ 1A5700A0180BC5D20088DEC7 /* CCNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57009D180BC5D20088DEC7 /* CCNode.h */; };
+ 1A5700A1180BC5D20088DEC7 /* CCNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57009D180BC5D20088DEC7 /* CCNode.h */; };
+ 1A57010E180BC8EE0088DEC7 /* CCDrawingPrimitives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57010A180BC8ED0088DEC7 /* CCDrawingPrimitives.cpp */; };
+ 1A57010F180BC8EE0088DEC7 /* CCDrawingPrimitives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57010A180BC8ED0088DEC7 /* CCDrawingPrimitives.cpp */; };
+ 1A570110180BC8EE0088DEC7 /* CCDrawingPrimitives.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57010B180BC8EE0088DEC7 /* CCDrawingPrimitives.h */; };
+ 1A570111180BC8EE0088DEC7 /* CCDrawingPrimitives.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57010B180BC8EE0088DEC7 /* CCDrawingPrimitives.h */; };
+ 1A570112180BC8EE0088DEC7 /* CCDrawNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57010C180BC8EE0088DEC7 /* CCDrawNode.cpp */; };
+ 1A570113180BC8EE0088DEC7 /* CCDrawNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57010C180BC8EE0088DEC7 /* CCDrawNode.cpp */; };
+ 1A570114180BC8EE0088DEC7 /* CCDrawNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57010D180BC8EE0088DEC7 /* CCDrawNode.h */; };
+ 1A570115180BC8EE0088DEC7 /* CCDrawNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57010D180BC8EE0088DEC7 /* CCDrawNode.h */; };
+ 1A57011B180BC90D0088DEC7 /* CCGrabber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570117180BC90D0088DEC7 /* CCGrabber.cpp */; };
+ 1A57011C180BC90D0088DEC7 /* CCGrabber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570117180BC90D0088DEC7 /* CCGrabber.cpp */; };
+ 1A57011D180BC90D0088DEC7 /* CCGrabber.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570118180BC90D0088DEC7 /* CCGrabber.h */; };
+ 1A57011E180BC90D0088DEC7 /* CCGrabber.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570118180BC90D0088DEC7 /* CCGrabber.h */; };
+ 1A57011F180BC90D0088DEC7 /* CCGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570119180BC90D0088DEC7 /* CCGrid.cpp */; };
+ 1A570120180BC90D0088DEC7 /* CCGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570119180BC90D0088DEC7 /* CCGrid.cpp */; };
+ 1A570121180BC90D0088DEC7 /* CCGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57011A180BC90D0088DEC7 /* CCGrid.h */; };
+ 1A570122180BC90D0088DEC7 /* CCGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57011A180BC90D0088DEC7 /* CCGrid.h */; };
+ 1A57019D180BCB590088DEC7 /* CCFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570182180BCB590088DEC7 /* CCFont.cpp */; };
+ 1A57019E180BCB590088DEC7 /* CCFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570182180BCB590088DEC7 /* CCFont.cpp */; };
+ 1A57019F180BCB590088DEC7 /* CCFont.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570183180BCB590088DEC7 /* CCFont.h */; };
+ 1A5701A0180BCB590088DEC7 /* CCFont.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570183180BCB590088DEC7 /* CCFont.h */; };
+ 1A5701A1180BCB590088DEC7 /* CCFontAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570184180BCB590088DEC7 /* CCFontAtlas.cpp */; };
+ 1A5701A2180BCB590088DEC7 /* CCFontAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570184180BCB590088DEC7 /* CCFontAtlas.cpp */; };
+ 1A5701A3180BCB590088DEC7 /* CCFontAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570185180BCB590088DEC7 /* CCFontAtlas.h */; };
+ 1A5701A4180BCB590088DEC7 /* CCFontAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570185180BCB590088DEC7 /* CCFontAtlas.h */; };
+ 1A5701A5180BCB590088DEC7 /* CCFontAtlasCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570186180BCB590088DEC7 /* CCFontAtlasCache.cpp */; };
+ 1A5701A6180BCB590088DEC7 /* CCFontAtlasCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570186180BCB590088DEC7 /* CCFontAtlasCache.cpp */; };
+ 1A5701A7180BCB590088DEC7 /* CCFontAtlasCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570187180BCB590088DEC7 /* CCFontAtlasCache.h */; };
+ 1A5701A8180BCB590088DEC7 /* CCFontAtlasCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570187180BCB590088DEC7 /* CCFontAtlasCache.h */; };
+ 1A5701B1180BCB590088DEC7 /* CCFontFNT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57018C180BCB590088DEC7 /* CCFontFNT.cpp */; };
+ 1A5701B2180BCB590088DEC7 /* CCFontFNT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57018C180BCB590088DEC7 /* CCFontFNT.cpp */; };
+ 1A5701B3180BCB590088DEC7 /* CCFontFNT.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57018D180BCB590088DEC7 /* CCFontFNT.h */; };
+ 1A5701B4180BCB590088DEC7 /* CCFontFNT.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57018D180BCB590088DEC7 /* CCFontFNT.h */; };
+ 1A5701B5180BCB590088DEC7 /* CCFontFreeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57018E180BCB590088DEC7 /* CCFontFreeType.cpp */; };
+ 1A5701B6180BCB590088DEC7 /* CCFontFreeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57018E180BCB590088DEC7 /* CCFontFreeType.cpp */; };
+ 1A5701B7180BCB5A0088DEC7 /* CCFontFreeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57018F180BCB590088DEC7 /* CCFontFreeType.h */; };
+ 1A5701B8180BCB5A0088DEC7 /* CCFontFreeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57018F180BCB590088DEC7 /* CCFontFreeType.h */; };
+ 1A5701B9180BCB5A0088DEC7 /* CCLabel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570190180BCB590088DEC7 /* CCLabel.cpp */; };
+ 1A5701BA180BCB5A0088DEC7 /* CCLabel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570190180BCB590088DEC7 /* CCLabel.cpp */; };
+ 1A5701BB180BCB5A0088DEC7 /* CCLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570191180BCB590088DEC7 /* CCLabel.h */; };
+ 1A5701BC180BCB5A0088DEC7 /* CCLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570191180BCB590088DEC7 /* CCLabel.h */; };
+ 1A5701BD180BCB5A0088DEC7 /* CCLabelAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570192180BCB590088DEC7 /* CCLabelAtlas.cpp */; };
+ 1A5701BE180BCB5A0088DEC7 /* CCLabelAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570192180BCB590088DEC7 /* CCLabelAtlas.cpp */; };
+ 1A5701BF180BCB5A0088DEC7 /* CCLabelAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570193180BCB590088DEC7 /* CCLabelAtlas.h */; };
+ 1A5701C0180BCB5A0088DEC7 /* CCLabelAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570193180BCB590088DEC7 /* CCLabelAtlas.h */; };
+ 1A5701C1180BCB5A0088DEC7 /* CCLabelBMFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570194180BCB590088DEC7 /* CCLabelBMFont.cpp */; };
+ 1A5701C2180BCB5A0088DEC7 /* CCLabelBMFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570194180BCB590088DEC7 /* CCLabelBMFont.cpp */; };
+ 1A5701C3180BCB5A0088DEC7 /* CCLabelBMFont.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570195180BCB590088DEC7 /* CCLabelBMFont.h */; };
+ 1A5701C4180BCB5A0088DEC7 /* CCLabelBMFont.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570195180BCB590088DEC7 /* CCLabelBMFont.h */; };
+ 1A5701C7180BCB5A0088DEC7 /* CCLabelTextFormatter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570197180BCB590088DEC7 /* CCLabelTextFormatter.cpp */; };
+ 1A5701C8180BCB5A0088DEC7 /* CCLabelTextFormatter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570197180BCB590088DEC7 /* CCLabelTextFormatter.cpp */; };
+ 1A5701C9180BCB5A0088DEC7 /* CCLabelTextFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570198180BCB590088DEC7 /* CCLabelTextFormatter.h */; };
+ 1A5701CA180BCB5A0088DEC7 /* CCLabelTextFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570198180BCB590088DEC7 /* CCLabelTextFormatter.h */; };
+ 1A5701CB180BCB5A0088DEC7 /* CCLabelTTF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570199180BCB590088DEC7 /* CCLabelTTF.cpp */; };
+ 1A5701CC180BCB5A0088DEC7 /* CCLabelTTF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570199180BCB590088DEC7 /* CCLabelTTF.cpp */; };
+ 1A5701CD180BCB5A0088DEC7 /* CCLabelTTF.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57019A180BCB590088DEC7 /* CCLabelTTF.h */; };
+ 1A5701CE180BCB5A0088DEC7 /* CCLabelTTF.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57019A180BCB590088DEC7 /* CCLabelTTF.h */; };
+ 1A5701DE180BCB8C0088DEC7 /* CCLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701D4180BCB8C0088DEC7 /* CCLayer.cpp */; };
+ 1A5701DF180BCB8C0088DEC7 /* CCLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701D4180BCB8C0088DEC7 /* CCLayer.cpp */; };
+ 1A5701E0180BCB8C0088DEC7 /* CCLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701D5180BCB8C0088DEC7 /* CCLayer.h */; };
+ 1A5701E1180BCB8C0088DEC7 /* CCLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701D5180BCB8C0088DEC7 /* CCLayer.h */; };
+ 1A5701E2180BCB8C0088DEC7 /* CCScene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701D6180BCB8C0088DEC7 /* CCScene.cpp */; };
+ 1A5701E3180BCB8C0088DEC7 /* CCScene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701D6180BCB8C0088DEC7 /* CCScene.cpp */; };
+ 1A5701E4180BCB8C0088DEC7 /* CCScene.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701D7180BCB8C0088DEC7 /* CCScene.h */; };
+ 1A5701E5180BCB8C0088DEC7 /* CCScene.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701D7180BCB8C0088DEC7 /* CCScene.h */; };
+ 1A5701E6180BCB8C0088DEC7 /* CCTransition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701D8180BCB8C0088DEC7 /* CCTransition.cpp */; };
+ 1A5701E7180BCB8C0088DEC7 /* CCTransition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701D8180BCB8C0088DEC7 /* CCTransition.cpp */; };
+ 1A5701E8180BCB8C0088DEC7 /* CCTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701D9180BCB8C0088DEC7 /* CCTransition.h */; };
+ 1A5701E9180BCB8C0088DEC7 /* CCTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701D9180BCB8C0088DEC7 /* CCTransition.h */; };
+ 1A5701EA180BCB8C0088DEC7 /* CCTransitionPageTurn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701DA180BCB8C0088DEC7 /* CCTransitionPageTurn.cpp */; };
+ 1A5701EB180BCB8C0088DEC7 /* CCTransitionPageTurn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701DA180BCB8C0088DEC7 /* CCTransitionPageTurn.cpp */; };
+ 1A5701EC180BCB8C0088DEC7 /* CCTransitionPageTurn.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701DB180BCB8C0088DEC7 /* CCTransitionPageTurn.h */; };
+ 1A5701ED180BCB8C0088DEC7 /* CCTransitionPageTurn.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701DB180BCB8C0088DEC7 /* CCTransitionPageTurn.h */; };
+ 1A5701EE180BCB8C0088DEC7 /* CCTransitionProgress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701DC180BCB8C0088DEC7 /* CCTransitionProgress.cpp */; };
+ 1A5701EF180BCB8C0088DEC7 /* CCTransitionProgress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701DC180BCB8C0088DEC7 /* CCTransitionProgress.cpp */; };
+ 1A5701F0180BCB8C0088DEC7 /* CCTransitionProgress.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701DD180BCB8C0088DEC7 /* CCTransitionProgress.h */; };
+ 1A5701F1180BCB8C0088DEC7 /* CCTransitionProgress.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701DD180BCB8C0088DEC7 /* CCTransitionProgress.h */; };
+ 1A5701F7180BCBAD0088DEC7 /* CCMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701F3180BCBAD0088DEC7 /* CCMenu.cpp */; };
+ 1A5701F8180BCBAD0088DEC7 /* CCMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701F3180BCBAD0088DEC7 /* CCMenu.cpp */; };
+ 1A5701F9180BCBAD0088DEC7 /* CCMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701F4180BCBAD0088DEC7 /* CCMenu.h */; };
+ 1A5701FA180BCBAD0088DEC7 /* CCMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701F4180BCBAD0088DEC7 /* CCMenu.h */; };
+ 1A5701FB180BCBAD0088DEC7 /* CCMenuItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701F5180BCBAD0088DEC7 /* CCMenuItem.cpp */; };
+ 1A5701FC180BCBAD0088DEC7 /* CCMenuItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701F5180BCBAD0088DEC7 /* CCMenuItem.cpp */; };
+ 1A5701FD180BCBAD0088DEC7 /* CCMenuItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701F6180BCBAD0088DEC7 /* CCMenuItem.h */; };
+ 1A5701FE180BCBAD0088DEC7 /* CCMenuItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701F6180BCBAD0088DEC7 /* CCMenuItem.h */; };
+ 1A570202180BCBD40088DEC7 /* CCClippingNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570200180BCBD40088DEC7 /* CCClippingNode.cpp */; };
+ 1A570203180BCBD40088DEC7 /* CCClippingNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570200180BCBD40088DEC7 /* CCClippingNode.cpp */; };
+ 1A570204180BCBD40088DEC7 /* CCClippingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570201180BCBD40088DEC7 /* CCClippingNode.h */; };
+ 1A570205180BCBD40088DEC7 /* CCClippingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570201180BCBD40088DEC7 /* CCClippingNode.h */; };
+ 1A570208180BCBDF0088DEC7 /* CCMotionStreak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570206180BCBDF0088DEC7 /* CCMotionStreak.cpp */; };
+ 1A570209180BCBDF0088DEC7 /* CCMotionStreak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570206180BCBDF0088DEC7 /* CCMotionStreak.cpp */; };
+ 1A57020A180BCBDF0088DEC7 /* CCMotionStreak.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570207180BCBDF0088DEC7 /* CCMotionStreak.h */; };
+ 1A57020B180BCBDF0088DEC7 /* CCMotionStreak.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570207180BCBDF0088DEC7 /* CCMotionStreak.h */; };
+ 1A570210180BCBF40088DEC7 /* CCProgressTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57020C180BCBF40088DEC7 /* CCProgressTimer.cpp */; };
+ 1A570211180BCBF40088DEC7 /* CCProgressTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57020C180BCBF40088DEC7 /* CCProgressTimer.cpp */; };
+ 1A570212180BCBF40088DEC7 /* CCProgressTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57020D180BCBF40088DEC7 /* CCProgressTimer.h */; };
+ 1A570213180BCBF40088DEC7 /* CCProgressTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57020D180BCBF40088DEC7 /* CCProgressTimer.h */; };
+ 1A570214180BCBF40088DEC7 /* CCRenderTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57020E180BCBF40088DEC7 /* CCRenderTexture.cpp */; };
+ 1A570215180BCBF40088DEC7 /* CCRenderTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57020E180BCBF40088DEC7 /* CCRenderTexture.cpp */; };
+ 1A570216180BCBF40088DEC7 /* CCRenderTexture.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57020F180BCBF40088DEC7 /* CCRenderTexture.h */; };
+ 1A570217180BCBF40088DEC7 /* CCRenderTexture.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57020F180BCBF40088DEC7 /* CCRenderTexture.h */; };
+ 1A570221180BCC1A0088DEC7 /* CCParticleBatchNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570219180BCC1A0088DEC7 /* CCParticleBatchNode.cpp */; };
+ 1A570222180BCC1A0088DEC7 /* CCParticleBatchNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570219180BCC1A0088DEC7 /* CCParticleBatchNode.cpp */; };
+ 1A570223180BCC1A0088DEC7 /* CCParticleBatchNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57021A180BCC1A0088DEC7 /* CCParticleBatchNode.h */; };
+ 1A570224180BCC1A0088DEC7 /* CCParticleBatchNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57021A180BCC1A0088DEC7 /* CCParticleBatchNode.h */; };
+ 1A570225180BCC1A0088DEC7 /* CCParticleExamples.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57021B180BCC1A0088DEC7 /* CCParticleExamples.cpp */; };
+ 1A570226180BCC1A0088DEC7 /* CCParticleExamples.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57021B180BCC1A0088DEC7 /* CCParticleExamples.cpp */; };
+ 1A570227180BCC1A0088DEC7 /* CCParticleExamples.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57021C180BCC1A0088DEC7 /* CCParticleExamples.h */; };
+ 1A570228180BCC1A0088DEC7 /* CCParticleExamples.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57021C180BCC1A0088DEC7 /* CCParticleExamples.h */; };
+ 1A570229180BCC1A0088DEC7 /* CCParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57021D180BCC1A0088DEC7 /* CCParticleSystem.cpp */; };
+ 1A57022A180BCC1A0088DEC7 /* CCParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57021D180BCC1A0088DEC7 /* CCParticleSystem.cpp */; };
+ 1A57022B180BCC1A0088DEC7 /* CCParticleSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57021E180BCC1A0088DEC7 /* CCParticleSystem.h */; };
+ 1A57022C180BCC1A0088DEC7 /* CCParticleSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57021E180BCC1A0088DEC7 /* CCParticleSystem.h */; };
+ 1A57022D180BCC1A0088DEC7 /* CCParticleSystemQuad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57021F180BCC1A0088DEC7 /* CCParticleSystemQuad.cpp */; };
+ 1A57022E180BCC1A0088DEC7 /* CCParticleSystemQuad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57021F180BCC1A0088DEC7 /* CCParticleSystemQuad.cpp */; };
+ 1A57022F180BCC1A0088DEC7 /* CCParticleSystemQuad.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570220180BCC1A0088DEC7 /* CCParticleSystemQuad.h */; };
+ 1A570230180BCC1A0088DEC7 /* CCParticleSystemQuad.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570220180BCC1A0088DEC7 /* CCParticleSystemQuad.h */; };
+ 1A57027E180BCC900088DEC7 /* CCSprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570276180BCC900088DEC7 /* CCSprite.cpp */; };
+ 1A57027F180BCC900088DEC7 /* CCSprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570276180BCC900088DEC7 /* CCSprite.cpp */; };
+ 1A570280180BCC900088DEC7 /* CCSprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570277180BCC900088DEC7 /* CCSprite.h */; };
+ 1A570281180BCC900088DEC7 /* CCSprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570277180BCC900088DEC7 /* CCSprite.h */; };
+ 1A570282180BCC900088DEC7 /* CCSpriteBatchNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570278180BCC900088DEC7 /* CCSpriteBatchNode.cpp */; };
+ 1A570283180BCC900088DEC7 /* CCSpriteBatchNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570278180BCC900088DEC7 /* CCSpriteBatchNode.cpp */; };
+ 1A570284180BCC900088DEC7 /* CCSpriteBatchNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570279180BCC900088DEC7 /* CCSpriteBatchNode.h */; };
+ 1A570285180BCC900088DEC7 /* CCSpriteBatchNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570279180BCC900088DEC7 /* CCSpriteBatchNode.h */; };
+ 1A570286180BCC900088DEC7 /* CCSpriteFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57027A180BCC900088DEC7 /* CCSpriteFrame.cpp */; };
+ 1A570287180BCC900088DEC7 /* CCSpriteFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57027A180BCC900088DEC7 /* CCSpriteFrame.cpp */; };
+ 1A570288180BCC900088DEC7 /* CCSpriteFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57027B180BCC900088DEC7 /* CCSpriteFrame.h */; };
+ 1A570289180BCC900088DEC7 /* CCSpriteFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57027B180BCC900088DEC7 /* CCSpriteFrame.h */; };
+ 1A57028A180BCC900088DEC7 /* CCSpriteFrameCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57027C180BCC900088DEC7 /* CCSpriteFrameCache.cpp */; };
+ 1A57028B180BCC900088DEC7 /* CCSpriteFrameCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57027C180BCC900088DEC7 /* CCSpriteFrameCache.cpp */; };
+ 1A57028C180BCC900088DEC7 /* CCSpriteFrameCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57027D180BCC900088DEC7 /* CCSpriteFrameCache.h */; };
+ 1A57028D180BCC900088DEC7 /* CCSpriteFrameCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57027D180BCC900088DEC7 /* CCSpriteFrameCache.h */; };
+ 1A570292180BCCAB0088DEC7 /* CCAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57028E180BCCAB0088DEC7 /* CCAnimation.cpp */; };
+ 1A570293180BCCAB0088DEC7 /* CCAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57028E180BCCAB0088DEC7 /* CCAnimation.cpp */; };
+ 1A570294180BCCAB0088DEC7 /* CCAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57028F180BCCAB0088DEC7 /* CCAnimation.h */; };
+ 1A570295180BCCAB0088DEC7 /* CCAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57028F180BCCAB0088DEC7 /* CCAnimation.h */; };
+ 1A570296180BCCAB0088DEC7 /* CCAnimationCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570290180BCCAB0088DEC7 /* CCAnimationCache.cpp */; };
+ 1A570297180BCCAB0088DEC7 /* CCAnimationCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570290180BCCAB0088DEC7 /* CCAnimationCache.cpp */; };
+ 1A570298180BCCAB0088DEC7 /* CCAnimationCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570291180BCCAB0088DEC7 /* CCAnimationCache.h */; };
+ 1A570299180BCCAB0088DEC7 /* CCAnimationCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570291180BCCAB0088DEC7 /* CCAnimationCache.h */; };
+ 1A5702C8180BCE370088DEC7 /* CCTextFieldTTF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702C6180BCE370088DEC7 /* CCTextFieldTTF.cpp */; };
+ 1A5702C9180BCE370088DEC7 /* CCTextFieldTTF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702C6180BCE370088DEC7 /* CCTextFieldTTF.cpp */; };
+ 1A5702CA180BCE370088DEC7 /* CCTextFieldTTF.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702C7180BCE370088DEC7 /* CCTextFieldTTF.h */; };
+ 1A5702CB180BCE370088DEC7 /* CCTextFieldTTF.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702C7180BCE370088DEC7 /* CCTextFieldTTF.h */; };
+ 1A5702EA180BCE750088DEC7 /* CCTileMapAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E0180BCE750088DEC7 /* CCTileMapAtlas.cpp */; };
+ 1A5702EB180BCE750088DEC7 /* CCTileMapAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E0180BCE750088DEC7 /* CCTileMapAtlas.cpp */; };
+ 1A5702EC180BCE750088DEC7 /* CCTileMapAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E1180BCE750088DEC7 /* CCTileMapAtlas.h */; };
+ 1A5702ED180BCE750088DEC7 /* CCTileMapAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E1180BCE750088DEC7 /* CCTileMapAtlas.h */; };
+ 1A5702EE180BCE750088DEC7 /* CCTMXLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E2180BCE750088DEC7 /* CCTMXLayer.cpp */; };
+ 1A5702EF180BCE750088DEC7 /* CCTMXLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E2180BCE750088DEC7 /* CCTMXLayer.cpp */; };
+ 1A5702F0180BCE750088DEC7 /* CCTMXLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E3180BCE750088DEC7 /* CCTMXLayer.h */; };
+ 1A5702F1180BCE750088DEC7 /* CCTMXLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E3180BCE750088DEC7 /* CCTMXLayer.h */; };
+ 1A5702F2180BCE750088DEC7 /* CCTMXObjectGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E4180BCE750088DEC7 /* CCTMXObjectGroup.cpp */; };
+ 1A5702F3180BCE750088DEC7 /* CCTMXObjectGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E4180BCE750088DEC7 /* CCTMXObjectGroup.cpp */; };
+ 1A5702F4180BCE750088DEC7 /* CCTMXObjectGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E5180BCE750088DEC7 /* CCTMXObjectGroup.h */; };
+ 1A5702F5180BCE750088DEC7 /* CCTMXObjectGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E5180BCE750088DEC7 /* CCTMXObjectGroup.h */; };
+ 1A5702F6180BCE750088DEC7 /* CCTMXTiledMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E6180BCE750088DEC7 /* CCTMXTiledMap.cpp */; };
+ 1A5702F7180BCE750088DEC7 /* CCTMXTiledMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E6180BCE750088DEC7 /* CCTMXTiledMap.cpp */; };
+ 1A5702F8180BCE750088DEC7 /* CCTMXTiledMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E7180BCE750088DEC7 /* CCTMXTiledMap.h */; };
+ 1A5702F9180BCE750088DEC7 /* CCTMXTiledMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E7180BCE750088DEC7 /* CCTMXTiledMap.h */; };
+ 1A5702FA180BCE750088DEC7 /* CCTMXXMLParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E8180BCE750088DEC7 /* CCTMXXMLParser.cpp */; };
+ 1A5702FB180BCE750088DEC7 /* CCTMXXMLParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E8180BCE750088DEC7 /* CCTMXXMLParser.cpp */; };
+ 1A5702FC180BCE750088DEC7 /* CCTMXXMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E9180BCE750088DEC7 /* CCTMXXMLParser.h */; };
+ 1A5702FD180BCE750088DEC7 /* CCTMXXMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E9180BCE750088DEC7 /* CCTMXXMLParser.h */; };
+ 1A570300180BCE890088DEC7 /* CCParallaxNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702FE180BCE890088DEC7 /* CCParallaxNode.cpp */; };
+ 1A570301180BCE890088DEC7 /* CCParallaxNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702FE180BCE890088DEC7 /* CCParallaxNode.cpp */; };
+ 1A570302180BCE890088DEC7 /* CCParallaxNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702FF180BCE890088DEC7 /* CCParallaxNode.h */; };
+ 1A570303180BCE890088DEC7 /* CCParallaxNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702FF180BCE890088DEC7 /* CCParallaxNode.h */; };
+ 1A57030C180BCF190088DEC7 /* CCComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570308180BCF190088DEC7 /* CCComponent.cpp */; };
+ 1A57030D180BCF190088DEC7 /* CCComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570308180BCF190088DEC7 /* CCComponent.cpp */; };
+ 1A57030E180BCF190088DEC7 /* CCComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570309180BCF190088DEC7 /* CCComponent.h */; };
+ 1A57030F180BCF190088DEC7 /* CCComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570309180BCF190088DEC7 /* CCComponent.h */; };
+ 1A570310180BCF190088DEC7 /* CCComponentContainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57030A180BCF190088DEC7 /* CCComponentContainer.cpp */; };
+ 1A570311180BCF190088DEC7 /* CCComponentContainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57030A180BCF190088DEC7 /* CCComponentContainer.cpp */; };
+ 1A570312180BCF190088DEC7 /* CCComponentContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57030B180BCF190088DEC7 /* CCComponentContainer.h */; };
+ 1A570313180BCF190088DEC7 /* CCComponentContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57030B180BCF190088DEC7 /* CCComponentContainer.h */; };
+ 1A570347180BD0850088DEC7 /* libglfw3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A570346180BD0850088DEC7 /* libglfw3.a */; };
+ 1A57034B180BD09B0088DEC7 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570349180BD09B0088DEC7 /* tinyxml2.cpp */; };
+ 1A57034C180BD09B0088DEC7 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570349180BD09B0088DEC7 /* tinyxml2.cpp */; };
+ 1A57034D180BD09B0088DEC7 /* tinyxml2.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57034A180BD09B0088DEC7 /* tinyxml2.h */; };
+ 1A57034E180BD09B0088DEC7 /* tinyxml2.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57034A180BD09B0088DEC7 /* tinyxml2.h */; };
+ 1A570354180BD0B00088DEC7 /* ioapi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570350180BD0B00088DEC7 /* ioapi.cpp */; };
+ 1A570355180BD0B00088DEC7 /* ioapi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570350180BD0B00088DEC7 /* ioapi.cpp */; };
+ 1A570356180BD0B00088DEC7 /* ioapi.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570351180BD0B00088DEC7 /* ioapi.h */; };
+ 1A570357180BD0B00088DEC7 /* ioapi.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570351180BD0B00088DEC7 /* ioapi.h */; };
+ 1A570358180BD0B00088DEC7 /* unzip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570352180BD0B00088DEC7 /* unzip.cpp */; };
+ 1A570359180BD0B00088DEC7 /* unzip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570352180BD0B00088DEC7 /* unzip.cpp */; };
+ 1A57035A180BD0B00088DEC7 /* unzip.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570353180BD0B00088DEC7 /* unzip.h */; };
+ 1A57035B180BD0B00088DEC7 /* unzip.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570353180BD0B00088DEC7 /* unzip.h */; };
+ 1A570361180BD1080088DEC7 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A570360180BD1080088DEC7 /* libpng.a */; };
+ 1A570364180BD1120088DEC7 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A570363180BD1120088DEC7 /* libpng.a */; };
+ 1A570378180BD1B40088DEC7 /* libjpeg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A570377180BD1B40088DEC7 /* libjpeg.a */; };
+ 1A57037B180BD1C90088DEC7 /* libjpeg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A57037A180BD1C90088DEC7 /* libjpeg.a */; };
+ 1A5703A1180BD22C0088DEC7 /* libtiff.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A5703A0180BD22C0088DEC7 /* libtiff.a */; };
+ 1A5703A4180BD2350088DEC7 /* libtiff.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A5703A3180BD2350088DEC7 /* libtiff.a */; };
+ 1A5703B8180BD2780088DEC7 /* libwebp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A5703B7180BD2780088DEC7 /* libwebp.a */; };
+ 1A5703BB180BD2800088DEC7 /* libwebp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A5703BA180BD2800088DEC7 /* libwebp.a */; };
+ 1A57052B180BD31F0088DEC7 /* libfreetype.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A57052A180BD31F0088DEC7 /* libfreetype.a */; };
+ 1A57052E180BD3280088DEC7 /* libfreetype.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A57052D180BD3280088DEC7 /* libfreetype.a */; };
+ 1A5FB7C41DF012D900C918C1 /* AudioMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5FB7C31DF012D900C918C1 /* AudioMacros.h */; };
+ 1A5FB7C51DF012D900C918C1 /* AudioMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5FB7C31DF012D900C918C1 /* AudioMacros.h */; };
+ 1A5FB7C61DF012D900C918C1 /* AudioMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5FB7C31DF012D900C918C1 /* AudioMacros.h */; };
+ 1A9DCA27180E6955007A3AD4 /* CCGLBufferedNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A9DCA02180E6955007A3AD4 /* CCGLBufferedNode.cpp */; };
+ 1A9DCA28180E6955007A3AD4 /* CCGLBufferedNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A9DCA02180E6955007A3AD4 /* CCGLBufferedNode.cpp */; };
+ 1A9DCA29180E6955007A3AD4 /* CCGLBufferedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A9DCA03180E6955007A3AD4 /* CCGLBufferedNode.h */; };
+ 1A9DCA2A180E6955007A3AD4 /* CCGLBufferedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A9DCA03180E6955007A3AD4 /* CCGLBufferedNode.h */; };
+ 1AAF584F180E40B9000584C8 /* LocalStorage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF584C180E40B9000584C8 /* LocalStorage.cpp */; };
+ 1AAF5850180E40B9000584C8 /* LocalStorage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF584C180E40B9000584C8 /* LocalStorage.cpp */; };
+ 1AAF5851180E40B9000584C8 /* LocalStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF584D180E40B9000584C8 /* LocalStorage.h */; };
+ 1AAF5852180E40B9000584C8 /* LocalStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF584D180E40B9000584C8 /* LocalStorage.h */; };
+ 1ABA68AE1888D700007D1BB4 /* CCFontCharMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABA68AC1888D700007D1BB4 /* CCFontCharMap.cpp */; };
+ 1ABA68AF1888D700007D1BB4 /* CCFontCharMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABA68AC1888D700007D1BB4 /* CCFontCharMap.cpp */; };
+ 1ABA68B01888D700007D1BB4 /* CCFontCharMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABA68AD1888D700007D1BB4 /* CCFontCharMap.h */; };
+ 1ABA68B11888D700007D1BB4 /* CCFontCharMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABA68AD1888D700007D1BB4 /* CCFontCharMap.h */; };
+ 1AC0269C1914068200FA920D /* ConvertUTF.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AC026991914068200FA920D /* ConvertUTF.h */; };
+ 1AC0269D1914068200FA920D /* ConvertUTF.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AC026991914068200FA920D /* ConvertUTF.h */; };
+ 29031E0719BFE8D400EFA1DF /* libchipmunk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 29031E0619BFE8D400EFA1DF /* libchipmunk.a */; };
+ 29031E0919BFE8DE00EFA1DF /* libchipmunk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 29031E0819BFE8DE00EFA1DF /* libchipmunk.a */; };
+ 291901431B05895600F8B4BA /* CCNinePatchImageParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 291901411B05895600F8B4BA /* CCNinePatchImageParser.h */; };
+ 291901441B05895600F8B4BA /* CCNinePatchImageParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 291901411B05895600F8B4BA /* CCNinePatchImageParser.h */; };
+ 291901451B05895600F8B4BA /* CCNinePatchImageParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 291901421B05895600F8B4BA /* CCNinePatchImageParser.cpp */; };
+ 291901461B05895600F8B4BA /* CCNinePatchImageParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 291901421B05895600F8B4BA /* CCNinePatchImageParser.cpp */; };
+ 291A09241C5F06A60068C1D2 /* CCUIEditBoxMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 291A09221C5F06A60068C1D2 /* CCUIEditBoxMac.h */; };
+ 291A09251C5F06A60068C1D2 /* CCUIEditBoxMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 291A09231C5F06A60068C1D2 /* CCUIEditBoxMac.mm */; };
+ 292DB13D19B4574100A80320 /* UIEditBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB12F19B4574100A80320 /* UIEditBox.cpp */; };
+ 292DB13E19B4574100A80320 /* UIEditBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB12F19B4574100A80320 /* UIEditBox.cpp */; };
+ 292DB13F19B4574100A80320 /* UIEditBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13019B4574100A80320 /* UIEditBox.h */; };
+ 292DB14019B4574100A80320 /* UIEditBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13019B4574100A80320 /* UIEditBox.h */; };
+ 292DB14119B4574100A80320 /* UIEditBoxImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13119B4574100A80320 /* UIEditBoxImpl.h */; };
+ 292DB14219B4574100A80320 /* UIEditBoxImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13119B4574100A80320 /* UIEditBoxImpl.h */; };
+ 292DB14319B4574100A80320 /* UIEditBoxImpl-android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB13219B4574100A80320 /* UIEditBoxImpl-android.cpp */; };
+ 292DB14419B4574100A80320 /* UIEditBoxImpl-android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB13219B4574100A80320 /* UIEditBoxImpl-android.cpp */; };
+ 292DB14519B4574100A80320 /* UIEditBoxImpl-android.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13319B4574100A80320 /* UIEditBoxImpl-android.h */; };
+ 292DB14619B4574100A80320 /* UIEditBoxImpl-android.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13319B4574100A80320 /* UIEditBoxImpl-android.h */; };
+ 292DB14719B4574100A80320 /* UIEditBoxImpl-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13419B4574100A80320 /* UIEditBoxImpl-ios.h */; };
+ 292DB14819B4574100A80320 /* UIEditBoxImpl-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13419B4574100A80320 /* UIEditBoxImpl-ios.h */; };
+ 292DB14919B4574100A80320 /* UIEditBoxImpl-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 292DB13519B4574100A80320 /* UIEditBoxImpl-ios.mm */; };
+ 292DB14A19B4574100A80320 /* UIEditBoxImpl-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 292DB13519B4574100A80320 /* UIEditBoxImpl-ios.mm */; };
+ 292DB14B19B4574100A80320 /* UIEditBoxImpl-mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13619B4574100A80320 /* UIEditBoxImpl-mac.h */; };
+ 292DB14C19B4574100A80320 /* UIEditBoxImpl-mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13619B4574100A80320 /* UIEditBoxImpl-mac.h */; };
+ 292DB14D19B4574100A80320 /* UIEditBoxImpl-mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 292DB13719B4574100A80320 /* UIEditBoxImpl-mac.mm */; };
+ 292DB14E19B4574100A80320 /* UIEditBoxImpl-mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 292DB13719B4574100A80320 /* UIEditBoxImpl-mac.mm */; };
+ 292DB14F19B4574100A80320 /* UIEditBoxImpl-stub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB13819B4574100A80320 /* UIEditBoxImpl-stub.cpp */; };
+ 292DB15019B4574100A80320 /* UIEditBoxImpl-stub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB13819B4574100A80320 /* UIEditBoxImpl-stub.cpp */; };
+ 292DB15F19B461CA00A80320 /* ExtensionDeprecated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB15D19B461CA00A80320 /* ExtensionDeprecated.cpp */; };
+ 292DB16019B461CA00A80320 /* ExtensionDeprecated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB15D19B461CA00A80320 /* ExtensionDeprecated.cpp */; };
+ 292DB16119B461CA00A80320 /* ExtensionDeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB15E19B461CA00A80320 /* ExtensionDeprecated.h */; };
+ 292DB16219B461CA00A80320 /* ExtensionDeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB15E19B461CA00A80320 /* ExtensionDeprecated.h */; };
+ 29394CF019B01DBA00D2DE1A /* UIWebView.h in Headers */ = {isa = PBXBuildFile; fileRef = 29394CEC19B01DBA00D2DE1A /* UIWebView.h */; };
+ 29394CF119B01DBA00D2DE1A /* UIWebView.h in Headers */ = {isa = PBXBuildFile; fileRef = 29394CEC19B01DBA00D2DE1A /* UIWebView.h */; };
+ 29394CF219B01DBA00D2DE1A /* UIWebView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29394CED19B01DBA00D2DE1A /* UIWebView.mm */; };
+ 29394CF319B01DBA00D2DE1A /* UIWebView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29394CED19B01DBA00D2DE1A /* UIWebView.mm */; };
+ 29394CF419B01DBA00D2DE1A /* UIWebViewImpl-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 29394CEE19B01DBA00D2DE1A /* UIWebViewImpl-ios.h */; };
+ 29394CF519B01DBA00D2DE1A /* UIWebViewImpl-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 29394CEE19B01DBA00D2DE1A /* UIWebViewImpl-ios.h */; };
+ 29394CF619B01DBA00D2DE1A /* UIWebViewImpl-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29394CEF19B01DBA00D2DE1A /* UIWebViewImpl-ios.mm */; };
+ 29394CF719B01DBA00D2DE1A /* UIWebViewImpl-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29394CEF19B01DBA00D2DE1A /* UIWebViewImpl-ios.mm */; };
+ 294D7D941D0E67B4002CE7B7 /* CCDevice-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 294D7D921D0E67B4002CE7B7 /* CCDevice-apple.mm */; };
+ 294D7D951D0E67B4002CE7B7 /* CCDevice-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 294D7D921D0E67B4002CE7B7 /* CCDevice-apple.mm */; };
+ 294D7D961D0E67B4002CE7B7 /* CCDevice-apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 294D7D931D0E67B4002CE7B7 /* CCDevice-apple.h */; };
+ 294D7D971D0E67B4002CE7B7 /* CCDevice-apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 294D7D931D0E67B4002CE7B7 /* CCDevice-apple.h */; };
+ 2962D5E81C61CBF9004821A3 /* CCUITextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 2962D5E71C61CBF9004821A3 /* CCUITextInput.h */; };
+ 2962D5EF1C61CF3F004821A3 /* CCUISingleLineTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 2962D5ED1C61CF3F004821A3 /* CCUISingleLineTextField.h */; };
+ 2962D5F01C61CF3F004821A3 /* CCUISingleLineTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 2962D5EE1C61CF3F004821A3 /* CCUISingleLineTextField.m */; };
+ 2962D5F71C61DBBF004821A3 /* CCUIPasswordTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 2962D5F51C61DBBF004821A3 /* CCUIPasswordTextField.h */; };
+ 2962D5F81C61DBBF004821A3 /* CCUIPasswordTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 2962D5F61C61DBBF004821A3 /* CCUIPasswordTextField.m */; };
+ 2962D5FF1C61DF1A004821A3 /* CCUIMultilineTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 2962D5FD1C61DF1A004821A3 /* CCUIMultilineTextField.h */; };
+ 2962D6001C61DF1A004821A3 /* CCUIMultilineTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 2962D5FE1C61DF1A004821A3 /* CCUIMultilineTextField.m */; };
+ 2962D6031C61F02E004821A3 /* CCUITextFieldFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2962D6011C61F02E004821A3 /* CCUITextFieldFormatter.h */; };
+ 2962D6041C61F02E004821A3 /* CCUITextFieldFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2962D6021C61F02E004821A3 /* CCUITextFieldFormatter.m */; };
+ 2980F0221BA9A5550059E678 /* CCUIEditBoxIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 2980F0171BA9A5550059E678 /* CCUIEditBoxIOS.h */; };
+ 2980F0231BA9A5550059E678 /* CCUIEditBoxIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2980F0181BA9A5550059E678 /* CCUIEditBoxIOS.mm */; };
+ 2980F0241BA9A5550059E678 /* CCUIMultilineTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 2980F0191BA9A5550059E678 /* CCUIMultilineTextField.h */; };
+ 2980F0251BA9A5550059E678 /* CCUIMultilineTextField.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2980F01A1BA9A5550059E678 /* CCUIMultilineTextField.mm */; };
+ 2980F0261BA9A5550059E678 /* CCUISingleLineTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 2980F01B1BA9A5550059E678 /* CCUISingleLineTextField.h */; };
+ 2980F0271BA9A5550059E678 /* CCUISingleLineTextField.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2980F01C1BA9A5550059E678 /* CCUISingleLineTextField.mm */; };
+ 2980F0281BA9A5550059E678 /* CCUITextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 2980F01D1BA9A5550059E678 /* CCUITextInput.h */; };
+ 2980F0291BA9A5550059E678 /* UITextField+CCUITextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 2980F01E1BA9A5550059E678 /* UITextField+CCUITextInput.h */; };
+ 2980F02A1BA9A5550059E678 /* UITextField+CCUITextInput.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2980F01F1BA9A5550059E678 /* UITextField+CCUITextInput.mm */; };
+ 2980F02B1BA9A5550059E678 /* UITextView+CCUITextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 2980F0201BA9A5550059E678 /* UITextView+CCUITextInput.h */; };
+ 2980F02C1BA9A5550059E678 /* UITextView+CCUITextInput.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2980F0211BA9A5550059E678 /* UITextView+CCUITextInput.mm */; };
+ 2986667F18B1B246000E39CA /* CCTweenFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2986667818B1B079000E39CA /* CCTweenFunction.cpp */; };
+ 298C75D51C0465D0006BAE63 /* CCStencilStateManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 298C75D31C0465D0006BAE63 /* CCStencilStateManager.cpp */; };
+ 298C75D61C0465D1006BAE63 /* CCStencilStateManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 298C75D31C0465D0006BAE63 /* CCStencilStateManager.cpp */; };
+ 299754F4193EC95400A54AC3 /* ObjectFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 299754F2193EC95400A54AC3 /* ObjectFactory.cpp */; };
+ 299754F5193EC95400A54AC3 /* ObjectFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 299754F2193EC95400A54AC3 /* ObjectFactory.cpp */; };
+ 299754F6193EC95400A54AC3 /* ObjectFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 299754F3193EC95400A54AC3 /* ObjectFactory.h */; };
+ 299754F7193EC95400A54AC3 /* ObjectFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 299754F3193EC95400A54AC3 /* ObjectFactory.h */; };
+ 299CF1FB19A434BC00C378C1 /* ccRandom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 299CF1F919A434BC00C378C1 /* ccRandom.cpp */; };
+ 299CF1FC19A434BC00C378C1 /* ccRandom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 299CF1F919A434BC00C378C1 /* ccRandom.cpp */; };
+ 299CF1FD19A434BC00C378C1 /* ccRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 299CF1FA19A434BC00C378C1 /* ccRandom.h */; };
+ 299CF1FE19A434BC00C378C1 /* ccRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 299CF1FA19A434BC00C378C1 /* ccRandom.h */; };
+ 29DA08F41C63351600F4052B /* UIEditBoxImpl-linux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29DA08F01C63351600F4052B /* UIEditBoxImpl-linux.cpp */; };
+ 29DA08F51C63351600F4052B /* UIEditBoxImpl-linux.h in Headers */ = {isa = PBXBuildFile; fileRef = 29DA08F11C63351600F4052B /* UIEditBoxImpl-linux.h */; };
+ 29DA08F61C63351600F4052B /* UIEditBoxImpl-winrt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29DA08F21C63351600F4052B /* UIEditBoxImpl-winrt.cpp */; };
+ 29DA08F71C63351600F4052B /* UIEditBoxImpl-winrt.h in Headers */ = {isa = PBXBuildFile; fileRef = 29DA08F31C63351600F4052B /* UIEditBoxImpl-winrt.h */; };
+ 382384031A259005002C4610 /* CSParseBinary_generated.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384021A259005002C4610 /* CSParseBinary_generated.h */; };
+ 382384041A259005002C4610 /* CSParseBinary_generated.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384021A259005002C4610 /* CSParseBinary_generated.h */; };
+ 382384071A25900F002C4610 /* FlatBuffersSerialize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384051A25900F002C4610 /* FlatBuffersSerialize.cpp */; };
+ 382384081A25900F002C4610 /* FlatBuffersSerialize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384051A25900F002C4610 /* FlatBuffersSerialize.cpp */; };
+ 382384091A25900F002C4610 /* FlatBuffersSerialize.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384061A25900F002C4610 /* FlatBuffersSerialize.h */; };
+ 3823840A1A25900F002C4610 /* FlatBuffersSerialize.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384061A25900F002C4610 /* FlatBuffersSerialize.h */; };
+ 3823840F1A259092002C4610 /* NodeReaderDefine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823840B1A259092002C4610 /* NodeReaderDefine.cpp */; };
+ 382384101A259092002C4610 /* NodeReaderDefine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823840B1A259092002C4610 /* NodeReaderDefine.cpp */; };
+ 382384111A259092002C4610 /* NodeReaderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 3823840C1A259092002C4610 /* NodeReaderDefine.h */; };
+ 382384121A259092002C4610 /* NodeReaderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 3823840C1A259092002C4610 /* NodeReaderDefine.h */; };
+ 382384131A259092002C4610 /* NodeReaderProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823840D1A259092002C4610 /* NodeReaderProtocol.cpp */; };
+ 382384141A259092002C4610 /* NodeReaderProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823840D1A259092002C4610 /* NodeReaderProtocol.cpp */; };
+ 382384151A259092002C4610 /* NodeReaderProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 3823840E1A259092002C4610 /* NodeReaderProtocol.h */; };
+ 382384161A259092002C4610 /* NodeReaderProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 3823840E1A259092002C4610 /* NodeReaderProtocol.h */; };
+ 3823841A1A2590D2002C4610 /* ComAudioReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384181A2590D2002C4610 /* ComAudioReader.cpp */; };
+ 3823841B1A2590D2002C4610 /* ComAudioReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384181A2590D2002C4610 /* ComAudioReader.cpp */; };
+ 3823841C1A2590D2002C4610 /* ComAudioReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384191A2590D2002C4610 /* ComAudioReader.h */; };
+ 3823841D1A2590D2002C4610 /* ComAudioReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384191A2590D2002C4610 /* ComAudioReader.h */; };
+ 382384211A2590DA002C4610 /* GameMapReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823841F1A2590DA002C4610 /* GameMapReader.cpp */; };
+ 382384221A2590DA002C4610 /* GameMapReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823841F1A2590DA002C4610 /* GameMapReader.cpp */; };
+ 382384231A2590DA002C4610 /* GameMapReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384201A2590DA002C4610 /* GameMapReader.h */; };
+ 382384241A2590DA002C4610 /* GameMapReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384201A2590DA002C4610 /* GameMapReader.h */; };
+ 382384281A2590F9002C4610 /* NodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384261A2590F9002C4610 /* NodeReader.cpp */; };
+ 382384291A2590F9002C4610 /* NodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384261A2590F9002C4610 /* NodeReader.cpp */; };
+ 3823842A1A2590F9002C4610 /* NodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384271A2590F9002C4610 /* NodeReader.h */; };
+ 3823842B1A2590F9002C4610 /* NodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384271A2590F9002C4610 /* NodeReader.h */; };
+ 3823842F1A259112002C4610 /* ParticleReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823842D1A259112002C4610 /* ParticleReader.cpp */; };
+ 382384301A259112002C4610 /* ParticleReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823842D1A259112002C4610 /* ParticleReader.cpp */; };
+ 382384311A259112002C4610 /* ParticleReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3823842E1A259112002C4610 /* ParticleReader.h */; };
+ 382384321A259112002C4610 /* ParticleReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3823842E1A259112002C4610 /* ParticleReader.h */; };
+ 382384361A259126002C4610 /* ProjectNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384341A259126002C4610 /* ProjectNodeReader.cpp */; };
+ 382384371A259126002C4610 /* ProjectNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384341A259126002C4610 /* ProjectNodeReader.cpp */; };
+ 382384381A259126002C4610 /* ProjectNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384351A259126002C4610 /* ProjectNodeReader.h */; };
+ 382384391A259126002C4610 /* ProjectNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384351A259126002C4610 /* ProjectNodeReader.h */; };
+ 3823843D1A259140002C4610 /* SingleNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823843B1A259140002C4610 /* SingleNodeReader.cpp */; };
+ 3823843E1A259140002C4610 /* SingleNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823843B1A259140002C4610 /* SingleNodeReader.cpp */; };
+ 3823843F1A259140002C4610 /* SingleNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3823843C1A259140002C4610 /* SingleNodeReader.h */; };
+ 382384401A259140002C4610 /* SingleNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3823843C1A259140002C4610 /* SingleNodeReader.h */; };
+ 382384441A25915C002C4610 /* SpriteReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384421A25915C002C4610 /* SpriteReader.cpp */; };
+ 382384451A25915C002C4610 /* SpriteReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384421A25915C002C4610 /* SpriteReader.cpp */; };
+ 382384461A25915C002C4610 /* SpriteReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384431A25915C002C4610 /* SpriteReader.h */; };
+ 382384471A25915C002C4610 /* SpriteReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384431A25915C002C4610 /* SpriteReader.h */; };
+ 38ACD1FC1A27111900C3093D /* WidgetCallBackHandlerProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38ACD1FA1A27111900C3093D /* WidgetCallBackHandlerProtocol.cpp */; };
+ 38ACD1FD1A27111900C3093D /* WidgetCallBackHandlerProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38ACD1FA1A27111900C3093D /* WidgetCallBackHandlerProtocol.cpp */; };
+ 38ACD1FE1A27111900C3093D /* WidgetCallBackHandlerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 38ACD1FB1A27111900C3093D /* WidgetCallBackHandlerProtocol.h */; };
+ 38ACD1FF1A27111900C3093D /* WidgetCallBackHandlerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 38ACD1FB1A27111900C3093D /* WidgetCallBackHandlerProtocol.h */; };
+ 38B8E2D519E66581002D7CE7 /* CSLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38B8E2D319E66581002D7CE7 /* CSLoader.cpp */; };
+ 38B8E2D619E66581002D7CE7 /* CSLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38B8E2D319E66581002D7CE7 /* CSLoader.cpp */; };
+ 38B8E2D719E66581002D7CE7 /* CSLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 38B8E2D419E66581002D7CE7 /* CSLoader.h */; };
+ 38B8E2D819E66581002D7CE7 /* CSLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 38B8E2D419E66581002D7CE7 /* CSLoader.h */; };
+ 38B8E2E119E671D2002D7CE7 /* UILayoutComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38B8E2DF19E671D2002D7CE7 /* UILayoutComponent.cpp */; };
+ 38B8E2E219E671D2002D7CE7 /* UILayoutComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38B8E2DF19E671D2002D7CE7 /* UILayoutComponent.cpp */; };
+ 38B8E2E319E671D2002D7CE7 /* UILayoutComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 38B8E2E019E671D2002D7CE7 /* UILayoutComponent.h */; };
+ 38B8E2E419E671D2002D7CE7 /* UILayoutComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 38B8E2E019E671D2002D7CE7 /* UILayoutComponent.h */; };
+ 38D9629D1ACA9721007C6FAF /* CocoStudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38D9629C1ACA9721007C6FAF /* CocoStudio.cpp */; };
+ 38D9629E1ACA9721007C6FAF /* CocoStudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38D9629C1ACA9721007C6FAF /* CocoStudio.cpp */; };
+ 38F5263E1A48363B000DB7F7 /* ArmatureNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38F5263B1A48363B000DB7F7 /* ArmatureNodeReader.cpp */; };
+ 38F5263F1A48363B000DB7F7 /* ArmatureNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38F5263B1A48363B000DB7F7 /* ArmatureNodeReader.cpp */; };
+ 38F526401A48363B000DB7F7 /* ArmatureNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 38F5263C1A48363B000DB7F7 /* ArmatureNodeReader.h */; };
+ 38F526411A48363B000DB7F7 /* ArmatureNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 38F5263C1A48363B000DB7F7 /* ArmatureNodeReader.h */; };
+ 38F526421A48363B000DB7F7 /* CSArmatureNode_generated.h in Headers */ = {isa = PBXBuildFile; fileRef = 38F5263D1A48363B000DB7F7 /* CSArmatureNode_generated.h */; };
+ 38F526431A48363B000DB7F7 /* CSArmatureNode_generated.h in Headers */ = {isa = PBXBuildFile; fileRef = 38F5263D1A48363B000DB7F7 /* CSArmatureNode_generated.h */; };
+ 3E2A09C21BAA91B70086B878 /* CCMotionStreak3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E2A09C01BAA91B70086B878 /* CCMotionStreak3D.cpp */; };
+ 3E2A09C31BAA91B70086B878 /* CCMotionStreak3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E2A09C01BAA91B70086B878 /* CCMotionStreak3D.cpp */; };
+ 3E2A09C41BAA91B70086B878 /* CCMotionStreak3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2A09C11BAA91B70086B878 /* CCMotionStreak3D.h */; };
+ 3E2A09C51BAA91B70086B878 /* CCMotionStreak3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2A09C11BAA91B70086B878 /* CCMotionStreak3D.h */; };
+ 3E2BDADE19C030ED0055CDCD /* AudioEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2BDADD19C030ED0055CDCD /* AudioEngine.h */; };
+ 3E2BDAEC19C0436F0055CDCD /* AudioEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E2BDAEB19C0436F0055CDCD /* AudioEngine.cpp */; };
+ 3E2F27A619CFBFE100E7C490 /* AudioEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E2BDAEB19C0436F0055CDCD /* AudioEngine.cpp */; };
+ 3E2F27A719CFBFE400E7C490 /* AudioEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2BDADD19C030ED0055CDCD /* AudioEngine.h */; };
+ 3E6176681960F89B00DE83F5 /* CCController-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E6176551960F89B00DE83F5 /* CCController-apple.mm */; };
+ 3E6176691960F89B00DE83F5 /* CCController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E6176561960F89B00DE83F5 /* CCController.h */; };
+ 3E6176741960F89B00DE83F5 /* CCEventController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E6176611960F89B00DE83F5 /* CCEventController.cpp */; };
+ 3E6176751960F89B00DE83F5 /* CCEventController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E6176621960F89B00DE83F5 /* CCEventController.h */; };
+ 3E6176761960F89B00DE83F5 /* CCEventListenerController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E6176631960F89B00DE83F5 /* CCEventListenerController.cpp */; };
+ 3E6176771960F89B00DE83F5 /* CCEventListenerController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E6176641960F89B00DE83F5 /* CCEventListenerController.h */; };
+ 3E6176781960F89B00DE83F5 /* CCGameController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E6176651960F89B00DE83F5 /* CCGameController.h */; };
+ 3E61781D1966A5A300DE83F5 /* CCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E61781C1966A5A300DE83F5 /* CCController.cpp */; };
+ 3EACC9A019F5014D00EB3C5E /* CCCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EACC99C19F5014D00EB3C5E /* CCCamera.cpp */; };
+ 3EACC9A119F5014D00EB3C5E /* CCCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EACC99C19F5014D00EB3C5E /* CCCamera.cpp */; };
+ 3EACC9A219F5014D00EB3C5E /* CCCamera.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EACC99D19F5014D00EB3C5E /* CCCamera.h */; };
+ 3EACC9A319F5014D00EB3C5E /* CCCamera.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EACC99D19F5014D00EB3C5E /* CCCamera.h */; };
+ 3EACC9A419F5014D00EB3C5E /* CCLight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EACC99E19F5014D00EB3C5E /* CCLight.cpp */; };
+ 3EACC9A519F5014D00EB3C5E /* CCLight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EACC99E19F5014D00EB3C5E /* CCLight.cpp */; };
+ 3EACC9A619F5014D00EB3C5E /* CCLight.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EACC99F19F5014D00EB3C5E /* CCLight.h */; };
+ 3EACC9A719F5014D00EB3C5E /* CCLight.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EACC99F19F5014D00EB3C5E /* CCLight.h */; };
+ 43015DBF1B60DF4000E75161 /* CCComExtensionData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43015DBD1B60DF4000E75161 /* CCComExtensionData.cpp */; };
+ 43015DC01B60DF4000E75161 /* CCComExtensionData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43015DBD1B60DF4000E75161 /* CCComExtensionData.cpp */; };
+ 43015DC11B60DF4000E75161 /* CCComExtensionData.h in Headers */ = {isa = PBXBuildFile; fileRef = 43015DBE1B60DF4000E75161 /* CCComExtensionData.h */; };
+ 43015DC21B60DF4000E75161 /* CCComExtensionData.h in Headers */ = {isa = PBXBuildFile; fileRef = 43015DBE1B60DF4000E75161 /* CCComExtensionData.h */; };
+ 46270FA41E1CC6A200AAA098 /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 46270FA21E1CC6A100AAA098 /* libcrypto.a */; };
+ 46270FA51E1CC6A200AAA098 /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 46270FA31E1CC6A100AAA098 /* libssl.a */; };
+ 46270FA81E1CC84500AAA098 /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 46270FA61E1CC84500AAA098 /* libcrypto.a */; };
+ 46270FA91E1CC84500AAA098 /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 46270FA71E1CC84500AAA098 /* libssl.a */; };
+ 464AD6E5197EBB1400E502D8 /* pvr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 464AD6E3197EBB1400E502D8 /* pvr.cpp */; };
+ 464AD6E6197EBB1400E502D8 /* pvr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 464AD6E3197EBB1400E502D8 /* pvr.cpp */; };
+ 464AD6E7197EBB1400E502D8 /* pvr.h in Headers */ = {isa = PBXBuildFile; fileRef = 464AD6E4197EBB1400E502D8 /* pvr.h */; };
+ 464AD6E8197EBB1400E502D8 /* pvr.h in Headers */ = {isa = PBXBuildFile; fileRef = 464AD6E4197EBB1400E502D8 /* pvr.h */; };
+ 466F05251EF7659300B80080 /* libBulletCollision.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 466F05201EF7659300B80080 /* libBulletCollision.a */; };
+ 466F05261EF7659300B80080 /* libBulletDynamics.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 466F05211EF7659300B80080 /* libBulletDynamics.a */; };
+ 466F05271EF7659300B80080 /* libBulletMultiThreaded.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 466F05221EF7659300B80080 /* libBulletMultiThreaded.a */; };
+ 466F05281EF7659300B80080 /* libLinearMath.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 466F05231EF7659300B80080 /* libLinearMath.a */; };
+ 466F05291EF7659300B80080 /* libMiniCL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 466F05241EF7659300B80080 /* libMiniCL.a */; };
+ 468A14E01EF223B600ECA675 /* flatbuffers.h in Headers */ = {isa = PBXBuildFile; fileRef = 468A14D61EF223B600ECA675 /* flatbuffers.h */; };
+ 468A14E11EF223B700ECA675 /* flatbuffers.h in Headers */ = {isa = PBXBuildFile; fileRef = 468A14D61EF223B600ECA675 /* flatbuffers.h */; };
+ 468A14E21EF223B700ECA675 /* flatbuffers.h in Headers */ = {isa = PBXBuildFile; fileRef = 468A14D61EF223B600ECA675 /* flatbuffers.h */; };
+ 468A14E31EF223B700ECA675 /* flatc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14D71EF223B600ECA675 /* flatc.cpp */; };
+ 468A14E41EF223B700ECA675 /* flatc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14D71EF223B600ECA675 /* flatc.cpp */; };
+ 468A14E51EF223B700ECA675 /* flatc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14D71EF223B600ECA675 /* flatc.cpp */; };
+ 468A14E61EF223B700ECA675 /* idl_gen_cpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14D81EF223B600ECA675 /* idl_gen_cpp.cpp */; };
+ 468A14E71EF223B700ECA675 /* idl_gen_cpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14D81EF223B600ECA675 /* idl_gen_cpp.cpp */; };
+ 468A14E81EF223B700ECA675 /* idl_gen_cpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14D81EF223B600ECA675 /* idl_gen_cpp.cpp */; };
+ 468A14E91EF223B700ECA675 /* idl_gen_fbs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14D91EF223B600ECA675 /* idl_gen_fbs.cpp */; };
+ 468A14EA1EF223B700ECA675 /* idl_gen_fbs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14D91EF223B600ECA675 /* idl_gen_fbs.cpp */; };
+ 468A14EB1EF223B700ECA675 /* idl_gen_fbs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14D91EF223B600ECA675 /* idl_gen_fbs.cpp */; };
+ 468A14EC1EF223B700ECA675 /* idl_gen_general.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14DA1EF223B600ECA675 /* idl_gen_general.cpp */; };
+ 468A14ED1EF223B700ECA675 /* idl_gen_general.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14DA1EF223B600ECA675 /* idl_gen_general.cpp */; };
+ 468A14EE1EF223B700ECA675 /* idl_gen_general.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14DA1EF223B600ECA675 /* idl_gen_general.cpp */; };
+ 468A14EF1EF223B700ECA675 /* idl_gen_go.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14DB1EF223B600ECA675 /* idl_gen_go.cpp */; };
+ 468A14F01EF223B700ECA675 /* idl_gen_go.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14DB1EF223B600ECA675 /* idl_gen_go.cpp */; };
+ 468A14F11EF223B700ECA675 /* idl_gen_go.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14DB1EF223B600ECA675 /* idl_gen_go.cpp */; };
+ 468A14F21EF223B700ECA675 /* idl_gen_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14DC1EF223B600ECA675 /* idl_gen_text.cpp */; };
+ 468A14F31EF223B700ECA675 /* idl_gen_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14DC1EF223B600ECA675 /* idl_gen_text.cpp */; };
+ 468A14F41EF223B700ECA675 /* idl_gen_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14DC1EF223B600ECA675 /* idl_gen_text.cpp */; };
+ 468A14F51EF223B700ECA675 /* idl_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14DD1EF223B600ECA675 /* idl_parser.cpp */; };
+ 468A14F61EF223B700ECA675 /* idl_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14DD1EF223B600ECA675 /* idl_parser.cpp */; };
+ 468A14F71EF223B700ECA675 /* idl_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468A14DD1EF223B600ECA675 /* idl_parser.cpp */; };
+ 468A14F81EF223B700ECA675 /* idl.h in Headers */ = {isa = PBXBuildFile; fileRef = 468A14DE1EF223B600ECA675 /* idl.h */; };
+ 468A14F91EF223B700ECA675 /* idl.h in Headers */ = {isa = PBXBuildFile; fileRef = 468A14DE1EF223B600ECA675 /* idl.h */; };
+ 468A14FA1EF223B700ECA675 /* idl.h in Headers */ = {isa = PBXBuildFile; fileRef = 468A14DE1EF223B600ECA675 /* idl.h */; };
+ 468A14FB1EF223B700ECA675 /* util.h in Headers */ = {isa = PBXBuildFile; fileRef = 468A14DF1EF223B600ECA675 /* util.h */; };
+ 468A14FC1EF223B700ECA675 /* util.h in Headers */ = {isa = PBXBuildFile; fileRef = 468A14DF1EF223B600ECA675 /* util.h */; };
+ 468A14FD1EF223B700ECA675 /* util.h in Headers */ = {isa = PBXBuildFile; fileRef = 468A14DF1EF223B600ECA675 /* util.h */; };
+ 468A19791EF3BA6500ECA675 /* libBulletCollision.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 468A19741EF3BA6500ECA675 /* libBulletCollision.a */; };
+ 468A197A1EF3BA6500ECA675 /* libBulletDynamics.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 468A19751EF3BA6500ECA675 /* libBulletDynamics.a */; };
+ 468A197B1EF3BA6500ECA675 /* libBulletMultiThreaded.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 468A19761EF3BA6500ECA675 /* libBulletMultiThreaded.a */; };
+ 468A197C1EF3BA6500ECA675 /* libLinearMath.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 468A19771EF3BA6500ECA675 /* libLinearMath.a */; };
+ 468A197D1EF3BA6500ECA675 /* libMiniCL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 468A19781EF3BA6500ECA675 /* libMiniCL.a */; };
+ 46A170E61807CECA005B8026 /* CCPhysicsBody.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1706E1807CE7A005B8026 /* CCPhysicsBody.cpp */; };
+ 46A170E71807CECA005B8026 /* CCPhysicsBody.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1706F1807CE7A005B8026 /* CCPhysicsBody.h */; };
+ 46A170E81807CECA005B8026 /* CCPhysicsContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A170701807CE7A005B8026 /* CCPhysicsContact.cpp */; };
+ 46A170E91807CECA005B8026 /* CCPhysicsContact.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A170711807CE7A005B8026 /* CCPhysicsContact.h */; };
+ 46A170EA1807CECA005B8026 /* CCPhysicsJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A170721807CE7A005B8026 /* CCPhysicsJoint.cpp */; };
+ 46A170EB1807CECA005B8026 /* CCPhysicsJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A170731807CE7A005B8026 /* CCPhysicsJoint.h */; };
+ 46A170ED1807CECA005B8026 /* CCPhysicsShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A170751807CE7A005B8026 /* CCPhysicsShape.cpp */; };
+ 46A170EE1807CECA005B8026 /* CCPhysicsShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A170761807CE7A005B8026 /* CCPhysicsShape.h */; };
+ 46A170EF1807CECA005B8026 /* CCPhysicsWorld.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A170771807CE7A005B8026 /* CCPhysicsWorld.cpp */; };
+ 46A170F01807CECA005B8026 /* CCPhysicsWorld.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A170781807CE7A005B8026 /* CCPhysicsWorld.h */; };
+ 46A170FC1807CECB005B8026 /* CCPhysicsBody.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1706E1807CE7A005B8026 /* CCPhysicsBody.cpp */; };
+ 46A170FD1807CECB005B8026 /* CCPhysicsBody.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1706F1807CE7A005B8026 /* CCPhysicsBody.h */; };
+ 46A170FE1807CECB005B8026 /* CCPhysicsContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A170701807CE7A005B8026 /* CCPhysicsContact.cpp */; };
+ 46A170FF1807CECB005B8026 /* CCPhysicsContact.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A170711807CE7A005B8026 /* CCPhysicsContact.h */; };
+ 46A171011807CECB005B8026 /* CCPhysicsJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A170731807CE7A005B8026 /* CCPhysicsJoint.h */; };
+ 46A171031807CECB005B8026 /* CCPhysicsShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A170751807CE7A005B8026 /* CCPhysicsShape.cpp */; };
+ 46A171041807CECB005B8026 /* CCPhysicsShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A170761807CE7A005B8026 /* CCPhysicsShape.h */; };
+ 46A171051807CECB005B8026 /* CCPhysicsWorld.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A170771807CE7A005B8026 /* CCPhysicsWorld.cpp */; };
+ 46A171061807CECB005B8026 /* CCPhysicsWorld.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A170781807CE7A005B8026 /* CCPhysicsWorld.h */; };
+ 46BDE4A81FA32D3400104C05 /* libbox2d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 46BDE4A71FA32D3400104C05 /* libbox2d.a */; };
+ 46BDE4AA1FA3316A00104C05 /* libbox2d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 46BDE4A91FA3316A00104C05 /* libbox2d.a */; };
+ 46BDE4C21FA86C7F00104C05 /* Array.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4B11FA86C7F00104C05 /* Array.c */; };
+ 46BDE4C31FA86C7F00104C05 /* Array.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B21FA86C7F00104C05 /* Array.h */; };
+ 46BDE4C41FA86C7F00104C05 /* ClippingAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4B31FA86C7F00104C05 /* ClippingAttachment.c */; };
+ 46BDE4C51FA86C7F00104C05 /* ClippingAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B41FA86C7F00104C05 /* ClippingAttachment.h */; };
+ 46BDE4C61FA86C7F00104C05 /* Color.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4B51FA86C7F00104C05 /* Color.c */; };
+ 46BDE4C71FA86C7F00104C05 /* Color.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B61FA86C7F00104C05 /* Color.h */; };
+ 46BDE4C81FA86C7F00104C05 /* dll.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B71FA86C7F00104C05 /* dll.h */; };
+ 46BDE4C91FA86C7F00104C05 /* PointAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4B81FA86C7F00104C05 /* PointAttachment.c */; };
+ 46BDE4CA1FA86C7F00104C05 /* PointAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B91FA86C7F00104C05 /* PointAttachment.h */; };
+ 46BDE4CB1FA86C7F00104C05 /* SkeletonClipping.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4BA1FA86C7F00104C05 /* SkeletonClipping.c */; };
+ 46BDE4CC1FA86C7F00104C05 /* SkeletonClipping.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4BB1FA86C7F00104C05 /* SkeletonClipping.h */; };
+ 46BDE4CD1FA86C7F00104C05 /* SkeletonTwoColorBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4BC1FA86C7F00104C05 /* SkeletonTwoColorBatch.cpp */; };
+ 46BDE4CE1FA86C7F00104C05 /* SkeletonTwoColorBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4BD1FA86C7F00104C05 /* SkeletonTwoColorBatch.h */; };
+ 46BDE4CF1FA86C7F00104C05 /* Triangulator.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4BE1FA86C7F00104C05 /* Triangulator.c */; };
+ 46BDE4D01FA86C7F00104C05 /* Triangulator.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4BF1FA86C7F00104C05 /* Triangulator.h */; };
+ 46BDE4D11FA86C7F00104C05 /* VertexEffect.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4C01FA86C7F00104C05 /* VertexEffect.c */; };
+ 46BDE4D21FA86C7F00104C05 /* VertexEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4C11FA86C7F00104C05 /* VertexEffect.h */; };
+ 46BDE4D31FA87CAC00104C05 /* PointAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4B81FA86C7F00104C05 /* PointAttachment.c */; };
+ 46BDE4D41FA87CB000104C05 /* SkeletonClipping.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4BA1FA86C7F00104C05 /* SkeletonClipping.c */; };
+ 46BDE4D51FA87CB400104C05 /* SkeletonTwoColorBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4BC1FA86C7F00104C05 /* SkeletonTwoColorBatch.cpp */; };
+ 46BDE4D61FA87CB700104C05 /* Triangulator.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4BE1FA86C7F00104C05 /* Triangulator.c */; };
+ 46BDE4D71FA87CBD00104C05 /* VertexEffect.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4C01FA86C7F00104C05 /* VertexEffect.c */; };
+ 46BDE4D81FA87CCC00104C05 /* PointAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4B81FA86C7F00104C05 /* PointAttachment.c */; };
+ 46BDE4D91FA87CCF00104C05 /* SkeletonClipping.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4BA1FA86C7F00104C05 /* SkeletonClipping.c */; };
+ 46BDE4DA1FA87CD200104C05 /* SkeletonTwoColorBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4BC1FA86C7F00104C05 /* SkeletonTwoColorBatch.cpp */; };
+ 46BDE4DB1FA87CD500104C05 /* Triangulator.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4BE1FA86C7F00104C05 /* Triangulator.c */; };
+ 46BDE4DC1FA87CD700104C05 /* VertexEffect.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4C01FA86C7F00104C05 /* VertexEffect.c */; };
+ 46BDE4DD1FA87D4900104C05 /* ClippingAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4B31FA86C7F00104C05 /* ClippingAttachment.c */; };
+ 46BDE4DE1FA87D4900104C05 /* ClippingAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4B31FA86C7F00104C05 /* ClippingAttachment.c */; };
+ 46BDE4DF1FA87D4D00104C05 /* ClippingAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B41FA86C7F00104C05 /* ClippingAttachment.h */; };
+ 46BDE4E01FA87D4D00104C05 /* ClippingAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B41FA86C7F00104C05 /* ClippingAttachment.h */; };
+ 46BDE4E11FA87D5000104C05 /* Array.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4B11FA86C7F00104C05 /* Array.c */; };
+ 46BDE4E21FA87D5000104C05 /* Array.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4B11FA86C7F00104C05 /* Array.c */; };
+ 46BDE4E31FA87D5300104C05 /* Array.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B21FA86C7F00104C05 /* Array.h */; };
+ 46BDE4E41FA87D5300104C05 /* Array.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B21FA86C7F00104C05 /* Array.h */; };
+ 46BDE4E51FA87D5700104C05 /* Color.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4B51FA86C7F00104C05 /* Color.c */; };
+ 46BDE4E61FA87D5800104C05 /* Color.c in Sources */ = {isa = PBXBuildFile; fileRef = 46BDE4B51FA86C7F00104C05 /* Color.c */; };
+ 46BDE4E71FA87D5A00104C05 /* Color.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B61FA86C7F00104C05 /* Color.h */; };
+ 46BDE4E81FA87D5B00104C05 /* Color.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B61FA86C7F00104C05 /* Color.h */; };
+ 46BDE4E91FA87D5D00104C05 /* dll.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B71FA86C7F00104C05 /* dll.h */; };
+ 46BDE4EA1FA87D5D00104C05 /* dll.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B71FA86C7F00104C05 /* dll.h */; };
+ 46BDE4EB1FA87D6100104C05 /* PointAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B91FA86C7F00104C05 /* PointAttachment.h */; };
+ 46BDE4EC1FA87D6200104C05 /* PointAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4B91FA86C7F00104C05 /* PointAttachment.h */; };
+ 46BDE4ED1FA87D6600104C05 /* SkeletonClipping.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4BB1FA86C7F00104C05 /* SkeletonClipping.h */; };
+ 46BDE4EE1FA87D6700104C05 /* SkeletonClipping.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4BB1FA86C7F00104C05 /* SkeletonClipping.h */; };
+ 46BDE4EF1FA87D6B00104C05 /* SkeletonTwoColorBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4BD1FA86C7F00104C05 /* SkeletonTwoColorBatch.h */; };
+ 46BDE4F01FA87D6B00104C05 /* SkeletonTwoColorBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4BD1FA86C7F00104C05 /* SkeletonTwoColorBatch.h */; };
+ 46BDE4F11FA87D6F00104C05 /* Triangulator.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4BF1FA86C7F00104C05 /* Triangulator.h */; };
+ 46BDE4F21FA87D6F00104C05 /* Triangulator.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4BF1FA86C7F00104C05 /* Triangulator.h */; };
+ 46BDE4F31FA87D7400104C05 /* VertexEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4C11FA86C7F00104C05 /* VertexEffect.h */; };
+ 46BDE4F41FA87D7500104C05 /* VertexEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BDE4C11FA86C7F00104C05 /* VertexEffect.h */; };
+ 46C02E0718E91123004B7456 /* xxhash.c in Sources */ = {isa = PBXBuildFile; fileRef = 46C02E0518E91123004B7456 /* xxhash.c */; };
+ 46C02E0818E91123004B7456 /* xxhash.c in Sources */ = {isa = PBXBuildFile; fileRef = 46C02E0518E91123004B7456 /* xxhash.c */; };
+ 46C02E0918E91123004B7456 /* xxhash.h in Headers */ = {isa = PBXBuildFile; fileRef = 46C02E0618E91123004B7456 /* xxhash.h */; };
+ 46C02E0A18E91123004B7456 /* xxhash.h in Headers */ = {isa = PBXBuildFile; fileRef = 46C02E0618E91123004B7456 /* xxhash.h */; };
+ 4D76BE3A1A4AAF0A00102962 /* CCActionTimelineNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D76BE381A4AAF0A00102962 /* CCActionTimelineNode.cpp */; };
+ 4D76BE3B1A4AAF0A00102962 /* CCActionTimelineNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D76BE381A4AAF0A00102962 /* CCActionTimelineNode.cpp */; };
+ 4D76BE3C1A4AAF0A00102962 /* CCActionTimelineNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D76BE391A4AAF0A00102962 /* CCActionTimelineNode.h */; };
+ 4D76BE3D1A4AAF0A00102962 /* CCActionTimelineNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D76BE391A4AAF0A00102962 /* CCActionTimelineNode.h */; };
+ 5012168E1AC47380009A4BEA /* CCRenderState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5012168C1AC47380009A4BEA /* CCRenderState.cpp */; };
+ 5012168F1AC47380009A4BEA /* CCRenderState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5012168C1AC47380009A4BEA /* CCRenderState.cpp */; };
+ 501216901AC47380009A4BEA /* CCRenderState.h in Headers */ = {isa = PBXBuildFile; fileRef = 5012168D1AC47380009A4BEA /* CCRenderState.h */; };
+ 501216911AC47380009A4BEA /* CCRenderState.h in Headers */ = {isa = PBXBuildFile; fileRef = 5012168D1AC47380009A4BEA /* CCRenderState.h */; };
+ 501216941AC47393009A4BEA /* CCPass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 501216921AC47393009A4BEA /* CCPass.cpp */; };
+ 501216951AC47393009A4BEA /* CCPass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 501216921AC47393009A4BEA /* CCPass.cpp */; };
+ 501216961AC47393009A4BEA /* CCPass.h in Headers */ = {isa = PBXBuildFile; fileRef = 501216931AC47393009A4BEA /* CCPass.h */; };
+ 501216971AC47393009A4BEA /* CCPass.h in Headers */ = {isa = PBXBuildFile; fileRef = 501216931AC47393009A4BEA /* CCPass.h */; };
+ 5012169A1AC473A3009A4BEA /* CCTechnique.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 501216981AC473A3009A4BEA /* CCTechnique.cpp */; };
+ 5012169B1AC473A3009A4BEA /* CCTechnique.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 501216981AC473A3009A4BEA /* CCTechnique.cpp */; };
+ 5012169C1AC473A3009A4BEA /* CCTechnique.h in Headers */ = {isa = PBXBuildFile; fileRef = 501216991AC473A3009A4BEA /* CCTechnique.h */; };
+ 5012169D1AC473A3009A4BEA /* CCTechnique.h in Headers */ = {isa = PBXBuildFile; fileRef = 501216991AC473A3009A4BEA /* CCTechnique.h */; };
+ 501216A01AC473AD009A4BEA /* CCMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5012169E1AC473AD009A4BEA /* CCMaterial.cpp */; };
+ 501216A11AC473AD009A4BEA /* CCMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5012169E1AC473AD009A4BEA /* CCMaterial.cpp */; };
+ 501216A21AC473AD009A4BEA /* CCMaterial.h in Headers */ = {isa = PBXBuildFile; fileRef = 5012169F1AC473AD009A4BEA /* CCMaterial.h */; };
+ 501216A31AC473AD009A4BEA /* CCMaterial.h in Headers */ = {isa = PBXBuildFile; fileRef = 5012169F1AC473AD009A4BEA /* CCMaterial.h */; };
+ 5020A1501D49912500E80C72 /* Animation.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1051D49912500E80C72 /* Animation.c */; };
+ 5020A1511D49912500E80C72 /* Animation.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1051D49912500E80C72 /* Animation.c */; };
+ 5020A1521D49912500E80C72 /* Animation.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1051D49912500E80C72 /* Animation.c */; };
+ 5020A1531D49912500E80C72 /* Animation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1061D49912500E80C72 /* Animation.h */; };
+ 5020A1541D49912500E80C72 /* Animation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1061D49912500E80C72 /* Animation.h */; };
+ 5020A1551D49912500E80C72 /* Animation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1061D49912500E80C72 /* Animation.h */; };
+ 5020A1561D49912500E80C72 /* AnimationState.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1071D49912500E80C72 /* AnimationState.c */; };
+ 5020A1571D49912500E80C72 /* AnimationState.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1071D49912500E80C72 /* AnimationState.c */; };
+ 5020A1581D49912500E80C72 /* AnimationState.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1071D49912500E80C72 /* AnimationState.c */; };
+ 5020A1591D49912500E80C72 /* AnimationState.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1081D49912500E80C72 /* AnimationState.h */; };
+ 5020A15A1D49912500E80C72 /* AnimationState.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1081D49912500E80C72 /* AnimationState.h */; };
+ 5020A15B1D49912500E80C72 /* AnimationState.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1081D49912500E80C72 /* AnimationState.h */; };
+ 5020A15C1D49912500E80C72 /* AnimationStateData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1091D49912500E80C72 /* AnimationStateData.c */; };
+ 5020A15D1D49912500E80C72 /* AnimationStateData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1091D49912500E80C72 /* AnimationStateData.c */; };
+ 5020A15E1D49912500E80C72 /* AnimationStateData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1091D49912500E80C72 /* AnimationStateData.c */; };
+ 5020A15F1D49912500E80C72 /* AnimationStateData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A10A1D49912500E80C72 /* AnimationStateData.h */; };
+ 5020A1601D49912500E80C72 /* AnimationStateData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A10A1D49912500E80C72 /* AnimationStateData.h */; };
+ 5020A1611D49912500E80C72 /* AnimationStateData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A10A1D49912500E80C72 /* AnimationStateData.h */; };
+ 5020A1621D49912500E80C72 /* Atlas.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A10B1D49912500E80C72 /* Atlas.c */; };
+ 5020A1631D49912500E80C72 /* Atlas.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A10B1D49912500E80C72 /* Atlas.c */; };
+ 5020A1641D49912500E80C72 /* Atlas.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A10B1D49912500E80C72 /* Atlas.c */; };
+ 5020A1651D49912500E80C72 /* Atlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A10C1D49912500E80C72 /* Atlas.h */; };
+ 5020A1661D49912500E80C72 /* Atlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A10C1D49912500E80C72 /* Atlas.h */; };
+ 5020A1671D49912500E80C72 /* Atlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A10C1D49912500E80C72 /* Atlas.h */; };
+ 5020A1681D49912500E80C72 /* AtlasAttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A10D1D49912500E80C72 /* AtlasAttachmentLoader.c */; };
+ 5020A1691D49912500E80C72 /* AtlasAttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A10D1D49912500E80C72 /* AtlasAttachmentLoader.c */; };
+ 5020A16A1D49912500E80C72 /* AtlasAttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A10D1D49912500E80C72 /* AtlasAttachmentLoader.c */; };
+ 5020A16B1D49912500E80C72 /* AtlasAttachmentLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A10E1D49912500E80C72 /* AtlasAttachmentLoader.h */; };
+ 5020A16C1D49912500E80C72 /* AtlasAttachmentLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A10E1D49912500E80C72 /* AtlasAttachmentLoader.h */; };
+ 5020A16D1D49912500E80C72 /* AtlasAttachmentLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A10E1D49912500E80C72 /* AtlasAttachmentLoader.h */; };
+ 5020A16E1D49912500E80C72 /* Attachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A10F1D49912500E80C72 /* Attachment.c */; };
+ 5020A16F1D49912500E80C72 /* Attachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A10F1D49912500E80C72 /* Attachment.c */; };
+ 5020A1701D49912500E80C72 /* Attachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A10F1D49912500E80C72 /* Attachment.c */; };
+ 5020A1711D49912500E80C72 /* Attachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1101D49912500E80C72 /* Attachment.h */; };
+ 5020A1721D49912500E80C72 /* Attachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1101D49912500E80C72 /* Attachment.h */; };
+ 5020A1731D49912500E80C72 /* Attachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1101D49912500E80C72 /* Attachment.h */; };
+ 5020A1741D49912500E80C72 /* AttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1111D49912500E80C72 /* AttachmentLoader.c */; };
+ 5020A1751D49912500E80C72 /* AttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1111D49912500E80C72 /* AttachmentLoader.c */; };
+ 5020A1761D49912500E80C72 /* AttachmentLoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1111D49912500E80C72 /* AttachmentLoader.c */; };
+ 5020A1771D49912500E80C72 /* AttachmentLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1121D49912500E80C72 /* AttachmentLoader.h */; };
+ 5020A1781D49912500E80C72 /* AttachmentLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1121D49912500E80C72 /* AttachmentLoader.h */; };
+ 5020A1791D49912500E80C72 /* AttachmentLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1121D49912500E80C72 /* AttachmentLoader.h */; };
+ 5020A17A1D49912500E80C72 /* AttachmentVertices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1131D49912500E80C72 /* AttachmentVertices.cpp */; };
+ 5020A17B1D49912500E80C72 /* AttachmentVertices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1131D49912500E80C72 /* AttachmentVertices.cpp */; };
+ 5020A17C1D49912500E80C72 /* AttachmentVertices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1131D49912500E80C72 /* AttachmentVertices.cpp */; };
+ 5020A17D1D49912500E80C72 /* AttachmentVertices.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1141D49912500E80C72 /* AttachmentVertices.h */; };
+ 5020A17E1D49912500E80C72 /* AttachmentVertices.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1141D49912500E80C72 /* AttachmentVertices.h */; };
+ 5020A17F1D49912500E80C72 /* AttachmentVertices.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1141D49912500E80C72 /* AttachmentVertices.h */; };
+ 5020A1801D49912500E80C72 /* Bone.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1151D49912500E80C72 /* Bone.c */; };
+ 5020A1811D49912500E80C72 /* Bone.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1151D49912500E80C72 /* Bone.c */; };
+ 5020A1821D49912500E80C72 /* Bone.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1151D49912500E80C72 /* Bone.c */; };
+ 5020A1831D49912500E80C72 /* Bone.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1161D49912500E80C72 /* Bone.h */; };
+ 5020A1841D49912500E80C72 /* Bone.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1161D49912500E80C72 /* Bone.h */; };
+ 5020A1851D49912500E80C72 /* Bone.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1161D49912500E80C72 /* Bone.h */; };
+ 5020A1861D49912500E80C72 /* BoneData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1171D49912500E80C72 /* BoneData.c */; };
+ 5020A1871D49912500E80C72 /* BoneData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1171D49912500E80C72 /* BoneData.c */; };
+ 5020A1881D49912500E80C72 /* BoneData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1171D49912500E80C72 /* BoneData.c */; };
+ 5020A1891D49912500E80C72 /* BoneData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1181D49912500E80C72 /* BoneData.h */; };
+ 5020A18A1D49912500E80C72 /* BoneData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1181D49912500E80C72 /* BoneData.h */; };
+ 5020A18B1D49912500E80C72 /* BoneData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1181D49912500E80C72 /* BoneData.h */; };
+ 5020A18C1D49912500E80C72 /* BoundingBoxAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1191D49912500E80C72 /* BoundingBoxAttachment.c */; };
+ 5020A18D1D49912500E80C72 /* BoundingBoxAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1191D49912500E80C72 /* BoundingBoxAttachment.c */; };
+ 5020A18E1D49912500E80C72 /* BoundingBoxAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1191D49912500E80C72 /* BoundingBoxAttachment.c */; };
+ 5020A18F1D49912500E80C72 /* BoundingBoxAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A11A1D49912500E80C72 /* BoundingBoxAttachment.h */; };
+ 5020A1901D49912500E80C72 /* BoundingBoxAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A11A1D49912500E80C72 /* BoundingBoxAttachment.h */; };
+ 5020A1911D49912500E80C72 /* BoundingBoxAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A11A1D49912500E80C72 /* BoundingBoxAttachment.h */; };
+ 5020A1921D49912500E80C72 /* Cocos2dAttachmentLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A11B1D49912500E80C72 /* Cocos2dAttachmentLoader.cpp */; };
+ 5020A1931D49912500E80C72 /* Cocos2dAttachmentLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A11B1D49912500E80C72 /* Cocos2dAttachmentLoader.cpp */; };
+ 5020A1941D49912500E80C72 /* Cocos2dAttachmentLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A11B1D49912500E80C72 /* Cocos2dAttachmentLoader.cpp */; };
+ 5020A1951D49912500E80C72 /* Cocos2dAttachmentLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A11C1D49912500E80C72 /* Cocos2dAttachmentLoader.h */; };
+ 5020A1961D49912500E80C72 /* Cocos2dAttachmentLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A11C1D49912500E80C72 /* Cocos2dAttachmentLoader.h */; };
+ 5020A1971D49912500E80C72 /* Cocos2dAttachmentLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A11C1D49912500E80C72 /* Cocos2dAttachmentLoader.h */; };
+ 5020A1981D49912500E80C72 /* Event.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A11D1D49912500E80C72 /* Event.c */; };
+ 5020A1991D49912500E80C72 /* Event.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A11D1D49912500E80C72 /* Event.c */; };
+ 5020A19A1D49912500E80C72 /* Event.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A11D1D49912500E80C72 /* Event.c */; };
+ 5020A19B1D49912500E80C72 /* Event.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A11E1D49912500E80C72 /* Event.h */; };
+ 5020A19C1D49912500E80C72 /* Event.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A11E1D49912500E80C72 /* Event.h */; };
+ 5020A19D1D49912500E80C72 /* Event.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A11E1D49912500E80C72 /* Event.h */; };
+ 5020A19E1D49912500E80C72 /* EventData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A11F1D49912500E80C72 /* EventData.c */; };
+ 5020A19F1D49912500E80C72 /* EventData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A11F1D49912500E80C72 /* EventData.c */; };
+ 5020A1A01D49912500E80C72 /* EventData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A11F1D49912500E80C72 /* EventData.c */; };
+ 5020A1A11D49912500E80C72 /* EventData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1201D49912500E80C72 /* EventData.h */; };
+ 5020A1A21D49912500E80C72 /* EventData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1201D49912500E80C72 /* EventData.h */; };
+ 5020A1A31D49912500E80C72 /* EventData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1201D49912500E80C72 /* EventData.h */; };
+ 5020A1A41D49912500E80C72 /* extension.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1211D49912500E80C72 /* extension.c */; };
+ 5020A1A51D49912500E80C72 /* extension.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1211D49912500E80C72 /* extension.c */; };
+ 5020A1A61D49912500E80C72 /* extension.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1211D49912500E80C72 /* extension.c */; };
+ 5020A1A71D49912500E80C72 /* extension.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1221D49912500E80C72 /* extension.h */; };
+ 5020A1A81D49912500E80C72 /* extension.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1221D49912500E80C72 /* extension.h */; };
+ 5020A1A91D49912500E80C72 /* extension.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1221D49912500E80C72 /* extension.h */; };
+ 5020A1AA1D49912500E80C72 /* IkConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1231D49912500E80C72 /* IkConstraint.c */; };
+ 5020A1AB1D49912500E80C72 /* IkConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1231D49912500E80C72 /* IkConstraint.c */; };
+ 5020A1AC1D49912500E80C72 /* IkConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1231D49912500E80C72 /* IkConstraint.c */; };
+ 5020A1AD1D49912500E80C72 /* IkConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1241D49912500E80C72 /* IkConstraint.h */; };
+ 5020A1AE1D49912500E80C72 /* IkConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1241D49912500E80C72 /* IkConstraint.h */; };
+ 5020A1AF1D49912500E80C72 /* IkConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1241D49912500E80C72 /* IkConstraint.h */; };
+ 5020A1B01D49912500E80C72 /* IkConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1251D49912500E80C72 /* IkConstraintData.c */; };
+ 5020A1B11D49912500E80C72 /* IkConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1251D49912500E80C72 /* IkConstraintData.c */; };
+ 5020A1B21D49912500E80C72 /* IkConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1251D49912500E80C72 /* IkConstraintData.c */; };
+ 5020A1B31D49912500E80C72 /* IkConstraintData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1261D49912500E80C72 /* IkConstraintData.h */; };
+ 5020A1B41D49912500E80C72 /* IkConstraintData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1261D49912500E80C72 /* IkConstraintData.h */; };
+ 5020A1B51D49912500E80C72 /* IkConstraintData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1261D49912500E80C72 /* IkConstraintData.h */; };
+ 5020A1B61D49912500E80C72 /* Json.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1271D49912500E80C72 /* Json.c */; };
+ 5020A1B71D49912500E80C72 /* Json.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1271D49912500E80C72 /* Json.c */; };
+ 5020A1B81D49912500E80C72 /* Json.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1271D49912500E80C72 /* Json.c */; };
+ 5020A1B91D49912500E80C72 /* Json.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1281D49912500E80C72 /* Json.h */; };
+ 5020A1BA1D49912500E80C72 /* Json.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1281D49912500E80C72 /* Json.h */; };
+ 5020A1BB1D49912500E80C72 /* Json.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1281D49912500E80C72 /* Json.h */; };
+ 5020A1BC1D49912500E80C72 /* MeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1291D49912500E80C72 /* MeshAttachment.c */; };
+ 5020A1BD1D49912500E80C72 /* MeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1291D49912500E80C72 /* MeshAttachment.c */; };
+ 5020A1BE1D49912500E80C72 /* MeshAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1291D49912500E80C72 /* MeshAttachment.c */; };
+ 5020A1BF1D49912500E80C72 /* MeshAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A12A1D49912500E80C72 /* MeshAttachment.h */; };
+ 5020A1C01D49912500E80C72 /* MeshAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A12A1D49912500E80C72 /* MeshAttachment.h */; };
+ 5020A1C11D49912500E80C72 /* MeshAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A12A1D49912500E80C72 /* MeshAttachment.h */; };
+ 5020A1C21D49912500E80C72 /* PathAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A12B1D49912500E80C72 /* PathAttachment.c */; };
+ 5020A1C31D49912500E80C72 /* PathAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A12B1D49912500E80C72 /* PathAttachment.c */; };
+ 5020A1C41D49912500E80C72 /* PathAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A12B1D49912500E80C72 /* PathAttachment.c */; };
+ 5020A1C51D49912500E80C72 /* PathAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A12C1D49912500E80C72 /* PathAttachment.h */; };
+ 5020A1C61D49912500E80C72 /* PathAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A12C1D49912500E80C72 /* PathAttachment.h */; };
+ 5020A1C71D49912500E80C72 /* PathAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A12C1D49912500E80C72 /* PathAttachment.h */; };
+ 5020A1C81D49912500E80C72 /* PathConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A12D1D49912500E80C72 /* PathConstraint.c */; };
+ 5020A1C91D49912500E80C72 /* PathConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A12D1D49912500E80C72 /* PathConstraint.c */; };
+ 5020A1CA1D49912500E80C72 /* PathConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A12D1D49912500E80C72 /* PathConstraint.c */; };
+ 5020A1CB1D49912500E80C72 /* PathConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A12E1D49912500E80C72 /* PathConstraint.h */; };
+ 5020A1CC1D49912500E80C72 /* PathConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A12E1D49912500E80C72 /* PathConstraint.h */; };
+ 5020A1CD1D49912500E80C72 /* PathConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A12E1D49912500E80C72 /* PathConstraint.h */; };
+ 5020A1CE1D49912500E80C72 /* PathConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A12F1D49912500E80C72 /* PathConstraintData.c */; };
+ 5020A1CF1D49912500E80C72 /* PathConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A12F1D49912500E80C72 /* PathConstraintData.c */; };
+ 5020A1D01D49912500E80C72 /* PathConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A12F1D49912500E80C72 /* PathConstraintData.c */; };
+ 5020A1D11D49912500E80C72 /* PathConstraintData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1301D49912500E80C72 /* PathConstraintData.h */; };
+ 5020A1D21D49912500E80C72 /* PathConstraintData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1301D49912500E80C72 /* PathConstraintData.h */; };
+ 5020A1D31D49912500E80C72 /* PathConstraintData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1301D49912500E80C72 /* PathConstraintData.h */; };
+ 5020A1D41D49912500E80C72 /* RegionAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1311D49912500E80C72 /* RegionAttachment.c */; };
+ 5020A1D51D49912500E80C72 /* RegionAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1311D49912500E80C72 /* RegionAttachment.c */; };
+ 5020A1D61D49912500E80C72 /* RegionAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1311D49912500E80C72 /* RegionAttachment.c */; };
+ 5020A1D71D49912500E80C72 /* RegionAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1321D49912500E80C72 /* RegionAttachment.h */; };
+ 5020A1D81D49912500E80C72 /* RegionAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1321D49912500E80C72 /* RegionAttachment.h */; };
+ 5020A1D91D49912500E80C72 /* RegionAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1321D49912500E80C72 /* RegionAttachment.h */; };
+ 5020A1DA1D49912500E80C72 /* Skeleton.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1331D49912500E80C72 /* Skeleton.c */; };
+ 5020A1DB1D49912500E80C72 /* Skeleton.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1331D49912500E80C72 /* Skeleton.c */; };
+ 5020A1DC1D49912500E80C72 /* Skeleton.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1331D49912500E80C72 /* Skeleton.c */; };
+ 5020A1DD1D49912500E80C72 /* Skeleton.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1341D49912500E80C72 /* Skeleton.h */; };
+ 5020A1DE1D49912500E80C72 /* Skeleton.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1341D49912500E80C72 /* Skeleton.h */; };
+ 5020A1DF1D49912500E80C72 /* Skeleton.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1341D49912500E80C72 /* Skeleton.h */; };
+ 5020A1E01D49912500E80C72 /* SkeletonAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1351D49912500E80C72 /* SkeletonAnimation.cpp */; };
+ 5020A1E11D49912500E80C72 /* SkeletonAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1351D49912500E80C72 /* SkeletonAnimation.cpp */; };
+ 5020A1E21D49912500E80C72 /* SkeletonAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1351D49912500E80C72 /* SkeletonAnimation.cpp */; };
+ 5020A1E31D49912500E80C72 /* SkeletonAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1361D49912500E80C72 /* SkeletonAnimation.h */; };
+ 5020A1E41D49912500E80C72 /* SkeletonAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1361D49912500E80C72 /* SkeletonAnimation.h */; };
+ 5020A1E51D49912500E80C72 /* SkeletonAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1361D49912500E80C72 /* SkeletonAnimation.h */; };
+ 5020A1E61D49912500E80C72 /* SkeletonBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1371D49912500E80C72 /* SkeletonBatch.cpp */; };
+ 5020A1E71D49912500E80C72 /* SkeletonBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1371D49912500E80C72 /* SkeletonBatch.cpp */; };
+ 5020A1E81D49912500E80C72 /* SkeletonBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1371D49912500E80C72 /* SkeletonBatch.cpp */; };
+ 5020A1E91D49912500E80C72 /* SkeletonBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1381D49912500E80C72 /* SkeletonBatch.h */; };
+ 5020A1EA1D49912500E80C72 /* SkeletonBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1381D49912500E80C72 /* SkeletonBatch.h */; };
+ 5020A1EB1D49912500E80C72 /* SkeletonBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1381D49912500E80C72 /* SkeletonBatch.h */; };
+ 5020A1EC1D49912500E80C72 /* SkeletonBounds.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1391D49912500E80C72 /* SkeletonBounds.c */; };
+ 5020A1ED1D49912500E80C72 /* SkeletonBounds.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1391D49912500E80C72 /* SkeletonBounds.c */; };
+ 5020A1EE1D49912500E80C72 /* SkeletonBounds.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1391D49912500E80C72 /* SkeletonBounds.c */; };
+ 5020A1EF1D49912500E80C72 /* SkeletonBounds.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A13A1D49912500E80C72 /* SkeletonBounds.h */; };
+ 5020A1F01D49912500E80C72 /* SkeletonBounds.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A13A1D49912500E80C72 /* SkeletonBounds.h */; };
+ 5020A1F11D49912500E80C72 /* SkeletonBounds.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A13A1D49912500E80C72 /* SkeletonBounds.h */; };
+ 5020A1F21D49912500E80C72 /* SkeletonData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A13B1D49912500E80C72 /* SkeletonData.c */; };
+ 5020A1F31D49912500E80C72 /* SkeletonData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A13B1D49912500E80C72 /* SkeletonData.c */; };
+ 5020A1F41D49912500E80C72 /* SkeletonData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A13B1D49912500E80C72 /* SkeletonData.c */; };
+ 5020A1F51D49912500E80C72 /* SkeletonData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A13C1D49912500E80C72 /* SkeletonData.h */; };
+ 5020A1F61D49912500E80C72 /* SkeletonData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A13C1D49912500E80C72 /* SkeletonData.h */; };
+ 5020A1F71D49912500E80C72 /* SkeletonData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A13C1D49912500E80C72 /* SkeletonData.h */; };
+ 5020A1F81D49912500E80C72 /* SkeletonJson.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A13D1D49912500E80C72 /* SkeletonJson.c */; };
+ 5020A1F91D49912500E80C72 /* SkeletonJson.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A13D1D49912500E80C72 /* SkeletonJson.c */; };
+ 5020A1FA1D49912500E80C72 /* SkeletonJson.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A13D1D49912500E80C72 /* SkeletonJson.c */; };
+ 5020A1FB1D49912500E80C72 /* SkeletonJson.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A13E1D49912500E80C72 /* SkeletonJson.h */; };
+ 5020A1FC1D49912500E80C72 /* SkeletonJson.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A13E1D49912500E80C72 /* SkeletonJson.h */; };
+ 5020A1FD1D49912500E80C72 /* SkeletonJson.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A13E1D49912500E80C72 /* SkeletonJson.h */; };
+ 5020A1FE1D49912500E80C72 /* SkeletonRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A13F1D49912500E80C72 /* SkeletonRenderer.cpp */; };
+ 5020A1FF1D49912500E80C72 /* SkeletonRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A13F1D49912500E80C72 /* SkeletonRenderer.cpp */; };
+ 5020A2001D49912500E80C72 /* SkeletonRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A13F1D49912500E80C72 /* SkeletonRenderer.cpp */; };
+ 5020A2011D49912500E80C72 /* SkeletonRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1401D49912500E80C72 /* SkeletonRenderer.h */; };
+ 5020A2021D49912500E80C72 /* SkeletonRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1401D49912500E80C72 /* SkeletonRenderer.h */; };
+ 5020A2031D49912500E80C72 /* SkeletonRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1401D49912500E80C72 /* SkeletonRenderer.h */; };
+ 5020A2041D49912500E80C72 /* Skin.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1411D49912500E80C72 /* Skin.c */; };
+ 5020A2051D49912500E80C72 /* Skin.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1411D49912500E80C72 /* Skin.c */; };
+ 5020A2061D49912500E80C72 /* Skin.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1411D49912500E80C72 /* Skin.c */; };
+ 5020A2071D49912500E80C72 /* Skin.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1421D49912500E80C72 /* Skin.h */; };
+ 5020A2081D49912500E80C72 /* Skin.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1421D49912500E80C72 /* Skin.h */; };
+ 5020A2091D49912500E80C72 /* Skin.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1421D49912500E80C72 /* Skin.h */; };
+ 5020A20A1D49912500E80C72 /* Slot.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1431D49912500E80C72 /* Slot.c */; };
+ 5020A20B1D49912500E80C72 /* Slot.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1431D49912500E80C72 /* Slot.c */; };
+ 5020A20C1D49912500E80C72 /* Slot.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1431D49912500E80C72 /* Slot.c */; };
+ 5020A20D1D49912500E80C72 /* Slot.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1441D49912500E80C72 /* Slot.h */; };
+ 5020A20E1D49912500E80C72 /* Slot.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1441D49912500E80C72 /* Slot.h */; };
+ 5020A20F1D49912500E80C72 /* Slot.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1441D49912500E80C72 /* Slot.h */; };
+ 5020A2101D49912500E80C72 /* SlotData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1451D49912500E80C72 /* SlotData.c */; };
+ 5020A2111D49912500E80C72 /* SlotData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1451D49912500E80C72 /* SlotData.c */; };
+ 5020A2121D49912500E80C72 /* SlotData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1451D49912500E80C72 /* SlotData.c */; };
+ 5020A2131D49912500E80C72 /* SlotData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1461D49912500E80C72 /* SlotData.h */; };
+ 5020A2141D49912500E80C72 /* SlotData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1461D49912500E80C72 /* SlotData.h */; };
+ 5020A2151D49912500E80C72 /* SlotData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1461D49912500E80C72 /* SlotData.h */; };
+ 5020A2161D49912500E80C72 /* spine-cocos2dx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1471D49912500E80C72 /* spine-cocos2dx.cpp */; };
+ 5020A2171D49912500E80C72 /* spine-cocos2dx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1471D49912500E80C72 /* spine-cocos2dx.cpp */; };
+ 5020A2181D49912500E80C72 /* spine-cocos2dx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5020A1471D49912500E80C72 /* spine-cocos2dx.cpp */; };
+ 5020A2191D49912500E80C72 /* spine-cocos2dx.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1481D49912500E80C72 /* spine-cocos2dx.h */; };
+ 5020A21A1D49912500E80C72 /* spine-cocos2dx.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1481D49912500E80C72 /* spine-cocos2dx.h */; };
+ 5020A21B1D49912500E80C72 /* spine-cocos2dx.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1481D49912500E80C72 /* spine-cocos2dx.h */; };
+ 5020A21C1D49912500E80C72 /* spine.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1491D49912500E80C72 /* spine.h */; };
+ 5020A21D1D49912500E80C72 /* spine.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1491D49912500E80C72 /* spine.h */; };
+ 5020A21E1D49912500E80C72 /* spine.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A1491D49912500E80C72 /* spine.h */; };
+ 5020A21F1D49912500E80C72 /* TransformConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A14A1D49912500E80C72 /* TransformConstraint.c */; };
+ 5020A2201D49912500E80C72 /* TransformConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A14A1D49912500E80C72 /* TransformConstraint.c */; };
+ 5020A2211D49912500E80C72 /* TransformConstraint.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A14A1D49912500E80C72 /* TransformConstraint.c */; };
+ 5020A2221D49912500E80C72 /* TransformConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A14B1D49912500E80C72 /* TransformConstraint.h */; };
+ 5020A2231D49912500E80C72 /* TransformConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A14B1D49912500E80C72 /* TransformConstraint.h */; };
+ 5020A2241D49912500E80C72 /* TransformConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A14B1D49912500E80C72 /* TransformConstraint.h */; };
+ 5020A2251D49912500E80C72 /* TransformConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A14C1D49912500E80C72 /* TransformConstraintData.c */; };
+ 5020A2261D49912500E80C72 /* TransformConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A14C1D49912500E80C72 /* TransformConstraintData.c */; };
+ 5020A2271D49912500E80C72 /* TransformConstraintData.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A14C1D49912500E80C72 /* TransformConstraintData.c */; };
+ 5020A2281D49912500E80C72 /* TransformConstraintData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A14D1D49912500E80C72 /* TransformConstraintData.h */; };
+ 5020A2291D49912500E80C72 /* TransformConstraintData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A14D1D49912500E80C72 /* TransformConstraintData.h */; };
+ 5020A22A1D49912500E80C72 /* TransformConstraintData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A14D1D49912500E80C72 /* TransformConstraintData.h */; };
+ 5020A22B1D49912500E80C72 /* VertexAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A14E1D49912500E80C72 /* VertexAttachment.c */; };
+ 5020A22C1D49912500E80C72 /* VertexAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A14E1D49912500E80C72 /* VertexAttachment.c */; };
+ 5020A22D1D49912500E80C72 /* VertexAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 5020A14E1D49912500E80C72 /* VertexAttachment.c */; };
+ 5020A22E1D49912500E80C72 /* VertexAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A14F1D49912500E80C72 /* VertexAttachment.h */; };
+ 5020A22F1D49912500E80C72 /* VertexAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A14F1D49912500E80C72 /* VertexAttachment.h */; };
+ 5020A2301D49912500E80C72 /* VertexAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A14F1D49912500E80C72 /* VertexAttachment.h */; };
+ 5027253A190BF1B900AAF4ED /* cocos2d.h in Headers */ = {isa = PBXBuildFile; fileRef = 50272538190BF1B900AAF4ED /* cocos2d.h */; };
+ 5027253B190BF1B900AAF4ED /* cocos2d.h in Headers */ = {isa = PBXBuildFile; fileRef = 50272538190BF1B900AAF4ED /* cocos2d.h */; };
+ 5027253C190BF1B900AAF4ED /* cocos2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50272539190BF1B900AAF4ED /* cocos2d.cpp */; };
+ 5027253D190BF1B900AAF4ED /* cocos2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50272539190BF1B900AAF4ED /* cocos2d.cpp */; };
+ 502AF9781D0711B8006AF256 /* CCVRGenericHeadTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 502AF9771D0711B8006AF256 /* CCVRGenericHeadTracker.cpp */; };
+ 502AF9791D0711C9006AF256 /* CCVRGenericHeadTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 502AF9771D0711B8006AF256 /* CCVRGenericHeadTracker.cpp */; };
+ 502AF97A1D0711CA006AF256 /* CCVRGenericHeadTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 502AF9771D0711B8006AF256 /* CCVRGenericHeadTracker.cpp */; };
+ 5030C0421CE6DF8B00C5D3E7 /* CCVRGenericHeadTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 5030C03E1CE6DF8B00C5D3E7 /* CCVRGenericHeadTracker.h */; };
+ 5030C0431CE6DF8B00C5D3E7 /* CCVRGenericHeadTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 5030C03E1CE6DF8B00C5D3E7 /* CCVRGenericHeadTracker.h */; };
+ 5030C0441CE6DF8B00C5D3E7 /* CCVRGenericHeadTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 5030C03E1CE6DF8B00C5D3E7 /* CCVRGenericHeadTracker.h */; };
+ 503341991D9DC7B400770EC7 /* kvec.h in Headers */ = {isa = PBXBuildFile; fileRef = 503341961D9DC7B400770EC7 /* kvec.h */; };
+ 5033419A1D9DC7B400770EC7 /* kvec.h in Headers */ = {isa = PBXBuildFile; fileRef = 503341961D9DC7B400770EC7 /* kvec.h */; };
+ 5033419B1D9DC7B400770EC7 /* kvec.h in Headers */ = {isa = PBXBuildFile; fileRef = 503341961D9DC7B400770EC7 /* kvec.h */; };
+ 5033419C1D9DC7B400770EC7 /* SkeletonBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = 503341971D9DC7B400770EC7 /* SkeletonBinary.c */; };
+ 5033419D1D9DC7B400770EC7 /* SkeletonBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = 503341971D9DC7B400770EC7 /* SkeletonBinary.c */; };
+ 5033419E1D9DC7B400770EC7 /* SkeletonBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = 503341971D9DC7B400770EC7 /* SkeletonBinary.c */; };
+ 5033419F1D9DC7B400770EC7 /* SkeletonBinary.h in Headers */ = {isa = PBXBuildFile; fileRef = 503341981D9DC7B400770EC7 /* SkeletonBinary.h */; };
+ 503341A01D9DC7B400770EC7 /* SkeletonBinary.h in Headers */ = {isa = PBXBuildFile; fileRef = 503341981D9DC7B400770EC7 /* SkeletonBinary.h */; };
+ 503341A11D9DC7B400770EC7 /* SkeletonBinary.h in Headers */ = {isa = PBXBuildFile; fileRef = 503341981D9DC7B400770EC7 /* SkeletonBinary.h */; };
+ 5034CA21191D591100CE6051 /* ccShader_PositionTextureColorAlphaTest.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034C9FB191D591000CE6051 /* ccShader_PositionTextureColorAlphaTest.frag */; };
+ 5034CA22191D591100CE6051 /* ccShader_PositionTextureColorAlphaTest.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034C9FB191D591000CE6051 /* ccShader_PositionTextureColorAlphaTest.frag */; };
+ 5034CA2B191D591100CE6051 /* ccShader_PositionTextureA8Color.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA00191D591000CE6051 /* ccShader_PositionTextureA8Color.vert */; };
+ 5034CA2C191D591100CE6051 /* ccShader_PositionTextureA8Color.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA00191D591000CE6051 /* ccShader_PositionTextureA8Color.vert */; };
+ 5034CA2D191D591100CE6051 /* ccShader_PositionTextureA8Color.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA01191D591000CE6051 /* ccShader_PositionTextureA8Color.frag */; };
+ 5034CA2E191D591100CE6051 /* ccShader_PositionTextureA8Color.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA01191D591000CE6051 /* ccShader_PositionTextureA8Color.frag */; };
+ 5034CA2F191D591100CE6051 /* ccShader_PositionTexture.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA02191D591000CE6051 /* ccShader_PositionTexture.vert */; };
+ 5034CA30191D591100CE6051 /* ccShader_PositionTexture.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA02191D591000CE6051 /* ccShader_PositionTexture.vert */; };
+ 5034CA31191D591100CE6051 /* ccShader_PositionTexture_uColor.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA03191D591000CE6051 /* ccShader_PositionTexture_uColor.vert */; };
+ 5034CA33191D591100CE6051 /* ccShader_PositionTexture_uColor.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA04191D591000CE6051 /* ccShader_PositionTexture_uColor.frag */; };
+ 5034CA34191D591100CE6051 /* ccShader_PositionTexture_uColor.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA04191D591000CE6051 /* ccShader_PositionTexture_uColor.frag */; };
+ 5034CA35191D591100CE6051 /* ccShader_PositionTexture.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA05191D591000CE6051 /* ccShader_PositionTexture.frag */; };
+ 5034CA36191D591100CE6051 /* ccShader_PositionTexture.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA05191D591000CE6051 /* ccShader_PositionTexture.frag */; };
+ 5034CA37191D591100CE6051 /* ccShader_PositionColorLengthTexture.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA06191D591000CE6051 /* ccShader_PositionColorLengthTexture.vert */; };
+ 5034CA38191D591100CE6051 /* ccShader_PositionColorLengthTexture.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA06191D591000CE6051 /* ccShader_PositionColorLengthTexture.vert */; };
+ 5034CA39191D591100CE6051 /* ccShader_PositionColorLengthTexture.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA07191D591000CE6051 /* ccShader_PositionColorLengthTexture.frag */; };
+ 5034CA3A191D591100CE6051 /* ccShader_PositionColorLengthTexture.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA07191D591000CE6051 /* ccShader_PositionColorLengthTexture.frag */; };
+ 5034CA3B191D591100CE6051 /* ccShader_PositionColor.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA08191D591000CE6051 /* ccShader_PositionColor.vert */; };
+ 5034CA3C191D591100CE6051 /* ccShader_PositionColor.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA08191D591000CE6051 /* ccShader_PositionColor.vert */; };
+ 5034CA3D191D591100CE6051 /* ccShader_PositionColor.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA09191D591000CE6051 /* ccShader_PositionColor.frag */; };
+ 5034CA3E191D591100CE6051 /* ccShader_PositionColor.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA09191D591000CE6051 /* ccShader_PositionColor.frag */; };
+ 5034CA3F191D591100CE6051 /* ccShader_Position_uColor.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0A191D591000CE6051 /* ccShader_Position_uColor.vert */; };
+ 5034CA40191D591100CE6051 /* ccShader_Position_uColor.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0A191D591000CE6051 /* ccShader_Position_uColor.vert */; };
+ 5034CA41191D591100CE6051 /* ccShader_Position_uColor.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0B191D591000CE6051 /* ccShader_Position_uColor.frag */; };
+ 5034CA42191D591100CE6051 /* ccShader_Position_uColor.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0B191D591000CE6051 /* ccShader_Position_uColor.frag */; };
+ 5034CA43191D591100CE6051 /* ccShader_Label.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0C191D591000CE6051 /* ccShader_Label.vert */; };
+ 5034CA44191D591100CE6051 /* ccShader_Label.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0C191D591000CE6051 /* ccShader_Label.vert */; };
+ 5034CA45191D591100CE6051 /* ccShader_Label_outline.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0D191D591000CE6051 /* ccShader_Label_outline.frag */; };
+ 5034CA46191D591100CE6051 /* ccShader_Label_outline.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0D191D591000CE6051 /* ccShader_Label_outline.frag */; };
+ 5034CA47191D591100CE6051 /* ccShader_Label_normal.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0E191D591000CE6051 /* ccShader_Label_normal.frag */; };
+ 5034CA48191D591100CE6051 /* ccShader_Label_normal.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0E191D591000CE6051 /* ccShader_Label_normal.frag */; };
+ 5034CA49191D591100CE6051 /* ccShader_Label_df.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0F191D591000CE6051 /* ccShader_Label_df.frag */; };
+ 5034CA4A191D591100CE6051 /* ccShader_Label_df.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0F191D591000CE6051 /* ccShader_Label_df.frag */; };
+ 5034CA4B191D591100CE6051 /* ccShader_Label_df_glow.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA10191D591000CE6051 /* ccShader_Label_df_glow.frag */; };
+ 5034CA4C191D591100CE6051 /* ccShader_Label_df_glow.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA10191D591000CE6051 /* ccShader_Label_df_glow.frag */; };
+ 503D4F631CE29D4E0054A2D1 /* CCVRDistortionMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503D4F611CE29D4E0054A2D1 /* CCVRDistortionMesh.cpp */; };
+ 503D4F641CE29D4E0054A2D1 /* CCVRDistortionMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503D4F611CE29D4E0054A2D1 /* CCVRDistortionMesh.cpp */; };
+ 503D4F651CE29D4E0054A2D1 /* CCVRDistortionMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503D4F611CE29D4E0054A2D1 /* CCVRDistortionMesh.cpp */; };
+ 503D4F661CE29D4E0054A2D1 /* CCVRDistortionMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 503D4F621CE29D4E0054A2D1 /* CCVRDistortionMesh.h */; };
+ 503D4F671CE29D4E0054A2D1 /* CCVRDistortionMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 503D4F621CE29D4E0054A2D1 /* CCVRDistortionMesh.h */; };
+ 503D4F681CE29D4E0054A2D1 /* CCVRDistortionMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 503D4F621CE29D4E0054A2D1 /* CCVRDistortionMesh.h */; };
+ 503D4F6B1CE2BDBE0054A2D1 /* CCVRDistortion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503D4F691CE2BDBE0054A2D1 /* CCVRDistortion.cpp */; };
+ 503D4F6C1CE2BDBE0054A2D1 /* CCVRDistortion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503D4F691CE2BDBE0054A2D1 /* CCVRDistortion.cpp */; };
+ 503D4F6D1CE2BDBE0054A2D1 /* CCVRDistortion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503D4F691CE2BDBE0054A2D1 /* CCVRDistortion.cpp */; };
+ 503D4F6E1CE2BDBE0054A2D1 /* CCVRDistortion.h in Headers */ = {isa = PBXBuildFile; fileRef = 503D4F6A1CE2BDBE0054A2D1 /* CCVRDistortion.h */; };
+ 503D4F6F1CE2BDBE0054A2D1 /* CCVRDistortion.h in Headers */ = {isa = PBXBuildFile; fileRef = 503D4F6A1CE2BDBE0054A2D1 /* CCVRDistortion.h */; };
+ 503D4F701CE2BDBE0054A2D1 /* CCVRDistortion.h in Headers */ = {isa = PBXBuildFile; fileRef = 503D4F6A1CE2BDBE0054A2D1 /* CCVRDistortion.h */; };
+ 503DD8E01926736A00CD74DD /* CCApplication-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8CE1926736A00CD74DD /* CCApplication-ios.h */; };
+ 503DD8E11926736A00CD74DD /* CCApplication-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8CF1926736A00CD74DD /* CCApplication-ios.mm */; };
+ 503DD8E21926736A00CD74DD /* CCCommon-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8D01926736A00CD74DD /* CCCommon-ios.mm */; };
+ 503DD8E31926736A00CD74DD /* CCDevice-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8D11926736A00CD74DD /* CCDevice-ios.mm */; };
+ 503DD8E41926736A00CD74DD /* CCDirectorCaller-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8D21926736A00CD74DD /* CCDirectorCaller-ios.h */; };
+ 503DD8E51926736A00CD74DD /* CCDirectorCaller-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8D31926736A00CD74DD /* CCDirectorCaller-ios.mm */; };
+ 503DD8E61926736A00CD74DD /* CCEAGLView-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8D41926736A00CD74DD /* CCEAGLView-ios.h */; };
+ 503DD8E71926736A00CD74DD /* CCEAGLView-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8D51926736A00CD74DD /* CCEAGLView-ios.mm */; };
+ 503DD8E81926736A00CD74DD /* CCES2Renderer-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8D61926736A00CD74DD /* CCES2Renderer-ios.h */; };
+ 503DD8E91926736A00CD74DD /* CCES2Renderer-ios.m in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8D71926736A00CD74DD /* CCES2Renderer-ios.m */; };
+ 503DD8EA1926736A00CD74DD /* CCESRenderer-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8D81926736A00CD74DD /* CCESRenderer-ios.h */; };
+ 503DD8EB1926736A00CD74DD /* CCGL-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8D91926736A00CD74DD /* CCGL-ios.h */; };
+ 503DD8EC1926736A00CD74DD /* CCGLViewImpl-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8DA1926736A00CD74DD /* CCGLViewImpl-ios.h */; };
+ 503DD8ED1926736A00CD74DD /* CCGLViewImpl-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8DB1926736A00CD74DD /* CCGLViewImpl-ios.mm */; };
+ 503DD8EE1926736A00CD74DD /* CCImage-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8DC1926736A00CD74DD /* CCImage-ios.mm */; };
+ 503DD8EF1926736A00CD74DD /* CCPlatformDefine-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8DD1926736A00CD74DD /* CCPlatformDefine-ios.h */; };
+ 503DD8F01926736A00CD74DD /* CCStdC-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8DE1926736A00CD74DD /* CCStdC-ios.h */; };
+ 503DD8F11926736A00CD74DD /* OpenGL_Internal-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8DF1926736A00CD74DD /* OpenGL_Internal-ios.h */; };
+ 503DD8F51926B0DB00CD74DD /* CCIMEDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8F21926B0DB00CD74DD /* CCIMEDelegate.h */; };
+ 503DD8F61926B0DB00CD74DD /* CCIMEDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8F21926B0DB00CD74DD /* CCIMEDelegate.h */; };
+ 503DD8F71926B0DB00CD74DD /* CCIMEDispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8F31926B0DB00CD74DD /* CCIMEDispatcher.cpp */; };
+ 503DD8F81926B0DB00CD74DD /* CCIMEDispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8F31926B0DB00CD74DD /* CCIMEDispatcher.cpp */; };
+ 503DD8F91926B0DB00CD74DD /* CCIMEDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8F41926B0DB00CD74DD /* CCIMEDispatcher.h */; };
+ 503DD8FA1926B0DB00CD74DD /* CCIMEDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8F41926B0DB00CD74DD /* CCIMEDispatcher.h */; };
+ 505385021B01887A00793096 /* CCProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 505385001B01887A00793096 /* CCProperties.h */; };
+ 505385031B01887A00793096 /* CCProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 505385001B01887A00793096 /* CCProperties.h */; };
+ 505385041B01887A00793096 /* CCProperties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 505385011B01887A00793096 /* CCProperties.cpp */; };
+ 505385051B01887A00793096 /* CCProperties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 505385011B01887A00793096 /* CCProperties.cpp */; };
+ 5053850C1B02819E00793096 /* CCVertexAttribBinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5053850A1B02819E00793096 /* CCVertexAttribBinding.cpp */; };
+ 5053850D1B02819E00793096 /* CCVertexAttribBinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5053850A1B02819E00793096 /* CCVertexAttribBinding.cpp */; };
+ 5053850E1B02819E00793096 /* CCVertexAttribBinding.h in Headers */ = {isa = PBXBuildFile; fileRef = 5053850B1B02819E00793096 /* CCVertexAttribBinding.h */; };
+ 5053850F1B02819E00793096 /* CCVertexAttribBinding.h in Headers */ = {isa = PBXBuildFile; fileRef = 5053850B1B02819E00793096 /* CCVertexAttribBinding.h */; };
+ 50643BD419BFAECF00EF68ED /* CCGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BD319BFAECF00EF68ED /* CCGL.h */; };
+ 50643BD519BFAECF00EF68ED /* CCGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BD319BFAECF00EF68ED /* CCGL.h */; };
+ 50643BD619BFAEDA00EF68ED /* CCPlatformDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 5091A7A219BFABA800AC8789 /* CCPlatformDefine.h */; };
+ 50643BD919BFAF4400EF68ED /* CCApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BD719BFAF4400EF68ED /* CCApplication.h */; };
+ 50643BDA19BFAF4400EF68ED /* CCApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BD719BFAF4400EF68ED /* CCApplication.h */; };
+ 50643BDB19BFAF4400EF68ED /* CCStdC.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BD819BFAF4400EF68ED /* CCStdC.h */; };
+ 50643BDC19BFAF4400EF68ED /* CCStdC.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BD819BFAF4400EF68ED /* CCStdC.h */; };
+ 50643BDE19BFCCA400EF68ED /* LocalStorage-android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50643BDD19BFCCA300EF68ED /* LocalStorage-android.cpp */; };
+ 50643BDF19BFCCA400EF68ED /* LocalStorage-android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50643BDD19BFCCA300EF68ED /* LocalStorage-android.cpp */; };
+ 50643BE219BFCF1800EF68ED /* CCPlatformConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BE019BFCF1800EF68ED /* CCPlatformConfig.h */; };
+ 50643BE319BFCF1800EF68ED /* CCPlatformConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BE019BFCF1800EF68ED /* CCPlatformConfig.h */; };
+ 50643BE419BFCF1800EF68ED /* CCPlatformMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BE119BFCF1800EF68ED /* CCPlatformMacros.h */; };
+ 50643BE519BFCF1800EF68ED /* CCPlatformMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BE119BFCF1800EF68ED /* CCPlatformMacros.h */; };
+ 50693C5E1B6BF2AE005C5820 /* CCDownloader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50693C5C1B6BF2AE005C5820 /* CCDownloader.cpp */; };
+ 50693C5F1B6BF2AE005C5820 /* CCDownloader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50693C5C1B6BF2AE005C5820 /* CCDownloader.cpp */; };
+ 50693C601B6BF2AE005C5820 /* CCDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50693C5D1B6BF2AE005C5820 /* CCDownloader.h */; };
+ 50693C611B6BF2AE005C5820 /* CCDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50693C5D1B6BF2AE005C5820 /* CCDownloader.h */; };
+ 5070031B1B69735200E83DDD /* HttpClient-android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 507003161B69735200E83DDD /* HttpClient-android.cpp */; };
+ 5070031D1B69735200E83DDD /* HttpClient-winrt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 507003171B69735200E83DDD /* HttpClient-winrt.cpp */; };
+ 507003211B69735300E83DDD /* HttpConnection-winrt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 507003191B69735200E83DDD /* HttpConnection-winrt.cpp */; };
+ 507003221B69735300E83DDD /* HttpConnection-winrt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 507003191B69735200E83DDD /* HttpConnection-winrt.cpp */; };
+ 507003231B69735300E83DDD /* HttpConnection-winrt.h in Headers */ = {isa = PBXBuildFile; fileRef = 5070031A1B69735200E83DDD /* HttpConnection-winrt.h */; };
+ 507003241B69735300E83DDD /* HttpConnection-winrt.h in Headers */ = {isa = PBXBuildFile; fileRef = 5070031A1B69735200E83DDD /* HttpConnection-winrt.h */; };
+ 507B39C21C31BDD30067B53E /* CCAllocatorGlobalNewDelete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0FD03401A3B51AA00825BB5 /* CCAllocatorGlobalNewDelete.cpp */; };
+ 507B39C31C31BDD30067B53E /* UIVideoPlayer-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3EA0FB6A191C841D00B170C8 /* UIVideoPlayer-ios.mm */; };
+ 507B39C41C31BDD30067B53E /* CCPUPlaneCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E19A1AA80A6500DDB1C5 /* CCPUPlaneCollider.cpp */; };
+ 507B39C51C31BDD30067B53E /* CCPUBehaviour.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E01AA80A6500DDB1C5 /* CCPUBehaviour.cpp */; };
+ 507B39C71C31BDD30067B53E /* DetourPathQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F9B1B04825B00E47F5F /* DetourPathQueue.cpp */; };
+ 507B39C81C31BDD30067B53E /* CCPUPlane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1981AA80A6500DDB1C5 /* CCPUPlane.cpp */; };
+ 507B39C91C31BDD30067B53E /* CCPUDoPlacementParticleEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E10C1AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandler.cpp */; };
+ 507B39CA1C31BDD30067B53E /* CCTableViewCell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168641807AF4E005B8026 /* CCTableViewCell.cpp */; };
+ 507B39CC1C31BDD30067B53E /* ButtonReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB6A18C72017004AD434 /* ButtonReader.cpp */; };
+ 507B39CD1C31BDD30067B53E /* CCNodeLoaderLibrary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D21180E26E600808F54 /* CCNodeLoaderLibrary.cpp */; };
+ 507B39CE1C31BDD30067B53E /* CCActionFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5948180E930E00EF57C3 /* CCActionFrame.cpp */; };
+ 507B39D01C31BDD30067B53E /* CCSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C68018F57BE800EFE3A6 /* CCSet.cpp */; };
+ 507B39D11C31BDD30067B53E /* CCString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C68218F57BE800EFE3A6 /* CCString.cpp */; };
+ 507B39D21C31BDD30067B53E /* sweep.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20831AE7C57D00C31518 /* sweep.cc */; };
+ 507B39D31C31BDD30067B53E /* ImageViewReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7018C72017004AD434 /* ImageViewReader.cpp */; };
+ 507B39D51C31BDD30067B53E /* CCPUAffectorManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0CE1AA80A6500DDB1C5 /* CCPUAffectorManager.cpp */; };
+ 507B39D61C31BDD30067B53E /* CCTweenFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2986667818B1B079000E39CA /* CCTweenFunction.cpp */; };
+ 507B39D71C31BDD30067B53E /* CCPhysicsWorld.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A170771807CE7A005B8026 /* CCPhysicsWorld.cpp */; };
+ 507B39D91C31BDD30067B53E /* CCGroupCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD721925AB4100A911A9 /* CCGroupCommand.cpp */; };
+ 507B39DA1C31BDD30067B53E /* CCPhysicsShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A170751807CE7A005B8026 /* CCPhysicsShape.cpp */; };
+ 507B39DB1C31BDD30067B53E /* CCPUOnRandomObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1801AA80A6500DDB1C5 /* CCPUOnRandomObserver.cpp */; };
+ 507B39DC1C31BDD30067B53E /* CCImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF271926664700A911A9 /* CCImage.cpp */; };
+ 507B39DD1C31BDD30067B53E /* CCPURandomiserTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A81AA80A6500DDB1C5 /* CCPURandomiserTranslator.cpp */; };
+ 507B39DE1C31BDD30067B53E /* DetourPathCorridor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F991B04825B00E47F5F /* DetourPathCorridor.cpp */; };
+ 507B39DF1C31BDD30067B53E /* CCNotificationCenter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C6A218F58F7500EFE3A6 /* CCNotificationCenter.cpp */; };
+ 507B39E01C31BDD30067B53E /* UIEditBoxImpl-mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 292DB13719B4574100A80320 /* UIEditBoxImpl-mac.mm */; };
+ 507B39E31C31BDD30067B53E /* CCPURandomiser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A61AA80A6500DDB1C5 /* CCPURandomiser.cpp */; };
+ 507B39E41C31BDD30067B53E /* CCControlUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168481807AF4E005B8026 /* CCControlUtils.cpp */; };
+ 507B39E51C31BDD30067B53E /* CCPUObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E15A1AA80A6500DDB1C5 /* CCPUObserver.cpp */; };
+ 507B39E71C31BDD30067B53E /* CCTrianglesCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B230ED6F19B417AE00364AA8 /* CCTrianglesCommand.cpp */; };
+ 507B39EA1C31BDD30067B53E /* UIWidget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA1318CF08D100240AA3 /* UIWidget.cpp */; };
+ 507B39EB1C31BDD30067B53E /* CCNodeGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9C6A9218599AD8000A5232 /* CCNodeGrid.cpp */; };
+ 507B39EC1C31BDD30067B53E /* CCPUDoAffectorEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0FC1AA80A6500DDB1C5 /* CCPUDoAffectorEventHandler.cpp */; };
+ 507B39ED1C31BDD30067B53E /* CCPUSlaveEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1CE1AA80A6500DDB1C5 /* CCPUSlaveEmitterTranslator.cpp */; };
+ 507B39EF1C31BDD30067B53E /* CCDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C67B18F57BE800EFE3A6 /* CCDictionary.cpp */; };
+ 507B39F01C31BDD30067B53E /* CCVertexIndexData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B276EF5C1988D1D500CD400F /* CCVertexIndexData.cpp */; };
+ 507B39F11C31BDD30067B53E /* CCEventFocus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDDC1925AB6E00A911A9 /* CCEventFocus.cpp */; };
+ 507B39F21C31BDD30067B53E /* CCSkeleton3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17FF19AAD2F700C27E9E /* CCSkeleton3D.cpp */; };
+ 507B39F31C31BDD30067B53E /* DetourTileCacheBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2FA21B04825B00E47F5F /* DetourTileCacheBuilder.cpp */; };
+ 507B39F41C31BDD30067B53E /* CCApplication-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8CF1926736A00CD74DD /* CCApplication-ios.mm */; };
+ 507B39F81C31BDD30067B53E /* CCMenuItemImageLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D18180E26E600808F54 /* CCMenuItemImageLoader.cpp */; };
+ 507B39F91C31BDD30067B53E /* fastlz.c in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2FA51B04825B00E47F5F /* fastlz.c */; };
+ 507B39FA1C31BDD30067B53E /* CCSAXParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF291926664700A911A9 /* CCSAXParser.cpp */; };
+ 507B39FC1C31BDD30067B53E /* CCPhysicsJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A170721807CE7A005B8026 /* CCPhysicsJoint.cpp */; };
+ 507B39FE1C31BDD30067B53E /* UserCameraReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 182C5CE31A9D725400C30D34 /* UserCameraReader.cpp */; };
+ 507B39FF1C31BDD30067B53E /* UILayoutComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38B8E2DF19E671D2002D7CE7 /* UILayoutComponent.cpp */; };
+ 507B3A011C31BDD30067B53E /* CCPrimitiveCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B257B45E198A353E00D9A687 /* CCPrimitiveCommand.cpp */; };
+ 507B3A021C31BDD30067B53E /* UIScrollViewBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5668D7B1B3838E4003CBD5E /* UIScrollViewBar.cpp */; };
+ 507B3A031C31BDD30067B53E /* CCPUOnCountObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1681AA80A6500DDB1C5 /* CCPUOnCountObserver.cpp */; };
+ 507B3A041C31BDD30067B53E /* CDOpenALSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FE81807A56F005B8026 /* CDOpenALSupport.m */; };
+ 507B3A061C31BDD30067B53E /* SimpleAudioEngine_objc.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FED1807A56F005B8026 /* SimpleAudioEngine_objc.m */; };
+ 507B3A071C31BDD30067B53E /* CCMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F319AAD2F700C27E9E /* CCMesh.cpp */; };
+ 507B3A081C31BDD30067B53E /* CCPUSphereSurfaceEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D61AA80A6500DDB1C5 /* CCPUSphereSurfaceEmitter.cpp */; };
+ 507B3A091C31BDD30067B53E /* CCImage-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8DC1926736A00CD74DD /* CCImage-ios.mm */; };
+ 507B3A0C1C31BDD30067B53E /* CCPhysicsBody.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1706E1807CE7A005B8026 /* CCPhysicsBody.cpp */; };
+ 507B3A0D1C31BDD30067B53E /* CCControlButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168371807AF4E005B8026 /* CCControlButton.cpp */; };
+ 507B3A0E1C31BDD30067B53E /* CCGLProgramState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD6C1925AB4100A911A9 /* CCGLProgramState.cpp */; };
+ 507B3A0F1C31BDD30067B53E /* CCPUSimpleSpline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C21AA80A6500DDB1C5 /* CCPUSimpleSpline.cpp */; };
+ 507B3A111C31BDD30067B53E /* CCPrimitive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B257B44C1989D5E800D9A687 /* CCPrimitive.cpp */; };
+ 507B3A121C31BDD30067B53E /* CCAutoreleasePool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDC51925AB6E00A911A9 /* CCAutoreleasePool.cpp */; };
+ 507B3A131C31BDD30067B53E /* CCScale9SpriteLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D26180E26E600808F54 /* CCScale9SpriteLoader.cpp */; };
+ 507B3A141C31BDD30067B53E /* TriggerMng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06CAAABE186AD63B0012A414 /* TriggerMng.cpp */; };
+ 507B3A181C31BDD30067B53E /* CocosDenshion.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FEA1807A56F005B8026 /* CocosDenshion.m */; };
+ 507B3A191C31BDD30067B53E /* CCPUBaseCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D61AA80A6500DDB1C5 /* CCPUBaseCollider.cpp */; };
+ 507B3A1A1C31BDD30067B53E /* RecastDebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F7E1B04825B00E47F5F /* RecastDebugDraw.cpp */; };
+ 507B3A1B1C31BDD30067B53E /* CCPhysicsContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A170701807CE7A005B8026 /* CCPhysicsContact.cpp */; };
+ 507B3A1C1C31BDD30067B53E /* CCAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570047180BC5A10088DEC7 /* CCAction.cpp */; };
+ 507B3A1D1C31BDD30067B53E /* CCActionCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570049180BC5A10088DEC7 /* CCActionCamera.cpp */; };
+ 507B3A1E1C31BDD30067B53E /* CCPUJetAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E13E1AA80A6500DDB1C5 /* CCPUJetAffector.cpp */; };
+ 507B3A1F1C31BDD30067B53E /* CCVertexIndexBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B276EF5E1988D1D500CD400F /* CCVertexIndexBuffer.cpp */; };
+ 507B3A211C31BDD30067B53E /* CCScrollView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1685E1807AF4E005B8026 /* CCScrollView.cpp */; };
+ 507B3A231C31BDD30067B53E /* Manifest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15B3707619EE414C00ABE682 /* Manifest.cpp */; };
+ 507B3A261C31BDD30067B53E /* CCActionCatmullRom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57004B180BC5A10088DEC7 /* CCActionCatmullRom.cpp */; };
+ 507B3A271C31BDD30067B53E /* CCControlHuePicker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1683C1807AF4E005B8026 /* CCControlHuePicker.cpp */; };
+ 507B3A281C31BDD30067B53E /* CCFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0634A4C9194B19E400E608AF /* CCFrame.cpp */; };
+ 507B3A2B1C31BDD30067B53E /* CCActionEase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57004D180BC5A10088DEC7 /* CCActionEase.cpp */; };
+ 507B3A2C1C31BDD30067B53E /* CCGLProgram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD681925AB4100A911A9 /* CCGLProgram.cpp */; };
+ 507B3A2D1C31BDD30067B53E /* CCPUDoExpireEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1061AA80A6500DDB1C5 /* CCPUDoExpireEventHandlerTranslator.cpp */; };
+ 507B3A2F1C31BDD30067B53E /* CCPhysicsSprite3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFE01AF9A9E100B9B856 /* CCPhysicsSprite3D.cpp */; };
+ 507B3A301C31BDD30067B53E /* CCSSceneReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C597C180E930E00EF57C3 /* CCSSceneReader.cpp */; };
+ 507B3A311C31BDD30067B53E /* CCActionGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57004F180BC5A10088DEC7 /* CCActionGrid.cpp */; };
+ 507B3A341C31BDD30067B53E /* CCPULinearForceAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1481AA80A6500DDB1C5 /* CCPULinearForceAffectorTranslator.cpp */; };
+ 507B3A351C31BDD30067B53E /* CCPUUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E61AA80A6500DDB1C5 /* CCPUUtil.cpp */; };
+ 507B3A361C31BDD30067B53E /* CCPUGeometryRotator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1321AA80A6500DDB1C5 /* CCPUGeometryRotator.cpp */; };
+ 507B3A391C31BDD30067B53E /* HttpClient-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52B47A2B1A5349A3004E4C60 /* HttpClient-apple.mm */; };
+ 507B3A3B1C31BDD30067B53E /* CCPUBaseForceAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0DC1AA80A6500DDB1C5 /* CCPUBaseForceAffectorTranslator.cpp */; };
+ 507B3A3C1C31BDD30067B53E /* FlatBuffersSerialize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384051A25900F002C4610 /* FlatBuffersSerialize.cpp */; };
+ 507B3A3D1C31BDD30067B53E /* CCParticle3DRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B68778F41A8CA82E00643ABF /* CCParticle3DRender.cpp */; };
+ 507B3A3E1C31BDD30067B53E /* CCClippingRectangleNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DABC9FA719E7DFA900FA252C /* CCClippingRectangleNode.cpp */; };
+ 507B3A3F1C31BDD30067B53E /* CCPULinearForceAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1461AA80A6500DDB1C5 /* CCPULinearForceAffector.cpp */; };
+ 507B3A401C31BDD30067B53E /* CCControlPotentiometer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1683E1807AF4E005B8026 /* CCControlPotentiometer.cpp */; };
+ 507B3A421C31BDD30067B53E /* CCPUDynamicAttributeTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E11A1AA80A6500DDB1C5 /* CCPUDynamicAttributeTranslator.cpp */; };
+ 507B3A431C31BDD30067B53E /* CCPUOnClearObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1601AA80A6500DDB1C5 /* CCPUOnClearObserver.cpp */; };
+ 507B3A481C31BDD30067B53E /* UITextField.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA1118CF08D100240AA3 /* UITextField.cpp */; };
+ 507B3A491C31BDD30067B53E /* CheckBoxReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB6D18C72017004AD434 /* CheckBoxReader.cpp */; };
+ 507B3A4A1C31BDD30067B53E /* CCPhysics3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFD21AF9A9E100B9B856 /* CCPhysics3D.cpp */; };
+ 507B3A4B1C31BDD30067B53E /* CCEventListenerAcceleration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE21925AB6E00A911A9 /* CCEventListenerAcceleration.cpp */; };
+ 507B3A4C1C31BDD30067B53E /* CCPUGravityAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1361AA80A6500DDB1C5 /* CCPUGravityAffector.cpp */; };
+ 507B3A4D1C31BDD30067B53E /* CCPULineAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1441AA80A6500DDB1C5 /* CCPULineAffectorTranslator.cpp */; };
+ 507B3A4F1C31BDD30067B53E /* UIEditBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB12F19B4574100A80320 /* UIEditBox.cpp */; };
+ 507B3A531C31BDD30067B53E /* CCController-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E6176551960F89B00DE83F5 /* CCController-apple.mm */; };
+ 507B3A541C31BDD30067B53E /* CCBReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D01180E26E600808F54 /* CCBReader.cpp */; };
+ 507B3A551C31BDD30067B53E /* CCArmatureDefine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5958180E930E00EF57C3 /* CCArmatureDefine.cpp */; };
+ 507B3A561C31BDD30067B53E /* CCPUOnRandomObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1821AA80A6500DDB1C5 /* CCPUOnRandomObserverTranslator.cpp */; };
+ 507B3A571C31BDD30067B53E /* CCMeshCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594B21926D5EC003EEF37 /* CCMeshCommand.cpp */; };
+ 507B3A581C31BDD30067B53E /* CCStencilStateManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 298C75D31C0465D0006BAE63 /* CCStencilStateManager.cpp */; };
+ 507B3A591C31BDD30067B53E /* CCComRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5966180E930E00EF57C3 /* CCComRender.cpp */; };
+ 507B3A5A1C31BDD30067B53E /* SpriteReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384421A25915C002C4610 /* SpriteReader.cpp */; };
+ 507B3A5D1C31BDD30067B53E /* LoadingBarReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7918C72017004AD434 /* LoadingBarReader.cpp */; };
+ 507B3A5E1C31BDD30067B53E /* CCEventTouch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDF01925AB6E00A911A9 /* CCEventTouch.cpp */; };
+ 507B3A5F1C31BDD30067B53E /* CCOBB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F919AAD2F700C27E9E /* CCOBB.cpp */; };
+ 507B3A621C31BDD30067B53E /* CCLayerLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D16180E26E600808F54 /* CCLayerLoader.cpp */; };
+ 507B3A631C31BDD30067B53E /* CCControlStepper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168441807AF4E005B8026 /* CCControlStepper.cpp */; };
+ 507B3A651C31BDD30067B53E /* CCPass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 501216921AC47393009A4BEA /* CCPass.cpp */; };
+ 507B3A661C31BDD30067B53E /* CCEventListenerKeyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE81925AB6E00A911A9 /* CCEventListenerKeyboard.cpp */; };
+ 507B3A671C31BDD30067B53E /* CCPUGravityAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1381AA80A6500DDB1C5 /* CCPUGravityAffectorTranslator.cpp */; };
+ 507B3A681C31BDD30067B53E /* CCScrollViewLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D28180E26E600808F54 /* CCScrollViewLoader.cpp */; };
+ 507B3A691C31BDD30067B53E /* AudioEngine-inl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50CB247219D9C5A100687767 /* AudioEngine-inl.mm */; };
+ 507B3A6B1C31BDD30067B53E /* CCEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD41925AB6E00A911A9 /* CCEvent.cpp */; };
+ 507B3A6D1C31BDD30067B53E /* shapes.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB207A1AE7C57D00C31518 /* shapes.cc */; };
+ 507B3A6F1C31BDD30067B53E /* CCScheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE011925AB6E00A911A9 /* CCScheduler.cpp */; };
+ 507B3A711C31BDD30067B53E /* CCEventCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD81925AB6E00A911A9 /* CCEventCustom.cpp */; };
+ 507B3A731C31BDD30067B53E /* CCControlSlider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168421807AF4E005B8026 /* CCControlSlider.cpp */; };
+ 507B3A741C31BDD30067B53E /* CCAttachNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17EC19AAD2F700C27E9E /* CCAttachNode.cpp */; };
+ 507B3A751C31BDD30067B53E /* CCParticleSystem3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B68778F61A8CA82E00643ABF /* CCParticleSystem3D.cpp */; };
+ 507B3A761C31BDD30067B53E /* CCBSequenceProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D06180E26E600808F54 /* CCBSequenceProperty.cpp */; };
+ 507B3A791C31BDD30067B53E /* CCControlButtonLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D0A180E26E600808F54 /* CCControlButtonLoader.cpp */; };
+ 507B3A7B1C31BDD30067B53E /* CCEventListenerTouch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDEC1925AB6E00A911A9 /* CCEventListenerTouch.cpp */; };
+ 507B3A7E1C31BDD30067B53E /* DetourTileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2FA01B04825B00E47F5F /* DetourTileCache.cpp */; };
+ 507B3A811C31BDD30067B53E /* CCSprite3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE180119AAD2F700C27E9E /* CCSprite3D.cpp */; };
+ 507B3A821C31BDD30067B53E /* CCEventKeyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDDE1925AB6E00A911A9 /* CCEventKeyboard.cpp */; };
+ 507B3A831C31BDD30067B53E /* CCArmatureDataManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5956180E930E00EF57C3 /* CCArmatureDataManager.cpp */; };
+ 507B3A841C31BDD30067B53E /* CCPUBehaviourManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E21AA80A6500DDB1C5 /* CCPUBehaviourManager.cpp */; };
+ 507B3A851C31BDD30067B53E /* CCPUParticleSystem3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1901AA80A6500DDB1C5 /* CCPUParticleSystem3D.cpp */; };
+ 507B3A861C31BDD30067B53E /* CCLight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EACC99E19F5014D00EB3C5E /* CCLight.cpp */; };
+ 507B3A871C31BDD30067B53E /* UIScrollView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0718CF08D000240AA3 /* UIScrollView.cpp */; };
+ 507B3A881C31BDD30067B53E /* CCActionGrid3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570051180BC5A10088DEC7 /* CCActionGrid3D.cpp */; };
+ 507B3A8B1C31BDD30067B53E /* SliderReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8218C72017004AD434 /* SliderReader.cpp */; };
+ 507B3A8D1C31BDD30067B53E /* CCPURibbonTrail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1AE1AA80A6500DDB1C5 /* CCPURibbonTrail.cpp */; };
+ 507B3A8E1C31BDD30067B53E /* CCPUAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0CC1AA80A6500DDB1C5 /* CCPUAffector.cpp */; };
+ 507B3A8F1C31BDD30067B53E /* UIText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0B18CF08D100240AA3 /* UIText.cpp */; };
+ 507B3A941C31BDD30067B53E /* DetourLocalBoundary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F951B04825B00E47F5F /* DetourLocalBoundary.cpp */; };
+ 507B3A951C31BDD30067B53E /* CCLayerColorLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D12180E26E600808F54 /* CCLayerColorLoader.cpp */; };
+ 507B3A961C31BDD30067B53E /* TransformUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD2D1925AB0000A911A9 /* TransformUtils.cpp */; };
+ 507B3A971C31BDD30067B53E /* CCPUInterParticleCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E13A1AA80A6500DDB1C5 /* CCPUInterParticleCollider.cpp */; };
+ 507B3A981C31BDD30067B53E /* UIEditBoxImpl-android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB13219B4574100A80320 /* UIEditBoxImpl-android.cpp */; };
+ 507B3A991C31BDD30067B53E /* CCArmature.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5952180E930E00EF57C3 /* CCArmature.cpp */; };
+ 507B3A9A1C31BDD30067B53E /* CCActionInstant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570053180BC5A10088DEC7 /* CCActionInstant.cpp */; };
+ 507B3A9C1C31BDD30067B53E /* DetourObstacleAvoidance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F971B04825B00E47F5F /* DetourObstacleAvoidance.cpp */; };
+ 507B3A9D1C31BDD30067B53E /* CCControlColourPicker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168391807AF4E005B8026 /* CCControlColourPicker.cpp */; };
+ 507B3AA01C31BDD30067B53E /* ComAudioReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384181A2590D2002C4610 /* ComAudioReader.cpp */; };
+ 507B3AA21C31BDD30067B53E /* CCValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE111925AB6F00A911A9 /* CCValue.cpp */; };
+ 507B3AA31C31BDD30067B53E /* Vec2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD2F1925AB0000A911A9 /* Vec2.cpp */; };
+ 507B3AA41C31BDD30067B53E /* CCPUScaleVelocityAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B81AA80A6500DDB1C5 /* CCPUScaleVelocityAffectorTranslator.cpp */; };
+ 507B3AA61C31BDD30067B53E /* CCPUOnCountObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E16A1AA80A6500DDB1C5 /* CCPUOnCountObserverTranslator.cpp */; };
+ 507B3AA71C31BDD30067B53E /* CocoLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29E99D1C1957BA7000046604 /* CocoLoader.cpp */; };
+ 507B3AA81C31BDD30067B53E /* CCPURibbonTrailRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B01AA80A6500DDB1C5 /* CCPURibbonTrailRender.cpp */; };
+ 507B3AA91C31BDD30067B53E /* CCBoneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306631B60B583001E6D43 /* CCBoneNode.cpp */; };
+ 507B3AAA1C31BDD30067B53E /* CCDirector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD21925AB6E00A911A9 /* CCDirector.cpp */; };
+ 507B3AAB1C31BDD30067B53E /* CCTableView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168621807AF4E005B8026 /* CCTableView.cpp */; };
+ 507B3AAD1C31BDD30067B53E /* CCPUPositionEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A21AA80A6500DDB1C5 /* CCPUPositionEmitter.cpp */; };
+ 507B3AAE1C31BDD30067B53E /* CCActionInterval.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570055180BC5A10088DEC7 /* CCActionInterval.cpp */; };
+ 507B3AAF1C31BDD30067B53E /* CCControlSaturationBrightnessPicker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168401807AF4E005B8026 /* CCControlSaturationBrightnessPicker.cpp */; };
+ 507B3AB11C31BDD30067B53E /* CCPUInterParticleColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E13C1AA80A6500DDB1C5 /* CCPUInterParticleColliderTranslator.cpp */; };
+ 507B3AB21C31BDD30067B53E /* CCPUOnEmissionObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E16C1AA80A6500DDB1C5 /* CCPUOnEmissionObserver.cpp */; };
+ 507B3AB31C31BDD30067B53E /* CCActionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570057180BC5A10088DEC7 /* CCActionManager.cpp */; };
+ 507B3AB41C31BDD30067B53E /* CCDownloader-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = A0534A641B872FFD006B03E5 /* CCDownloader-apple.mm */; };
+ 507B3AB51C31BDD30067B53E /* CCPUBoxColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0EA1AA80A6500DDB1C5 /* CCPUBoxColliderTranslator.cpp */; };
+ 507B3AB61C31BDD30067B53E /* CCActionPageTurn3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570059180BC5A10088DEC7 /* CCActionPageTurn3D.cpp */; };
+ 507B3AB81C31BDD30067B53E /* CCActionProgressTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57005B180BC5A10088DEC7 /* CCActionProgressTimer.cpp */; };
+ 507B3ABA1C31BDD30067B53E /* CCPUSlaveBehaviourTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1CA1AA80A6500DDB1C5 /* CCPUSlaveBehaviourTranslator.cpp */; };
+ 507B3ABB1C31BDD30067B53E /* CCBKeyframe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71CFE180E26E600808F54 /* CCBKeyframe.cpp */; };
+ 507B3ABF1C31BDD30067B53E /* LocalStorage-android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50643BDD19BFCCA300EF68ED /* LocalStorage-android.cpp */; };
+ 507B3AC01C31BDD30067B53E /* ZipUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE1D1925AB6F00A911A9 /* ZipUtils.cpp */; };
+ 507B3AC11C31BDD30067B53E /* UIHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F418CF08D000240AA3 /* UIHelper.cpp */; };
+ 507B3AC31C31BDD30067B53E /* CCPhysics3DDebugDrawer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFD81AF9A9E100B9B856 /* CCPhysics3DDebugDrawer.cpp */; };
+ 507B3AC61C31BDD30067B53E /* CCBundle3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17EE19AAD2F700C27E9E /* CCBundle3D.cpp */; };
+ 507B3AC91C31BDD30067B53E /* CCActionTiledGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57005D180BC5A10088DEC7 /* CCActionTiledGrid.cpp */; };
+ 507B3ACA1C31BDD30067B53E /* CCNavMeshAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0C11B18492D006762CB /* CCNavMeshAgent.cpp */; };
+ 507B3ACC1C31BDD30067B53E /* CCActionTween.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57005F180BC5A10088DEC7 /* CCActionTween.cpp */; };
+ 507B3ACD1C31BDD30067B53E /* CCAtlasNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570096180BC5C10088DEC7 /* CCAtlasNode.cpp */; };
+ 507B3ACF1C31BDD30067B53E /* CCPhysics3DObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFDA1AF9A9E100B9B856 /* CCPhysics3DObject.cpp */; };
+ 507B3AD01C31BDD30067B53E /* CCPUEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E11C1AA80A6500DDB1C5 /* CCPUEmitter.cpp */; };
+ 507B3AD11C31BDD30067B53E /* MathUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD261925AB0000A911A9 /* MathUtil.cpp */; };
+ 507B3AD21C31BDD30067B53E /* DetourNavMeshQuery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F8D1B04825B00E47F5F /* DetourNavMeshQuery.cpp */; };
+ 507B3AD31C31BDD30067B53E /* CCDataVisitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD01925AB6E00A911A9 /* CCDataVisitor.cpp */; };
+ 507B3AD51C31BDD30067B53E /* CCNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57009C180BC5D20088DEC7 /* CCNode.cpp */; };
+ 507B3AD61C31BDD30067B53E /* CCDrawingPrimitives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57010A180BC8ED0088DEC7 /* CCDrawingPrimitives.cpp */; };
+ 507B3AD71C31BDD30067B53E /* CCPUSlaveEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1CC1AA80A6500DDB1C5 /* CCPUSlaveEmitter.cpp */; };
+ 507B3AD81C31BDD30067B53E /* CCDrawNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57010C180BC8EE0088DEC7 /* CCDrawNode.cpp */; };
+ 507B3AD91C31BDD30067B53E /* CCGrabber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570117180BC90D0088DEC7 /* CCGrabber.cpp */; };
+ 507B3ADA1C31BDD30067B53E /* ParticleReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823842D1A259112002C4610 /* ParticleReader.cpp */; };
+ 507B3ADC1C31BDD30067B53E /* CCGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570119180BC90D0088DEC7 /* CCGrid.cpp */; };
+ 507B3ADD1C31BDD30067B53E /* CCAnimation3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17E819AAD2F700C27E9E /* CCAnimation3D.cpp */; };
+ 507B3ADF1C31BDD30067B53E /* CCPlane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E9F61241A3FFE3D0038DE01 /* CCPlane.cpp */; };
+ 507B3AE01C31BDD30067B53E /* CCFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570182180BCB590088DEC7 /* CCFont.cpp */; };
+ 507B3AE21C31BDD30067B53E /* CCSpriteFrameCacheHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C597A180E930E00EF57C3 /* CCSpriteFrameCacheHelper.cpp */; };
+ 507B3AE31C31BDD30067B53E /* CCActionManagerEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C594C180E930E00EF57C3 /* CCActionManagerEx.cpp */; };
+ 507B3AE41C31BDD30067B53E /* CCEventListenerAssetsManagerEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15B3707219EE414C00ABE682 /* CCEventListenerAssetsManagerEx.cpp */; };
+ 507B3AE61C31BDD30067B53E /* CCCommon-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8D01926736A00CD74DD /* CCCommon-ios.mm */; };
+ 507B3AE71C31BDD30067B53E /* UIEditBoxImpl-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 292DB13519B4574100A80320 /* UIEditBoxImpl-ios.mm */; };
+ 507B3AE81C31BDD30067B53E /* CCNavMeshObstacle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0C51B18492D006762CB /* CCNavMeshObstacle.cpp */; };
+ 507B3AED1C31BDD30067B53E /* CCComExtensionData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43015DBD1B60DF4000E75161 /* CCComExtensionData.cpp */; };
+ 507B3AF01C31BDD30067B53E /* CCFontAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570184180BCB590088DEC7 /* CCFontAtlas.cpp */; };
+ 507B3AF11C31BDD30067B53E /* CCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E61781C1966A5A300DE83F5 /* CCController.cpp */; };
+ 507B3AF31C31BDD30067B53E /* CCFileUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF231926664700A911A9 /* CCFileUtils.cpp */; };
+ 507B3AF41C31BDD30067B53E /* ccRandom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 299CF1F919A434BC00C378C1 /* ccRandom.cpp */; };
+ 507B3AF51C31BDD30067B53E /* ioapi_mem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA8C62A019E52C6400000516 /* ioapi_mem.cpp */; };
+ 507B3AF61C31BDD30067B53E /* ProjectNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384341A259126002C4610 /* ProjectNodeReader.cpp */; };
+ 507B3AF71C31BDD30067B53E /* CCMenuItemLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D1A180E26E600808F54 /* CCMenuItemLoader.cpp */; };
+ 507B3AF91C31BDD30067B53E /* CCPUDoStopSystemEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1141AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandler.cpp */; };
+ 507B3AFA1C31BDD30067B53E /* base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDC31925AB6E00A911A9 /* base64.cpp */; };
+ 507B3AFB1C31BDD30067B53E /* CCPUOnVelocityObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E18A1AA80A6500DDB1C5 /* CCPUOnVelocityObserverTranslator.cpp */; };
+ 507B3AFC1C31BDD30067B53E /* CCFontAtlasCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570186180BCB590088DEC7 /* CCFontAtlasCache.cpp */; };
+ 507B3AFD1C31BDD30067B53E /* TriggerObj.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06CAAAC0186AD63B0012A414 /* TriggerObj.cpp */; };
+ 507B3AFE1C31BDD30067B53E /* CCPhysics3DConstraint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFD61AF9A9E100B9B856 /* CCPhysics3DConstraint.cpp */; };
+ 507B3AFF1C31BDD30067B53E /* CCNavMeshDebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0C31B18492D006762CB /* CCNavMeshDebugDraw.cpp */; };
+ 507B3B001C31BDD30067B53E /* CCActionTimelineNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D76BE381A4AAF0A00102962 /* CCActionTimelineNode.cpp */; };
+ 507B3B011C31BDD30067B53E /* WidgetReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB9018C72017004AD434 /* WidgetReader.cpp */; };
+ 507B3B021C31BDD30067B53E /* CCPUOnVelocityObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1881AA80A6500DDB1C5 /* CCPUOnVelocityObserver.cpp */; };
+ 507B3B041C31BDD30067B53E /* CCPUObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E15E1AA80A6500DDB1C5 /* CCPUObserverTranslator.cpp */; };
+ 507B3B061C31BDD30067B53E /* CCPUAlignAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D41AA80A6500DDB1C5 /* CCPUAlignAffectorTranslator.cpp */; };
+ 507B3B081C31BDD30067B53E /* CCFontFNT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57018C180BCB590088DEC7 /* CCFontFNT.cpp */; };
+ 507B3B091C31BDD30067B53E /* CCParticle3DAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B68778F01A8CA82E00643ABF /* CCParticle3DAffector.cpp */; };
+ 507B3B0A1C31BDD30067B53E /* CCPUBillboardChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E61AA80A6500DDB1C5 /* CCPUBillboardChain.cpp */; };
+ 507B3B0B1C31BDD30067B53E /* GameNode3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A045F6ED1BA81821005076C7 /* GameNode3DReader.cpp */; };
+ 507B3B0C1C31BDD30067B53E /* CCFontFreeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57018E180BCB590088DEC7 /* CCFontFreeType.cpp */; };
+ 507B3B0D1C31BDD30067B53E /* CCPUTechniqueTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1DA1AA80A6500DDB1C5 /* CCPUTechniqueTranslator.cpp */; };
+ 507B3B0E1C31BDD30067B53E /* ExtensionDeprecated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB15D19B461CA00A80320 /* ExtensionDeprecated.cpp */; };
+ 507B3B0F1C31BDD30067B53E /* ccTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE071925AB6E00A911A9 /* ccTypes.cpp */; };
+ 507B3B101C31BDD30067B53E /* DictionaryHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5989180E930E00EF57C3 /* DictionaryHelper.cpp */; };
+ 507B3B131C31BDD30067B53E /* CCPUDoFreezeEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1081AA80A6500DDB1C5 /* CCPUDoFreezeEventHandler.cpp */; };
+ 507B3B151C31BDD30067B53E /* CCLabel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570190180BCB590088DEC7 /* CCLabel.cpp */; };
+ 507B3B161C31BDD30067B53E /* CCBFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71CFC180E26E600808F54 /* CCBFileLoader.cpp */; };
+ 507B3B181C31BDD30067B53E /* UIRadioButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5CE6DC61B3C05BA002B0419 /* UIRadioButton.cpp */; };
+ 507B3B191C31BDD30067B53E /* CCBAnimationManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71CFA180E26E600808F54 /* CCBAnimationManager.cpp */; };
+ 507B3B1A1C31BDD30067B53E /* UIListView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9FE18CF08D000240AA3 /* UIListView.cpp */; };
+ 507B3B1B1C31BDD30067B53E /* CCLabelAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570192180BCB590088DEC7 /* CCLabelAtlas.cpp */; };
+ 507B3B1C1C31BDD30067B53E /* CCAutoPolygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20721AE7BF8600C31518 /* CCAutoPolygon.cpp */; };
+ 507B3B1D1C31BDD30067B53E /* UIEditBoxImpl-common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0E749F51BA8FD7F001A8332 /* UIEditBoxImpl-common.cpp */; };
+ 507B3B201C31BDD30067B53E /* CCLabelBMFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570194180BCB590088DEC7 /* CCLabelBMFont.cpp */; };
+ 507B3B211C31BDD30067B53E /* edtaa3func.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A087AE61860400400196EF5 /* edtaa3func.cpp */; };
+ 507B3B221C31BDD30067B53E /* CCPUOnEventFlagObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1721AA80A6500DDB1C5 /* CCPUOnEventFlagObserverTranslator.cpp */; };
+ 507B3B231C31BDD30067B53E /* CCColliderDetector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C595E180E930E00EF57C3 /* CCColliderDetector.cpp */; };
+ 507B3B271C31BDD30067B53E /* CCPUParticleFollowerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E18E1AA80A6500DDB1C5 /* CCPUParticleFollowerTranslator.cpp */; };
+ 507B3B291C31BDD30067B53E /* UISlider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0918CF08D000240AA3 /* UISlider.cpp */; };
+ 507B3B2A1C31BDD30067B53E /* DetourNavMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F891B04825B00E47F5F /* DetourNavMesh.cpp */; };
+ 507B3B2B1C31BDD30067B53E /* CCPhysics3DWorld.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFDE1AF9A9E100B9B856 /* CCPhysics3DWorld.cpp */; };
+ 507B3B2C1C31BDD30067B53E /* CCPUOnExpireObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1761AA80A6500DDB1C5 /* CCPUOnExpireObserverTranslator.cpp */; };
+ 507B3B311C31BDD30067B53E /* UILayoutParameter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9FC18CF08D000240AA3 /* UILayoutParameter.cpp */; };
+ 507B3B321C31BDD30067B53E /* SingleNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823843B1A259140002C4610 /* SingleNodeReader.cpp */; };
+ 507B3B351C31BDD30067B53E /* CCPUDynamicAttribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1181AA80A6500DDB1C5 /* CCPUDynamicAttribute.cpp */; };
+ 507B3B371C31BDD30067B53E /* ListViewReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7618C72017004AD434 /* ListViewReader.cpp */; };
+ 507B3B381C31BDD30067B53E /* CCLabelTextFormatter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570197180BCB590088DEC7 /* CCLabelTextFormatter.cpp */; };
+ 507B3B391C31BDD30067B53E /* CCLabelTTF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570199180BCB590088DEC7 /* CCLabelTTF.cpp */; };
+ 507B3B3A1C31BDD30067B53E /* CCNinePatchImageParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 291901421B05895600F8B4BA /* CCNinePatchImageParser.cpp */; };
+ 507B3B3B1C31BDD30067B53E /* CCPUPointEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A01AA80A6500DDB1C5 /* CCPUPointEmitterTranslator.cpp */; };
+ 507B3B3C1C31BDD30067B53E /* NodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 382384261A2590F9002C4610 /* NodeReader.cpp */; };
+ 507B3B3D1C31BDD30067B53E /* CCActionObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5950180E930E00EF57C3 /* CCActionObject.cpp */; };
+ 507B3B3E1C31BDD30067B53E /* CCPUTextureAnimatorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1DE1AA80A6500DDB1C5 /* CCPUTextureAnimatorTranslator.cpp */; };
+ 507B3B3F1C31BDD30067B53E /* cdt.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20811AE7C57D00C31518 /* cdt.cc */; };
+ 507B3B401C31BDD30067B53E /* CCPUOnPositionObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1781AA80A6500DDB1C5 /* CCPUOnPositionObserver.cpp */; };
+ 507B3B421C31BDD30067B53E /* CCSkinNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306671B60B583001E6D43 /* CCSkinNode.cpp */; };
+ 507B3B441C31BDD30067B53E /* ObjectFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 299754F2193EC95400A54AC3 /* ObjectFactory.cpp */; };
+ 507B3B451C31BDD30067B53E /* CCLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701D4180BCB8C0088DEC7 /* CCLayer.cpp */; };
+ 507B3B471C31BDD30067B53E /* CCTextureCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD811925AB4100A911A9 /* CCTextureCache.cpp */; };
+ 507B3B481C31BDD30067B53E /* CCPUMaterialManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1501AA80A6500DDB1C5 /* CCPUMaterialManager.cpp */; };
+ 507B3B491C31BDD30067B53E /* CCScene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701D6180BCB8C0088DEC7 /* CCScene.cpp */; };
+ 507B3B4A1C31BDD30067B53E /* Vec4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD351925AB0000A911A9 /* Vec4.cpp */; };
+ 507B3B4B1C31BDD30067B53E /* CCBillBoard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B60C5BD219AC68B10056FBDE /* CCBillBoard.cpp */; };
+ 507B3B4C1C31BDD30067B53E /* Particle3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18956BB01A9DFBFD006E9155 /* Particle3DReader.cpp */; };
+ 507B3B4D1C31BDD30067B53E /* CCSprite3DMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE180319AAD2F700C27E9E /* CCSprite3DMaterial.cpp */; };
+ 507B3B4E1C31BDD30067B53E /* ccGLStateCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD701925AB4100A911A9 /* ccGLStateCache.cpp */; };
+ 507B3B501C31BDD30067B53E /* CCPUDoEnableComponentEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1021AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandlerTranslator.cpp */; };
+ 507B3B511C31BDD30067B53E /* CCTransition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701D8180BCB8C0088DEC7 /* CCTransition.cpp */; };
+ 507B3B531C31BDD30067B53E /* CCEventAssetsManagerEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15B3707019EE414C00ABE682 /* CCEventAssetsManagerEx.cpp */; };
+ 507B3B541C31BDD30067B53E /* UIWebView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29394CED19B01DBA00D2DE1A /* UIWebView.mm */; };
+ 507B3B551C31BDD30067B53E /* CCLabelBMFontLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D0E180E26E600808F54 /* CCLabelBMFontLoader.cpp */; };
+ 507B3B571C31BDD30067B53E /* CCPUCollisionAvoidanceAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F61AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffectorTranslator.cpp */; };
+ 507B3B581C31BDD30067B53E /* CCThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF2B1926664700A911A9 /* CCThread.cpp */; };
+ 507B3B591C31BDD30067B53E /* CCUISingleLineTextField.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2980F01C1BA9A5550059E678 /* CCUISingleLineTextField.mm */; };
+ 507B3B5B1C31BDD30067B53E /* CCTransitionPageTurn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701DA180BCB8C0088DEC7 /* CCTransitionPageTurn.cpp */; };
+ 507B3B5D1C31BDD30067B53E /* CCPUOnPositionObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E17A1AA80A6500DDB1C5 /* CCPUOnPositionObserverTranslator.cpp */; };
+ 507B3B5E1C31BDD30067B53E /* CCTransitionProgress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701DC180BCB8C0088DEC7 /* CCTransitionProgress.cpp */; };
+ 507B3B5F1C31BDD30067B53E /* CCSkybox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6D38B861AC3AFAC00043997 /* CCSkybox.cpp */; };
+ 507B3B601C31BDD30067B53E /* CCFrameBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B240C5E71B09DFB000137F50 /* CCFrameBuffer.cpp */; };
+ 507B3B611C31BDD30067B53E /* CCMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701F3180BCBAD0088DEC7 /* CCMenu.cpp */; };
+ 507B3B621C31BDD30067B53E /* NodeReaderProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823840D1A259092002C4610 /* NodeReaderProtocol.cpp */; };
+ 507B3B631C31BDD30067B53E /* Quaternion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD2A1925AB0000A911A9 /* Quaternion.cpp */; };
+ 507B3B641C31BDD30067B53E /* CCMenuItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5701F5180BCBAD0088DEC7 /* CCMenuItem.cpp */; };
+ 507B3B651C31BDD30067B53E /* CCProperties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 505385011B01887A00793096 /* CCProperties.cpp */; };
+ 507B3B671C31BDD30067B53E /* CCPUEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1261AA80A6500DDB1C5 /* CCPUEventHandlerTranslator.cpp */; };
+ 507B3B691C31BDD30067B53E /* CCDecorativeDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C596C180E930E00EF57C3 /* CCDecorativeDisplay.cpp */; };
+ 507B3B6A1C31BDD30067B53E /* TextReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8E18C72017004AD434 /* TextReader.cpp */; };
+ 507B3B6B1C31BDD30067B53E /* Mat4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD231925AB0000A911A9 /* Mat4.cpp */; };
+ 507B3B6C1C31BDD30067B53E /* CCClippingNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570200180BCBD40088DEC7 /* CCClippingNode.cpp */; };
+ 507B3B6D1C31BDD30067B53E /* UIButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F018CF08D000240AA3 /* UIButton.cpp */; };
+ 507B3B6E1C31BDD30067B53E /* CCMotionStreak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570206180BCBDF0088DEC7 /* CCMotionStreak.cpp */; };
+ 507B3B6F1C31BDD30067B53E /* CCProgressTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57020C180BCBF40088DEC7 /* CCProgressTimer.cpp */; };
+ 507B3B701C31BDD30067B53E /* CCArmatureAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5954180E930E00EF57C3 /* CCArmatureAnimation.cpp */; };
+ 507B3B711C31BDD30067B53E /* CCGLViewImpl-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8DB1926736A00CD74DD /* CCGLViewImpl-ios.mm */; };
+ 507B3B721C31BDD30067B53E /* CCActionTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0634A4C5194B19E400E608AF /* CCActionTimeline.cpp */; };
+ 507B3B731C31BDD30067B53E /* TextAtlasReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8518C72017004AD434 /* TextAtlasReader.cpp */; };
+ 507B3B741C31BDD30067B53E /* DebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F7A1B04825B00E47F5F /* DebugDraw.cpp */; };
+ 507B3B751C31BDD30067B53E /* CCPUEventHandlerManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1241AA80A6500DDB1C5 /* CCPUEventHandlerManager.cpp */; };
+ 507B3B771C31BDD30067B53E /* CCBone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C595C180E930E00EF57C3 /* CCBone.cpp */; };
+ 507B3B781C31BDD30067B53E /* CCRenderTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57020E180BCBF40088DEC7 /* CCRenderTexture.cpp */; };
+ 507B3B7A1C31BDD30067B53E /* CCParticleBatchNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570219180BCC1A0088DEC7 /* CCParticleBatchNode.cpp */; };
+ 507B3B7B1C31BDD30067B53E /* UIEditBoxImpl-stub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB13819B4574100A80320 /* UIEditBoxImpl-stub.cpp */; };
+ 507B3B7C1C31BDD30067B53E /* CCPUDoEnableComponentEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1001AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandler.cpp */; };
+ 507B3B7D1C31BDD30067B53E /* CCPUOnExpireObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1741AA80A6500DDB1C5 /* CCPUOnExpireObserver.cpp */; };
+ 507B3B7E1C31BDD30067B53E /* SimpleAudioEngine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FEB1807A56F005B8026 /* SimpleAudioEngine.mm */; };
+ 507B3B801C31BDD30067B53E /* CCControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168351807AF4E005B8026 /* CCControl.cpp */; };
+ 507B3B821C31BDD30067B53E /* CCParticleExamples.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57021B180BCC1A0088DEC7 /* CCParticleExamples.cpp */; };
+ 507B3B841C31BDD30067B53E /* CCComController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5964180E930E00EF57C3 /* CCComController.cpp */; };
+ 507B3B851C31BDD30067B53E /* CCTerrain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B603F1A61AC8EA0900A9579C /* CCTerrain.cpp */; };
+ 507B3B861C31BDD30067B53E /* CCPUScriptCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1BA1AA80A6500DDB1C5 /* CCPUScriptCompiler.cpp */; };
+ 507B3B871C31BDD30067B53E /* CCParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57021D180BCC1A0088DEC7 /* CCParticleSystem.cpp */; };
+ 507B3B881C31BDD30067B53E /* CCMeshSkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F519AAD2F700C27E9E /* CCMeshSkin.cpp */; };
+ 507B3B891C31BDD30067B53E /* CCCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EACC99C19F5014D00EB3C5E /* CCCamera.cpp */; };
+ 507B3B8A1C31BDD30067B53E /* CCPUSineForceAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C61AA80A6500DDB1C5 /* CCPUSineForceAffectorTranslator.cpp */; };
+ 507B3B8B1C31BDD30067B53E /* SocketIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF5366180E3374000584C8 /* SocketIO.cpp */; };
+ 507B3B8F1C31BDD30067B53E /* DetourNavMeshBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F8B1B04825B00E47F5F /* DetourNavMeshBuilder.cpp */; };
+ 507B3B901C31BDD30067B53E /* CCPUVelocityMatchingAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E81AA80A6500DDB1C5 /* CCPUVelocityMatchingAffector.cpp */; };
+ 507B3B911C31BDD30067B53E /* CCPUOnEmissionObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E16E1AA80A6500DDB1C5 /* CCPUOnEmissionObserverTranslator.cpp */; };
+ 507B3B921C31BDD30067B53E /* TextBMFontReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8818C72017004AD434 /* TextBMFontReader.cpp */; };
+ 507B3B931C31BDD30067B53E /* DetourCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F861B04825B00E47F5F /* DetourCommon.cpp */; };
+ 507B3B941C31BDD30067B53E /* CCInvocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A1684A1807AF4E005B8026 /* CCInvocation.cpp */; };
+ 507B3B951C31BDD30067B53E /* CCFastTMXTiledMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B24AA983195A675C007B4522 /* CCFastTMXTiledMap.cpp */; };
+ 507B3B961C31BDD30067B53E /* ArmatureNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38F5263B1A48363B000DB7F7 /* ArmatureNodeReader.cpp */; };
+ 507B3B981C31BDD30067B53E /* CCPUFlockCenteringAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1281AA80A6500DDB1C5 /* CCPUFlockCenteringAffector.cpp */; };
+ 507B3B991C31BDD30067B53E /* CCPUOnTimeObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1861AA80A6500DDB1C5 /* CCPUOnTimeObserverTranslator.cpp */; };
+ 507B3B9A1C31BDD30067B53E /* CCPUDoScaleEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1101AA80A6500DDB1C5 /* CCPUDoScaleEventHandler.cpp */; };
+ 507B3B9B1C31BDD30067B53E /* CCNodeLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D1F180E26E600808F54 /* CCNodeLoader.cpp */; };
+ 507B3B9C1C31BDD30067B53E /* CCPUVelocityMatchingAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1EA1AA80A6500DDB1C5 /* CCPUVelocityMatchingAffectorTranslator.cpp */; };
+ 507B3B9D1C31BDD30067B53E /* WidgetCallBackHandlerProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38ACD1FA1A27111900C3093D /* WidgetCallBackHandlerProtocol.cpp */; };
+ 507B3B9E1C31BDD30067B53E /* UIWebViewImpl-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29394CEF19B01DBA00D2DE1A /* UIWebViewImpl-ios.mm */; };
+ 507B3B9F1C31BDD30067B53E /* CCPUGeometryRotatorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1341AA80A6500DDB1C5 /* CCPUGeometryRotatorTranslator.cpp */; };
+ 507B3BA31C31BDD30067B53E /* CCFastTMXLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B24AA981195A675C007B4522 /* CCFastTMXLayer.cpp */; };
+ 507B3BA41C31BDD30067B53E /* CCParticleSystemQuad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57021F180BCC1A0088DEC7 /* CCParticleSystemQuad.cpp */; };
+ 507B3BA51C31BDD30067B53E /* CCGLProgramCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD6A1925AB4100A911A9 /* CCGLProgramCache.cpp */; };
+ 507B3BA61C31BDD30067B53E /* CCTimeLine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0634A4CD194B19E400E608AF /* CCTimeLine.cpp */; };
+ 507B3BA91C31BDD30067B53E /* CCSprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570276180BCC900088DEC7 /* CCSprite.cpp */; };
+ 507B3BAB1C31BDD30067B53E /* CCPUColorAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0FA1AA80A6500DDB1C5 /* CCPUColorAffectorTranslator.cpp */; };
+ 507B3BAC1C31BDD30067B53E /* CCComAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5962180E930E00EF57C3 /* CCComAudio.cpp */; };
+ 507B3BAD1C31BDD30067B53E /* TriggerBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06CAAABC186AD63B0012A414 /* TriggerBase.cpp */; };
+ 507B3BAE1C31BDD30067B53E /* UICheckBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F218CF08D000240AA3 /* UICheckBox.cpp */; };
+ 507B3BB11C31BDD30067B53E /* CCPUOnCollisionObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1641AA80A6500DDB1C5 /* CCPUOnCollisionObserver.cpp */; };
+ 507B3BB21C31BDD30067B53E /* CCPUOnCollisionObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1661AA80A6500DDB1C5 /* CCPUOnCollisionObserverTranslator.cpp */; };
+ 507B3BB31C31BDD30067B53E /* CCBSequence.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D04180E26E600808F54 /* CCBSequence.cpp */; };
+ 507B3BB41C31BDD30067B53E /* CCPUScaleAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B41AA80A6500DDB1C5 /* CCPUScaleAffectorTranslator.cpp */; };
+ 507B3BB51C31BDD30067B53E /* CCPUDoExpireEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1041AA80A6500DDB1C5 /* CCPUDoExpireEventHandler.cpp */; };
+ 507B3BB81C31BDD30067B53E /* CCSpriteBatchNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570278180BCC900088DEC7 /* CCSpriteBatchNode.cpp */; };
+ 507B3BBA1C31BDD30067B53E /* CCPUListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E14E1AA80A6500DDB1C5 /* CCPUListener.cpp */; };
+ 507B3BBB1C31BDD30067B53E /* CCSpriteFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57027A180BCC900088DEC7 /* CCSpriteFrame.cpp */; };
+ 507B3BBC1C31BDD30067B53E /* HttpConnection-winrt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 507003191B69735200E83DDD /* HttpConnection-winrt.cpp */; };
+ 507B3BBE1C31BDD30067B53E /* UITextField+CCUITextInput.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2980F01F1BA9A5550059E678 /* UITextField+CCUITextInput.mm */; };
+ 507B3BBF1C31BDD30067B53E /* CCPUCollisionAvoidanceAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F41AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffector.cpp */; };
+ 507B3BC11C31BDD30067B53E /* CCPUSlaveBehaviour.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C81AA80A6500DDB1C5 /* CCPUSlaveBehaviour.cpp */; };
+ 507B3BC21C31BDD30067B53E /* CCPUDoPlacementParticleEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E10E1AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandlerTranslator.cpp */; };
+ 507B3BC31C31BDD30067B53E /* CCBatchNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C595A180E930E00EF57C3 /* CCBatchNode.cpp */; };
+ 507B3BC41C31BDD30067B53E /* CDAudioManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A15FE51807A56F005B8026 /* CDAudioManager.m */; };
+ 507B3BC51C31BDD30067B53E /* CCSpriteFrameCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57027C180BCC900088DEC7 /* CCSpriteFrameCache.cpp */; };
+ 507B3BC61C31BDD30067B53E /* sweep_context.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20851AE7C57D00C31518 /* sweep_context.cc */; };
+ 507B3BC71C31BDD30067B53E /* CCPUSineForceAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C41AA80A6500DDB1C5 /* CCPUSineForceAffector.cpp */; };
+ 507B3BC81C31BDD30067B53E /* CCAnimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57028E180BCCAB0088DEC7 /* CCAnimation.cpp */; };
+ 507B3BCA1C31BDD30067B53E /* CCDataReaderHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5968180E930E00EF57C3 /* CCDataReaderHelper.cpp */; };
+ 507B3BCB1C31BDD30067B53E /* CCVertexAttribBinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5053850A1B02819E00793096 /* CCVertexAttribBinding.cpp */; };
+ 507B3BCC1C31BDD30067B53E /* advancing_front.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB207F1AE7C57D00C31518 /* advancing_front.cc */; };
+ 507B3BCD1C31BDD30067B53E /* UIScale9Sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2958244919873D8E00F9746D /* UIScale9Sprite.cpp */; };
+ 507B3BCE1C31BDD30067B53E /* PageViewReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7C18C72017004AD434 /* PageViewReader.cpp */; };
+ 507B3BCF1C31BDD30067B53E /* CCParticle3DEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B68778F21A8CA82E00643ABF /* CCParticle3DEmitter.cpp */; };
+ 507B3BD01C31BDD30067B53E /* CCAnimationCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570290180BCCAB0088DEC7 /* CCAnimationCache.cpp */; };
+ 507B3BD11C31BDD30067B53E /* CCPUSphereColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D41AA80A6500DDB1C5 /* CCPUSphereColliderTranslator.cpp */; };
+ 507B3BD21C31BDD30067B53E /* CCConfiguration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDCA1925AB6E00A911A9 /* CCConfiguration.cpp */; };
+ 507B3BD61C31BDD30067B53E /* CCTextFieldTTF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702C6180BCE370088DEC7 /* CCTextFieldTTF.cpp */; };
+ 507B3BD71C31BDD30067B53E /* CCPhysicsSprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71EEE180E27CF00808F54 /* CCPhysicsSprite.cpp */; };
+ 507B3BD81C31BDD30067B53E /* CCTileMapAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E0180BCE750088DEC7 /* CCTileMapAtlas.cpp */; };
+ 507B3BD91C31BDD30067B53E /* CCPUTextureAnimator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1DC1AA80A6500DDB1C5 /* CCPUTextureAnimator.cpp */; };
+ 507B3BDA1C31BDD30067B53E /* CCTMXLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E2180BCE750088DEC7 /* CCTMXLayer.cpp */; };
+ 507B3BDB1C31BDD30067B53E /* UIHBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50E6D32E18E174130051CA34 /* UIHBox.cpp */; };
+ 507B3BDD1C31BDD30067B53E /* CCPUScriptTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C01AA80A6500DDB1C5 /* CCPUScriptTranslator.cpp */; };
+ 507B3BDE1C31BDD30067B53E /* CCPUOnEventFlagObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1701AA80A6500DDB1C5 /* CCPUOnEventFlagObserver.cpp */; };
+ 507B3BDF1C31BDD30067B53E /* CCMotionStreak3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E2A09C01BAA91B70086B878 /* CCMotionStreak3D.cpp */; };
+ 507B3BE01C31BDD30067B53E /* CCTMXObjectGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E4180BCE750088DEC7 /* CCTMXObjectGroup.cpp */; };
+ 507B3BE11C31BDD30067B53E /* GameMapReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823841F1A2590DA002C4610 /* GameMapReader.cpp */; };
+ 507B3BE21C31BDD30067B53E /* UILayoutManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29CB8F4A1929D1BB00C841D6 /* UILayoutManager.cpp */; };
+ 507B3BE31C31BDD30067B53E /* CCBundleReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F119AAD2F700C27E9E /* CCBundleReader.cpp */; };
+ 507B3BE41C31BDD30067B53E /* CCPUForceFieldAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E12E1AA80A6500DDB1C5 /* CCPUForceFieldAffector.cpp */; };
+ 507B3BE51C31BDD30067B53E /* CCGeometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD1D1925AB0000A911A9 /* CCGeometry.cpp */; };
+ 507B3BE61C31BDD30067B53E /* CCPUNoise.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1581AA80A6500DDB1C5 /* CCPUNoise.cpp */; };
+ 507B3BE71C31BDD30067B53E /* CCPUDoFreezeEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E10A1AA80A6500DDB1C5 /* CCPUDoFreezeEventHandlerTranslator.cpp */; };
+ 507B3BE91C31BDD30067B53E /* CCSpriteLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D2A180E26E600808F54 /* CCSpriteLoader.cpp */; };
+ 507B3BEA1C31BDD30067B53E /* s3tc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE171925AB6F00A911A9 /* s3tc.cpp */; };
+ 507B3BEB1C31BDD30067B53E /* UIRichText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0418CF08D000240AA3 /* UIRichText.cpp */; };
+ 507B3BED1C31BDD30067B53E /* CCSkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5978180E930E00EF57C3 /* CCSkin.cpp */; };
+ 507B3BEE1C31BDD30067B53E /* CCPUJetAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1401AA80A6500DDB1C5 /* CCPUJetAffectorTranslator.cpp */; };
+ 507B3BF31C31BDD30067B53E /* CCTMXTiledMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E6180BCE750088DEC7 /* CCTMXTiledMap.cpp */; };
+ 507B3BF41C31BDD30067B53E /* etc1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE141925AB6F00A911A9 /* etc1.cpp */; };
+ 507B3BF51C31BDD30067B53E /* CCNS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDF71925AB6E00A911A9 /* CCNS.cpp */; };
+ 507B3BF61C31BDD30067B53E /* DetourDebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F7C1B04825B00E47F5F /* DetourDebugDraw.cpp */; };
+ 507B3BFB1C31BDD30067B53E /* SkeletonNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306731B60B5B2001E6D43 /* SkeletonNodeReader.cpp */; };
+ 507B3BFC1C31BDD30067B53E /* CCAllocatorGlobal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0FD033E1A3B51AA00825BB5 /* CCAllocatorGlobal.cpp */; };
+ 507B3BFD1C31BDD30067B53E /* CCPUBehaviourTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E41AA80A6500DDB1C5 /* CCPUBehaviourTranslator.cpp */; };
+ 507B3BFE1C31BDD30067B53E /* CCPUScriptParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1BE1AA80A6500DDB1C5 /* CCPUScriptParser.cpp */; };
+ 507B3BFF1C31BDD30067B53E /* CCPUBoxEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0EC1AA80A6500DDB1C5 /* CCPUBoxEmitter.cpp */; };
+ 507B3C001C31BDD30067B53E /* UIVBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50E6D33218E174130051CA34 /* UIVBox.cpp */; };
+ 507B3C021C31BDD30067B53E /* CCRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD791925AB4100A911A9 /* CCRenderer.cpp */; };
+ 507B3C031C31BDD30067B53E /* CCPURender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1AA1AA80A6500DDB1C5 /* CCPURender.cpp */; };
+ 507B3C051C31BDD30067B53E /* CCPULineEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E14A1AA80A6500DDB1C5 /* CCPULineEmitter.cpp */; };
+ 507B3C071C31BDD30067B53E /* CocoStudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38D9629C1ACA9721007C6FAF /* CocoStudio.cpp */; };
+ 507B3C081C31BDD30067B53E /* CCTextureAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD7F1925AB4100A911A9 /* CCTextureAtlas.cpp */; };
+ 507B3C091C31BDD30067B53E /* CCTMXXMLParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702E8180BCE750088DEC7 /* CCTMXXMLParser.cpp */; };
+ 507B3C0A1C31BDD30067B53E /* CCPUSphereSurfaceEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D81AA80A6500DDB1C5 /* CCPUSphereSurfaceEmitterTranslator.cpp */; };
+ 507B3C0B1C31BDD30067B53E /* CCParallaxNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5702FE180BCE890088DEC7 /* CCParallaxNode.cpp */; };
+ 507B3C0C1C31BDD30067B53E /* CCPUAlignAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D21AA80A6500DDB1C5 /* CCPUAlignAffector.cpp */; };
+ 507B3C0F1C31BDD30067B53E /* CCComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570308180BCF190088DEC7 /* CCComponent.cpp */; };
+ 507B3C101C31BDD30067B53E /* UIDeprecated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29BDBA52195D597A003225C9 /* UIDeprecated.cpp */; };
+ 507B3C121C31BDD30067B53E /* pvr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 464AD6E3197EBB1400E502D8 /* pvr.cpp */; };
+ 507B3C131C31BDD30067B53E /* CCFrustum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E9F61221A3FFE3D0038DE01 /* CCFrustum.cpp */; };
+ 507B3C141C31BDD30067B53E /* CCPUBoxCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E81AA80A6500DDB1C5 /* CCPUBoxCollider.cpp */; };
+ 507B3C151C31BDD30067B53E /* CCPUMeshSurfaceEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1541AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitter.cpp */; };
+ 507B3C161C31BDD30067B53E /* CCPUOnQuotaObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E17E1AA80A6500DDB1C5 /* CCPUOnQuotaObserverTranslator.cpp */; };
+ 507B3C171C31BDD30067B53E /* UIPageView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0218CF08D000240AA3 /* UIPageView.cpp */; };
+ 507B3C181C31BDD30067B53E /* CCComponentContainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A57030A180BCF190088DEC7 /* CCComponentContainer.cpp */; };
+ 507B3C191C31BDD30067B53E /* ccCArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDC71925AB6E00A911A9 /* ccCArray.cpp */; };
+ 507B3C1A1C31BDD30067B53E /* CCActionNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C594E180E930E00EF57C3 /* CCActionNode.cpp */; };
+ 507B3C1B1C31BDD30067B53E /* CCDisplayFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C596E180E930E00EF57C3 /* CCDisplayFactory.cpp */; };
+ 507B3C1C1C31BDD30067B53E /* Sprite3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 182C5CD41A98F30500C30D34 /* Sprite3DReader.cpp */; };
+ 507B3C1D1C31BDD30067B53E /* CCThread-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF1F1926664700A911A9 /* CCThread-apple.mm */; };
+ 507B3C1E1C31BDD30067B53E /* UIAbstractCheckButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5CE6DBC1B3BF2B1002B0419 /* UIAbstractCheckButton.cpp */; };
+ 507B3C201C31BDD30067B53E /* CCUserDefault-android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE0C1925AB6F00A911A9 /* CCUserDefault-android.cpp */; };
+ 507B3C221C31BDD30067B53E /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570349180BD09B0088DEC7 /* tinyxml2.cpp */; };
+ 507B3C231C31BDD30067B53E /* CCTexture2D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD7D1925AB4100A911A9 /* CCTexture2D.cpp */; };
+ 507B3C241C31BDD30067B53E /* CCPUDoStopSystemEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1161AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandlerTranslator.cpp */; };
+ 507B3C251C31BDD30067B53E /* UILayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F818CF08D000240AA3 /* UILayout.cpp */; };
+ 507B3C261C31BDD30067B53E /* ioapi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570350180BD0B00088DEC7 /* ioapi.cpp */; };
+ 507B3C271C31BDD30067B53E /* CCPUMeshSurfaceEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1561AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitterTranslator.cpp */; };
+ 507B3C281C31BDD30067B53E /* CCPUForceField.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E12C1AA80A6500DDB1C5 /* CCPUForceField.cpp */; };
+ 507B3C291C31BDD30067B53E /* unzip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A570352180BD0B00088DEC7 /* unzip.cpp */; };
+ 507B3C2A1C31BDD30067B53E /* CCControlLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D0C180E26E600808F54 /* CCControlLoader.cpp */; };
+ 507B3C2B1C31BDD30067B53E /* TextFieldReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB8B18C72017004AD434 /* TextFieldReader.cpp */; };
+ 507B3C2C1C31BDD30067B53E /* CCPUEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1201AA80A6500DDB1C5 /* CCPUEmitterTranslator.cpp */; };
+ 507B3C2D1C31BDD30067B53E /* NodeReaderDefine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3823840B1A259092002C4610 /* NodeReaderDefine.cpp */; };
+ 507B3C2E1C31BDD30067B53E /* CCSGUIReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5976180E930E00EF57C3 /* CCSGUIReader.cpp */; };
+ 507B3C2F1C31BDD30067B53E /* CCCustomCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD661925AB4100A911A9 /* CCCustomCommand.cpp */; };
+ 507B3C311C31BDD30067B53E /* ScrollViewReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7F18C72017004AD434 /* ScrollViewReader.cpp */; };
+ 507B3C321C31BDD30067B53E /* UITextView+CCUITextInput.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2980F0211BA9A5550059E678 /* UITextView+CCUITextInput.mm */; };
+ 507B3C331C31BDD30067B53E /* CCSkeletonNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306651B60B583001E6D43 /* CCSkeletonNode.cpp */; };
+ 507B3C341C31BDD30067B53E /* CCProfiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDFB1925AB6E00A911A9 /* CCProfiling.cpp */; };
+ 507B3C351C31BDD30067B53E /* CCTechnique.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 501216981AC473A3009A4BEA /* CCTechnique.cpp */; };
+ 507B3C361C31BDD30067B53E /* CCMeshVertexIndexData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17F719AAD2F700C27E9E /* CCMeshVertexIndexData.cpp */; };
+ 507B3C371C31BDD30067B53E /* CCEventListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE01925AB6E00A911A9 /* CCEventListener.cpp */; };
+ 507B3C381C31BDD30067B53E /* CCRenderState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5012168C1AC47380009A4BEA /* CCRenderState.cpp */; };
+ 507B3C391C31BDD30067B53E /* AssetsManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF5351180E3060000584C8 /* AssetsManager.cpp */; };
+ 507B3C3B1C31BDD30067B53E /* CCTouch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE051925AB6E00A911A9 /* CCTouch.cpp */; };
+ 507B3C3E1C31BDD30067B53E /* CCPUParticleSystem3DTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1921AA80A6500DDB1C5 /* CCPUParticleSystem3DTranslator.cpp */; };
+ 507B3C401C31BDD30067B53E /* CCES2Renderer-ios.m in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8D71926736A00CD74DD /* CCES2Renderer-ios.m */; };
+ 507B3C411C31BDD30067B53E /* cocos2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50272539190BF1B900AAF4ED /* cocos2d.cpp */; };
+ 507B3C461C31BDD30067B53E /* CCRay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17FD19AAD2F700C27E9E /* CCRay.cpp */; };
+ 507B3C471C31BDD30067B53E /* UITextBMFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0F18CF08D100240AA3 /* UITextBMFont.cpp */; };
+ 507B3C491C31BDD30067B53E /* CCEventListenerFocus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE61925AB6E00A911A9 /* CCEventListenerFocus.cpp */; };
+ 507B3C4B1C31BDD30067B53E /* CCEventListenerCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE41925AB6E00A911A9 /* CCEventListenerCustom.cpp */; };
+ 507B3C4C1C31BDD30067B53E /* CCIMEDispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8F31926B0DB00CD74DD /* CCIMEDispatcher.cpp */; };
+ 507B3C4D1C31BDD30067B53E /* ccShaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD7B1925AB4100A911A9 /* ccShaders.cpp */; };
+ 507B3C4E1C31BDD30067B53E /* CCVertex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD211925AB0000A911A9 /* CCVertex.cpp */; };
+ 507B3C4F1C31BDD30067B53E /* CCUserDefault.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE091925AB6E00A911A9 /* CCUserDefault.cpp */; };
+ 507B3C511C31BDD30067B53E /* CCEventDispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDDA1925AB6E00A911A9 /* CCEventDispatcher.cpp */; };
+ 507B3C521C31BDD30067B53E /* CCTextureCube.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A045F6D41BA81577005076C7 /* CCTextureCube.cpp */; };
+ 507B3C551C31BDD30067B53E /* HttpAsynConnection-apple.m in Sources */ = {isa = PBXBuildFile; fileRef = 52B47A2A1A5349A3004E4C60 /* HttpAsynConnection-apple.m */; };
+ 507B3C561C31BDD30067B53E /* RecastDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F801B04825B00E47F5F /* RecastDump.cpp */; };
+ 507B3C571C31BDD30067B53E /* CCPUCircleEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F01AA80A6500DDB1C5 /* CCPUCircleEmitter.cpp */; };
+ 507B3C581C31BDD30067B53E /* UITextAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0D18CF08D100240AA3 /* UITextAtlas.cpp */; };
+ 507B3C591C31BDD30067B53E /* CCProcessBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5974180E930E00EF57C3 /* CCProcessBase.cpp */; };
+ 507B3C5A1C31BDD30067B53E /* DetourAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F831B04825B00E47F5F /* DetourAlloc.cpp */; };
+ 507B3C5B1C31BDD30067B53E /* CCPUSphereCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D21AA80A6500DDB1C5 /* CCPUSphereCollider.cpp */; };
+ 507B3C5C1C31BDD30067B53E /* CCParticleSystemQuadLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D24180E26E600808F54 /* CCParticleSystemQuadLoader.cpp */; };
+ 507B3C601C31BDD30067B53E /* CCPUBoxEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0EE1AA80A6500DDB1C5 /* CCPUBoxEmitterTranslator.cpp */; };
+ 507B3C611C31BDD30067B53E /* CCTransformHelp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C597E180E930E00EF57C3 /* CCTransformHelp.cpp */; };
+ 507B3C631C31BDD30067B53E /* LayoutReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50FCEB7318C72017004AD434 /* LayoutReader.cpp */; };
+ 507B3C641C31BDD30067B53E /* CCDeprecated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C67918F57BE800EFE3A6 /* CCDeprecated.cpp */; };
+ 507B3C651C31BDD30067B53E /* CCInputDelegate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5972180E930E00EF57C3 /* CCInputDelegate.cpp */; };
+ 507B3C671C31BDD30067B53E /* UIImageView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9F618CF08D000240AA3 /* UIImageView.cpp */; };
+ 507B3C681C31BDD30067B53E /* DetourCrowd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F931B04825B00E47F5F /* DetourCrowd.cpp */; };
+ 507B3C691C31BDD30067B53E /* CCAffineTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD1B1925AB0000A911A9 /* CCAffineTransform.cpp */; };
+ 507B3C6C1C31BDD30067B53E /* CCPUPathFollower.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1941AA80A6500DDB1C5 /* CCPUPathFollower.cpp */; };
+ 507B3C6D1C31BDD30067B53E /* CCPhysicsDebugNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71EEC180E27CF00808F54 /* CCPhysicsDebugNode.cpp */; };
+ 507B3C701C31BDD30067B53E /* CCBatchCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD641925AB4100A911A9 /* CCBatchCommand.cpp */; };
+ 507B3C711C31BDD30067B53E /* CCPUBeamRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0DE1AA80A6500DDB1C5 /* CCPUBeamRender.cpp */; };
+ 507B3C721C31BDD30067B53E /* CCRenderCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD761925AB4100A911A9 /* CCRenderCommand.cpp */; };
+ 507B3C731C31BDD30067B53E /* CCPUAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D01AA80A6500DDB1C5 /* CCPUAffectorTranslator.cpp */; };
+ 507B3C741C31BDD30067B53E /* CCPUPlaneColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E19C1AA80A6500DDB1C5 /* CCPUPlaneColliderTranslator.cpp */; };
+ 507B3C761C31BDD30067B53E /* UIPageViewIndicator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5A738941BB0051F00BAAEF8 /* UIPageViewIndicator.cpp */; };
+ 507B3C771C31BDD30067B53E /* CCPUColorAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F81AA80A6500DDB1C5 /* CCPUColorAffector.cpp */; };
+ 507B3C781C31BDD30067B53E /* CCPUBaseForceAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0DA1AA80A6500DDB1C5 /* CCPUBaseForceAffector.cpp */; };
+ 507B3C791C31BDD30067B53E /* UILoadingBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905FA0018CF08D000240AA3 /* UILoadingBar.cpp */; };
+ 507B3C7A1C31BDD30067B53E /* CCScriptSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE031925AB6E00A911A9 /* CCScriptSupport.cpp */; };
+ 507B3C7C1C31BDD30067B53E /* BoneNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306701B60B5B2001E6D43 /* BoneNodeReader.cpp */; };
+ 507B3C7D1C31BDD30067B53E /* CCMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5012169E1AC473AD009A4BEA /* CCMaterial.cpp */; };
+ 507B3C7E1C31BDD30067B53E /* CCPUPointEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E19E1AA80A6500DDB1C5 /* CCPUPointEmitter.cpp */; };
+ 507B3C811C31BDD30067B53E /* CCEventListenerController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E6176631960F89B00DE83F5 /* CCEventListenerController.cpp */; };
+ 507B3C831C31BDD30067B53E /* CCEAGLView-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8D51926736A00CD74DD /* CCEAGLView-ios.mm */; };
+ 507B3C841C31BDD30067B53E /* AudioEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E2BDAEB19C0436F0055CDCD /* AudioEngine.cpp */; };
+ 507B3C861C31BDD30067B53E /* HttpCookie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B47A2C1A5349A3004E4C60 /* HttpCookie.cpp */; };
+ 507B3C871C31BDD30067B53E /* AssetsManagerEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15B3706E19EE414C00ABE682 /* AssetsManagerEx.cpp */; };
+ 507B3C881C31BDD30067B53E /* CCQuadCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD741925AB4100A911A9 /* CCQuadCommand.cpp */; };
+ 507B3C8A1C31BDD30067B53E /* CCLayerGradientLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D14180E26E600808F54 /* CCLayerGradientLoader.cpp */; };
+ 507B3C8C1C31BDD30067B53E /* CCActionTimelineCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0634A4C7194B19E400E608AF /* CCActionTimelineCache.cpp */; };
+ 507B3C8D1C31BDD30067B53E /* LocalStorage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF584C180E40B9000584C8 /* LocalStorage.cpp */; };
+ 507B3C8E1C31BDD30067B53E /* UIEditBoxImpl-win32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ED2BDE19BEAF7900A0AB90 /* UIEditBoxImpl-win32.cpp */; };
+ 507B3C8F1C31BDD30067B53E /* CCActionFrameEasing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C594A180E930E00EF57C3 /* CCActionFrameEasing.cpp */; };
+ 507B3C911C31BDD30067B53E /* CCPUOnQuotaObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E17C1AA80A6500DDB1C5 /* CCPUOnQuotaObserver.cpp */; };
+ 507B3C931C31BDD30067B53E /* CCPUEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1221AA80A6500DDB1C5 /* CCPUEventHandler.cpp */; };
+ 507B3C941C31BDD30067B53E /* CCDisplayManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5970180E930E00EF57C3 /* CCDisplayManager.cpp */; };
+ 507B3C951C31BDD30067B53E /* CCPUVortexAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1F01AA80A6500DDB1C5 /* CCPUVortexAffectorTranslator.cpp */; };
+ 507B3C961C31BDD30067B53E /* UIRelativeBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50E6D33018E174130051CA34 /* UIRelativeBox.cpp */; };
+ 507B3C981C31BDD30067B53E /* CCPULineAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1421AA80A6500DDB1C5 /* CCPULineAffector.cpp */; };
+ 507B3C9A1C31BDD30067B53E /* CCGLBufferedNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A9DCA02180E6955007A3AD4 /* CCGLBufferedNode.cpp */; };
+ 507B3C9B1C31BDD30067B53E /* CCControlSwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A168461807AF4E005B8026 /* CCControlSwitch.cpp */; };
+ 507B3C9C1C31BDD30067B53E /* CCPUSphere.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D01AA80A6500DDB1C5 /* CCPUSphere.cpp */; };
+ 507B3C9D1C31BDD30067B53E /* CCUtilMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5984180E930E00EF57C3 /* CCUtilMath.cpp */; };
+ 507B3C9E1C31BDD30067B53E /* CCPUBaseColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D81AA80A6500DDB1C5 /* CCPUBaseColliderTranslator.cpp */; };
+ 507B3C9F1C31BDD30067B53E /* CCPUScriptLexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1BC1AA80A6500DDB1C5 /* CCPUScriptLexer.cpp */; };
+ 507B3CA01C31BDD30067B53E /* atitc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDC11925AB6E00A911A9 /* atitc.cpp */; };
+ 507B3CA21C31BDD30067B53E /* CCPUObserverManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E15C1AA80A6500DDB1C5 /* CCPUObserverManager.cpp */; };
+ 507B3CA31C31BDD30067B53E /* AudioPlayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50CB247419D9C5A100687767 /* AudioPlayer.mm */; };
+ 507B3CA41C31BDD30067B53E /* CCRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDFE1925AB6E00A911A9 /* CCRef.cpp */; };
+ 507B3CA51C31BDD30067B53E /* CCUIMultilineTextField.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2980F01A1BA9A5550059E678 /* CCUIMultilineTextField.mm */; };
+ 507B3CA61C31BDD30067B53E /* clipper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 85B374381B204B9400C488D6 /* clipper.cpp */; };
+ 507B3CA71C31BDD30067B53E /* CCLabelTTFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D10180E26E600808F54 /* CCLabelTTFLoader.cpp */; };
+ 507B3CA91C31BDD30067B53E /* CocosGUI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2905F9E918CF08D000240AA3 /* CocosGUI.cpp */; };
+ 507B3CAA1C31BDD30067B53E /* CCPUForceFieldAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1301AA80A6500DDB1C5 /* CCPUForceFieldAffectorTranslator.cpp */; };
+ 507B3CAB1C31BDD30067B53E /* CCAABB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17E419AAD2F700C27E9E /* CCAABB.cpp */; };
+ 507B3CAD1C31BDD30067B53E /* CCPUCircleEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F21AA80A6500DDB1C5 /* CCPUCircleEmitterTranslator.cpp */; };
+ 507B3CAF1C31BDD30067B53E /* CCEventController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E6176611960F89B00DE83F5 /* CCEventController.cpp */; };
+ 507B3CB01C31BDD30067B53E /* Node3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 182C5CB01A95964700C30D34 /* Node3DReader.cpp */; };
+ 507B3CB11C31BDD30067B53E /* CCAsyncTaskPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B63990CA1A490AFE00B07923 /* CCAsyncTaskPool.cpp */; };
+ 507B3CB21C31BDD30067B53E /* CCConsole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDCC1925AB6E00A911A9 /* CCConsole.cpp */; };
+ 507B3CB51C31BDD30067B53E /* CCPUVortexAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1EE1AA80A6500DDB1C5 /* CCPUVortexAffector.cpp */; };
+ 507B3CB61C31BDD30067B53E /* CCPULineEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E14C1AA80A6500DDB1C5 /* CCPULineEmitterTranslator.cpp */; };
+ 507B3CB71C31BDD30067B53E /* CCPUParticleFollower.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E18C1AA80A6500DDB1C5 /* CCPUParticleFollower.cpp */; };
+ 507B3CB81C31BDD30067B53E /* CCCameraBackgroundBrush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A045F6DA1BA816A1005076C7 /* CCCameraBackgroundBrush.cpp */; };
+ 507B3CB91C31BDD30067B53E /* CCPUTextureRotatorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E21AA80A6500DDB1C5 /* CCPUTextureRotatorTranslator.cpp */; };
+ 507B3CBA1C31BDD30067B53E /* CCDirectorCaller-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8D31926736A00CD74DD /* CCDirectorCaller-ios.mm */; };
+ 507B3CBB1C31BDD30067B53E /* CCPUDoAffectorEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0FE1AA80A6500DDB1C5 /* CCPUDoAffectorEventHandlerTranslator.cpp */; };
+ 507B3CBC1C31BDD30067B53E /* CCPhysics3DShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFDC1AF9A9E100B9B856 /* CCPhysics3DShape.cpp */; };
+ 507B3CBD1C31BDD30067B53E /* CCComAttribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5960180E930E00EF57C3 /* CCComAttribute.cpp */; };
+ 507B3CBE1C31BDD30067B53E /* CCNode+CCBRelativePositioning.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD71D1D180E26E600808F54 /* CCNode+CCBRelativePositioning.cpp */; };
+ 507B3CBF1C31BDD30067B53E /* AudioCache.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50CB247019D9C5A100687767 /* AudioCache.mm */; };
+ 507B3CC01C31BDD30067B53E /* CCPUTranslateManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E41AA80A6500DDB1C5 /* CCPUTranslateManager.cpp */; };
+ 507B3CC21C31BDD30067B53E /* Vec3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD321925AB0000A911A9 /* Vec3.cpp */; };
+ 507B3CC41C31BDD30067B53E /* CSLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38B8E2D319E66581002D7CE7 /* CSLoader.cpp */; };
+ 507B3CC51C31BDD30067B53E /* CCNavMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0BF1B18492D006762CB /* CCNavMesh.cpp */; };
+ 507B3CC61C31BDD30067B53E /* CCPURendererTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1AC1AA80A6500DDB1C5 /* CCPURendererTranslator.cpp */; };
+ 507B3CC71C31BDD30067B53E /* CCPhysics3DComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFD41AF9A9E100B9B856 /* CCPhysics3DComponent.cpp */; };
+ 507B3CCA1C31BDD30067B53E /* CCGLView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF251926664700A911A9 /* CCGLView.cpp */; };
+ 507B3CCC1C31BDD30067B53E /* CCPUPathFollowerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1961AA80A6500DDB1C5 /* CCPUPathFollowerTranslator.cpp */; };
+ 507B3CCD1C31BDD30067B53E /* CCPUDoScaleEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1121AA80A6500DDB1C5 /* CCPUDoScaleEventHandlerTranslator.cpp */; };
+ 507B3CCE1C31BDD30067B53E /* CCLock-apple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF1D1926664700A911A9 /* CCLock-apple.cpp */; };
+ 507B3CD01C31BDD30067B53E /* ccUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE0F1925AB6F00A911A9 /* ccUtils.cpp */; };
+ 507B3CD21C31BDD30067B53E /* CCEventListenerMouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDEA1925AB6E00A911A9 /* CCEventListenerMouse.cpp */; };
+ 507B3CD41C31BDD30067B53E /* CCPUTextureRotator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E01AA80A6500DDB1C5 /* CCPUTextureRotator.cpp */; };
+ 507B3CD51C31BDD30067B53E /* CCPUEmitterManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E11E1AA80A6500DDB1C5 /* CCPUEmitterManager.cpp */; };
+ 507B3CD61C31BDD30067B53E /* CCFileUtils-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF1C1926664700A911A9 /* CCFileUtils-apple.mm */; };
+ 507B3CD71C31BDD30067B53E /* ccUTF8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE0D1925AB6F00A911A9 /* ccUTF8.cpp */; };
+ 507B3CD81C31BDD30067B53E /* CCDatas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C596A180E930E00EF57C3 /* CCDatas.cpp */; };
+ 507B3CD91C31BDD30067B53E /* ccFPSImages.c in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDF31925AB6E00A911A9 /* ccFPSImages.c */; };
+ 507B3CDB1C31BDD30067B53E /* CCEventAcceleration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD61925AB6E00A911A9 /* CCEventAcceleration.cpp */; };
+ 507B3CDD1C31BDD30067B53E /* CCPUPositionEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A41AA80A6500DDB1C5 /* CCPUPositionEmitterTranslator.cpp */; };
+ 507B3CDE1C31BDD30067B53E /* CCTween.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A8C5980180E930E00EF57C3 /* CCTween.cpp */; };
+ 507B3CDF1C31BDD30067B53E /* xxhash.c in Sources */ = {isa = PBXBuildFile; fileRef = 46C02E0518E91123004B7456 /* xxhash.c */; };
+ 507B3CE01C31BDD30067B53E /* CCObjLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17FB19AAD2F700C27E9E /* CCObjLoader.cpp */; };
+ 507B3CE11C31BDD30067B53E /* CCAllocatorDiagnostics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0FD033C1A3B51AA00825BB5 /* CCAllocatorDiagnostics.cpp */; };
+ 507B3CE21C31BDD30067B53E /* CCPUOnClearObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1621AA80A6500DDB1C5 /* CCPUOnClearObserverTranslator.cpp */; };
+ 507B3CE31C31BDD30067B53E /* CCUIEditBoxIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2980F0181BA9A5550059E678 /* CCUIEditBoxIOS.mm */; };
+ 507B3CE41C31BDD30067B53E /* CCPUVertexEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1EC1AA80A6500DDB1C5 /* CCPUVertexEmitter.cpp */; };
+ 507B3CE51C31BDD30067B53E /* CCNavMeshUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0C71B18492D006762CB /* CCNavMeshUtils.cpp */; };
+ 507B3CE61C31BDD30067B53E /* CCPUScaleVelocityAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B61AA80A6500DDB1C5 /* CCPUScaleVelocityAffector.cpp */; };
+ 507B3CE81C31BDD30067B53E /* TGAlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE191925AB6F00A911A9 /* TGAlib.cpp */; };
+ 507B3CE91C31BDD30067B53E /* CCDownloader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50693C5C1B6BF2AE005C5820 /* CCDownloader.cpp */; };
+ 507B3CEA1C31BDD30067B53E /* Light3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C261F261BE7528900707478 /* Light3DReader.cpp */; };
+ 507B3CEB1C31BDD30067B53E /* CCArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A01C67618F57BE800EFE3A6 /* CCArray.cpp */; };
+ 507B3CEC1C31BDD30067B53E /* CCPUFlockCenteringAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E12A1AA80A6500DDB1C5 /* CCPUFlockCenteringAffectorTranslator.cpp */; };
+ 507B3CEE1C31BDD30067B53E /* CCDevice-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503DD8D11926736A00CD74DD /* CCDevice-ios.mm */; };
+ 507B3CF11C31BDD30067B53E /* CCUserDefault-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE0B1925AB6F00A911A9 /* CCUserDefault-apple.mm */; };
+ 507B3CF21C31BDD30067B53E /* ConvertUTF.c in Sources */ = {isa = PBXBuildFile; fileRef = 1A1645AE191B726C008C7C7F /* ConvertUTF.c */; };
+ 507B3CF41C31BDD30067B53E /* CCPUMaterialTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1521AA80A6500DDB1C5 /* CCPUMaterialTranslator.cpp */; };
+ 507B3CF51C31BDD30067B53E /* CCData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDCE1925AB6E00A911A9 /* CCData.cpp */; };
+ 507B3CF71C31BDD30067B53E /* ConvertUTFWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1645AF191B726C008C7C7F /* ConvertUTFWrapper.cpp */; };
+ 507B3CF81C31BDD30067B53E /* DetourProximityGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F9D1B04825B00E47F5F /* DetourProximityGrid.cpp */; };
+ 507B3CF91C31BDD30067B53E /* CCFontCharMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABA68AC1888D700007D1BB4 /* CCFontCharMap.cpp */; };
+ 507B3CFA1C31BDD30067B53E /* DetourNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F8F1B04825B00E47F5F /* DetourNode.cpp */; };
+ 507B3CFC1C31BDD30067B53E /* CCAnimate3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15AE17E619AAD2F700C27E9E /* CCAnimate3D.cpp */; };
+ 507B3CFE1C31BDD30067B53E /* CCEventMouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDEE1925AB6E00A911A9 /* CCEventMouse.cpp */; };
+ 507B3CFF1C31BDD30067B53E /* CCPUScaleAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B21AA80A6500DDB1C5 /* CCPUScaleAffector.cpp */; };
+ 507B3D001C31BDD30067B53E /* CCProtectedNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15EFA20F198A2BB5000C57D3 /* CCProtectedNode.cpp */; };
+ 507B3D011C31BDD30067B53E /* CCGLProgramStateCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD6E1925AB4100A911A9 /* CCGLProgramStateCache.cpp */; };
+ 507B3D041C31BDD30067B53E /* CCPUOnTimeObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1841AA80A6500DDB1C5 /* CCPUOnTimeObserver.cpp */; };
+ 507B3D051C31BDD30067B53E /* WebSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF5368180E3374000584C8 /* WebSocket.cpp */; };
+ 507B3D071C31BDD30067B53E /* libwebsockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1AAF5387180E35AC000584C8 /* libwebsockets.a */; };
+ 507B3D081C31BDD30067B53E /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 292F1A5C1A5151CE00E479F8 /* libssl.a */; };
+ 507B3D091C31BDD30067B53E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1551A342158F2AB200E66CFE /* Foundation.framework */; };
+ 507B3D0A1C31BDD30067B53E /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A570363180BD1120088DEC7 /* libpng.a */; };
+ 507B3D0B1C31BDD30067B53E /* libjpeg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A570377180BD1B40088DEC7 /* libjpeg.a */; };
+ 507B3D0C1C31BDD30067B53E /* libtiff.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A5703A3180BD2350088DEC7 /* libtiff.a */; };
+ 507B3D0D1C31BDD30067B53E /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 292F1A5B1A5151CE00E479F8 /* libcrypto.a */; };
+ 507B3D0E1C31BDD30067B53E /* libchipmunk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 29031E0819BFE8DE00EFA1DF /* libchipmunk.a */; };
+ 507B3D0F1C31BDD30067B53E /* libwebp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A5703BA180BD2800088DEC7 /* libwebp.a */; };
+ 507B3D101C31BDD30067B53E /* libfreetype.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A57052D180BD3280088DEC7 /* libfreetype.a */; };
+ 507B3D121C31BDD30067B53E /* CCStdC-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8DE1926736A00CD74DD /* CCStdC-ios.h */; };
+ 507B3D141C31BDD30067B53E /* CCUITextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 2980F01D1BA9A5550059E678 /* CCUITextInput.h */; };
+ 507B3D161C31BDD30067B53E /* CCPUPathFollower.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1951AA80A6500DDB1C5 /* CCPUPathFollower.h */; };
+ 507B3D171C31BDD30067B53E /* UITextField+CCUITextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 2980F01E1BA9A5550059E678 /* UITextField+CCUITextInput.h */; };
+ 507B3D181C31BDD30067B53E /* CCPhysicsContact.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A170711807CE7A005B8026 /* CCPhysicsContact.h */; };
+ 507B3D1C1C31BDD30067B53E /* CCCamera.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EACC99D19F5014D00EB3C5E /* CCCamera.h */; };
+ 507B3D1F1C31BDD30067B53E /* CCPULinearForceAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1491AA80A6500DDB1C5 /* CCPULinearForceAffectorTranslator.h */; };
+ 507B3D211C31BDD30067B53E /* CCGroupCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD731925AB4100A911A9 /* CCGroupCommand.h */; };
+ 507B3D221C31BDD30067B53E /* CCLayerColorLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D13180E26E600808F54 /* CCLayerColorLoader.h */; };
+ 507B3D231C31BDD30067B53E /* CCApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BD719BFAF4400EF68ED /* CCApplication.h */; };
+ 507B3D251C31BDD30067B53E /* CCAnimationCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17EA19AAD2F700C27E9E /* CCAnimationCurve.h */; };
+ 507B3D271C31BDD30067B53E /* CCPUTextureAnimatorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1DF1AA80A6500DDB1C5 /* CCPUTextureAnimatorTranslator.h */; };
+ 507B3D281C31BDD30067B53E /* CCPlatformDefine-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8DD1926736A00CD74DD /* CCPlatformDefine-ios.h */; };
+ 507B3D291C31BDD30067B53E /* CocoStudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5986180E930E00EF57C3 /* CocoStudio.h */; };
+ 507B3D2A1C31BDD30067B53E /* CCPhysicsShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A170761807CE7A005B8026 /* CCPhysicsShape.h */; };
+ 507B3D2B1C31BDD30067B53E /* CCOBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17FA19AAD2F700C27E9E /* CCOBB.h */; };
+ 507B3D2D1C31BDD30067B53E /* CCPUOnEventFlagObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1711AA80A6500DDB1C5 /* CCPUOnEventFlagObserver.h */; };
+ 507B3D2E1C31BDD30067B53E /* CCBMemberVariableAssigner.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D00180E26E600808F54 /* CCBMemberVariableAssigner.h */; };
+ 507B3D301C31BDD30067B53E /* CCPUParticleFollowerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E18F1AA80A6500DDB1C5 /* CCPUParticleFollowerTranslator.h */; };
+ 507B3D311C31BDD30067B53E /* UIEditBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13019B4574100A80320 /* UIEditBox.h */; };
+ 507B3D321C31BDD30067B53E /* CCAffineTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD1C1925AB0000A911A9 /* CCAffineTransform.h */; };
+ 507B3D331C31BDD30067B53E /* ccShader_PositionColorLengthTexture.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA06191D591000CE6051 /* ccShader_PositionColorLengthTexture.vert */; };
+ 507B3D341C31BDD30067B53E /* UITextAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0E18CF08D100240AA3 /* UITextAtlas.h */; };
+ 507B3D361C31BDD30067B53E /* utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB207C1AE7C57D00C31518 /* utils.h */; };
+ 507B3D371C31BDD30067B53E /* CCPUForceField.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E12D1AA80A6500DDB1C5 /* CCPUForceField.h */; };
+ 507B3D391C31BDD30067B53E /* CCPUJetAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E13F1AA80A6500DDB1C5 /* CCPUJetAffector.h */; };
+ 507B3D3A1C31BDD30067B53E /* CCEventListenerAssetsManagerEx.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B3707319EE414C00ABE682 /* CCEventListenerAssetsManagerEx.h */; };
+ 507B3D3C1C31BDD30067B53E /* CCAllocatorGlobal.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD033F1A3B51AA00825BB5 /* CCAllocatorGlobal.h */; };
+ 507B3D3F1C31BDD30067B53E /* CCPUScriptCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1BB1AA80A6500DDB1C5 /* CCPUScriptCompiler.h */; };
+ 507B3D401C31BDD30067B53E /* CCPURibbonTrail.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1AF1AA80A6500DDB1C5 /* CCPURibbonTrail.h */; };
+ 507B3D411C31BDD30067B53E /* CCEventMouse.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDEF1925AB6E00A911A9 /* CCEventMouse.h */; };
+ 507B3D431C31BDD30067B53E /* CCPhysicsJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A170731807CE7A005B8026 /* CCPhysicsJoint.h */; };
+ 507B3D441C31BDD30067B53E /* CCPUScriptParser.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1BF1AA80A6500DDB1C5 /* CCPUScriptParser.h */; };
+ 507B3D451C31BDD30067B53E /* CCPUVortexAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1F11AA80A6500DDB1C5 /* CCPUVortexAffectorTranslator.h */; };
+ 507B3D461C31BDD30067B53E /* poly2tri.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB207D1AE7C57D00C31518 /* poly2tri.h */; };
+ 507B3D481C31BDD30067B53E /* CCPhysicsBody.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1706F1807CE7A005B8026 /* CCPhysicsBody.h */; };
+ 507B3D491C31BDD30067B53E /* CCRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDFF1925AB6E00A911A9 /* CCRef.h */; };
+ 507B3D4B1C31BDD30067B53E /* ExtensionDeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB15E19B461CA00A80320 /* ExtensionDeprecated.h */; };
+ 507B3D4C1C31BDD30067B53E /* CCGLProgramState.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD6D1925AB4100A911A9 /* CCGLProgramState.h */; };
+ 507B3D4D1C31BDD30067B53E /* CCPhysicsWorld.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A170781807CE7A005B8026 /* CCPhysicsWorld.h */; };
+ 507B3D4E1C31BDD30067B53E /* ccShaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD7C1925AB4100A911A9 /* ccShaders.h */; };
+ 507B3D4F1C31BDD30067B53E /* SliderReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8318C72017004AD434 /* SliderReader.h */; };
+ 507B3D501C31BDD30067B53E /* UIRichText.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0518CF08D000240AA3 /* UIRichText.h */; };
+ 507B3D511C31BDD30067B53E /* CCPUScaleAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B31AA80A6500DDB1C5 /* CCPUScaleAffector.h */; };
+ 507B3D551C31BDD30067B53E /* UIEditBoxImpl-common.h in Headers */ = {isa = PBXBuildFile; fileRef = A0E749F61BA8FD7F001A8332 /* UIEditBoxImpl-common.h */; };
+ 507B3D571C31BDD30067B53E /* ccFPSImages.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF41925AB6E00A911A9 /* ccFPSImages.h */; };
+ 507B3D5A1C31BDD30067B53E /* TriggerObj.h in Headers */ = {isa = PBXBuildFile; fileRef = 06CAAAC1186AD63B0012A414 /* TriggerObj.h */; };
+ 507B3D5B1C31BDD30067B53E /* CCPULineAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1451AA80A6500DDB1C5 /* CCPULineAffectorTranslator.h */; };
+ 507B3D5C1C31BDD30067B53E /* ccCArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC81925AB6E00A911A9 /* ccCArray.h */; };
+ 507B3D5E1C31BDD30067B53E /* AssetsManagerEx.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B3706F19EE414C00ABE682 /* AssetsManagerEx.h */; };
+ 507B3D5F1C31BDD30067B53E /* CCPUSineForceAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C71AA80A6500DDB1C5 /* CCPUSineForceAffectorTranslator.h */; };
+ 507B3D631C31BDD30067B53E /* UIWidget.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA1418CF08D100240AA3 /* UIWidget.h */; };
+ 507B3D651C31BDD30067B53E /* CCPUDoEnableComponentEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1031AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandlerTranslator.h */; };
+ 507B3D661C31BDD30067B53E /* CCLock-apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF1E1926664700A911A9 /* CCLock-apple.h */; };
+ 507B3D681C31BDD30067B53E /* SingleNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3823843C1A259140002C4610 /* SingleNodeReader.h */; };
+ 507B3D691C31BDD30067B53E /* CCPUDoPlacementParticleEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E10D1AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandler.h */; };
+ 507B3D6D1C31BDD30067B53E /* CCPUOnVelocityObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1891AA80A6500DDB1C5 /* CCPUOnVelocityObserver.h */; };
+ 507B3D6F1C31BDD30067B53E /* CCPhysicsHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = ED74D7681A5B8A2600157FD4 /* CCPhysicsHelper.h */; };
+ 507B3D701C31BDD30067B53E /* ccShader_Position_uColor.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0A191D591000CE6051 /* ccShader_Position_uColor.vert */; };
+ 507B3D711C31BDD30067B53E /* DetourStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F911B04825B00E47F5F /* DetourStatus.h */; };
+ 507B3D721C31BDD30067B53E /* UIRadioButton.h in Headers */ = {isa = PBXBuildFile; fileRef = B5CE6DC71B3C05BA002B0419 /* UIRadioButton.h */; };
+ 507B3D731C31BDD30067B53E /* CCPUDoStopSystemEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1171AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandlerTranslator.h */; };
+ 507B3D741C31BDD30067B53E /* CCSprite3DMaterial.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE180419AAD2F700C27E9E /* CCSprite3DMaterial.h */; };
+ 507B3D751C31BDD30067B53E /* DetourMath.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F881B04825B00E47F5F /* DetourMath.h */; };
+ 507B3D771C31BDD30067B53E /* CCControlUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168491807AF4E005B8026 /* CCControlUtils.h */; };
+ 507B3D781C31BDD30067B53E /* CCActionObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5951180E930E00EF57C3 /* CCActionObject.h */; };
+ 507B3D7A1C31BDD30067B53E /* CCPUGravityAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1371AA80A6500DDB1C5 /* CCPUGravityAffector.h */; };
+ 507B3D7B1C31BDD30067B53E /* CCActionTimelineCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4C8194B19E400E608AF /* CCActionTimelineCache.h */; };
+ 507B3D7D1C31BDD30067B53E /* TextFieldReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8C18C72017004AD434 /* TextFieldReader.h */; };
+ 507B3D7E1C31BDD30067B53E /* CCAnimation3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17E919AAD2F700C27E9E /* CCAnimation3D.h */; };
+ 507B3D7F1C31BDD30067B53E /* CCValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE121925AB6F00A911A9 /* CCValue.h */; };
+ 507B3D801C31BDD30067B53E /* CCUIMultilineTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 2980F0191BA9A5550059E678 /* CCUIMultilineTextField.h */; };
+ 507B3D821C31BDD30067B53E /* firePngData.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE161925AB6F00A911A9 /* firePngData.h */; };
+ 507B3D831C31BDD30067B53E /* CCPrimitive.h in Headers */ = {isa = PBXBuildFile; fileRef = B257B44D1989D5E800D9A687 /* CCPrimitive.h */; };
+ 507B3D841C31BDD30067B53E /* CCPlatformConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BE019BFCF1800EF68ED /* CCPlatformConfig.h */; };
+ 507B3D851C31BDD30067B53E /* CCPUDoScaleEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1111AA80A6500DDB1C5 /* CCPUDoScaleEventHandler.h */; };
+ 507B3D861C31BDD30067B53E /* DetourPathQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F9C1B04825B00E47F5F /* DetourPathQueue.h */; };
+ 507B3D881C31BDD30067B53E /* CCNavMeshObstacle.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C61B18492D006762CB /* CCNavMeshObstacle.h */; };
+ 507B3D891C31BDD30067B53E /* CCBundle3DData.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F019AAD2F700C27E9E /* CCBundle3DData.h */; };
+ 507B3D8A1C31BDD30067B53E /* CCActionManagerEx.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C594D180E930E00EF57C3 /* CCActionManagerEx.h */; };
+ 507B3D8B1C31BDD30067B53E /* CDOpenALSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE71807A56F005B8026 /* CDOpenALSupport.h */; };
+ 507B3D8C1C31BDD30067B53E /* CCDataVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD11925AB6E00A911A9 /* CCDataVisitor.h */; };
+ 507B3D8E1C31BDD30067B53E /* TextBMFontReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8918C72017004AD434 /* TextBMFontReader.h */; };
+ 507B3D8F1C31BDD30067B53E /* CCAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570048180BC5A10088DEC7 /* CCAction.h */; };
+ 507B3D921C31BDD30067B53E /* UIRelativeBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E6D33118E174130051CA34 /* UIRelativeBox.h */; };
+ 507B3D931C31BDD30067B53E /* CCGLViewImpl-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8DA1926736A00CD74DD /* CCGLViewImpl-ios.h */; };
+ 507B3D941C31BDD30067B53E /* CCScrollViewLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D29180E26E600808F54 /* CCScrollViewLoader.h */; };
+ 507B3D961C31BDD30067B53E /* CocosBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D2C180E26E600808F54 /* CocosBuilder.h */; };
+ 507B3D971C31BDD30067B53E /* GameNode3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = A045F6EE1BA81821005076C7 /* GameNode3DReader.h */; };
+ 507B3D991C31BDD30067B53E /* CCPUAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0CD1AA80A6500DDB1C5 /* CCPUAffector.h */; };
+ 507B3D9C1C31BDD30067B53E /* ccUTF8.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE0E1925AB6F00A911A9 /* ccUTF8.h */; };
+ 507B3DA01C31BDD30067B53E /* CCPlatformDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 5091A7A219BFABA800AC8789 /* CCPlatformDefine.h */; };
+ 507B3DA11C31BDD30067B53E /* DetourNavMeshQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F8E1B04825B00E47F5F /* DetourNavMeshQuery.h */; };
+ 507B3DA21C31BDD30067B53E /* CCActionCamera.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57004A180BC5A10088DEC7 /* CCActionCamera.h */; };
+ 507B3DA51C31BDD30067B53E /* CCControlLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D0D180E26E600808F54 /* CCControlLoader.h */; };
+ 507B3DA61C31BDD30067B53E /* CCLabelTTFLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D11180E26E600808F54 /* CCLabelTTFLoader.h */; };
+ 507B3DA71C31BDD30067B53E /* CCActionCatmullRom.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57004C180BC5A10088DEC7 /* CCActionCatmullRom.h */; };
+ 507B3DA81C31BDD30067B53E /* CCSGUIReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5977180E930E00EF57C3 /* CCSGUIReader.h */; };
+ 507B3DA91C31BDD30067B53E /* ccShader_PositionColorLengthTexture.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA07191D591000CE6051 /* ccShader_PositionColorLengthTexture.frag */; };
+ 507B3DAA1C31BDD30067B53E /* CCAllocatorDiagnostics.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD033D1A3B51AA00825BB5 /* CCAllocatorDiagnostics.h */; };
+ 507B3DAB1C31BDD30067B53E /* CCPUEventHandlerManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1251AA80A6500DDB1C5 /* CCPUEventHandlerManager.h */; };
+ 507B3DAD1C31BDD30067B53E /* CCClippingRectangleNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DABC9FA819E7DFA900FA252C /* CCClippingRectangleNode.h */; };
+ 507B3DAE1C31BDD30067B53E /* CCPUVelocityMatchingAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1EB1AA80A6500DDB1C5 /* CCPUVelocityMatchingAffectorTranslator.h */; };
+ 507B3DB01C31BDD30067B53E /* CCPUScaleAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B51AA80A6500DDB1C5 /* CCPUScaleAffectorTranslator.h */; };
+ 507B3DB11C31BDD30067B53E /* fastlz.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2FA61B04825B00E47F5F /* fastlz.h */; };
+ 507B3DB21C31BDD30067B53E /* CCPUVertexEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1ED1AA80A6500DDB1C5 /* CCPUVertexEmitter.h */; };
+ 507B3DB31C31BDD30067B53E /* CCPUCollisionAvoidanceAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F51AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffector.h */; };
+ 507B3DB51C31BDD30067B53E /* CCVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE131925AB6F00A911A9 /* CCVector.h */; };
+ 507B3DB61C31BDD30067B53E /* CCEventCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD91925AB6E00A911A9 /* CCEventCustom.h */; };
+ 507B3DB81C31BDD30067B53E /* CCPUOnCountObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E16B1AA80A6500DDB1C5 /* CCPUOnCountObserverTranslator.h */; };
+ 507B3DB91C31BDD30067B53E /* CCDownloader-apple.h in Headers */ = {isa = PBXBuildFile; fileRef = A0534A631B872FFD006B03E5 /* CCDownloader-apple.h */; };
+ 507B3DBA1C31BDD30067B53E /* CCFrameBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = B240C5E81B09DFB000137F50 /* CCFrameBuffer.h */; };
+ 507B3DBC1C31BDD30067B53E /* CCPUAlignAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D51AA80A6500DDB1C5 /* CCPUAlignAffectorTranslator.h */; };
+ 507B3DBD1C31BDD30067B53E /* CCActionEase.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57004E180BC5A10088DEC7 /* CCActionEase.h */; };
+ 507B3DBE1C31BDD30067B53E /* CCActionGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570050180BC5A10088DEC7 /* CCActionGrid.h */; };
+ 507B3DBF1C31BDD30067B53E /* CCComController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5965180E930E00EF57C3 /* CCComController.h */; };
+ 507B3DC01C31BDD30067B53E /* NodeReaderProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 3823840E1A259092002C4610 /* NodeReaderProtocol.h */; };
+ 507B3DC11C31BDD30067B53E /* ccShader_Label_outline.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0D191D591000CE6051 /* ccShader_Label_outline.frag */; };
+ 507B3DC21C31BDD30067B53E /* CCActionGrid3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570052180BC5A10088DEC7 /* CCActionGrid3D.h */; };
+ 507B3DC31C31BDD30067B53E /* Vec4.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD361925AB0000A911A9 /* Vec4.h */; };
+ 507B3DC41C31BDD30067B53E /* CCPURandomiser.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A71AA80A6500DDB1C5 /* CCPURandomiser.h */; };
+ 507B3DC51C31BDD30067B53E /* PageViewReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7D18C72017004AD434 /* PageViewReader.h */; };
+ 507B3DC71C31BDD30067B53E /* CCMotionStreak3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2A09C11BAA91B70086B878 /* CCMotionStreak3D.h */; };
+ 507B3DCC1C31BDD30067B53E /* CCBool.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67818F57BE800EFE3A6 /* CCBool.h */; };
+ 507B3DCD1C31BDD30067B53E /* CCPUDoStopSystemEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1151AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandler.h */; };
+ 507B3DCE1C31BDD30067B53E /* CSParse3DBinary_generated.h in Headers */ = {isa = PBXBuildFile; fileRef = 182C5CAD1A95961600C30D34 /* CSParse3DBinary_generated.h */; };
+ 507B3DCF1C31BDD30067B53E /* CCSprite3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE180219AAD2F700C27E9E /* CCSprite3D.h */; };
+ 507B3DD01C31BDD30067B53E /* AudioPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CB247319D9C5A100687767 /* AudioPlayer.h */; };
+ 507B3DD11C31BDD30067B53E /* CCActionInstant.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570054180BC5A10088DEC7 /* CCActionInstant.h */; };
+ 507B3DD21C31BDD30067B53E /* CCEventController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E6176621960F89B00DE83F5 /* CCEventController.h */; };
+ 507B3DD31C31BDD30067B53E /* CCNode+CCBRelativePositioning.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D1E180E26E600808F54 /* CCNode+CCBRelativePositioning.h */; };
+ 507B3DD41C31BDD30067B53E /* NodeReaderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 3823840C1A259092002C4610 /* NodeReaderDefine.h */; };
+ 507B3DD51C31BDD30067B53E /* CCEventListenerTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDED1925AB6E00A911A9 /* CCEventListenerTouch.h */; };
+ 507B3DD61C31BDD30067B53E /* WebSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5369180E3374000584C8 /* WebSocket.h */; };
+ 507B3DD81C31BDD30067B53E /* CCPUMaterialManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1511AA80A6500DDB1C5 /* CCPUMaterialManager.h */; };
+ 507B3DD91C31BDD30067B53E /* FlatBuffersSerialize.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384061A25900F002C4610 /* FlatBuffersSerialize.h */; };
+ 507B3DDB1C31BDD30067B53E /* CCActionInterval.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570056180BC5A10088DEC7 /* CCActionInterval.h */; };
+ 507B3DDC1C31BDD30067B53E /* CCPUEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1231AA80A6500DDB1C5 /* CCPUEventHandler.h */; };
+ 507B3DDD1C31BDD30067B53E /* CCActionFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5949180E930E00EF57C3 /* CCActionFrame.h */; };
+ 507B3DDE1C31BDD30067B53E /* CCActionFrameEasing.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C594B180E930E00EF57C3 /* CCActionFrameEasing.h */; };
+ 507B3DDF1C31BDD30067B53E /* CCActionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570058180BC5A10088DEC7 /* CCActionManager.h */; };
+ 507B3DE01C31BDD30067B53E /* CCPUObserverManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E15D1AA80A6500DDB1C5 /* CCPUObserverManager.h */; };
+ 507B3DE11C31BDD30067B53E /* CCLayerLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D17180E26E600808F54 /* CCLayerLoader.h */; };
+ 507B3DE41C31BDD30067B53E /* CCPUGeometryRotatorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1351AA80A6500DDB1C5 /* CCPUGeometryRotatorTranslator.h */; };
+ 507B3DE91C31BDD30067B53E /* CCGLView.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF261926664700A911A9 /* CCGLView.h */; };
+ 507B3DEB1C31BDD30067B53E /* CCActionPageTurn3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57005A180BC5A10088DEC7 /* CCActionPageTurn3D.h */; };
+ 507B3DEC1C31BDD30067B53E /* UIHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F518CF08D000240AA3 /* UIHelper.h */; };
+ 507B3DED1C31BDD30067B53E /* CCNavMeshUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C81B18492D006762CB /* CCNavMeshUtils.h */; };
+ 507B3DEE1C31BDD30067B53E /* ccGLStateCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD711925AB4100A911A9 /* ccGLStateCache.h */; };
+ 507B3DEF1C31BDD30067B53E /* CCPUBaseForceAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0DB1AA80A6500DDB1C5 /* CCPUBaseForceAffector.h */; };
+ 507B3DF01C31BDD30067B53E /* CCPUNoise.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1591AA80A6500DDB1C5 /* CCPUNoise.h */; };
+ 507B3DF11C31BDD30067B53E /* CocosGUI.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9EA18CF08D000240AA3 /* CocosGUI.h */; };
+ 507B3DF21C31BDD30067B53E /* CCActionProgressTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57005C180BC5A10088DEC7 /* CCActionProgressTimer.h */; };
+ 507B3DF41C31BDD30067B53E /* CCPUBehaviour.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E11AA80A6500DDB1C5 /* CCPUBehaviour.h */; };
+ 507B3DF51C31BDD30067B53E /* CCActionTiledGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57005E180BC5A10088DEC7 /* CCActionTiledGrid.h */; };
+ 507B3DF61C31BDD30067B53E /* CCPUEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1271AA80A6500DDB1C5 /* CCPUEventHandlerTranslator.h */; };
+ 507B3DF81C31BDD30067B53E /* ioapi_mem.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8C62A119E52C6400000516 /* ioapi_mem.h */; };
+ 507B3DFA1C31BDD30067B53E /* CCActionTween.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570060180BC5A10088DEC7 /* CCActionTween.h */; };
+ 507B3DFB1C31BDD30067B53E /* CCAtlasNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570097180BC5C10088DEC7 /* CCAtlasNode.h */; };
+ 507B3DFC1C31BDD30067B53E /* cocos3d.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE180519AAD2F700C27E9E /* cocos3d.h */; };
+ 507B3DFD1C31BDD30067B53E /* CCNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57009D180BC5D20088DEC7 /* CCNode.h */; };
+ 507B3DFE1C31BDD30067B53E /* CCAttachNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17ED19AAD2F700C27E9E /* CCAttachNode.h */; };
+ 507B3E001C31BDD30067B53E /* UIEditBoxImpl-mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13619B4574100A80320 /* UIEditBoxImpl-mac.h */; };
+ 507B3E011C31BDD30067B53E /* CCControlHuePicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1683D1807AF4E005B8026 /* CCControlHuePicker.h */; };
+ 507B3E021C31BDD30067B53E /* CCPUOnRandomObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1831AA80A6500DDB1C5 /* CCPUOnRandomObserverTranslator.h */; };
+ 507B3E031C31BDD30067B53E /* CCPUObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E15B1AA80A6500DDB1C5 /* CCPUObserver.h */; };
+ 507B3E041C31BDD30067B53E /* CCBSequenceProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D07180E26E600808F54 /* CCBSequenceProperty.h */; };
+ 507B3E051C31BDD30067B53E /* CCPUBoxColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0EB1AA80A6500DDB1C5 /* CCPUBoxColliderTranslator.h */; };
+ 507B3E061C31BDD30067B53E /* BoneNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306711B60B5B2001E6D43 /* BoneNodeReader.h */; };
+ 507B3E081C31BDD30067B53E /* CCDirectorCaller-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8D21926736A00CD74DD /* CCDirectorCaller-ios.h */; };
+ 507B3E091C31BDD30067B53E /* CCTimelineMacro.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4CF194B19E400E608AF /* CCTimelineMacro.h */; };
+ 507B3E0C1C31BDD30067B53E /* CCPUColorAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F91AA80A6500DDB1C5 /* CCPUColorAffector.h */; };
+ 507B3E0E1C31BDD30067B53E /* UIPageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0318CF08D000240AA3 /* UIPageView.h */; };
+ 507B3E0F1C31BDD30067B53E /* CCCustomCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD671925AB4100A911A9 /* CCCustomCommand.h */; };
+ 507B3E101C31BDD30067B53E /* CSBoneBinary_generated.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306721B60B5B2001E6D43 /* CSBoneBinary_generated.h */; };
+ 507B3E111C31BDD30067B53E /* ObjectFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 299754F3193EC95400A54AC3 /* ObjectFactory.h */; };
+ 507B3E121C31BDD30067B53E /* advancing_front.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20801AE7C57D00C31518 /* advancing_front.h */; };
+ 507B3E131C31BDD30067B53E /* ccMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF51925AB6E00A911A9 /* ccMacros.h */; };
+ 507B3E141C31BDD30067B53E /* CCPUPointEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E19F1AA80A6500DDB1C5 /* CCPUPointEmitter.h */; };
+ 507B3E161C31BDD30067B53E /* CCFileUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF241926664700A911A9 /* CCFileUtils.h */; };
+ 507B3E181C31BDD30067B53E /* LayoutReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7418C72017004AD434 /* LayoutReader.h */; };
+ 507B3E191C31BDD30067B53E /* CCPUEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1211AA80A6500DDB1C5 /* CCPUEmitterTranslator.h */; };
+ 507B3E1A1C31BDD30067B53E /* UIScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0818CF08D000240AA3 /* UIScrollView.h */; };
+ 507B3E1B1C31BDD30067B53E /* ccShader_PositionTexture.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA02191D591000CE6051 /* ccShader_PositionTexture.vert */; };
+ 507B3E1C1C31BDD30067B53E /* ProjectNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384351A259126002C4610 /* ProjectNodeReader.h */; };
+ 507B3E1D1C31BDD30067B53E /* CCDrawingPrimitives.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57010B180BC8EE0088DEC7 /* CCDrawingPrimitives.h */; };
+ 507B3E1F1C31BDD30067B53E /* CCConsole.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDCD1925AB6E00A911A9 /* CCConsole.h */; };
+ 507B3E211C31BDD30067B53E /* CCMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF61925AB6E00A911A9 /* CCMap.h */; };
+ 507B3E221C31BDD30067B53E /* CCPUOnCountObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1691AA80A6500DDB1C5 /* CCPUOnCountObserver.h */; };
+ 507B3E231C31BDD30067B53E /* CCEAGLView-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8D41926736A00CD74DD /* CCEAGLView-ios.h */; };
+ 507B3E241C31BDD30067B53E /* CCEventAcceleration.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD71925AB6E00A911A9 /* CCEventAcceleration.h */; };
+ 507B3E251C31BDD30067B53E /* CCPUListener.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E14F1AA80A6500DDB1C5 /* CCPUListener.h */; };
+ 507B3E271C31BDD30067B53E /* TransformUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD2E1925AB0000A911A9 /* TransformUtils.h */; };
+ 507B3E281C31BDD30067B53E /* CCPUDoFreezeEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E10B1AA80A6500DDB1C5 /* CCPUDoFreezeEventHandlerTranslator.h */; };
+ 507B3E291C31BDD30067B53E /* CCDrawNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57010D180BC8EE0088DEC7 /* CCDrawNode.h */; };
+ 507B3E2A1C31BDD30067B53E /* CCNavMeshDebugDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C41B18492D006762CB /* CCNavMeshDebugDraw.h */; };
+ 507B3E2C1C31BDD30067B53E /* CCGrabber.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570118180BC90D0088DEC7 /* CCGrabber.h */; };
+ 507B3E2F1C31BDD30067B53E /* CCGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57011A180BC90D0088DEC7 /* CCGrid.h */; };
+ 507B3E321C31BDD30067B53E /* ccShader_PositionTextureA8Color.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA01191D591000CE6051 /* ccShader_PositionTextureA8Color.frag */; };
+ 507B3E351C31BDD30067B53E /* UIWebViewImpl-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 29394CEE19B01DBA00D2DE1A /* UIWebViewImpl-ios.h */; };
+ 507B3E361C31BDD30067B53E /* Vec2.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD301925AB0000A911A9 /* Vec2.h */; };
+ 507B3E371C31BDD30067B53E /* CCComExtensionData.h in Headers */ = {isa = PBXBuildFile; fileRef = 43015DBE1B60DF4000E75161 /* CCComExtensionData.h */; };
+ 507B3E381C31BDD30067B53E /* CCAllocatorStrategyGlobalSmallBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03451A3B51AA00825BB5 /* CCAllocatorStrategyGlobalSmallBlock.h */; };
+ 507B3E391C31BDD30067B53E /* CCMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD1F1925AB0000A911A9 /* CCMath.h */; };
+ 507B3E3A1C31BDD30067B53E /* CCFont.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570183180BCB590088DEC7 /* CCFont.h */; };
+ 507B3E3D1C31BDD30067B53E /* UIEditBoxImpl-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13419B4574100A80320 /* UIEditBoxImpl-ios.h */; };
+ 507B3E401C31BDD30067B53E /* AudioEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2BDADD19C030ED0055CDCD /* AudioEngine.h */; };
+ 507B3E411C31BDD30067B53E /* CCPUMaterialTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1531AA80A6500DDB1C5 /* CCPUMaterialTranslator.h */; };
+ 507B3E421C31BDD30067B53E /* CCGLProgramStateCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD6F1925AB4100A911A9 /* CCGLProgramStateCache.h */; };
+ 507B3E431C31BDD30067B53E /* CCBundle3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17EF19AAD2F700C27E9E /* CCBundle3D.h */; };
+ 507B3E441C31BDD30067B53E /* CocoLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 29E99D1D1957BA7000046604 /* CocoLoader.h */; };
+ 507B3E451C31BDD30067B53E /* HttpRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5364180E3374000584C8 /* HttpRequest.h */; };
+ 507B3E471C31BDD30067B53E /* CCPUForceFieldAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1311AA80A6500DDB1C5 /* CCPUForceFieldAffectorTranslator.h */; };
+ 507B3E481C31BDD30067B53E /* CCBillBoard.h in Headers */ = {isa = PBXBuildFile; fileRef = B60C5BD319AC68B10056FBDE /* CCBillBoard.h */; };
+ 507B3E491C31BDD30067B53E /* CCTrianglesCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = B230ED7019B417AE00364AA8 /* CCTrianglesCommand.h */; };
+ 507B3E4A1C31BDD30067B53E /* CCPUDynamicAttributeTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E11B1AA80A6500DDB1C5 /* CCPUDynamicAttributeTranslator.h */; };
+ 507B3E4C1C31BDD30067B53E /* UIEditBoxImpl-win32.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ED2BDC19BEAF7900A0AB90 /* UIEditBoxImpl-win32.h */; };
+ 507B3E4E1C31BDD30067B53E /* CCPUOnExpireObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1771AA80A6500DDB1C5 /* CCPUOnExpireObserverTranslator.h */; };
+ 507B3E4F1C31BDD30067B53E /* CCGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD1E1925AB0000A911A9 /* CCGeometry.h */; };
+ 507B3E511C31BDD30067B53E /* CCPUOnCollisionObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1671AA80A6500DDB1C5 /* CCPUOnCollisionObserverTranslator.h */; };
+ 507B3E531C31BDD30067B53E /* CCAllocatorBase.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD033B1A3B51AA00825BB5 /* CCAllocatorBase.h */; };
+ 507B3E571C31BDD30067B53E /* CCFileUtils-apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF1B1926664700A911A9 /* CCFileUtils-apple.h */; };
+ 507B3E591C31BDD30067B53E /* CCFontAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570185180BCB590088DEC7 /* CCFontAtlas.h */; };
+ 507B3E5B1C31BDD30067B53E /* CCScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1685F1807AF4E005B8026 /* CCScrollView.h */; };
+ 507B3E5C1C31BDD30067B53E /* CCFontAtlasCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570187180BCB590088DEC7 /* CCFontAtlasCache.h */; };
+ 507B3E5D1C31BDD30067B53E /* CCPUSineForceAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C51AA80A6500DDB1C5 /* CCPUSineForceAffector.h */; };
+ 507B3E5E1C31BDD30067B53E /* UserCameraReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 182C5CE41A9D725400C30D34 /* UserCameraReader.h */; };
+ 507B3E601C31BDD30067B53E /* RecastDebugDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F7F1B04825B00E47F5F /* RecastDebugDraw.h */; };
+ 507B3E631C31BDD30067B53E /* CCFontFNT.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57018D180BCB590088DEC7 /* CCFontFNT.h */; };
+ 507B3E641C31BDD30067B53E /* DetourAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F851B04825B00E47F5F /* DetourAssert.h */; };
+ 507B3E651C31BDD30067B53E /* CCParticleSystemQuadLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D25180E26E600808F54 /* CCParticleSystemQuadLoader.h */; };
+ 507B3E661C31BDD30067B53E /* CCPUOnEventFlagObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1731AA80A6500DDB1C5 /* CCPUOnEventFlagObserverTranslator.h */; };
+ 507B3E691C31BDD30067B53E /* DetourTileCacheBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2FA31B04825B00E47F5F /* DetourTileCacheBuilder.h */; };
+ 507B3E6B1C31BDD30067B53E /* NodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384271A2590F9002C4610 /* NodeReader.h */; };
+ 507B3E6D1C31BDD30067B53E /* CCFontFreeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57018F180BCB590088DEC7 /* CCFontFreeType.h */; };
+ 507B3E6E1C31BDD30067B53E /* CCMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F419AAD2F700C27E9E /* CCMesh.h */; };
+ 507B3E701C31BDD30067B53E /* ImageViewReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7118C72017004AD434 /* ImageViewReader.h */; };
+ 507B3E711C31BDD30067B53E /* CCPUDoPlacementParticleEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E10F1AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandlerTranslator.h */; };
+ 507B3E731C31BDD30067B53E /* CCPUMeshSurfaceEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1571AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitterTranslator.h */; };
+ 507B3E741C31BDD30067B53E /* CCMenuLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D1C180E26E600808F54 /* CCMenuLoader.h */; };
+ 507B3E751C31BDD30067B53E /* CCPUSphereCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D31AA80A6500DDB1C5 /* CCPUSphereCollider.h */; };
+ 507B3E771C31BDD30067B53E /* DetourNavMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F8A1B04825B00E47F5F /* DetourNavMesh.h */; };
+ 507B3E781C31BDD30067B53E /* CCLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570191180BCB590088DEC7 /* CCLabel.h */; };
+ 507B3E791C31BDD30067B53E /* CCPUInterParticleColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E13D1AA80A6500DDB1C5 /* CCPUInterParticleColliderTranslator.h */; };
+ 507B3E7A1C31BDD30067B53E /* CCLabelAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570193180BCB590088DEC7 /* CCLabelAtlas.h */; };
+ 507B3E7C1C31BDD30067B53E /* CCEventListenerCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE51925AB6E00A911A9 /* CCEventListenerCustom.h */; };
+ 507B3E7D1C31BDD30067B53E /* CCPUFlockCenteringAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1291AA80A6500DDB1C5 /* CCPUFlockCenteringAffector.h */; };
+ 507B3E7E1C31BDD30067B53E /* DictionaryHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C598A180E930E00EF57C3 /* DictionaryHelper.h */; };
+ 507B3E801C31BDD30067B53E /* clipper.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 8525E3A11B291E42008EE815 /* clipper.hpp */; };
+ 507B3E821C31BDD30067B53E /* CCPUCircleEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F31AA80A6500DDB1C5 /* CCPUCircleEmitterTranslator.h */; };
+ 507B3E881C31BDD30067B53E /* HttpClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5363180E3374000584C8 /* HttpClient.h */; };
+ 507B3E8A1C31BDD30067B53E /* DetourNavMeshBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F8C1B04825B00E47F5F /* DetourNavMeshBuilder.h */; };
+ 507B3E8B1C31BDD30067B53E /* UIEditBoxImpl-android.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13319B4574100A80320 /* UIEditBoxImpl-android.h */; };
+ 507B3E8D1C31BDD30067B53E /* CCPUJetAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1411AA80A6500DDB1C5 /* CCPUJetAffectorTranslator.h */; };
+ 507B3E8E1C31BDD30067B53E /* GUIDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9EB18CF08D000240AA3 /* GUIDefine.h */; };
+ 507B3E8F1C31BDD30067B53E /* CCDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50693C5D1B6BF2AE005C5820 /* CCDownloader.h */; };
+ 507B3E911C31BDD30067B53E /* CCRay.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17FE19AAD2F700C27E9E /* CCRay.h */; };
+ 507B3E921C31BDD30067B53E /* ccShader_Position_uColor.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0B191D591000CE6051 /* ccShader_Position_uColor.frag */; };
+ 507B3E931C31BDD30067B53E /* CCLabelBMFont.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570195180BCB590088DEC7 /* CCLabelBMFont.h */; };
+ 507B3E951C31BDD30067B53E /* CCBatchNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C595B180E930E00EF57C3 /* CCBatchNode.h */; };
+ 507B3E961C31BDD30067B53E /* CCPUParticleSystem3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1911AA80A6500DDB1C5 /* CCPUParticleSystem3D.h */; };
+ 507B3E971C31BDD30067B53E /* CCPUDoEnableComponentEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1011AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandler.h */; };
+ 507B3E991C31BDD30067B53E /* CCPUPointEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A11AA80A6500DDB1C5 /* CCPUPointEmitterTranslator.h */; };
+ 507B3E9B1C31BDD30067B53E /* CCPhysicsSprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71EEF180E27CF00808F54 /* CCPhysicsSprite.h */; };
+ 507B3E9C1C31BDD30067B53E /* AssetsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5352180E3060000584C8 /* AssetsManager.h */; };
+ 507B3E9D1C31BDD30067B53E /* CCPULineAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1431AA80A6500DDB1C5 /* CCPULineAffector.h */; };
+ 507B3EA01C31BDD30067B53E /* HttpAsynConnection-apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B47A291A5349A3004E4C60 /* HttpAsynConnection-apple.h */; };
+ 507B3EA21C31BDD30067B53E /* HttpResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5365180E3374000584C8 /* HttpResponse.h */; };
+ 507B3EA31C31BDD30067B53E /* SimpleAudioEngine_objc.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FEC1807A56F005B8026 /* SimpleAudioEngine_objc.h */; };
+ 507B3EA41C31BDD30067B53E /* CCQuadCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD751925AB4100A911A9 /* CCQuadCommand.h */; };
+ 507B3EA51C31BDD30067B53E /* UILayoutManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 29CB8F4B1929D1BB00C841D6 /* UILayoutManager.h */; };
+ 507B3EA71C31BDD30067B53E /* CCRefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE001925AB6E00A911A9 /* CCRefPtr.h */; };
+ 507B3EA81C31BDD30067B53E /* CCSpriteLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D2B180E26E600808F54 /* CCSpriteLoader.h */; };
+ 507B3EAA1C31BDD30067B53E /* CCSSceneReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C597D180E930E00EF57C3 /* CCSSceneReader.h */; };
+ 507B3EAB1C31BDD30067B53E /* CCFloat.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67E18F57BE800EFE3A6 /* CCFloat.h */; };
+ 507B3EAC1C31BDD30067B53E /* CCPUAlignAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D31AA80A6500DDB1C5 /* CCPUAlignAffector.h */; };
+ 507B3EAD1C31BDD30067B53E /* DetourProximityGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F9E1B04825B00E47F5F /* DetourProximityGrid.h */; };
+ 507B3EAF1C31BDD30067B53E /* CCLabelTextFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570198180BCB590088DEC7 /* CCLabelTextFormatter.h */; };
+ 507B3EB41C31BDD30067B53E /* CCStdC.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BD819BFAF4400EF68ED /* CCStdC.h */; };
+ 507B3EB51C31BDD30067B53E /* ccShader_PositionTextureColorAlphaTest.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034C9FB191D591000CE6051 /* ccShader_PositionTextureColorAlphaTest.frag */; };
+ 507B3EB61C31BDD30067B53E /* UIDeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = 29080DEB191B82CE0066F8DF /* UIDeprecated.h */; };
+ 507B3EB81C31BDD30067B53E /* s3tc.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE181925AB6F00A911A9 /* s3tc.h */; };
+ 507B3EB91C31BDD30067B53E /* CCPlatformMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BE119BFCF1800EF68ED /* CCPlatformMacros.h */; };
+ 507B3EBA1C31BDD30067B53E /* CCControlSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168471807AF4E005B8026 /* CCControlSwitch.h */; };
+ 507B3EBB1C31BDD30067B53E /* CCMeshVertexIndexData.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F819AAD2F700C27E9E /* CCMeshVertexIndexData.h */; };
+ 507B3EBC1C31BDD30067B53E /* UIVBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E6D33318E174130051CA34 /* UIVBox.h */; };
+ 507B3EBD1C31BDD30067B53E /* CCLight.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EACC99F19F5014D00EB3C5E /* CCLight.h */; };
+ 507B3EBE1C31BDD30067B53E /* CCFrustum.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E9F61231A3FFE3D0038DE01 /* CCFrustum.h */; };
+ 507B3EBF1C31BDD30067B53E /* CCPUPositionEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A31AA80A6500DDB1C5 /* CCPUPositionEmitter.h */; };
+ 507B3EC01C31BDD30067B53E /* CCDataReaderHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5969180E930E00EF57C3 /* CCDataReaderHelper.h */; };
+ 507B3EC11C31BDD30067B53E /* CCPUDoExpireEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1071AA80A6500DDB1C5 /* CCPUDoExpireEventHandlerTranslator.h */; };
+ 507B3EC21C31BDD30067B53E /* CCSkinNode.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306681B60B583001E6D43 /* CCSkinNode.h */; };
+ 507B3EC41C31BDD30067B53E /* CCAllocatorMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03411A3B51AA00825BB5 /* CCAllocatorMacros.h */; };
+ 507B3EC51C31BDD30067B53E /* CCPUVelocityMatchingAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E91AA80A6500DDB1C5 /* CCPUVelocityMatchingAffector.h */; };
+ 507B3EC61C31BDD30067B53E /* CCLabelTTF.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57019A180BCB590088DEC7 /* CCLabelTTF.h */; };
+ 507B3EC81C31BDD30067B53E /* CCPUTextureRotatorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E31AA80A6500DDB1C5 /* CCPUTextureRotatorTranslator.h */; };
+ 507B3EC91C31BDD30067B53E /* CCRenderState.h in Headers */ = {isa = PBXBuildFile; fileRef = 5012168D1AC47380009A4BEA /* CCRenderState.h */; };
+ 507B3ECB1C31BDD30067B53E /* CCLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701D5180BCB8C0088DEC7 /* CCLayer.h */; };
+ 507B3ECF1C31BDD30067B53E /* CCPUOnTimeObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1871AA80A6500DDB1C5 /* CCPUOnTimeObserverTranslator.h */; };
+ 507B3ED01C31BDD30067B53E /* CCControlExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1683B1807AF4E005B8026 /* CCControlExtensions.h */; };
+ 507B3ED11C31BDD30067B53E /* CCScene.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701D7180BCB8C0088DEC7 /* CCScene.h */; };
+ 507B3ED31C31BDD30067B53E /* CCTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701D9180BCB8C0088DEC7 /* CCTransition.h */; };
+ 507B3ED41C31BDD30067B53E /* CheckBoxReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB6E18C72017004AD434 /* CheckBoxReader.h */; };
+ 507B3ED51C31BDD30067B53E /* UIAbstractCheckButton.h in Headers */ = {isa = PBXBuildFile; fileRef = B5CE6DBD1B3BF2B1002B0419 /* UIAbstractCheckButton.h */; };
+ 507B3ED61C31BDD30067B53E /* CCPUPlaneCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E19B1AA80A6500DDB1C5 /* CCPUPlaneCollider.h */; };
+ 507B3ED71C31BDD30067B53E /* DetourDebugDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F7D1B04825B00E47F5F /* DetourDebugDraw.h */; };
+ 507B3ED91C31BDD30067B53E /* Particle3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 18956BB11A9DFBFD006E9155 /* Particle3DReader.h */; };
+ 507B3EDA1C31BDD30067B53E /* DetourCrowd.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F941B04825B00E47F5F /* DetourCrowd.h */; };
+ 507B3EDC1C31BDD30067B53E /* CCPUSlaveEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1CF1AA80A6500DDB1C5 /* CCPUSlaveEmitterTranslator.h */; };
+ 507B3EDD1C31BDD30067B53E /* CCPUDoAffectorEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0FD1AA80A6500DDB1C5 /* CCPUDoAffectorEventHandler.h */; };
+ 507B3EDF1C31BDD30067B53E /* uthash.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE1B1925AB6F00A911A9 /* uthash.h */; };
+ 507B3EE01C31BDD30067B53E /* CCPURandomiserTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A91AA80A6500DDB1C5 /* CCPURandomiserTranslator.h */; };
+ 507B3EE21C31BDD30067B53E /* CCTransitionPageTurn.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701DB180BCB8C0088DEC7 /* CCTransitionPageTurn.h */; };
+ 507B3EE31C31BDD30067B53E /* CCTransitionProgress.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701DD180BCB8C0088DEC7 /* CCTransitionProgress.h */; };
+ 507B3EE61C31BDD30067B53E /* CCMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701F4180BCBAD0088DEC7 /* CCMenu.h */; };
+ 507B3EE71C31BDD30067B53E /* CCControlButtonLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D0B180E26E600808F54 /* CCControlButtonLoader.h */; };
+ 507B3EE81C31BDD30067B53E /* CCMenuItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5701F6180BCBAD0088DEC7 /* CCMenuItem.h */; };
+ 507B3EE91C31BDD30067B53E /* CCDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF221926664700A911A9 /* CCDevice.h */; };
+ 507B3EEA1C31BDD30067B53E /* CCClippingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570201180BCBD40088DEC7 /* CCClippingNode.h */; };
+ 507B3EEC1C31BDD30067B53E /* UICheckBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F318CF08D000240AA3 /* UICheckBox.h */; };
+ 507B3EEE1C31BDD30067B53E /* ccShader_PositionTexture_uColor.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA04191D591000CE6051 /* ccShader_PositionTexture_uColor.frag */; };
+ 507B3EEF1C31BDD30067B53E /* CCPUSphereSurfaceEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D91AA80A6500DDB1C5 /* CCPUSphereSurfaceEmitterTranslator.h */; };
+ 507B3EF21C31BDD30067B53E /* CCFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4CA194B19E400E608AF /* CCFrame.h */; };
+ 507B3EF31C31BDD30067B53E /* CCPUOnClearObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1611AA80A6500DDB1C5 /* CCPUOnClearObserver.h */; };
+ 507B3EF51C31BDD30067B53E /* CCTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168631807AF4E005B8026 /* CCTableView.h */; };
+ 507B3EF61C31BDD30067B53E /* CCPUPositionEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A51AA80A6500DDB1C5 /* CCPUPositionEmitterTranslator.h */; };
+ 507B3EF71C31BDD30067B53E /* CCParticleSystem3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B68778F71A8CA82E00643ABF /* CCParticleSystem3D.h */; };
+ 507B3EF81C31BDD30067B53E /* CCPUDoExpireEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1051AA80A6500DDB1C5 /* CCPUDoExpireEventHandler.h */; };
+ 507B3EF91C31BDD30067B53E /* shapes.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB207B1AE7C57D00C31518 /* shapes.h */; };
+ 507B3EFA1C31BDD30067B53E /* CCScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE021925AB6E00A911A9 /* CCScheduler.h */; };
+ 507B3EFC1C31BDD30067B53E /* CCMotionStreak.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570207180BCBDF0088DEC7 /* CCMotionStreak.h */; };
+ 507B3EFD1C31BDD30067B53E /* CCPUBehaviourManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E31AA80A6500DDB1C5 /* CCPUBehaviourManager.h */; };
+ 507B3EFE1C31BDD30067B53E /* CCDecorativeDisplay.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C596D180E930E00EF57C3 /* CCDecorativeDisplay.h */; };
+ 507B3EFF1C31BDD30067B53E /* DebugDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F7B1B04825B00E47F5F /* DebugDraw.h */; };
+ 507B3F001C31BDD30067B53E /* CCTween.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5981180E930E00EF57C3 /* CCTween.h */; };
+ 507B3F011C31BDD30067B53E /* CCComAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5961180E930E00EF57C3 /* CCComAttribute.h */; };
+ 507B3F031C31BDD30067B53E /* CCPhysics3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFD31AF9A9E100B9B856 /* CCPhysics3D.h */; };
+ 507B3F051C31BDD30067B53E /* GameMapReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384201A2590DA002C4610 /* GameMapReader.h */; };
+ 507B3F061C31BDD30067B53E /* DetourLocalBoundary.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F961B04825B00E47F5F /* DetourLocalBoundary.h */; };
+ 507B3F091C31BDD30067B53E /* CCPUBoxEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0EF1AA80A6500DDB1C5 /* CCPUBoxEmitterTranslator.h */; };
+ 507B3F0A1C31BDD30067B53E /* Manifest.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B3707719EE414C00ABE682 /* Manifest.h */; };
+ 507B3F0B1C31BDD30067B53E /* sweep.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20841AE7C57D00C31518 /* sweep.h */; };
+ 507B3F0C1C31BDD30067B53E /* CCProgressTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57020D180BCBF40088DEC7 /* CCProgressTimer.h */; };
+ 507B3F0D1C31BDD30067B53E /* CSArmatureNode_generated.h in Headers */ = {isa = PBXBuildFile; fileRef = 38F5263D1A48363B000DB7F7 /* CSArmatureNode_generated.h */; };
+ 507B3F0E1C31BDD30067B53E /* CCRenderTexture.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57020F180BCBF40088DEC7 /* CCRenderTexture.h */; };
+ 507B3F0F1C31BDD30067B53E /* CCTerrain.h in Headers */ = {isa = PBXBuildFile; fileRef = B603F1A71AC8EA0900A9579C /* CCTerrain.h */; };
+ 507B3F121C31BDD30067B53E /* WidgetReaderProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB9218C72017004AD434 /* WidgetReaderProtocol.h */; };
+ 507B3F131C31BDD30067B53E /* CCPUSlaveBehaviour.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C91AA80A6500DDB1C5 /* CCPUSlaveBehaviour.h */; };
+ 507B3F151C31BDD30067B53E /* WidgetReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB9118C72017004AD434 /* WidgetReader.h */; };
+ 507B3F161C31BDD30067B53E /* CCParticleBatchNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57021A180BCC1A0088DEC7 /* CCParticleBatchNode.h */; };
+ 507B3F181C31BDD30067B53E /* cdt.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20821AE7C57D00C31518 /* cdt.h */; };
+ 507B3F1B1C31BDD30067B53E /* CCNavMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C01B18492D006762CB /* CCNavMesh.h */; };
+ 507B3F1C1C31BDD30067B53E /* CCPUDoScaleEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1131AA80A6500DDB1C5 /* CCPUDoScaleEventHandlerTranslator.h */; };
+ 507B3F1D1C31BDD30067B53E /* CCUtilMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5985180E930E00EF57C3 /* CCUtilMath.h */; };
+ 507B3F1F1C31BDD30067B53E /* CCIMEDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8F21926B0DB00CD74DD /* CCIMEDelegate.h */; };
+ 507B3F201C31BDD30067B53E /* CCPhysics3DConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFD71AF9A9E100B9B856 /* CCPhysics3DConstraint.h */; };
+ 507B3F211C31BDD30067B53E /* CCParticleExamples.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57021C180BCC1A0088DEC7 /* CCParticleExamples.h */; };
+ 507B3F221C31BDD30067B53E /* CCPUVortexAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1EF1AA80A6500DDB1C5 /* CCPUVortexAffector.h */; };
+ 507B3F231C31BDD30067B53E /* CCParticleSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57021E180BCC1A0088DEC7 /* CCParticleSystem.h */; };
+ 507B3F251C31BDD30067B53E /* CCPUUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E71AA80A6500DDB1C5 /* CCPUUtil.h */; };
+ 507B3F261C31BDD30067B53E /* UILayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F918CF08D000240AA3 /* UILayout.h */; };
+ 507B3F271C31BDD30067B53E /* CCParticleSystemQuad.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570220180BCC1A0088DEC7 /* CCParticleSystemQuad.h */; };
+ 507B3F291C31BDD30067B53E /* UIWebView.h in Headers */ = {isa = PBXBuildFile; fileRef = 29394CEC19B01DBA00D2DE1A /* UIWebView.h */; };
+ 507B3F2A1C31BDD30067B53E /* CCUISingleLineTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 2980F01B1BA9A5550059E678 /* CCUISingleLineTextField.h */; };
+ 507B3F2C1C31BDD30067B53E /* CCBSelectorResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D03180E26E600808F54 /* CCBSelectorResolver.h */; };
+ 507B3F2D1C31BDD30067B53E /* CCFastTMXLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = B24AA982195A675C007B4522 /* CCFastTMXLayer.h */; };
+ 507B3F2F1C31BDD30067B53E /* UIListView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9FF18CF08D000240AA3 /* UIListView.h */; };
+ 507B3F301C31BDD30067B53E /* TriggerMng.h in Headers */ = {isa = PBXBuildFile; fileRef = 06CAAABF186AD63B0012A414 /* TriggerMng.h */; };
+ 507B3F311C31BDD30067B53E /* ccShader_PositionTextureA8Color.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA00191D591000CE6051 /* ccShader_PositionTextureA8Color.vert */; };
+ 507B3F331C31BDD30067B53E /* CCProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDFD1925AB6E00A911A9 /* CCProtocols.h */; };
+ 507B3F351C31BDD30067B53E /* AudioEngine-inl.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CB247119D9C5A100687767 /* AudioEngine-inl.h */; };
+ 507B3F361C31BDD30067B53E /* HttpCookie.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B47A2D1A5349A3004E4C60 /* HttpCookie.h */; };
+ 507B3F371C31BDD30067B53E /* CCMathBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD201925AB0000A911A9 /* CCMathBase.h */; };
+ 507B3F381C31BDD30067B53E /* CCProtectedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 15EFA210198A2BB5000C57D3 /* CCProtectedNode.h */; };
+ 507B3F3A1C31BDD30067B53E /* CCComBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 373B910718787C0B00198F86 /* CCComBase.h */; };
+ 507B3F3C1C31BDD30067B53E /* CCDisplayManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5971180E930E00EF57C3 /* CCDisplayManager.h */; };
+ 507B3F3D1C31BDD30067B53E /* UIButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F118CF08D000240AA3 /* UIButton.h */; };
+ 507B3F3E1C31BDD30067B53E /* ArmatureNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 38F5263C1A48363B000DB7F7 /* ArmatureNodeReader.h */; };
+ 507B3F401C31BDD30067B53E /* CCDirector.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD31925AB6E00A911A9 /* CCDirector.h */; };
+ 507B3F421C31BDD30067B53E /* ccShader_Label_df.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0F191D591000CE6051 /* ccShader_Label_df.frag */; };
+ 507B3F471C31BDD30067B53E /* CCPUDoAffectorEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0FF1AA80A6500DDB1C5 /* CCPUDoAffectorEventHandlerTranslator.h */; };
+ 507B3F481C31BDD30067B53E /* CCPUAffectorManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0CF1AA80A6500DDB1C5 /* CCPUAffectorManager.h */; };
+ 507B3F491C31BDD30067B53E /* CCUIEditBoxIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 2980F0171BA9A5550059E678 /* CCUIEditBoxIOS.h */; };
+ 507B3F4A1C31BDD30067B53E /* CCPUBoxEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0ED1AA80A6500DDB1C5 /* CCPUBoxEmitter.h */; };
+ 507B3F4D1C31BDD30067B53E /* UILoadingBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0118CF08D000240AA3 /* UILoadingBar.h */; };
+ 507B3F4E1C31BDD30067B53E /* CCControlPotentiometer.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1683F1807AF4E005B8026 /* CCControlPotentiometer.h */; };
+ 507B3F4F1C31BDD30067B53E /* CCControlButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168381807AF4E005B8026 /* CCControlButton.h */; };
+ 507B3F511C31BDD30067B53E /* CCPUOnRandomObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1811AA80A6500DDB1C5 /* CCPUOnRandomObserver.h */; };
+ 507B3F521C31BDD30067B53E /* CCSprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570277180BCC900088DEC7 /* CCSprite.h */; };
+ 507B3F531C31BDD30067B53E /* DetourNode.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F901B04825B00E47F5F /* DetourNode.h */; };
+ 507B3F541C31BDD30067B53E /* CCSpriteBatchNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570279180BCC900088DEC7 /* CCSpriteBatchNode.h */; };
+ 507B3F551C31BDD30067B53E /* CCArmatureDataManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5957180E930E00EF57C3 /* CCArmatureDataManager.h */; };
+ 507B3F561C31BDD30067B53E /* CCSpriteFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57027B180BCC900088DEC7 /* CCSpriteFrame.h */; };
+ 507B3F571C31BDD30067B53E /* UIText.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0C18CF08D100240AA3 /* UIText.h */; };
+ 507B3F591C31BDD30067B53E /* CCPhysics3DShape.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFDD1AF9A9E100B9B856 /* CCPhysics3DShape.h */; };
+ 507B3F5A1C31BDD30067B53E /* CCPUScriptLexer.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1BD1AA80A6500DDB1C5 /* CCPUScriptLexer.h */; };
+ 507B3F5B1C31BDD30067B53E /* CCEventListenerKeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE91925AB6E00A911A9 /* CCEventListenerKeyboard.h */; };
+ 507B3F5C1C31BDD30067B53E /* CCBSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D05180E26E600808F54 /* CCBSequence.h */; };
+ 507B3F5E1C31BDD30067B53E /* CCSpriteFrameCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57027D180BCC900088DEC7 /* CCSpriteFrameCache.h */; };
+ 507B3F5F1C31BDD30067B53E /* CCAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57028F180BCCAB0088DEC7 /* CCAnimation.h */; };
+ 507B3F621C31BDD30067B53E /* CCPUInterParticleCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E13B1AA80A6500DDB1C5 /* CCPUInterParticleCollider.h */; };
+ 507B3F631C31BDD30067B53E /* CCTexture2D.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD7E1925AB4100A911A9 /* CCTexture2D.h */; };
+ 507B3F661C31BDD30067B53E /* CCAnimate3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17E719AAD2F700C27E9E /* CCAnimate3D.h */; };
+ 507B3F671C31BDD30067B53E /* CCConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDCB1925AB6E00A911A9 /* CCConfiguration.h */; };
+ 507B3F681C31BDD30067B53E /* CCParticle3DEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B68778F31A8CA82E00643ABF /* CCParticle3DEmitter.h */; };
+ 507B3F691C31BDD30067B53E /* CCAnimationCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570291180BCCAB0088DEC7 /* CCAnimationCache.h */; };
+ 507B3F6B1C31BDD30067B53E /* CCPUFlockCenteringAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E12B1AA80A6500DDB1C5 /* CCPUFlockCenteringAffectorTranslator.h */; };
+ 507B3F6E1C31BDD30067B53E /* CCTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE061925AB6E00A911A9 /* CCTouch.h */; };
+ 507B3F6F1C31BDD30067B53E /* UILayoutParameter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9FD18CF08D000240AA3 /* UILayoutParameter.h */; };
+ 507B3F701C31BDD30067B53E /* CCMenuItemImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D19180E26E600808F54 /* CCMenuItemImageLoader.h */; };
+ 507B3F721C31BDD30067B53E /* CCBoneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306641B60B583001E6D43 /* CCBoneNode.h */; };
+ 507B3F731C31BDD30067B53E /* CCPUCollisionAvoidanceAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F71AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffectorTranslator.h */; };
+ 507B3F761C31BDD30067B53E /* CCNodeLoaderLibrary.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D22180E26E600808F54 /* CCNodeLoaderLibrary.h */; };
+ 507B3F791C31BDD30067B53E /* UITextView+CCUITextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 2980F0201BA9A5550059E678 /* UITextView+CCUITextInput.h */; };
+ 507B3F7A1C31BDD30067B53E /* CCEventListenerMouse.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDEB1925AB6E00A911A9 /* CCEventListenerMouse.h */; };
+ 507B3F7B1C31BDD30067B53E /* CCAllocatorMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03421A3B51AA00825BB5 /* CCAllocatorMutex.h */; };
+ 507B3F7D1C31BDD30067B53E /* CCTextFieldTTF.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702C7180BCE370088DEC7 /* CCTextFieldTTF.h */; };
+ 507B3F7E1C31BDD30067B53E /* CCTileMapAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E1180BCE750088DEC7 /* CCTileMapAtlas.h */; };
+ 507B3F7F1C31BDD30067B53E /* CCSkin.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5979180E930E00EF57C3 /* CCSkin.h */; };
+ 507B3F811C31BDD30067B53E /* DetourObstacleAvoidance.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F981B04825B00E47F5F /* DetourObstacleAvoidance.h */; };
+ 507B3F831C31BDD30067B53E /* CCTMXLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E3180BCE750088DEC7 /* CCTMXLayer.h */; };
+ 507B3F841C31BDD30067B53E /* CCAutoPolygon.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20731AE7BF8600C31518 /* CCAutoPolygon.h */; };
+ 507B3F861C31BDD30067B53E /* CCBFileLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71CFD180E26E600808F54 /* CCBFileLoader.h */; };
+ 507B3F881C31BDD30067B53E /* CCActionTimeline.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4C6194B19E400E608AF /* CCActionTimeline.h */; };
+ 507B3F891C31BDD30067B53E /* CCPhysics3DDebugDrawer.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFD91AF9A9E100B9B856 /* CCPhysics3DDebugDrawer.h */; };
+ 507B3F8B1C31BDD30067B53E /* ccShader_Label.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0C191D591000CE6051 /* ccShader_Label.vert */; };
+ 507B3F8C1C31BDD30067B53E /* CCTMXObjectGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E5180BCE750088DEC7 /* CCTMXObjectGroup.h */; };
+ 507B3F8D1C31BDD30067B53E /* CCTMXTiledMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E7180BCE750088DEC7 /* CCTMXTiledMap.h */; };
+ 507B3F8E1C31BDD30067B53E /* CCEventAssetsManagerEx.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B3707119EE414C00ABE682 /* CCEventAssetsManagerEx.h */; };
+ 507B3F8F1C31BDD30067B53E /* ConvertUTF.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AC026991914068200FA920D /* ConvertUTF.h */; };
+ 507B3F911C31BDD30067B53E /* HttpConnection-winrt.h in Headers */ = {isa = PBXBuildFile; fileRef = 5070031A1B69735200E83DDD /* HttpConnection-winrt.h */; };
+ 507B3F921C31BDD30067B53E /* CCTMXXMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702E9180BCE750088DEC7 /* CCTMXXMLParser.h */; };
+ 507B3F931C31BDD30067B53E /* CCPURender.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1AB1AA80A6500DDB1C5 /* CCPURender.h */; };
+ 507B3F941C31BDD30067B53E /* CCPUPlaneColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E19D1AA80A6500DDB1C5 /* CCPUPlaneColliderTranslator.h */; };
+ 507B3F961C31BDD30067B53E /* UIScale9Sprite.h in Headers */ = {isa = PBXBuildFile; fileRef = 2958244A19873D8E00F9746D /* UIScale9Sprite.h */; };
+ 507B3F971C31BDD30067B53E /* CCBAnimationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71CFB180E26E600808F54 /* CCBAnimationManager.h */; };
+ 507B3F991C31BDD30067B53E /* UIEditBoxImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13119B4574100A80320 /* UIEditBoxImpl.h */; };
+ 507B3F9B1C31BDD30067B53E /* CCParallaxNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5702FF180BCE890088DEC7 /* CCParallaxNode.h */; };
+ 507B3F9C1C31BDD30067B53E /* CCAutoreleasePool.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC61925AB6E00A911A9 /* CCAutoreleasePool.h */; };
+ 507B3F9D1C31BDD30067B53E /* CCPhysics3DWorld.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFDF1AF9A9E100B9B856 /* CCPhysics3DWorld.h */; };
+ 507B3F9E1C31BDD30067B53E /* CCPass.h in Headers */ = {isa = PBXBuildFile; fileRef = 501216931AC47393009A4BEA /* CCPass.h */; };
+ 507B3F9F1C31BDD30067B53E /* CCComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570309180BCF190088DEC7 /* CCComponent.h */; };
+ 507B3FA01C31BDD30067B53E /* CCPUBoxCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E91AA80A6500DDB1C5 /* CCPUBoxCollider.h */; };
+ 507B3FA21C31BDD30067B53E /* CCSkeletonNode.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306661B60B583001E6D43 /* CCSkeletonNode.h */; };
+ 507B3FA41C31BDD30067B53E /* CCBKeyframe.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71CFF180E26E600808F54 /* CCBKeyframe.h */; };
+ 507B3FA51C31BDD30067B53E /* CCLayerGradientLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D15180E26E600808F54 /* CCLayerGradientLoader.h */; };
+ 507B3FA71C31BDD30067B53E /* CCPUOnPositionObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E17B1AA80A6500DDB1C5 /* CCPUOnPositionObserverTranslator.h */; };
+ 507B3FA91C31BDD30067B53E /* CCComponentContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57030B180BCF190088DEC7 /* CCComponentContainer.h */; };
+ 507B3FAB1C31BDD30067B53E /* CCTextureCube.h in Headers */ = {isa = PBXBuildFile; fileRef = A045F6D51BA81577005076C7 /* CCTextureCube.h */; };
+ 507B3FAD1C31BDD30067B53E /* CCPULineEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E14D1AA80A6500DDB1C5 /* CCPULineEmitterTranslator.h */; };
+ 507B3FAE1C31BDD30067B53E /* edtaa3func.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A087AE71860400400196EF5 /* edtaa3func.h */; };
+ 507B3FAF1C31BDD30067B53E /* CCPUParticleFollower.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E18D1AA80A6500DDB1C5 /* CCPUParticleFollower.h */; };
+ 507B3FB11C31BDD30067B53E /* CocosDenshion.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE91807A56F005B8026 /* CocosDenshion.h */; };
+ 507B3FB31C31BDD30067B53E /* UIScrollViewBar.h in Headers */ = {isa = PBXBuildFile; fileRef = B5668D7C1B3838E4003CBD5E /* UIScrollViewBar.h */; };
+ 507B3FB41C31BDD30067B53E /* CCColliderDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C595F180E930E00EF57C3 /* CCColliderDetector.h */; };
+ 507B3FB61C31BDD30067B53E /* CCAllocatorStrategyFixedBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03441A3B51AA00825BB5 /* CCAllocatorStrategyFixedBlock.h */; };
+ 507B3FB71C31BDD30067B53E /* ExtensionMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168321807AF4E005B8026 /* ExtensionMacros.h */; };
+ 507B3FB81C31BDD30067B53E /* CDConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE61807A56F005B8026 /* CDConfig.h */; };
+ 507B3FBB1C31BDD30067B53E /* tinyxml2.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A57034A180BD09B0088DEC7 /* tinyxml2.h */; };
+ 507B3FBC1C31BDD30067B53E /* CCInvocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1684B1807AF4E005B8026 /* CCInvocation.h */; };
+ 507B3FBE1C31BDD30067B53E /* ioapi.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570351180BD0B00088DEC7 /* ioapi.h */; };
+ 507B3FC01C31BDD30067B53E /* Mat4.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD241925AB0000A911A9 /* Mat4.h */; };
+ 507B3FC11C31BDD30067B53E /* CCPUPathFollowerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1971AA80A6500DDB1C5 /* CCPUPathFollowerTranslator.h */; };
+ 507B3FC41C31BDD30067B53E /* CCPhysicsSprite3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFE11AF9A9E100B9B856 /* CCPhysicsSprite3D.h */; };
+ 507B3FC51C31BDD30067B53E /* SocketIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF5367180E3374000584C8 /* SocketIO.h */; };
+ 507B3FC61C31BDD30067B53E /* CCPUOnEmissionObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E16D1AA80A6500DDB1C5 /* CCPUOnEmissionObserver.h */; };
+ 507B3FC71C31BDD30067B53E /* CCPUParticleSystem3DTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1931AA80A6500DDB1C5 /* CCPUParticleSystem3DTranslator.h */; };
+ 507B3FC81C31BDD30067B53E /* DetourAlloc.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F841B04825B00E47F5F /* DetourAlloc.h */; };
+ 507B3FCA1C31BDD30067B53E /* CCPUBaseForceAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0DD1AA80A6500DDB1C5 /* CCPUBaseForceAffectorTranslator.h */; };
+ 507B3FCB1C31BDD30067B53E /* CCSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C68118F57BE800EFE3A6 /* CCSet.h */; };
+ 507B3FCC1C31BDD30067B53E /* CCPUSphereColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D51AA80A6500DDB1C5 /* CCPUSphereColliderTranslator.h */; };
+ 507B3FCD1C31BDD30067B53E /* utlist.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE1C1925AB6F00A911A9 /* utlist.h */; };
+ 507B3FCE1C31BDD30067B53E /* unzip.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A570353180BD0B00088DEC7 /* unzip.h */; };
+ 507B3FD11C31BDD30067B53E /* UIHBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E6D32F18E174130051CA34 /* UIHBox.h */; };
+ 507B3FD31C31BDD30067B53E /* CCProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 505385001B01887A00793096 /* CCProperties.h */; };
+ 507B3FD51C31BDD30067B53E /* ccShader_Label_normal.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA0E191D591000CE6051 /* ccShader_Label_normal.frag */; };
+ 507B3FD91C31BDD30067B53E /* CCSkeleton3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE180019AAD2F700C27E9E /* CCSkeleton3D.h */; };
+ 507B3FDA1C31BDD30067B53E /* Quaternion.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD2B1925AB0000A911A9 /* Quaternion.h */; };
+ 507B3FDB1C31BDD30067B53E /* CCTechnique.h in Headers */ = {isa = PBXBuildFile; fileRef = 501216991AC473A3009A4BEA /* CCTechnique.h */; };
+ 507B3FDD1C31BDD30067B53E /* ScrollViewReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8018C72017004AD434 /* ScrollViewReader.h */; };
+ 507B3FDE1C31BDD30067B53E /* CCES2Renderer-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8D61926736A00CD74DD /* CCES2Renderer-ios.h */; };
+ 507B3FDF1C31BDD30067B53E /* CCPUTextureRotator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E11AA80A6500DDB1C5 /* CCPUTextureRotator.h */; };
+ 507B3FE01C31BDD30067B53E /* CCPUOnPositionObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1791AA80A6500DDB1C5 /* CCPUOnPositionObserver.h */; };
+ 507B3FE31C31BDD30067B53E /* CCEventListenerFocus.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE71925AB6E00A911A9 /* CCEventListenerFocus.h */; };
+ 507B3FE41C31BDD30067B53E /* ccShader_PositionColor.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA09191D591000CE6051 /* ccShader_PositionColor.frag */; };
+ 507B3FE61C31BDD30067B53E /* Sprite3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 182C5CD51A98F30500C30D34 /* Sprite3DReader.h */; };
+ 507B3FE71C31BDD30067B53E /* ccConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC91925AB6E00A911A9 /* ccConfig.h */; };
+ 507B3FE81C31BDD30067B53E /* DetourPathCorridor.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F9A1B04825B00E47F5F /* DetourPathCorridor.h */; };
+ 507B3FE91C31BDD30067B53E /* CCInputDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5973180E930E00EF57C3 /* CCInputDelegate.h */; };
+ 507B3FEB1C31BDD30067B53E /* RecastDump.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F811B04825B00E47F5F /* RecastDump.h */; };
+ 507B3FEC1C31BDD30067B53E /* CCRenderCommandPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD781925AB4100A911A9 /* CCRenderCommandPool.h */; };
+ 507B3FEE1C31BDD30067B53E /* CCPUScaleVelocityAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B91AA80A6500DDB1C5 /* CCPUScaleVelocityAffectorTranslator.h */; };
+ 507B3FF01C31BDD30067B53E /* CCPUOnVelocityObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E18B1AA80A6500DDB1C5 /* CCPUOnVelocityObserverTranslator.h */; };
+ 507B3FF11C31BDD30067B53E /* ccShader_PositionColor.vert in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA08191D591000CE6051 /* ccShader_PositionColor.vert */; };
+ 507B3FF21C31BDD30067B53E /* CCPUSlaveEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1CD1AA80A6500DDB1C5 /* CCPUSlaveEmitter.h */; };
+ 507B3FF31C31BDD30067B53E /* CCImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF281926664700A911A9 /* CCImage.h */; };
+ 507B3FF41C31BDD30067B53E /* CCPUForceFieldAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E12F1AA80A6500DDB1C5 /* CCPUForceFieldAffector.h */; };
+ 507B3FF81C31BDD30067B53E /* SpriteReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384431A25915C002C4610 /* SpriteReader.h */; };
+ 507B3FF91C31BDD30067B53E /* CCNS.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF81925AB6E00A911A9 /* CCNS.h */; };
+ 507B3FFA1C31BDD30067B53E /* CCPUMeshSurfaceEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1551AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitter.h */; };
+ 507B3FFC1C31BDD30067B53E /* CCPUCircleEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F11AA80A6500DDB1C5 /* CCPUCircleEmitter.h */; };
+ 507B3FFD1C31BDD30067B53E /* CCScriptSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE041925AB6E00A911A9 /* CCScriptSupport.h */; };
+ 507B3FFF1C31BDD30067B53E /* xxhash.h in Headers */ = {isa = PBXBuildFile; fileRef = 46C02E0618E91123004B7456 /* xxhash.h */; };
+ 507B40011C31BDD30067B53E /* ccShader_Label_df_glow.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA10191D591000CE6051 /* ccShader_Label_df_glow.frag */; };
+ 507B40031C31BDD30067B53E /* CCGL-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8D91926736A00CD74DD /* CCGL-ios.h */; };
+ 507B40041C31BDD30067B53E /* CCPUSphereSurfaceEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D71AA80A6500DDB1C5 /* CCPUSphereSurfaceEmitter.h */; };
+ 507B40061C31BDD30067B53E /* CCData.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDCF1925AB6E00A911A9 /* CCData.h */; };
+ 507B400A1C31BDD30067B53E /* CCIMEDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8F41926B0DB00CD74DD /* CCIMEDispatcher.h */; };
+ 507B400F1C31BDD30067B53E /* CCPUOnQuotaObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E17F1AA80A6500DDB1C5 /* CCPUOnQuotaObserverTranslator.h */; };
+ 507B40101C31BDD30067B53E /* etc1.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE151925AB6F00A911A9 /* etc1.h */; };
+ 507B40121C31BDD30067B53E /* CCRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD7A1925AB4100A911A9 /* CCRenderer.h */; };
+ 507B40141C31BDD30067B53E /* CCMeshCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594B31926D5EC003EEF37 /* CCMeshCommand.h */; };
+ 507B40151C31BDD30067B53E /* CCEventListenerController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E6176641960F89B00DE83F5 /* CCEventListenerController.h */; };
+ 507B40161C31BDD30067B53E /* CCBatchCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD651925AB4100A911A9 /* CCBatchCommand.h */; };
+ 507B40171C31BDD30067B53E /* CCMenuItemLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D1B180E26E600808F54 /* CCMenuItemLoader.h */; };
+ 507B40191C31BDD30067B53E /* CCEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD51925AB6E00A911A9 /* CCEvent.h */; };
+ 507B401A1C31BDD30067B53E /* cocos2d.h in Headers */ = {isa = PBXBuildFile; fileRef = 50272538190BF1B900AAF4ED /* cocos2d.h */; };
+ 507B401C1C31BDD30067B53E /* CCNinePatchImageParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 291901411B05895600F8B4BA /* CCNinePatchImageParser.h */; };
+ 507B401D1C31BDD30067B53E /* CCController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E6176561960F89B00DE83F5 /* CCController.h */; };
+ 507B401F1C31BDD30067B53E /* ComAudioReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384191A2590D2002C4610 /* ComAudioReader.h */; };
+ 507B40201C31BDD30067B53E /* CCGameController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E6176651960F89B00DE83F5 /* CCGameController.h */; };
+ 507B40221C31BDD30067B53E /* TextReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8F18C72017004AD434 /* TextReader.h */; };
+ 507B40231C31BDD30067B53E /* CCEventListenerAcceleration.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE31925AB6E00A911A9 /* CCEventListenerAcceleration.h */; };
+ 507B40241C31BDD30067B53E /* CCAABB.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17E519AAD2F700C27E9E /* CCAABB.h */; };
+ 507B40251C31BDD30067B53E /* CCGLProgramCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD6B1925AB4100A911A9 /* CCGLProgramCache.h */; };
+ 507B40271C31BDD30067B53E /* CCProfiling.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDFC1925AB6E00A911A9 /* CCProfiling.h */; };
+ 507B40281C31BDD30067B53E /* TextAtlasReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB8618C72017004AD434 /* TextAtlasReader.h */; };
+ 507B40291C31BDD30067B53E /* CCScale9SpriteLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D27180E26E600808F54 /* CCScale9SpriteLoader.h */; };
+ 507B402A1C31BDD30067B53E /* CCMeshSkin.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F619AAD2F700C27E9E /* CCMeshSkin.h */; };
+ 507B402B1C31BDD30067B53E /* CCPUBehaviourTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E51AA80A6500DDB1C5 /* CCPUBehaviourTranslator.h */; };
+ 507B402C1C31BDD30067B53E /* CCPUOnTimeObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1851AA80A6500DDB1C5 /* CCPUOnTimeObserver.h */; };
+ 507B402E1C31BDD30067B53E /* UISlider.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA0A18CF08D100240AA3 /* UISlider.h */; };
+ 507B402F1C31BDD30067B53E /* CCApplication-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8CE1926736A00CD74DD /* CCApplication-ios.h */; };
+ 507B40311C31BDD30067B53E /* CCPUTechniqueTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1DB1AA80A6500DDB1C5 /* CCPUTechniqueTranslator.h */; };
+ 507B40321C31BDD30067B53E /* UITextBMFont.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA1018CF08D100240AA3 /* UITextBMFont.h */; };
+ 507B40341C31BDD30067B53E /* CCGLProgram.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD691925AB4100A911A9 /* CCGLProgram.h */; };
+ 507B40351C31BDD30067B53E /* CSLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 38B8E2D419E66581002D7CE7 /* CSLoader.h */; };
+ 507B40361C31BDD30067B53E /* CCApplicationProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF201926664700A911A9 /* CCApplicationProtocol.h */; };
+ 507B40371C31BDD30067B53E /* CCFontCharMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABA68AD1888D700007D1BB4 /* CCFontCharMap.h */; };
+ 507B40391C31BDD30067B53E /* CCAllocatorStrategyPool.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03461A3B51AA00825BB5 /* CCAllocatorStrategyPool.h */; };
+ 507B403A1C31BDD30067B53E /* CCTimeLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0634A4CE194B19E400E608AF /* CCTimeLine.h */; };
+ 507B403B1C31BDD30067B53E /* UILayoutComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 38B8E2E019E671D2002D7CE7 /* UILayoutComponent.h */; };
+ 507B403D1C31BDD30067B53E /* CCPUGravityAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1391AA80A6500DDB1C5 /* CCPUGravityAffectorTranslator.h */; };
+ 507B403E1C31BDD30067B53E /* MathUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD271925AB0000A911A9 /* MathUtil.h */; };
+ 507B403F1C31BDD30067B53E /* CCInteger.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67F18F57BE800EFE3A6 /* CCInteger.h */; };
+ 507B40401C31BDD30067B53E /* CCSkybox.h in Headers */ = {isa = PBXBuildFile; fileRef = B6D38B871AC3AFAC00043997 /* CCSkybox.h */; };
+ 507B40411C31BDD30067B53E /* CCTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168651807AF4E005B8026 /* CCTableViewCell.h */; };
+ 507B40421C31BDD30067B53E /* CCPUTranslateManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E51AA80A6500DDB1C5 /* CCPUTranslateManager.h */; };
+ 507B40431C31BDD30067B53E /* ListViewReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7718C72017004AD434 /* ListViewReader.h */; };
+ 507B40441C31BDD30067B53E /* CCVertexAttribBinding.h in Headers */ = {isa = PBXBuildFile; fileRef = 5053850B1B02819E00793096 /* CCVertexAttribBinding.h */; };
+ 507B40461C31BDD30067B53E /* ccUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE101925AB6F00A911A9 /* ccUtils.h */; };
+ 507B40471C31BDD30067B53E /* CCObjLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17FC19AAD2F700C27E9E /* CCObjLoader.h */; };
+ 507B40481C31BDD30067B53E /* CCNodeLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D20180E26E600808F54 /* CCNodeLoader.h */; };
+ 507B40491C31BDD30067B53E /* CCEventTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF11925AB6E00A911A9 /* CCEventTouch.h */; };
+ 507B404A1C31BDD30067B53E /* CCPUAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D11AA80A6500DDB1C5 /* CCPUAffectorTranslator.h */; };
+ 507B404B1C31BDD30067B53E /* ccRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 299CF1FA19A434BC00C378C1 /* ccRandom.h */; };
+ 507B404C1C31BDD30067B53E /* CCPURibbonTrailRender.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B11AA80A6500DDB1C5 /* CCPURibbonTrailRender.h */; };
+ 507B404D1C31BDD30067B53E /* CCTextureAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD801925AB4100A911A9 /* CCTextureAtlas.h */; };
+ 507B404E1C31BDD30067B53E /* DetourCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F871B04825B00E47F5F /* DetourCommon.h */; };
+ 507B404F1C31BDD30067B53E /* CCPhysics3DComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFD51AF9A9E100B9B856 /* CCPhysics3DComponent.h */; };
+ 507B40501C31BDD30067B53E /* CCBundleReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 15AE17F219AAD2F700C27E9E /* CCBundleReader.h */; };
+ 507B40511C31BDD30067B53E /* Node3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 182C5CB11A95964700C30D34 /* Node3DReader.h */; };
+ 507B40521C31BDD30067B53E /* CCEventDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDDB1925AB6E00A911A9 /* CCEventDispatcher.h */; };
+ 507B40531C31BDD30067B53E /* CCTweenFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 2986667918B1B079000E39CA /* CCTweenFunction.h */; };
+ 507B40541C31BDD30067B53E /* TriggerBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 06CAAABD186AD63B0012A414 /* TriggerBase.h */; };
+ 507B40571C31BDD30067B53E /* CCPUSlaveBehaviourTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1CB1AA80A6500DDB1C5 /* CCPUSlaveBehaviourTranslator.h */; };
+ 507B40581C31BDD30067B53E /* CCControlSaturationBrightnessPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168411807AF4E005B8026 /* CCControlSaturationBrightnessPicker.h */; };
+ 507B405A1C31BDD30067B53E /* CCPUDoFreezeEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1091AA80A6500DDB1C5 /* CCPUDoFreezeEventHandler.h */; };
+ 507B405B1C31BDD30067B53E /* CCGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 50643BD319BFAECF00EF68ED /* CCGL.h */; };
+ 507B405C1C31BDD30067B53E /* CCArmatureAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5955180E930E00EF57C3 /* CCArmatureAnimation.h */; };
+ 507B405E1C31BDD30067B53E /* CCVertexIndexData.h in Headers */ = {isa = PBXBuildFile; fileRef = B276EF5B1988D1D500CD400F /* CCVertexIndexData.h */; };
+ 507B405F1C31BDD30067B53E /* Vec3.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD331925AB0000A911A9 /* Vec3.h */; };
+ 507B40601C31BDD30067B53E /* CCEventType.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF21925AB6E00A911A9 /* CCEventType.h */; };
+ 507B40631C31BDD30067B53E /* CCComRender.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5967180E930E00EF57C3 /* CCComRender.h */; };
+ 507B40641C31BDD30067B53E /* CCPUGeometryRotator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1331AA80A6500DDB1C5 /* CCPUGeometryRotator.h */; };
+ 507B40651C31BDD30067B53E /* LocalStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF584D180E40B9000584C8 /* LocalStorage.h */; };
+ 507B40661C31BDD30067B53E /* AudioCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CB246F19D9C5A100687767 /* AudioCache.h */; };
+ 507B40691C31BDD30067B53E /* CCBone.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C595D180E930E00EF57C3 /* CCBone.h */; };
+ 507B406A1C31BDD30067B53E /* CCAllocatorStrategyDefault.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03431A3B51AA00825BB5 /* CCAllocatorStrategyDefault.h */; };
+ 507B406B1C31BDD30067B53E /* CCVertex.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD221925AB0000A911A9 /* CCVertex.h */; };
+ 507B406F1C31BDD30067B53E /* CCPUOnCollisionObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1651AA80A6500DDB1C5 /* CCPUOnCollisionObserver.h */; };
+ 507B40731C31BDD30067B53E /* CCParticle3DRender.h in Headers */ = {isa = PBXBuildFile; fileRef = B68778F51A8CA82E00643ABF /* CCParticle3DRender.h */; };
+ 507B40741C31BDD30067B53E /* DetourTileCache.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2FA11B04825B00E47F5F /* DetourTileCache.h */; };
+ 507B40751C31BDD30067B53E /* CCProcessBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5975180E930E00EF57C3 /* CCProcessBase.h */; };
+ 507B40761C31BDD30067B53E /* CCArmatureDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5959180E930E00EF57C3 /* CCArmatureDefine.h */; };
+ 507B40791C31BDD30067B53E /* CSParseBinary_generated.h in Headers */ = {isa = PBXBuildFile; fileRef = 382384021A259005002C4610 /* CSParseBinary_generated.h */; };
+ 507B407C1C31BDD30067B53E /* CCDisplayFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C596F180E930E00EF57C3 /* CCDisplayFactory.h */; };
+ 507B407D1C31BDD30067B53E /* CCGLBufferedNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A9DCA03180E6955007A3AD4 /* CCGLBufferedNode.h */; };
+ 507B407E1C31BDD30067B53E /* CCString.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C68318F57BE800EFE3A6 /* CCString.h */; };
+ 507B407F1C31BDD30067B53E /* pvr.h in Headers */ = {isa = PBXBuildFile; fileRef = 464AD6E4197EBB1400E502D8 /* pvr.h */; };
+ 507B40821C31BDD30067B53E /* CCComAudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5963180E930E00EF57C3 /* CCComAudio.h */; };
+ 507B40831C31BDD30067B53E /* CCDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67C18F57BE800EFE3A6 /* CCDictionary.h */; };
+ 507B40841C31BDD30067B53E /* CCPUOnClearObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1631AA80A6500DDB1C5 /* CCPUOnClearObserverTranslator.h */; };
+ 507B40851C31BDD30067B53E /* ccShader_PositionTexture.frag in Headers */ = {isa = PBXBuildFile; fileRef = 5034CA05191D591000CE6051 /* ccShader_PositionTexture.frag */; };
+ 507B40861C31BDD30067B53E /* CCFastTMXTiledMap.h in Headers */ = {isa = PBXBuildFile; fileRef = B24AA984195A675C007B4522 /* CCFastTMXTiledMap.h */; };
+ 507B40881C31BDD30067B53E /* ccTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE081925AB6E00A911A9 /* ccTypes.h */; };
+ 507B408A1C31BDD30067B53E /* CDAudioManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE41807A56F005B8026 /* CDAudioManager.h */; };
+ 507B408C1C31BDD30067B53E /* Light3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C261F271BE7528900707478 /* Light3DReader.h */; };
+ 507B408D1C31BDD30067B53E /* CCPUPlane.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1991AA80A6500DDB1C5 /* CCPUPlane.h */; };
+ 507B40901C31BDD30067B53E /* CCControlStepper.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168451807AF4E005B8026 /* CCControlStepper.h */; };
+ 507B40911C31BDD30067B53E /* base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC41925AB6E00A911A9 /* base64.h */; };
+ 507B40941C31BDD30067B53E /* CCPhysicsDebugNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71EED180E27CF00808F54 /* CCPhysicsDebugNode.h */; };
+ 507B40951C31BDD30067B53E /* CCControlSlider.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168431807AF4E005B8026 /* CCControlSlider.h */; };
+ 507B40991C31BDD30067B53E /* CCPUBaseCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D71AA80A6500DDB1C5 /* CCPUBaseCollider.h */; };
+ 507B409A1C31BDD30067B53E /* CCArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67718F57BE800EFE3A6 /* CCArray.h */; };
+ 507B409B1C31BDD30067B53E /* CCPUScriptTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C11AA80A6500DDB1C5 /* CCPUScriptTranslator.h */; };
+ 507B409C1C31BDD30067B53E /* CCNotificationCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C6A318F58F7500EFE3A6 /* CCNotificationCenter.h */; };
+ 507B409D1C31BDD30067B53E /* ZipUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE1E1925AB6F00A911A9 /* ZipUtils.h */; };
+ 507B409E1C31BDD30067B53E /* CCTextureCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD821925AB4100A911A9 /* CCTextureCache.h */; };
+ 507B409F1C31BDD30067B53E /* CCVertexIndexBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = B276EF5D1988D1D500CD400F /* CCVertexIndexBuffer.h */; };
+ 507B40A01C31BDD30067B53E /* CCPULineEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E14B1AA80A6500DDB1C5 /* CCPULineEmitter.h */; };
+ 507B40A11C31BDD30067B53E /* CCNodeGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9C6A9318599AD8000A5232 /* CCNodeGrid.h */; };
+ 507B40A21C31BDD30067B53E /* CCThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF2C1926664700A911A9 /* CCThread.h */; };
+ 507B40A31C31BDD30067B53E /* UITextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905FA1218CF08D100240AA3 /* UITextField.h */; };
+ 507B40A41C31BDD30067B53E /* CCDouble.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67D18F57BE800EFE3A6 /* CCDouble.h */; };
+ 507B40A51C31BDD30067B53E /* CCPUColorAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0FB1AA80A6500DDB1C5 /* CCPUColorAffectorTranslator.h */; };
+ 507B40A71C31BDD30067B53E /* Export.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE11807A56F005B8026 /* Export.h */; };
+ 507B40AB1C31BDD30067B53E /* CCSpriteFrameCacheHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C597B180E930E00EF57C3 /* CCSpriteFrameCacheHelper.h */; };
+ 507B40AC1C31BDD30067B53E /* atitc.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC21925AB6E00A911A9 /* atitc.h */; };
+ 507B40AD1C31BDD30067B53E /* CCPUSimpleSpline.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C31AA80A6500DDB1C5 /* CCPUSimpleSpline.h */; };
+ 507B40B01C31BDD30067B53E /* CCPUOnExpireObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1751AA80A6500DDB1C5 /* CCPUOnExpireObserver.h */; };
+ 507B40B11C31BDD30067B53E /* CCActionNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C594F180E930E00EF57C3 /* CCActionNode.h */; };
+ 507B40B31C31BDD30067B53E /* CCPhysics3DObject.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFDB1AF9A9E100B9B856 /* CCPhysics3DObject.h */; };
+ 507B40B41C31BDD30067B53E /* SkeletonNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306741B60B5B2001E6D43 /* SkeletonNodeReader.h */; };
+ 507B40B61C31BDD30067B53E /* TGAlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE1A1925AB6F00A911A9 /* TGAlib.h */; };
+ 507B40B71C31BDD30067B53E /* CCPUEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E11D1AA80A6500DDB1C5 /* CCPUEmitter.h */; };
+ 507B40BA1C31BDD30067B53E /* UIPageViewIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = B5A738951BB0051F00BAAEF8 /* UIPageViewIndicator.h */; };
+ 507B40BB1C31BDD30067B53E /* CCControlColourPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A1683A1807AF4E005B8026 /* CCControlColourPicker.h */; };
+ 507B40BC1C31BDD30067B53E /* CCDatas.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C596B180E930E00EF57C3 /* CCDatas.h */; };
+ 507B40BD1C31BDD30067B53E /* CCBReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D02180E26E600808F54 /* CCBReader.h */; };
+ 507B40BE1C31BDD30067B53E /* CCNodeLoaderListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D23180E26E600808F54 /* CCNodeLoaderListener.h */; };
+ 507B40BF1C31BDD30067B53E /* SimpleAudioEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A15FE21807A56F005B8026 /* SimpleAudioEngine.h */; };
+ 507B40C01C31BDD30067B53E /* CCPUOnQuotaObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E17D1AA80A6500DDB1C5 /* CCPUOnQuotaObserver.h */; };
+ 507B40C11C31BDD30067B53E /* CCNavMeshAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C21B18492D006762CB /* CCNavMeshAgent.h */; };
+ 507B40C21C31BDD30067B53E /* CCPUScaleVelocityAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B71AA80A6500DDB1C5 /* CCPUScaleVelocityAffector.h */; };
+ 507B40C31C31BDD30067B53E /* CCPUSphere.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D11AA80A6500DDB1C5 /* CCPUSphere.h */; };
+ 507B40C41C31BDD30067B53E /* CCParticle3DAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B68778F11A8CA82E00643ABF /* CCParticle3DAffector.h */; };
+ 507B40C51C31BDD30067B53E /* CCPURendererTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1AD1AA80A6500DDB1C5 /* CCPURendererTranslator.h */; };
+ 507B40C61C31BDD30067B53E /* CCMaterial.h in Headers */ = {isa = PBXBuildFile; fileRef = 5012169F1AC473AD009A4BEA /* CCMaterial.h */; };
+ 507B40C71C31BDD30067B53E /* CCPUBaseColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D91AA80A6500DDB1C5 /* CCPUBaseColliderTranslator.h */; };
+ 507B40C81C31BDD30067B53E /* CCDeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A01C67A18F57BE800EFE3A6 /* CCDeprecated.h */; };
+ 507B40C91C31BDD30067B53E /* CCPULinearForceAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1471AA80A6500DDB1C5 /* CCPULinearForceAffector.h */; };
+ 507B40CA1C31BDD30067B53E /* ParticleReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3823842E1A259112002C4610 /* ParticleReader.h */; };
+ 507B40CC1C31BDD30067B53E /* CCPUDynamicAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1191AA80A6500DDB1C5 /* CCPUDynamicAttribute.h */; };
+ 507B40CE1C31BDD30067B53E /* CCESRenderer-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8D81926736A00CD74DD /* CCESRenderer-ios.h */; };
+ 507B40CF1C31BDD30067B53E /* CCPUObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E15F1AA80A6500DDB1C5 /* CCPUObserverTranslator.h */; };
+ 507B40D01C31BDD30067B53E /* CCEventFocus.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDDD1925AB6E00A911A9 /* CCEventFocus.h */; };
+ 507B40D11C31BDD30067B53E /* CCTransformHelp.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C597F180E930E00EF57C3 /* CCTransformHelp.h */; };
+ 507B40D31C31BDD30067B53E /* CCPUEmitterManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E11F1AA80A6500DDB1C5 /* CCPUEmitterManager.h */; };
+ 507B40D51C31BDD30067B53E /* UIVideoPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EA0FB69191C841D00B170C8 /* UIVideoPlayer.h */; };
+ 507B40D61C31BDD30067B53E /* CCLabelBMFontLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD71D0F180E26E600808F54 /* CCLabelBMFontLoader.h */; };
+ 507B40D71C31BDD30067B53E /* CCCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF211926664700A911A9 /* CCCommon.h */; };
+ 507B40D81C31BDD30067B53E /* CCCameraBackgroundBrush.h in Headers */ = {isa = PBXBuildFile; fileRef = A045F6DB1BA816A1005076C7 /* CCCameraBackgroundBrush.h */; };
+ 507B40D91C31BDD30067B53E /* LoadingBarReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB7A18C72017004AD434 /* LoadingBarReader.h */; };
+ 507B40DA1C31BDD30067B53E /* sweep_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20861AE7C57D00C31518 /* sweep_context.h */; };
+ 507B40DB1C31BDD30067B53E /* CCEventKeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDDF1925AB6E00A911A9 /* CCEventKeyboard.h */; };
+ 507B40DC1C31BDD30067B53E /* CCPUBeamRender.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0DF1AA80A6500DDB1C5 /* CCPUBeamRender.h */; };
+ 507B40DE1C31BDD30067B53E /* CCPlane.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E9F61251A3FFE3D0038DE01 /* CCPlane.h */; };
+ 507B40DF1C31BDD30067B53E /* CCPUOnEmissionObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E16F1AA80A6500DDB1C5 /* CCPUOnEmissionObserverTranslator.h */; };
+ 507B40E01C31BDD30067B53E /* CCPUTextureAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1DD1AA80A6500DDB1C5 /* CCPUTextureAnimator.h */; };
+ 507B40E11C31BDD30067B53E /* CCSAXParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF2A1926664700A911A9 /* CCSAXParser.h */; };
+ 507B40E31C31BDD30067B53E /* OpenGL_Internal-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 503DD8DF1926736A00CD74DD /* OpenGL_Internal-ios.h */; };
+ 507B40E51C31BDD30067B53E /* WidgetCallBackHandlerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 38ACD1FB1A27111900C3093D /* WidgetCallBackHandlerProtocol.h */; };
+ 507B40E81C31BDD30067B53E /* CCRenderCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD771925AB4100A911A9 /* CCRenderCommand.h */; };
+ 507B40EB1C31BDD30067B53E /* CCControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A168361807AF4E005B8026 /* CCControl.h */; };
+ 507B40EC1C31BDD30067B53E /* CCArmature.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8C5953180E930E00EF57C3 /* CCArmature.h */; };
+ 507B40ED1C31BDD30067B53E /* CCAsyncTaskPool.h in Headers */ = {isa = PBXBuildFile; fileRef = B63990CB1A490AFE00B07923 /* CCAsyncTaskPool.h */; };
+ 507B40EE1C31BDD30067B53E /* cocos-ext.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A167D21807AF4D005B8026 /* cocos-ext.h */; };
+ 507B40EF1C31BDD30067B53E /* UIImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2905F9F718CF08D000240AA3 /* UIImageView.h */; };
+ 507B40F11C31BDD30067B53E /* CCPUBillboardChain.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E71AA80A6500DDB1C5 /* CCPUBillboardChain.h */; };
+ 507B40F21C31BDD30067B53E /* CCEventListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE11925AB6E00A911A9 /* CCEventListener.h */; };
+ 507B40F31C31BDD30067B53E /* CCActionTimelineNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D76BE391A4AAF0A00102962 /* CCActionTimelineNode.h */; };
+ 507B40F61C31BDD30067B53E /* CCUserDefault.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE0A1925AB6E00A911A9 /* CCUserDefault.h */; };
+ 507B40F71C31BDD30067B53E /* ButtonReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCEB6B18C72017004AD434 /* ButtonReader.h */; };
+ 507B40F91C31BDD30067B53E /* CCIDownloaderImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = A0534A691B87306E006B03E5 /* CCIDownloaderImpl.h */; };
+ 50864C8B1C7BC1B000B3BAB1 /* chipmunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C6D1C7BC1B000B3BAB1 /* chipmunk.h */; };
+ 50864C8C1C7BC1B000B3BAB1 /* chipmunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C6D1C7BC1B000B3BAB1 /* chipmunk.h */; };
+ 50864C8D1C7BC1B000B3BAB1 /* chipmunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C6D1C7BC1B000B3BAB1 /* chipmunk.h */; };
+ 50864C8E1C7BC1B000B3BAB1 /* chipmunk_ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C6E1C7BC1B000B3BAB1 /* chipmunk_ffi.h */; };
+ 50864C8F1C7BC1B000B3BAB1 /* chipmunk_ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C6E1C7BC1B000B3BAB1 /* chipmunk_ffi.h */; };
+ 50864C901C7BC1B000B3BAB1 /* chipmunk_ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C6E1C7BC1B000B3BAB1 /* chipmunk_ffi.h */; };
+ 50864C911C7BC1B000B3BAB1 /* chipmunk_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C6F1C7BC1B000B3BAB1 /* chipmunk_private.h */; };
+ 50864C921C7BC1B000B3BAB1 /* chipmunk_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C6F1C7BC1B000B3BAB1 /* chipmunk_private.h */; };
+ 50864C931C7BC1B000B3BAB1 /* chipmunk_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C6F1C7BC1B000B3BAB1 /* chipmunk_private.h */; };
+ 50864C941C7BC1B000B3BAB1 /* chipmunk_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C701C7BC1B000B3BAB1 /* chipmunk_types.h */; };
+ 50864C951C7BC1B000B3BAB1 /* chipmunk_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C701C7BC1B000B3BAB1 /* chipmunk_types.h */; };
+ 50864C961C7BC1B000B3BAB1 /* chipmunk_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C701C7BC1B000B3BAB1 /* chipmunk_types.h */; };
+ 50864C971C7BC1B000B3BAB1 /* chipmunk_unsafe.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C711C7BC1B000B3BAB1 /* chipmunk_unsafe.h */; };
+ 50864C981C7BC1B000B3BAB1 /* chipmunk_unsafe.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C711C7BC1B000B3BAB1 /* chipmunk_unsafe.h */; };
+ 50864C991C7BC1B000B3BAB1 /* chipmunk_unsafe.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C711C7BC1B000B3BAB1 /* chipmunk_unsafe.h */; };
+ 50864C9A1C7BC1B000B3BAB1 /* cpCompat62.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C721C7BC1B000B3BAB1 /* cpCompat62.h */; };
+ 50864C9B1C7BC1B000B3BAB1 /* cpCompat62.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C721C7BC1B000B3BAB1 /* cpCompat62.h */; };
+ 50864C9C1C7BC1B000B3BAB1 /* cpCompat62.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C721C7BC1B000B3BAB1 /* cpCompat62.h */; };
+ 50864C9D1C7BC1B000B3BAB1 /* cpArbiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C731C7BC1B000B3BAB1 /* cpArbiter.h */; };
+ 50864C9E1C7BC1B000B3BAB1 /* cpArbiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C731C7BC1B000B3BAB1 /* cpArbiter.h */; };
+ 50864C9F1C7BC1B000B3BAB1 /* cpArbiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C731C7BC1B000B3BAB1 /* cpArbiter.h */; };
+ 50864CA01C7BC1B000B3BAB1 /* cpBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C741C7BC1B000B3BAB1 /* cpBB.h */; };
+ 50864CA11C7BC1B000B3BAB1 /* cpBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C741C7BC1B000B3BAB1 /* cpBB.h */; };
+ 50864CA21C7BC1B000B3BAB1 /* cpBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C741C7BC1B000B3BAB1 /* cpBB.h */; };
+ 50864CA31C7BC1B000B3BAB1 /* cpBody.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C751C7BC1B000B3BAB1 /* cpBody.h */; };
+ 50864CA41C7BC1B000B3BAB1 /* cpBody.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C751C7BC1B000B3BAB1 /* cpBody.h */; };
+ 50864CA51C7BC1B000B3BAB1 /* cpBody.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C751C7BC1B000B3BAB1 /* cpBody.h */; };
+ 50864CA61C7BC1B000B3BAB1 /* cpConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C761C7BC1B000B3BAB1 /* cpConstraint.h */; };
+ 50864CA71C7BC1B000B3BAB1 /* cpConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C761C7BC1B000B3BAB1 /* cpConstraint.h */; };
+ 50864CA81C7BC1B000B3BAB1 /* cpConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C761C7BC1B000B3BAB1 /* cpConstraint.h */; };
+ 50864CA91C7BC1B000B3BAB1 /* cpDampedRotarySpring.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C771C7BC1B000B3BAB1 /* cpDampedRotarySpring.h */; };
+ 50864CAA1C7BC1B000B3BAB1 /* cpDampedRotarySpring.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C771C7BC1B000B3BAB1 /* cpDampedRotarySpring.h */; };
+ 50864CAB1C7BC1B000B3BAB1 /* cpDampedRotarySpring.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C771C7BC1B000B3BAB1 /* cpDampedRotarySpring.h */; };
+ 50864CAC1C7BC1B000B3BAB1 /* cpDampedSpring.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C781C7BC1B000B3BAB1 /* cpDampedSpring.h */; };
+ 50864CAD1C7BC1B000B3BAB1 /* cpDampedSpring.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C781C7BC1B000B3BAB1 /* cpDampedSpring.h */; };
+ 50864CAE1C7BC1B000B3BAB1 /* cpDampedSpring.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C781C7BC1B000B3BAB1 /* cpDampedSpring.h */; };
+ 50864CAF1C7BC1B000B3BAB1 /* cpGearJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C791C7BC1B000B3BAB1 /* cpGearJoint.h */; };
+ 50864CB01C7BC1B000B3BAB1 /* cpGearJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C791C7BC1B000B3BAB1 /* cpGearJoint.h */; };
+ 50864CB11C7BC1B000B3BAB1 /* cpGearJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C791C7BC1B000B3BAB1 /* cpGearJoint.h */; };
+ 50864CB21C7BC1B000B3BAB1 /* cpGrooveJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7A1C7BC1B000B3BAB1 /* cpGrooveJoint.h */; };
+ 50864CB31C7BC1B000B3BAB1 /* cpGrooveJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7A1C7BC1B000B3BAB1 /* cpGrooveJoint.h */; };
+ 50864CB41C7BC1B000B3BAB1 /* cpGrooveJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7A1C7BC1B000B3BAB1 /* cpGrooveJoint.h */; };
+ 50864CB51C7BC1B000B3BAB1 /* cpHastySpace.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7B1C7BC1B000B3BAB1 /* cpHastySpace.h */; };
+ 50864CB61C7BC1B000B3BAB1 /* cpHastySpace.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7B1C7BC1B000B3BAB1 /* cpHastySpace.h */; };
+ 50864CB71C7BC1B000B3BAB1 /* cpHastySpace.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7B1C7BC1B000B3BAB1 /* cpHastySpace.h */; };
+ 50864CB81C7BC1B000B3BAB1 /* cpMarch.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7C1C7BC1B000B3BAB1 /* cpMarch.h */; };
+ 50864CB91C7BC1B000B3BAB1 /* cpMarch.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7C1C7BC1B000B3BAB1 /* cpMarch.h */; };
+ 50864CBA1C7BC1B000B3BAB1 /* cpMarch.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7C1C7BC1B000B3BAB1 /* cpMarch.h */; };
+ 50864CBB1C7BC1B000B3BAB1 /* cpPinJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7D1C7BC1B000B3BAB1 /* cpPinJoint.h */; };
+ 50864CBC1C7BC1B000B3BAB1 /* cpPinJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7D1C7BC1B000B3BAB1 /* cpPinJoint.h */; };
+ 50864CBD1C7BC1B000B3BAB1 /* cpPinJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7D1C7BC1B000B3BAB1 /* cpPinJoint.h */; };
+ 50864CBE1C7BC1B000B3BAB1 /* cpPivotJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7E1C7BC1B000B3BAB1 /* cpPivotJoint.h */; };
+ 50864CBF1C7BC1B000B3BAB1 /* cpPivotJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7E1C7BC1B000B3BAB1 /* cpPivotJoint.h */; };
+ 50864CC01C7BC1B000B3BAB1 /* cpPivotJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7E1C7BC1B000B3BAB1 /* cpPivotJoint.h */; };
+ 50864CC11C7BC1B000B3BAB1 /* cpPolyline.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7F1C7BC1B000B3BAB1 /* cpPolyline.h */; };
+ 50864CC21C7BC1B100B3BAB1 /* cpPolyline.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7F1C7BC1B000B3BAB1 /* cpPolyline.h */; };
+ 50864CC31C7BC1B100B3BAB1 /* cpPolyline.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C7F1C7BC1B000B3BAB1 /* cpPolyline.h */; };
+ 50864CC41C7BC1B100B3BAB1 /* cpPolyShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C801C7BC1B000B3BAB1 /* cpPolyShape.h */; };
+ 50864CC51C7BC1B100B3BAB1 /* cpPolyShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C801C7BC1B000B3BAB1 /* cpPolyShape.h */; };
+ 50864CC61C7BC1B100B3BAB1 /* cpPolyShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C801C7BC1B000B3BAB1 /* cpPolyShape.h */; };
+ 50864CC71C7BC1B100B3BAB1 /* cpRatchetJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C811C7BC1B000B3BAB1 /* cpRatchetJoint.h */; };
+ 50864CC81C7BC1B100B3BAB1 /* cpRatchetJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C811C7BC1B000B3BAB1 /* cpRatchetJoint.h */; };
+ 50864CC91C7BC1B100B3BAB1 /* cpRatchetJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C811C7BC1B000B3BAB1 /* cpRatchetJoint.h */; };
+ 50864CCA1C7BC1B100B3BAB1 /* cpRobust.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C821C7BC1B000B3BAB1 /* cpRobust.h */; };
+ 50864CCB1C7BC1B100B3BAB1 /* cpRobust.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C821C7BC1B000B3BAB1 /* cpRobust.h */; };
+ 50864CCC1C7BC1B100B3BAB1 /* cpRobust.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C821C7BC1B000B3BAB1 /* cpRobust.h */; };
+ 50864CCD1C7BC1B100B3BAB1 /* cpRotaryLimitJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C831C7BC1B000B3BAB1 /* cpRotaryLimitJoint.h */; };
+ 50864CCE1C7BC1B100B3BAB1 /* cpRotaryLimitJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C831C7BC1B000B3BAB1 /* cpRotaryLimitJoint.h */; };
+ 50864CCF1C7BC1B100B3BAB1 /* cpRotaryLimitJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C831C7BC1B000B3BAB1 /* cpRotaryLimitJoint.h */; };
+ 50864CD01C7BC1B100B3BAB1 /* cpShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C841C7BC1B000B3BAB1 /* cpShape.h */; };
+ 50864CD11C7BC1B100B3BAB1 /* cpShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C841C7BC1B000B3BAB1 /* cpShape.h */; };
+ 50864CD21C7BC1B100B3BAB1 /* cpShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C841C7BC1B000B3BAB1 /* cpShape.h */; };
+ 50864CD31C7BC1B100B3BAB1 /* cpSimpleMotor.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C851C7BC1B000B3BAB1 /* cpSimpleMotor.h */; };
+ 50864CD41C7BC1B100B3BAB1 /* cpSimpleMotor.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C851C7BC1B000B3BAB1 /* cpSimpleMotor.h */; };
+ 50864CD51C7BC1B100B3BAB1 /* cpSimpleMotor.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C851C7BC1B000B3BAB1 /* cpSimpleMotor.h */; };
+ 50864CD61C7BC1B100B3BAB1 /* cpSlideJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C861C7BC1B000B3BAB1 /* cpSlideJoint.h */; };
+ 50864CD71C7BC1B100B3BAB1 /* cpSlideJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C861C7BC1B000B3BAB1 /* cpSlideJoint.h */; };
+ 50864CD81C7BC1B100B3BAB1 /* cpSlideJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C861C7BC1B000B3BAB1 /* cpSlideJoint.h */; };
+ 50864CD91C7BC1B100B3BAB1 /* cpSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C871C7BC1B000B3BAB1 /* cpSpace.h */; };
+ 50864CDA1C7BC1B100B3BAB1 /* cpSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C871C7BC1B000B3BAB1 /* cpSpace.h */; };
+ 50864CDB1C7BC1B100B3BAB1 /* cpSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C871C7BC1B000B3BAB1 /* cpSpace.h */; };
+ 50864CDC1C7BC1B100B3BAB1 /* cpSpatialIndex.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C881C7BC1B000B3BAB1 /* cpSpatialIndex.h */; };
+ 50864CDD1C7BC1B100B3BAB1 /* cpSpatialIndex.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C881C7BC1B000B3BAB1 /* cpSpatialIndex.h */; };
+ 50864CDE1C7BC1B100B3BAB1 /* cpSpatialIndex.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C881C7BC1B000B3BAB1 /* cpSpatialIndex.h */; };
+ 50864CDF1C7BC1B100B3BAB1 /* cpTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C891C7BC1B000B3BAB1 /* cpTransform.h */; };
+ 50864CE01C7BC1B100B3BAB1 /* cpTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C891C7BC1B000B3BAB1 /* cpTransform.h */; };
+ 50864CE11C7BC1B100B3BAB1 /* cpTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C891C7BC1B000B3BAB1 /* cpTransform.h */; };
+ 50864CE21C7BC1B100B3BAB1 /* cpVect.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C8A1C7BC1B000B3BAB1 /* cpVect.h */; };
+ 50864CE31C7BC1B100B3BAB1 /* cpVect.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C8A1C7BC1B000B3BAB1 /* cpVect.h */; };
+ 50864CE41C7BC1B100B3BAB1 /* cpVect.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864C8A1C7BC1B000B3BAB1 /* cpVect.h */; };
+ 50864CEA1C7BC90A00B3BAB1 /* cpCompat62.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864CE61C7BC90A00B3BAB1 /* cpCompat62.h */; };
+ 50864CEB1C7BC90A00B3BAB1 /* cpCompat62.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864CE61C7BC90A00B3BAB1 /* cpCompat62.h */; };
+ 50864CEC1C7BC90A00B3BAB1 /* cpCompat62.h in Headers */ = {isa = PBXBuildFile; fileRef = 50864CE61C7BC90A00B3BAB1 /* cpCompat62.h */; };
+ 5091A7A319BFABA800AC8789 /* CCPlatformDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 5091A7A219BFABA800AC8789 /* CCPlatformDefine.h */; };
+ 50ABBD381925AB0000A911A9 /* CCAffineTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD1B1925AB0000A911A9 /* CCAffineTransform.cpp */; };
+ 50ABBD391925AB0000A911A9 /* CCAffineTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD1B1925AB0000A911A9 /* CCAffineTransform.cpp */; };
+ 50ABBD3A1925AB0000A911A9 /* CCAffineTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD1C1925AB0000A911A9 /* CCAffineTransform.h */; };
+ 50ABBD3B1925AB0000A911A9 /* CCAffineTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD1C1925AB0000A911A9 /* CCAffineTransform.h */; };
+ 50ABBD3C1925AB0000A911A9 /* CCGeometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD1D1925AB0000A911A9 /* CCGeometry.cpp */; };
+ 50ABBD3D1925AB0000A911A9 /* CCGeometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD1D1925AB0000A911A9 /* CCGeometry.cpp */; };
+ 50ABBD3E1925AB0000A911A9 /* CCGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD1E1925AB0000A911A9 /* CCGeometry.h */; };
+ 50ABBD3F1925AB0000A911A9 /* CCGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD1E1925AB0000A911A9 /* CCGeometry.h */; };
+ 50ABBD401925AB0000A911A9 /* CCMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD1F1925AB0000A911A9 /* CCMath.h */; };
+ 50ABBD411925AB0000A911A9 /* CCMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD1F1925AB0000A911A9 /* CCMath.h */; };
+ 50ABBD421925AB0000A911A9 /* CCMathBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD201925AB0000A911A9 /* CCMathBase.h */; };
+ 50ABBD431925AB0000A911A9 /* CCMathBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD201925AB0000A911A9 /* CCMathBase.h */; };
+ 50ABBD441925AB0000A911A9 /* CCVertex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD211925AB0000A911A9 /* CCVertex.cpp */; };
+ 50ABBD451925AB0000A911A9 /* CCVertex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD211925AB0000A911A9 /* CCVertex.cpp */; };
+ 50ABBD461925AB0000A911A9 /* CCVertex.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD221925AB0000A911A9 /* CCVertex.h */; };
+ 50ABBD471925AB0000A911A9 /* CCVertex.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD221925AB0000A911A9 /* CCVertex.h */; };
+ 50ABBD481925AB0000A911A9 /* Mat4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD231925AB0000A911A9 /* Mat4.cpp */; };
+ 50ABBD491925AB0000A911A9 /* Mat4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD231925AB0000A911A9 /* Mat4.cpp */; };
+ 50ABBD4A1925AB0000A911A9 /* Mat4.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD241925AB0000A911A9 /* Mat4.h */; };
+ 50ABBD4B1925AB0000A911A9 /* Mat4.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD241925AB0000A911A9 /* Mat4.h */; };
+ 50ABBD4C1925AB0000A911A9 /* MathUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD261925AB0000A911A9 /* MathUtil.cpp */; };
+ 50ABBD4D1925AB0000A911A9 /* MathUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD261925AB0000A911A9 /* MathUtil.cpp */; };
+ 50ABBD4E1925AB0000A911A9 /* MathUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD271925AB0000A911A9 /* MathUtil.h */; };
+ 50ABBD4F1925AB0000A911A9 /* MathUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD271925AB0000A911A9 /* MathUtil.h */; };
+ 50ABBD501925AB0000A911A9 /* Quaternion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD2A1925AB0000A911A9 /* Quaternion.cpp */; };
+ 50ABBD511925AB0000A911A9 /* Quaternion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD2A1925AB0000A911A9 /* Quaternion.cpp */; };
+ 50ABBD521925AB0000A911A9 /* Quaternion.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD2B1925AB0000A911A9 /* Quaternion.h */; };
+ 50ABBD531925AB0000A911A9 /* Quaternion.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD2B1925AB0000A911A9 /* Quaternion.h */; };
+ 50ABBD541925AB0000A911A9 /* TransformUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD2D1925AB0000A911A9 /* TransformUtils.cpp */; };
+ 50ABBD551925AB0000A911A9 /* TransformUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD2D1925AB0000A911A9 /* TransformUtils.cpp */; };
+ 50ABBD561925AB0000A911A9 /* TransformUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD2E1925AB0000A911A9 /* TransformUtils.h */; };
+ 50ABBD571925AB0000A911A9 /* TransformUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD2E1925AB0000A911A9 /* TransformUtils.h */; };
+ 50ABBD581925AB0000A911A9 /* Vec2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD2F1925AB0000A911A9 /* Vec2.cpp */; };
+ 50ABBD591925AB0000A911A9 /* Vec2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD2F1925AB0000A911A9 /* Vec2.cpp */; };
+ 50ABBD5A1925AB0000A911A9 /* Vec2.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD301925AB0000A911A9 /* Vec2.h */; };
+ 50ABBD5B1925AB0000A911A9 /* Vec2.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD301925AB0000A911A9 /* Vec2.h */; };
+ 50ABBD5C1925AB0000A911A9 /* Vec3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD321925AB0000A911A9 /* Vec3.cpp */; };
+ 50ABBD5D1925AB0000A911A9 /* Vec3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD321925AB0000A911A9 /* Vec3.cpp */; };
+ 50ABBD5E1925AB0000A911A9 /* Vec3.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD331925AB0000A911A9 /* Vec3.h */; };
+ 50ABBD5F1925AB0000A911A9 /* Vec3.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD331925AB0000A911A9 /* Vec3.h */; };
+ 50ABBD601925AB0000A911A9 /* Vec4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD351925AB0000A911A9 /* Vec4.cpp */; };
+ 50ABBD611925AB0000A911A9 /* Vec4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD351925AB0000A911A9 /* Vec4.cpp */; };
+ 50ABBD621925AB0000A911A9 /* Vec4.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD361925AB0000A911A9 /* Vec4.h */; };
+ 50ABBD631925AB0000A911A9 /* Vec4.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD361925AB0000A911A9 /* Vec4.h */; };
+ 50ABBD831925AB4100A911A9 /* CCBatchCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD641925AB4100A911A9 /* CCBatchCommand.cpp */; };
+ 50ABBD841925AB4100A911A9 /* CCBatchCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD641925AB4100A911A9 /* CCBatchCommand.cpp */; };
+ 50ABBD851925AB4100A911A9 /* CCBatchCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD651925AB4100A911A9 /* CCBatchCommand.h */; };
+ 50ABBD861925AB4100A911A9 /* CCBatchCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD651925AB4100A911A9 /* CCBatchCommand.h */; };
+ 50ABBD871925AB4100A911A9 /* CCCustomCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD661925AB4100A911A9 /* CCCustomCommand.cpp */; };
+ 50ABBD881925AB4100A911A9 /* CCCustomCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD661925AB4100A911A9 /* CCCustomCommand.cpp */; };
+ 50ABBD891925AB4100A911A9 /* CCCustomCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD671925AB4100A911A9 /* CCCustomCommand.h */; };
+ 50ABBD8A1925AB4100A911A9 /* CCCustomCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD671925AB4100A911A9 /* CCCustomCommand.h */; };
+ 50ABBD8B1925AB4100A911A9 /* CCGLProgram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD681925AB4100A911A9 /* CCGLProgram.cpp */; };
+ 50ABBD8C1925AB4100A911A9 /* CCGLProgram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD681925AB4100A911A9 /* CCGLProgram.cpp */; };
+ 50ABBD8D1925AB4100A911A9 /* CCGLProgram.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD691925AB4100A911A9 /* CCGLProgram.h */; };
+ 50ABBD8E1925AB4100A911A9 /* CCGLProgram.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD691925AB4100A911A9 /* CCGLProgram.h */; };
+ 50ABBD8F1925AB4100A911A9 /* CCGLProgramCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD6A1925AB4100A911A9 /* CCGLProgramCache.cpp */; };
+ 50ABBD901925AB4100A911A9 /* CCGLProgramCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD6A1925AB4100A911A9 /* CCGLProgramCache.cpp */; };
+ 50ABBD911925AB4100A911A9 /* CCGLProgramCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD6B1925AB4100A911A9 /* CCGLProgramCache.h */; };
+ 50ABBD921925AB4100A911A9 /* CCGLProgramCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD6B1925AB4100A911A9 /* CCGLProgramCache.h */; };
+ 50ABBD931925AB4100A911A9 /* CCGLProgramState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD6C1925AB4100A911A9 /* CCGLProgramState.cpp */; };
+ 50ABBD941925AB4100A911A9 /* CCGLProgramState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD6C1925AB4100A911A9 /* CCGLProgramState.cpp */; };
+ 50ABBD951925AB4100A911A9 /* CCGLProgramState.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD6D1925AB4100A911A9 /* CCGLProgramState.h */; };
+ 50ABBD961925AB4100A911A9 /* CCGLProgramState.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD6D1925AB4100A911A9 /* CCGLProgramState.h */; };
+ 50ABBD971925AB4100A911A9 /* CCGLProgramStateCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD6E1925AB4100A911A9 /* CCGLProgramStateCache.cpp */; };
+ 50ABBD981925AB4100A911A9 /* CCGLProgramStateCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD6E1925AB4100A911A9 /* CCGLProgramStateCache.cpp */; };
+ 50ABBD991925AB4100A911A9 /* CCGLProgramStateCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD6F1925AB4100A911A9 /* CCGLProgramStateCache.h */; };
+ 50ABBD9A1925AB4100A911A9 /* CCGLProgramStateCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD6F1925AB4100A911A9 /* CCGLProgramStateCache.h */; };
+ 50ABBD9B1925AB4100A911A9 /* ccGLStateCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD701925AB4100A911A9 /* ccGLStateCache.cpp */; };
+ 50ABBD9C1925AB4100A911A9 /* ccGLStateCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD701925AB4100A911A9 /* ccGLStateCache.cpp */; };
+ 50ABBD9D1925AB4100A911A9 /* ccGLStateCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD711925AB4100A911A9 /* ccGLStateCache.h */; };
+ 50ABBD9E1925AB4100A911A9 /* ccGLStateCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD711925AB4100A911A9 /* ccGLStateCache.h */; };
+ 50ABBD9F1925AB4100A911A9 /* CCGroupCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD721925AB4100A911A9 /* CCGroupCommand.cpp */; };
+ 50ABBDA01925AB4100A911A9 /* CCGroupCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD721925AB4100A911A9 /* CCGroupCommand.cpp */; };
+ 50ABBDA11925AB4100A911A9 /* CCGroupCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD731925AB4100A911A9 /* CCGroupCommand.h */; };
+ 50ABBDA21925AB4100A911A9 /* CCGroupCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD731925AB4100A911A9 /* CCGroupCommand.h */; };
+ 50ABBDA31925AB4100A911A9 /* CCQuadCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD741925AB4100A911A9 /* CCQuadCommand.cpp */; };
+ 50ABBDA41925AB4100A911A9 /* CCQuadCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD741925AB4100A911A9 /* CCQuadCommand.cpp */; };
+ 50ABBDA51925AB4100A911A9 /* CCQuadCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD751925AB4100A911A9 /* CCQuadCommand.h */; };
+ 50ABBDA61925AB4100A911A9 /* CCQuadCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD751925AB4100A911A9 /* CCQuadCommand.h */; };
+ 50ABBDA71925AB4100A911A9 /* CCRenderCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD761925AB4100A911A9 /* CCRenderCommand.cpp */; };
+ 50ABBDA81925AB4100A911A9 /* CCRenderCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD761925AB4100A911A9 /* CCRenderCommand.cpp */; };
+ 50ABBDA91925AB4100A911A9 /* CCRenderCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD771925AB4100A911A9 /* CCRenderCommand.h */; };
+ 50ABBDAA1925AB4100A911A9 /* CCRenderCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD771925AB4100A911A9 /* CCRenderCommand.h */; };
+ 50ABBDAB1925AB4100A911A9 /* CCRenderCommandPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD781925AB4100A911A9 /* CCRenderCommandPool.h */; };
+ 50ABBDAC1925AB4100A911A9 /* CCRenderCommandPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD781925AB4100A911A9 /* CCRenderCommandPool.h */; };
+ 50ABBDAD1925AB4100A911A9 /* CCRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD791925AB4100A911A9 /* CCRenderer.cpp */; };
+ 50ABBDAE1925AB4100A911A9 /* CCRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD791925AB4100A911A9 /* CCRenderer.cpp */; };
+ 50ABBDAF1925AB4100A911A9 /* CCRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD7A1925AB4100A911A9 /* CCRenderer.h */; };
+ 50ABBDB01925AB4100A911A9 /* CCRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD7A1925AB4100A911A9 /* CCRenderer.h */; };
+ 50ABBDB11925AB4100A911A9 /* ccShaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD7B1925AB4100A911A9 /* ccShaders.cpp */; };
+ 50ABBDB21925AB4100A911A9 /* ccShaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD7B1925AB4100A911A9 /* ccShaders.cpp */; };
+ 50ABBDB31925AB4100A911A9 /* ccShaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD7C1925AB4100A911A9 /* ccShaders.h */; };
+ 50ABBDB41925AB4100A911A9 /* ccShaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD7C1925AB4100A911A9 /* ccShaders.h */; };
+ 50ABBDB51925AB4100A911A9 /* CCTexture2D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD7D1925AB4100A911A9 /* CCTexture2D.cpp */; };
+ 50ABBDB61925AB4100A911A9 /* CCTexture2D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD7D1925AB4100A911A9 /* CCTexture2D.cpp */; };
+ 50ABBDB71925AB4100A911A9 /* CCTexture2D.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD7E1925AB4100A911A9 /* CCTexture2D.h */; };
+ 50ABBDB81925AB4100A911A9 /* CCTexture2D.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD7E1925AB4100A911A9 /* CCTexture2D.h */; };
+ 50ABBDB91925AB4100A911A9 /* CCTextureAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD7F1925AB4100A911A9 /* CCTextureAtlas.cpp */; };
+ 50ABBDBA1925AB4100A911A9 /* CCTextureAtlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD7F1925AB4100A911A9 /* CCTextureAtlas.cpp */; };
+ 50ABBDBB1925AB4100A911A9 /* CCTextureAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD801925AB4100A911A9 /* CCTextureAtlas.h */; };
+ 50ABBDBC1925AB4100A911A9 /* CCTextureAtlas.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD801925AB4100A911A9 /* CCTextureAtlas.h */; };
+ 50ABBDBD1925AB4100A911A9 /* CCTextureCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD811925AB4100A911A9 /* CCTextureCache.cpp */; };
+ 50ABBDBE1925AB4100A911A9 /* CCTextureCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBD811925AB4100A911A9 /* CCTextureCache.cpp */; };
+ 50ABBDBF1925AB4100A911A9 /* CCTextureCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD821925AB4100A911A9 /* CCTextureCache.h */; };
+ 50ABBDC01925AB4100A911A9 /* CCTextureCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBD821925AB4100A911A9 /* CCTextureCache.h */; };
+ 50ABBE1F1925AB6F00A911A9 /* atitc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDC11925AB6E00A911A9 /* atitc.cpp */; };
+ 50ABBE201925AB6F00A911A9 /* atitc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDC11925AB6E00A911A9 /* atitc.cpp */; };
+ 50ABBE211925AB6F00A911A9 /* atitc.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC21925AB6E00A911A9 /* atitc.h */; };
+ 50ABBE221925AB6F00A911A9 /* atitc.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC21925AB6E00A911A9 /* atitc.h */; };
+ 50ABBE231925AB6F00A911A9 /* base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDC31925AB6E00A911A9 /* base64.cpp */; };
+ 50ABBE241925AB6F00A911A9 /* base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDC31925AB6E00A911A9 /* base64.cpp */; };
+ 50ABBE251925AB6F00A911A9 /* base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC41925AB6E00A911A9 /* base64.h */; };
+ 50ABBE261925AB6F00A911A9 /* base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC41925AB6E00A911A9 /* base64.h */; };
+ 50ABBE271925AB6F00A911A9 /* CCAutoreleasePool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDC51925AB6E00A911A9 /* CCAutoreleasePool.cpp */; };
+ 50ABBE281925AB6F00A911A9 /* CCAutoreleasePool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDC51925AB6E00A911A9 /* CCAutoreleasePool.cpp */; };
+ 50ABBE291925AB6F00A911A9 /* CCAutoreleasePool.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC61925AB6E00A911A9 /* CCAutoreleasePool.h */; };
+ 50ABBE2A1925AB6F00A911A9 /* CCAutoreleasePool.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC61925AB6E00A911A9 /* CCAutoreleasePool.h */; };
+ 50ABBE2B1925AB6F00A911A9 /* ccCArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDC71925AB6E00A911A9 /* ccCArray.cpp */; };
+ 50ABBE2C1925AB6F00A911A9 /* ccCArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDC71925AB6E00A911A9 /* ccCArray.cpp */; };
+ 50ABBE2D1925AB6F00A911A9 /* ccCArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC81925AB6E00A911A9 /* ccCArray.h */; };
+ 50ABBE2E1925AB6F00A911A9 /* ccCArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC81925AB6E00A911A9 /* ccCArray.h */; };
+ 50ABBE2F1925AB6F00A911A9 /* ccConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC91925AB6E00A911A9 /* ccConfig.h */; };
+ 50ABBE301925AB6F00A911A9 /* ccConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDC91925AB6E00A911A9 /* ccConfig.h */; };
+ 50ABBE311925AB6F00A911A9 /* CCConfiguration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDCA1925AB6E00A911A9 /* CCConfiguration.cpp */; };
+ 50ABBE321925AB6F00A911A9 /* CCConfiguration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDCA1925AB6E00A911A9 /* CCConfiguration.cpp */; };
+ 50ABBE331925AB6F00A911A9 /* CCConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDCB1925AB6E00A911A9 /* CCConfiguration.h */; };
+ 50ABBE341925AB6F00A911A9 /* CCConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDCB1925AB6E00A911A9 /* CCConfiguration.h */; };
+ 50ABBE351925AB6F00A911A9 /* CCConsole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDCC1925AB6E00A911A9 /* CCConsole.cpp */; };
+ 50ABBE361925AB6F00A911A9 /* CCConsole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDCC1925AB6E00A911A9 /* CCConsole.cpp */; };
+ 50ABBE371925AB6F00A911A9 /* CCConsole.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDCD1925AB6E00A911A9 /* CCConsole.h */; };
+ 50ABBE381925AB6F00A911A9 /* CCConsole.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDCD1925AB6E00A911A9 /* CCConsole.h */; };
+ 50ABBE391925AB6F00A911A9 /* CCData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDCE1925AB6E00A911A9 /* CCData.cpp */; };
+ 50ABBE3A1925AB6F00A911A9 /* CCData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDCE1925AB6E00A911A9 /* CCData.cpp */; };
+ 50ABBE3B1925AB6F00A911A9 /* CCData.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDCF1925AB6E00A911A9 /* CCData.h */; };
+ 50ABBE3C1925AB6F00A911A9 /* CCData.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDCF1925AB6E00A911A9 /* CCData.h */; };
+ 50ABBE3D1925AB6F00A911A9 /* CCDataVisitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD01925AB6E00A911A9 /* CCDataVisitor.cpp */; };
+ 50ABBE3E1925AB6F00A911A9 /* CCDataVisitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD01925AB6E00A911A9 /* CCDataVisitor.cpp */; };
+ 50ABBE3F1925AB6F00A911A9 /* CCDataVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD11925AB6E00A911A9 /* CCDataVisitor.h */; };
+ 50ABBE401925AB6F00A911A9 /* CCDataVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD11925AB6E00A911A9 /* CCDataVisitor.h */; };
+ 50ABBE411925AB6F00A911A9 /* CCDirector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD21925AB6E00A911A9 /* CCDirector.cpp */; };
+ 50ABBE421925AB6F00A911A9 /* CCDirector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD21925AB6E00A911A9 /* CCDirector.cpp */; };
+ 50ABBE431925AB6F00A911A9 /* CCDirector.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD31925AB6E00A911A9 /* CCDirector.h */; };
+ 50ABBE441925AB6F00A911A9 /* CCDirector.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD31925AB6E00A911A9 /* CCDirector.h */; };
+ 50ABBE451925AB6F00A911A9 /* CCEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD41925AB6E00A911A9 /* CCEvent.cpp */; };
+ 50ABBE461925AB6F00A911A9 /* CCEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD41925AB6E00A911A9 /* CCEvent.cpp */; };
+ 50ABBE471925AB6F00A911A9 /* CCEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD51925AB6E00A911A9 /* CCEvent.h */; };
+ 50ABBE481925AB6F00A911A9 /* CCEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD51925AB6E00A911A9 /* CCEvent.h */; };
+ 50ABBE491925AB6F00A911A9 /* CCEventAcceleration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD61925AB6E00A911A9 /* CCEventAcceleration.cpp */; };
+ 50ABBE4A1925AB6F00A911A9 /* CCEventAcceleration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD61925AB6E00A911A9 /* CCEventAcceleration.cpp */; };
+ 50ABBE4B1925AB6F00A911A9 /* CCEventAcceleration.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD71925AB6E00A911A9 /* CCEventAcceleration.h */; };
+ 50ABBE4C1925AB6F00A911A9 /* CCEventAcceleration.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD71925AB6E00A911A9 /* CCEventAcceleration.h */; };
+ 50ABBE4D1925AB6F00A911A9 /* CCEventCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD81925AB6E00A911A9 /* CCEventCustom.cpp */; };
+ 50ABBE4E1925AB6F00A911A9 /* CCEventCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDD81925AB6E00A911A9 /* CCEventCustom.cpp */; };
+ 50ABBE4F1925AB6F00A911A9 /* CCEventCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD91925AB6E00A911A9 /* CCEventCustom.h */; };
+ 50ABBE501925AB6F00A911A9 /* CCEventCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDD91925AB6E00A911A9 /* CCEventCustom.h */; };
+ 50ABBE511925AB6F00A911A9 /* CCEventDispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDDA1925AB6E00A911A9 /* CCEventDispatcher.cpp */; };
+ 50ABBE521925AB6F00A911A9 /* CCEventDispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDDA1925AB6E00A911A9 /* CCEventDispatcher.cpp */; };
+ 50ABBE531925AB6F00A911A9 /* CCEventDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDDB1925AB6E00A911A9 /* CCEventDispatcher.h */; };
+ 50ABBE541925AB6F00A911A9 /* CCEventDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDDB1925AB6E00A911A9 /* CCEventDispatcher.h */; };
+ 50ABBE551925AB6F00A911A9 /* CCEventFocus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDDC1925AB6E00A911A9 /* CCEventFocus.cpp */; };
+ 50ABBE561925AB6F00A911A9 /* CCEventFocus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDDC1925AB6E00A911A9 /* CCEventFocus.cpp */; };
+ 50ABBE571925AB6F00A911A9 /* CCEventFocus.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDDD1925AB6E00A911A9 /* CCEventFocus.h */; };
+ 50ABBE581925AB6F00A911A9 /* CCEventFocus.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDDD1925AB6E00A911A9 /* CCEventFocus.h */; };
+ 50ABBE591925AB6F00A911A9 /* CCEventKeyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDDE1925AB6E00A911A9 /* CCEventKeyboard.cpp */; };
+ 50ABBE5A1925AB6F00A911A9 /* CCEventKeyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDDE1925AB6E00A911A9 /* CCEventKeyboard.cpp */; };
+ 50ABBE5B1925AB6F00A911A9 /* CCEventKeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDDF1925AB6E00A911A9 /* CCEventKeyboard.h */; };
+ 50ABBE5C1925AB6F00A911A9 /* CCEventKeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDDF1925AB6E00A911A9 /* CCEventKeyboard.h */; };
+ 50ABBE5D1925AB6F00A911A9 /* CCEventListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE01925AB6E00A911A9 /* CCEventListener.cpp */; };
+ 50ABBE5E1925AB6F00A911A9 /* CCEventListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE01925AB6E00A911A9 /* CCEventListener.cpp */; };
+ 50ABBE5F1925AB6F00A911A9 /* CCEventListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE11925AB6E00A911A9 /* CCEventListener.h */; };
+ 50ABBE601925AB6F00A911A9 /* CCEventListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE11925AB6E00A911A9 /* CCEventListener.h */; };
+ 50ABBE611925AB6F00A911A9 /* CCEventListenerAcceleration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE21925AB6E00A911A9 /* CCEventListenerAcceleration.cpp */; };
+ 50ABBE621925AB6F00A911A9 /* CCEventListenerAcceleration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE21925AB6E00A911A9 /* CCEventListenerAcceleration.cpp */; };
+ 50ABBE631925AB6F00A911A9 /* CCEventListenerAcceleration.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE31925AB6E00A911A9 /* CCEventListenerAcceleration.h */; };
+ 50ABBE641925AB6F00A911A9 /* CCEventListenerAcceleration.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE31925AB6E00A911A9 /* CCEventListenerAcceleration.h */; };
+ 50ABBE651925AB6F00A911A9 /* CCEventListenerCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE41925AB6E00A911A9 /* CCEventListenerCustom.cpp */; };
+ 50ABBE661925AB6F00A911A9 /* CCEventListenerCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE41925AB6E00A911A9 /* CCEventListenerCustom.cpp */; };
+ 50ABBE671925AB6F00A911A9 /* CCEventListenerCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE51925AB6E00A911A9 /* CCEventListenerCustom.h */; };
+ 50ABBE681925AB6F00A911A9 /* CCEventListenerCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE51925AB6E00A911A9 /* CCEventListenerCustom.h */; };
+ 50ABBE691925AB6F00A911A9 /* CCEventListenerFocus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE61925AB6E00A911A9 /* CCEventListenerFocus.cpp */; };
+ 50ABBE6A1925AB6F00A911A9 /* CCEventListenerFocus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE61925AB6E00A911A9 /* CCEventListenerFocus.cpp */; };
+ 50ABBE6B1925AB6F00A911A9 /* CCEventListenerFocus.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE71925AB6E00A911A9 /* CCEventListenerFocus.h */; };
+ 50ABBE6C1925AB6F00A911A9 /* CCEventListenerFocus.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE71925AB6E00A911A9 /* CCEventListenerFocus.h */; };
+ 50ABBE6D1925AB6F00A911A9 /* CCEventListenerKeyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE81925AB6E00A911A9 /* CCEventListenerKeyboard.cpp */; };
+ 50ABBE6E1925AB6F00A911A9 /* CCEventListenerKeyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDE81925AB6E00A911A9 /* CCEventListenerKeyboard.cpp */; };
+ 50ABBE6F1925AB6F00A911A9 /* CCEventListenerKeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE91925AB6E00A911A9 /* CCEventListenerKeyboard.h */; };
+ 50ABBE701925AB6F00A911A9 /* CCEventListenerKeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDE91925AB6E00A911A9 /* CCEventListenerKeyboard.h */; };
+ 50ABBE711925AB6F00A911A9 /* CCEventListenerMouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDEA1925AB6E00A911A9 /* CCEventListenerMouse.cpp */; };
+ 50ABBE721925AB6F00A911A9 /* CCEventListenerMouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDEA1925AB6E00A911A9 /* CCEventListenerMouse.cpp */; };
+ 50ABBE731925AB6F00A911A9 /* CCEventListenerMouse.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDEB1925AB6E00A911A9 /* CCEventListenerMouse.h */; };
+ 50ABBE741925AB6F00A911A9 /* CCEventListenerMouse.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDEB1925AB6E00A911A9 /* CCEventListenerMouse.h */; };
+ 50ABBE751925AB6F00A911A9 /* CCEventListenerTouch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDEC1925AB6E00A911A9 /* CCEventListenerTouch.cpp */; };
+ 50ABBE761925AB6F00A911A9 /* CCEventListenerTouch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDEC1925AB6E00A911A9 /* CCEventListenerTouch.cpp */; };
+ 50ABBE771925AB6F00A911A9 /* CCEventListenerTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDED1925AB6E00A911A9 /* CCEventListenerTouch.h */; };
+ 50ABBE781925AB6F00A911A9 /* CCEventListenerTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDED1925AB6E00A911A9 /* CCEventListenerTouch.h */; };
+ 50ABBE791925AB6F00A911A9 /* CCEventMouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDEE1925AB6E00A911A9 /* CCEventMouse.cpp */; };
+ 50ABBE7A1925AB6F00A911A9 /* CCEventMouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDEE1925AB6E00A911A9 /* CCEventMouse.cpp */; };
+ 50ABBE7B1925AB6F00A911A9 /* CCEventMouse.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDEF1925AB6E00A911A9 /* CCEventMouse.h */; };
+ 50ABBE7C1925AB6F00A911A9 /* CCEventMouse.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDEF1925AB6E00A911A9 /* CCEventMouse.h */; };
+ 50ABBE7D1925AB6F00A911A9 /* CCEventTouch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDF01925AB6E00A911A9 /* CCEventTouch.cpp */; };
+ 50ABBE7E1925AB6F00A911A9 /* CCEventTouch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDF01925AB6E00A911A9 /* CCEventTouch.cpp */; };
+ 50ABBE7F1925AB6F00A911A9 /* CCEventTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF11925AB6E00A911A9 /* CCEventTouch.h */; };
+ 50ABBE801925AB6F00A911A9 /* CCEventTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF11925AB6E00A911A9 /* CCEventTouch.h */; };
+ 50ABBE811925AB6F00A911A9 /* CCEventType.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF21925AB6E00A911A9 /* CCEventType.h */; };
+ 50ABBE821925AB6F00A911A9 /* CCEventType.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF21925AB6E00A911A9 /* CCEventType.h */; };
+ 50ABBE831925AB6F00A911A9 /* ccFPSImages.c in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDF31925AB6E00A911A9 /* ccFPSImages.c */; };
+ 50ABBE841925AB6F00A911A9 /* ccFPSImages.c in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDF31925AB6E00A911A9 /* ccFPSImages.c */; };
+ 50ABBE851925AB6F00A911A9 /* ccFPSImages.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF41925AB6E00A911A9 /* ccFPSImages.h */; };
+ 50ABBE861925AB6F00A911A9 /* ccFPSImages.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF41925AB6E00A911A9 /* ccFPSImages.h */; };
+ 50ABBE871925AB6F00A911A9 /* ccMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF51925AB6E00A911A9 /* ccMacros.h */; };
+ 50ABBE881925AB6F00A911A9 /* ccMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF51925AB6E00A911A9 /* ccMacros.h */; };
+ 50ABBE891925AB6F00A911A9 /* CCMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF61925AB6E00A911A9 /* CCMap.h */; };
+ 50ABBE8A1925AB6F00A911A9 /* CCMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF61925AB6E00A911A9 /* CCMap.h */; };
+ 50ABBE8B1925AB6F00A911A9 /* CCNS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDF71925AB6E00A911A9 /* CCNS.cpp */; };
+ 50ABBE8C1925AB6F00A911A9 /* CCNS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDF71925AB6E00A911A9 /* CCNS.cpp */; };
+ 50ABBE8D1925AB6F00A911A9 /* CCNS.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF81925AB6E00A911A9 /* CCNS.h */; };
+ 50ABBE8E1925AB6F00A911A9 /* CCNS.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDF81925AB6E00A911A9 /* CCNS.h */; };
+ 50ABBE931925AB6F00A911A9 /* CCProfiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDFB1925AB6E00A911A9 /* CCProfiling.cpp */; };
+ 50ABBE941925AB6F00A911A9 /* CCProfiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDFB1925AB6E00A911A9 /* CCProfiling.cpp */; };
+ 50ABBE951925AB6F00A911A9 /* CCProfiling.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDFC1925AB6E00A911A9 /* CCProfiling.h */; };
+ 50ABBE961925AB6F00A911A9 /* CCProfiling.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDFC1925AB6E00A911A9 /* CCProfiling.h */; };
+ 50ABBE971925AB6F00A911A9 /* CCProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDFD1925AB6E00A911A9 /* CCProtocols.h */; };
+ 50ABBE981925AB6F00A911A9 /* CCProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDFD1925AB6E00A911A9 /* CCProtocols.h */; };
+ 50ABBE991925AB6F00A911A9 /* CCRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDFE1925AB6E00A911A9 /* CCRef.cpp */; };
+ 50ABBE9A1925AB6F00A911A9 /* CCRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBDFE1925AB6E00A911A9 /* CCRef.cpp */; };
+ 50ABBE9B1925AB6F00A911A9 /* CCRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDFF1925AB6E00A911A9 /* CCRef.h */; };
+ 50ABBE9C1925AB6F00A911A9 /* CCRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBDFF1925AB6E00A911A9 /* CCRef.h */; };
+ 50ABBE9D1925AB6F00A911A9 /* CCRefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE001925AB6E00A911A9 /* CCRefPtr.h */; };
+ 50ABBE9E1925AB6F00A911A9 /* CCRefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE001925AB6E00A911A9 /* CCRefPtr.h */; };
+ 50ABBE9F1925AB6F00A911A9 /* CCScheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE011925AB6E00A911A9 /* CCScheduler.cpp */; };
+ 50ABBEA01925AB6F00A911A9 /* CCScheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE011925AB6E00A911A9 /* CCScheduler.cpp */; };
+ 50ABBEA11925AB6F00A911A9 /* CCScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE021925AB6E00A911A9 /* CCScheduler.h */; };
+ 50ABBEA21925AB6F00A911A9 /* CCScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE021925AB6E00A911A9 /* CCScheduler.h */; };
+ 50ABBEA31925AB6F00A911A9 /* CCScriptSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE031925AB6E00A911A9 /* CCScriptSupport.cpp */; };
+ 50ABBEA41925AB6F00A911A9 /* CCScriptSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE031925AB6E00A911A9 /* CCScriptSupport.cpp */; };
+ 50ABBEA51925AB6F00A911A9 /* CCScriptSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE041925AB6E00A911A9 /* CCScriptSupport.h */; };
+ 50ABBEA61925AB6F00A911A9 /* CCScriptSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE041925AB6E00A911A9 /* CCScriptSupport.h */; };
+ 50ABBEA71925AB6F00A911A9 /* CCTouch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE051925AB6E00A911A9 /* CCTouch.cpp */; };
+ 50ABBEA81925AB6F00A911A9 /* CCTouch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE051925AB6E00A911A9 /* CCTouch.cpp */; };
+ 50ABBEA91925AB6F00A911A9 /* CCTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE061925AB6E00A911A9 /* CCTouch.h */; };
+ 50ABBEAA1925AB6F00A911A9 /* CCTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE061925AB6E00A911A9 /* CCTouch.h */; };
+ 50ABBEAB1925AB6F00A911A9 /* ccTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE071925AB6E00A911A9 /* ccTypes.cpp */; };
+ 50ABBEAC1925AB6F00A911A9 /* ccTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE071925AB6E00A911A9 /* ccTypes.cpp */; };
+ 50ABBEAD1925AB6F00A911A9 /* ccTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE081925AB6E00A911A9 /* ccTypes.h */; };
+ 50ABBEAE1925AB6F00A911A9 /* ccTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE081925AB6E00A911A9 /* ccTypes.h */; };
+ 50ABBEAF1925AB6F00A911A9 /* CCUserDefault.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE091925AB6E00A911A9 /* CCUserDefault.cpp */; };
+ 50ABBEB01925AB6F00A911A9 /* CCUserDefault.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE091925AB6E00A911A9 /* CCUserDefault.cpp */; };
+ 50ABBEB11925AB6F00A911A9 /* CCUserDefault.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE0A1925AB6E00A911A9 /* CCUserDefault.h */; };
+ 50ABBEB21925AB6F00A911A9 /* CCUserDefault.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE0A1925AB6E00A911A9 /* CCUserDefault.h */; };
+ 50ABBEB31925AB6F00A911A9 /* CCUserDefault-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE0B1925AB6F00A911A9 /* CCUserDefault-apple.mm */; };
+ 50ABBEB41925AB6F00A911A9 /* CCUserDefault-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE0B1925AB6F00A911A9 /* CCUserDefault-apple.mm */; };
+ 50ABBEB51925AB6F00A911A9 /* CCUserDefault-android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE0C1925AB6F00A911A9 /* CCUserDefault-android.cpp */; };
+ 50ABBEB61925AB6F00A911A9 /* CCUserDefault-android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE0C1925AB6F00A911A9 /* CCUserDefault-android.cpp */; };
+ 50ABBEB71925AB6F00A911A9 /* ccUTF8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE0D1925AB6F00A911A9 /* ccUTF8.cpp */; };
+ 50ABBEB81925AB6F00A911A9 /* ccUTF8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE0D1925AB6F00A911A9 /* ccUTF8.cpp */; };
+ 50ABBEB91925AB6F00A911A9 /* ccUTF8.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE0E1925AB6F00A911A9 /* ccUTF8.h */; };
+ 50ABBEBA1925AB6F00A911A9 /* ccUTF8.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE0E1925AB6F00A911A9 /* ccUTF8.h */; };
+ 50ABBEBB1925AB6F00A911A9 /* ccUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE0F1925AB6F00A911A9 /* ccUtils.cpp */; };
+ 50ABBEBC1925AB6F00A911A9 /* ccUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE0F1925AB6F00A911A9 /* ccUtils.cpp */; };
+ 50ABBEBD1925AB6F00A911A9 /* ccUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE101925AB6F00A911A9 /* ccUtils.h */; };
+ 50ABBEBE1925AB6F00A911A9 /* ccUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE101925AB6F00A911A9 /* ccUtils.h */; };
+ 50ABBEBF1925AB6F00A911A9 /* CCValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE111925AB6F00A911A9 /* CCValue.cpp */; };
+ 50ABBEC01925AB6F00A911A9 /* CCValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE111925AB6F00A911A9 /* CCValue.cpp */; };
+ 50ABBEC11925AB6F00A911A9 /* CCValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE121925AB6F00A911A9 /* CCValue.h */; };
+ 50ABBEC21925AB6F00A911A9 /* CCValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE121925AB6F00A911A9 /* CCValue.h */; };
+ 50ABBEC31925AB6F00A911A9 /* CCVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE131925AB6F00A911A9 /* CCVector.h */; };
+ 50ABBEC41925AB6F00A911A9 /* CCVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE131925AB6F00A911A9 /* CCVector.h */; };
+ 50ABBEC51925AB6F00A911A9 /* etc1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE141925AB6F00A911A9 /* etc1.cpp */; };
+ 50ABBEC61925AB6F00A911A9 /* etc1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE141925AB6F00A911A9 /* etc1.cpp */; };
+ 50ABBEC71925AB6F00A911A9 /* etc1.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE151925AB6F00A911A9 /* etc1.h */; };
+ 50ABBEC81925AB6F00A911A9 /* etc1.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE151925AB6F00A911A9 /* etc1.h */; };
+ 50ABBEC91925AB6F00A911A9 /* firePngData.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE161925AB6F00A911A9 /* firePngData.h */; };
+ 50ABBECA1925AB6F00A911A9 /* firePngData.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE161925AB6F00A911A9 /* firePngData.h */; };
+ 50ABBECB1925AB6F00A911A9 /* s3tc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE171925AB6F00A911A9 /* s3tc.cpp */; };
+ 50ABBECC1925AB6F00A911A9 /* s3tc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE171925AB6F00A911A9 /* s3tc.cpp */; };
+ 50ABBECD1925AB6F00A911A9 /* s3tc.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE181925AB6F00A911A9 /* s3tc.h */; };
+ 50ABBECE1925AB6F00A911A9 /* s3tc.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE181925AB6F00A911A9 /* s3tc.h */; };
+ 50ABBECF1925AB6F00A911A9 /* TGAlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE191925AB6F00A911A9 /* TGAlib.cpp */; };
+ 50ABBED01925AB6F00A911A9 /* TGAlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE191925AB6F00A911A9 /* TGAlib.cpp */; };
+ 50ABBED11925AB6F00A911A9 /* TGAlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE1A1925AB6F00A911A9 /* TGAlib.h */; };
+ 50ABBED21925AB6F00A911A9 /* TGAlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE1A1925AB6F00A911A9 /* TGAlib.h */; };
+ 50ABBED31925AB6F00A911A9 /* uthash.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE1B1925AB6F00A911A9 /* uthash.h */; };
+ 50ABBED41925AB6F00A911A9 /* uthash.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE1B1925AB6F00A911A9 /* uthash.h */; };
+ 50ABBED51925AB6F00A911A9 /* utlist.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE1C1925AB6F00A911A9 /* utlist.h */; };
+ 50ABBED61925AB6F00A911A9 /* utlist.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE1C1925AB6F00A911A9 /* utlist.h */; };
+ 50ABBED71925AB6F00A911A9 /* ZipUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE1D1925AB6F00A911A9 /* ZipUtils.cpp */; };
+ 50ABBED81925AB6F00A911A9 /* ZipUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBE1D1925AB6F00A911A9 /* ZipUtils.cpp */; };
+ 50ABBED91925AB6F00A911A9 /* ZipUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE1E1925AB6F00A911A9 /* ZipUtils.h */; };
+ 50ABBEDA1925AB6F00A911A9 /* ZipUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBE1E1925AB6F00A911A9 /* ZipUtils.h */; };
+ 50ABBFFD1926664800A911A9 /* CCFileUtils-apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF1B1926664700A911A9 /* CCFileUtils-apple.h */; };
+ 50ABBFFE1926664800A911A9 /* CCFileUtils-apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF1B1926664700A911A9 /* CCFileUtils-apple.h */; };
+ 50ABBFFF1926664800A911A9 /* CCFileUtils-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF1C1926664700A911A9 /* CCFileUtils-apple.mm */; };
+ 50ABC0001926664800A911A9 /* CCFileUtils-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF1C1926664700A911A9 /* CCFileUtils-apple.mm */; };
+ 50ABC0011926664800A911A9 /* CCLock-apple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF1D1926664700A911A9 /* CCLock-apple.cpp */; };
+ 50ABC0021926664800A911A9 /* CCLock-apple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF1D1926664700A911A9 /* CCLock-apple.cpp */; };
+ 50ABC0031926664800A911A9 /* CCLock-apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF1E1926664700A911A9 /* CCLock-apple.h */; };
+ 50ABC0041926664800A911A9 /* CCLock-apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF1E1926664700A911A9 /* CCLock-apple.h */; };
+ 50ABC0051926664800A911A9 /* CCThread-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF1F1926664700A911A9 /* CCThread-apple.mm */; };
+ 50ABC0061926664800A911A9 /* CCThread-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF1F1926664700A911A9 /* CCThread-apple.mm */; };
+ 50ABC0071926664800A911A9 /* CCApplicationProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF201926664700A911A9 /* CCApplicationProtocol.h */; };
+ 50ABC0081926664800A911A9 /* CCApplicationProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF201926664700A911A9 /* CCApplicationProtocol.h */; };
+ 50ABC0091926664800A911A9 /* CCCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF211926664700A911A9 /* CCCommon.h */; };
+ 50ABC00A1926664800A911A9 /* CCCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF211926664700A911A9 /* CCCommon.h */; };
+ 50ABC00B1926664800A911A9 /* CCDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF221926664700A911A9 /* CCDevice.h */; };
+ 50ABC00C1926664800A911A9 /* CCDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF221926664700A911A9 /* CCDevice.h */; };
+ 50ABC00D1926664800A911A9 /* CCFileUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF231926664700A911A9 /* CCFileUtils.cpp */; };
+ 50ABC00E1926664800A911A9 /* CCFileUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF231926664700A911A9 /* CCFileUtils.cpp */; };
+ 50ABC00F1926664800A911A9 /* CCFileUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF241926664700A911A9 /* CCFileUtils.h */; };
+ 50ABC0101926664800A911A9 /* CCFileUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF241926664700A911A9 /* CCFileUtils.h */; };
+ 50ABC0111926664800A911A9 /* CCGLView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF251926664700A911A9 /* CCGLView.cpp */; };
+ 50ABC0121926664800A911A9 /* CCGLView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF251926664700A911A9 /* CCGLView.cpp */; };
+ 50ABC0131926664800A911A9 /* CCGLView.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF261926664700A911A9 /* CCGLView.h */; };
+ 50ABC0141926664800A911A9 /* CCGLView.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF261926664700A911A9 /* CCGLView.h */; };
+ 50ABC0151926664800A911A9 /* CCImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF271926664700A911A9 /* CCImage.cpp */; };
+ 50ABC0161926664800A911A9 /* CCImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF271926664700A911A9 /* CCImage.cpp */; };
+ 50ABC0171926664800A911A9 /* CCImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF281926664700A911A9 /* CCImage.h */; };
+ 50ABC0181926664800A911A9 /* CCImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF281926664700A911A9 /* CCImage.h */; };
+ 50ABC0191926664800A911A9 /* CCSAXParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF291926664700A911A9 /* CCSAXParser.cpp */; };
+ 50ABC01A1926664800A911A9 /* CCSAXParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF291926664700A911A9 /* CCSAXParser.cpp */; };
+ 50ABC01B1926664800A911A9 /* CCSAXParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF2A1926664700A911A9 /* CCSAXParser.h */; };
+ 50ABC01C1926664800A911A9 /* CCSAXParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF2A1926664700A911A9 /* CCSAXParser.h */; };
+ 50ABC01D1926664800A911A9 /* CCThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF2B1926664700A911A9 /* CCThread.cpp */; };
+ 50ABC01E1926664800A911A9 /* CCThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF2B1926664700A911A9 /* CCThread.cpp */; };
+ 50ABC01F1926664800A911A9 /* CCThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF2C1926664700A911A9 /* CCThread.h */; };
+ 50ABC0201926664800A911A9 /* CCThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF2C1926664700A911A9 /* CCThread.h */; };
+ 50ABC0211926664800A911A9 /* CCGLViewImpl-desktop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF2E1926664700A911A9 /* CCGLViewImpl-desktop.cpp */; };
+ 50ABC0231926664800A911A9 /* CCGLViewImpl-desktop.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF2F1926664700A911A9 /* CCGLViewImpl-desktop.h */; };
+ 50ABC05D1926664800A911A9 /* CCApplication-mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF4F1926664700A911A9 /* CCApplication-mac.h */; };
+ 50ABC05F1926664800A911A9 /* CCApplication-mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF501926664700A911A9 /* CCApplication-mac.mm */; };
+ 50ABC0611926664800A911A9 /* CCCommon-mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF511926664700A911A9 /* CCCommon-mac.mm */; };
+ 50ABC0631926664800A911A9 /* CCDevice-mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50ABBF521926664700A911A9 /* CCDevice-mac.mm */; };
+ 50ABC0651926664800A911A9 /* CCGL-mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF531926664700A911A9 /* CCGL-mac.h */; };
+ 50ABC0671926664800A911A9 /* CCPlatformDefine-mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF541926664700A911A9 /* CCPlatformDefine-mac.h */; };
+ 50ABC0691926664800A911A9 /* CCStdC-mac.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF551926664700A911A9 /* CCStdC-mac.h */; };
+ 50CB247519D9C5A100687767 /* AudioCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CB246F19D9C5A100687767 /* AudioCache.h */; };
+ 50CB247619D9C5A100687767 /* AudioCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CB246F19D9C5A100687767 /* AudioCache.h */; };
+ 50CB247719D9C5A100687767 /* AudioCache.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50CB247019D9C5A100687767 /* AudioCache.mm */; };
+ 50CB247819D9C5A100687767 /* AudioCache.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50CB247019D9C5A100687767 /* AudioCache.mm */; };
+ 50CB247919D9C5A100687767 /* AudioEngine-inl.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CB247119D9C5A100687767 /* AudioEngine-inl.h */; };
+ 50CB247A19D9C5A100687767 /* AudioEngine-inl.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CB247119D9C5A100687767 /* AudioEngine-inl.h */; };
+ 50CB247B19D9C5A100687767 /* AudioEngine-inl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50CB247219D9C5A100687767 /* AudioEngine-inl.mm */; };
+ 50CB247C19D9C5A100687767 /* AudioEngine-inl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50CB247219D9C5A100687767 /* AudioEngine-inl.mm */; };
+ 50CB247D19D9C5A100687767 /* AudioPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CB247319D9C5A100687767 /* AudioPlayer.h */; };
+ 50CB247E19D9C5A100687767 /* AudioPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CB247319D9C5A100687767 /* AudioPlayer.h */; };
+ 50CB247F19D9C5A100687767 /* AudioPlayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50CB247419D9C5A100687767 /* AudioPlayer.mm */; };
+ 50CB248019D9C5A100687767 /* AudioPlayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 50CB247419D9C5A100687767 /* AudioPlayer.mm */; };
+ 50CE4D1F1D243DD8003D2FB9 /* glfw3.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CE4D1D1D243DD8003D2FB9 /* glfw3.h */; };
+ 50CE4D201D243DD8003D2FB9 /* glfw3native.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CE4D1E1D243DD8003D2FB9 /* glfw3native.h */; };
+ 50ED2BDA19BE76D300A0AB90 /* UIVideoPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EA0FB69191C841D00B170C8 /* UIVideoPlayer.h */; };
+ 50ED2BDB19BE76D500A0AB90 /* UIVideoPlayer-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3EA0FB6A191C841D00B170C8 /* UIVideoPlayer-ios.mm */; };
+ 50ED2BE019BEAF7900A0AB90 /* UIEditBoxImpl-win32.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ED2BDC19BEAF7900A0AB90 /* UIEditBoxImpl-win32.h */; };
+ 50ED2BE119BEAF7900A0AB90 /* UIEditBoxImpl-win32.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ED2BDC19BEAF7900A0AB90 /* UIEditBoxImpl-win32.h */; };
+ 50ED2BE419BEAF7900A0AB90 /* UIEditBoxImpl-win32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ED2BDE19BEAF7900A0AB90 /* UIEditBoxImpl-win32.cpp */; };
+ 50ED2BE519BEAF7900A0AB90 /* UIEditBoxImpl-win32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ED2BDE19BEAF7900A0AB90 /* UIEditBoxImpl-win32.cpp */; };
+ 50F965511CD0360000ADE813 /* CCVRGenericRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50F9654E1CD0360000ADE813 /* CCVRGenericRenderer.cpp */; };
+ 50F965521CD0360000ADE813 /* CCVRGenericRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50F9654E1CD0360000ADE813 /* CCVRGenericRenderer.cpp */; };
+ 50F965531CD0360000ADE813 /* CCVRGenericRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50F9654E1CD0360000ADE813 /* CCVRGenericRenderer.cpp */; };
+ 50F965541CD0360000ADE813 /* CCVRGenericRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F9654F1CD0360000ADE813 /* CCVRGenericRenderer.h */; };
+ 50F965551CD0360000ADE813 /* CCVRGenericRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F9654F1CD0360000ADE813 /* CCVRGenericRenderer.h */; };
+ 50F965561CD0360000ADE813 /* CCVRGenericRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F9654F1CD0360000ADE813 /* CCVRGenericRenderer.h */; };
+ 50F965571CD0360000ADE813 /* CCVRProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F965501CD0360000ADE813 /* CCVRProtocol.h */; };
+ 50F965581CD0360000ADE813 /* CCVRProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F965501CD0360000ADE813 /* CCVRProtocol.h */; };
+ 50F965591CD0360000ADE813 /* CCVRProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F965501CD0360000ADE813 /* CCVRProtocol.h */; };
+ 50FC3F9E1D74C0A3001C936A /* CCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E61781C1966A5A300DE83F5 /* CCController.cpp */; };
+ 50FC3F9F1D74C0E5001C936A /* CCController-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E6176551960F89B00DE83F5 /* CCController-apple.mm */; };
+ 50FC3FA21D74C1A1001C936A /* CCEventController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E6176611960F89B00DE83F5 /* CCEventController.cpp */; };
+ 50FC3FA81D74C2A1001C936A /* CCEventListenerController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E6176641960F89B00DE83F5 /* CCEventListenerController.h */; };
+ 50FC3FA91D74C2D1001C936A /* CCEventListenerController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E6176631960F89B00DE83F5 /* CCEventListenerController.cpp */; };
+ 52B47A2E1A5349A3004E4C60 /* HttpAsynConnection-apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B47A291A5349A3004E4C60 /* HttpAsynConnection-apple.h */; };
+ 52B47A2F1A5349A3004E4C60 /* HttpAsynConnection-apple.m in Sources */ = {isa = PBXBuildFile; fileRef = 52B47A2A1A5349A3004E4C60 /* HttpAsynConnection-apple.m */; };
+ 52B47A301A5349A3004E4C60 /* HttpClient-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52B47A2B1A5349A3004E4C60 /* HttpClient-apple.mm */; };
+ 52B47A311A5349A3004E4C60 /* HttpCookie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B47A2C1A5349A3004E4C60 /* HttpCookie.cpp */; };
+ 52B47A321A5349A3004E4C60 /* HttpCookie.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B47A2D1A5349A3004E4C60 /* HttpCookie.h */; };
+ 53E23A171E78B082009DD732 /* CCDevice-apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 294D7D931D0E67B4002CE7B7 /* CCDevice-apple.h */; };
+ 53E23A181E78B085009DD732 /* CCDevice-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 294D7D921D0E67B4002CE7B7 /* CCDevice-apple.mm */; };
+ 5E9F61261A3FFE3D0038DE01 /* CCFrustum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E9F61221A3FFE3D0038DE01 /* CCFrustum.cpp */; };
+ 5E9F61271A3FFE3D0038DE01 /* CCFrustum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E9F61221A3FFE3D0038DE01 /* CCFrustum.cpp */; };
+ 5E9F61281A3FFE3D0038DE01 /* CCFrustum.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E9F61231A3FFE3D0038DE01 /* CCFrustum.h */; };
+ 5E9F61291A3FFE3D0038DE01 /* CCFrustum.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E9F61231A3FFE3D0038DE01 /* CCFrustum.h */; };
+ 5E9F612A1A3FFE3D0038DE01 /* CCPlane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E9F61241A3FFE3D0038DE01 /* CCPlane.cpp */; };
+ 5E9F612B1A3FFE3D0038DE01 /* CCPlane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E9F61241A3FFE3D0038DE01 /* CCPlane.cpp */; };
+ 5E9F612C1A3FFE3D0038DE01 /* CCPlane.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E9F61251A3FFE3D0038DE01 /* CCPlane.h */; };
+ 5E9F612D1A3FFE3D0038DE01 /* CCPlane.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E9F61251A3FFE3D0038DE01 /* CCPlane.h */; };
+ 826294331AAF001C00CB7CF7 /* HttpAsynConnection-apple.m in Sources */ = {isa = PBXBuildFile; fileRef = 52B47A2A1A5349A3004E4C60 /* HttpAsynConnection-apple.m */; };
+ 826294341AAF003E00CB7CF7 /* HttpClient-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52B47A2B1A5349A3004E4C60 /* HttpClient-apple.mm */; };
+ 826294351AAF004C00CB7CF7 /* HttpCookie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52B47A2C1A5349A3004E4C60 /* HttpCookie.cpp */; };
+ 8525E3A21B291E42008EE815 /* clipper.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 8525E3A11B291E42008EE815 /* clipper.hpp */; };
+ 8525E3A31B291E42008EE815 /* clipper.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 8525E3A11B291E42008EE815 /* clipper.hpp */; };
+ 85505F041B60E3AB003F2CD4 /* CCBoneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306631B60B583001E6D43 /* CCBoneNode.cpp */; };
+ 85505F051B60E3B2003F2CD4 /* CCBoneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306641B60B583001E6D43 /* CCBoneNode.h */; };
+ 85505F061B60E3B6003F2CD4 /* CCSkeletonNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306651B60B583001E6D43 /* CCSkeletonNode.cpp */; };
+ 85505F071B60E3BA003F2CD4 /* CCSkeletonNode.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306661B60B583001E6D43 /* CCSkeletonNode.h */; };
+ 85505F081B60E3BD003F2CD4 /* CCSkinNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306671B60B583001E6D43 /* CCSkinNode.cpp */; };
+ 85505F091B60E3C1003F2CD4 /* CCSkinNode.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306681B60B583001E6D43 /* CCSkinNode.h */; };
+ 85505F0A1B60E3CE003F2CD4 /* BoneNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306701B60B5B2001E6D43 /* BoneNodeReader.cpp */; };
+ 85505F0B1B60E3D1003F2CD4 /* BoneNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306711B60B5B2001E6D43 /* BoneNodeReader.h */; };
+ 85505F0C1B60E3D5003F2CD4 /* CSBoneBinary_generated.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306721B60B5B2001E6D43 /* CSBoneBinary_generated.h */; };
+ 85505F0D1B60E3D8003F2CD4 /* SkeletonNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306731B60B5B2001E6D43 /* SkeletonNodeReader.cpp */; };
+ 85505F0E1B60E3DB003F2CD4 /* SkeletonNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306741B60B5B2001E6D43 /* SkeletonNodeReader.h */; };
+ 85B3743A1B204B9400C488D6 /* clipper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 85B374381B204B9400C488D6 /* clipper.cpp */; };
+ 85B3743B1B204B9400C488D6 /* clipper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 85B374381B204B9400C488D6 /* clipper.cpp */; };
+ 94A6DF051C7303FD0094AEF7 /* LocalizationManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A6DF031C7303FD0094AEF7 /* LocalizationManager.cpp */; };
+ 94A6DF061C7303FD0094AEF7 /* LocalizationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 94A6DF041C7303FD0094AEF7 /* LocalizationManager.h */; };
+ 94A6DF071C73040D0094AEF7 /* LocalizationManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A6DF031C7303FD0094AEF7 /* LocalizationManager.cpp */; };
+ 94A6DF081C73040E0094AEF7 /* LocalizationManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A6DF031C7303FD0094AEF7 /* LocalizationManager.cpp */; };
+ 94A6DF091C7304120094AEF7 /* LocalizationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 94A6DF041C7303FD0094AEF7 /* LocalizationManager.h */; };
+ 94A6DF0A1C7304120094AEF7 /* LocalizationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 94A6DF041C7303FD0094AEF7 /* LocalizationManager.h */; };
+ A045F6D61BA81577005076C7 /* CCTextureCube.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A045F6D41BA81577005076C7 /* CCTextureCube.cpp */; };
+ A045F6D71BA81577005076C7 /* CCTextureCube.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A045F6D41BA81577005076C7 /* CCTextureCube.cpp */; };
+ A045F6D81BA81577005076C7 /* CCTextureCube.h in Headers */ = {isa = PBXBuildFile; fileRef = A045F6D51BA81577005076C7 /* CCTextureCube.h */; };
+ A045F6D91BA81577005076C7 /* CCTextureCube.h in Headers */ = {isa = PBXBuildFile; fileRef = A045F6D51BA81577005076C7 /* CCTextureCube.h */; };
+ A045F6DC1BA816A1005076C7 /* CCCameraBackgroundBrush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A045F6DA1BA816A1005076C7 /* CCCameraBackgroundBrush.cpp */; };
+ A045F6DD1BA816A1005076C7 /* CCCameraBackgroundBrush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A045F6DA1BA816A1005076C7 /* CCCameraBackgroundBrush.cpp */; };
+ A045F6DE1BA816A1005076C7 /* CCCameraBackgroundBrush.h in Headers */ = {isa = PBXBuildFile; fileRef = A045F6DB1BA816A1005076C7 /* CCCameraBackgroundBrush.h */; };
+ A045F6DF1BA816A1005076C7 /* CCCameraBackgroundBrush.h in Headers */ = {isa = PBXBuildFile; fileRef = A045F6DB1BA816A1005076C7 /* CCCameraBackgroundBrush.h */; };
+ A045F6EF1BA81821005076C7 /* GameNode3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A045F6ED1BA81821005076C7 /* GameNode3DReader.cpp */; };
+ A045F6F01BA81821005076C7 /* GameNode3DReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A045F6ED1BA81821005076C7 /* GameNode3DReader.cpp */; };
+ A045F6F11BA81821005076C7 /* GameNode3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = A045F6EE1BA81821005076C7 /* GameNode3DReader.h */; };
+ A045F6F21BA81821005076C7 /* GameNode3DReader.h in Headers */ = {isa = PBXBuildFile; fileRef = A045F6EE1BA81821005076C7 /* GameNode3DReader.h */; };
+ A0534A651B872FFD006B03E5 /* CCDownloader-apple.h in Headers */ = {isa = PBXBuildFile; fileRef = A0534A631B872FFD006B03E5 /* CCDownloader-apple.h */; };
+ A0534A661B872FFD006B03E5 /* CCDownloader-apple.h in Headers */ = {isa = PBXBuildFile; fileRef = A0534A631B872FFD006B03E5 /* CCDownloader-apple.h */; };
+ A0534A671B872FFD006B03E5 /* CCDownloader-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = A0534A641B872FFD006B03E5 /* CCDownloader-apple.mm */; };
+ A0534A681B872FFD006B03E5 /* CCDownloader-apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = A0534A641B872FFD006B03E5 /* CCDownloader-apple.mm */; };
+ A0534A6A1B87306E006B03E5 /* CCIDownloaderImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = A0534A691B87306E006B03E5 /* CCIDownloaderImpl.h */; };
+ A0534A6B1B87306E006B03E5 /* CCIDownloaderImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = A0534A691B87306E006B03E5 /* CCIDownloaderImpl.h */; };
+ A05DCF9D1B90584E00EE040B /* CCDownloader-curl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A05DCF9B1B90584E00EE040B /* CCDownloader-curl.cpp */; };
+ A05DCF9E1B90584E00EE040B /* CCDownloader-curl.h in Headers */ = {isa = PBXBuildFile; fileRef = A05DCF9C1B90584E00EE040B /* CCDownloader-curl.h */; };
+ A07A4CAF1783777C0073F6A7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1551A342158F2AB200E66CFE /* Foundation.framework */; };
+ A0E749F71BA8FD7F001A8332 /* UIEditBoxImpl-common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0E749F51BA8FD7F001A8332 /* UIEditBoxImpl-common.cpp */; };
+ A0E749F81BA8FD7F001A8332 /* UIEditBoxImpl-common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0E749F51BA8FD7F001A8332 /* UIEditBoxImpl-common.cpp */; };
+ A0E749F91BA8FD7F001A8332 /* UIEditBoxImpl-common.h in Headers */ = {isa = PBXBuildFile; fileRef = A0E749F61BA8FD7F001A8332 /* UIEditBoxImpl-common.h */; };
+ A0E749FA1BA8FD7F001A8332 /* UIEditBoxImpl-common.h in Headers */ = {isa = PBXBuildFile; fileRef = A0E749F61BA8FD7F001A8332 /* UIEditBoxImpl-common.h */; };
+ B2165EEA19921124000BE3E6 /* CCPrimitiveCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B257B45E198A353E00D9A687 /* CCPrimitiveCommand.cpp */; };
+ B217703C1977ECB4009EE11B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B217703B1977ECB4009EE11B /* IOKit.framework */; };
+ B21770401977ECE6009EE11B /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B217703F1977ECE6009EE11B /* OpenGL.framework */; };
+ B21770421977ECF8009EE11B /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B21770411977ECF8009EE11B /* ApplicationServices.framework */; };
+ B21770451977ED14009EE11B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B21770431977ED07009EE11B /* Cocoa.framework */; };
+ B21770471977ED34009EE11B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B21770461977ED34009EE11B /* QuartzCore.framework */; };
+ B230ED7119B417AE00364AA8 /* CCTrianglesCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B230ED6F19B417AE00364AA8 /* CCTrianglesCommand.cpp */; };
+ B230ED7219B417AE00364AA8 /* CCTrianglesCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B230ED6F19B417AE00364AA8 /* CCTrianglesCommand.cpp */; };
+ B230ED7319B417AE00364AA8 /* CCTrianglesCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = B230ED7019B417AE00364AA8 /* CCTrianglesCommand.h */; };
+ B230ED7419B417AE00364AA8 /* CCTrianglesCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = B230ED7019B417AE00364AA8 /* CCTrianglesCommand.h */; };
+ B240C5E91B09DFB000137F50 /* CCFrameBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B240C5E71B09DFB000137F50 /* CCFrameBuffer.cpp */; };
+ B240C5EA1B09DFB000137F50 /* CCFrameBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B240C5E71B09DFB000137F50 /* CCFrameBuffer.cpp */; };
+ B240C5EB1B09DFB000137F50 /* CCFrameBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = B240C5E81B09DFB000137F50 /* CCFrameBuffer.h */; };
+ B240C5EC1B09DFB000137F50 /* CCFrameBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = B240C5E81B09DFB000137F50 /* CCFrameBuffer.h */; };
+ B24AA985195A675C007B4522 /* CCFastTMXLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B24AA981195A675C007B4522 /* CCFastTMXLayer.cpp */; };
+ B24AA986195A675C007B4522 /* CCFastTMXLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B24AA981195A675C007B4522 /* CCFastTMXLayer.cpp */; };
+ B24AA987195A675C007B4522 /* CCFastTMXLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = B24AA982195A675C007B4522 /* CCFastTMXLayer.h */; };
+ B24AA988195A675C007B4522 /* CCFastTMXLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = B24AA982195A675C007B4522 /* CCFastTMXLayer.h */; };
+ B24AA989195A675C007B4522 /* CCFastTMXTiledMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B24AA983195A675C007B4522 /* CCFastTMXTiledMap.cpp */; };
+ B24AA98A195A675C007B4522 /* CCFastTMXTiledMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B24AA983195A675C007B4522 /* CCFastTMXTiledMap.cpp */; };
+ B24AA98B195A675C007B4522 /* CCFastTMXTiledMap.h in Headers */ = {isa = PBXBuildFile; fileRef = B24AA984195A675C007B4522 /* CCFastTMXTiledMap.h */; };
+ B24AA98C195A675C007B4522 /* CCFastTMXTiledMap.h in Headers */ = {isa = PBXBuildFile; fileRef = B24AA984195A675C007B4522 /* CCFastTMXTiledMap.h */; };
+ B257B44E1989D5E800D9A687 /* CCPrimitive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B257B44C1989D5E800D9A687 /* CCPrimitive.cpp */; };
+ B257B44F1989D5E800D9A687 /* CCPrimitive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B257B44C1989D5E800D9A687 /* CCPrimitive.cpp */; };
+ B257B4501989D5E800D9A687 /* CCPrimitive.h in Headers */ = {isa = PBXBuildFile; fileRef = B257B44D1989D5E800D9A687 /* CCPrimitive.h */; };
+ B257B4511989D5E800D9A687 /* CCPrimitive.h in Headers */ = {isa = PBXBuildFile; fileRef = B257B44D1989D5E800D9A687 /* CCPrimitive.h */; };
+ B257B460198A353E00D9A687 /* CCPrimitiveCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B257B45E198A353E00D9A687 /* CCPrimitiveCommand.cpp */; };
+ B257B461198A353E00D9A687 /* CCPrimitiveCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = B257B45F198A353E00D9A687 /* CCPrimitiveCommand.h */; };
+ B276EF5F1988D1D500CD400F /* CCVertexIndexData.h in Headers */ = {isa = PBXBuildFile; fileRef = B276EF5B1988D1D500CD400F /* CCVertexIndexData.h */; };
+ B276EF601988D1D500CD400F /* CCVertexIndexData.h in Headers */ = {isa = PBXBuildFile; fileRef = B276EF5B1988D1D500CD400F /* CCVertexIndexData.h */; };
+ B276EF611988D1D500CD400F /* CCVertexIndexData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B276EF5C1988D1D500CD400F /* CCVertexIndexData.cpp */; };
+ B276EF621988D1D500CD400F /* CCVertexIndexData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B276EF5C1988D1D500CD400F /* CCVertexIndexData.cpp */; };
+ B276EF631988D1D500CD400F /* CCVertexIndexBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = B276EF5D1988D1D500CD400F /* CCVertexIndexBuffer.h */; };
+ B276EF641988D1D500CD400F /* CCVertexIndexBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = B276EF5D1988D1D500CD400F /* CCVertexIndexBuffer.h */; };
+ B276EF651988D1D500CD400F /* CCVertexIndexBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B276EF5E1988D1D500CD400F /* CCVertexIndexBuffer.cpp */; };
+ B276EF661988D1D500CD400F /* CCVertexIndexBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B276EF5E1988D1D500CD400F /* CCVertexIndexBuffer.cpp */; };
+ B29594B41926D5EC003EEF37 /* CCMeshCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594B21926D5EC003EEF37 /* CCMeshCommand.cpp */; };
+ B29594B51926D5EC003EEF37 /* CCMeshCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594B21926D5EC003EEF37 /* CCMeshCommand.cpp */; };
+ B29594B61926D5EC003EEF37 /* CCMeshCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594B31926D5EC003EEF37 /* CCMeshCommand.h */; };
+ B29594B71926D5EC003EEF37 /* CCMeshCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594B31926D5EC003EEF37 /* CCMeshCommand.h */; };
+ B2CC507C19776DD10041958E /* CCPhysicsJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46A170721807CE7A005B8026 /* CCPhysicsJoint.cpp */; };
+ B5668D7D1B3838E4003CBD5E /* UIScrollViewBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5668D7B1B3838E4003CBD5E /* UIScrollViewBar.cpp */; };
+ B5668D7E1B3838E4003CBD5E /* UIScrollViewBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5668D7B1B3838E4003CBD5E /* UIScrollViewBar.cpp */; };
+ B5668D7F1B3838E4003CBD5E /* UIScrollViewBar.h in Headers */ = {isa = PBXBuildFile; fileRef = B5668D7C1B3838E4003CBD5E /* UIScrollViewBar.h */; };
+ B5668D801B3838E4003CBD5E /* UIScrollViewBar.h in Headers */ = {isa = PBXBuildFile; fileRef = B5668D7C1B3838E4003CBD5E /* UIScrollViewBar.h */; };
+ B5A738961BB0051F00BAAEF8 /* UIPageViewIndicator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5A738941BB0051F00BAAEF8 /* UIPageViewIndicator.cpp */; };
+ B5A738971BB0051F00BAAEF8 /* UIPageViewIndicator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5A738941BB0051F00BAAEF8 /* UIPageViewIndicator.cpp */; };
+ B5A738981BB0051F00BAAEF8 /* UIPageViewIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = B5A738951BB0051F00BAAEF8 /* UIPageViewIndicator.h */; };
+ B5A738991BB0051F00BAAEF8 /* UIPageViewIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = B5A738951BB0051F00BAAEF8 /* UIPageViewIndicator.h */; };
+ B5CE6DBE1B3BF2B1002B0419 /* UIAbstractCheckButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5CE6DBC1B3BF2B1002B0419 /* UIAbstractCheckButton.cpp */; };
+ B5CE6DBF1B3BF2B1002B0419 /* UIAbstractCheckButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5CE6DBC1B3BF2B1002B0419 /* UIAbstractCheckButton.cpp */; };
+ B5CE6DC01B3BF2B1002B0419 /* UIAbstractCheckButton.h in Headers */ = {isa = PBXBuildFile; fileRef = B5CE6DBD1B3BF2B1002B0419 /* UIAbstractCheckButton.h */; };
+ B5CE6DC11B3BF2B1002B0419 /* UIAbstractCheckButton.h in Headers */ = {isa = PBXBuildFile; fileRef = B5CE6DBD1B3BF2B1002B0419 /* UIAbstractCheckButton.h */; };
+ B5CE6DC81B3C05BA002B0419 /* UIRadioButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5CE6DC61B3C05BA002B0419 /* UIRadioButton.cpp */; };
+ B5CE6DC91B3C05BA002B0419 /* UIRadioButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5CE6DC61B3C05BA002B0419 /* UIRadioButton.cpp */; };
+ B5CE6DCA1B3C05BA002B0419 /* UIRadioButton.h in Headers */ = {isa = PBXBuildFile; fileRef = B5CE6DC71B3C05BA002B0419 /* UIRadioButton.h */; };
+ B5CE6DCB1B3C05BA002B0419 /* UIRadioButton.h in Headers */ = {isa = PBXBuildFile; fileRef = B5CE6DC71B3C05BA002B0419 /* UIRadioButton.h */; };
+ B603F1A81AC8EA0900A9579C /* CCTerrain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B603F1A61AC8EA0900A9579C /* CCTerrain.cpp */; };
+ B603F1A91AC8EA0900A9579C /* CCTerrain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B603F1A61AC8EA0900A9579C /* CCTerrain.cpp */; };
+ B603F1AA1AC8EA0900A9579C /* CCTerrain.h in Headers */ = {isa = PBXBuildFile; fileRef = B603F1A71AC8EA0900A9579C /* CCTerrain.h */; };
+ B603F1AB1AC8EA0900A9579C /* CCTerrain.h in Headers */ = {isa = PBXBuildFile; fileRef = B603F1A71AC8EA0900A9579C /* CCTerrain.h */; };
+ B60C5BD419AC68B10056FBDE /* CCBillBoard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B60C5BD219AC68B10056FBDE /* CCBillBoard.cpp */; };
+ B60C5BD519AC68B10056FBDE /* CCBillBoard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B60C5BD219AC68B10056FBDE /* CCBillBoard.cpp */; };
+ B60C5BD619AC68B10056FBDE /* CCBillBoard.h in Headers */ = {isa = PBXBuildFile; fileRef = B60C5BD319AC68B10056FBDE /* CCBillBoard.h */; };
+ B60C5BD719AC68B10056FBDE /* CCBillBoard.h in Headers */ = {isa = PBXBuildFile; fileRef = B60C5BD319AC68B10056FBDE /* CCBillBoard.h */; };
+ B63990CC1A490AFE00B07923 /* CCAsyncTaskPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B63990CA1A490AFE00B07923 /* CCAsyncTaskPool.cpp */; };
+ B63990CD1A490AFE00B07923 /* CCAsyncTaskPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B63990CA1A490AFE00B07923 /* CCAsyncTaskPool.cpp */; };
+ B63990CE1A490AFE00B07923 /* CCAsyncTaskPool.h in Headers */ = {isa = PBXBuildFile; fileRef = B63990CB1A490AFE00B07923 /* CCAsyncTaskPool.h */; };
+ B63990CF1A490AFE00B07923 /* CCAsyncTaskPool.h in Headers */ = {isa = PBXBuildFile; fileRef = B63990CB1A490AFE00B07923 /* CCAsyncTaskPool.h */; };
+ B665E1F21AA80A6500DDB1C5 /* CCPUAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0CC1AA80A6500DDB1C5 /* CCPUAffector.cpp */; };
+ B665E1F31AA80A6500DDB1C5 /* CCPUAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0CC1AA80A6500DDB1C5 /* CCPUAffector.cpp */; };
+ B665E1F41AA80A6500DDB1C5 /* CCPUAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0CD1AA80A6500DDB1C5 /* CCPUAffector.h */; };
+ B665E1F51AA80A6500DDB1C5 /* CCPUAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0CD1AA80A6500DDB1C5 /* CCPUAffector.h */; };
+ B665E1F61AA80A6500DDB1C5 /* CCPUAffectorManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0CE1AA80A6500DDB1C5 /* CCPUAffectorManager.cpp */; };
+ B665E1F71AA80A6500DDB1C5 /* CCPUAffectorManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0CE1AA80A6500DDB1C5 /* CCPUAffectorManager.cpp */; };
+ B665E1F81AA80A6500DDB1C5 /* CCPUAffectorManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0CF1AA80A6500DDB1C5 /* CCPUAffectorManager.h */; };
+ B665E1F91AA80A6500DDB1C5 /* CCPUAffectorManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0CF1AA80A6500DDB1C5 /* CCPUAffectorManager.h */; };
+ B665E1FA1AA80A6500DDB1C5 /* CCPUAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D01AA80A6500DDB1C5 /* CCPUAffectorTranslator.cpp */; };
+ B665E1FB1AA80A6500DDB1C5 /* CCPUAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D01AA80A6500DDB1C5 /* CCPUAffectorTranslator.cpp */; };
+ B665E1FC1AA80A6500DDB1C5 /* CCPUAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D11AA80A6500DDB1C5 /* CCPUAffectorTranslator.h */; };
+ B665E1FD1AA80A6500DDB1C5 /* CCPUAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D11AA80A6500DDB1C5 /* CCPUAffectorTranslator.h */; };
+ B665E1FE1AA80A6500DDB1C5 /* CCPUAlignAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D21AA80A6500DDB1C5 /* CCPUAlignAffector.cpp */; };
+ B665E1FF1AA80A6500DDB1C5 /* CCPUAlignAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D21AA80A6500DDB1C5 /* CCPUAlignAffector.cpp */; };
+ B665E2001AA80A6500DDB1C5 /* CCPUAlignAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D31AA80A6500DDB1C5 /* CCPUAlignAffector.h */; };
+ B665E2011AA80A6500DDB1C5 /* CCPUAlignAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D31AA80A6500DDB1C5 /* CCPUAlignAffector.h */; };
+ B665E2021AA80A6500DDB1C5 /* CCPUAlignAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D41AA80A6500DDB1C5 /* CCPUAlignAffectorTranslator.cpp */; };
+ B665E2031AA80A6500DDB1C5 /* CCPUAlignAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D41AA80A6500DDB1C5 /* CCPUAlignAffectorTranslator.cpp */; };
+ B665E2041AA80A6500DDB1C5 /* CCPUAlignAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D51AA80A6500DDB1C5 /* CCPUAlignAffectorTranslator.h */; };
+ B665E2051AA80A6500DDB1C5 /* CCPUAlignAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D51AA80A6500DDB1C5 /* CCPUAlignAffectorTranslator.h */; };
+ B665E2061AA80A6500DDB1C5 /* CCPUBaseCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D61AA80A6500DDB1C5 /* CCPUBaseCollider.cpp */; };
+ B665E2071AA80A6500DDB1C5 /* CCPUBaseCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D61AA80A6500DDB1C5 /* CCPUBaseCollider.cpp */; };
+ B665E2081AA80A6500DDB1C5 /* CCPUBaseCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D71AA80A6500DDB1C5 /* CCPUBaseCollider.h */; };
+ B665E2091AA80A6500DDB1C5 /* CCPUBaseCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D71AA80A6500DDB1C5 /* CCPUBaseCollider.h */; };
+ B665E20A1AA80A6500DDB1C5 /* CCPUBaseColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D81AA80A6500DDB1C5 /* CCPUBaseColliderTranslator.cpp */; };
+ B665E20B1AA80A6500DDB1C5 /* CCPUBaseColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0D81AA80A6500DDB1C5 /* CCPUBaseColliderTranslator.cpp */; };
+ B665E20C1AA80A6500DDB1C5 /* CCPUBaseColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D91AA80A6500DDB1C5 /* CCPUBaseColliderTranslator.h */; };
+ B665E20D1AA80A6500DDB1C5 /* CCPUBaseColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0D91AA80A6500DDB1C5 /* CCPUBaseColliderTranslator.h */; };
+ B665E20E1AA80A6500DDB1C5 /* CCPUBaseForceAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0DA1AA80A6500DDB1C5 /* CCPUBaseForceAffector.cpp */; };
+ B665E20F1AA80A6500DDB1C5 /* CCPUBaseForceAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0DA1AA80A6500DDB1C5 /* CCPUBaseForceAffector.cpp */; };
+ B665E2101AA80A6500DDB1C5 /* CCPUBaseForceAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0DB1AA80A6500DDB1C5 /* CCPUBaseForceAffector.h */; };
+ B665E2111AA80A6500DDB1C5 /* CCPUBaseForceAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0DB1AA80A6500DDB1C5 /* CCPUBaseForceAffector.h */; };
+ B665E2121AA80A6500DDB1C5 /* CCPUBaseForceAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0DC1AA80A6500DDB1C5 /* CCPUBaseForceAffectorTranslator.cpp */; };
+ B665E2131AA80A6500DDB1C5 /* CCPUBaseForceAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0DC1AA80A6500DDB1C5 /* CCPUBaseForceAffectorTranslator.cpp */; };
+ B665E2141AA80A6500DDB1C5 /* CCPUBaseForceAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0DD1AA80A6500DDB1C5 /* CCPUBaseForceAffectorTranslator.h */; };
+ B665E2151AA80A6500DDB1C5 /* CCPUBaseForceAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0DD1AA80A6500DDB1C5 /* CCPUBaseForceAffectorTranslator.h */; };
+ B665E2161AA80A6500DDB1C5 /* CCPUBeamRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0DE1AA80A6500DDB1C5 /* CCPUBeamRender.cpp */; };
+ B665E2171AA80A6500DDB1C5 /* CCPUBeamRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0DE1AA80A6500DDB1C5 /* CCPUBeamRender.cpp */; };
+ B665E2181AA80A6500DDB1C5 /* CCPUBeamRender.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0DF1AA80A6500DDB1C5 /* CCPUBeamRender.h */; };
+ B665E2191AA80A6500DDB1C5 /* CCPUBeamRender.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0DF1AA80A6500DDB1C5 /* CCPUBeamRender.h */; };
+ B665E21A1AA80A6500DDB1C5 /* CCPUBehaviour.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E01AA80A6500DDB1C5 /* CCPUBehaviour.cpp */; };
+ B665E21B1AA80A6500DDB1C5 /* CCPUBehaviour.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E01AA80A6500DDB1C5 /* CCPUBehaviour.cpp */; };
+ B665E21C1AA80A6500DDB1C5 /* CCPUBehaviour.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E11AA80A6500DDB1C5 /* CCPUBehaviour.h */; };
+ B665E21D1AA80A6500DDB1C5 /* CCPUBehaviour.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E11AA80A6500DDB1C5 /* CCPUBehaviour.h */; };
+ B665E21E1AA80A6500DDB1C5 /* CCPUBehaviourManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E21AA80A6500DDB1C5 /* CCPUBehaviourManager.cpp */; };
+ B665E21F1AA80A6500DDB1C5 /* CCPUBehaviourManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E21AA80A6500DDB1C5 /* CCPUBehaviourManager.cpp */; };
+ B665E2201AA80A6500DDB1C5 /* CCPUBehaviourManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E31AA80A6500DDB1C5 /* CCPUBehaviourManager.h */; };
+ B665E2211AA80A6500DDB1C5 /* CCPUBehaviourManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E31AA80A6500DDB1C5 /* CCPUBehaviourManager.h */; };
+ B665E2221AA80A6500DDB1C5 /* CCPUBehaviourTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E41AA80A6500DDB1C5 /* CCPUBehaviourTranslator.cpp */; };
+ B665E2231AA80A6500DDB1C5 /* CCPUBehaviourTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E41AA80A6500DDB1C5 /* CCPUBehaviourTranslator.cpp */; };
+ B665E2241AA80A6500DDB1C5 /* CCPUBehaviourTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E51AA80A6500DDB1C5 /* CCPUBehaviourTranslator.h */; };
+ B665E2251AA80A6500DDB1C5 /* CCPUBehaviourTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E51AA80A6500DDB1C5 /* CCPUBehaviourTranslator.h */; };
+ B665E2261AA80A6500DDB1C5 /* CCPUBillboardChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E61AA80A6500DDB1C5 /* CCPUBillboardChain.cpp */; };
+ B665E2271AA80A6500DDB1C5 /* CCPUBillboardChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E61AA80A6500DDB1C5 /* CCPUBillboardChain.cpp */; };
+ B665E2281AA80A6500DDB1C5 /* CCPUBillboardChain.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E71AA80A6500DDB1C5 /* CCPUBillboardChain.h */; };
+ B665E2291AA80A6500DDB1C5 /* CCPUBillboardChain.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E71AA80A6500DDB1C5 /* CCPUBillboardChain.h */; };
+ B665E22A1AA80A6500DDB1C5 /* CCPUBoxCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E81AA80A6500DDB1C5 /* CCPUBoxCollider.cpp */; };
+ B665E22B1AA80A6500DDB1C5 /* CCPUBoxCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0E81AA80A6500DDB1C5 /* CCPUBoxCollider.cpp */; };
+ B665E22C1AA80A6500DDB1C5 /* CCPUBoxCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E91AA80A6500DDB1C5 /* CCPUBoxCollider.h */; };
+ B665E22D1AA80A6500DDB1C5 /* CCPUBoxCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0E91AA80A6500DDB1C5 /* CCPUBoxCollider.h */; };
+ B665E22E1AA80A6500DDB1C5 /* CCPUBoxColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0EA1AA80A6500DDB1C5 /* CCPUBoxColliderTranslator.cpp */; };
+ B665E22F1AA80A6500DDB1C5 /* CCPUBoxColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0EA1AA80A6500DDB1C5 /* CCPUBoxColliderTranslator.cpp */; };
+ B665E2301AA80A6500DDB1C5 /* CCPUBoxColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0EB1AA80A6500DDB1C5 /* CCPUBoxColliderTranslator.h */; };
+ B665E2311AA80A6500DDB1C5 /* CCPUBoxColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0EB1AA80A6500DDB1C5 /* CCPUBoxColliderTranslator.h */; };
+ B665E2321AA80A6500DDB1C5 /* CCPUBoxEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0EC1AA80A6500DDB1C5 /* CCPUBoxEmitter.cpp */; };
+ B665E2331AA80A6500DDB1C5 /* CCPUBoxEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0EC1AA80A6500DDB1C5 /* CCPUBoxEmitter.cpp */; };
+ B665E2341AA80A6500DDB1C5 /* CCPUBoxEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0ED1AA80A6500DDB1C5 /* CCPUBoxEmitter.h */; };
+ B665E2351AA80A6500DDB1C5 /* CCPUBoxEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0ED1AA80A6500DDB1C5 /* CCPUBoxEmitter.h */; };
+ B665E2361AA80A6500DDB1C5 /* CCPUBoxEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0EE1AA80A6500DDB1C5 /* CCPUBoxEmitterTranslator.cpp */; };
+ B665E2371AA80A6500DDB1C5 /* CCPUBoxEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0EE1AA80A6500DDB1C5 /* CCPUBoxEmitterTranslator.cpp */; };
+ B665E2381AA80A6500DDB1C5 /* CCPUBoxEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0EF1AA80A6500DDB1C5 /* CCPUBoxEmitterTranslator.h */; };
+ B665E2391AA80A6500DDB1C5 /* CCPUBoxEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0EF1AA80A6500DDB1C5 /* CCPUBoxEmitterTranslator.h */; };
+ B665E23A1AA80A6500DDB1C5 /* CCPUCircleEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F01AA80A6500DDB1C5 /* CCPUCircleEmitter.cpp */; };
+ B665E23B1AA80A6500DDB1C5 /* CCPUCircleEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F01AA80A6500DDB1C5 /* CCPUCircleEmitter.cpp */; };
+ B665E23C1AA80A6500DDB1C5 /* CCPUCircleEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F11AA80A6500DDB1C5 /* CCPUCircleEmitter.h */; };
+ B665E23D1AA80A6500DDB1C5 /* CCPUCircleEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F11AA80A6500DDB1C5 /* CCPUCircleEmitter.h */; };
+ B665E23E1AA80A6500DDB1C5 /* CCPUCircleEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F21AA80A6500DDB1C5 /* CCPUCircleEmitterTranslator.cpp */; };
+ B665E23F1AA80A6500DDB1C5 /* CCPUCircleEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F21AA80A6500DDB1C5 /* CCPUCircleEmitterTranslator.cpp */; };
+ B665E2401AA80A6500DDB1C5 /* CCPUCircleEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F31AA80A6500DDB1C5 /* CCPUCircleEmitterTranslator.h */; };
+ B665E2411AA80A6500DDB1C5 /* CCPUCircleEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F31AA80A6500DDB1C5 /* CCPUCircleEmitterTranslator.h */; };
+ B665E2421AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F41AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffector.cpp */; };
+ B665E2431AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F41AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffector.cpp */; };
+ B665E2441AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F51AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffector.h */; };
+ B665E2451AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F51AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffector.h */; };
+ B665E2461AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F61AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffectorTranslator.cpp */; };
+ B665E2471AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F61AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffectorTranslator.cpp */; };
+ B665E2481AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F71AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffectorTranslator.h */; };
+ B665E2491AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F71AA80A6500DDB1C5 /* CCPUCollisionAvoidanceAffectorTranslator.h */; };
+ B665E24A1AA80A6500DDB1C5 /* CCPUColorAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F81AA80A6500DDB1C5 /* CCPUColorAffector.cpp */; };
+ B665E24B1AA80A6500DDB1C5 /* CCPUColorAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0F81AA80A6500DDB1C5 /* CCPUColorAffector.cpp */; };
+ B665E24C1AA80A6500DDB1C5 /* CCPUColorAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F91AA80A6500DDB1C5 /* CCPUColorAffector.h */; };
+ B665E24D1AA80A6500DDB1C5 /* CCPUColorAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0F91AA80A6500DDB1C5 /* CCPUColorAffector.h */; };
+ B665E24E1AA80A6500DDB1C5 /* CCPUColorAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0FA1AA80A6500DDB1C5 /* CCPUColorAffectorTranslator.cpp */; };
+ B665E24F1AA80A6500DDB1C5 /* CCPUColorAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0FA1AA80A6500DDB1C5 /* CCPUColorAffectorTranslator.cpp */; };
+ B665E2501AA80A6500DDB1C5 /* CCPUColorAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0FB1AA80A6500DDB1C5 /* CCPUColorAffectorTranslator.h */; };
+ B665E2511AA80A6500DDB1C5 /* CCPUColorAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0FB1AA80A6500DDB1C5 /* CCPUColorAffectorTranslator.h */; };
+ B665E2521AA80A6500DDB1C5 /* CCPUDoAffectorEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0FC1AA80A6500DDB1C5 /* CCPUDoAffectorEventHandler.cpp */; };
+ B665E2531AA80A6500DDB1C5 /* CCPUDoAffectorEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0FC1AA80A6500DDB1C5 /* CCPUDoAffectorEventHandler.cpp */; };
+ B665E2541AA80A6500DDB1C5 /* CCPUDoAffectorEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0FD1AA80A6500DDB1C5 /* CCPUDoAffectorEventHandler.h */; };
+ B665E2551AA80A6500DDB1C5 /* CCPUDoAffectorEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0FD1AA80A6500DDB1C5 /* CCPUDoAffectorEventHandler.h */; };
+ B665E2561AA80A6500DDB1C5 /* CCPUDoAffectorEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0FE1AA80A6500DDB1C5 /* CCPUDoAffectorEventHandlerTranslator.cpp */; };
+ B665E2571AA80A6500DDB1C5 /* CCPUDoAffectorEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E0FE1AA80A6500DDB1C5 /* CCPUDoAffectorEventHandlerTranslator.cpp */; };
+ B665E2581AA80A6500DDB1C5 /* CCPUDoAffectorEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0FF1AA80A6500DDB1C5 /* CCPUDoAffectorEventHandlerTranslator.h */; };
+ B665E2591AA80A6500DDB1C5 /* CCPUDoAffectorEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E0FF1AA80A6500DDB1C5 /* CCPUDoAffectorEventHandlerTranslator.h */; };
+ B665E25A1AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1001AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandler.cpp */; };
+ B665E25B1AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1001AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandler.cpp */; };
+ B665E25C1AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1011AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandler.h */; };
+ B665E25D1AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1011AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandler.h */; };
+ B665E25E1AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1021AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandlerTranslator.cpp */; };
+ B665E25F1AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1021AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandlerTranslator.cpp */; };
+ B665E2601AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1031AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandlerTranslator.h */; };
+ B665E2611AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1031AA80A6500DDB1C5 /* CCPUDoEnableComponentEventHandlerTranslator.h */; };
+ B665E2621AA80A6500DDB1C5 /* CCPUDoExpireEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1041AA80A6500DDB1C5 /* CCPUDoExpireEventHandler.cpp */; };
+ B665E2631AA80A6500DDB1C5 /* CCPUDoExpireEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1041AA80A6500DDB1C5 /* CCPUDoExpireEventHandler.cpp */; };
+ B665E2641AA80A6500DDB1C5 /* CCPUDoExpireEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1051AA80A6500DDB1C5 /* CCPUDoExpireEventHandler.h */; };
+ B665E2651AA80A6500DDB1C5 /* CCPUDoExpireEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1051AA80A6500DDB1C5 /* CCPUDoExpireEventHandler.h */; };
+ B665E2661AA80A6500DDB1C5 /* CCPUDoExpireEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1061AA80A6500DDB1C5 /* CCPUDoExpireEventHandlerTranslator.cpp */; };
+ B665E2671AA80A6500DDB1C5 /* CCPUDoExpireEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1061AA80A6500DDB1C5 /* CCPUDoExpireEventHandlerTranslator.cpp */; };
+ B665E2681AA80A6500DDB1C5 /* CCPUDoExpireEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1071AA80A6500DDB1C5 /* CCPUDoExpireEventHandlerTranslator.h */; };
+ B665E2691AA80A6500DDB1C5 /* CCPUDoExpireEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1071AA80A6500DDB1C5 /* CCPUDoExpireEventHandlerTranslator.h */; };
+ B665E26A1AA80A6500DDB1C5 /* CCPUDoFreezeEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1081AA80A6500DDB1C5 /* CCPUDoFreezeEventHandler.cpp */; };
+ B665E26B1AA80A6500DDB1C5 /* CCPUDoFreezeEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1081AA80A6500DDB1C5 /* CCPUDoFreezeEventHandler.cpp */; };
+ B665E26C1AA80A6500DDB1C5 /* CCPUDoFreezeEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1091AA80A6500DDB1C5 /* CCPUDoFreezeEventHandler.h */; };
+ B665E26D1AA80A6500DDB1C5 /* CCPUDoFreezeEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1091AA80A6500DDB1C5 /* CCPUDoFreezeEventHandler.h */; };
+ B665E26E1AA80A6500DDB1C5 /* CCPUDoFreezeEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E10A1AA80A6500DDB1C5 /* CCPUDoFreezeEventHandlerTranslator.cpp */; };
+ B665E26F1AA80A6500DDB1C5 /* CCPUDoFreezeEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E10A1AA80A6500DDB1C5 /* CCPUDoFreezeEventHandlerTranslator.cpp */; };
+ B665E2701AA80A6500DDB1C5 /* CCPUDoFreezeEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E10B1AA80A6500DDB1C5 /* CCPUDoFreezeEventHandlerTranslator.h */; };
+ B665E2711AA80A6500DDB1C5 /* CCPUDoFreezeEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E10B1AA80A6500DDB1C5 /* CCPUDoFreezeEventHandlerTranslator.h */; };
+ B665E2721AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E10C1AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandler.cpp */; };
+ B665E2731AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E10C1AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandler.cpp */; };
+ B665E2741AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E10D1AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandler.h */; };
+ B665E2751AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E10D1AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandler.h */; };
+ B665E2761AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E10E1AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandlerTranslator.cpp */; };
+ B665E2771AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E10E1AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandlerTranslator.cpp */; };
+ B665E2781AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E10F1AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandlerTranslator.h */; };
+ B665E2791AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E10F1AA80A6500DDB1C5 /* CCPUDoPlacementParticleEventHandlerTranslator.h */; };
+ B665E27A1AA80A6500DDB1C5 /* CCPUDoScaleEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1101AA80A6500DDB1C5 /* CCPUDoScaleEventHandler.cpp */; };
+ B665E27B1AA80A6500DDB1C5 /* CCPUDoScaleEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1101AA80A6500DDB1C5 /* CCPUDoScaleEventHandler.cpp */; };
+ B665E27C1AA80A6500DDB1C5 /* CCPUDoScaleEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1111AA80A6500DDB1C5 /* CCPUDoScaleEventHandler.h */; };
+ B665E27D1AA80A6500DDB1C5 /* CCPUDoScaleEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1111AA80A6500DDB1C5 /* CCPUDoScaleEventHandler.h */; };
+ B665E27E1AA80A6500DDB1C5 /* CCPUDoScaleEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1121AA80A6500DDB1C5 /* CCPUDoScaleEventHandlerTranslator.cpp */; };
+ B665E27F1AA80A6500DDB1C5 /* CCPUDoScaleEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1121AA80A6500DDB1C5 /* CCPUDoScaleEventHandlerTranslator.cpp */; };
+ B665E2801AA80A6500DDB1C5 /* CCPUDoScaleEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1131AA80A6500DDB1C5 /* CCPUDoScaleEventHandlerTranslator.h */; };
+ B665E2811AA80A6500DDB1C5 /* CCPUDoScaleEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1131AA80A6500DDB1C5 /* CCPUDoScaleEventHandlerTranslator.h */; };
+ B665E2821AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1141AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandler.cpp */; };
+ B665E2831AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1141AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandler.cpp */; };
+ B665E2841AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1151AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandler.h */; };
+ B665E2851AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1151AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandler.h */; };
+ B665E2861AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1161AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandlerTranslator.cpp */; };
+ B665E2871AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1161AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandlerTranslator.cpp */; };
+ B665E2881AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1171AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandlerTranslator.h */; };
+ B665E2891AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1171AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandlerTranslator.h */; };
+ B665E28A1AA80A6500DDB1C5 /* CCPUDynamicAttribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1181AA80A6500DDB1C5 /* CCPUDynamicAttribute.cpp */; };
+ B665E28B1AA80A6500DDB1C5 /* CCPUDynamicAttribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1181AA80A6500DDB1C5 /* CCPUDynamicAttribute.cpp */; };
+ B665E28C1AA80A6500DDB1C5 /* CCPUDynamicAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1191AA80A6500DDB1C5 /* CCPUDynamicAttribute.h */; };
+ B665E28D1AA80A6500DDB1C5 /* CCPUDynamicAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1191AA80A6500DDB1C5 /* CCPUDynamicAttribute.h */; };
+ B665E28E1AA80A6500DDB1C5 /* CCPUDynamicAttributeTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E11A1AA80A6500DDB1C5 /* CCPUDynamicAttributeTranslator.cpp */; };
+ B665E28F1AA80A6500DDB1C5 /* CCPUDynamicAttributeTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E11A1AA80A6500DDB1C5 /* CCPUDynamicAttributeTranslator.cpp */; };
+ B665E2901AA80A6500DDB1C5 /* CCPUDynamicAttributeTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E11B1AA80A6500DDB1C5 /* CCPUDynamicAttributeTranslator.h */; };
+ B665E2911AA80A6500DDB1C5 /* CCPUDynamicAttributeTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E11B1AA80A6500DDB1C5 /* CCPUDynamicAttributeTranslator.h */; };
+ B665E2921AA80A6500DDB1C5 /* CCPUEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E11C1AA80A6500DDB1C5 /* CCPUEmitter.cpp */; };
+ B665E2931AA80A6500DDB1C5 /* CCPUEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E11C1AA80A6500DDB1C5 /* CCPUEmitter.cpp */; };
+ B665E2941AA80A6500DDB1C5 /* CCPUEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E11D1AA80A6500DDB1C5 /* CCPUEmitter.h */; };
+ B665E2951AA80A6500DDB1C5 /* CCPUEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E11D1AA80A6500DDB1C5 /* CCPUEmitter.h */; };
+ B665E2961AA80A6500DDB1C5 /* CCPUEmitterManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E11E1AA80A6500DDB1C5 /* CCPUEmitterManager.cpp */; };
+ B665E2971AA80A6500DDB1C5 /* CCPUEmitterManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E11E1AA80A6500DDB1C5 /* CCPUEmitterManager.cpp */; };
+ B665E2981AA80A6500DDB1C5 /* CCPUEmitterManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E11F1AA80A6500DDB1C5 /* CCPUEmitterManager.h */; };
+ B665E2991AA80A6500DDB1C5 /* CCPUEmitterManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E11F1AA80A6500DDB1C5 /* CCPUEmitterManager.h */; };
+ B665E29A1AA80A6500DDB1C5 /* CCPUEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1201AA80A6500DDB1C5 /* CCPUEmitterTranslator.cpp */; };
+ B665E29B1AA80A6500DDB1C5 /* CCPUEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1201AA80A6500DDB1C5 /* CCPUEmitterTranslator.cpp */; };
+ B665E29C1AA80A6500DDB1C5 /* CCPUEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1211AA80A6500DDB1C5 /* CCPUEmitterTranslator.h */; };
+ B665E29D1AA80A6500DDB1C5 /* CCPUEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1211AA80A6500DDB1C5 /* CCPUEmitterTranslator.h */; };
+ B665E29E1AA80A6500DDB1C5 /* CCPUEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1221AA80A6500DDB1C5 /* CCPUEventHandler.cpp */; };
+ B665E29F1AA80A6500DDB1C5 /* CCPUEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1221AA80A6500DDB1C5 /* CCPUEventHandler.cpp */; };
+ B665E2A01AA80A6500DDB1C5 /* CCPUEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1231AA80A6500DDB1C5 /* CCPUEventHandler.h */; };
+ B665E2A11AA80A6500DDB1C5 /* CCPUEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1231AA80A6500DDB1C5 /* CCPUEventHandler.h */; };
+ B665E2A21AA80A6500DDB1C5 /* CCPUEventHandlerManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1241AA80A6500DDB1C5 /* CCPUEventHandlerManager.cpp */; };
+ B665E2A31AA80A6500DDB1C5 /* CCPUEventHandlerManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1241AA80A6500DDB1C5 /* CCPUEventHandlerManager.cpp */; };
+ B665E2A41AA80A6500DDB1C5 /* CCPUEventHandlerManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1251AA80A6500DDB1C5 /* CCPUEventHandlerManager.h */; };
+ B665E2A51AA80A6500DDB1C5 /* CCPUEventHandlerManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1251AA80A6500DDB1C5 /* CCPUEventHandlerManager.h */; };
+ B665E2A61AA80A6500DDB1C5 /* CCPUEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1261AA80A6500DDB1C5 /* CCPUEventHandlerTranslator.cpp */; };
+ B665E2A71AA80A6500DDB1C5 /* CCPUEventHandlerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1261AA80A6500DDB1C5 /* CCPUEventHandlerTranslator.cpp */; };
+ B665E2A81AA80A6500DDB1C5 /* CCPUEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1271AA80A6500DDB1C5 /* CCPUEventHandlerTranslator.h */; };
+ B665E2A91AA80A6500DDB1C5 /* CCPUEventHandlerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1271AA80A6500DDB1C5 /* CCPUEventHandlerTranslator.h */; };
+ B665E2AA1AA80A6500DDB1C5 /* CCPUFlockCenteringAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1281AA80A6500DDB1C5 /* CCPUFlockCenteringAffector.cpp */; };
+ B665E2AB1AA80A6500DDB1C5 /* CCPUFlockCenteringAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1281AA80A6500DDB1C5 /* CCPUFlockCenteringAffector.cpp */; };
+ B665E2AC1AA80A6500DDB1C5 /* CCPUFlockCenteringAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1291AA80A6500DDB1C5 /* CCPUFlockCenteringAffector.h */; };
+ B665E2AD1AA80A6500DDB1C5 /* CCPUFlockCenteringAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1291AA80A6500DDB1C5 /* CCPUFlockCenteringAffector.h */; };
+ B665E2AE1AA80A6500DDB1C5 /* CCPUFlockCenteringAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E12A1AA80A6500DDB1C5 /* CCPUFlockCenteringAffectorTranslator.cpp */; };
+ B665E2AF1AA80A6500DDB1C5 /* CCPUFlockCenteringAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E12A1AA80A6500DDB1C5 /* CCPUFlockCenteringAffectorTranslator.cpp */; };
+ B665E2B01AA80A6500DDB1C5 /* CCPUFlockCenteringAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E12B1AA80A6500DDB1C5 /* CCPUFlockCenteringAffectorTranslator.h */; };
+ B665E2B11AA80A6500DDB1C5 /* CCPUFlockCenteringAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E12B1AA80A6500DDB1C5 /* CCPUFlockCenteringAffectorTranslator.h */; };
+ B665E2B21AA80A6500DDB1C5 /* CCPUForceField.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E12C1AA80A6500DDB1C5 /* CCPUForceField.cpp */; };
+ B665E2B31AA80A6500DDB1C5 /* CCPUForceField.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E12C1AA80A6500DDB1C5 /* CCPUForceField.cpp */; };
+ B665E2B41AA80A6500DDB1C5 /* CCPUForceField.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E12D1AA80A6500DDB1C5 /* CCPUForceField.h */; };
+ B665E2B51AA80A6500DDB1C5 /* CCPUForceField.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E12D1AA80A6500DDB1C5 /* CCPUForceField.h */; };
+ B665E2B61AA80A6500DDB1C5 /* CCPUForceFieldAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E12E1AA80A6500DDB1C5 /* CCPUForceFieldAffector.cpp */; };
+ B665E2B71AA80A6500DDB1C5 /* CCPUForceFieldAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E12E1AA80A6500DDB1C5 /* CCPUForceFieldAffector.cpp */; };
+ B665E2B81AA80A6500DDB1C5 /* CCPUForceFieldAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E12F1AA80A6500DDB1C5 /* CCPUForceFieldAffector.h */; };
+ B665E2B91AA80A6500DDB1C5 /* CCPUForceFieldAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E12F1AA80A6500DDB1C5 /* CCPUForceFieldAffector.h */; };
+ B665E2BA1AA80A6500DDB1C5 /* CCPUForceFieldAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1301AA80A6500DDB1C5 /* CCPUForceFieldAffectorTranslator.cpp */; };
+ B665E2BB1AA80A6500DDB1C5 /* CCPUForceFieldAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1301AA80A6500DDB1C5 /* CCPUForceFieldAffectorTranslator.cpp */; };
+ B665E2BC1AA80A6500DDB1C5 /* CCPUForceFieldAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1311AA80A6500DDB1C5 /* CCPUForceFieldAffectorTranslator.h */; };
+ B665E2BD1AA80A6500DDB1C5 /* CCPUForceFieldAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1311AA80A6500DDB1C5 /* CCPUForceFieldAffectorTranslator.h */; };
+ B665E2BE1AA80A6500DDB1C5 /* CCPUGeometryRotator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1321AA80A6500DDB1C5 /* CCPUGeometryRotator.cpp */; };
+ B665E2BF1AA80A6500DDB1C5 /* CCPUGeometryRotator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1321AA80A6500DDB1C5 /* CCPUGeometryRotator.cpp */; };
+ B665E2C01AA80A6500DDB1C5 /* CCPUGeometryRotator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1331AA80A6500DDB1C5 /* CCPUGeometryRotator.h */; };
+ B665E2C11AA80A6500DDB1C5 /* CCPUGeometryRotator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1331AA80A6500DDB1C5 /* CCPUGeometryRotator.h */; };
+ B665E2C21AA80A6500DDB1C5 /* CCPUGeometryRotatorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1341AA80A6500DDB1C5 /* CCPUGeometryRotatorTranslator.cpp */; };
+ B665E2C31AA80A6500DDB1C5 /* CCPUGeometryRotatorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1341AA80A6500DDB1C5 /* CCPUGeometryRotatorTranslator.cpp */; };
+ B665E2C41AA80A6500DDB1C5 /* CCPUGeometryRotatorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1351AA80A6500DDB1C5 /* CCPUGeometryRotatorTranslator.h */; };
+ B665E2C51AA80A6500DDB1C5 /* CCPUGeometryRotatorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1351AA80A6500DDB1C5 /* CCPUGeometryRotatorTranslator.h */; };
+ B665E2C61AA80A6500DDB1C5 /* CCPUGravityAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1361AA80A6500DDB1C5 /* CCPUGravityAffector.cpp */; };
+ B665E2C71AA80A6500DDB1C5 /* CCPUGravityAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1361AA80A6500DDB1C5 /* CCPUGravityAffector.cpp */; };
+ B665E2C81AA80A6500DDB1C5 /* CCPUGravityAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1371AA80A6500DDB1C5 /* CCPUGravityAffector.h */; };
+ B665E2C91AA80A6500DDB1C5 /* CCPUGravityAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1371AA80A6500DDB1C5 /* CCPUGravityAffector.h */; };
+ B665E2CA1AA80A6500DDB1C5 /* CCPUGravityAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1381AA80A6500DDB1C5 /* CCPUGravityAffectorTranslator.cpp */; };
+ B665E2CB1AA80A6500DDB1C5 /* CCPUGravityAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1381AA80A6500DDB1C5 /* CCPUGravityAffectorTranslator.cpp */; };
+ B665E2CC1AA80A6500DDB1C5 /* CCPUGravityAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1391AA80A6500DDB1C5 /* CCPUGravityAffectorTranslator.h */; };
+ B665E2CD1AA80A6500DDB1C5 /* CCPUGravityAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1391AA80A6500DDB1C5 /* CCPUGravityAffectorTranslator.h */; };
+ B665E2CE1AA80A6500DDB1C5 /* CCPUInterParticleCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E13A1AA80A6500DDB1C5 /* CCPUInterParticleCollider.cpp */; };
+ B665E2CF1AA80A6500DDB1C5 /* CCPUInterParticleCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E13A1AA80A6500DDB1C5 /* CCPUInterParticleCollider.cpp */; };
+ B665E2D01AA80A6500DDB1C5 /* CCPUInterParticleCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E13B1AA80A6500DDB1C5 /* CCPUInterParticleCollider.h */; };
+ B665E2D11AA80A6500DDB1C5 /* CCPUInterParticleCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E13B1AA80A6500DDB1C5 /* CCPUInterParticleCollider.h */; };
+ B665E2D21AA80A6500DDB1C5 /* CCPUInterParticleColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E13C1AA80A6500DDB1C5 /* CCPUInterParticleColliderTranslator.cpp */; };
+ B665E2D31AA80A6500DDB1C5 /* CCPUInterParticleColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E13C1AA80A6500DDB1C5 /* CCPUInterParticleColliderTranslator.cpp */; };
+ B665E2D41AA80A6500DDB1C5 /* CCPUInterParticleColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E13D1AA80A6500DDB1C5 /* CCPUInterParticleColliderTranslator.h */; };
+ B665E2D51AA80A6500DDB1C5 /* CCPUInterParticleColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E13D1AA80A6500DDB1C5 /* CCPUInterParticleColliderTranslator.h */; };
+ B665E2D61AA80A6500DDB1C5 /* CCPUJetAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E13E1AA80A6500DDB1C5 /* CCPUJetAffector.cpp */; };
+ B665E2D71AA80A6500DDB1C5 /* CCPUJetAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E13E1AA80A6500DDB1C5 /* CCPUJetAffector.cpp */; };
+ B665E2D81AA80A6500DDB1C5 /* CCPUJetAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E13F1AA80A6500DDB1C5 /* CCPUJetAffector.h */; };
+ B665E2D91AA80A6500DDB1C5 /* CCPUJetAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E13F1AA80A6500DDB1C5 /* CCPUJetAffector.h */; };
+ B665E2DA1AA80A6500DDB1C5 /* CCPUJetAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1401AA80A6500DDB1C5 /* CCPUJetAffectorTranslator.cpp */; };
+ B665E2DB1AA80A6500DDB1C5 /* CCPUJetAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1401AA80A6500DDB1C5 /* CCPUJetAffectorTranslator.cpp */; };
+ B665E2DC1AA80A6500DDB1C5 /* CCPUJetAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1411AA80A6500DDB1C5 /* CCPUJetAffectorTranslator.h */; };
+ B665E2DD1AA80A6500DDB1C5 /* CCPUJetAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1411AA80A6500DDB1C5 /* CCPUJetAffectorTranslator.h */; };
+ B665E2DE1AA80A6500DDB1C5 /* CCPULineAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1421AA80A6500DDB1C5 /* CCPULineAffector.cpp */; };
+ B665E2DF1AA80A6500DDB1C5 /* CCPULineAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1421AA80A6500DDB1C5 /* CCPULineAffector.cpp */; };
+ B665E2E01AA80A6500DDB1C5 /* CCPULineAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1431AA80A6500DDB1C5 /* CCPULineAffector.h */; };
+ B665E2E11AA80A6500DDB1C5 /* CCPULineAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1431AA80A6500DDB1C5 /* CCPULineAffector.h */; };
+ B665E2E21AA80A6500DDB1C5 /* CCPULineAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1441AA80A6500DDB1C5 /* CCPULineAffectorTranslator.cpp */; };
+ B665E2E31AA80A6500DDB1C5 /* CCPULineAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1441AA80A6500DDB1C5 /* CCPULineAffectorTranslator.cpp */; };
+ B665E2E41AA80A6500DDB1C5 /* CCPULineAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1451AA80A6500DDB1C5 /* CCPULineAffectorTranslator.h */; };
+ B665E2E51AA80A6500DDB1C5 /* CCPULineAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1451AA80A6500DDB1C5 /* CCPULineAffectorTranslator.h */; };
+ B665E2E61AA80A6500DDB1C5 /* CCPULinearForceAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1461AA80A6500DDB1C5 /* CCPULinearForceAffector.cpp */; };
+ B665E2E71AA80A6500DDB1C5 /* CCPULinearForceAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1461AA80A6500DDB1C5 /* CCPULinearForceAffector.cpp */; };
+ B665E2E81AA80A6500DDB1C5 /* CCPULinearForceAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1471AA80A6500DDB1C5 /* CCPULinearForceAffector.h */; };
+ B665E2E91AA80A6500DDB1C5 /* CCPULinearForceAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1471AA80A6500DDB1C5 /* CCPULinearForceAffector.h */; };
+ B665E2EA1AA80A6500DDB1C5 /* CCPULinearForceAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1481AA80A6500DDB1C5 /* CCPULinearForceAffectorTranslator.cpp */; };
+ B665E2EB1AA80A6500DDB1C5 /* CCPULinearForceAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1481AA80A6500DDB1C5 /* CCPULinearForceAffectorTranslator.cpp */; };
+ B665E2EC1AA80A6500DDB1C5 /* CCPULinearForceAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1491AA80A6500DDB1C5 /* CCPULinearForceAffectorTranslator.h */; };
+ B665E2ED1AA80A6500DDB1C5 /* CCPULinearForceAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1491AA80A6500DDB1C5 /* CCPULinearForceAffectorTranslator.h */; };
+ B665E2EE1AA80A6500DDB1C5 /* CCPULineEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E14A1AA80A6500DDB1C5 /* CCPULineEmitter.cpp */; };
+ B665E2EF1AA80A6500DDB1C5 /* CCPULineEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E14A1AA80A6500DDB1C5 /* CCPULineEmitter.cpp */; };
+ B665E2F01AA80A6500DDB1C5 /* CCPULineEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E14B1AA80A6500DDB1C5 /* CCPULineEmitter.h */; };
+ B665E2F11AA80A6500DDB1C5 /* CCPULineEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E14B1AA80A6500DDB1C5 /* CCPULineEmitter.h */; };
+ B665E2F21AA80A6500DDB1C5 /* CCPULineEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E14C1AA80A6500DDB1C5 /* CCPULineEmitterTranslator.cpp */; };
+ B665E2F31AA80A6500DDB1C5 /* CCPULineEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E14C1AA80A6500DDB1C5 /* CCPULineEmitterTranslator.cpp */; };
+ B665E2F41AA80A6500DDB1C5 /* CCPULineEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E14D1AA80A6500DDB1C5 /* CCPULineEmitterTranslator.h */; };
+ B665E2F51AA80A6500DDB1C5 /* CCPULineEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E14D1AA80A6500DDB1C5 /* CCPULineEmitterTranslator.h */; };
+ B665E2F61AA80A6500DDB1C5 /* CCPUListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E14E1AA80A6500DDB1C5 /* CCPUListener.cpp */; };
+ B665E2F71AA80A6500DDB1C5 /* CCPUListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E14E1AA80A6500DDB1C5 /* CCPUListener.cpp */; };
+ B665E2F81AA80A6500DDB1C5 /* CCPUListener.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E14F1AA80A6500DDB1C5 /* CCPUListener.h */; };
+ B665E2F91AA80A6500DDB1C5 /* CCPUListener.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E14F1AA80A6500DDB1C5 /* CCPUListener.h */; };
+ B665E2FA1AA80A6500DDB1C5 /* CCPUMaterialManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1501AA80A6500DDB1C5 /* CCPUMaterialManager.cpp */; };
+ B665E2FB1AA80A6500DDB1C5 /* CCPUMaterialManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1501AA80A6500DDB1C5 /* CCPUMaterialManager.cpp */; };
+ B665E2FC1AA80A6500DDB1C5 /* CCPUMaterialManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1511AA80A6500DDB1C5 /* CCPUMaterialManager.h */; };
+ B665E2FD1AA80A6500DDB1C5 /* CCPUMaterialManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1511AA80A6500DDB1C5 /* CCPUMaterialManager.h */; };
+ B665E2FE1AA80A6500DDB1C5 /* CCPUMaterialTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1521AA80A6500DDB1C5 /* CCPUMaterialTranslator.cpp */; };
+ B665E2FF1AA80A6500DDB1C5 /* CCPUMaterialTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1521AA80A6500DDB1C5 /* CCPUMaterialTranslator.cpp */; };
+ B665E3001AA80A6500DDB1C5 /* CCPUMaterialTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1531AA80A6500DDB1C5 /* CCPUMaterialTranslator.h */; };
+ B665E3011AA80A6500DDB1C5 /* CCPUMaterialTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1531AA80A6500DDB1C5 /* CCPUMaterialTranslator.h */; };
+ B665E3021AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1541AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitter.cpp */; };
+ B665E3031AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1541AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitter.cpp */; };
+ B665E3041AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1551AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitter.h */; };
+ B665E3051AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1551AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitter.h */; };
+ B665E3061AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1561AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitterTranslator.cpp */; };
+ B665E3071AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1561AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitterTranslator.cpp */; };
+ B665E3081AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1571AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitterTranslator.h */; };
+ B665E3091AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1571AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitterTranslator.h */; };
+ B665E30A1AA80A6500DDB1C5 /* CCPUNoise.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1581AA80A6500DDB1C5 /* CCPUNoise.cpp */; };
+ B665E30B1AA80A6500DDB1C5 /* CCPUNoise.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1581AA80A6500DDB1C5 /* CCPUNoise.cpp */; };
+ B665E30C1AA80A6500DDB1C5 /* CCPUNoise.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1591AA80A6500DDB1C5 /* CCPUNoise.h */; };
+ B665E30D1AA80A6500DDB1C5 /* CCPUNoise.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1591AA80A6500DDB1C5 /* CCPUNoise.h */; };
+ B665E30E1AA80A6500DDB1C5 /* CCPUObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E15A1AA80A6500DDB1C5 /* CCPUObserver.cpp */; };
+ B665E30F1AA80A6500DDB1C5 /* CCPUObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E15A1AA80A6500DDB1C5 /* CCPUObserver.cpp */; };
+ B665E3101AA80A6500DDB1C5 /* CCPUObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E15B1AA80A6500DDB1C5 /* CCPUObserver.h */; };
+ B665E3111AA80A6500DDB1C5 /* CCPUObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E15B1AA80A6500DDB1C5 /* CCPUObserver.h */; };
+ B665E3121AA80A6500DDB1C5 /* CCPUObserverManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E15C1AA80A6500DDB1C5 /* CCPUObserverManager.cpp */; };
+ B665E3131AA80A6500DDB1C5 /* CCPUObserverManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E15C1AA80A6500DDB1C5 /* CCPUObserverManager.cpp */; };
+ B665E3141AA80A6500DDB1C5 /* CCPUObserverManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E15D1AA80A6500DDB1C5 /* CCPUObserverManager.h */; };
+ B665E3151AA80A6500DDB1C5 /* CCPUObserverManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E15D1AA80A6500DDB1C5 /* CCPUObserverManager.h */; };
+ B665E3161AA80A6500DDB1C5 /* CCPUObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E15E1AA80A6500DDB1C5 /* CCPUObserverTranslator.cpp */; };
+ B665E3171AA80A6500DDB1C5 /* CCPUObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E15E1AA80A6500DDB1C5 /* CCPUObserverTranslator.cpp */; };
+ B665E3181AA80A6500DDB1C5 /* CCPUObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E15F1AA80A6500DDB1C5 /* CCPUObserverTranslator.h */; };
+ B665E3191AA80A6500DDB1C5 /* CCPUObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E15F1AA80A6500DDB1C5 /* CCPUObserverTranslator.h */; };
+ B665E31A1AA80A6500DDB1C5 /* CCPUOnClearObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1601AA80A6500DDB1C5 /* CCPUOnClearObserver.cpp */; };
+ B665E31B1AA80A6500DDB1C5 /* CCPUOnClearObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1601AA80A6500DDB1C5 /* CCPUOnClearObserver.cpp */; };
+ B665E31C1AA80A6500DDB1C5 /* CCPUOnClearObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1611AA80A6500DDB1C5 /* CCPUOnClearObserver.h */; };
+ B665E31D1AA80A6500DDB1C5 /* CCPUOnClearObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1611AA80A6500DDB1C5 /* CCPUOnClearObserver.h */; };
+ B665E31E1AA80A6500DDB1C5 /* CCPUOnClearObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1621AA80A6500DDB1C5 /* CCPUOnClearObserverTranslator.cpp */; };
+ B665E31F1AA80A6500DDB1C5 /* CCPUOnClearObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1621AA80A6500DDB1C5 /* CCPUOnClearObserverTranslator.cpp */; };
+ B665E3201AA80A6500DDB1C5 /* CCPUOnClearObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1631AA80A6500DDB1C5 /* CCPUOnClearObserverTranslator.h */; };
+ B665E3211AA80A6500DDB1C5 /* CCPUOnClearObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1631AA80A6500DDB1C5 /* CCPUOnClearObserverTranslator.h */; };
+ B665E3221AA80A6500DDB1C5 /* CCPUOnCollisionObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1641AA80A6500DDB1C5 /* CCPUOnCollisionObserver.cpp */; };
+ B665E3231AA80A6500DDB1C5 /* CCPUOnCollisionObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1641AA80A6500DDB1C5 /* CCPUOnCollisionObserver.cpp */; };
+ B665E3241AA80A6500DDB1C5 /* CCPUOnCollisionObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1651AA80A6500DDB1C5 /* CCPUOnCollisionObserver.h */; };
+ B665E3251AA80A6500DDB1C5 /* CCPUOnCollisionObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1651AA80A6500DDB1C5 /* CCPUOnCollisionObserver.h */; };
+ B665E3261AA80A6500DDB1C5 /* CCPUOnCollisionObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1661AA80A6500DDB1C5 /* CCPUOnCollisionObserverTranslator.cpp */; };
+ B665E3271AA80A6500DDB1C5 /* CCPUOnCollisionObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1661AA80A6500DDB1C5 /* CCPUOnCollisionObserverTranslator.cpp */; };
+ B665E3281AA80A6500DDB1C5 /* CCPUOnCollisionObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1671AA80A6500DDB1C5 /* CCPUOnCollisionObserverTranslator.h */; };
+ B665E3291AA80A6500DDB1C5 /* CCPUOnCollisionObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1671AA80A6500DDB1C5 /* CCPUOnCollisionObserverTranslator.h */; };
+ B665E32A1AA80A6500DDB1C5 /* CCPUOnCountObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1681AA80A6500DDB1C5 /* CCPUOnCountObserver.cpp */; };
+ B665E32B1AA80A6500DDB1C5 /* CCPUOnCountObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1681AA80A6500DDB1C5 /* CCPUOnCountObserver.cpp */; };
+ B665E32C1AA80A6500DDB1C5 /* CCPUOnCountObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1691AA80A6500DDB1C5 /* CCPUOnCountObserver.h */; };
+ B665E32D1AA80A6500DDB1C5 /* CCPUOnCountObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1691AA80A6500DDB1C5 /* CCPUOnCountObserver.h */; };
+ B665E32E1AA80A6500DDB1C5 /* CCPUOnCountObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E16A1AA80A6500DDB1C5 /* CCPUOnCountObserverTranslator.cpp */; };
+ B665E32F1AA80A6500DDB1C5 /* CCPUOnCountObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E16A1AA80A6500DDB1C5 /* CCPUOnCountObserverTranslator.cpp */; };
+ B665E3301AA80A6500DDB1C5 /* CCPUOnCountObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E16B1AA80A6500DDB1C5 /* CCPUOnCountObserverTranslator.h */; };
+ B665E3311AA80A6500DDB1C5 /* CCPUOnCountObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E16B1AA80A6500DDB1C5 /* CCPUOnCountObserverTranslator.h */; };
+ B665E3321AA80A6500DDB1C5 /* CCPUOnEmissionObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E16C1AA80A6500DDB1C5 /* CCPUOnEmissionObserver.cpp */; };
+ B665E3331AA80A6500DDB1C5 /* CCPUOnEmissionObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E16C1AA80A6500DDB1C5 /* CCPUOnEmissionObserver.cpp */; };
+ B665E3341AA80A6500DDB1C5 /* CCPUOnEmissionObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E16D1AA80A6500DDB1C5 /* CCPUOnEmissionObserver.h */; };
+ B665E3351AA80A6500DDB1C5 /* CCPUOnEmissionObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E16D1AA80A6500DDB1C5 /* CCPUOnEmissionObserver.h */; };
+ B665E3361AA80A6500DDB1C5 /* CCPUOnEmissionObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E16E1AA80A6500DDB1C5 /* CCPUOnEmissionObserverTranslator.cpp */; };
+ B665E3371AA80A6500DDB1C5 /* CCPUOnEmissionObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E16E1AA80A6500DDB1C5 /* CCPUOnEmissionObserverTranslator.cpp */; };
+ B665E3381AA80A6500DDB1C5 /* CCPUOnEmissionObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E16F1AA80A6500DDB1C5 /* CCPUOnEmissionObserverTranslator.h */; };
+ B665E3391AA80A6500DDB1C5 /* CCPUOnEmissionObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E16F1AA80A6500DDB1C5 /* CCPUOnEmissionObserverTranslator.h */; };
+ B665E33A1AA80A6500DDB1C5 /* CCPUOnEventFlagObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1701AA80A6500DDB1C5 /* CCPUOnEventFlagObserver.cpp */; };
+ B665E33B1AA80A6500DDB1C5 /* CCPUOnEventFlagObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1701AA80A6500DDB1C5 /* CCPUOnEventFlagObserver.cpp */; };
+ B665E33C1AA80A6500DDB1C5 /* CCPUOnEventFlagObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1711AA80A6500DDB1C5 /* CCPUOnEventFlagObserver.h */; };
+ B665E33D1AA80A6500DDB1C5 /* CCPUOnEventFlagObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1711AA80A6500DDB1C5 /* CCPUOnEventFlagObserver.h */; };
+ B665E33E1AA80A6500DDB1C5 /* CCPUOnEventFlagObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1721AA80A6500DDB1C5 /* CCPUOnEventFlagObserverTranslator.cpp */; };
+ B665E33F1AA80A6500DDB1C5 /* CCPUOnEventFlagObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1721AA80A6500DDB1C5 /* CCPUOnEventFlagObserverTranslator.cpp */; };
+ B665E3401AA80A6500DDB1C5 /* CCPUOnEventFlagObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1731AA80A6500DDB1C5 /* CCPUOnEventFlagObserverTranslator.h */; };
+ B665E3411AA80A6500DDB1C5 /* CCPUOnEventFlagObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1731AA80A6500DDB1C5 /* CCPUOnEventFlagObserverTranslator.h */; };
+ B665E3421AA80A6500DDB1C5 /* CCPUOnExpireObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1741AA80A6500DDB1C5 /* CCPUOnExpireObserver.cpp */; };
+ B665E3431AA80A6500DDB1C5 /* CCPUOnExpireObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1741AA80A6500DDB1C5 /* CCPUOnExpireObserver.cpp */; };
+ B665E3441AA80A6500DDB1C5 /* CCPUOnExpireObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1751AA80A6500DDB1C5 /* CCPUOnExpireObserver.h */; };
+ B665E3451AA80A6500DDB1C5 /* CCPUOnExpireObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1751AA80A6500DDB1C5 /* CCPUOnExpireObserver.h */; };
+ B665E3461AA80A6500DDB1C5 /* CCPUOnExpireObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1761AA80A6500DDB1C5 /* CCPUOnExpireObserverTranslator.cpp */; };
+ B665E3471AA80A6500DDB1C5 /* CCPUOnExpireObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1761AA80A6500DDB1C5 /* CCPUOnExpireObserverTranslator.cpp */; };
+ B665E3481AA80A6500DDB1C5 /* CCPUOnExpireObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1771AA80A6500DDB1C5 /* CCPUOnExpireObserverTranslator.h */; };
+ B665E3491AA80A6500DDB1C5 /* CCPUOnExpireObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1771AA80A6500DDB1C5 /* CCPUOnExpireObserverTranslator.h */; };
+ B665E34A1AA80A6500DDB1C5 /* CCPUOnPositionObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1781AA80A6500DDB1C5 /* CCPUOnPositionObserver.cpp */; };
+ B665E34B1AA80A6500DDB1C5 /* CCPUOnPositionObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1781AA80A6500DDB1C5 /* CCPUOnPositionObserver.cpp */; };
+ B665E34C1AA80A6500DDB1C5 /* CCPUOnPositionObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1791AA80A6500DDB1C5 /* CCPUOnPositionObserver.h */; };
+ B665E34D1AA80A6500DDB1C5 /* CCPUOnPositionObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1791AA80A6500DDB1C5 /* CCPUOnPositionObserver.h */; };
+ B665E34E1AA80A6500DDB1C5 /* CCPUOnPositionObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E17A1AA80A6500DDB1C5 /* CCPUOnPositionObserverTranslator.cpp */; };
+ B665E34F1AA80A6500DDB1C5 /* CCPUOnPositionObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E17A1AA80A6500DDB1C5 /* CCPUOnPositionObserverTranslator.cpp */; };
+ B665E3501AA80A6500DDB1C5 /* CCPUOnPositionObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E17B1AA80A6500DDB1C5 /* CCPUOnPositionObserverTranslator.h */; };
+ B665E3511AA80A6500DDB1C5 /* CCPUOnPositionObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E17B1AA80A6500DDB1C5 /* CCPUOnPositionObserverTranslator.h */; };
+ B665E3521AA80A6500DDB1C5 /* CCPUOnQuotaObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E17C1AA80A6500DDB1C5 /* CCPUOnQuotaObserver.cpp */; };
+ B665E3531AA80A6500DDB1C5 /* CCPUOnQuotaObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E17C1AA80A6500DDB1C5 /* CCPUOnQuotaObserver.cpp */; };
+ B665E3541AA80A6500DDB1C5 /* CCPUOnQuotaObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E17D1AA80A6500DDB1C5 /* CCPUOnQuotaObserver.h */; };
+ B665E3551AA80A6500DDB1C5 /* CCPUOnQuotaObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E17D1AA80A6500DDB1C5 /* CCPUOnQuotaObserver.h */; };
+ B665E3561AA80A6500DDB1C5 /* CCPUOnQuotaObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E17E1AA80A6500DDB1C5 /* CCPUOnQuotaObserverTranslator.cpp */; };
+ B665E3571AA80A6500DDB1C5 /* CCPUOnQuotaObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E17E1AA80A6500DDB1C5 /* CCPUOnQuotaObserverTranslator.cpp */; };
+ B665E3581AA80A6500DDB1C5 /* CCPUOnQuotaObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E17F1AA80A6500DDB1C5 /* CCPUOnQuotaObserverTranslator.h */; };
+ B665E3591AA80A6500DDB1C5 /* CCPUOnQuotaObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E17F1AA80A6500DDB1C5 /* CCPUOnQuotaObserverTranslator.h */; };
+ B665E35A1AA80A6500DDB1C5 /* CCPUOnRandomObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1801AA80A6500DDB1C5 /* CCPUOnRandomObserver.cpp */; };
+ B665E35B1AA80A6500DDB1C5 /* CCPUOnRandomObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1801AA80A6500DDB1C5 /* CCPUOnRandomObserver.cpp */; };
+ B665E35C1AA80A6500DDB1C5 /* CCPUOnRandomObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1811AA80A6500DDB1C5 /* CCPUOnRandomObserver.h */; };
+ B665E35D1AA80A6500DDB1C5 /* CCPUOnRandomObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1811AA80A6500DDB1C5 /* CCPUOnRandomObserver.h */; };
+ B665E35E1AA80A6500DDB1C5 /* CCPUOnRandomObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1821AA80A6500DDB1C5 /* CCPUOnRandomObserverTranslator.cpp */; };
+ B665E35F1AA80A6500DDB1C5 /* CCPUOnRandomObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1821AA80A6500DDB1C5 /* CCPUOnRandomObserverTranslator.cpp */; };
+ B665E3601AA80A6500DDB1C5 /* CCPUOnRandomObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1831AA80A6500DDB1C5 /* CCPUOnRandomObserverTranslator.h */; };
+ B665E3611AA80A6500DDB1C5 /* CCPUOnRandomObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1831AA80A6500DDB1C5 /* CCPUOnRandomObserverTranslator.h */; };
+ B665E3621AA80A6500DDB1C5 /* CCPUOnTimeObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1841AA80A6500DDB1C5 /* CCPUOnTimeObserver.cpp */; };
+ B665E3631AA80A6500DDB1C5 /* CCPUOnTimeObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1841AA80A6500DDB1C5 /* CCPUOnTimeObserver.cpp */; };
+ B665E3641AA80A6500DDB1C5 /* CCPUOnTimeObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1851AA80A6500DDB1C5 /* CCPUOnTimeObserver.h */; };
+ B665E3651AA80A6500DDB1C5 /* CCPUOnTimeObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1851AA80A6500DDB1C5 /* CCPUOnTimeObserver.h */; };
+ B665E3661AA80A6500DDB1C5 /* CCPUOnTimeObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1861AA80A6500DDB1C5 /* CCPUOnTimeObserverTranslator.cpp */; };
+ B665E3671AA80A6500DDB1C5 /* CCPUOnTimeObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1861AA80A6500DDB1C5 /* CCPUOnTimeObserverTranslator.cpp */; };
+ B665E3681AA80A6500DDB1C5 /* CCPUOnTimeObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1871AA80A6500DDB1C5 /* CCPUOnTimeObserverTranslator.h */; };
+ B665E3691AA80A6500DDB1C5 /* CCPUOnTimeObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1871AA80A6500DDB1C5 /* CCPUOnTimeObserverTranslator.h */; };
+ B665E36A1AA80A6500DDB1C5 /* CCPUOnVelocityObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1881AA80A6500DDB1C5 /* CCPUOnVelocityObserver.cpp */; };
+ B665E36B1AA80A6500DDB1C5 /* CCPUOnVelocityObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1881AA80A6500DDB1C5 /* CCPUOnVelocityObserver.cpp */; };
+ B665E36C1AA80A6500DDB1C5 /* CCPUOnVelocityObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1891AA80A6500DDB1C5 /* CCPUOnVelocityObserver.h */; };
+ B665E36D1AA80A6500DDB1C5 /* CCPUOnVelocityObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1891AA80A6500DDB1C5 /* CCPUOnVelocityObserver.h */; };
+ B665E36E1AA80A6500DDB1C5 /* CCPUOnVelocityObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E18A1AA80A6500DDB1C5 /* CCPUOnVelocityObserverTranslator.cpp */; };
+ B665E36F1AA80A6500DDB1C5 /* CCPUOnVelocityObserverTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E18A1AA80A6500DDB1C5 /* CCPUOnVelocityObserverTranslator.cpp */; };
+ B665E3701AA80A6500DDB1C5 /* CCPUOnVelocityObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E18B1AA80A6500DDB1C5 /* CCPUOnVelocityObserverTranslator.h */; };
+ B665E3711AA80A6500DDB1C5 /* CCPUOnVelocityObserverTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E18B1AA80A6500DDB1C5 /* CCPUOnVelocityObserverTranslator.h */; };
+ B665E3721AA80A6500DDB1C5 /* CCPUParticleFollower.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E18C1AA80A6500DDB1C5 /* CCPUParticleFollower.cpp */; };
+ B665E3731AA80A6500DDB1C5 /* CCPUParticleFollower.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E18C1AA80A6500DDB1C5 /* CCPUParticleFollower.cpp */; };
+ B665E3741AA80A6500DDB1C5 /* CCPUParticleFollower.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E18D1AA80A6500DDB1C5 /* CCPUParticleFollower.h */; };
+ B665E3751AA80A6500DDB1C5 /* CCPUParticleFollower.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E18D1AA80A6500DDB1C5 /* CCPUParticleFollower.h */; };
+ B665E3761AA80A6500DDB1C5 /* CCPUParticleFollowerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E18E1AA80A6500DDB1C5 /* CCPUParticleFollowerTranslator.cpp */; };
+ B665E3771AA80A6500DDB1C5 /* CCPUParticleFollowerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E18E1AA80A6500DDB1C5 /* CCPUParticleFollowerTranslator.cpp */; };
+ B665E3781AA80A6500DDB1C5 /* CCPUParticleFollowerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E18F1AA80A6500DDB1C5 /* CCPUParticleFollowerTranslator.h */; };
+ B665E3791AA80A6500DDB1C5 /* CCPUParticleFollowerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E18F1AA80A6500DDB1C5 /* CCPUParticleFollowerTranslator.h */; };
+ B665E37A1AA80A6500DDB1C5 /* CCPUParticleSystem3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1901AA80A6500DDB1C5 /* CCPUParticleSystem3D.cpp */; };
+ B665E37B1AA80A6500DDB1C5 /* CCPUParticleSystem3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1901AA80A6500DDB1C5 /* CCPUParticleSystem3D.cpp */; };
+ B665E37C1AA80A6500DDB1C5 /* CCPUParticleSystem3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1911AA80A6500DDB1C5 /* CCPUParticleSystem3D.h */; };
+ B665E37D1AA80A6500DDB1C5 /* CCPUParticleSystem3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1911AA80A6500DDB1C5 /* CCPUParticleSystem3D.h */; };
+ B665E37E1AA80A6500DDB1C5 /* CCPUParticleSystem3DTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1921AA80A6500DDB1C5 /* CCPUParticleSystem3DTranslator.cpp */; };
+ B665E37F1AA80A6500DDB1C5 /* CCPUParticleSystem3DTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1921AA80A6500DDB1C5 /* CCPUParticleSystem3DTranslator.cpp */; };
+ B665E3801AA80A6500DDB1C5 /* CCPUParticleSystem3DTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1931AA80A6500DDB1C5 /* CCPUParticleSystem3DTranslator.h */; };
+ B665E3811AA80A6500DDB1C5 /* CCPUParticleSystem3DTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1931AA80A6500DDB1C5 /* CCPUParticleSystem3DTranslator.h */; };
+ B665E3821AA80A6500DDB1C5 /* CCPUPathFollower.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1941AA80A6500DDB1C5 /* CCPUPathFollower.cpp */; };
+ B665E3831AA80A6500DDB1C5 /* CCPUPathFollower.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1941AA80A6500DDB1C5 /* CCPUPathFollower.cpp */; };
+ B665E3841AA80A6500DDB1C5 /* CCPUPathFollower.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1951AA80A6500DDB1C5 /* CCPUPathFollower.h */; };
+ B665E3851AA80A6500DDB1C5 /* CCPUPathFollower.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1951AA80A6500DDB1C5 /* CCPUPathFollower.h */; };
+ B665E3861AA80A6500DDB1C5 /* CCPUPathFollowerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1961AA80A6500DDB1C5 /* CCPUPathFollowerTranslator.cpp */; };
+ B665E3871AA80A6500DDB1C5 /* CCPUPathFollowerTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1961AA80A6500DDB1C5 /* CCPUPathFollowerTranslator.cpp */; };
+ B665E3881AA80A6500DDB1C5 /* CCPUPathFollowerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1971AA80A6500DDB1C5 /* CCPUPathFollowerTranslator.h */; };
+ B665E3891AA80A6500DDB1C5 /* CCPUPathFollowerTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1971AA80A6500DDB1C5 /* CCPUPathFollowerTranslator.h */; };
+ B665E38A1AA80A6500DDB1C5 /* CCPUPlane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1981AA80A6500DDB1C5 /* CCPUPlane.cpp */; };
+ B665E38B1AA80A6500DDB1C5 /* CCPUPlane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1981AA80A6500DDB1C5 /* CCPUPlane.cpp */; };
+ B665E38C1AA80A6500DDB1C5 /* CCPUPlane.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1991AA80A6500DDB1C5 /* CCPUPlane.h */; };
+ B665E38D1AA80A6500DDB1C5 /* CCPUPlane.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1991AA80A6500DDB1C5 /* CCPUPlane.h */; };
+ B665E38E1AA80A6500DDB1C5 /* CCPUPlaneCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E19A1AA80A6500DDB1C5 /* CCPUPlaneCollider.cpp */; };
+ B665E38F1AA80A6500DDB1C5 /* CCPUPlaneCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E19A1AA80A6500DDB1C5 /* CCPUPlaneCollider.cpp */; };
+ B665E3901AA80A6500DDB1C5 /* CCPUPlaneCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E19B1AA80A6500DDB1C5 /* CCPUPlaneCollider.h */; };
+ B665E3911AA80A6500DDB1C5 /* CCPUPlaneCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E19B1AA80A6500DDB1C5 /* CCPUPlaneCollider.h */; };
+ B665E3921AA80A6500DDB1C5 /* CCPUPlaneColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E19C1AA80A6500DDB1C5 /* CCPUPlaneColliderTranslator.cpp */; };
+ B665E3931AA80A6500DDB1C5 /* CCPUPlaneColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E19C1AA80A6500DDB1C5 /* CCPUPlaneColliderTranslator.cpp */; };
+ B665E3941AA80A6500DDB1C5 /* CCPUPlaneColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E19D1AA80A6500DDB1C5 /* CCPUPlaneColliderTranslator.h */; };
+ B665E3951AA80A6500DDB1C5 /* CCPUPlaneColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E19D1AA80A6500DDB1C5 /* CCPUPlaneColliderTranslator.h */; };
+ B665E3961AA80A6500DDB1C5 /* CCPUPointEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E19E1AA80A6500DDB1C5 /* CCPUPointEmitter.cpp */; };
+ B665E3971AA80A6500DDB1C5 /* CCPUPointEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E19E1AA80A6500DDB1C5 /* CCPUPointEmitter.cpp */; };
+ B665E3981AA80A6500DDB1C5 /* CCPUPointEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E19F1AA80A6500DDB1C5 /* CCPUPointEmitter.h */; };
+ B665E3991AA80A6500DDB1C5 /* CCPUPointEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E19F1AA80A6500DDB1C5 /* CCPUPointEmitter.h */; };
+ B665E39A1AA80A6500DDB1C5 /* CCPUPointEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A01AA80A6500DDB1C5 /* CCPUPointEmitterTranslator.cpp */; };
+ B665E39B1AA80A6500DDB1C5 /* CCPUPointEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A01AA80A6500DDB1C5 /* CCPUPointEmitterTranslator.cpp */; };
+ B665E39C1AA80A6500DDB1C5 /* CCPUPointEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A11AA80A6500DDB1C5 /* CCPUPointEmitterTranslator.h */; };
+ B665E39D1AA80A6500DDB1C5 /* CCPUPointEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A11AA80A6500DDB1C5 /* CCPUPointEmitterTranslator.h */; };
+ B665E39E1AA80A6500DDB1C5 /* CCPUPositionEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A21AA80A6500DDB1C5 /* CCPUPositionEmitter.cpp */; };
+ B665E39F1AA80A6500DDB1C5 /* CCPUPositionEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A21AA80A6500DDB1C5 /* CCPUPositionEmitter.cpp */; };
+ B665E3A01AA80A6500DDB1C5 /* CCPUPositionEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A31AA80A6500DDB1C5 /* CCPUPositionEmitter.h */; };
+ B665E3A11AA80A6500DDB1C5 /* CCPUPositionEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A31AA80A6500DDB1C5 /* CCPUPositionEmitter.h */; };
+ B665E3A21AA80A6500DDB1C5 /* CCPUPositionEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A41AA80A6500DDB1C5 /* CCPUPositionEmitterTranslator.cpp */; };
+ B665E3A31AA80A6500DDB1C5 /* CCPUPositionEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A41AA80A6500DDB1C5 /* CCPUPositionEmitterTranslator.cpp */; };
+ B665E3A41AA80A6500DDB1C5 /* CCPUPositionEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A51AA80A6500DDB1C5 /* CCPUPositionEmitterTranslator.h */; };
+ B665E3A51AA80A6500DDB1C5 /* CCPUPositionEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A51AA80A6500DDB1C5 /* CCPUPositionEmitterTranslator.h */; };
+ B665E3A61AA80A6500DDB1C5 /* CCPURandomiser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A61AA80A6500DDB1C5 /* CCPURandomiser.cpp */; };
+ B665E3A71AA80A6500DDB1C5 /* CCPURandomiser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A61AA80A6500DDB1C5 /* CCPURandomiser.cpp */; };
+ B665E3A81AA80A6500DDB1C5 /* CCPURandomiser.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A71AA80A6500DDB1C5 /* CCPURandomiser.h */; };
+ B665E3A91AA80A6500DDB1C5 /* CCPURandomiser.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A71AA80A6500DDB1C5 /* CCPURandomiser.h */; };
+ B665E3AA1AA80A6500DDB1C5 /* CCPURandomiserTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A81AA80A6500DDB1C5 /* CCPURandomiserTranslator.cpp */; };
+ B665E3AB1AA80A6500DDB1C5 /* CCPURandomiserTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1A81AA80A6500DDB1C5 /* CCPURandomiserTranslator.cpp */; };
+ B665E3AC1AA80A6500DDB1C5 /* CCPURandomiserTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A91AA80A6500DDB1C5 /* CCPURandomiserTranslator.h */; };
+ B665E3AD1AA80A6500DDB1C5 /* CCPURandomiserTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1A91AA80A6500DDB1C5 /* CCPURandomiserTranslator.h */; };
+ B665E3AE1AA80A6500DDB1C5 /* CCPURender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1AA1AA80A6500DDB1C5 /* CCPURender.cpp */; };
+ B665E3AF1AA80A6500DDB1C5 /* CCPURender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1AA1AA80A6500DDB1C5 /* CCPURender.cpp */; };
+ B665E3B01AA80A6500DDB1C5 /* CCPURender.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1AB1AA80A6500DDB1C5 /* CCPURender.h */; };
+ B665E3B11AA80A6500DDB1C5 /* CCPURender.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1AB1AA80A6500DDB1C5 /* CCPURender.h */; };
+ B665E3B21AA80A6500DDB1C5 /* CCPURendererTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1AC1AA80A6500DDB1C5 /* CCPURendererTranslator.cpp */; };
+ B665E3B31AA80A6500DDB1C5 /* CCPURendererTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1AC1AA80A6500DDB1C5 /* CCPURendererTranslator.cpp */; };
+ B665E3B41AA80A6500DDB1C5 /* CCPURendererTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1AD1AA80A6500DDB1C5 /* CCPURendererTranslator.h */; };
+ B665E3B51AA80A6500DDB1C5 /* CCPURendererTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1AD1AA80A6500DDB1C5 /* CCPURendererTranslator.h */; };
+ B665E3B61AA80A6500DDB1C5 /* CCPURibbonTrail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1AE1AA80A6500DDB1C5 /* CCPURibbonTrail.cpp */; };
+ B665E3B71AA80A6500DDB1C5 /* CCPURibbonTrail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1AE1AA80A6500DDB1C5 /* CCPURibbonTrail.cpp */; };
+ B665E3B81AA80A6500DDB1C5 /* CCPURibbonTrail.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1AF1AA80A6500DDB1C5 /* CCPURibbonTrail.h */; };
+ B665E3B91AA80A6500DDB1C5 /* CCPURibbonTrail.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1AF1AA80A6500DDB1C5 /* CCPURibbonTrail.h */; };
+ B665E3BA1AA80A6500DDB1C5 /* CCPURibbonTrailRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B01AA80A6500DDB1C5 /* CCPURibbonTrailRender.cpp */; };
+ B665E3BB1AA80A6500DDB1C5 /* CCPURibbonTrailRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B01AA80A6500DDB1C5 /* CCPURibbonTrailRender.cpp */; };
+ B665E3BC1AA80A6500DDB1C5 /* CCPURibbonTrailRender.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B11AA80A6500DDB1C5 /* CCPURibbonTrailRender.h */; };
+ B665E3BD1AA80A6500DDB1C5 /* CCPURibbonTrailRender.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B11AA80A6500DDB1C5 /* CCPURibbonTrailRender.h */; };
+ B665E3BE1AA80A6500DDB1C5 /* CCPUScaleAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B21AA80A6500DDB1C5 /* CCPUScaleAffector.cpp */; };
+ B665E3BF1AA80A6500DDB1C5 /* CCPUScaleAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B21AA80A6500DDB1C5 /* CCPUScaleAffector.cpp */; };
+ B665E3C01AA80A6500DDB1C5 /* CCPUScaleAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B31AA80A6500DDB1C5 /* CCPUScaleAffector.h */; };
+ B665E3C11AA80A6500DDB1C5 /* CCPUScaleAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B31AA80A6500DDB1C5 /* CCPUScaleAffector.h */; };
+ B665E3C21AA80A6600DDB1C5 /* CCPUScaleAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B41AA80A6500DDB1C5 /* CCPUScaleAffectorTranslator.cpp */; };
+ B665E3C31AA80A6600DDB1C5 /* CCPUScaleAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B41AA80A6500DDB1C5 /* CCPUScaleAffectorTranslator.cpp */; };
+ B665E3C41AA80A6600DDB1C5 /* CCPUScaleAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B51AA80A6500DDB1C5 /* CCPUScaleAffectorTranslator.h */; };
+ B665E3C51AA80A6600DDB1C5 /* CCPUScaleAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B51AA80A6500DDB1C5 /* CCPUScaleAffectorTranslator.h */; };
+ B665E3C61AA80A6600DDB1C5 /* CCPUScaleVelocityAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B61AA80A6500DDB1C5 /* CCPUScaleVelocityAffector.cpp */; };
+ B665E3C71AA80A6600DDB1C5 /* CCPUScaleVelocityAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B61AA80A6500DDB1C5 /* CCPUScaleVelocityAffector.cpp */; };
+ B665E3C81AA80A6600DDB1C5 /* CCPUScaleVelocityAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B71AA80A6500DDB1C5 /* CCPUScaleVelocityAffector.h */; };
+ B665E3C91AA80A6600DDB1C5 /* CCPUScaleVelocityAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B71AA80A6500DDB1C5 /* CCPUScaleVelocityAffector.h */; };
+ B665E3CA1AA80A6600DDB1C5 /* CCPUScaleVelocityAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B81AA80A6500DDB1C5 /* CCPUScaleVelocityAffectorTranslator.cpp */; };
+ B665E3CB1AA80A6600DDB1C5 /* CCPUScaleVelocityAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1B81AA80A6500DDB1C5 /* CCPUScaleVelocityAffectorTranslator.cpp */; };
+ B665E3CC1AA80A6600DDB1C5 /* CCPUScaleVelocityAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B91AA80A6500DDB1C5 /* CCPUScaleVelocityAffectorTranslator.h */; };
+ B665E3CD1AA80A6600DDB1C5 /* CCPUScaleVelocityAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1B91AA80A6500DDB1C5 /* CCPUScaleVelocityAffectorTranslator.h */; };
+ B665E3CE1AA80A6600DDB1C5 /* CCPUScriptCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1BA1AA80A6500DDB1C5 /* CCPUScriptCompiler.cpp */; };
+ B665E3CF1AA80A6600DDB1C5 /* CCPUScriptCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1BA1AA80A6500DDB1C5 /* CCPUScriptCompiler.cpp */; };
+ B665E3D01AA80A6600DDB1C5 /* CCPUScriptCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1BB1AA80A6500DDB1C5 /* CCPUScriptCompiler.h */; };
+ B665E3D11AA80A6600DDB1C5 /* CCPUScriptCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1BB1AA80A6500DDB1C5 /* CCPUScriptCompiler.h */; };
+ B665E3D21AA80A6600DDB1C5 /* CCPUScriptLexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1BC1AA80A6500DDB1C5 /* CCPUScriptLexer.cpp */; };
+ B665E3D31AA80A6600DDB1C5 /* CCPUScriptLexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1BC1AA80A6500DDB1C5 /* CCPUScriptLexer.cpp */; };
+ B665E3D41AA80A6600DDB1C5 /* CCPUScriptLexer.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1BD1AA80A6500DDB1C5 /* CCPUScriptLexer.h */; };
+ B665E3D51AA80A6600DDB1C5 /* CCPUScriptLexer.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1BD1AA80A6500DDB1C5 /* CCPUScriptLexer.h */; };
+ B665E3D61AA80A6600DDB1C5 /* CCPUScriptParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1BE1AA80A6500DDB1C5 /* CCPUScriptParser.cpp */; };
+ B665E3D71AA80A6600DDB1C5 /* CCPUScriptParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1BE1AA80A6500DDB1C5 /* CCPUScriptParser.cpp */; };
+ B665E3D81AA80A6600DDB1C5 /* CCPUScriptParser.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1BF1AA80A6500DDB1C5 /* CCPUScriptParser.h */; };
+ B665E3D91AA80A6600DDB1C5 /* CCPUScriptParser.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1BF1AA80A6500DDB1C5 /* CCPUScriptParser.h */; };
+ B665E3DA1AA80A6600DDB1C5 /* CCPUScriptTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C01AA80A6500DDB1C5 /* CCPUScriptTranslator.cpp */; };
+ B665E3DB1AA80A6600DDB1C5 /* CCPUScriptTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C01AA80A6500DDB1C5 /* CCPUScriptTranslator.cpp */; };
+ B665E3DC1AA80A6600DDB1C5 /* CCPUScriptTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C11AA80A6500DDB1C5 /* CCPUScriptTranslator.h */; };
+ B665E3DD1AA80A6600DDB1C5 /* CCPUScriptTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C11AA80A6500DDB1C5 /* CCPUScriptTranslator.h */; };
+ B665E3DE1AA80A6600DDB1C5 /* CCPUSimpleSpline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C21AA80A6500DDB1C5 /* CCPUSimpleSpline.cpp */; };
+ B665E3DF1AA80A6600DDB1C5 /* CCPUSimpleSpline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C21AA80A6500DDB1C5 /* CCPUSimpleSpline.cpp */; };
+ B665E3E01AA80A6600DDB1C5 /* CCPUSimpleSpline.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C31AA80A6500DDB1C5 /* CCPUSimpleSpline.h */; };
+ B665E3E11AA80A6600DDB1C5 /* CCPUSimpleSpline.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C31AA80A6500DDB1C5 /* CCPUSimpleSpline.h */; };
+ B665E3E21AA80A6600DDB1C5 /* CCPUSineForceAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C41AA80A6500DDB1C5 /* CCPUSineForceAffector.cpp */; };
+ B665E3E31AA80A6600DDB1C5 /* CCPUSineForceAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C41AA80A6500DDB1C5 /* CCPUSineForceAffector.cpp */; };
+ B665E3E41AA80A6600DDB1C5 /* CCPUSineForceAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C51AA80A6500DDB1C5 /* CCPUSineForceAffector.h */; };
+ B665E3E51AA80A6600DDB1C5 /* CCPUSineForceAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C51AA80A6500DDB1C5 /* CCPUSineForceAffector.h */; };
+ B665E3E61AA80A6600DDB1C5 /* CCPUSineForceAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C61AA80A6500DDB1C5 /* CCPUSineForceAffectorTranslator.cpp */; };
+ B665E3E71AA80A6600DDB1C5 /* CCPUSineForceAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C61AA80A6500DDB1C5 /* CCPUSineForceAffectorTranslator.cpp */; };
+ B665E3E81AA80A6600DDB1C5 /* CCPUSineForceAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C71AA80A6500DDB1C5 /* CCPUSineForceAffectorTranslator.h */; };
+ B665E3E91AA80A6600DDB1C5 /* CCPUSineForceAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C71AA80A6500DDB1C5 /* CCPUSineForceAffectorTranslator.h */; };
+ B665E3EA1AA80A6600DDB1C5 /* CCPUSlaveBehaviour.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C81AA80A6500DDB1C5 /* CCPUSlaveBehaviour.cpp */; };
+ B665E3EB1AA80A6600DDB1C5 /* CCPUSlaveBehaviour.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1C81AA80A6500DDB1C5 /* CCPUSlaveBehaviour.cpp */; };
+ B665E3EC1AA80A6600DDB1C5 /* CCPUSlaveBehaviour.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C91AA80A6500DDB1C5 /* CCPUSlaveBehaviour.h */; };
+ B665E3ED1AA80A6600DDB1C5 /* CCPUSlaveBehaviour.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1C91AA80A6500DDB1C5 /* CCPUSlaveBehaviour.h */; };
+ B665E3EE1AA80A6600DDB1C5 /* CCPUSlaveBehaviourTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1CA1AA80A6500DDB1C5 /* CCPUSlaveBehaviourTranslator.cpp */; };
+ B665E3EF1AA80A6600DDB1C5 /* CCPUSlaveBehaviourTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1CA1AA80A6500DDB1C5 /* CCPUSlaveBehaviourTranslator.cpp */; };
+ B665E3F01AA80A6600DDB1C5 /* CCPUSlaveBehaviourTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1CB1AA80A6500DDB1C5 /* CCPUSlaveBehaviourTranslator.h */; };
+ B665E3F11AA80A6600DDB1C5 /* CCPUSlaveBehaviourTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1CB1AA80A6500DDB1C5 /* CCPUSlaveBehaviourTranslator.h */; };
+ B665E3F21AA80A6600DDB1C5 /* CCPUSlaveEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1CC1AA80A6500DDB1C5 /* CCPUSlaveEmitter.cpp */; };
+ B665E3F31AA80A6600DDB1C5 /* CCPUSlaveEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1CC1AA80A6500DDB1C5 /* CCPUSlaveEmitter.cpp */; };
+ B665E3F41AA80A6600DDB1C5 /* CCPUSlaveEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1CD1AA80A6500DDB1C5 /* CCPUSlaveEmitter.h */; };
+ B665E3F51AA80A6600DDB1C5 /* CCPUSlaveEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1CD1AA80A6500DDB1C5 /* CCPUSlaveEmitter.h */; };
+ B665E3F61AA80A6600DDB1C5 /* CCPUSlaveEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1CE1AA80A6500DDB1C5 /* CCPUSlaveEmitterTranslator.cpp */; };
+ B665E3F71AA80A6600DDB1C5 /* CCPUSlaveEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1CE1AA80A6500DDB1C5 /* CCPUSlaveEmitterTranslator.cpp */; };
+ B665E3F81AA80A6600DDB1C5 /* CCPUSlaveEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1CF1AA80A6500DDB1C5 /* CCPUSlaveEmitterTranslator.h */; };
+ B665E3F91AA80A6600DDB1C5 /* CCPUSlaveEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1CF1AA80A6500DDB1C5 /* CCPUSlaveEmitterTranslator.h */; };
+ B665E3FA1AA80A6600DDB1C5 /* CCPUSphere.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D01AA80A6500DDB1C5 /* CCPUSphere.cpp */; };
+ B665E3FB1AA80A6600DDB1C5 /* CCPUSphere.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D01AA80A6500DDB1C5 /* CCPUSphere.cpp */; };
+ B665E3FC1AA80A6600DDB1C5 /* CCPUSphere.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D11AA80A6500DDB1C5 /* CCPUSphere.h */; };
+ B665E3FD1AA80A6600DDB1C5 /* CCPUSphere.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D11AA80A6500DDB1C5 /* CCPUSphere.h */; };
+ B665E3FE1AA80A6600DDB1C5 /* CCPUSphereCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D21AA80A6500DDB1C5 /* CCPUSphereCollider.cpp */; };
+ B665E3FF1AA80A6600DDB1C5 /* CCPUSphereCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D21AA80A6500DDB1C5 /* CCPUSphereCollider.cpp */; };
+ B665E4001AA80A6600DDB1C5 /* CCPUSphereCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D31AA80A6500DDB1C5 /* CCPUSphereCollider.h */; };
+ B665E4011AA80A6600DDB1C5 /* CCPUSphereCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D31AA80A6500DDB1C5 /* CCPUSphereCollider.h */; };
+ B665E4021AA80A6600DDB1C5 /* CCPUSphereColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D41AA80A6500DDB1C5 /* CCPUSphereColliderTranslator.cpp */; };
+ B665E4031AA80A6600DDB1C5 /* CCPUSphereColliderTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D41AA80A6500DDB1C5 /* CCPUSphereColliderTranslator.cpp */; };
+ B665E4041AA80A6600DDB1C5 /* CCPUSphereColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D51AA80A6500DDB1C5 /* CCPUSphereColliderTranslator.h */; };
+ B665E4051AA80A6600DDB1C5 /* CCPUSphereColliderTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D51AA80A6500DDB1C5 /* CCPUSphereColliderTranslator.h */; };
+ B665E4061AA80A6600DDB1C5 /* CCPUSphereSurfaceEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D61AA80A6500DDB1C5 /* CCPUSphereSurfaceEmitter.cpp */; };
+ B665E4071AA80A6600DDB1C5 /* CCPUSphereSurfaceEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D61AA80A6500DDB1C5 /* CCPUSphereSurfaceEmitter.cpp */; };
+ B665E4081AA80A6600DDB1C5 /* CCPUSphereSurfaceEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D71AA80A6500DDB1C5 /* CCPUSphereSurfaceEmitter.h */; };
+ B665E4091AA80A6600DDB1C5 /* CCPUSphereSurfaceEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D71AA80A6500DDB1C5 /* CCPUSphereSurfaceEmitter.h */; };
+ B665E40A1AA80A6600DDB1C5 /* CCPUSphereSurfaceEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D81AA80A6500DDB1C5 /* CCPUSphereSurfaceEmitterTranslator.cpp */; };
+ B665E40B1AA80A6600DDB1C5 /* CCPUSphereSurfaceEmitterTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1D81AA80A6500DDB1C5 /* CCPUSphereSurfaceEmitterTranslator.cpp */; };
+ B665E40C1AA80A6600DDB1C5 /* CCPUSphereSurfaceEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D91AA80A6500DDB1C5 /* CCPUSphereSurfaceEmitterTranslator.h */; };
+ B665E40D1AA80A6600DDB1C5 /* CCPUSphereSurfaceEmitterTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1D91AA80A6500DDB1C5 /* CCPUSphereSurfaceEmitterTranslator.h */; };
+ B665E40E1AA80A6600DDB1C5 /* CCPUTechniqueTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1DA1AA80A6500DDB1C5 /* CCPUTechniqueTranslator.cpp */; };
+ B665E40F1AA80A6600DDB1C5 /* CCPUTechniqueTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1DA1AA80A6500DDB1C5 /* CCPUTechniqueTranslator.cpp */; };
+ B665E4101AA80A6600DDB1C5 /* CCPUTechniqueTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1DB1AA80A6500DDB1C5 /* CCPUTechniqueTranslator.h */; };
+ B665E4111AA80A6600DDB1C5 /* CCPUTechniqueTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1DB1AA80A6500DDB1C5 /* CCPUTechniqueTranslator.h */; };
+ B665E4121AA80A6600DDB1C5 /* CCPUTextureAnimator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1DC1AA80A6500DDB1C5 /* CCPUTextureAnimator.cpp */; };
+ B665E4131AA80A6600DDB1C5 /* CCPUTextureAnimator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1DC1AA80A6500DDB1C5 /* CCPUTextureAnimator.cpp */; };
+ B665E4141AA80A6600DDB1C5 /* CCPUTextureAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1DD1AA80A6500DDB1C5 /* CCPUTextureAnimator.h */; };
+ B665E4151AA80A6600DDB1C5 /* CCPUTextureAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1DD1AA80A6500DDB1C5 /* CCPUTextureAnimator.h */; };
+ B665E4161AA80A6600DDB1C5 /* CCPUTextureAnimatorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1DE1AA80A6500DDB1C5 /* CCPUTextureAnimatorTranslator.cpp */; };
+ B665E4171AA80A6600DDB1C5 /* CCPUTextureAnimatorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1DE1AA80A6500DDB1C5 /* CCPUTextureAnimatorTranslator.cpp */; };
+ B665E4181AA80A6600DDB1C5 /* CCPUTextureAnimatorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1DF1AA80A6500DDB1C5 /* CCPUTextureAnimatorTranslator.h */; };
+ B665E4191AA80A6600DDB1C5 /* CCPUTextureAnimatorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1DF1AA80A6500DDB1C5 /* CCPUTextureAnimatorTranslator.h */; };
+ B665E41A1AA80A6600DDB1C5 /* CCPUTextureRotator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E01AA80A6500DDB1C5 /* CCPUTextureRotator.cpp */; };
+ B665E41B1AA80A6600DDB1C5 /* CCPUTextureRotator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E01AA80A6500DDB1C5 /* CCPUTextureRotator.cpp */; };
+ B665E41C1AA80A6600DDB1C5 /* CCPUTextureRotator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E11AA80A6500DDB1C5 /* CCPUTextureRotator.h */; };
+ B665E41D1AA80A6600DDB1C5 /* CCPUTextureRotator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E11AA80A6500DDB1C5 /* CCPUTextureRotator.h */; };
+ B665E41E1AA80A6600DDB1C5 /* CCPUTextureRotatorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E21AA80A6500DDB1C5 /* CCPUTextureRotatorTranslator.cpp */; };
+ B665E41F1AA80A6600DDB1C5 /* CCPUTextureRotatorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E21AA80A6500DDB1C5 /* CCPUTextureRotatorTranslator.cpp */; };
+ B665E4201AA80A6600DDB1C5 /* CCPUTextureRotatorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E31AA80A6500DDB1C5 /* CCPUTextureRotatorTranslator.h */; };
+ B665E4211AA80A6600DDB1C5 /* CCPUTextureRotatorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E31AA80A6500DDB1C5 /* CCPUTextureRotatorTranslator.h */; };
+ B665E4221AA80A6600DDB1C5 /* CCPUTranslateManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E41AA80A6500DDB1C5 /* CCPUTranslateManager.cpp */; };
+ B665E4231AA80A6600DDB1C5 /* CCPUTranslateManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E41AA80A6500DDB1C5 /* CCPUTranslateManager.cpp */; };
+ B665E4241AA80A6600DDB1C5 /* CCPUTranslateManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E51AA80A6500DDB1C5 /* CCPUTranslateManager.h */; };
+ B665E4251AA80A6600DDB1C5 /* CCPUTranslateManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E51AA80A6500DDB1C5 /* CCPUTranslateManager.h */; };
+ B665E4261AA80A6600DDB1C5 /* CCPUUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E61AA80A6500DDB1C5 /* CCPUUtil.cpp */; };
+ B665E4271AA80A6600DDB1C5 /* CCPUUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E61AA80A6500DDB1C5 /* CCPUUtil.cpp */; };
+ B665E4281AA80A6600DDB1C5 /* CCPUUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E71AA80A6500DDB1C5 /* CCPUUtil.h */; };
+ B665E4291AA80A6600DDB1C5 /* CCPUUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E71AA80A6500DDB1C5 /* CCPUUtil.h */; };
+ B665E42A1AA80A6600DDB1C5 /* CCPUVelocityMatchingAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E81AA80A6500DDB1C5 /* CCPUVelocityMatchingAffector.cpp */; };
+ B665E42B1AA80A6600DDB1C5 /* CCPUVelocityMatchingAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1E81AA80A6500DDB1C5 /* CCPUVelocityMatchingAffector.cpp */; };
+ B665E42C1AA80A6600DDB1C5 /* CCPUVelocityMatchingAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E91AA80A6500DDB1C5 /* CCPUVelocityMatchingAffector.h */; };
+ B665E42D1AA80A6600DDB1C5 /* CCPUVelocityMatchingAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1E91AA80A6500DDB1C5 /* CCPUVelocityMatchingAffector.h */; };
+ B665E42E1AA80A6600DDB1C5 /* CCPUVelocityMatchingAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1EA1AA80A6500DDB1C5 /* CCPUVelocityMatchingAffectorTranslator.cpp */; };
+ B665E42F1AA80A6600DDB1C5 /* CCPUVelocityMatchingAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1EA1AA80A6500DDB1C5 /* CCPUVelocityMatchingAffectorTranslator.cpp */; };
+ B665E4301AA80A6600DDB1C5 /* CCPUVelocityMatchingAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1EB1AA80A6500DDB1C5 /* CCPUVelocityMatchingAffectorTranslator.h */; };
+ B665E4311AA80A6600DDB1C5 /* CCPUVelocityMatchingAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1EB1AA80A6500DDB1C5 /* CCPUVelocityMatchingAffectorTranslator.h */; };
+ B665E4321AA80A6600DDB1C5 /* CCPUVertexEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1EC1AA80A6500DDB1C5 /* CCPUVertexEmitter.cpp */; };
+ B665E4331AA80A6600DDB1C5 /* CCPUVertexEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1EC1AA80A6500DDB1C5 /* CCPUVertexEmitter.cpp */; };
+ B665E4341AA80A6600DDB1C5 /* CCPUVertexEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1ED1AA80A6500DDB1C5 /* CCPUVertexEmitter.h */; };
+ B665E4351AA80A6600DDB1C5 /* CCPUVertexEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1ED1AA80A6500DDB1C5 /* CCPUVertexEmitter.h */; };
+ B665E4361AA80A6600DDB1C5 /* CCPUVortexAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1EE1AA80A6500DDB1C5 /* CCPUVortexAffector.cpp */; };
+ B665E4371AA80A6600DDB1C5 /* CCPUVortexAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1EE1AA80A6500DDB1C5 /* CCPUVortexAffector.cpp */; };
+ B665E4381AA80A6600DDB1C5 /* CCPUVortexAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1EF1AA80A6500DDB1C5 /* CCPUVortexAffector.h */; };
+ B665E4391AA80A6600DDB1C5 /* CCPUVortexAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1EF1AA80A6500DDB1C5 /* CCPUVortexAffector.h */; };
+ B665E43A1AA80A6600DDB1C5 /* CCPUVortexAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1F01AA80A6500DDB1C5 /* CCPUVortexAffectorTranslator.cpp */; };
+ B665E43B1AA80A6600DDB1C5 /* CCPUVortexAffectorTranslator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B665E1F01AA80A6500DDB1C5 /* CCPUVortexAffectorTranslator.cpp */; };
+ B665E43C1AA80A6600DDB1C5 /* CCPUVortexAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1F11AA80A6500DDB1C5 /* CCPUVortexAffectorTranslator.h */; };
+ B665E43D1AA80A6600DDB1C5 /* CCPUVortexAffectorTranslator.h in Headers */ = {isa = PBXBuildFile; fileRef = B665E1F11AA80A6500DDB1C5 /* CCPUVortexAffectorTranslator.h */; };
+ B677B0C91B18492D006762CB /* CCNavMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0BF1B18492D006762CB /* CCNavMesh.cpp */; };
+ B677B0CA1B18492D006762CB /* CCNavMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0BF1B18492D006762CB /* CCNavMesh.cpp */; };
+ B677B0CB1B18492D006762CB /* CCNavMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C01B18492D006762CB /* CCNavMesh.h */; };
+ B677B0CC1B18492D006762CB /* CCNavMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C01B18492D006762CB /* CCNavMesh.h */; };
+ B677B0CD1B18492D006762CB /* CCNavMeshAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0C11B18492D006762CB /* CCNavMeshAgent.cpp */; };
+ B677B0CE1B18492D006762CB /* CCNavMeshAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0C11B18492D006762CB /* CCNavMeshAgent.cpp */; };
+ B677B0CF1B18492D006762CB /* CCNavMeshAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C21B18492D006762CB /* CCNavMeshAgent.h */; };
+ B677B0D01B18492D006762CB /* CCNavMeshAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C21B18492D006762CB /* CCNavMeshAgent.h */; };
+ B677B0D11B18492D006762CB /* CCNavMeshDebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0C31B18492D006762CB /* CCNavMeshDebugDraw.cpp */; };
+ B677B0D21B18492D006762CB /* CCNavMeshDebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0C31B18492D006762CB /* CCNavMeshDebugDraw.cpp */; };
+ B677B0D31B18492D006762CB /* CCNavMeshDebugDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C41B18492D006762CB /* CCNavMeshDebugDraw.h */; };
+ B677B0D41B18492D006762CB /* CCNavMeshDebugDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C41B18492D006762CB /* CCNavMeshDebugDraw.h */; };
+ B677B0D51B18492D006762CB /* CCNavMeshObstacle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0C51B18492D006762CB /* CCNavMeshObstacle.cpp */; };
+ B677B0D61B18492D006762CB /* CCNavMeshObstacle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0C51B18492D006762CB /* CCNavMeshObstacle.cpp */; };
+ B677B0D71B18492D006762CB /* CCNavMeshObstacle.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C61B18492D006762CB /* CCNavMeshObstacle.h */; };
+ B677B0D81B18492D006762CB /* CCNavMeshObstacle.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C61B18492D006762CB /* CCNavMeshObstacle.h */; };
+ B677B0D91B18492D006762CB /* CCNavMeshUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0C71B18492D006762CB /* CCNavMeshUtils.cpp */; };
+ B677B0DA1B18492D006762CB /* CCNavMeshUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B677B0C71B18492D006762CB /* CCNavMeshUtils.cpp */; };
+ B677B0DB1B18492D006762CB /* CCNavMeshUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C81B18492D006762CB /* CCNavMeshUtils.h */; };
+ B677B0DC1B18492D006762CB /* CCNavMeshUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = B677B0C81B18492D006762CB /* CCNavMeshUtils.h */; };
+ B68778F81A8CA82E00643ABF /* CCParticle3DAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B68778F01A8CA82E00643ABF /* CCParticle3DAffector.cpp */; };
+ B68778F91A8CA82E00643ABF /* CCParticle3DAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B68778F01A8CA82E00643ABF /* CCParticle3DAffector.cpp */; };
+ B68778FA1A8CA82E00643ABF /* CCParticle3DAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B68778F11A8CA82E00643ABF /* CCParticle3DAffector.h */; };
+ B68778FB1A8CA82E00643ABF /* CCParticle3DAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = B68778F11A8CA82E00643ABF /* CCParticle3DAffector.h */; };
+ B68778FC1A8CA82E00643ABF /* CCParticle3DEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B68778F21A8CA82E00643ABF /* CCParticle3DEmitter.cpp */; };
+ B68778FD1A8CA82E00643ABF /* CCParticle3DEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B68778F21A8CA82E00643ABF /* CCParticle3DEmitter.cpp */; };
+ B68778FE1A8CA82E00643ABF /* CCParticle3DEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B68778F31A8CA82E00643ABF /* CCParticle3DEmitter.h */; };
+ B68778FF1A8CA82E00643ABF /* CCParticle3DEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = B68778F31A8CA82E00643ABF /* CCParticle3DEmitter.h */; };
+ B68779001A8CA82E00643ABF /* CCParticle3DRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B68778F41A8CA82E00643ABF /* CCParticle3DRender.cpp */; };
+ B68779011A8CA82E00643ABF /* CCParticle3DRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B68778F41A8CA82E00643ABF /* CCParticle3DRender.cpp */; };
+ B68779021A8CA82E00643ABF /* CCParticle3DRender.h in Headers */ = {isa = PBXBuildFile; fileRef = B68778F51A8CA82E00643ABF /* CCParticle3DRender.h */; };
+ B68779031A8CA82E00643ABF /* CCParticle3DRender.h in Headers */ = {isa = PBXBuildFile; fileRef = B68778F51A8CA82E00643ABF /* CCParticle3DRender.h */; };
+ B68779041A8CA82E00643ABF /* CCParticleSystem3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B68778F61A8CA82E00643ABF /* CCParticleSystem3D.cpp */; };
+ B68779051A8CA82E00643ABF /* CCParticleSystem3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B68778F61A8CA82E00643ABF /* CCParticleSystem3D.cpp */; };
+ B68779061A8CA82E00643ABF /* CCParticleSystem3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B68778F71A8CA82E00643ABF /* CCParticleSystem3D.h */; };
+ B68779071A8CA82E00643ABF /* CCParticleSystem3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B68778F71A8CA82E00643ABF /* CCParticleSystem3D.h */; };
+ B6CAAFE21AF9A9E100B9B856 /* CCPhysics3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFD21AF9A9E100B9B856 /* CCPhysics3D.cpp */; };
+ B6CAAFE31AF9A9E100B9B856 /* CCPhysics3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFD21AF9A9E100B9B856 /* CCPhysics3D.cpp */; };
+ B6CAAFE41AF9A9E100B9B856 /* CCPhysics3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFD31AF9A9E100B9B856 /* CCPhysics3D.h */; };
+ B6CAAFE51AF9A9E100B9B856 /* CCPhysics3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFD31AF9A9E100B9B856 /* CCPhysics3D.h */; };
+ B6CAAFE61AF9A9E100B9B856 /* CCPhysics3DComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFD41AF9A9E100B9B856 /* CCPhysics3DComponent.cpp */; };
+ B6CAAFE71AF9A9E100B9B856 /* CCPhysics3DComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFD41AF9A9E100B9B856 /* CCPhysics3DComponent.cpp */; };
+ B6CAAFE81AF9A9E100B9B856 /* CCPhysics3DComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFD51AF9A9E100B9B856 /* CCPhysics3DComponent.h */; };
+ B6CAAFE91AF9A9E100B9B856 /* CCPhysics3DComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFD51AF9A9E100B9B856 /* CCPhysics3DComponent.h */; };
+ B6CAAFEA1AF9A9E100B9B856 /* CCPhysics3DConstraint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFD61AF9A9E100B9B856 /* CCPhysics3DConstraint.cpp */; };
+ B6CAAFEB1AF9A9E100B9B856 /* CCPhysics3DConstraint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFD61AF9A9E100B9B856 /* CCPhysics3DConstraint.cpp */; };
+ B6CAAFEC1AF9A9E100B9B856 /* CCPhysics3DConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFD71AF9A9E100B9B856 /* CCPhysics3DConstraint.h */; };
+ B6CAAFED1AF9A9E100B9B856 /* CCPhysics3DConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFD71AF9A9E100B9B856 /* CCPhysics3DConstraint.h */; };
+ B6CAAFEE1AF9A9E100B9B856 /* CCPhysics3DDebugDrawer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFD81AF9A9E100B9B856 /* CCPhysics3DDebugDrawer.cpp */; };
+ B6CAAFEF1AF9A9E100B9B856 /* CCPhysics3DDebugDrawer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFD81AF9A9E100B9B856 /* CCPhysics3DDebugDrawer.cpp */; };
+ B6CAAFF01AF9A9E100B9B856 /* CCPhysics3DDebugDrawer.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFD91AF9A9E100B9B856 /* CCPhysics3DDebugDrawer.h */; };
+ B6CAAFF11AF9A9E100B9B856 /* CCPhysics3DDebugDrawer.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFD91AF9A9E100B9B856 /* CCPhysics3DDebugDrawer.h */; };
+ B6CAAFF21AF9A9E100B9B856 /* CCPhysics3DObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFDA1AF9A9E100B9B856 /* CCPhysics3DObject.cpp */; };
+ B6CAAFF31AF9A9E100B9B856 /* CCPhysics3DObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFDA1AF9A9E100B9B856 /* CCPhysics3DObject.cpp */; };
+ B6CAAFF41AF9A9E100B9B856 /* CCPhysics3DObject.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFDB1AF9A9E100B9B856 /* CCPhysics3DObject.h */; };
+ B6CAAFF51AF9A9E100B9B856 /* CCPhysics3DObject.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFDB1AF9A9E100B9B856 /* CCPhysics3DObject.h */; };
+ B6CAAFF61AF9A9E100B9B856 /* CCPhysics3DShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFDC1AF9A9E100B9B856 /* CCPhysics3DShape.cpp */; };
+ B6CAAFF71AF9A9E100B9B856 /* CCPhysics3DShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFDC1AF9A9E100B9B856 /* CCPhysics3DShape.cpp */; };
+ B6CAAFF81AF9A9E100B9B856 /* CCPhysics3DShape.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFDD1AF9A9E100B9B856 /* CCPhysics3DShape.h */; };
+ B6CAAFF91AF9A9E100B9B856 /* CCPhysics3DShape.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFDD1AF9A9E100B9B856 /* CCPhysics3DShape.h */; };
+ B6CAAFFA1AF9A9E100B9B856 /* CCPhysics3DWorld.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFDE1AF9A9E100B9B856 /* CCPhysics3DWorld.cpp */; };
+ B6CAAFFB1AF9A9E100B9B856 /* CCPhysics3DWorld.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFDE1AF9A9E100B9B856 /* CCPhysics3DWorld.cpp */; };
+ B6CAAFFC1AF9A9E100B9B856 /* CCPhysics3DWorld.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFDF1AF9A9E100B9B856 /* CCPhysics3DWorld.h */; };
+ B6CAAFFD1AF9A9E100B9B856 /* CCPhysics3DWorld.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFDF1AF9A9E100B9B856 /* CCPhysics3DWorld.h */; };
+ B6CAAFFE1AF9A9E100B9B856 /* CCPhysicsSprite3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFE01AF9A9E100B9B856 /* CCPhysicsSprite3D.cpp */; };
+ B6CAAFFF1AF9A9E100B9B856 /* CCPhysicsSprite3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6CAAFE01AF9A9E100B9B856 /* CCPhysicsSprite3D.cpp */; };
+ B6CAB0001AF9A9E100B9B856 /* CCPhysicsSprite3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFE11AF9A9E100B9B856 /* CCPhysicsSprite3D.h */; };
+ B6CAB0011AF9A9E100B9B856 /* CCPhysicsSprite3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6CAAFE11AF9A9E100B9B856 /* CCPhysicsSprite3D.h */; };
+ B6D38B8A1AC3AFAC00043997 /* CCSkybox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6D38B861AC3AFAC00043997 /* CCSkybox.cpp */; };
+ B6D38B8B1AC3AFAC00043997 /* CCSkybox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6D38B861AC3AFAC00043997 /* CCSkybox.cpp */; };
+ B6D38B8C1AC3AFAC00043997 /* CCSkybox.h in Headers */ = {isa = PBXBuildFile; fileRef = B6D38B871AC3AFAC00043997 /* CCSkybox.h */; };
+ B6D38B8D1AC3AFAC00043997 /* CCSkybox.h in Headers */ = {isa = PBXBuildFile; fileRef = B6D38B871AC3AFAC00043997 /* CCSkybox.h */; };
+ B6DD2FA71B04825B00E47F5F /* DebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F7A1B04825B00E47F5F /* DebugDraw.cpp */; };
+ B6DD2FA81B04825B00E47F5F /* DebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F7A1B04825B00E47F5F /* DebugDraw.cpp */; };
+ B6DD2FA91B04825B00E47F5F /* DebugDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F7B1B04825B00E47F5F /* DebugDraw.h */; };
+ B6DD2FAA1B04825B00E47F5F /* DebugDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F7B1B04825B00E47F5F /* DebugDraw.h */; };
+ B6DD2FAB1B04825B00E47F5F /* DetourDebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F7C1B04825B00E47F5F /* DetourDebugDraw.cpp */; };
+ B6DD2FAC1B04825B00E47F5F /* DetourDebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F7C1B04825B00E47F5F /* DetourDebugDraw.cpp */; };
+ B6DD2FAD1B04825B00E47F5F /* DetourDebugDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F7D1B04825B00E47F5F /* DetourDebugDraw.h */; };
+ B6DD2FAE1B04825B00E47F5F /* DetourDebugDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F7D1B04825B00E47F5F /* DetourDebugDraw.h */; };
+ B6DD2FAF1B04825B00E47F5F /* RecastDebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F7E1B04825B00E47F5F /* RecastDebugDraw.cpp */; };
+ B6DD2FB01B04825B00E47F5F /* RecastDebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F7E1B04825B00E47F5F /* RecastDebugDraw.cpp */; };
+ B6DD2FB11B04825B00E47F5F /* RecastDebugDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F7F1B04825B00E47F5F /* RecastDebugDraw.h */; };
+ B6DD2FB21B04825B00E47F5F /* RecastDebugDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F7F1B04825B00E47F5F /* RecastDebugDraw.h */; };
+ B6DD2FB31B04825B00E47F5F /* RecastDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F801B04825B00E47F5F /* RecastDump.cpp */; };
+ B6DD2FB41B04825B00E47F5F /* RecastDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F801B04825B00E47F5F /* RecastDump.cpp */; };
+ B6DD2FB51B04825B00E47F5F /* RecastDump.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F811B04825B00E47F5F /* RecastDump.h */; };
+ B6DD2FB61B04825B00E47F5F /* RecastDump.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F811B04825B00E47F5F /* RecastDump.h */; };
+ B6DD2FB71B04825B00E47F5F /* DetourAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F831B04825B00E47F5F /* DetourAlloc.cpp */; };
+ B6DD2FB81B04825B00E47F5F /* DetourAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F831B04825B00E47F5F /* DetourAlloc.cpp */; };
+ B6DD2FB91B04825B00E47F5F /* DetourAlloc.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F841B04825B00E47F5F /* DetourAlloc.h */; };
+ B6DD2FBA1B04825B00E47F5F /* DetourAlloc.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F841B04825B00E47F5F /* DetourAlloc.h */; };
+ B6DD2FBB1B04825B00E47F5F /* DetourAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F851B04825B00E47F5F /* DetourAssert.h */; };
+ B6DD2FBC1B04825B00E47F5F /* DetourAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F851B04825B00E47F5F /* DetourAssert.h */; };
+ B6DD2FBD1B04825B00E47F5F /* DetourCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F861B04825B00E47F5F /* DetourCommon.cpp */; };
+ B6DD2FBE1B04825B00E47F5F /* DetourCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F861B04825B00E47F5F /* DetourCommon.cpp */; };
+ B6DD2FBF1B04825B00E47F5F /* DetourCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F871B04825B00E47F5F /* DetourCommon.h */; };
+ B6DD2FC01B04825B00E47F5F /* DetourCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F871B04825B00E47F5F /* DetourCommon.h */; };
+ B6DD2FC11B04825B00E47F5F /* DetourMath.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F881B04825B00E47F5F /* DetourMath.h */; };
+ B6DD2FC21B04825B00E47F5F /* DetourMath.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F881B04825B00E47F5F /* DetourMath.h */; };
+ B6DD2FC31B04825B00E47F5F /* DetourNavMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F891B04825B00E47F5F /* DetourNavMesh.cpp */; };
+ B6DD2FC41B04825B00E47F5F /* DetourNavMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F891B04825B00E47F5F /* DetourNavMesh.cpp */; };
+ B6DD2FC51B04825B00E47F5F /* DetourNavMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F8A1B04825B00E47F5F /* DetourNavMesh.h */; };
+ B6DD2FC61B04825B00E47F5F /* DetourNavMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F8A1B04825B00E47F5F /* DetourNavMesh.h */; };
+ B6DD2FC71B04825B00E47F5F /* DetourNavMeshBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F8B1B04825B00E47F5F /* DetourNavMeshBuilder.cpp */; };
+ B6DD2FC81B04825B00E47F5F /* DetourNavMeshBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F8B1B04825B00E47F5F /* DetourNavMeshBuilder.cpp */; };
+ B6DD2FC91B04825B00E47F5F /* DetourNavMeshBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F8C1B04825B00E47F5F /* DetourNavMeshBuilder.h */; };
+ B6DD2FCA1B04825B00E47F5F /* DetourNavMeshBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F8C1B04825B00E47F5F /* DetourNavMeshBuilder.h */; };
+ B6DD2FCB1B04825B00E47F5F /* DetourNavMeshQuery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F8D1B04825B00E47F5F /* DetourNavMeshQuery.cpp */; };
+ B6DD2FCC1B04825B00E47F5F /* DetourNavMeshQuery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F8D1B04825B00E47F5F /* DetourNavMeshQuery.cpp */; };
+ B6DD2FCD1B04825B00E47F5F /* DetourNavMeshQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F8E1B04825B00E47F5F /* DetourNavMeshQuery.h */; };
+ B6DD2FCE1B04825B00E47F5F /* DetourNavMeshQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F8E1B04825B00E47F5F /* DetourNavMeshQuery.h */; };
+ B6DD2FCF1B04825B00E47F5F /* DetourNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F8F1B04825B00E47F5F /* DetourNode.cpp */; };
+ B6DD2FD01B04825B00E47F5F /* DetourNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F8F1B04825B00E47F5F /* DetourNode.cpp */; };
+ B6DD2FD11B04825B00E47F5F /* DetourNode.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F901B04825B00E47F5F /* DetourNode.h */; };
+ B6DD2FD21B04825B00E47F5F /* DetourNode.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F901B04825B00E47F5F /* DetourNode.h */; };
+ B6DD2FD31B04825B00E47F5F /* DetourStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F911B04825B00E47F5F /* DetourStatus.h */; };
+ B6DD2FD41B04825B00E47F5F /* DetourStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F911B04825B00E47F5F /* DetourStatus.h */; };
+ B6DD2FD51B04825B00E47F5F /* DetourCrowd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F931B04825B00E47F5F /* DetourCrowd.cpp */; };
+ B6DD2FD61B04825B00E47F5F /* DetourCrowd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F931B04825B00E47F5F /* DetourCrowd.cpp */; };
+ B6DD2FD71B04825B00E47F5F /* DetourCrowd.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F941B04825B00E47F5F /* DetourCrowd.h */; };
+ B6DD2FD81B04825B00E47F5F /* DetourCrowd.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F941B04825B00E47F5F /* DetourCrowd.h */; };
+ B6DD2FD91B04825B00E47F5F /* DetourLocalBoundary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F951B04825B00E47F5F /* DetourLocalBoundary.cpp */; };
+ B6DD2FDA1B04825B00E47F5F /* DetourLocalBoundary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F951B04825B00E47F5F /* DetourLocalBoundary.cpp */; };
+ B6DD2FDB1B04825B00E47F5F /* DetourLocalBoundary.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F961B04825B00E47F5F /* DetourLocalBoundary.h */; };
+ B6DD2FDC1B04825B00E47F5F /* DetourLocalBoundary.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F961B04825B00E47F5F /* DetourLocalBoundary.h */; };
+ B6DD2FDD1B04825B00E47F5F /* DetourObstacleAvoidance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F971B04825B00E47F5F /* DetourObstacleAvoidance.cpp */; };
+ B6DD2FDE1B04825B00E47F5F /* DetourObstacleAvoidance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F971B04825B00E47F5F /* DetourObstacleAvoidance.cpp */; };
+ B6DD2FDF1B04825B00E47F5F /* DetourObstacleAvoidance.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F981B04825B00E47F5F /* DetourObstacleAvoidance.h */; };
+ B6DD2FE01B04825B00E47F5F /* DetourObstacleAvoidance.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F981B04825B00E47F5F /* DetourObstacleAvoidance.h */; };
+ B6DD2FE11B04825B00E47F5F /* DetourPathCorridor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F991B04825B00E47F5F /* DetourPathCorridor.cpp */; };
+ B6DD2FE21B04825B00E47F5F /* DetourPathCorridor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F991B04825B00E47F5F /* DetourPathCorridor.cpp */; };
+ B6DD2FE31B04825B00E47F5F /* DetourPathCorridor.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F9A1B04825B00E47F5F /* DetourPathCorridor.h */; };
+ B6DD2FE41B04825B00E47F5F /* DetourPathCorridor.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F9A1B04825B00E47F5F /* DetourPathCorridor.h */; };
+ B6DD2FE51B04825B00E47F5F /* DetourPathQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F9B1B04825B00E47F5F /* DetourPathQueue.cpp */; };
+ B6DD2FE61B04825B00E47F5F /* DetourPathQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F9B1B04825B00E47F5F /* DetourPathQueue.cpp */; };
+ B6DD2FE71B04825B00E47F5F /* DetourPathQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F9C1B04825B00E47F5F /* DetourPathQueue.h */; };
+ B6DD2FE81B04825B00E47F5F /* DetourPathQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F9C1B04825B00E47F5F /* DetourPathQueue.h */; };
+ B6DD2FE91B04825B00E47F5F /* DetourProximityGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F9D1B04825B00E47F5F /* DetourProximityGrid.cpp */; };
+ B6DD2FEA1B04825B00E47F5F /* DetourProximityGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2F9D1B04825B00E47F5F /* DetourProximityGrid.cpp */; };
+ B6DD2FEB1B04825B00E47F5F /* DetourProximityGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F9E1B04825B00E47F5F /* DetourProximityGrid.h */; };
+ B6DD2FEC1B04825B00E47F5F /* DetourProximityGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2F9E1B04825B00E47F5F /* DetourProximityGrid.h */; };
+ B6DD2FED1B04825B00E47F5F /* DetourTileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2FA01B04825B00E47F5F /* DetourTileCache.cpp */; };
+ B6DD2FEE1B04825B00E47F5F /* DetourTileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2FA01B04825B00E47F5F /* DetourTileCache.cpp */; };
+ B6DD2FEF1B04825B00E47F5F /* DetourTileCache.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2FA11B04825B00E47F5F /* DetourTileCache.h */; };
+ B6DD2FF01B04825B00E47F5F /* DetourTileCache.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2FA11B04825B00E47F5F /* DetourTileCache.h */; };
+ B6DD2FF11B04825B00E47F5F /* DetourTileCacheBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2FA21B04825B00E47F5F /* DetourTileCacheBuilder.cpp */; };
+ B6DD2FF21B04825B00E47F5F /* DetourTileCacheBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2FA21B04825B00E47F5F /* DetourTileCacheBuilder.cpp */; };
+ B6DD2FF31B04825B00E47F5F /* DetourTileCacheBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2FA31B04825B00E47F5F /* DetourTileCacheBuilder.h */; };
+ B6DD2FF41B04825B00E47F5F /* DetourTileCacheBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2FA31B04825B00E47F5F /* DetourTileCacheBuilder.h */; };
+ B6DD2FF51B04825B00E47F5F /* fastlz.c in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2FA51B04825B00E47F5F /* fastlz.c */; };
+ B6DD2FF61B04825B00E47F5F /* fastlz.c in Sources */ = {isa = PBXBuildFile; fileRef = B6DD2FA51B04825B00E47F5F /* fastlz.c */; };
+ B6DD2FF71B04825B00E47F5F /* fastlz.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2FA61B04825B00E47F5F /* fastlz.h */; };
+ B6DD2FF81B04825B00E47F5F /* fastlz.h in Headers */ = {isa = PBXBuildFile; fileRef = B6DD2FA61B04825B00E47F5F /* fastlz.h */; };
+ BA6249A81E77D2850096291C /* tinydir.h in Headers */ = {isa = PBXBuildFile; fileRef = BA6249A71E77D2850096291C /* tinydir.h */; };
+ BA6249A91E77D2850096291C /* tinydir.h in Headers */ = {isa = PBXBuildFile; fileRef = BA6249A71E77D2850096291C /* tinydir.h */; };
+ BA6249AA1E77D2850096291C /* tinydir.h in Headers */ = {isa = PBXBuildFile; fileRef = BA6249A71E77D2850096291C /* tinydir.h */; };
+ C50306691B60B583001E6D43 /* CCBoneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306631B60B583001E6D43 /* CCBoneNode.cpp */; };
+ C503066A1B60B583001E6D43 /* CCBoneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306641B60B583001E6D43 /* CCBoneNode.h */; };
+ C503066B1B60B583001E6D43 /* CCSkeletonNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306651B60B583001E6D43 /* CCSkeletonNode.cpp */; };
+ C503066C1B60B583001E6D43 /* CCSkeletonNode.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306661B60B583001E6D43 /* CCSkeletonNode.h */; };
+ C503066D1B60B583001E6D43 /* CCSkinNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306671B60B583001E6D43 /* CCSkinNode.cpp */; };
+ C503066E1B60B583001E6D43 /* CCSkinNode.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306681B60B583001E6D43 /* CCSkinNode.h */; };
+ C50306751B60B5B2001E6D43 /* BoneNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306701B60B5B2001E6D43 /* BoneNodeReader.cpp */; };
+ C50306761B60B5B2001E6D43 /* BoneNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306711B60B5B2001E6D43 /* BoneNodeReader.h */; };
+ C50306771B60B5B2001E6D43 /* CSBoneBinary_generated.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306721B60B5B2001E6D43 /* CSBoneBinary_generated.h */; };
+ C50306781B60B5B2001E6D43 /* SkeletonNodeReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50306731B60B5B2001E6D43 /* SkeletonNodeReader.cpp */; };
+ C50306791B60B5B2001E6D43 /* SkeletonNodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = C50306741B60B5B2001E6D43 /* SkeletonNodeReader.h */; };
+ C5F516121C8216660013B695 /* UITabControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C5F516101C8216660013B695 /* UITabControl.cpp */; };
+ C5F516131C8216660013B695 /* UITabControl.h in Headers */ = {isa = PBXBuildFile; fileRef = C5F516111C8216660013B695 /* UITabControl.h */; };
+ C5F516181C8216C60013B695 /* CSTabControl_generated.h in Headers */ = {isa = PBXBuildFile; fileRef = C5F516151C8216C60013B695 /* CSTabControl_generated.h */; };
+ C5F516191C8216C60013B695 /* TabControlReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C5F516161C8216C60013B695 /* TabControlReader.cpp */; };
+ C5F5161A1C8216C60013B695 /* TabControlReader.h in Headers */ = {isa = PBXBuildFile; fileRef = C5F516171C8216C60013B695 /* TabControlReader.h */; };
+ C5F5161D1C822D400013B695 /* TabControlReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C5F516161C8216C60013B695 /* TabControlReader.cpp */; };
+ C5F5161E1C822D5B0013B695 /* TabControlReader.h in Headers */ = {isa = PBXBuildFile; fileRef = C5F516171C8216C60013B695 /* TabControlReader.h */; };
+ C5F5161F1C822D6D0013B695 /* UITabControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C5F516101C8216660013B695 /* UITabControl.cpp */; };
+ C5F516201C822D900013B695 /* UITabControl.h in Headers */ = {isa = PBXBuildFile; fileRef = C5F516111C8216660013B695 /* UITabControl.h */; };
+ C5F516211C822DED0013B695 /* UITabControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C5F516101C8216660013B695 /* UITabControl.cpp */; };
+ C5F516221C822E060013B695 /* TabControlReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C5F516161C8216C60013B695 /* TabControlReader.cpp */; };
+ C5F516231C822E190013B695 /* UITabControl.h in Headers */ = {isa = PBXBuildFile; fileRef = C5F516111C8216660013B695 /* UITabControl.h */; };
+ C5F516251C822E470013B695 /* TabControlReader.h in Headers */ = {isa = PBXBuildFile; fileRef = C5F516171C8216C60013B695 /* TabControlReader.h */; };
+ D0FD03491A3B51AA00825BB5 /* CCAllocatorBase.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD033B1A3B51AA00825BB5 /* CCAllocatorBase.h */; };
+ D0FD034A1A3B51AA00825BB5 /* CCAllocatorBase.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD033B1A3B51AA00825BB5 /* CCAllocatorBase.h */; };
+ D0FD034B1A3B51AA00825BB5 /* CCAllocatorDiagnostics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0FD033C1A3B51AA00825BB5 /* CCAllocatorDiagnostics.cpp */; };
+ D0FD034C1A3B51AA00825BB5 /* CCAllocatorDiagnostics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0FD033C1A3B51AA00825BB5 /* CCAllocatorDiagnostics.cpp */; };
+ D0FD034D1A3B51AA00825BB5 /* CCAllocatorDiagnostics.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD033D1A3B51AA00825BB5 /* CCAllocatorDiagnostics.h */; };
+ D0FD034E1A3B51AA00825BB5 /* CCAllocatorDiagnostics.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD033D1A3B51AA00825BB5 /* CCAllocatorDiagnostics.h */; };
+ D0FD034F1A3B51AA00825BB5 /* CCAllocatorGlobal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0FD033E1A3B51AA00825BB5 /* CCAllocatorGlobal.cpp */; };
+ D0FD03501A3B51AA00825BB5 /* CCAllocatorGlobal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0FD033E1A3B51AA00825BB5 /* CCAllocatorGlobal.cpp */; };
+ D0FD03511A3B51AA00825BB5 /* CCAllocatorGlobal.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD033F1A3B51AA00825BB5 /* CCAllocatorGlobal.h */; };
+ D0FD03521A3B51AA00825BB5 /* CCAllocatorGlobal.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD033F1A3B51AA00825BB5 /* CCAllocatorGlobal.h */; };
+ D0FD03531A3B51AA00825BB5 /* CCAllocatorGlobalNewDelete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0FD03401A3B51AA00825BB5 /* CCAllocatorGlobalNewDelete.cpp */; };
+ D0FD03541A3B51AA00825BB5 /* CCAllocatorGlobalNewDelete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0FD03401A3B51AA00825BB5 /* CCAllocatorGlobalNewDelete.cpp */; };
+ D0FD03551A3B51AA00825BB5 /* CCAllocatorMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03411A3B51AA00825BB5 /* CCAllocatorMacros.h */; };
+ D0FD03561A3B51AA00825BB5 /* CCAllocatorMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03411A3B51AA00825BB5 /* CCAllocatorMacros.h */; };
+ D0FD03571A3B51AA00825BB5 /* CCAllocatorMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03421A3B51AA00825BB5 /* CCAllocatorMutex.h */; };
+ D0FD03581A3B51AA00825BB5 /* CCAllocatorMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03421A3B51AA00825BB5 /* CCAllocatorMutex.h */; };
+ D0FD03591A3B51AA00825BB5 /* CCAllocatorStrategyDefault.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03431A3B51AA00825BB5 /* CCAllocatorStrategyDefault.h */; };
+ D0FD035A1A3B51AA00825BB5 /* CCAllocatorStrategyDefault.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03431A3B51AA00825BB5 /* CCAllocatorStrategyDefault.h */; };
+ D0FD035B1A3B51AA00825BB5 /* CCAllocatorStrategyFixedBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03441A3B51AA00825BB5 /* CCAllocatorStrategyFixedBlock.h */; };
+ D0FD035C1A3B51AA00825BB5 /* CCAllocatorStrategyFixedBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03441A3B51AA00825BB5 /* CCAllocatorStrategyFixedBlock.h */; };
+ D0FD035D1A3B51AA00825BB5 /* CCAllocatorStrategyGlobalSmallBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03451A3B51AA00825BB5 /* CCAllocatorStrategyGlobalSmallBlock.h */; };
+ D0FD035E1A3B51AA00825BB5 /* CCAllocatorStrategyGlobalSmallBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03451A3B51AA00825BB5 /* CCAllocatorStrategyGlobalSmallBlock.h */; };
+ D0FD035F1A3B51AA00825BB5 /* CCAllocatorStrategyPool.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03461A3B51AA00825BB5 /* CCAllocatorStrategyPool.h */; };
+ D0FD03601A3B51AA00825BB5 /* CCAllocatorStrategyPool.h in Headers */ = {isa = PBXBuildFile; fileRef = D0FD03461A3B51AA00825BB5 /* CCAllocatorStrategyPool.h */; };
+ DA8C62A219E52C6400000516 /* ioapi_mem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA8C62A019E52C6400000516 /* ioapi_mem.cpp */; };
+ DA8C62A319E52C6400000516 /* ioapi_mem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DA8C62A019E52C6400000516 /* ioapi_mem.cpp */; };
+ DA8C62A419E52C6400000516 /* ioapi_mem.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8C62A119E52C6400000516 /* ioapi_mem.h */; };
+ DA8C62A519E52C6400000516 /* ioapi_mem.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8C62A119E52C6400000516 /* ioapi_mem.h */; };
+ DABC9FA919E7DFA900FA252C /* CCClippingRectangleNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DABC9FA719E7DFA900FA252C /* CCClippingRectangleNode.cpp */; };
+ DABC9FAA19E7DFA900FA252C /* CCClippingRectangleNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DABC9FA719E7DFA900FA252C /* CCClippingRectangleNode.cpp */; };
+ DABC9FAB19E7DFA900FA252C /* CCClippingRectangleNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DABC9FA819E7DFA900FA252C /* CCClippingRectangleNode.h */; };
+ DABC9FAC19E7DFA900FA252C /* CCClippingRectangleNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DABC9FA819E7DFA900FA252C /* CCClippingRectangleNode.h */; };
+ ED682BBA213F5FC7001BF6CB /* libuv_a.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ED682BB9213F5FC6001BF6CB /* libuv_a.a */; };
+ ED682BC1213F63CB001BF6CB /* libuv_a.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ED682BC0213F63CB001BF6CB /* libuv_a.a */; };
+ ED682BC3213F6C7A001BF6CB /* libwebsockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ED682BC2213F6C7A001BF6CB /* libwebsockets.a */; };
+ ED682BC5213F6CBF001BF6CB /* libuv_a.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ED682BC4213F6CBE001BF6CB /* libuv_a.a */; };
+ ED74D7691A5B8A2600157FD4 /* CCPhysicsHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = ED74D7681A5B8A2600157FD4 /* CCPhysicsHelper.h */; };
+ ED74D76A1A5B8A2600157FD4 /* CCPhysicsHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = ED74D7681A5B8A2600157FD4 /* CCPhysicsHelper.h */; };
+ ED9C6A9418599AD8000A5232 /* CCNodeGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9C6A9218599AD8000A5232 /* CCNodeGrid.cpp */; };
+ ED9C6A9518599AD8000A5232 /* CCNodeGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9C6A9218599AD8000A5232 /* CCNodeGrid.cpp */; };
+ ED9C6A9618599AD8000A5232 /* CCNodeGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9C6A9318599AD8000A5232 /* CCNodeGrid.h */; };
+ ED9C6A9718599AD8000A5232 /* CCNodeGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9C6A9318599AD8000A5232 /* CCNodeGrid.h */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 0634A4C5194B19E400E608AF /* CCActionTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCActionTimeline.cpp; sourceTree = ""; };
+ 0634A4C6194B19E400E608AF /* CCActionTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCActionTimeline.h; sourceTree = ""; };
+ 0634A4C7194B19E400E608AF /* CCActionTimelineCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCActionTimelineCache.cpp; sourceTree = ""; };
+ 0634A4C8194B19E400E608AF /* CCActionTimelineCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCActionTimelineCache.h; sourceTree = ""; };
+ 0634A4C9194B19E400E608AF /* CCFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCFrame.cpp; sourceTree = ""; };
+ 0634A4CA194B19E400E608AF /* CCFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCFrame.h; sourceTree = ""; };
+ 0634A4CD194B19E400E608AF /* CCTimeLine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCTimeLine.cpp; sourceTree = ""; };
+ 0634A4CE194B19E400E608AF /* CCTimeLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCTimeLine.h; sourceTree = ""; };
+ 0634A4CF194B19E400E608AF /* CCTimelineMacro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCTimelineMacro.h; sourceTree = ""; };
+ 06CAAABC186AD63B0012A414 /* TriggerBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TriggerBase.cpp; sourceTree = ""; };
+ 06CAAABD186AD63B0012A414 /* TriggerBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TriggerBase.h; sourceTree = ""; };
+ 06CAAABE186AD63B0012A414 /* TriggerMng.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TriggerMng.cpp; sourceTree = ""; };
+ 06CAAABF186AD63B0012A414 /* TriggerMng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TriggerMng.h; sourceTree = ""; };
+ 06CAAAC0186AD63B0012A414 /* TriggerObj.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TriggerObj.cpp; sourceTree = ""; };
+ 06CAAAC1186AD63B0012A414 /* TriggerObj.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TriggerObj.h; sourceTree = ""; };
+ 0C261F261BE7528900707478 /* Light3DReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Light3DReader.cpp; sourceTree = ""; };
+ 0C261F271BE7528900707478 /* Light3DReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Light3DReader.h; sourceTree = ""; };
+ 1551A33F158F2AB200E66CFE /* libcocos2d Mac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libcocos2d Mac.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1551A342158F2AB200E66CFE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 15AE17E419AAD2F700C27E9E /* CCAABB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCAABB.cpp; sourceTree = ""; };
+ 15AE17E519AAD2F700C27E9E /* CCAABB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCAABB.h; sourceTree = ""; };
+ 15AE17E619AAD2F700C27E9E /* CCAnimate3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCAnimate3D.cpp; sourceTree = ""; };
+ 15AE17E719AAD2F700C27E9E /* CCAnimate3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCAnimate3D.h; sourceTree = ""; };
+ 15AE17E819AAD2F700C27E9E /* CCAnimation3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCAnimation3D.cpp; sourceTree = ""; };
+ 15AE17E919AAD2F700C27E9E /* CCAnimation3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCAnimation3D.h; sourceTree = ""; };
+ 15AE17EA19AAD2F700C27E9E /* CCAnimationCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCAnimationCurve.h; sourceTree = ""; };
+ 15AE17EB19AAD2F700C27E9E /* CCAnimationCurve.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CCAnimationCurve.inl; sourceTree = ""; };
+ 15AE17EC19AAD2F700C27E9E /* CCAttachNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCAttachNode.cpp; sourceTree = ""; };
+ 15AE17ED19AAD2F700C27E9E /* CCAttachNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCAttachNode.h; sourceTree = ""; };
+ 15AE17EE19AAD2F700C27E9E /* CCBundle3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCBundle3D.cpp; sourceTree = ""; };
+ 15AE17EF19AAD2F700C27E9E /* CCBundle3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCBundle3D.h; sourceTree = ""; };
+ 15AE17F019AAD2F700C27E9E /* CCBundle3DData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCBundle3DData.h; sourceTree = ""; };
+ 15AE17F119AAD2F700C27E9E /* CCBundleReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCBundleReader.cpp; sourceTree = ""; };
+ 15AE17F219AAD2F700C27E9E /* CCBundleReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCBundleReader.h; sourceTree = ""; };
+ 15AE17F319AAD2F700C27E9E /* CCMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCMesh.cpp; sourceTree = ""; };
+ 15AE17F419AAD2F700C27E9E /* CCMesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCMesh.h; sourceTree = ""; };
+ 15AE17F519AAD2F700C27E9E /* CCMeshSkin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCMeshSkin.cpp; sourceTree = ""; };
+ 15AE17F619AAD2F700C27E9E /* CCMeshSkin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCMeshSkin.h; sourceTree = ""; };
+ 15AE17F719AAD2F700C27E9E /* CCMeshVertexIndexData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCMeshVertexIndexData.cpp; sourceTree = ""; };
+ 15AE17F819AAD2F700C27E9E /* CCMeshVertexIndexData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCMeshVertexIndexData.h; sourceTree = ""; };
+ 15AE17F919AAD2F700C27E9E /* CCOBB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCOBB.cpp; sourceTree = ""; };
+ 15AE17FA19AAD2F700C27E9E /* CCOBB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCOBB.h; sourceTree = ""; };
+ 15AE17FB19AAD2F700C27E9E /* CCObjLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCObjLoader.cpp; sourceTree = ""; };
+ 15AE17FC19AAD2F700C27E9E /* CCObjLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCObjLoader.h; sourceTree = ""; };
+ 15AE17FD19AAD2F700C27E9E /* CCRay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCRay.cpp; sourceTree = ""; };
+ 15AE17FE19AAD2F700C27E9E /* CCRay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCRay.h; sourceTree = ""; };
+ 15AE17FF19AAD2F700C27E9E /* CCSkeleton3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCSkeleton3D.cpp; sourceTree = ""; };
+ 15AE180019AAD2F700C27E9E /* CCSkeleton3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSkeleton3D.h; sourceTree = ""; };
+ 15AE180119AAD2F700C27E9E /* CCSprite3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCSprite3D.cpp; sourceTree = ""; };
+ 15AE180219AAD2F700C27E9E /* CCSprite3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSprite3D.h; sourceTree = ""; };
+ 15AE180319AAD2F700C27E9E /* CCSprite3DMaterial.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCSprite3DMaterial.cpp; sourceTree = ""; };
+ 15AE180419AAD2F700C27E9E /* CCSprite3DMaterial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSprite3DMaterial.h; sourceTree = ""; };
+ 15AE180519AAD2F700C27E9E /* cocos3d.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocos3d.h; sourceTree = ""; };
+ 15B3706E19EE414C00ABE682 /* AssetsManagerEx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AssetsManagerEx.cpp; sourceTree = ""; };
+ 15B3706F19EE414C00ABE682 /* AssetsManagerEx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssetsManagerEx.h; sourceTree = ""; };
+ 15B3707019EE414C00ABE682 /* CCEventAssetsManagerEx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCEventAssetsManagerEx.cpp; sourceTree = ""; };
+ 15B3707119EE414C00ABE682 /* CCEventAssetsManagerEx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCEventAssetsManagerEx.h; sourceTree = ""; };
+ 15B3707219EE414C00ABE682 /* CCEventListenerAssetsManagerEx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCEventListenerAssetsManagerEx.cpp; sourceTree = ""; };
+ 15B3707319EE414C00ABE682 /* CCEventListenerAssetsManagerEx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCEventListenerAssetsManagerEx.h; sourceTree = ""; };
+ 15B3707619EE414C00ABE682 /* Manifest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Manifest.cpp; sourceTree = ""; };
+ 15B3707719EE414C00ABE682 /* Manifest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Manifest.h; sourceTree = ""; };
+ 15EFA20F198A2BB5000C57D3 /* CCProtectedNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCProtectedNode.cpp; sourceTree = ""; };
+ 15EFA210198A2BB5000C57D3 /* CCProtectedNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCProtectedNode.h; sourceTree = ""; };
+ 15FB20721AE7BF8600C31518 /* CCAutoPolygon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCAutoPolygon.cpp; sourceTree = ""; };
+ 15FB20731AE7BF8600C31518 /* CCAutoPolygon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCAutoPolygon.h; sourceTree = ""; };
+ 15FB207A1AE7C57D00C31518 /* shapes.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shapes.cc; sourceTree = ""; };
+ 15FB207B1AE7C57D00C31518 /* shapes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shapes.h; sourceTree = ""; };
+ 15FB207C1AE7C57D00C31518 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = ""; };
+ 15FB207D1AE7C57D00C31518 /* poly2tri.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = poly2tri.h; sourceTree = ""; };
+ 15FB207F1AE7C57D00C31518 /* advancing_front.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = advancing_front.cc; sourceTree = ""; };
+ 15FB20801AE7C57D00C31518 /* advancing_front.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = advancing_front.h; sourceTree = ""; };
+ 15FB20811AE7C57D00C31518 /* cdt.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cdt.cc; sourceTree = ""; };
+ 15FB20821AE7C57D00C31518 /* cdt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cdt.h; sourceTree = ""; };
+ 15FB20831AE7C57D00C31518 /* sweep.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sweep.cc; sourceTree = ""; };
+ 15FB20841AE7C57D00C31518 /* sweep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sweep.h; sourceTree = ""; };
+ 15FB20851AE7C57D00C31518 /* sweep_context.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sweep_context.cc; sourceTree = ""; };
+ 15FB20861AE7C57D00C31518 /* sweep_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sweep_context.h; sourceTree = ""; };
+ 182C5CAD1A95961600C30D34 /* CSParse3DBinary_generated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSParse3DBinary_generated.h; sourceTree = ""; };
+ 182C5CB01A95964700C30D34 /* Node3DReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Node3DReader.cpp; path = Node3DReader/Node3DReader.cpp; sourceTree = ""; };
+ 182C5CB11A95964700C30D34 /* Node3DReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Node3DReader.h; path = Node3DReader/Node3DReader.h; sourceTree = ""; };
+ 182C5CD41A98F30500C30D34 /* Sprite3DReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sprite3DReader.cpp; path = Sprite3DReader/Sprite3DReader.cpp; sourceTree = ""; };
+ 182C5CD51A98F30500C30D34 /* Sprite3DReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Sprite3DReader.h; path = Sprite3DReader/Sprite3DReader.h; sourceTree = ""; };
+ 182C5CE31A9D725400C30D34 /* UserCameraReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UserCameraReader.cpp; path = UserCameraReader/UserCameraReader.cpp; sourceTree = ""; };
+ 182C5CE41A9D725400C30D34 /* UserCameraReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UserCameraReader.h; path = UserCameraReader/UserCameraReader.h; sourceTree = ""; };
+ 18956BB01A9DFBFD006E9155 /* Particle3DReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Particle3DReader.cpp; path = Particle3DReader/Particle3DReader.cpp; sourceTree = ""; };
+ 18956BB11A9DFBFD006E9155 /* Particle3DReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Particle3DReader.h; path = Particle3DReader/Particle3DReader.h; sourceTree = ""; };
+ 1A01C67618F57BE800EFE3A6 /* CCArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCArray.cpp; sourceTree = ""; };
+ 1A01C67718F57BE800EFE3A6 /* CCArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCArray.h; sourceTree = ""; };
+ 1A01C67818F57BE800EFE3A6 /* CCBool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCBool.h; sourceTree = ""; };
+ 1A01C67918F57BE800EFE3A6 /* CCDeprecated.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCDeprecated.cpp; sourceTree = ""; };
+ 1A01C67A18F57BE800EFE3A6 /* CCDeprecated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCDeprecated.h; sourceTree = ""; };
+ 1A01C67B18F57BE800EFE3A6 /* CCDictionary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCDictionary.cpp; sourceTree = ""; };
+ 1A01C67C18F57BE800EFE3A6 /* CCDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCDictionary.h; sourceTree = ""; };
+ 1A01C67D18F57BE800EFE3A6 /* CCDouble.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCDouble.h; sourceTree = ""; };
+ 1A01C67E18F57BE800EFE3A6 /* CCFloat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCFloat.h; sourceTree = ""; };
+ 1A01C67F18F57BE800EFE3A6 /* CCInteger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCInteger.h; sourceTree = ""; };
+ 1A01C68018F57BE800EFE3A6 /* CCSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCSet.cpp; sourceTree = ""; };
+ 1A01C68118F57BE800EFE3A6 /* CCSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSet.h; sourceTree = ""; };
+ 1A01C68218F57BE800EFE3A6 /* CCString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCString.cpp; sourceTree = ""; };
+ 1A01C68318F57BE800EFE3A6 /* CCString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCString.h; sourceTree = ""; };
+ 1A01C6A218F58F7500EFE3A6 /* CCNotificationCenter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCNotificationCenter.cpp; sourceTree = ""; };
+ 1A01C6A318F58F7500EFE3A6 /* CCNotificationCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCNotificationCenter.h; sourceTree = ""; };
+ 1A087AE61860400400196EF5 /* edtaa3func.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = edtaa3func.cpp; sourceTree = ""; };
+ 1A087AE71860400400196EF5 /* edtaa3func.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = edtaa3func.h; sourceTree = ""; };
+ 1A1645AE191B726C008C7C7F /* ConvertUTF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ConvertUTF.c; sourceTree = ""; };
+ 1A1645AF191B726C008C7C7F /* ConvertUTFWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConvertUTFWrapper.cpp; sourceTree = ""; };
+ 1A2B22AF1E6E54D6001D5EC9 /* Uri.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Uri.h; sourceTree = ""; };
+ 1A2B22B11E6E54EC001D5EC9 /* Uri.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Uri.cpp; sourceTree = ""; };
+ 1A40D0DA1E8E4C76002E363A /* md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = md5.c; sourceTree = ""; };
+ 1A40D0DB1E8E4C76002E363A /* md5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = md5.h; sourceTree = ""; };
+ 1A40D0E21E8E56C6002E363A /* allocators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = allocators.h; sourceTree = ""; };
+ 1A40D0E31E8E56C6002E363A /* document-wrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "document-wrapper.h"; sourceTree = ""; };
+ 1A40D0E41E8E56C6002E363A /* document.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = document.h; sourceTree = ""; };
+ 1A40D0E51E8E56C6002E363A /* encodedstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = encodedstream.h; sourceTree = ""; };
+ 1A40D0E61E8E56C6002E363A /* encodings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = encodings.h; sourceTree = ""; };
+ 1A40D0E81E8E56C6002E363A /* en.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = en.h; sourceTree = ""; };
+ 1A40D0E91E8E56C6002E363A /* error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = error.h; sourceTree = ""; };
+ 1A40D0EA1E8E56C6002E363A /* filereadstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = filereadstream.h; sourceTree = ""; };
+ 1A40D0EB1E8E56C6002E363A /* filewritestream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = filewritestream.h; sourceTree = ""; };
+ 1A40D0EC1E8E56C6002E363A /* fwd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fwd.h; sourceTree = ""; };
+ 1A40D0EE1E8E56C6002E363A /* biginteger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = biginteger.h; sourceTree = ""; };
+ 1A40D0EF1E8E56C6002E363A /* diyfp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = diyfp.h; sourceTree = ""; };
+ 1A40D0F01E8E56C6002E363A /* dtoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dtoa.h; sourceTree = ""; };
+ 1A40D0F11E8E56C6002E363A /* ieee754.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ieee754.h; sourceTree = ""; };
+ 1A40D0F21E8E56C6002E363A /* itoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = itoa.h; sourceTree = ""; };
+ 1A40D0F31E8E56C6002E363A /* meta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = meta.h; sourceTree = ""; };
+ 1A40D0F41E8E56C6002E363A /* pow10.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pow10.h; sourceTree = ""; };
+ 1A40D0F51E8E56C6002E363A /* regex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regex.h; sourceTree = ""; };
+ 1A40D0F61E8E56C6002E363A /* stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stack.h; sourceTree = ""; };
+ 1A40D0F71E8E56C6002E363A /* strfunc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strfunc.h; sourceTree = ""; };
+ 1A40D0F81E8E56C6002E363A /* strtod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strtod.h; sourceTree = ""; };
+ 1A40D0F91E8E56C6002E363A /* swap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = swap.h; sourceTree = ""; };
+ 1A40D0FA1E8E56C6002E363A /* istreamwrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = istreamwrapper.h; sourceTree = ""; };
+ 1A40D0FB1E8E56C6002E363A /* memorybuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memorybuffer.h; sourceTree = ""; };
+ 1A40D0FC1E8E56C6002E363A /* memorystream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memorystream.h; sourceTree = ""; };
+ 1A40D1001E8E56C6002E363A /* ostreamwrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ostreamwrapper.h; sourceTree = ""; };
+ 1A40D1011E8E56C6002E363A /* pointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pointer.h; sourceTree = ""; };
+ 1A40D1021E8E56C6002E363A /* prettywriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = prettywriter.h; sourceTree = ""; };
+ 1A40D1031E8E56C6002E363A /* rapidjson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rapidjson.h; sourceTree = ""; };
+ 1A40D1041E8E56C6002E363A /* reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reader.h; sourceTree = ""; };
+ 1A40D1051E8E56C6002E363A /* schema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = schema.h; sourceTree = "