mgplugin.js 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129
  1. // Learn cc.Class:
  2. // - [Chinese] http://www.cocos.com/docs/creator/scripting/class.html
  3. // - [English] http://www.cocos2d-x.org/docs/editors_and_tools/creator-chapters/scripting/class/index.html
  4. // Learn Attribute:
  5. // - [Chinese] http://www.cocos.com/docs/creator/scripting/reference/attributes.html
  6. // - [English] http://www.cocos2d-x.org/docs/editors_and_tools/creator-chapters/scripting/reference/attributes/index.html
  7. // Learn life-cycle callbacks:
  8. // - [Chinese] http://www.cocos.com/docs/creator/scripting/life-cycle-callbacks.html
  9. // - [English] http://www.cocos2d-x.org/docs/editors_and_tools/creator-chapters/scripting/life-cycle-callbacks/index.html
  10. const OFFLINE_TIPS = 'data:image/png;base64,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';
  11. const RECONNECT_BTN = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAAAzCAMAAABCDgGNAAAAZlBMVEUAAAAAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOUAiOXHNmdXAAAAIXRSTlMACH8P7PjcBPG0YFYl4NXQyr6rd2lbQjkzGpTlIHr5jJUXB7SdAAABgUlEQVRYw8zVx27CUBCF4XOLKwaXuAKG/O//kpGFnEhAkp19v9XsRjqaolemt015SdlAeikb2xv9y3RZxMairDP6i7OeXXjr9KvWszh95sPktAE3Dfn5xMK3eq+oAI620MYKewSo3jY+pECcJ9pBksdAetCLDyCyRjsxNgI+9OQOxKN2NMbA/TWr2mlXrn7O6wBkRjszGXDQtyKCOtHukhrSQqsKYqcAuBiqNZ8WbqOCMN6glRbOg1UgLHinxQzx7uO+MjHMWgoPnYLRgTeP43AMYAtXyfFxJDKYFZAZMslEcFVArhAZ9XBSUE7Qy8JZQTmDVQO5gpJDoxIGBWWAUh4mBWWCi24QxJf+4SAVoMB8VWfHKAACMRBFw8KC1qYSm7n/Ja3E0k6fV1g2ycz/SdTXQv8WOono3kK3PHoT0QTB5a0tWd10imb5GlrzGXJPrE6m0qpn0jaDUIkNyreqBkkDVXaqkmaVy98W4/U8cVwW48H57B84n6X/ZshUn8jY1xND+YFI77v8MAAAAABJRU5ErkJggg==';
  12. const PANEL = 'data:image/png;base64,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';
  13. const BAR = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAFklEQVQImWOcPHnyfwYcgAmXxKCUBAAm8ALGxCtPnQAAAABJRU5ErkJggg==';
  14. 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';
  15. const LINE = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAAABAQMAAABQVuppAAAAA1BMVEXZ2dmK1ydDAAAACklEQVQI12OAAwAACgABaQY5MgAAAABJRU5ErkJggg==';
  16. 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==';
  17. const GREYARROW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAlCAYAAABGWhk4AAABdElEQVRIS63WSU7DMBjF8X9BAgoLBiG6YbwCV2ASFPYcEwkobDgA92BBGfYMG/QkuzKRHftz4l2V6NeXZzvOgP9jCzgEnoDfxjXTz0Fw9wg4BxaAV+AR+DFpwc0eDlF/uRMuWAmvgaVIuinwUJPcJz4AjoC5vvCw4zb8DZhYkoewwu4Dx4nkJrwJ94bH4F7wFJzD34H7ts7bYOF7wEmi81Y8B1fjJbDwXeA0kfzD1fId7oFS2IxbYOE7wFlJcivscdUyH9n+s1pq4BJ8Ugvn8Jcu8CpwBSxHKrmphYVeAisRVKfObQ285tBYUqE6GKZWuAjVU1jgYtQC51CdLjoIZqMksRktSVyF5mChWqfDxJLSi17v5OhIVbHullQVmkrcGY3BOfQO0BssO8IqhKrT2KeWTgd1WoSGiTdcp72gHu4d9fAFsB0pzfz4zZ2nxxe+GVz4ch+BxZ02g/nJWwTGDheqifrMTn3LDeGqEK5v5OeuqP7vD69mZ6FJZpeeAAAAAElFTkSuQmCC';
  18. const PORTRAIT_ITEM_WIDTH = 670,
  19. PORTRAIT_ITEM_HEIGHT = 202,
  20. PORTRAIT_ITEM_SPACE = 25,
  21. LANDSCAPE_ITEM_WIDTH = 272,
  22. LANDSCAPE_ITEM_HEIGHT = 440,
  23. LANDSCAPE_ITEM_SPACE = 30;
  24. class RecommendUI {
  25. constructor(appid = 'default') {
  26. this.appid = appid;
  27. this.touching = false;
  28. this.firstShow = true;
  29. this.loadSuccess = false;
  30. this.specPanels = [];
  31. let window = cc.Canvas.instance; //获取游戏的canvas对象作为游戏窗口,以作为大小适配的基准参考
  32. if (window instanceof cc.Canvas) {
  33. this.window = window.node;
  34. this.initRoot();
  35. this.createBackground();
  36. this.initTitle();
  37. this.getSession(); // 获取上报的session
  38. this.fetchData();
  39. } else {
  40. cc.error('Can\'t find the canvas node in the current scene.');
  41. }
  42. }
  43. getSession() {
  44. let session = window.localStorage.getItem('session');
  45. if (!session) {
  46. this.request('POST', 'https://goplatform.minigame.qq.com/mplogin/getsessionid', {
  47. AppID: this.appid + ''
  48. }).then(res => {
  49. if (res.result === 0) {
  50. session = res.session;
  51. window.localStorage.setItem('session', session);
  52. this.session = session;
  53. }
  54. });
  55. } else {
  56. this.session = session;
  57. }
  58. }
  59. fetchData(reconnect = false) {
  60. this.request('GET', 'https://goplatform.minigame.qq.com/3366game/getcurrentgame?appid=' + this.appid)
  61. .then((res) => {
  62. if (res.result == 0) {
  63. this.loadSuccess = true;
  64. if (this.offlineNode) {
  65. this.offlineNode.active = false;
  66. }
  67. if (reconnect) {
  68. this.firstReport();
  69. }
  70. this.games = [];
  71. this.moreGames = [];
  72. for (let i = 0; i < res.data.Games.length; ++i) {
  73. this.games.push({
  74. app_id: res.data.Games[i]['app_id'],
  75. name: res.data.Games[i]['app_name'],
  76. icon: res.data.Games[i]['app_icon'],
  77. desc: res.data.Games[i]['app_introduction'],
  78. qrcode: res.data.Games[i]['mini_program_code']
  79. });
  80. }
  81. for (let i = 0; i < res.data.More_games.length; ++i) {
  82. this.moreGames.push({
  83. name: res.data.More_games[i]['app_name'],
  84. icon: res.data.More_games[i]['app_icon'],
  85. desc: res.data.More_games[i]['app_introduction'],
  86. qrcode: res.data.More_games[i]['mini_program_code']
  87. });
  88. }
  89. this.banner = this.choose(res.data.Banner, res.data.Banner_landscape);
  90. this.poster = res.data.App_poster;
  91. if (res.data.More_game_image) {
  92. this.moreGameQrcode = res.data.More_game_image;
  93. } else {
  94. this.moreGameQrcode = '';
  95. }
  96. this.loadResource();
  97. } else {
  98. this.loadOfflineResource();
  99. }
  100. }).catch(e => {
  101. cc.error(e);
  102. this.loadOfflineResource();
  103. });
  104. }
  105. // 拉取图片资源
  106. loadResource() {
  107. let promises = [];
  108. for (let i = 0; i < this.games.length; ++i) {
  109. promises.push(this.loadRemoteImage(this.games[i].icon)); // 游戏图标
  110. }
  111. for (let i = 0; i < this.moreGames.length; ++i) {
  112. promises.push(this.loadRemoteImage(this.moreGames[i].icon)); //更多游戏图标
  113. }
  114. promises.push(this.loadRemoteImage(this.banner));
  115. promises.push(this.loadRemoteImage(BAR));
  116. promises.push(this.loadRemoteImage(PANEL));
  117. promises.push(this.loadRemoteImage(CIRCLE));
  118. promises.push(this.loadRemoteImage(LINE));
  119. promises.push(this.loadRemoteImage(GREYARROW));
  120. Promise.all(promises).then((results) => {
  121. this.gameIcons = [];
  122. this.moreGameIcons = [];
  123. for (let i = 0; i < this.games.length; ++i) {
  124. this.gameIcons.push(results[i]);
  125. }
  126. for (let i = 0; i < this.moreGames.length; ++i) {
  127. this.moreGameIcons.push(results[i + this.games.length]);
  128. }
  129. this.bannerImg = results[this.games.length + this.moreGames.length];
  130. this.bar = results[this.games.length + this.moreGames.length + 1];
  131. this.panel = results[this.games.length + this.moreGames.length + 2];
  132. this.circle = results[this.games.length + this.moreGames.length + 3];
  133. this.line = results[this.games.length + this.moreGames.length + 4];
  134. this.greyArrow = results[this.games.length + this.moreGames.length + 5];
  135. this.createUI();
  136. }).catch((e) => {
  137. cc.error(e);
  138. });
  139. }
  140. // 拉取离线图片资源
  141. loadOfflineResource() {
  142. if (this.offlineNode) {
  143. this.offlineNode.active = true;
  144. return;
  145. }
  146. let promises = [];
  147. promises.push(this.loadRemoteImage(OFFLINE_TIPS));
  148. promises.push(this.loadRemoteImage(RECONNECT_BTN));
  149. Promise.all(promises).then((results) => {
  150. this.offlineTips = results[0];
  151. this.reconnectBtn = results[1];
  152. this.createUI();
  153. }).catch((e) => {
  154. cc.error(e);
  155. });
  156. }
  157. createNode(options) {
  158. let node = new cc.Node(options.name);
  159. let customProps = ['x', 'y', 'width', 'height', 'anchorX', 'anchorY', 'active', 'scaleX', 'scaleY', 'color', 'rotation'];
  160. if (options.components) {
  161. for (let component of options.components) {
  162. this.addComponent(node, component, options);
  163. }
  164. }
  165. for (let prop of customProps) {
  166. node[prop] = options[prop] !== undefined ? options[prop] : node[prop];
  167. if (prop == 'width' && options[prop] == 476) {
  168. window.line = node;
  169. }
  170. }
  171. if (options.children) {
  172. for (let child of options.children) {
  173. let childNode = this.createNode(child);
  174. node.addChild(childNode);
  175. }
  176. }
  177. return node;
  178. }
  179. addComponent(node, component, options) {
  180. let spriteFrames = this.uis;
  181. let props = {
  182. 'sprite': ['spriteFrame', 'type', 'sizeMode', 'trim'],
  183. 'mask': ['type', 'segements', 'alphaThreshold', 'spriteFrame'],
  184. 'richText': ['horizontalAlign', 'fontSize', 'maxWidth', 'lineHeight', 'string'],
  185. 'label': ['horizontalAlign', 'verticalAlign', 'fontSize', 'maxWidth', 'lineHeight', 'string', 'overflow'],
  186. 'widget': ['isAlignHorizontalCenter', 'isAlignVerticalCenter', 'isAlignTop', 'isAlignBottom', 'isAlignLeft', 'isAlignRight', 'top', 'bottom', 'left', 'right'],
  187. 'scrollview': ['vertical', 'horizonal', 'elastic'],
  188. 'layout': ['type', 'paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight', 'spacingX', 'spacingY'],
  189. 'graphics': [],
  190. 'scrollbar': ['direction', 'enableAutoHide'],
  191. 'blockInputEvents': []
  192. };
  193. let classes = {
  194. 'sprite': cc.Sprite,
  195. 'mask': cc.Mask,
  196. 'richText': cc.RichText,
  197. 'label': cc.Label,
  198. 'widget': cc.Widget,
  199. 'scrollview': cc.ScrollView,
  200. 'graphics': cc.Graphics,
  201. 'layout': cc.Layout,
  202. 'scrollbar': cc.Scrollbar,
  203. 'blockInputEvents': cc.BlockInputEvents
  204. };
  205. let cp = node.addComponent(classes[component.name]);
  206. if (component.name == 'graphics' && component.drawFunc) {
  207. component.drawFunc(cp);
  208. }
  209. for (let prop of props[component.name]) {
  210. // if (prop == 'sizeMode') {
  211. // debugger;
  212. // }
  213. if (prop == 'spriteFrame') {
  214. let value = component[prop];
  215. if (value != undefined) {
  216. if (typeof (value) == 'string') {
  217. cp[prop] = spriteFrames[value];
  218. }
  219. if (value instanceof cc.SpriteFrame) {
  220. cp[prop] = value;
  221. }
  222. }
  223. } else {
  224. cp[prop] = component[prop] !== undefined ? component[prop] : cp[prop];
  225. }
  226. }
  227. }
  228. request(method, url, data) {
  229. return new Promise((resolve, reject) => {
  230. let timeoutcb = setTimeout(() => {
  231. reject('timeout');
  232. }, 3000);
  233. if (typeof (wx) != "undefined") {
  234. let xhr = new XMLHttpRequest();
  235. xhr.onreadystatechange = () => {
  236. if (xhr.readyState == 4) {
  237. clearTimeout(timeoutcb);
  238. if ((xhr.status >= 200 && xhr.status < 400)) {
  239. let res = xhr.responseText;
  240. try {
  241. res = JSON.parse(res);
  242. } catch (e) {
  243. reject('json parse err');
  244. }
  245. resolve(res);
  246. } else {
  247. reject('server error: ' + xhr.status);
  248. }
  249. }
  250. };
  251. xhr.open(method, url, true);
  252. xhr.setRequestHeader('Content-Type', 'application/json');
  253. if (typeof(wx) !== 'undefined') {
  254. xhr.send(data || {});
  255. } else {
  256. xhr.send(JSON.stringify(data || {}));
  257. }
  258. } else {
  259. clearTimeout(timeoutcb);
  260. reject();
  261. }
  262. });
  263. }
  264. loadRemoteImage(url) {
  265. return new Promise((resolve, reject) => {
  266. if (url) {
  267. let image = new Image();
  268. image.src = url;
  269. image.crossOrigin = "Anonymous";
  270. image.onload = () => {
  271. let texture = new cc.Texture2D();
  272. texture.initWithElement(image);
  273. texture.handleLoadedTexture();
  274. resolve(texture);
  275. };
  276. image.onerror = () => {
  277. resolve(new cc.Texture2D());
  278. }
  279. } else {
  280. resolve(null);
  281. }
  282. });
  283. }
  284. createUI() {
  285. if (this.loadSuccess) {
  286. this.scrollView = this.createScrollView();
  287. this.root.addChild(this.scrollView);
  288. this.bindScrollEvents(this.scrollView);
  289. this.gameListContainer = this.createContainer();
  290. this.scrollView.addChild(this.gameListContainer);
  291. this.scrollView.getComponent(cc.ScrollView).content = this.gameListContainer;
  292. this.gameListPanels = this.createGameListPanels(this.gameListContainer);
  293. this.moreGamePanel = this.createMoreGamePanel(this.gameListContainer);
  294. if (this.bannerImg) {
  295. this.gameBanner = this.createGameBanner(this.gameListContainer);
  296. }
  297. } else {
  298. this.createOffLineUI();
  299. }
  300. }
  301. createOffLineUI() {
  302. let options = {
  303. name: 'offline-tips-container',
  304. width: this.choose(720, 1280),
  305. height: this.choose(1280, 720),
  306. scaleX: this.measureScale,
  307. scaleY: this.measureScale,
  308. children: [
  309. {
  310. name: 'offline-tips',
  311. width: 219,
  312. height: 265,
  313. y: this.choose(171, 27),
  314. components: [{
  315. name: 'sprite',
  316. spriteFrame: new cc.SpriteFrame(this.offlineTips)
  317. }]
  318. },
  319. {
  320. name: 'offline-text',
  321. y: this.choose(17, -127),
  322. color: cc.hexToColor('#525252'),
  323. height: 23,
  324. components: [{
  325. name: 'label',
  326. string: '您的网络貌似有问题,请刷新试试哦',
  327. fontSize: 22
  328. }]
  329. },
  330. {
  331. name: 'reconnect-btn',
  332. y: this.choose(-64, -208),
  333. components: [{
  334. name: 'sprite',
  335. spriteFrame: new cc.SpriteFrame(this.reconnectBtn)
  336. }],
  337. children: [{
  338. name: 'btn-text',
  339. color: cc.hexToColor('#3086de'),
  340. components: [{
  341. name: 'label',
  342. string: '刷新',
  343. fontSize: 28,
  344. verticalAlign: cc.Label.VerticalAlign.CENTER
  345. }]
  346. }]
  347. }
  348. ]
  349. };
  350. this.offlineNode = this.createNode(options);
  351. this.root.addChild(this.offlineNode);
  352. cc.find('reconnect-btn', this.offlineNode).on(cc.Node.EventType.TOUCH_START, (e) => {
  353. this.fetchData(true);
  354. });
  355. }
  356. createScrollView() {
  357. let options = {
  358. name: '3666-game-scrollview',
  359. width: this.mode == 'portrait' ? 720 : 1280,
  360. height: this.mode == 'portrait' ? 1280 : 720,
  361. x: 0,
  362. y: 0,
  363. components: [
  364. {
  365. name: 'scrollview',
  366. vertical: this.mode == 'portrait',
  367. horizonal: this.mode == 'landscape',
  368. elastic: false
  369. },
  370. {
  371. name: 'mask',
  372. type: cc.Mask.Type.RECT
  373. }
  374. ]
  375. // children: [
  376. // {
  377. // name: 'scroll-bar',
  378. // width: this.mode == 'portrait' ? 5 : 1120,
  379. // height: this.mode == 'portrait' ? 1120 : 5,
  380. // components: [
  381. // {
  382. // name: 'scrollbar',
  383. // direction: this.mode == 'portrait' ? cc.Scrollbar.Direction.VERTICAL : cc.Scrollbar.Direction.HORIZONTAL,
  384. // enableAutoHide: true
  385. // },
  386. // {
  387. // name: 'widget',
  388. // isAlignBottom: this.mode == 'portrait',
  389. // isAlignTop: this.mode == 'landscape',
  390. // top: 10,
  391. // bottom: 0,
  392. // isAlignRight: true,
  393. // right: this.mode == 'portrait' ? 10 : 0
  394. // },
  395. // {
  396. // name: 'graphics',
  397. // drawFunc: (graphics) => {
  398. // this.drawRect(graphics, this.mode == 'portrait' ? 5 : 1120, this.mode == 'portrait' ? 1120 : 5, cc.hexToColor('#cccccc'));
  399. // }
  400. // }
  401. // ],
  402. // children: [{
  403. // name: 'bar',
  404. // width: this.mode == 'portrait' ? 7 : 30,
  405. // height: this.mode == 'portrait' ? 30 : 7,
  406. // components: [
  407. // {
  408. // name: 'sprite',
  409. // spriteFrame: new cc.SpriteFrame(this.bar)
  410. // }
  411. // ]
  412. // }]
  413. // }
  414. // ]
  415. };
  416. let node = this.createNode(options);
  417. // let scrollBar = cc.find('scroll-bar', node);
  418. // let bar = cc.find('scroll-bar/bar', node);
  419. // scrollBar.getComponent(cc.Scrollbar).handle = bar.getComponent(cc.Sprite);
  420. // node.getComponent(cc.ScrollView).verticalScrollBar = scrollBar.getComponent(cc.Scrollbar);
  421. node.scaleX = node.scaleY = this.measureScale; // 大小适配(等比例缩放)
  422. return node;
  423. }
  424. bindScrollEvents(node) {
  425. node.on('scroll-ended', () => {
  426. this.checkExposedGames();
  427. });
  428. }
  429. // 检查曝光的游戏并上报(曝光条件:在显示屏幕区域占一半以上)
  430. checkExposedGames(first = false) {
  431. let component = this.scrollView.getComponent(cc.ScrollView);
  432. let offset = component.getScrollOffset();
  433. let gameOffset;
  434. let datas = [];
  435. if (this.mode == 'landscape') {
  436. gameOffset = -offset.x
  437. } else {
  438. gameOffset = offset.y;
  439. }
  440. if (first) gameOffset = 0;
  441. let extraNum = 2;
  442. if (!this.moreGameIcons || this.moreGameIcons.length == 0) {
  443. extraNum = 1;
  444. }
  445. // 检测游戏曝光
  446. for (let i = 0; i < this.games.length + extraNum; ++i) {
  447. let x = this.choose(145 + i * 227, 51 + i * 302);
  448. if (x > gameOffset - this.choose(PORTRAIT_ITEM_HEIGHT, LANDSCAPE_ITEM_WIDTH) / 2
  449. && x + this.choose(PORTRAIT_ITEM_HEIGHT, LANDSCAPE_ITEM_WIDTH) < gameOffset + 1280 + this.choose(PORTRAIT_ITEM_HEIGHT, LANDSCAPE_ITEM_WIDTH) / 2) {
  450. if (i < this.games.length && !this.games[i].exposed) {
  451. this.games[i].exposed = true;
  452. this.reportItem(datas, i, 100, 2);
  453. }
  454. if (i >= this.games.length) {
  455. let name = this.specPanels[i - this.games.length];
  456. if (name == 'more-game' && !this.moreGameIsExposed) {
  457. this.reportItem(datas, null, 100, 3);
  458. this.moreGameIsExposed = true;
  459. }
  460. if (name == 'game-banner' && !this.bannerIsExposed) {
  461. this.reportItem(datas, null, 100, 4);
  462. this.bannerIsExposed = true;
  463. }
  464. }
  465. } else {
  466. if (i < this.games.length) {
  467. this.games[i].exposed = false;
  468. } else {
  469. var name = this.specPanels[i - this.games.length];
  470. if (name == 'more-game') {
  471. this.moreGameIsExposed = false;
  472. }
  473. if (name == 'game-banner') {
  474. this.bannerIsExposed = false;
  475. }
  476. }
  477. }
  478. }
  479. if (datas.length > 0) {
  480. this.report(datas); // 统一批量上报
  481. }
  482. }
  483. // 生成单个上报数据
  484. reportItem(datas, i, actionId, slotId) {
  485. let data = {
  486. iSceneLevel1: 1000000,
  487. iSceneLevel2: slotId,
  488. iActionId: actionId,
  489. iResourceId2: this.appid,
  490. vV1: 1
  491. };
  492. if (i !== null) {
  493. data.iSceneLevel3 = i + 1;
  494. data.iResourceId1 = this.games[i].app_id;
  495. } else {
  496. data.iSceneLevel3 = 1;
  497. }
  498. datas.push(data);
  499. }
  500. createContainer() {
  501. let extraNum = 0;
  502. if (this.moreGameIcons && this.moreGameIcons.length > 0) {
  503. ++extraNum;
  504. }
  505. if (this.banner) {
  506. ++extraNum;
  507. }
  508. let landscapeWidth = (this.games.length + extraNum) * (LANDSCAPE_ITEM_WIDTH + LANDSCAPE_ITEM_SPACE) + 72;
  509. let portraitHeight = (this.games.length + extraNum) * (PORTRAIT_ITEM_HEIGHT + PORTRAIT_ITEM_SPACE) + 145;
  510. let options = {
  511. name: 'container',
  512. width: this.choose(720, landscapeWidth),
  513. height: this.choose(portraitHeight, 720),
  514. // x: this.choose(0, (this.games.length > 3 ? landscapeWidth / 2 - 640 : 0)),
  515. x: this.choose(0, (landscapeWidth / 2 - 640)),
  516. y: this.choose((this.games.length > 3 ? 640 - portraitHeight / 2 : 0), 0),
  517. components: [
  518. {
  519. name: 'widget',
  520. isAlignHorizontalCenter: this.mode == 'portrait',
  521. isAlignVerticalCenter: this.mode == 'landscape'
  522. },
  523. {
  524. name: 'layout',
  525. type: this.mode == 'portrait' ? cc.Layout.Type.VERTICAL : cc.Layout.Type.HORIZONTAL,
  526. paddingTop: this.choose(145 - 5, 100),
  527. // paddingBottom: this.choose(undefined, 70 - 18),
  528. paddingLeft: this.choose(0, 51 - 7),
  529. spacingY: this.choose(PORTRAIT_ITEM_SPACE - 20, 0),
  530. spacingX: this.choose(0, LANDSCAPE_ITEM_SPACE - 16)
  531. }
  532. ]
  533. };
  534. let node = this.createNode(options);
  535. return node;
  536. }
  537. createGameListPanels(parent) {
  538. let panels = [];
  539. let panelFrame = new cc.SpriteFrame(this.panel);
  540. panelFrame.insetTop = 13;
  541. panelFrame.insetBottom = 23;
  542. panelFrame.insetLeft = 17;
  543. panelFrame.insetRight = 19;
  544. for (let i = 0; i < this.games.length; ++i) {
  545. let desc = this.games[i].desc;
  546. if (this.mode == 'portrait') {
  547. if (desc.length > 16) {
  548. desc = desc.substr(0, 15) + '...';
  549. }
  550. } else {
  551. if (desc.length > 20) {
  552. desc = desc.substr(0, 19) + '...';
  553. }
  554. }
  555. let realWidth = this.choose(PORTRAIT_ITEM_WIDTH + 16, LANDSCAPE_ITEM_WIDTH + 16);
  556. let realHeight = this.choose(PORTRAIT_ITEM_HEIGHT + 20, LANDSCAPE_ITEM_HEIGHT + 20);
  557. let options = {
  558. name: 'game-item',
  559. width: realWidth,
  560. x: 0,
  561. y: this.choose(0, -80),
  562. anchorX: 0.5 - 1 / (realWidth * 2),
  563. anchorY: 0.5 + 5 / realHeight,
  564. height: realHeight,
  565. components: [
  566. {
  567. name: 'sprite',
  568. spriteFrame: panelFrame,
  569. type: cc.Sprite.Type.SLICED,
  570. sizeMode: cc.Sprite.SizeMode.CUSTOM,
  571. trim: false
  572. }
  573. ],
  574. children: [
  575. {
  576. name: 'icon-bg',
  577. width: 130,
  578. height: 130,
  579. x: this.choose(-250, 0),
  580. y: this.choose(0, 200),
  581. components: [{
  582. name: 'sprite',
  583. spriteFrame: new cc.SpriteFrame(this.circle)
  584. }],
  585. active: this.mode == 'landscape'
  586. },
  587. {
  588. name: 'icon',
  589. x: this.choose(-250, 0),
  590. y: this.choose(0, 205),
  591. width: 122,
  592. height: 122,
  593. components: [
  594. {
  595. name: 'sprite',
  596. sizeMode: cc.Sprite.SizeMode.CUSTOM,
  597. type: cc.Sprite.Type.SIMPLE,
  598. spriteFrame: new cc.SpriteFrame(this.gameIcons[i])
  599. }
  600. ]
  601. },
  602. {
  603. name: 'name',
  604. x: this.choose(-165, 0),
  605. y: this.choose(55, 78),
  606. width: this.choose(440, 205),
  607. height: this.choose(48, 72),
  608. color: cc.hexToColor('#000000'),
  609. anchorX: this.choose(0, 0.5),
  610. anchorY: this.choose(1, 1),
  611. components: [{
  612. name: 'label',
  613. horizontalAlign: this.choose(cc.Label.HorizontalAlign.LEFT, cc.Label.HorizontalAlign.CENTER),
  614. overflow: cc.Label.Overflow.RESIZE_HEIGHT,
  615. fontSize: this.choose(40, 30),
  616. lineHeight: this.choose(48, 42),
  617. string: this.games[i].name.length > 12 ? this.games[i].name.substr(0, 11) + '...' : this.games[i].name
  618. }],
  619. },
  620. {
  621. name: 'line',
  622. // width: this.choose(476, 200),
  623. scaleX: this.choose(476 / 66, 200 / 66),
  624. height: 1,
  625. x: this.choose(73, 0),
  626. y: this.choose(1, -40),
  627. active: this.mode == 'portrait',
  628. components: [
  629. {
  630. name: 'sprite',
  631. spriteFrame: new cc.SpriteFrame(this.line),
  632. type: cc.Sprite.Type.SIMPLE,
  633. sizeMode: cc.Sprite.SizeMode.COSTOM
  634. // drawFunc: (graphics) => {
  635. // graphics.lineWidth = 1;
  636. // graphics.strokeColor = cc.hexToColor('#999999');
  637. // graphics.moveTo(0, 0);
  638. // graphics.lineTo(476, 0);
  639. // graphics.stroke();
  640. // }
  641. }
  642. ]
  643. },
  644. {
  645. name: 'desc',
  646. x: this.choose(-165, 0),
  647. y: this.choose(-11, -26),
  648. width: this.choose(416, 220),
  649. height: this.choose(31, 36),
  650. anchorX: this.choose(0, 0.5),
  651. anchorY: this.choose(1, 1),
  652. color: cc.hexToColor('#999999'),
  653. components: [{
  654. name: 'label',
  655. horizontalAlign: this.choose(cc.Label.HorizontalAlign.LEFT, cc.Label.HorizontalAlign.CENTER),
  656. verticalAlign: cc.Label.VerticalAlign.TOP,
  657. overflow: cc.Label.Overflow.RESIZE_HEIGHT,
  658. fontSize: this.choose(26, 22),
  659. lineHeight: this.choose(31, 36),
  660. string: desc
  661. }]
  662. }
  663. ],
  664. };
  665. let node = this.createNode(options);
  666. this.bindTouchEvent(node, ((currentIndex) => {
  667. return () => {
  668. let datas = [];
  669. this.reportItem(datas, currentIndex, 101, 2);
  670. this.report(datas);
  671. this.showQrcode(this.games[currentIndex]);
  672. };
  673. })(i));
  674. panels.push(node);
  675. }
  676. for (let panel of panels) {
  677. parent.addChild(panel);
  678. }
  679. return panels;
  680. }
  681. bindTouchEvent(node, cb) {
  682. let distance, x1, y1, x2, y2;
  683. node.on(cc.Node.EventType.TOUCH_START, (e) => {
  684. let loc = e.getLocation();
  685. x1 = loc.x;
  686. y1 = loc.y;
  687. });
  688. node.on(cc.Node.EventType.TOUCH_END, (e) => {
  689. let loc = e.getLocation();
  690. x2 = loc.x;
  691. y2 = loc.y;
  692. distance = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
  693. if (distance < 25) {
  694. if (!this.touching) {
  695. this.touching = true;
  696. setTimeout(() => {
  697. this.touching = false;
  698. }, 10);
  699. cb();
  700. }
  701. }
  702. });
  703. }
  704. showQrcode(data) {
  705. if (typeof (wx) != 'undefined') {
  706. wx.previewImage({
  707. urls: [data.qrcode]
  708. });
  709. }
  710. }
  711. createTitle() {
  712. let options = {
  713. name: 'title',
  714. // x: -this.width / 2,
  715. // y: -this.height / 2,
  716. x: 0,
  717. y: this.root.height / 2 - 60 * this.measureScale,
  718. width: this.root.width,
  719. height: 120 * this.measureScale,
  720. components: [
  721. // {
  722. // name: 'widget',
  723. // isAlignTop: true,
  724. // top: 0
  725. // },
  726. {
  727. name: 'blockInputEvents'
  728. },
  729. {
  730. name: 'graphics',
  731. drawFunc: (graphics) => {
  732. this.drawRect(graphics, this.root.width,
  733. 120 * this.measureScale);
  734. }
  735. }
  736. ],
  737. children: [
  738. {
  739. name: 'title-container',
  740. width: this.root.width,
  741. height: 120 * this.measureScale,
  742. children: [
  743. {
  744. name: 'arrow_container',
  745. width: this.choose(21 * 0.8 + 60, 21 * 0.8 + 50),
  746. height: 120,
  747. scaleX: this.measureScale,
  748. scaleY: this.measureScale,
  749. children: [{
  750. name: 'button_arrow',
  751. width: 21,
  752. height: 37,
  753. components: [
  754. {
  755. name: 'sprite',
  756. type: cc.Sprite.Type.SIMPLE,
  757. sizeMode: cc.Sprite.SizeMode.CUSTOM,
  758. spriteFrame: new cc.SpriteFrame(this.blackArrow)
  759. }
  760. ]
  761. }],
  762. components: [{
  763. name: 'widget',
  764. isAlignLeft: true,
  765. left: 0,
  766. isAlignVerticalCenter: true
  767. }]
  768. },
  769. {
  770. name: 'title-text',
  771. color: cc.hexToColor('#000000'),
  772. height: 46,
  773. x: this.choose(0, -438),
  774. scaleX: this.measureScale,
  775. scaleY: this.measureScale,
  776. components: [
  777. {
  778. name: 'richText',
  779. string: '<bold>精彩游戏推荐<bold>',
  780. horizontalAlign: cc.RichText.HorizontalAlign.CENTER,
  781. fontSize: 34,
  782. lineHeight: 36
  783. },
  784. {
  785. name: 'widget',
  786. isAlignHorizontalCenter: this.choose(true, false),
  787. isAlignVerticalCenter: true,
  788. isAlignLeft: this.mode == 'landscape',
  789. left: 90 * this.measureScale
  790. }
  791. ]
  792. }
  793. ]
  794. }
  795. ]
  796. };
  797. let node = this.createNode(options);
  798. let backBtn = cc.find('title-container/arrow_container', node);
  799. backBtn.on(cc.Node.EventType.TOUCH_START, () => {
  800. this.hide();
  801. });
  802. return node;
  803. }
  804. createMoreGamePanel(parent) {
  805. if (!this.moreGameIcons || this.moreGameIcons.length == 0) {
  806. return null;
  807. }
  808. let panels = [];
  809. let panelFrame = new cc.SpriteFrame(this.panel);
  810. panelFrame.insetTop = 13;
  811. panelFrame.insetBottom = 23;
  812. panelFrame.insetLeft = 17;
  813. panelFrame.insetRight = 19;
  814. let realWidth = this.choose(PORTRAIT_ITEM_WIDTH + 16, LANDSCAPE_ITEM_WIDTH + 16);
  815. let realHeight = this.choose(PORTRAIT_ITEM_HEIGHT + 20, LANDSCAPE_ITEM_HEIGHT + 20);
  816. let options = {
  817. name: 'more-game-panel',
  818. width: realWidth,
  819. height: realHeight,
  820. anchorX: 0.5 - 1 / realWidth,
  821. anchorY: 0.5 + 5 / realHeight,
  822. y: this.choose(0, -80),
  823. components: [
  824. // {
  825. // name: 'graphics',
  826. // drawFunc: (graphics) => {
  827. // this.drawRoundRect(graphics, this.choose(PORTRAIT_ITEM_WIDTH, 250), this.choose(PORTRAIT_ITEM_HEIGHT, 400));
  828. // }
  829. // }
  830. {
  831. name: 'sprite',
  832. spriteFrame: panelFrame,
  833. type: cc.Sprite.Type.SLICED,
  834. sizeMode: cc.Sprite.SizeMode.CUSTOM,
  835. trim: false
  836. }
  837. ],
  838. children: []
  839. };
  840. for (let i = 0; i < 3; ++i) {
  841. if (this.moreGameIcons && this.moreGameIcons[i]) {
  842. options.children.push(
  843. {
  844. name: 'icon',
  845. width: this.choose(86 + 2 * 86 / 120, 70 + 2 * 70 / 120),
  846. height: this.choose(86 + 2 * 86 / 120, 70 + 2 * 70 / 120),
  847. x: this.choose(-267 + 106 * i, -76 + 76 * i),
  848. y: this.choose(0, 50),
  849. components: [
  850. {
  851. name: 'sprite',
  852. sizeMode: cc.Sprite.SizeMode.CUSTOM,
  853. type: cc.Sprite.Type.SIMPLE,
  854. spriteFrame: new cc.SpriteFrame(this.moreGameIcons[i])
  855. }
  856. ]
  857. }
  858. );
  859. }
  860. }
  861. options.children.push({
  862. name: 'more-game',
  863. color: cc.hexToColor('#000000'),
  864. width: 144,
  865. height: this.choose(42, 32),
  866. x: this.choose(150, -10),
  867. y: this.choose(0, -75),
  868. components: [
  869. {
  870. name: 'label',
  871. string: '更多好玩',
  872. horizontalAlign: cc.Label.HorizontalAlign.CENTER,
  873. fontSize: this.choose(40, 30),
  874. lineHeight: this.choose(42, 32)
  875. }
  876. ]
  877. });
  878. let btnWidth = 22 * 32 / 37;
  879. options.children.push({
  880. name: 'button_arrow',
  881. width: btnWidth,
  882. height: 32,
  883. x: this.choose((PORTRAIT_ITEM_WIDTH / 2 - 50 - btnWidth / 2), (LANDSCAPE_ITEM_WIDTH / 2 - 45 - btnWidth / 2)),
  884. y: this.choose(-1, -76),
  885. components: [
  886. {
  887. name: 'sprite',
  888. type: cc.Sprite.Type.SIMPLE,
  889. sizeMode: cc.Sprite.SizeMode.CUSTOM,
  890. spriteFrame: new cc.SpriteFrame(this.greyArrow)
  891. }
  892. ]
  893. });
  894. let node = this.createNode(options);
  895. this.bindTouchEvent(node, () => {
  896. let datas = [];
  897. this.reportItem(datas, null, 101, 3);
  898. this.report(datas);
  899. if (typeof (wx) !== 'undefined') {
  900. wx.previewImage({
  901. urls: [this.moreGameQrcode]
  902. });
  903. }
  904. });
  905. parent.addChild(node);
  906. this.specPanels.push('more-game');
  907. return node;
  908. }
  909. drawArrow(ctx, w, h, lineWidth, color = '#999999') {
  910. ctx.lineWidth = lineWidth || 5;
  911. ctx.strokeColor = cc.hexToColor(color);
  912. ctx.moveTo(0, 0);
  913. ctx.lineTo(w, h / 2);
  914. ctx.lineTo(0, h);
  915. ctx.stroke();
  916. }
  917. createGameBanner(parent) {
  918. let options = {
  919. name: 'game-banner',
  920. width: this.choose(PORTRAIT_ITEM_WIDTH, LANDSCAPE_ITEM_WIDTH),
  921. height: this.choose(PORTRAIT_ITEM_HEIGHT, LANDSCAPE_ITEM_HEIGHT),
  922. y: this.choose(0, -70),
  923. children: [{
  924. name: 'game-banner-img',
  925. width: this.choose(PORTRAIT_ITEM_WIDTH, LANDSCAPE_ITEM_WIDTH),
  926. height: this.choose(PORTRAIT_ITEM_HEIGHT, LANDSCAPE_ITEM_HEIGHT),
  927. x: this.choose(2, 11),
  928. components: [{
  929. name: 'sprite',
  930. sizeMode: cc.Sprite.SizeMode.CUSTOM,
  931. type: cc.Sprite.Type.SIMPLE,
  932. spriteFrame: new cc.SpriteFrame(this.bannerImg)
  933. }, {
  934. name: 'widget',
  935. isAlignTop: true,
  936. top: this.choose(5, 9)
  937. }]
  938. }]
  939. };
  940. let node = this.createNode(options);
  941. this.bindTouchEvent(node, () => {
  942. let datas = [];
  943. this.reportItem(datas, null, 101, 4);
  944. this.report(datas);
  945. if (typeof (wx) !== 'undefined') {
  946. wx.previewImage({
  947. urls: [this.poster]
  948. });
  949. }
  950. });
  951. parent.addChild(node);
  952. this.specPanels.push('game-banner');
  953. return node;
  954. }
  955. initRoot() {
  956. this.root = new cc.Node('wx-game-cross');
  957. this.calSize();
  958. }
  959. initTitle() {
  960. this.loadRemoteImage(BLACKARROW).then((texture) => {
  961. this.blackArrow = texture;
  962. this.title = this.createTitle();
  963. this.title.zIndex = 1;
  964. this.root.addChild(this.title);
  965. });
  966. }
  967. calSize() {
  968. this.root.setPosition(0, 0);
  969. this.width = Math.ceil(this.window.width);
  970. this.height = Math.ceil(this.window.height);
  971. if (this.width > this.height) {
  972. this.mode = 'landscape';
  973. if (this.width / this.height > 1280 / 720) {
  974. this.measureScale = this.height / 720; // 比例尺,根据实际游戏高度换算
  975. this.root.width = this.width;
  976. this.root.height = 720 * this.measureScale;
  977. } else {
  978. this.measureScale = this.width / 1280; // 比例尺,根据实际游戏宽度换算
  979. this.root.width = 1280 * this.measureScale;
  980. this.root.height = this.height;
  981. }
  982. } else {
  983. this.mode = 'portrait';
  984. if (this.width / this.height > 720 / 1280) {
  985. this.measureScale = this.height / 1280;
  986. this.root.width = this.width;
  987. this.root.height = 1280 * this.measureScale;
  988. } else {
  989. this.measureScale = this.width / 720; // 比例尺,根据实际游戏宽度换算
  990. this.root.width = 720 * this.measureScale;
  991. this.root.height = this.height;
  992. }
  993. }
  994. this.root.active = false;
  995. }
  996. createBackground() {
  997. this.background = this.createNode({
  998. name: 'wx-cross-background',
  999. width: this.root.width,
  1000. height: this.root.height,
  1001. components: [
  1002. {
  1003. name: 'graphics',
  1004. drawFunc: (graphics) => {
  1005. this.drawRect(graphics, this.root.width, this.root.height, cc.hexToColor('#f5f5f5'), 256);
  1006. }
  1007. }
  1008. ]
  1009. });
  1010. this.root.addChild(this.background);
  1011. }
  1012. drawRect(ctx, width, height, color = cc.Color.WHITE, opacity = 256) {
  1013. let fillColor = color;
  1014. // fillColor.a = opacity;
  1015. ctx.fillColor = fillColor;
  1016. ctx.rect(0, 0, width, height);
  1017. ctx.fill();
  1018. }
  1019. drawRoundRect(ctx, width, height, color = cc.Color.WHITE, opacity = 256) {
  1020. ctx.fillColor = color;
  1021. ctx.fillColor.opacity = opacity;
  1022. ctx.roundRect(0, 0, width, height, 15);
  1023. ctx.fill();
  1024. }
  1025. hide() {
  1026. this.root.active = false;
  1027. for (let game of this.games) {
  1028. game.exposed = false;
  1029. }
  1030. this.moreGameIsExposed = false;
  1031. this.bannerIsExposed = false;
  1032. }
  1033. show() {
  1034. if (this.scrollView) {
  1035. this.firstReport();
  1036. }
  1037. this.root.active = true;
  1038. }
  1039. firstReport() {
  1040. let datas = [];
  1041. this.reportItem(datas, null, 100, 1);
  1042. this.report(datas);
  1043. this.checkExposedGames(this.firstShow);
  1044. this.firstShow = false;
  1045. }
  1046. report(datas) {
  1047. let map = {
  1048. dtLoginTime: -1, vQimei: -1, vAppVer: -1, PlatID: -1, vOsType: -1, osversion: -1, nettype: -1, model: -1,
  1049. iActionId: -1, iSceneLevel1: -1, iSceneLevel2: -1, iSceneLevel3: -1, iResourceId1: -1,
  1050. iResourceId2: -1, iResourceId3: -1, iResourceId4: -1, iResourceId5: -1, iRet: -1,
  1051. vV1: -1, vV2: -1, vV3: -1, vV4: -1, vV5: -1, vV6: -1, vV7: -1, vV8: -1, vV9: -1, vV10: -1,
  1052. };
  1053. return new Promise((resolve, reject) => {
  1054. datas = datas.map(item => {
  1055. let data = Object.assign({}, map, item);
  1056. let content = (() => {
  1057. let arr = [];
  1058. Object.keys(data).forEach(key => arr.push(data[key]));
  1059. return arr.join('|');
  1060. })();
  1061. return content;
  1062. });
  1063. this.request('POST', 'https://goplatform.minigame.qq.com/mpreport/reportplugintlog', {
  1064. data: datas,
  1065. session: this.session
  1066. });
  1067. });
  1068. }
  1069. choose(portraitVal, landscapeVal) {
  1070. return this.mode == 'portrait' ? portraitVal : landscapeVal;
  1071. }
  1072. }
  1073. // 营销插件渠道进入上报
  1074. function enterReport(appid = '', userid = '') {
  1075. let launchOptions = {
  1076. query: ''
  1077. };
  1078. if (typeof (wx) != "undefined") {
  1079. launchOptions = wx.getLaunchOptionsSync();
  1080. }
  1081. let plan = '';
  1082. let query = launchOptions.query;
  1083. const getParam = (search, key) => {
  1084. const reg = new RegExp(`(^|&)${key}=([^&]*)(&|$)`);
  1085. const r = search.substr(1).match(reg);
  1086. if (r !== null) return String(decodeURIComponent(r[2]));
  1087. return '';
  1088. };
  1089. if (query.scene) {
  1090. let scene = decodeURIComponent(query.scene);
  1091. plan = getParam(scene, 'plan');
  1092. } else {
  1093. if (query.path) {
  1094. plan = getParam(query.path, 'plan');
  1095. }
  1096. }
  1097. if (plan !== '') {
  1098. let url = 'https://goplatform.minigame.qq.com/mpreport/reportsource';
  1099. let xhr = new XMLHttpRequest();
  1100. xhr.open('POST', url, true);
  1101. xhr.setRequestHeader('Content-Type', 'application/json');
  1102. if (typeof(wx) !== 'undefined') {
  1103. xhr.send({
  1104. appid,
  1105. userid,
  1106. from: '',
  1107. plan
  1108. });
  1109. } else {
  1110. xhr.send(JSON.stringify({
  1111. appid,
  1112. userid,
  1113. from: '',
  1114. plan
  1115. }));
  1116. }
  1117. }
  1118. }
  1119. export {
  1120. RecommendUI,
  1121. enterReport
  1122. }