| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129 |
- // Learn cc.Class:
- // - [Chinese] http://www.cocos.com/docs/creator/scripting/class.html
- // - [English] http://www.cocos2d-x.org/docs/editors_and_tools/creator-chapters/scripting/class/index.html
- // Learn Attribute:
- // - [Chinese] http://www.cocos.com/docs/creator/scripting/reference/attributes.html
- // - [English] http://www.cocos2d-x.org/docs/editors_and_tools/creator-chapters/scripting/reference/attributes/index.html
- // Learn life-cycle callbacks:
- // - [Chinese] http://www.cocos.com/docs/creator/scripting/life-cycle-callbacks.html
- // - [English] http://www.cocos2d-x.org/docs/editors_and_tools/creator-chapters/scripting/life-cycle-callbacks/index.html
- const OFFLINE_TIPS = 'data:image/png;base64,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';
- const RECONNECT_BTN = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAAAzCAMAAABCDgGNAAAAZlBMVEUAAAAAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOXHNmdXAAAAIXRSTlMACH8P7PjcBPG0YFYl4NXQyr6rd2lbQjkzGpTlIHr5jJUXB7SdAAABgUlEQVRYw8zVx27CUBCF4XOLKwaXuAKG/O//kpGFnEhAkp19v9XsRjqaolemt015SdlAeikb2xv9y3RZxMairDP6i7OeXXjr9KvWszh95sPktAE3Dfn5xMK3eq+oAI620MYKewSo3jY+pECcJ9pBksdAetCLDyCyRjsxNgI+9OQOxKN2NMbA/TWr2mlXrn7O6wBkRjszGXDQtyKCOtHukhrSQqsKYqcAuBiqNZ8WbqOCMN6glRbOg1UgLHinxQzx7uO+MjHMWgoPnYLRgTeP43AMYAtXyfFxJDKYFZAZMslEcFVArhAZ9XBSUE7Qy8JZQTmDVQO5gpJDoxIGBWWAUh4mBWWCi24QxJf+4SAVoMB8VWfHKAACMRBFw8KC1qYSm7n/Ja3E0k6fV1g2ycz/SdTXQv8WOono3kK3PHoT0QTB5a0tWd10imb5GlrzGXJPrE6m0qpn0jaDUIkNyreqBkkDVXaqkmaVy98W4/U8cVwW48H57B84n6X/ZshUn8jY1xND+YFI77v8MAAAAABJRU5ErkJggg==';
- const PANEL = 'data:image/png;base64,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';
- const BAR = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAFklEQVQImWOcPHnyfwYcgAmXxKCUBAAm8ALGxCtPnQAAAABJRU5ErkJggg==';
- const CIRCLE = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJQAAACXCAYAAADzqHJ6AAAgAElEQVR4Xu2dDXhU5Zn3c77nIyGMhJo3IXxrxcC6u11WtvbypaBUXrBelsV1LbZbywq8JGAaSIhESTR8BAgIgRew1K6VtbqWeqnQWlTK61t3ZW23ZTVolS/Jx4YSnIRkPs73e/3PzjPXyeRMZpLMTE7g5LrmmjMzZ855nvv8ct//+36e8wyV5fzBAlSKzKCn6Dgj9jCpMuRIMUC0vzU1NdHtpqamXnYoLi5Oyi5NTU29ACouLo6+rqmpMX923YCWlOFGCi0W7ewFEAGHANPW1mZ87vf7qfz8/Oi+3d3dSdklJycnCkp7e7vu8/mM1wUFBcYzAQ6gXS+AJWW4EQRUXIAADwEHwPh8PmPfQCBAhUIhKicnx3gdDoeNZ6/X269tAoGAAY3L5TKeu7u7dbfbrXu9XuO13+/XARwBDZBdD4BdK0AZ/UAYgxeCB7ICqKOjgwY4gAbAdHd30263m5IkiXK5XMYxZFmm8CD/RIIg9LKRKIpRr8RxnI5HBESd53k9FAoBJA3AATaAlpeXp8UDLMZ7jfjQOJKBiguR1+ul4YEIQAzD0AQemqZpAJObm8t+61vfmlBUVHSz2+2eyPN8EcuyBQzDjKEoykfTtI+iKCErK4uhKCob0Oi63pOVlaXqui5qmubXdd2vquoVRVHaJElqDoVCF5qbmz/9+c9//nlXV5cC2DRN0whkqqpqZsACgYCGMEm817UA10gEqg9ITU1NNDQQy7I0IOI4jsY2QMJfMBikH3nkkfFTp06dlZOTM1MQhNsYhrmJoihvOsK5rusBVVU/E0XxVHd392/PnDnzb88999xFj8cDvjSApSiKJsuyBu+FbYTG4uJiDWFxJIM1koDqBZLP56MFQYDnoXiepxVFYQCRqqoMQJo1a9aoefPm3XnDDTfMEQRhNk3TRemAJ9ljaprWLIriiS+++OL4sWPH3n3//fevAiyGYVQCF7ahu0RRRIjURiJYIwGoKEhZWVk0tBFAIt5o9OjRDGACSDNnzsxZuHDhPT6f716e579OUZQr2Queyf10XQ9LknTC7/e/fuTIkTc/+OCDbsDEsqza2dmpEq8FsCIZo2bKEm2ts+wMVFyQRFGMQqRpGlNRUfGXEyZMeNjlct1H9E4mARnKuaDLwuHwa59//vkLW7du/Q+apuFiDbgEQTC810gCy45AWYY2eCQCEsdxbF5enrB8+fL78vLylrMs+2dDuah2+a6iKP/Z0dGxf//+/a91dHSIsiwrsWDZPRTaDSjKnPpDbI8bN44xgzR+/Hj397///e/6fL7lNE2PswsMqWyHpmktfr9///PPP/+Tc+fOBc1gtbS0qBbi3TZh0C5A9QpvAAmpP3QRNFIwGGTHjRvnKi0tXeLz+VbTNF2Qygto12Npmtbm9/t3NTY2HmppaQl7PB4FGgshESUHgJWVlWUrfWUHoKJeiWRuxCMJgsCGw2F2w4YNdxcWFtawLHuTXS9+OtulKMpnra2tNbW1tW+5XC5FFMVoKLTICIfVWw03UFGYUEAkXsntdrNZWVncd7/73UkzZ87cwnHcnHResJFybFmWj3/wwQfrnn/++fMo6odCIYV4KxRcTWWGYYNquIDqE+Kglbq6ulh4pezsbGHdunXLfD7f2nQVH0cKRLHt1HU96Pf7t27ZsuVAT0+PSLyV3+9X7BAChwOoPiGus7OThVdC9rZ48eLJX/3qV/8Px3F/NVIveibaLcvyb0+ePFny0ksvnYFoh7caPXo0wmFsUTSj3irTQPWCSZIkxuPxsBDdFEVxmzdvfvBLX/rSppFWS8oEQFbnQA3rT3/60/qqqqqf6rouQ7QHg0GF53k1pryQMagyCZQBE6rdpByAEAeQbr31Vu+yZcvqvV7v3w/XxRnJ5w0EAi8dOHCg4vTp0wGAlZubq6C8MBy6KlNA9YLJ5/MZWknTNA4j/nfeeedzLMveNpIv6nC3XVGUU+++++4jmOmACRXQVha6Ku2eKhNARWG6cuWKUaREBofHqlWrvjJt2rSf0DT9peG+INfC+TVNu/zxxx8/vHv37t8hC8QDwzdjxoyBtyL1qrRClW6g4sK0fv36/1VUVLSPoijPtXAx7dIHZIHNzc0rNm7c+IvhgCqdQPWCiWRysizzmzdv/vaNN964HbUnu1yIa6wd6qVLl8qqqqpe4jhOIhlgJjxVuoCKC9O2bduWjhkzZmMKb126xlhIWXe0y5cvP15ZWflcJqFKB1B9BDj0EjxTfX39P44dO7bOgSll0CQ6kH758uXqysrKHwIqhMB0C/VUA9VrKAXZHIEpEuZ2ODAlYiDln+uXLl36QVVV1T+boUpXSSGVQBnHWrx4MQ1thKEURVE4URT56urqe4uKin7oaKaUw5LsAdXm5uZ/rKure0MQBIllWZnUqV555RXMWMBfSrK/lAIFmDBjwOv1sihaut1ufuXKlbNuueWWVyiKcifbe2e/1FtA1/XQJ598snjv3r3vh0IhCcXPQCCAWpUWgcpWQEV104ULF1iapjlUwB966KGJs2fPPkrTdH7qTeQccaAW0DTtv06cOLHwxRdfvICKuqZp8sSJE5VU1qhS4aH6ZHTZ2dn8hAkTcsrLy193KuADvezp3R8V9fr6+ntbW1t7enp6JAwop7KcMFSgeukmiHBJkniXy8Vv3759l9frfTC95nGOPhgLYOxvzZo1q8PhsMTzvITMDyI9FXpqyECZdRNEeE9Pj1BXV/f3BQUFuwbTWec7mbFAW1vb6urq6p9mZ2eLEOmp0lNDAaqXbsI0FNy6/eCDD06944473namoGQGjMGeBVNfTpw4cdfhw4fP4NZ6THtJhZ4aLFC9Qp3L5eKgm3Jyctx1dXWvcxz3lcF21Ple5iwgy/Lvqqurv9nd3R2CngqHwxhQHlLoGzRQmNvU1taGeeAsCXVbt25dmZeXtyFzJnHONFQLdHR01FZUVOw1h76CggI1cqfygEsJgwGqV1anqipKBMKiRYumzp49+x1nDvhQL3Fmv4+FPU6cODGXhD6GYeShZH2DAopUw0lWx7KssGfPnhcFQXDuTsksDyk5myiKx0tKSh5SFEW0yPoG5KUGClSfAiZgqqys/MbkyZMPpaR3zkGGxQLnzp1bUl9f/ytANZSC54CBIt6JCPEbb7zRW11dfYJhmCnDYgnnpCmxgKqqZ+vq6mZfunQpYCHQk/ZSAwHK8E6xQry+vv6RsWPHbklJr5yDDKsFLl++vA7zp4Yi0AcElNk78TwvTJ06dVRFRcV718taA8N6tTNwcoz1bd269atnzpy5KkmSGFNGSMpLJQuUpXfaunXr8ry8vKcy0FfnFBmyQEdHx5MVFRX7B+ulkgYq1jvl5+d7n3rqqfcd75ShK52h02DFlyeffHJWe3t7YDBeKhmgemV2OTk5PMbramtrFxcVFe3NUD+d02TQAs3Nzf97w4YNP4OX6u7ulgYyJJMUULGZnaqqrr179x5jWXZ6BvvpnCpDFlAU5aOVK1fOYxgmPNCMLyFQNTU1mNJLk4lzqDuVlpbOmj59+hsZ6p9zmmGwwB/+8IeF+/btO2lRlyJThi1blQioqBjHzQaY6wSgdu7cuTM7O9tZh2AYLnSmTtnT0/PTsrKyMlI9xx0zyYzxJQQK4S4/P58lY3YzZsy44dFHH/29M2aXqUs7POfBGN+zzz77Fx9++OEXmN6CMb729nYl0fzz/oByxPjwXEvbnLWlpaX0ySeffHkg4jwhUKiMI9wxDCNgVkFDQ8OPXS7XPbbptdOQtFkgHA7/qry8/B/goVRVFZMJe/0CFRvubrvttjFLly79z8iP6qStI86B7WEBgHTw4ME/O3Xq1JVkw15coMzZHWpPsiy7qqqq7hs/fvyz9uiu04pMWODixYuPbt68+TWO48IxNSnLbC8eUH2yO4/H46qvr9+enZ397Ux0xDmHPSzQ09Pzz5WVlWuCwWAYc6UShb24QJFi5tixY3ncTs5xnHvPnj0nGYYptEdXnVZkwgKqqraWlJTcLstyCLexX758GVCReed9Boz781CMuZj5wAMP3DR37tx/zUQnnHPYywLHjx+/4+WXX/7UXOSsqanBqnhJAdVrZkEgEOBpmhbWr1//4Lhx45x77ex1rTPSmpaWlsdqa2tfomk67PV6JdzDF6/IaeWheuknlAswdtfQ0LDN0U8ZuX62Owl0VHl5+VqM7SUqH1gCFTtVBfpp9+7dRzmOc1bqtd3lTn+DZFk+tWrVqgXQUYmmtMQCFb2BE8MtCHcYu3O73Z6dO3d+4izJk/6LZ8czYCmgsrKyW0KhUBA6CmHPNAyDJke1VB+gyOL0EORk7tOSJUumzZkz5//asbNOmzJjgePHj//PQ4cOfZxoGMYSKHIjAjyUpmkoaC6YPHnyjzLTdOcsdrTA+fPnl27atOlIImEeFygyXQUFzSeeeGJ5fn6+c4u5Ha90htrU3t5e+/TTT+9PVODsA5TV7MytW7fW5ebmPpKhtjunsaEFurq6nquoqKhONIvTDFSvFVXMFfKGhoYfeTyeb9iwn06TMmSBYDCImQffj1MxjwpzS6DME+pEUXTv3bv3ZzzP356htjunsaEFJEk6uXLlyr8VBCFkMfPAGiiS4eFHfkjJAKJ8375977Ase7MN++k0KUMWwO8er1ixYg5EOSkdWK3S0stDmUsGWMlX13WX2+12NTY2/o6m6bEZartzGhtaAL90VVpa+pVQKBSmKCocb0GNuECRGhSq5Pv37/+IoqgcG/bTaVKGLKDrevfy5cunQ0P1V4tKFqjTzk0JGbpyNj0NfjZt+fLl05IFygArdnUVzNJkGAbzoC7YtJ9OszJogZKSkomqqoYwe5OsHGyadWAIc+Kh+gBFpq04QGXwitn8VAQoTdOM8byYaSzJA9XY2NjkhDybX+00Nw8hr7S09FZ4qFQA9aEjytN8xWx+eIjy0tLSGSkBavfu3b+laTrP5n12mpdGC2ia1rFq1aq/GjRQWHscohyFzT179rzNcdxNaWyvc2ibW0CW5c9KSkruQmFzUKKcLGaPOtSuXbtecblcf23zPjvNS6MFwuHwv69evXoxKRsMKMuTJIkhhU1Uyrdt23bQ4/HMS2N7nUPb3ALBYPDY2rVrl6JSTgqbPM+rCcsGsWtBsSzrfvrpp2tvuOGG79m8z07z0miBzs7Of1q/fv2TiqKE4qxlbl02iAUKGqq2tvbRgoKCJ9LYXufQNrdAW1vb0xs2bHiWDA5bjOXFBwqzDch6ULiF6gc/+MGCm2666YDN++w0L40W+Oyzz5bt2LHjKCbYkekrMbMNEgOFW9Choe69995b5s2b904a2+sc2uYWOHbs2Nw33njjE2go3JJu8SND/QPV2dnJ4jfw4KEEQfDs2rULxU3nl81tfuHT0TzcRrV69eoZoigGyRRgi98qjg9UU1MTbf6lKQjzXbt2vc7z/Ix0NNg5pr0tIEnSh6tXr/4mEeTkF6uKi4uxpI8W+W09a6CampowUMyMGzfOmLWJdQ0wQLxx48bNubm5zkKt9r72aWldV1fXT9evX19lrpK3tLRgsQy1uLhYTwiUz+ejzb/UCR21Zs2av5s0adK2tLTYOaitLXD+/Pm127dvf5nUoMw/eh0PKHTIWCQDHgpAobiJacBut9vQUQsWLLhp4cKFv7Z1z53GpcUCR44c+frRo0c/g34KhUISSgYoavr9fs0ElHE7ep8ZmwCquLiYIqUDZHpYgQVhr7Gx8f8xDFOQllY7B7WlBVRV/a/S0tKvIdxh5RVzhtfU1KQPCChkegzDcFgwA8J8y5YtW3Jzc//Olj13GpUWC3R1df3LunXrKokgV1VVJhnegIAimR5uSZdl2VgSsby8/N6bb755T1pa7hzUlhb49NNPSxoaGt7AoDDHccYam36/X0GGlxAo9IjcStXW1kZBmHd1dbHwUMj2brnlljGrVq36d2dZaVte+5Q3ChXx3bt3//Unn3xyBbM0MYaXm5urRKb+QjP1Khn00VAEKLMw93g8LNFRGNd75plnDni93rtT3nrngLazQCAQePuxxx57FON3RD8Fg0HFQpAbNahYoHplekSYm3WUIAiuxx57bNHUqVMbbNd7p0Ept8CZM2fKn3nmmcOiKBp3CyfSTwmBgo5CgROT7eCl4KG+/OUv31BeXv6vzk0LKb9+tjogbkpoaGj4mz/+8Y9fwEMhu0P9CQXNePrJEqhYHYV6lDnsoXywefNmZHuLbWUBpzEptUBXV9crVVVV68zlAhLuCgoKDP0UYQXb8ZdEjNVRgiDQsWHv4Ycfnnn77be/ktIeOAezlQVOnjy5+IUXXvggNtyJoqjFFDSj+qlfD0UKnKR8IAiCIc6R7dE07d65cycGi6fZygpOY1JiAUmSTpeVld2naZpxDx7CnSiKSpxyQb9A9RHmAMrr9dIk7AmCYGipNWvWLJoyZcr2lPTAOYitLHD27Nk127dvPwztJIqiBKAQ7gKBAIZaLOtPpAOW65TH6igS9txuNxvxUEJ2dnb2pk2b3mEY5n/YyhpOY4ZkAQy1PP7443N7enp64J3wCIVCCqrjCHdEP5lnGJhP2C9Q5rCHbA9FTgwWo7AZDoeFmpqapYWFhY8PqQfOl21lgdbW1k01NTUHXS6XiMImBoNRzIyT3fUKd1YaKuq5yMwD1KPMYS8YDLIul8sIewUFBaOqq6vfYhgm31ZWcRozKAuoqnqprq7urra2tqsId+FwWPJ4PEqy4a5foKzCniiKDBHnPMqlqupat27dd8aPH+8sOT2oS2ivL128eLF2y5YtP8E0FUmSDO0EMS4IgppMuEsKqNiwB6h0XTcGjKGnxowZk11bW3uE47hJ9jKP05qBWECW5fMbNmxYeOXKFUM7YSCYoigZMCUb7voDqk+2h8FiiHMrL7VixYq7ZsyY4dxmNZAraLN9P/zww2X79u17uz/vZDW7ILYb/f6INQl7ZLDY7/dTEOexXirya+kHvV7vnTazk9OcJCwQCATeLS8vXwoRbuWdfD6f3l8xM1GWFxXmZqDM4pzneRpaStM0jmR8CxYsmHzfffe9TlGUJ4k+OLvYxAIYs3vttde+efTo0XMks6NpWoZ2kiRJi1N76pPd9YKmn75Fl0okXgphj2VZI/SRjE9RMKOBd61fv35pQUFBpU1s5TQjCQu0tbXVb9y48aAkSVg3UyKZHbSToihaoqGWgYS8qMayKiGYvRREOjwVx3GeLVu2vCgIwp8n0Rdnl2G2gCiKf1i3bt1DsiwHEe4gwofinRKJ8qgXi8zixGuaiHOzl6IoisOQDKCaP3/+1AULFqBsnz3M9nJO348FNE3rOXLkyLfefPPNs4AJQyy6rsuoO5m9U38zC6wO358oT0pLKYrCACg8EPeysrKEsrKyxVOnTt3kXFH7WuDcuXNVDQ0NP8vKyhJRcwJMeLAsqw5GOyWrofp4qdiMr6Ojg8YYH8dxbORmBh41sW3btmHO1P32Nen127Kurq5X165du47neVGWZQk1J1mWFYzZ5eXlaag7mTO7SHLWa95TPOsl46EstZS5LoXwB4FOQh9EemFhYU5VVRX0VPH1e+ns13NRFJs2b978UGtrazdEuDnUQYSbq+Ixdae4mZ25l8kC1Qcq3F2MuhSmtqiqyowePdrI+uCpABSq6HPnzh2/aNGif2EYxllB2AZsqaracfjw4Qfeeeedi6g3ASh4Juimzs5OlWEYFWWCwXqnZEV5XC1lFujm0IesD1CxLMsvWbJk5qxZs56jKMplA5tet03QdT38/vvvP3Lo0KEPFEXB/HBjaMUc6kiZAEJ8MN5poEAlLCOQ0MfzPIsbRDmO4wHWqlWr7rn11lufQZZ43V7R4e04JsWtbmxs/FXEKxk3bEqSZHgngDQUIT7YkNcLqMhBjDICCX2oTSHrQxU9HA6zXq/X8FSqqvKVlZUPTJky5amY9RSG18zXx9n1s2fPbqivr3+ZYRjDMwUCAdnlcmHCnGLO6hDqLMoESWmngWZ5fSA0FztjQx/0FMBC6IOnwgM1qsrKyu9MmDChyoEqYyTrn3/++ab6+voXUGuCV8IDoQ4gQTchq0tFqBsyUJFU0lj+h4zz5efnU6TgCaAg1iHSARQ8FUKgA1XGYNIiMB1CaQCeCTBBM0F8AyhSwGxvb8cqKrFzxUlDo7dIJdPygWR5ll4Kb5prU8j6EPoAFqACUKIoGlARXVVeXr54ypQptY6mSuYSDWof7cyZM0/s2LHjMGAinkkQBAVAASazboqT1Q0o1A3FQ/Wb9cXqKYBlBdWKFSvunj59+lZnIdhBARP3S1hg9aOPPqrYt2/fW1YwASQr3TTYrC62IYP1UL0yxP70FMdxtKZpjNfrxTyqqKdCEXTJkiV/fscdd+x16lSpgQp1pvfee6/k0KFDv8cwitkzBQIBlaZpVZZlLQndNCjvNJiygSWQZPDYSk+hPhULFdYHQvhD9jdnzpyi+++/f7cgCLemxqzX51FEUTz96quvrjp+/HgzsjnAhHoAwpwVTLG6KaKJiV4akG4aStnA6mpF50wRPRUr0vuDCplgYWFhdmlp6ROjR492xv4G8f/Q2dn5amNj49Otra09yOCGC6ZUeKiEeopkfrFQIQOEp4rc8IBNvqys7P7Jkyc/TtO0dxB2ve6+omla4Pz585t37Njxc1S/OY5TABQ8U2QYpU+Yg2ci9aZU6aZUe6h+9RQR6T6fjzJDxTCMIdahrxD+GIYxwuDdd9896Z577tnidrtvu+4IGUCHQ6HQqTfffHPdW2+9dR4eSVVVBc8RnaSoqqqZNZPf79fJOF2coZVB66Z0ADVgqJD9wUsBKLfbzUiSZAAFsARBEMrLy79TVFRU4mSBvSlDFtfa2rp327Ztz2NWHAGJ53lMPzE8ErwTsjkiwDMFUypDXp8yRGzmZ+WpABU8FQELcQ9AybJswDVv3rwJ8+fPr/Z4PF8bwD/vNbtrMBj8zS9/+cu6Y8eOfQ5vhBAHoPBHQIJnGi6Y0gFUQk9l1lQ5OTkUgELIp2GRiMcCWPBYgAuPZcuWzZ42bdoajuMmX7O09NMxWZbPffzxx9sPHDhwAgDhAY9kBknTNKO+BKC6u7t1UhpIoJlSEubSFfIsj2vlqQhUgUDAGKoBVN3d3cYzCYF4Bkx4VhSFzc3NdZWUlCwuLCxcyrLsdbGWAtYaaGlp+eGePXte6erqwl0phicCUHgmIQ4Q5eTkaMQ7eb1eHV4q0zCly0MlFf4AVXd3N0WGacLhcBQueCp4LMCEBzwWASwvL8+zdOnSBwsKCr5zrYKlKEp7W1vbTw4ePPhSR0dHkABEPBJggkeCViIQuVwuAyJMQ8nJydGHA6Z0AxU3/EXqVbQZqlAoRKEA6vV6AVrUW8FruVwuAyw8aJpGqYEZNWqU63vf+943Jk6c+A+CIFwTK+mJovjxhQsXnv/xj3/85tWrV8MURQEcwxvhEQ5jdef/zt6IVwoEAjrEt9vt1s0wRX56DOOs5p/PIP/sgy5cJpIcQxl6SXTsuJ4KH6D4aZ5LhbKCOQSKomjoK/wFg0HcCBGFCmDxPI/pMcZ7S5YsuW369OmLcnNz54+0O5dx525XV9cvP/roo8OHDh06BVgAkiRJBkTkgfDm8XjgmIzQJgiCbg5xVplcxM7mnx9LuWaKhSATQPXxVBEPZUx7IVCZdZWVtyJwkVBoDokAi+M4pqioKPv+++//emFh4Te8Xu/XKIrCbV22+9N1HZPcftPa2vqrV1999dfNzc09siwbIBGAAA4JbQQiK6/Un15Cx00rzaUdpkyEvLhCPR5U0FWkCIoskGgrSZIMj2UGi0BFUZSht/AMuPA8adKkUQsXLrwjPz//a9nZ2X8z3HoLuqinp+ff2tvbf3PkyJH3zp8/f1XXdQ0Q4RnwkGfDDUX+ABEePM8bGglaiWRx8Erx9NJwwJRpoOJ6qtgQGOutSHkBYTAWLEVRKGiscDhshEf8ASgzXLIs0/Pnzy8qLi7+y7y8vNu8Xm8xz/OT01U0xQ0BkiSdDQQCTR0dHadOnz79+1/84hcXOY7TzBBhm/y5XC4NGgmjUWaPBJBIeANI0ErxvBIJccMF03AAZamrEnkraCuEQSuwXC4XBY0Fz8XzPAWgYuFSVUQT4yOoWWMbIfKuu+4qmjJlypRRo0aN83g8BTzP53Mc52MYZjQekTuicYu9cccOQEG4wtQQVVU78ZBl2S9JUnswGGy7evVqy9mzZ8++/fbbzQhhAIZhGAMQsh0LET7DjbvwQtBI4XDY2I4Hkh29kmUYGgahEdVvsdNf0BaztiJhkIBFskHisdxut0GLLMu4L8gIjWa4sA2IABM8GvZlWZbCa03TUK4wtskzzo/3+7MJTdNGpgRgFEXRyTPeJ9uRYqPxGiABHHgiM0Qcx+l44L1QKKQTkMzZGzySFUiRf0QjixtOr2QXoPp4yFiwABV2wrANKTGQbJB4LGgslBpIVoiQCK9F4BIEwQAIIAEsPBOoOI4zQMI58B5eY5u8B8CsoAJABCY8y7KsI1SR9/CawIT3ARIJZaIoGgDhAW8EgEjWBoiIRiKhLRYknMM8uGsBkuFMh8FBGKfMVJaXqH+W3ipWW+F1MmABKngt7G8FmBkuAhmBCs94z9xg7I/XBBryGUAxv2+Gh0BkBRC+E+uN+gMJ+5unnETsYhuvZCcPFbctZm81ELCwr9lrEagAGODCa+LBIt4Fa4dGvRRpUCxUsf8RBCYzUAQevEc8UARQnQCE1xDZxBvhtVlsmz3SAEAaVq9kV6BIu/p4K3xAphdjm+irWI+F12YBb4YL2wiLBDA8m70YAc1sHITNWJAILOb3EboIOHgGPObXACjSNiOkxUKE1/FAivQ9qpPwOtO1JSsbxHvPLiHPqn1xwcLOpCgauRiGxopcKKOOZYYL28gQCWB4hu4yQ2YGbSAGNEAr5JoAAAGNSURBVIODbTM8EUijAEUgNtJ+M0TYJmNv2CYaKdLPqB6yM0jEZnYGqk8bTSvpGR6LgIXnWK9F4MKzGTC8hqC3goyckMCWCCyELfM+Zu9D4InAGwUocl7jNSCKtI/cAm6MvY1EkEYSUJZttdJYZEdzdoj3zN7LDBi2ESLJ9whoiUCK/RwZmQnG6DbCWDyAiCci34sFKcYbYbdhy9wGYo+R4KFi+9Orzf15LeK58IzSAzkQAczsxchnxJsla0QCDdkfQyFkm3gg4oUSQYTPRypII9FD9QtW5GJEoSEhMRI+ou8T7xULmRVsyUBlhsYEZRSqyGomxkfEC0XaFE8bkcOMCI+U8KIkY0Qb7tPH05o9V+RiRveBoI/tgxm0wfTPDA75fjyA4ngivD0iITLbaySGvETXOyFcsYDFHtAKOKuTmoGxOEYfOCzC2TUB0bUOVFL9i/VgiSgd6Odx4BnR4SwZG1yLHipRvzPd5xEfxhIZNKn/4IEc5BrZd6igXVfgxLvmQzXiNcKS041UWeD/AzTMRB5WfXBJAAAAAElFTkSuQmCC';
- const LINE = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAAABAQMAAABQVuppAAAAA1BMVEXZ2dmK1ydDAAAACklEQVQI12OAAwAACgABaQY5MgAAAABJRU5ErkJggg==';
- const BLACKARROW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAlCAYAAACtbaI7AAACMklEQVRIS6XWT8gOURTH8c+bIjaSZGMjr6xkJUlKJAnlTyglRYpIQlFIYcFbSEKSiBD5F/K/XrGQpY0VZWFnQ2GhRKdm3sa488zM85zlnfv73nPm3HPO7dOb9eE03uBKjorFXuwEtuM3VuN2wHqBHsK+gke/sAyPuoXuxeFEiN/R3w00wo2wy/YHG3GhLTRE5yp+2zacavtP1+IihiW83IOjbbO/AjcqgAdxoHhQk/AX4Q6GJzw8jp3l9TroPDzAyATwLLYgEvSPdYLOwjOMSgAvYX0K2ClR0/EcoxPAm1iTVVGyGlOeTsUgxiYU97ESUT2VVoZOwWuMSyjC88V1wHL4k/ASExLAV1iIn026T+5pgEI4MSF6iwX41gSYezo+C3lyQvQOc/C1KTCHRlJCWLb32fqXNsAcGhf8RUL4EFGeHTOdOjD+6cwMmrrktXeyChrrkdl7FfXdsXo6QePbcoRnqdZ2BluryrIMLl/+KL/LFeBj2NUkaaky3YDzFd39v95ZF37xe4yGkxVe7cZAm9ov7g3xkQrx0Dxq42m+N8LdnxAOTc5uoKGJBO1IiONVEsPwel32qw6OK7WpAhz99W7xW92MyvfGvhjP6xLgKOOleFzc3OTqxZ4oimtYlRBEn40GHs2p9QMtxvQtLEmAf2B+PCubhl9kjMjGdgDKFo18bjfQAEVHe4LZCfBgt9Bgxfh+ihkF8Ic4qBdosMZkyZmGT5nnn3uFBjjG+VVsxsdY+At+xGFFRqHhqQAAAABJRU5ErkJggg==';
- const GREYARROW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAlCAYAAABGWhk4AAABdElEQVRIS63WSU7DMBjF8X9BAgoLBiG6YbwCV2ASFPYcEwkobDgA92BBGfYMG/QkuzKRHftz4l2V6NeXZzvOgP9jCzgEnoDfxjXTz0Fw9wg4BxaAV+AR+DFpwc0eDlF/uRMuWAmvgaVIuinwUJPcJz4AjoC5vvCw4zb8DZhYkoewwu4Dx4nkJrwJ94bH4F7wFJzD34H7ts7bYOF7wEmi81Y8B1fjJbDwXeA0kfzD1fId7oFS2IxbYOE7wFlJcivscdUyH9n+s1pq4BJ8Ugvn8Jcu8CpwBSxHKrmphYVeAisRVKfObQ285tBYUqE6GKZWuAjVU1jgYtQC51CdLjoIZqMksRktSVyF5mChWqfDxJLSi17v5OhIVbHullQVmkrcGY3BOfQO0BssO8IqhKrT2KeWTgd1WoSGiTdcp72gHu4d9fAFsB0pzfz4zZ2nxxe+GVz4ch+BxZ02g/nJWwTGDheqifrMTn3LDeGqEK5v5OeuqP7vD69mZ6FJZpeeAAAAAElFTkSuQmCC';
- const PORTRAIT_ITEM_WIDTH = 670,
- PORTRAIT_ITEM_HEIGHT = 202,
- PORTRAIT_ITEM_SPACE = 25,
- LANDSCAPE_ITEM_WIDTH = 272,
- LANDSCAPE_ITEM_HEIGHT = 440,
- LANDSCAPE_ITEM_SPACE = 30;
- class RecommendUI {
- constructor(appid = 'default') {
- this.appid = appid;
- this.touching = false;
- this.firstShow = true;
- this.loadSuccess = false;
- this.specPanels = [];
- let window = cc.Canvas.instance; //获取游戏的canvas对象作为游戏窗口,以作为大小适配的基准参考
- if (window instanceof cc.Canvas) {
- this.window = window.node;
- this.initRoot();
- this.createBackground();
- this.initTitle();
- this.getSession(); // 获取上报的session
- this.fetchData();
- } else {
- cc.error('Can\'t find the canvas node in the current scene.');
- }
- }
- getSession() {
- let session = window.localStorage.getItem('session');
- if (!session) {
- this.request('POST', 'https://goplatform.minigame.qq.com/mplogin/getsessionid', {
- AppID: this.appid + ''
- }).then(res => {
- if (res.result === 0) {
- session = res.session;
- window.localStorage.setItem('session', session);
- this.session = session;
- }
- });
- } else {
- this.session = session;
- }
- }
- fetchData(reconnect = false) {
- this.request('GET', 'https://goplatform.minigame.qq.com/3366game/getcurrentgame?appid=' + this.appid)
- .then((res) => {
- if (res.result == 0) {
- this.loadSuccess = true;
- if (this.offlineNode) {
- this.offlineNode.active = false;
- }
- if (reconnect) {
- this.firstReport();
- }
- this.games = [];
- this.moreGames = [];
- for (let i = 0; i < res.data.Games.length; ++i) {
- this.games.push({
- app_id: res.data.Games[i]['app_id'],
- name: res.data.Games[i]['app_name'],
- icon: res.data.Games[i]['app_icon'],
- desc: res.data.Games[i]['app_introduction'],
- qrcode: res.data.Games[i]['mini_program_code']
- });
- }
- for (let i = 0; i < res.data.More_games.length; ++i) {
- this.moreGames.push({
- name: res.data.More_games[i]['app_name'],
- icon: res.data.More_games[i]['app_icon'],
- desc: res.data.More_games[i]['app_introduction'],
- qrcode: res.data.More_games[i]['mini_program_code']
- });
- }
- this.banner = this.choose(res.data.Banner, res.data.Banner_landscape);
- this.poster = res.data.App_poster;
- if (res.data.More_game_image) {
- this.moreGameQrcode = res.data.More_game_image;
- } else {
- this.moreGameQrcode = '';
- }
- this.loadResource();
- } else {
- this.loadOfflineResource();
- }
- }).catch(e => {
- cc.error(e);
- this.loadOfflineResource();
- });
- }
- // 拉取图片资源
- loadResource() {
- let promises = [];
- for (let i = 0; i < this.games.length; ++i) {
- promises.push(this.loadRemoteImage(this.games[i].icon)); // 游戏图标
- }
- for (let i = 0; i < this.moreGames.length; ++i) {
- promises.push(this.loadRemoteImage(this.moreGames[i].icon)); //更多游戏图标
- }
- promises.push(this.loadRemoteImage(this.banner));
- promises.push(this.loadRemoteImage(BAR));
- promises.push(this.loadRemoteImage(PANEL));
- promises.push(this.loadRemoteImage(CIRCLE));
- promises.push(this.loadRemoteImage(LINE));
- promises.push(this.loadRemoteImage(GREYARROW));
- Promise.all(promises).then((results) => {
- this.gameIcons = [];
- this.moreGameIcons = [];
- for (let i = 0; i < this.games.length; ++i) {
- this.gameIcons.push(results[i]);
- }
- for (let i = 0; i < this.moreGames.length; ++i) {
- this.moreGameIcons.push(results[i + this.games.length]);
- }
- this.bannerImg = results[this.games.length + this.moreGames.length];
- this.bar = results[this.games.length + this.moreGames.length + 1];
- this.panel = results[this.games.length + this.moreGames.length + 2];
- this.circle = results[this.games.length + this.moreGames.length + 3];
- this.line = results[this.games.length + this.moreGames.length + 4];
- this.greyArrow = results[this.games.length + this.moreGames.length + 5];
- this.createUI();
- }).catch((e) => {
- cc.error(e);
- });
- }
- // 拉取离线图片资源
- loadOfflineResource() {
- if (this.offlineNode) {
- this.offlineNode.active = true;
- return;
- }
- let promises = [];
- promises.push(this.loadRemoteImage(OFFLINE_TIPS));
- promises.push(this.loadRemoteImage(RECONNECT_BTN));
- Promise.all(promises).then((results) => {
- this.offlineTips = results[0];
- this.reconnectBtn = results[1];
- this.createUI();
- }).catch((e) => {
- cc.error(e);
- });
- }
- createNode(options) {
- let node = new cc.Node(options.name);
- let customProps = ['x', 'y', 'width', 'height', 'anchorX', 'anchorY', 'active', 'scaleX', 'scaleY', 'color', 'rotation'];
- if (options.components) {
- for (let component of options.components) {
- this.addComponent(node, component, options);
- }
- }
- for (let prop of customProps) {
- node[prop] = options[prop] !== undefined ? options[prop] : node[prop];
- if (prop == 'width' && options[prop] == 476) {
- window.line = node;
- }
- }
- if (options.children) {
- for (let child of options.children) {
- let childNode = this.createNode(child);
- node.addChild(childNode);
- }
- }
- return node;
- }
- addComponent(node, component, options) {
- let spriteFrames = this.uis;
- let props = {
- 'sprite': ['spriteFrame', 'type', 'sizeMode', 'trim'],
- 'mask': ['type', 'segements', 'alphaThreshold', 'spriteFrame'],
- 'richText': ['horizontalAlign', 'fontSize', 'maxWidth', 'lineHeight', 'string'],
- 'label': ['horizontalAlign', 'verticalAlign', 'fontSize', 'maxWidth', 'lineHeight', 'string', 'overflow'],
- 'widget': ['isAlignHorizontalCenter', 'isAlignVerticalCenter', 'isAlignTop', 'isAlignBottom', 'isAlignLeft', 'isAlignRight', 'top', 'bottom', 'left', 'right'],
- 'scrollview': ['vertical', 'horizonal', 'elastic'],
- 'layout': ['type', 'paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight', 'spacingX', 'spacingY'],
- 'graphics': [],
- 'scrollbar': ['direction', 'enableAutoHide'],
- 'blockInputEvents': []
- };
- let classes = {
- 'sprite': cc.Sprite,
- 'mask': cc.Mask,
- 'richText': cc.RichText,
- 'label': cc.Label,
- 'widget': cc.Widget,
- 'scrollview': cc.ScrollView,
- 'graphics': cc.Graphics,
- 'layout': cc.Layout,
- 'scrollbar': cc.Scrollbar,
- 'blockInputEvents': cc.BlockInputEvents
- };
- let cp = node.addComponent(classes[component.name]);
- if (component.name == 'graphics' && component.drawFunc) {
- component.drawFunc(cp);
- }
- for (let prop of props[component.name]) {
- // if (prop == 'sizeMode') {
- // debugger;
- // }
- if (prop == 'spriteFrame') {
- let value = component[prop];
- if (value != undefined) {
- if (typeof (value) == 'string') {
- cp[prop] = spriteFrames[value];
- }
- if (value instanceof cc.SpriteFrame) {
- cp[prop] = value;
- }
- }
- } else {
- cp[prop] = component[prop] !== undefined ? component[prop] : cp[prop];
- }
- }
- }
- request(method, url, data) {
- return new Promise((resolve, reject) => {
- let timeoutcb = setTimeout(() => {
- reject('timeout');
- }, 3000);
- if (typeof (wx) != "undefined") {
- let xhr = new XMLHttpRequest();
- xhr.onreadystatechange = () => {
- if (xhr.readyState == 4) {
- clearTimeout(timeoutcb);
- if ((xhr.status >= 200 && xhr.status < 400)) {
- let res = xhr.responseText;
- try {
- res = JSON.parse(res);
- } catch (e) {
- reject('json parse err');
- }
- resolve(res);
- } else {
- reject('server error: ' + xhr.status);
- }
- }
- };
- xhr.open(method, url, true);
- xhr.setRequestHeader('Content-Type', 'application/json');
- if (typeof(wx) !== 'undefined') {
- xhr.send(data || {});
- } else {
- xhr.send(JSON.stringify(data || {}));
- }
- } else {
- clearTimeout(timeoutcb);
- reject();
- }
- });
- }
- loadRemoteImage(url) {
- return new Promise((resolve, reject) => {
- if (url) {
- let image = new Image();
- image.src = url;
- image.crossOrigin = "Anonymous";
- image.onload = () => {
- let texture = new cc.Texture2D();
- texture.initWithElement(image);
- texture.handleLoadedTexture();
- resolve(texture);
- };
- image.onerror = () => {
- resolve(new cc.Texture2D());
- }
- } else {
- resolve(null);
- }
- });
- }
- createUI() {
- if (this.loadSuccess) {
- this.scrollView = this.createScrollView();
- this.root.addChild(this.scrollView);
- this.bindScrollEvents(this.scrollView);
- this.gameListContainer = this.createContainer();
- this.scrollView.addChild(this.gameListContainer);
- this.scrollView.getComponent(cc.ScrollView).content = this.gameListContainer;
- this.gameListPanels = this.createGameListPanels(this.gameListContainer);
- this.moreGamePanel = this.createMoreGamePanel(this.gameListContainer);
- if (this.bannerImg) {
- this.gameBanner = this.createGameBanner(this.gameListContainer);
- }
- } else {
- this.createOffLineUI();
- }
- }
- createOffLineUI() {
- let options = {
- name: 'offline-tips-container',
- width: this.choose(720, 1280),
- height: this.choose(1280, 720),
- scaleX: this.measureScale,
- scaleY: this.measureScale,
- children: [
- {
- name: 'offline-tips',
- width: 219,
- height: 265,
- y: this.choose(171, 27),
- components: [{
- name: 'sprite',
- spriteFrame: new cc.SpriteFrame(this.offlineTips)
- }]
- },
- {
- name: 'offline-text',
- y: this.choose(17, -127),
- color: cc.hexToColor('#525252'),
- height: 23,
- components: [{
- name: 'label',
- string: '您的网络貌似有问题,请刷新试试哦',
- fontSize: 22
- }]
- },
- {
- name: 'reconnect-btn',
- y: this.choose(-64, -208),
- components: [{
- name: 'sprite',
- spriteFrame: new cc.SpriteFrame(this.reconnectBtn)
- }],
- children: [{
- name: 'btn-text',
- color: cc.hexToColor('#3086de'),
- components: [{
- name: 'label',
- string: '刷新',
- fontSize: 28,
- verticalAlign: cc.Label.VerticalAlign.CENTER
- }]
- }]
- }
- ]
- };
- this.offlineNode = this.createNode(options);
- this.root.addChild(this.offlineNode);
- cc.find('reconnect-btn', this.offlineNode).on(cc.Node.EventType.TOUCH_START, (e) => {
- this.fetchData(true);
- });
- }
- createScrollView() {
- let options = {
- name: '3666-game-scrollview',
- width: this.mode == 'portrait' ? 720 : 1280,
- height: this.mode == 'portrait' ? 1280 : 720,
- x: 0,
- y: 0,
- components: [
- {
- name: 'scrollview',
- vertical: this.mode == 'portrait',
- horizonal: this.mode == 'landscape',
- elastic: false
- },
- {
- name: 'mask',
- type: cc.Mask.Type.RECT
- }
- ]
- // children: [
- // {
- // name: 'scroll-bar',
- // width: this.mode == 'portrait' ? 5 : 1120,
- // height: this.mode == 'portrait' ? 1120 : 5,
- // components: [
- // {
- // name: 'scrollbar',
- // direction: this.mode == 'portrait' ? cc.Scrollbar.Direction.VERTICAL : cc.Scrollbar.Direction.HORIZONTAL,
- // enableAutoHide: true
- // },
- // {
- // name: 'widget',
- // isAlignBottom: this.mode == 'portrait',
- // isAlignTop: this.mode == 'landscape',
- // top: 10,
- // bottom: 0,
- // isAlignRight: true,
- // right: this.mode == 'portrait' ? 10 : 0
- // },
- // {
- // name: 'graphics',
- // drawFunc: (graphics) => {
- // this.drawRect(graphics, this.mode == 'portrait' ? 5 : 1120, this.mode == 'portrait' ? 1120 : 5, cc.hexToColor('#cccccc'));
- // }
- // }
- // ],
- // children: [{
- // name: 'bar',
- // width: this.mode == 'portrait' ? 7 : 30,
- // height: this.mode == 'portrait' ? 30 : 7,
- // components: [
- // {
- // name: 'sprite',
- // spriteFrame: new cc.SpriteFrame(this.bar)
- // }
- // ]
- // }]
- // }
- // ]
- };
- let node = this.createNode(options);
- // let scrollBar = cc.find('scroll-bar', node);
- // let bar = cc.find('scroll-bar/bar', node);
- // scrollBar.getComponent(cc.Scrollbar).handle = bar.getComponent(cc.Sprite);
- // node.getComponent(cc.ScrollView).verticalScrollBar = scrollBar.getComponent(cc.Scrollbar);
- node.scaleX = node.scaleY = this.measureScale; // 大小适配(等比例缩放)
- return node;
- }
- bindScrollEvents(node) {
- node.on('scroll-ended', () => {
- this.checkExposedGames();
- });
- }
- // 检查曝光的游戏并上报(曝光条件:在显示屏幕区域占一半以上)
- checkExposedGames(first = false) {
- let component = this.scrollView.getComponent(cc.ScrollView);
- let offset = component.getScrollOffset();
- let gameOffset;
- let datas = [];
- if (this.mode == 'landscape') {
- gameOffset = -offset.x
- } else {
- gameOffset = offset.y;
- }
- if (first) gameOffset = 0;
- let extraNum = 2;
- if (!this.moreGameIcons || this.moreGameIcons.length == 0) {
- extraNum = 1;
- }
- // 检测游戏曝光
- for (let i = 0; i < this.games.length + extraNum; ++i) {
- let x = this.choose(145 + i * 227, 51 + i * 302);
- if (x > gameOffset - this.choose(PORTRAIT_ITEM_HEIGHT, LANDSCAPE_ITEM_WIDTH) / 2
- && x + this.choose(PORTRAIT_ITEM_HEIGHT, LANDSCAPE_ITEM_WIDTH) < gameOffset + 1280 + this.choose(PORTRAIT_ITEM_HEIGHT, LANDSCAPE_ITEM_WIDTH) / 2) {
- if (i < this.games.length && !this.games[i].exposed) {
- this.games[i].exposed = true;
- this.reportItem(datas, i, 100, 2);
- }
- if (i >= this.games.length) {
- let name = this.specPanels[i - this.games.length];
- if (name == 'more-game' && !this.moreGameIsExposed) {
- this.reportItem(datas, null, 100, 3);
- this.moreGameIsExposed = true;
- }
- if (name == 'game-banner' && !this.bannerIsExposed) {
- this.reportItem(datas, null, 100, 4);
- this.bannerIsExposed = true;
- }
- }
- } else {
- if (i < this.games.length) {
- this.games[i].exposed = false;
- } else {
- var name = this.specPanels[i - this.games.length];
- if (name == 'more-game') {
- this.moreGameIsExposed = false;
- }
- if (name == 'game-banner') {
- this.bannerIsExposed = false;
- }
- }
- }
- }
- if (datas.length > 0) {
- this.report(datas); // 统一批量上报
- }
- }
- // 生成单个上报数据
- reportItem(datas, i, actionId, slotId) {
- let data = {
- iSceneLevel1: 1000000,
- iSceneLevel2: slotId,
- iActionId: actionId,
- iResourceId2: this.appid,
- vV1: 1
- };
- if (i !== null) {
- data.iSceneLevel3 = i + 1;
- data.iResourceId1 = this.games[i].app_id;
- } else {
- data.iSceneLevel3 = 1;
- }
- datas.push(data);
- }
- createContainer() {
- let extraNum = 0;
- if (this.moreGameIcons && this.moreGameIcons.length > 0) {
- ++extraNum;
- }
- if (this.banner) {
- ++extraNum;
- }
- let landscapeWidth = (this.games.length + extraNum) * (LANDSCAPE_ITEM_WIDTH + LANDSCAPE_ITEM_SPACE) + 72;
- let portraitHeight = (this.games.length + extraNum) * (PORTRAIT_ITEM_HEIGHT + PORTRAIT_ITEM_SPACE) + 145;
- let options = {
- name: 'container',
- width: this.choose(720, landscapeWidth),
- height: this.choose(portraitHeight, 720),
- // x: this.choose(0, (this.games.length > 3 ? landscapeWidth / 2 - 640 : 0)),
- x: this.choose(0, (landscapeWidth / 2 - 640)),
- y: this.choose((this.games.length > 3 ? 640 - portraitHeight / 2 : 0), 0),
- components: [
- {
- name: 'widget',
- isAlignHorizontalCenter: this.mode == 'portrait',
- isAlignVerticalCenter: this.mode == 'landscape'
- },
- {
- name: 'layout',
- type: this.mode == 'portrait' ? cc.Layout.Type.VERTICAL : cc.Layout.Type.HORIZONTAL,
- paddingTop: this.choose(145 - 5, 100),
- // paddingBottom: this.choose(undefined, 70 - 18),
- paddingLeft: this.choose(0, 51 - 7),
- spacingY: this.choose(PORTRAIT_ITEM_SPACE - 20, 0),
- spacingX: this.choose(0, LANDSCAPE_ITEM_SPACE - 16)
- }
- ]
- };
- let node = this.createNode(options);
- return node;
- }
- createGameListPanels(parent) {
- let panels = [];
- let panelFrame = new cc.SpriteFrame(this.panel);
- panelFrame.insetTop = 13;
- panelFrame.insetBottom = 23;
- panelFrame.insetLeft = 17;
- panelFrame.insetRight = 19;
- for (let i = 0; i < this.games.length; ++i) {
- let desc = this.games[i].desc;
- if (this.mode == 'portrait') {
- if (desc.length > 16) {
- desc = desc.substr(0, 15) + '...';
- }
- } else {
- if (desc.length > 20) {
- desc = desc.substr(0, 19) + '...';
- }
- }
- let realWidth = this.choose(PORTRAIT_ITEM_WIDTH + 16, LANDSCAPE_ITEM_WIDTH + 16);
- let realHeight = this.choose(PORTRAIT_ITEM_HEIGHT + 20, LANDSCAPE_ITEM_HEIGHT + 20);
- let options = {
- name: 'game-item',
- width: realWidth,
- x: 0,
- y: this.choose(0, -80),
- anchorX: 0.5 - 1 / (realWidth * 2),
- anchorY: 0.5 + 5 / realHeight,
- height: realHeight,
- components: [
- {
- name: 'sprite',
- spriteFrame: panelFrame,
- type: cc.Sprite.Type.SLICED,
- sizeMode: cc.Sprite.SizeMode.CUSTOM,
- trim: false
- }
- ],
- children: [
- {
- name: 'icon-bg',
- width: 130,
- height: 130,
- x: this.choose(-250, 0),
- y: this.choose(0, 200),
- components: [{
- name: 'sprite',
- spriteFrame: new cc.SpriteFrame(this.circle)
- }],
- active: this.mode == 'landscape'
- },
- {
- name: 'icon',
- x: this.choose(-250, 0),
- y: this.choose(0, 205),
- width: 122,
- height: 122,
- components: [
- {
- name: 'sprite',
- sizeMode: cc.Sprite.SizeMode.CUSTOM,
- type: cc.Sprite.Type.SIMPLE,
- spriteFrame: new cc.SpriteFrame(this.gameIcons[i])
- }
- ]
- },
- {
- name: 'name',
- x: this.choose(-165, 0),
- y: this.choose(55, 78),
- width: this.choose(440, 205),
- height: this.choose(48, 72),
- color: cc.hexToColor('#000000'),
- anchorX: this.choose(0, 0.5),
- anchorY: this.choose(1, 1),
- components: [{
- name: 'label',
- horizontalAlign: this.choose(cc.Label.HorizontalAlign.LEFT, cc.Label.HorizontalAlign.CENTER),
- overflow: cc.Label.Overflow.RESIZE_HEIGHT,
- fontSize: this.choose(40, 30),
- lineHeight: this.choose(48, 42),
- string: this.games[i].name.length > 12 ? this.games[i].name.substr(0, 11) + '...' : this.games[i].name
- }],
- },
- {
- name: 'line',
- // width: this.choose(476, 200),
- scaleX: this.choose(476 / 66, 200 / 66),
- height: 1,
- x: this.choose(73, 0),
- y: this.choose(1, -40),
- active: this.mode == 'portrait',
- components: [
- {
- name: 'sprite',
- spriteFrame: new cc.SpriteFrame(this.line),
- type: cc.Sprite.Type.SIMPLE,
- sizeMode: cc.Sprite.SizeMode.COSTOM
- // drawFunc: (graphics) => {
- // graphics.lineWidth = 1;
- // graphics.strokeColor = cc.hexToColor('#999999');
- // graphics.moveTo(0, 0);
- // graphics.lineTo(476, 0);
- // graphics.stroke();
- // }
- }
- ]
- },
- {
- name: 'desc',
- x: this.choose(-165, 0),
- y: this.choose(-11, -26),
- width: this.choose(416, 220),
- height: this.choose(31, 36),
- anchorX: this.choose(0, 0.5),
- anchorY: this.choose(1, 1),
- color: cc.hexToColor('#999999'),
- components: [{
- name: 'label',
- horizontalAlign: this.choose(cc.Label.HorizontalAlign.LEFT, cc.Label.HorizontalAlign.CENTER),
- verticalAlign: cc.Label.VerticalAlign.TOP,
- overflow: cc.Label.Overflow.RESIZE_HEIGHT,
- fontSize: this.choose(26, 22),
- lineHeight: this.choose(31, 36),
- string: desc
- }]
- }
- ],
- };
- let node = this.createNode(options);
- this.bindTouchEvent(node, ((currentIndex) => {
- return () => {
- let datas = [];
- this.reportItem(datas, currentIndex, 101, 2);
- this.report(datas);
- this.showQrcode(this.games[currentIndex]);
- };
- })(i));
- panels.push(node);
- }
- for (let panel of panels) {
- parent.addChild(panel);
- }
- return panels;
- }
- bindTouchEvent(node, cb) {
- let distance, x1, y1, x2, y2;
- node.on(cc.Node.EventType.TOUCH_START, (e) => {
- let loc = e.getLocation();
- x1 = loc.x;
- y1 = loc.y;
- });
- node.on(cc.Node.EventType.TOUCH_END, (e) => {
- let loc = e.getLocation();
- x2 = loc.x;
- y2 = loc.y;
- distance = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
- if (distance < 25) {
- if (!this.touching) {
- this.touching = true;
- setTimeout(() => {
- this.touching = false;
- }, 10);
- cb();
- }
- }
- });
- }
- showQrcode(data) {
- if (typeof (wx) != 'undefined') {
- wx.previewImage({
- urls: [data.qrcode]
- });
- }
- }
- createTitle() {
- let options = {
- name: 'title',
- // x: -this.width / 2,
- // y: -this.height / 2,
- x: 0,
- y: this.root.height / 2 - 60 * this.measureScale,
- width: this.root.width,
- height: 120 * this.measureScale,
- components: [
- // {
- // name: 'widget',
- // isAlignTop: true,
- // top: 0
- // },
- {
- name: 'blockInputEvents'
- },
- {
- name: 'graphics',
- drawFunc: (graphics) => {
- this.drawRect(graphics, this.root.width,
- 120 * this.measureScale);
- }
- }
- ],
- children: [
- {
- name: 'title-container',
- width: this.root.width,
- height: 120 * this.measureScale,
- children: [
- {
- name: 'arrow_container',
- width: this.choose(21 * 0.8 + 60, 21 * 0.8 + 50),
- height: 120,
- scaleX: this.measureScale,
- scaleY: this.measureScale,
- children: [{
- name: 'button_arrow',
- width: 21,
- height: 37,
- components: [
- {
- name: 'sprite',
- type: cc.Sprite.Type.SIMPLE,
- sizeMode: cc.Sprite.SizeMode.CUSTOM,
- spriteFrame: new cc.SpriteFrame(this.blackArrow)
- }
- ]
- }],
- components: [{
- name: 'widget',
- isAlignLeft: true,
- left: 0,
- isAlignVerticalCenter: true
- }]
- },
- {
- name: 'title-text',
- color: cc.hexToColor('#000000'),
- height: 46,
- x: this.choose(0, -438),
- scaleX: this.measureScale,
- scaleY: this.measureScale,
- components: [
- {
- name: 'richText',
- string: '<bold>精彩游戏推荐<bold>',
- horizontalAlign: cc.RichText.HorizontalAlign.CENTER,
- fontSize: 34,
- lineHeight: 36
- },
- {
- name: 'widget',
- isAlignHorizontalCenter: this.choose(true, false),
- isAlignVerticalCenter: true,
- isAlignLeft: this.mode == 'landscape',
- left: 90 * this.measureScale
- }
- ]
- }
- ]
- }
- ]
- };
- let node = this.createNode(options);
- let backBtn = cc.find('title-container/arrow_container', node);
- backBtn.on(cc.Node.EventType.TOUCH_START, () => {
- this.hide();
- });
- return node;
- }
- createMoreGamePanel(parent) {
- if (!this.moreGameIcons || this.moreGameIcons.length == 0) {
- return null;
- }
- let panels = [];
- let panelFrame = new cc.SpriteFrame(this.panel);
- panelFrame.insetTop = 13;
- panelFrame.insetBottom = 23;
- panelFrame.insetLeft = 17;
- panelFrame.insetRight = 19;
- let realWidth = this.choose(PORTRAIT_ITEM_WIDTH + 16, LANDSCAPE_ITEM_WIDTH + 16);
- let realHeight = this.choose(PORTRAIT_ITEM_HEIGHT + 20, LANDSCAPE_ITEM_HEIGHT + 20);
- let options = {
- name: 'more-game-panel',
- width: realWidth,
- height: realHeight,
- anchorX: 0.5 - 1 / realWidth,
- anchorY: 0.5 + 5 / realHeight,
- y: this.choose(0, -80),
- components: [
- // {
- // name: 'graphics',
- // drawFunc: (graphics) => {
- // this.drawRoundRect(graphics, this.choose(PORTRAIT_ITEM_WIDTH, 250), this.choose(PORTRAIT_ITEM_HEIGHT, 400));
- // }
- // }
- {
- name: 'sprite',
- spriteFrame: panelFrame,
- type: cc.Sprite.Type.SLICED,
- sizeMode: cc.Sprite.SizeMode.CUSTOM,
- trim: false
- }
- ],
- children: []
- };
- for (let i = 0; i < 3; ++i) {
- if (this.moreGameIcons && this.moreGameIcons[i]) {
- options.children.push(
- {
- name: 'icon',
- width: this.choose(86 + 2 * 86 / 120, 70 + 2 * 70 / 120),
- height: this.choose(86 + 2 * 86 / 120, 70 + 2 * 70 / 120),
- x: this.choose(-267 + 106 * i, -76 + 76 * i),
- y: this.choose(0, 50),
- components: [
- {
- name: 'sprite',
- sizeMode: cc.Sprite.SizeMode.CUSTOM,
- type: cc.Sprite.Type.SIMPLE,
- spriteFrame: new cc.SpriteFrame(this.moreGameIcons[i])
- }
- ]
- }
- );
- }
- }
- options.children.push({
- name: 'more-game',
- color: cc.hexToColor('#000000'),
- width: 144,
- height: this.choose(42, 32),
- x: this.choose(150, -10),
- y: this.choose(0, -75),
- components: [
- {
- name: 'label',
- string: '更多好玩',
- horizontalAlign: cc.Label.HorizontalAlign.CENTER,
- fontSize: this.choose(40, 30),
- lineHeight: this.choose(42, 32)
- }
- ]
- });
- let btnWidth = 22 * 32 / 37;
- options.children.push({
- name: 'button_arrow',
- width: btnWidth,
- height: 32,
- x: this.choose((PORTRAIT_ITEM_WIDTH / 2 - 50 - btnWidth / 2), (LANDSCAPE_ITEM_WIDTH / 2 - 45 - btnWidth / 2)),
- y: this.choose(-1, -76),
- components: [
- {
- name: 'sprite',
- type: cc.Sprite.Type.SIMPLE,
- sizeMode: cc.Sprite.SizeMode.CUSTOM,
- spriteFrame: new cc.SpriteFrame(this.greyArrow)
- }
- ]
- });
- let node = this.createNode(options);
- this.bindTouchEvent(node, () => {
- let datas = [];
- this.reportItem(datas, null, 101, 3);
- this.report(datas);
- if (typeof (wx) !== 'undefined') {
- wx.previewImage({
- urls: [this.moreGameQrcode]
- });
- }
- });
- parent.addChild(node);
- this.specPanels.push('more-game');
- return node;
- }
- drawArrow(ctx, w, h, lineWidth, color = '#999999') {
- ctx.lineWidth = lineWidth || 5;
- ctx.strokeColor = cc.hexToColor(color);
- ctx.moveTo(0, 0);
- ctx.lineTo(w, h / 2);
- ctx.lineTo(0, h);
- ctx.stroke();
- }
- createGameBanner(parent) {
- let options = {
- name: 'game-banner',
- width: this.choose(PORTRAIT_ITEM_WIDTH, LANDSCAPE_ITEM_WIDTH),
- height: this.choose(PORTRAIT_ITEM_HEIGHT, LANDSCAPE_ITEM_HEIGHT),
- y: this.choose(0, -70),
- children: [{
- name: 'game-banner-img',
- width: this.choose(PORTRAIT_ITEM_WIDTH, LANDSCAPE_ITEM_WIDTH),
- height: this.choose(PORTRAIT_ITEM_HEIGHT, LANDSCAPE_ITEM_HEIGHT),
- x: this.choose(2, 11),
- components: [{
- name: 'sprite',
- sizeMode: cc.Sprite.SizeMode.CUSTOM,
- type: cc.Sprite.Type.SIMPLE,
- spriteFrame: new cc.SpriteFrame(this.bannerImg)
- }, {
- name: 'widget',
- isAlignTop: true,
- top: this.choose(5, 9)
- }]
- }]
- };
- let node = this.createNode(options);
- this.bindTouchEvent(node, () => {
- let datas = [];
- this.reportItem(datas, null, 101, 4);
- this.report(datas);
- if (typeof (wx) !== 'undefined') {
- wx.previewImage({
- urls: [this.poster]
- });
- }
- });
- parent.addChild(node);
- this.specPanels.push('game-banner');
- return node;
- }
- initRoot() {
- this.root = new cc.Node('wx-game-cross');
- this.calSize();
- }
- initTitle() {
- this.loadRemoteImage(BLACKARROW).then((texture) => {
- this.blackArrow = texture;
- this.title = this.createTitle();
- this.title.zIndex = 1;
- this.root.addChild(this.title);
- });
- }
- calSize() {
- this.root.setPosition(0, 0);
- this.width = Math.ceil(this.window.width);
- this.height = Math.ceil(this.window.height);
- if (this.width > this.height) {
- this.mode = 'landscape';
- if (this.width / this.height > 1280 / 720) {
- this.measureScale = this.height / 720; // 比例尺,根据实际游戏高度换算
- this.root.width = this.width;
- this.root.height = 720 * this.measureScale;
- } else {
- this.measureScale = this.width / 1280; // 比例尺,根据实际游戏宽度换算
- this.root.width = 1280 * this.measureScale;
- this.root.height = this.height;
- }
- } else {
- this.mode = 'portrait';
- if (this.width / this.height > 720 / 1280) {
- this.measureScale = this.height / 1280;
- this.root.width = this.width;
- this.root.height = 1280 * this.measureScale;
- } else {
- this.measureScale = this.width / 720; // 比例尺,根据实际游戏宽度换算
- this.root.width = 720 * this.measureScale;
- this.root.height = this.height;
- }
- }
- this.root.active = false;
- }
- createBackground() {
- this.background = this.createNode({
- name: 'wx-cross-background',
- width: this.root.width,
- height: this.root.height,
- components: [
- {
- name: 'graphics',
- drawFunc: (graphics) => {
- this.drawRect(graphics, this.root.width, this.root.height, cc.hexToColor('#f5f5f5'), 256);
- }
- }
- ]
- });
- this.root.addChild(this.background);
- }
- drawRect(ctx, width, height, color = cc.Color.WHITE, opacity = 256) {
- let fillColor = color;
- // fillColor.a = opacity;
- ctx.fillColor = fillColor;
- ctx.rect(0, 0, width, height);
- ctx.fill();
- }
- drawRoundRect(ctx, width, height, color = cc.Color.WHITE, opacity = 256) {
- ctx.fillColor = color;
- ctx.fillColor.opacity = opacity;
- ctx.roundRect(0, 0, width, height, 15);
- ctx.fill();
- }
- hide() {
- this.root.active = false;
- for (let game of this.games) {
- game.exposed = false;
- }
- this.moreGameIsExposed = false;
- this.bannerIsExposed = false;
- }
- show() {
- if (this.scrollView) {
- this.firstReport();
- }
- this.root.active = true;
- }
- firstReport() {
- let datas = [];
- this.reportItem(datas, null, 100, 1);
- this.report(datas);
- this.checkExposedGames(this.firstShow);
- this.firstShow = false;
- }
- report(datas) {
- let map = {
- dtLoginTime: -1, vQimei: -1, vAppVer: -1, PlatID: -1, vOsType: -1, osversion: -1, nettype: -1, model: -1,
- iActionId: -1, iSceneLevel1: -1, iSceneLevel2: -1, iSceneLevel3: -1, iResourceId1: -1,
- iResourceId2: -1, iResourceId3: -1, iResourceId4: -1, iResourceId5: -1, iRet: -1,
- vV1: -1, vV2: -1, vV3: -1, vV4: -1, vV5: -1, vV6: -1, vV7: -1, vV8: -1, vV9: -1, vV10: -1,
- };
- return new Promise((resolve, reject) => {
- datas = datas.map(item => {
- let data = Object.assign({}, map, item);
- let content = (() => {
- let arr = [];
- Object.keys(data).forEach(key => arr.push(data[key]));
- return arr.join('|');
- })();
- return content;
- });
- this.request('POST', 'https://goplatform.minigame.qq.com/mpreport/reportplugintlog', {
- data: datas,
- session: this.session
- });
- });
- }
- choose(portraitVal, landscapeVal) {
- return this.mode == 'portrait' ? portraitVal : landscapeVal;
- }
- }
- // 营销插件渠道进入上报
- function enterReport(appid = '', userid = '') {
- let launchOptions = {
- query: ''
- };
- if (typeof (wx) != "undefined") {
- launchOptions = wx.getLaunchOptionsSync();
- }
- let plan = '';
- let query = launchOptions.query;
- const getParam = (search, key) => {
- const reg = new RegExp(`(^|&)${key}=([^&]*)(&|$)`);
- const r = search.substr(1).match(reg);
- if (r !== null) return String(decodeURIComponent(r[2]));
- return '';
- };
- if (query.scene) {
- let scene = decodeURIComponent(query.scene);
- plan = getParam(scene, 'plan');
- } else {
- if (query.path) {
- plan = getParam(query.path, 'plan');
- }
- }
- if (plan !== '') {
- let url = 'https://goplatform.minigame.qq.com/mpreport/reportsource';
- let xhr = new XMLHttpRequest();
- xhr.open('POST', url, true);
- xhr.setRequestHeader('Content-Type', 'application/json');
- if (typeof(wx) !== 'undefined') {
- xhr.send({
- appid,
- userid,
- from: '',
- plan
- });
- } else {
- xhr.send(JSON.stringify({
- appid,
- userid,
- from: '',
- plan
- }));
- }
- }
- }
- export {
- RecommendUI,
- enterReport
- }
|