diff --git a/.claude/hooks/check-redlines.js b/.claude/hooks/check-redlines.js deleted file mode 100644 index 1135584..0000000 --- a/.claude/hooks/check-redlines.js +++ /dev/null @@ -1,213 +0,0 @@ -#!/usr/bin/env node -// 机械红线校验(只覆盖“可机器判定、低误报”的硬红线;判断类规范不在此列)。 -// -// 运行模式: -// (默认,PreToolUse 钩子)读 stdin 工具调用 JSON,命中即 deny 阻止 Write/Edit。 -// --staged (pre-commit·严格)扫暂存文件“整文件内容”,命中即非零退出、阻断提交。 -// --staged-diff (pre-commit·增量)只查本次“新增行”,老代码存量违规不阻塞——适合已有 -// 开发量的老项目回迁:新代码从此强制合规、旧债日后碰到再还。 -// --scan-all (报告)扫全仓库可编辑正式代码的 ES5 存量违规,只打印、退出 0、不阻断。 -// -// 覆盖:A. 可编辑范围(路径级,禁改平台/vendor/00_Surface/02_Input/server 平台,app.js 例外) -// B. 严格 ES5(运行时正式 .js 禁箭头/模板串/class/let/const;测试脚本放行现代语法) -// 本脚本自身是 Node 工具,不受被检规则约束。 - -var fs = require('fs'); -var cp = require('child_process'); - -function norm(p) { return String(p || '').replace(/\\/g, '/'); } -// 归一为带前导斜杠,使绝对路径与仓库相对路径统一可匹配。 -function m(p) { return '/' + norm(p).replace(/^\/+/, ''); } - -function forbiddenReason(p) { - p = m(p); - if (/\/js\/vendor\//.test(p)) return '第三方/引擎 js/vendor/ 禁止修改'; - if (/\/js\/00_Surface\//.test(p)) return '平台代码 js/00_Surface/ 禁止修改'; - if (/\/02_SubGame_Input\.js$/.test(p)) return '受限契约文件 02_SubGame_Input.js 完全不碰'; - if (/\/server\/packet\.js$/.test(p)) return '服务端收包入口 server/packet.js 禁止修改'; - if (/\/server\/applist\.js$/.test(p)) return '服务端应用注册表 server/applist.js 禁止修改'; - if (/\/server\/class\//.test(p)) return '平台三层路由基类 server/class/ 禁止修改'; - if (/\/server\/youle\//.test(p) && !/\/server\/youle\/app\.js$/.test(p)) - return 'youle 平台代码 server/youle/ 禁止修改(仅 app.js 为接入注册点例外)'; - return null; -} - -function isRuntimeJs(p) { - p = m(p); - if (!/\.js$/.test(p)) return false; - if (/\.min\.js$/.test(p)) return false; - if (/\/(node_modules|\.claude|docs|client\/generated)\//.test(p)) return false; - if (/\/js\/vendor\//.test(p) || /\/js\/00_Surface\//.test(p)) return false; - if (/(^|\/)tests?\//.test(p) || /\.(test|spec)\.js$/.test(p)) return false; // 测试可用现代语法 - return /\/client\/js\//.test(p) || /\/server\//.test(p); -} - -// 去块注释(保留换行以维持行号),逐行去行注释与 '..'/".." 字符串(保留反引号以检测模板串)。 -function stripForScan(src) { - src = src.replace(/\/\*[\s\S]*?\*\//g, function (mm) { return mm.replace(/[^\n]/g, ' '); }); - return src.split('\n').map(function (line) { - var s = line.replace(/\/\/.*$/, ''); - s = s.replace(/'(?:\\.|[^'\\])*'/g, "''"); - s = s.replace(/"(?:\\.|[^"\\])*"/g, '""'); - return s; - }); -} - -var ES5_RULES = [ - { re: /=>/, msg: '箭头函数(=>)——请用 function' }, - { re: /`/, msg: '模板字符串(反引号)——请用字符串拼接' }, - { re: /\bclass\s+[A-Za-z_$]/, msg: 'class 声明——请用 Object.create 继承' }, - { re: /\b(?:let|const)\s+[A-Za-z_$[{]/, msg: 'let/const 声明——请用 var' } -]; - -// 扫描已 strip 的行数组;onlyLines 为 Set 时只查这些行号(1 基),null=全查。 -function scanStripped(lines, onlyLines) { - var out = []; - for (var i = 0; i < lines.length; i++) { - if (onlyLines && !onlyLines.has(i + 1)) continue; - for (var r = 0; r < ES5_RULES.length; r++) { - if (ES5_RULES[r].re.test(lines[i])) { - out.push({ line: i + 1, msg: ES5_RULES[r].msg, text: lines[i].trim().slice(0, 80) }); - } - } - } - return out; -} - -// 对「路径 + 完整内容」做检查(PreToolUse 用)。 -function checkOne(p, content) { - var problems = []; - var fr = forbiddenReason(p); - if (fr) problems.push('【可编辑范围】' + fr); - if (content != null && isRuntimeJs(p)) { - scanStripped(stripForScan(content), null).forEach(function (v) { - problems.push('【严格 ES5】第 ' + v.line + ' 行 ' + v.msg + ': ' + v.text); - }); - } - return problems; -} - -// ---------- git 辅助(--staged / --staged-diff / --scan-all 用) ---------- - -function gitStaged() { - try { - return cp.execSync('git diff --cached --name-only --diff-filter=ACM', { encoding: 'utf8' }) - .split('\n').map(function (s) { return s.trim(); }).filter(Boolean); - } catch (e) { return []; } -} -function stagedContent(name) { - try { return cp.execSync('git show ":' + name + '"', { encoding: 'utf8' }); } catch (e) { return null; } -} -// 本次暂存 diff 里“新增行”的新文件行号集合。 -function addedLines(name) { - var set = {}, has = function (n) { return set[n] === true; }; - var out; - try { out = cp.execSync('git diff --cached -U0 -- "' + name + '"', { encoding: 'utf8' }); } - catch (e) { return { has: function () { return false; } }; } - var cur = 0; - out.split('\n').forEach(function (l) { - var mh = l.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/); - if (mh) { cur = parseInt(mh[1], 10); return; } - if (l.charAt(0) === '+' && l.substr(0, 3) !== '+++') { set[cur] = true; cur++; return; } - // '-' 删除行不推进新文件行号;'\' 无换行标记忽略 - }); - return { has: has }; -} - -function checkStagedFile(name, diffMode) { - var probs = []; - var fr = forbiddenReason(name); - if (fr) probs.push('【可编辑范围】' + fr); - if (isRuntimeJs(name)) { - var content = stagedContent(name); - if (content != null) { - var lines = stripForScan(content); - var only = diffMode ? addedLines(name) : null; - for (var i = 0; i < lines.length; i++) { - if (only && !only.has(i + 1)) continue; - for (var r = 0; r < ES5_RULES.length; r++) { - if (ES5_RULES[r].re.test(lines[i])) { - probs.push('【严格 ES5】第 ' + (i + 1) + ' 行 ' + ES5_RULES[r].msg + ': ' + lines[i].trim().slice(0, 80)); - } - } - } - } - } - return probs; -} - -function runStaged(diffMode) { - var all = []; - gitStaged().forEach(function (name) { - var probs = checkStagedFile(norm(name), diffMode); - if (probs.length) all.push(' ' + name + '\n - ' + probs.join('\n - ')); - }); - if (all.length) { - process.stderr.write('\n✗ 机械红线校验未通过' + (diffMode ? '(仅查本次新增行)' : '') + - ',提交被阻止:\n' + all.join('\n') + - '\n\n修正后重新提交(这些是文档记载对应过真实事故的硬红线;不要用 --no-verify 绕过)。\n\n'); - process.exit(1); - } - process.exit(0); -} - -// 存量违规报告:只看“可编辑的正式运行时 js”的 ES5 违规;平台文件(本就禁改)不计为存量债。 -function scanAll() { - var files; - try { files = cp.execSync('git ls-files', { encoding: 'utf8' }).split('\n').map(function (s) { return s.trim(); }).filter(Boolean); } - catch (e) { console.log('(非 git 仓库,跳过存量扫描)'); process.exit(0); } - var scanned = 0, bad = 0, total = 0, rows = []; - files.forEach(function (name) { - var p = norm(name); - if (!isRuntimeJs(p) || forbiddenReason(p)) return; - var content = null; - try { content = fs.readFileSync(p, 'utf8'); } catch (e) { return; } - scanned++; - var v = scanStripped(stripForScan(content), null); - if (v.length) { bad++; total += v.length; rows.push(' ' + name + ' (' + v.length + ' 处:第 ' + v.map(function (x) { return x.line; }).join('/') + ' 行)'); } - }); - console.log('存量 ES5 违规扫描(可编辑正式代码,' + scanned + ' 文件):'); - if (bad) { - console.log(' 发现 ' + bad + ' 个文件、' + total + ' 处违规(不阻塞,日后碰到逐步还):'); - console.log(rows.join('\n')); - } else { - console.log(' ✓ 可编辑正式代码零 ES5 存量违规。'); - } - process.exit(0); -} - -function runPreToolUse() { - var chunks = []; - process.stdin.on('data', function (c) { chunks.push(c); }); - process.stdin.on('end', function () { - var probs = []; - try { - var input = JSON.parse(Buffer.concat(chunks).toString('utf8') || '{}'); - var ti = input.tool_input || {}; - var p = norm(ti.file_path || ''); - if (!p) process.exit(0); - var content = null; - if (typeof ti.content === 'string') content = ti.content; - else if (typeof ti.new_string === 'string') content = ti.new_string; - else if (Array.isArray(ti.edits)) - content = ti.edits.map(function (e) { return e && e.new_string; }).filter(function (s) { return typeof s === 'string'; }).join('\n'); - probs = checkOne(p, content); - } catch (e) { process.exit(0); } - if (probs.length) { - process.stdout.write(JSON.stringify({ - hookSpecificOutput: { - hookEventName: 'PreToolUse', - permissionDecision: 'deny', - permissionDecisionReason: '机械红线校验拦截(改正后重试):\n- ' + probs.join('\n- ') - } - })); - } - process.exit(0); - }); -} - -var argv = process.argv; -if (argv.indexOf('--staged-diff') !== -1) runStaged(true); -else if (argv.indexOf('--staged') !== -1) runStaged(false); -else if (argv.indexOf('--scan-all') !== -1) scanAll(); -else runPreToolUse(); diff --git a/.claude/hooks/remind-docs.js b/.claude/hooks/remind-docs.js deleted file mode 100644 index 6d12ed5..0000000 --- a/.claude/hooks/remind-docs.js +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env node -// PreToolUse 钩子:编辑 client/** 或 server/** 时,把「必须严格遵守的完整开发规范」注入上下文。 -// -// 策略(对应用户要求:三套文档全部规范时刻遵守、新会话也一样): -// - 每个文档目录,每会话「首次」编辑相关区域时全量注入其所有 .md 全文; -// - 同会话之后再改同区域,只给简短「已注入、继续遵守」提醒,避免重复刷屏; -// - 会话级去重用 .claude/.spec-injected/ 下的哨兵文件;SessionStart 钩子会在 -// 每个新会话开始时清空该目录 → 新会话必然重新注入。 -// - 改 docs/ 本身不打扰。 -// -// 本脚本是「工具代码」,只在 Node(Claude Code 宿主)里跑,不受项目 ES5 红线约束。 - -var fs = require('fs'); -var path = require('path'); - -var HOOK_DIR = __dirname; // .../.claude/hooks -var PROJECT_DIR = path.resolve(HOOK_DIR, '..', '..'); // 项目根 -var SENTINEL_DIR = path.join(PROJECT_DIR, '.claude', '.spec-injected'); - -function slug(relDir) { return relDir.replace(/[^A-Za-z0-9]+/g, '_'); } - -function alreadyInjected(relDir) { - try { return fs.existsSync(path.join(SENTINEL_DIR, slug(relDir))); } catch (e) { return false; } -} - -function markInjected(relDir) { - try { - fs.mkdirSync(SENTINEL_DIR, { recursive: true }); - fs.writeFileSync(path.join(SENTINEL_DIR, slug(relDir)), '1'); - } catch (e) {} -} - -// 读取某目录下的编号正文 .md(按文件名排序),拼成一段带分隔标题的全文。 -// 排除 README.md:它已被 CLAUDE.md 用 @import 常驻每次会话上下文,注入里再带就是重复。 -function readDirDocs(relDir) { - var abs = path.join(PROJECT_DIR, relDir); - var files; - try { files = fs.readdirSync(abs); } catch (e) { return ''; } - var out = []; - files.filter(function (f) { return /\.md$/i.test(f) && !/^README\.md$/i.test(f); }) - .sort() - .forEach(function (f) { - try { - out.push('===== ' + relDir + '/' + f + ' =====\n' + - fs.readFileSync(path.join(abs, f), 'utf8')); - } catch (e) {} - }); - return out.join('\n\n'); -} - -var chunks = []; -process.stdin.on('data', function (c) { chunks.push(c); }); -process.stdin.on('end', function () { - var context = ''; - try { - var input = JSON.parse(Buffer.concat(chunks).toString('utf8') || '{}'); - var p = String((input.tool_input && input.tool_input.file_path) || '').replace(/\\/g, '/'); - - var dirs = null, area = ''; - if (/\/docs\//.test(p)) { - dirs = null; // 改文档本身不提醒 - } else if (/\/server\//.test(p)) { - area = '服务端'; - dirs = ['docs/server/development-guide', 'docs/games/engineering']; - } else if (/\/client\/js\//.test(p) || /\/codes\/shared\//.test(p)) { - area = '客户端'; - dirs = ['docs/client/development-guide', 'docs/games/engineering']; - } - - if (dirs) { - var pending = []; - for (var i = 0; i < dirs.length; i++) { - if (!alreadyInjected(dirs[i])) { pending.push(dirs[i]); } - } - - if (pending.length) { - var full = []; - pending.forEach(function (d) { - var txt = readDirDocs(d); - if (txt) { full.push(txt); } - markInjected(d); - }); - context = - '【必须严格遵守 · ' + area + '开发规范(本会话首次注入编号正文全文)】\n' + - '你正在修改' + area + '代码。下面是本次及后续所有改动都必须时刻遵守的完整规范正文' + - '(' + dirs.join('、') + ';各目录 README 的红线速查/一页纸总则已随 CLAUDE.md 常驻上下文,此处不再重复)。' + - '逐条落实,勿凭记忆越线;dev-guide 与 engineering 冲突时以 dev-guide 硬红线为准。\n\n' + - full.join('\n\n'); - } else { - context = - '【必须严格遵守 · ' + area + '开发规范】本会话已注入完整规范(' + dirs.join('、') + - ')。继续严格遵守;细节记不清就回看已注入全文或对应编号文档,不要绕过任何红线与规范。'; - } - } - } catch (e) { - context = ''; - } - - if (context) { - process.stdout.write(JSON.stringify({ - hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: context } - })); - } - process.exit(0); -}); diff --git a/.claude/settings.json b/.claude/settings.json index 0b3da80..e69de29 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1,43 +0,0 @@ -{ - "hooks": { - "SessionStart": [ - { - "hooks": [ - { - "type": "command", - "command": "rm -rf \"$CLAUDE_PROJECT_DIR/.claude/.spec-injected\"" - } - ] - } - ], - "PostCompact": [ - { - "hooks": [ - { - "type": "command", - "command": "rm -rf \"$CLAUDE_PROJECT_DIR/.claude/.spec-injected\"" - } - ] - } - ], - "PreToolUse": [ - { - "matcher": "Edit|Write|MultiEdit", - "hooks": [ - { - "type": "command", - "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/check-redlines.js\"", - "timeout": 10, - "statusMessage": "校验机械红线…" - }, - { - "type": "command", - "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/remind-docs.js\"", - "timeout": 15, - "statusMessage": "注入/校验开发规范…" - } - ] - } - ] - } -} diff --git a/.githooks/pre-commit b/.githooks/pre-commit deleted file mode 100644 index 8a45653..0000000 --- a/.githooks/pre-commit +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -# 机械红线校验:对本次暂存做「可编辑范围 + 严格 ES5」硬检查,命中即阻断提交。 -# 工具无关——Claude Code、别的编辑器、人手改,提交都过这道闸。 -# 模式(本地 git 配置 redlines.stagedmode): -# 未设 / 非 diff → 严格:整文件扫描(模板等干净仓库用) -# diff → 增量:只查本次新增行(已有开发量的老项目回迁用) -# 启用(每个克隆一次性):git config core.hooksPath .githooks (或跑 setup-redlines.sh) -MODE="$(git config --get redlines.stagedmode 2>/dev/null)" -if [ "$MODE" = "diff" ]; then FLAG="--staged-diff"; else FLAG="--staged"; fi -exec node "$(git rev-parse --show-toplevel)/.claude/hooks/check-redlines.js" "$FLAG" diff --git a/CLAUDE.md b/CLAUDE.md index 55ea7b0..af237a4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,12 +1,12 @@ # CLAUDE.md -本文件为 Claude Code(claude.ai/code)在本仓库中工作时提供指导。**它是入口与强制指引**:三套文档的 README(含各自「红线速查 / 一页纸总则」)已通过 `@import` 常驻上下文(见下「文档」一节),**红线以它们为权威、始终在上下文里,本文件不再另抄一份**;规范的完整细节在 `docs/` 编号文档里,改动前先读对应文档。 +本文件为 Claude Code(claude.ai/code)在本仓库中工作时提供指导。**它是入口与强制指引**:三套文档的「红线速查 / 一页纸总则」单页已通过 `@import` 常驻上下文(见下「文档」一节),**红线以它们为权威、始终在上下文里,本文件不再另抄一份**;规范的完整细节在 `docs/` 编号文档里,改动前先读对应文档。 ## 这是一个什么仓库 一个友乐/gameabc 房卡类小游戏平台:浏览器端由私有的 `gameabc.min.js` 2D Canvas 引擎驱动,服务端是一个 Node.js 游戏服务器平台(`youle` 应用),双方通过 WebSocket/HTTP 收发 JSON 包通信。项目根目录**没有 `package.json`、没有 npm 构建/lint/测试流水线**——这是纯静态 JS:客户端靠 ` - + + - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file diff --git a/client/js/00_Surface/04_Data.js b/client/js/00_Surface/04_Data.js index 8321e70..0f464ba 100644 --- a/client/js/00_Surface/04_Data.js +++ b/client/js/00_Surface/04_Data.js @@ -142,7 +142,7 @@ GameData.hallConfigName = ["enablePay", 'wareHouse',//是否开启仓库功能0->不开启1->开启保险箱不开启赠送2->开启赠送不开启保险箱3->开启星星赠送(开启保险箱)4->开启房卡赠送(开启保险箱)5->开启星星房卡赠送(开启保险箱) 'betaText',//版本号后的beta显示内容 'launchImgUrl',//启动页图片地址 - 'shareType:',//分享朋友圈类型0->链接分享 1->图片分享 + 'shareType',//分享朋友圈类型0->链接分享 1->图片分享 'shareImgUrl',//分享朋友圈图片链接 'launchWaitTime',//启动等待时间 'shareBgUrl',//分享背景图片 @@ -151,7 +151,8 @@ GameData.hallConfigName = ["enablePay", 'channelKey',//支付key 'payCSS',//支付css 'payJS',//支付js - 'openVideo' + 'openVideo', + 'showVisitor'//是否显示游客登陆 ];//是否开启视频]; GameData.hallConfig = { enablePay:0, @@ -185,6 +186,7 @@ GameData.hallConfig = { payCSS:"",//支付css payJS:"",//支付js openVideo:0,//是否开启视频 + showVisitor:0//是否显示游客登陆 }; GameData.starName = "星星"; GameData.roomCardName = "房卡"; diff --git a/client/js/00_Surface/05_Func.js b/client/js/00_Surface/05_Func.js index 6689ccc..a08656e 100644 --- a/client/js/00_Surface/05_Func.js +++ b/client/js/00_Surface/05_Func.js @@ -15,16 +15,16 @@ */ var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ -var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ -var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ +var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ +var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ /* * These are the functions you'll usually want to call * They take string arguments and return either hex or base-64 encoded strings */ -function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));} -function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));} -function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));} +function hex_md5(s) { return binl2hex(core_md5(str2binl(s), s.length * chrsz)); } +function b64_md5(s) { return binl2b64(core_md5(str2binl(s), s.length * chrsz)); } +function str_md5(s) { return binl2str(core_md5(str2binl(s), s.length * chrsz)); } function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); } function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); } function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); } @@ -32,230 +32,211 @@ function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); } /* * Perform a simple self-test to see if the VM is working */ -function md5_vm_test() -{ - return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; +function md5_vm_test() { + return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; } /* * Calculate the MD5 of an array of little-endian words, and a bit length */ -function core_md5(x, len) -{ - /* append padding */ - x[len >> 5] |= 0x80 << ((len) % 32); - x[(((len + 64) >>> 9) << 4) + 14] = len; +function core_md5(x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << ((len) % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; - var a = 1732584193; - var b = -271733879; - var c = -1732584194; - var d = 271733878; + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; - for(var i = 0; i < x.length; i += 16) - { - var olda = a; - var oldb = b; - var oldc = c; - var oldd = d; + for (var i = 0; i < x.length; i += 16) { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; - a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); - d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); - c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); - b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); - a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); - d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); - c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); - b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); - a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); - d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); - c = md5_ff(c, d, a, b, x[i+10], 17, -42063); - b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); - a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); - d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); - c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); - b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); + a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936); + d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897); + d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); + d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i + 10], 17, -42063); + b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); + d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); - a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); - d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); - c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); - b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); - a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); - d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); - c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); - b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); - a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); - d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); - c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); - b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); - a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); - d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); - c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); - b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); + a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510); + d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); + c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302); + a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691); + d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083); + c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438); + d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); + c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); + d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784); + c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); - a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); - d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); - c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); - b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); - a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); - d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); - c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); - b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); - a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); - d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); - c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); - b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); - a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); - d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); - c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); - b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); + a = md5_hh(a, b, c, d, x[i + 5], 4, -378558); + d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); + d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174); + d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222); + c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487); + d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651); - a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); - d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); - c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); - b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); - a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); - d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); - c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); - b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); - a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); - d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); - c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); - b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); - a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); - d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); - c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); - b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); + a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844); + d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); + d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); + d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070); + d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551); - a = safe_add(a, olda); - b = safe_add(b, oldb); - c = safe_add(c, oldc); - d = safe_add(d, oldd); - } - return Array(a, b, c, d); + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + } + return Array(a, b, c, d); } /* * These functions implement the four basic operations the algorithm uses. */ -function md5_cmn(q, a, b, x, s, t) -{ - return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); +function md5_cmn(q, a, b, x, s, t) { + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); } -function md5_ff(a, b, c, d, x, s, t) -{ - return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); +function md5_ff(a, b, c, d, x, s, t) { + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); } -function md5_gg(a, b, c, d, x, s, t) -{ - return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); +function md5_gg(a, b, c, d, x, s, t) { + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); } -function md5_hh(a, b, c, d, x, s, t) -{ - return md5_cmn(b ^ c ^ d, a, b, x, s, t); +function md5_hh(a, b, c, d, x, s, t) { + return md5_cmn(b ^ c ^ d, a, b, x, s, t); } -function md5_ii(a, b, c, d, x, s, t) -{ - return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); +function md5_ii(a, b, c, d, x, s, t) { + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); } /* * Calculate the HMAC-MD5, of a key and some data */ -function core_hmac_md5(key, data) -{ - var bkey = str2binl(key); - if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz); +function core_hmac_md5(key, data) { + var bkey = str2binl(key); + if (bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz); - var ipad = Array(16), opad = Array(16); - for(var i = 0; i < 16; i++) - { - ipad[i] = bkey[i] ^ 0x36363636; - opad[i] = bkey[i] ^ 0x5C5C5C5C; - } + var ipad = Array(16), opad = Array(16); + for (var i = 0; i < 16; i++) { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } - var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); - return core_md5(opad.concat(hash), 512 + 128); + var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); + return core_md5(opad.concat(hash), 512 + 128); } /* * Add integers, wrapping at 2^32. This uses 16-bit operations internally * to work around bugs in some JS interpreters. */ -function safe_add(x, y) -{ - var lsw = (x & 0xFFFF) + (y & 0xFFFF); - var msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); +function safe_add(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); } /* * Bitwise rotate a 32-bit number to the left. */ -function bit_rol(num, cnt) -{ - return (num << cnt) | (num >>> (32 - cnt)); +function bit_rol(num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)); } /* * Convert a string to an array of little-endian words * If chrsz is ASCII, characters >255 have their hi-byte silently ignored. */ -function str2binl(str) -{ - var bin = Array(); - var mask = (1 << chrsz) - 1; - for(var i = 0; i < str.length * chrsz; i += chrsz) - bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32); - return bin; +function str2binl(str) { + var bin = Array(); + var mask = (1 << chrsz) - 1; + for (var i = 0; i < str.length * chrsz; i += chrsz) + bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32); + return bin; } /* * Convert an array of little-endian words to a string */ -function binl2str(bin) -{ - var str = ""; - var mask = (1 << chrsz) - 1; - for(var i = 0; i < bin.length * 32; i += chrsz) - str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask); - return str; +function binl2str(bin) { + var str = ""; + var mask = (1 << chrsz) - 1; + for (var i = 0; i < bin.length * 32; i += chrsz) + str += String.fromCharCode((bin[i >> 5] >>> (i % 32)) & mask); + return str; } /* * Convert an array of little-endian words to a hex string. */ -function binl2hex(binarray) -{ - var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; - var str = ""; - for(var i = 0; i < binarray.length * 4; i++) - { - str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) + - hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF); - } - return str; +function binl2hex(binarray) { + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var str = ""; + for (var i = 0; i < binarray.length * 4; i++) { + str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) + + hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF); + } + return str; } /* * Convert an array of little-endian words to a base-64 string */ -function binl2b64(binarray) -{ - var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - var str = ""; - for(var i = 0; i < binarray.length * 4; i += 3) - { - var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16) - | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 ) - | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF); - for(var j = 0; j < 4; j++) - { - if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; - else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); - } - } - return str; +function binl2b64(binarray) { + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + for (var i = 0; i < binarray.length * 4; i += 3) { + var triplet = (((binarray[i >> 2] >> 8 * (i % 4)) & 0xFF) << 16) + | (((binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4)) & 0xFF) << 8) + | ((binarray[i + 2 >> 2] >> 8 * ((i + 2) % 4)) & 0xFF); + for (var j = 0; j < 4; j++) { + if (i * 8 + j * 6 > binarray.length * 32) str += b64pad; + else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F); + } + } + return str; } var _context = null; @@ -266,239 +247,239 @@ _gameSoundsObj.completed = false; _gameSoundsObj.soundList = {}; _gameSoundsObj.requestList = {}; _gameSoundsObj.autoBgmList = {}; -_gameSoundsObj.loadAudio = function(item,callback){ - var src = "assets/wav/"+item.src; - if (!_context) callback('Audio Downloader: no web audio context.',null); +_gameSoundsObj.loadAudio = function (item, callback) { + var src = "assets/wav/" + item.src; + if (!_context) callback('Audio Downloader: no web audio context.', null); //var request = new XMLHttpRequest(); - //request.open("GET", src, true); - //request.responseType = "arraybuffer"; + //request.open("GET", src, true); + //request.responseType = "arraybuffer"; - //request.onload = function () { - //_context["decodeAudioData"](request.response, function(buffer){ - //item.buffer = buffer; - //_gameSoundsObj.soundList[item.id] = item; - //_gameSoundsObj.soundList[item.id].touched = false; - //callback(null, item.src); - //}, function(){ - //callback('decode error - ' + item.src,null); - //}); - //}; + //request.onload = function () { + //_context["decodeAudioData"](request.response, function(buffer){ + //item.buffer = buffer; + //_gameSoundsObj.soundList[item.id] = item; + //_gameSoundsObj.soundList[item.id].touched = false; + //callback(null, item.src); + //}, function(){ + //callback('decode error - ' + item.src,null); + //}); + //}; - //request.onerror = function(){ - //callback('request error - ' + item.src,null); - //}; + //request.onerror = function(){ + //callback('request error - ' + item.src,null); + //}; - //request.send(); - _gameSoundsObj.requestList[item.src] = new XMLHttpRequest(); - _gameSoundsObj.requestList[item.src].open("GET", src, true); - _gameSoundsObj.requestList[item.src].responseType = "arraybuffer"; + //request.send(); + _gameSoundsObj.requestList[item.src] = new XMLHttpRequest(); + _gameSoundsObj.requestList[item.src].open("GET", src, true); + _gameSoundsObj.requestList[item.src].responseType = "arraybuffer"; - _gameSoundsObj.requestList[item.src].onload = function () { - _context["decodeAudioData"](_gameSoundsObj.requestList[item.src].response, function(buffer){ - item.buffer = buffer; - _gameSoundsObj.completedLoad++; - //logmessage(_gameSoundsObj.completedLoad+"/"+_gameSoundsObj.loadCount,1); - _gameSoundsObj.soundList[item.id] = item; - _gameSoundsObj.soundList[item.id].touched = false; - //var source = _context.createBufferSource(); + _gameSoundsObj.requestList[item.src].onload = function () { + _context["decodeAudioData"](_gameSoundsObj.requestList[item.src].response, function (buffer) { + item.buffer = buffer; + _gameSoundsObj.completedLoad++; + //logmessage(_gameSoundsObj.completedLoad+"/"+_gameSoundsObj.loadCount,1); + _gameSoundsObj.soundList[item.id] = item; + _gameSoundsObj.soundList[item.id].touched = false; + //var source = _context.createBufferSource(); //source.buffer = _gameSoundsObj.soundList[item.id].buffer;// //source.connect(_context.destination);// - callback(null, item.src); - }, function(){ - callback('decode error - ' + item.src,null); - }); - }; + callback(null, item.src); + }, function () { + callback('decode error - ' + item.src, null); + }); + }; - _gameSoundsObj.requestList[item.src].onerror = function(){ - callback('request error - ' + item.src,null); - }; + _gameSoundsObj.requestList[item.src].onerror = function () { + callback('request error - ' + item.src, null); + }; - _gameSoundsObj.requestList[item.src].send(); - if(GameData.OS == ConstVal.OS.apple){ + _gameSoundsObj.requestList[item.src].send(); + if (GameData.OS == ConstVal.OS.apple) { document.addEventListener('touchstart', function () { - //logmessage("touchstart1",1); - if(!_gameSoundsObj.completed){ - //logmessage("touchstart2",1); - var scount = 0; - for(src in _gameSoundsObj.soundList){ - scount++; + //logmessage("touchstart1",1); + if (!_gameSoundsObj.completed) { + //logmessage("touchstart2",1); + var scount = 0; + for (src in _gameSoundsObj.soundList) { + scount++; //for(var i=0;i<_gameSoundsObj.soundList[src].sourceList.length;i++){ - try{ - if(!_gameSoundsObj.soundList[src].touched){ - //logmessage("touched"+_gameSoundsObj.soundList[src].id,1); - _gameSoundsObj.soundList[src].touched = true; - _gameSoundsObj.soundList[src].connected = true; - var source = _context.createBufferSource(); - source.buffer = _gameSoundsObj.soundList[src].buffer;// - source.connect(_context.destination);// - } - - }catch(e){ - + try { + if (!_gameSoundsObj.soundList[src].touched) { + //logmessage("touched"+_gameSoundsObj.soundList[src].id,1); + _gameSoundsObj.soundList[src].touched = true; + _gameSoundsObj.soundList[src].connected = true; + var source = _context.createBufferSource(); + source.buffer = _gameSoundsObj.soundList[src].buffer;// + source.connect(_context.destination);// } + + } catch (e) { + + } //} } - for(src in _gameSoundsObj.autoBgmList){ - try{ - - //logmessage(src+"touched:"+_gameSoundsObj.soundList[src].touched+"、connected:"+_gameSoundsObj.soundList[src].connected,1); - if(_gameSoundsObj.soundList[src].touched && _gameSoundsObj.soundList[src].connected){ - //logmessage("autoBgmList:"+_gameSoundsObj.soundList[src].id,1); - _gameSoundsObj.play(src,true); - delete _gameSoundsObj.autoBgmList.src; - break; - } - - }catch(e){ + for (src in _gameSoundsObj.autoBgmList) { + try { + //logmessage(src+"touched:"+_gameSoundsObj.soundList[src].touched+"、connected:"+_gameSoundsObj.soundList[src].connected,1); + if (_gameSoundsObj.soundList[src].touched && _gameSoundsObj.soundList[src].connected) { + //logmessage("autoBgmList:"+_gameSoundsObj.soundList[src].id,1); + _gameSoundsObj.play(src, true); + delete _gameSoundsObj.autoBgmList.src; + break; } + + } catch (e) { + + } } - - for(var i=0;i0){//背景音 + if (loop && item.sourceList.length > 0) {//背景音 return; } //logmessage("_gameSoundsObj.play2",1); var source = _context.createBufferSource(); - - source.buffer = item.buffer;// - source.connect(_context.destination);// - source.loop = loop; - source.playing = true; - source.isEnded = false; - source.onended = function(){ - this.isEnded = true; - this.playing = false; - _gameSoundsObj.clearEndedSource(); + + source.buffer = item.buffer;// + source.connect(_context.destination);// + source.loop = loop; + source.playing = true; + source.isEnded = false; + source.onended = function () { + this.isEnded = true; + this.playing = false; + _gameSoundsObj.clearEndedSource(); } - item.sourceList.push(source); + item.sourceList.push(source); //logmessage("play",1); - source.start(0);// - }catch(e){ + source.start(0);// + } catch (e) { } - + } -_gameSoundsObj.stop = function(src){ - try{ +_gameSoundsObj.stop = function (src) { + try { //logmessage("stop1:"+src,1); - for(var i=0;i<_gameSoundsObj.soundList[src].sourceList.length;i++){ + for (var i = 0; i < _gameSoundsObj.soundList[src].sourceList.length; i++) { //logmessage("stop2:"+src,1); - if(!_gameSoundsObj.soundList[src].sourceList[i].isEnded){ - + if (!_gameSoundsObj.soundList[src].sourceList[i].isEnded) { + _gameSoundsObj.soundList[src].sourceList[i].stop(); _gameSoundsObj.soundList[src].sourceList[i].isEnded = true; - _gameSoundsObj.soundList[src].sourceList[i].splice(i,1); + _gameSoundsObj.soundList[src].sourceList[i].splice(i, 1); i--; } - + } - for(src in _gameSoundsObj.autoBgmList){ - try{ + for (src in _gameSoundsObj.autoBgmList) { + try { //logmessage(src+"touched2:"+_gameSoundsObj.soundList[src].touched+"、connected:"+_gameSoundsObj.soundList[src].connected,1); - if(_gameSoundsObj.soundList[src]){ + if (_gameSoundsObj.soundList[src]) { //logmessage("autoBgmList2:"+_gameSoundsObj.soundList[src].id,1); delete _gameSoundsObj.autoBgmList.src; } - }catch(e){ + } catch (e) { } - } - }catch(e){ + } + } catch (e) { } } -_gameSoundsObj.clearAllSource = function(src){ - for(var i=0;i<_gameSoundsObj.soundList[src].sourceList.length;i++){ - try{ - if(!_gameSoundsObj.soundList[src].sourceList[i].isEnded){ +_gameSoundsObj.clearAllSource = function (src) { + for (var i = 0; i < _gameSoundsObj.soundList[src].sourceList.length; i++) { + try { + if (!_gameSoundsObj.soundList[src].sourceList[i].isEnded) { _gameSoundsObj.soundList[src].sourceList[i].stop(); } _gameSoundsObj.soundList[src].sourceList = null; - }catch(e){ + } catch (e) { } } _gameSoundsObj.soundList[src].sourceList = []; } -_gameSoundsObj.clearEndedSource = function(){ - for(src in _gameSoundsObj.soundList){ - for(var i=0;i<_gameSoundsObj.soundList[src].sourceList.length;i++){ - try{ - if(_gameSoundsObj.soundList[src].sourceList[i].isEnded){ - _gameSoundsObj.soundList[src].sourceList.splice(i,1); +_gameSoundsObj.clearEndedSource = function () { + for (src in _gameSoundsObj.soundList) { + for (var i = 0; i < _gameSoundsObj.soundList[src].sourceList.length; i++) { + try { + if (_gameSoundsObj.soundList[src].sourceList[i].isEnded) { + _gameSoundsObj.soundList[src].sourceList.splice(i, 1); i--; } - }catch(e){ + } catch (e) { } } @@ -506,126 +487,126 @@ _gameSoundsObj.clearEndedSource = function(){ } var dynamicLoading = { - css: function(path){ - if(!path || path.length === 0){ + css: function (path) { + if (!path || path.length === 0) { throw new Error('argument "path" is required !'); } var head = document.getElementsByTagName('head')[0]; - var link = document.createElement('link'); - link.href = path; - link.rel = 'stylesheet'; - link.type = 'text/css'; - head.appendChild(link); - }, - js: function(path){ - if(!path || path.length === 0){ + var link = document.createElement('link'); + link.href = path; + link.rel = 'stylesheet'; + link.type = 'text/css'; + head.appendChild(link); + }, + js: function (path) { + if (!path || path.length === 0) { throw new Error('argument "path" is required !'); } var head = document.getElementsByTagName('head')[0]; - var script = document.createElement('script'); - script.src = path; - script.type = 'text/javascript'; - head.appendChild(script); - } + var script = document.createElement('script'); + script.src = path; + script.type = 'text/javascript'; + head.appendChild(script); + } } -var setPostUrl = function setPostUrl(url){ +var setPostUrl = function setPostUrl(url) { GameData.sharePostUrl = url; } -var isArray = function isArray(o){ - return Object.prototype.toString.call(o)=='[object Array]'; +var isArray = function isArray(o) { + return Object.prototype.toString.call(o) == '[object Array]'; } -var gameLog = function gameLog(msg,mode){ +var gameLog = function gameLog(msg, mode) { //logmessage(msg,1); } -var checkMobile = function checkMobile(sMobile){ - //var sMobile = document.mobileform.mobile.value +var checkMobile = function checkMobile(sMobile) { + //var sMobile = document.mobileform.mobile.value ///^1[3|4|5|7|8|9][0-9]{9}$/ - if(!(/^1[3|4|5|6|7|8|9][0-9]{9}$/.test(sMobile))){ - return false; - } - return true; -} -var sliceStrByKey = function(str,key){ + if (!(/^1[3|4|5|6|7|8|9][0-9]{9}$/.test(sMobile))) { + return false; + } + return true; +} +var sliceStrByKey = function (str, key) { var idx = str.indexOf(key); - if(idx>-1){ - return str.slice(0,idx); + if (idx > -1) { + return str.slice(0, idx); } return str; } //获取网页参数 -var fGetQuery = function(name){//获取参数值 +var fGetQuery = function (name) {//获取参数值 //var sUrl = window.location.search.substr(1); //var r = sUrl.match(new RegExp("(^|&)" + name + "=([^&]*)(&|$)")); //return (r == null ? null : unescape(r[2])); - if(typeof(window.location.search)!="undefined"&&window.location.search!=''){ + if (typeof (window.location.search) != "undefined" && window.location.search != '') { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); - var r = window.location.search.substr(1).match(reg); - if (r != null) { - return r[2]; - } - } - return null; + var r = window.location.search.substr(1).match(reg); + if (r != null) { + return r[2]; + } + } + return null; } -var fGetQuery1 = function(url,name){//获取参数值 +var fGetQuery1 = function (url, name) {//获取参数值 //if(typeof(window.location.search)!="undefined"&&window.location.search!=''){ - var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); - var r = url.slice(url.indexOf("?"),url.length).substr(1).match(reg); - if (r != null) { - return r[2]; - } - //} - return null; + var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); + var r = url.slice(url.indexOf("?"), url.length).substr(1).match(reg); + if (r != null) { + return r[2]; + } + //} + return null; } -var fixUrl = function(url){ - +var fixUrl = function (url) { + var idx = url.indexOf("?"); - if(idx>-1){ - var preUrl = url.substr(0,idx+1); - var subUrl = url.substr(idx+1,url.length); - return preUrl+min_replaceAll(subUrl,"\\?","&"); - }else{ + if (idx > -1) { + var preUrl = url.substr(0, idx + 1); + var subUrl = url.substr(idx + 1, url.length); + return preUrl + min_replaceAll(subUrl, "\\?", "&"); + } else { return url; } } -var addParam = function(url,paramKey,paramVal){ - var andStr = "?"; - var beforeparam = url.indexOf("?"); - if(beforeparam != -1){ - andStr = "&"; - } - return url + andStr + paramKey + "="+ encodeURIComponent(paramVal); +var addParam = function (url, paramKey, paramVal) { + var andStr = "?"; + var beforeparam = url.indexOf("?"); + if (beforeparam != -1) { + andStr = "&"; + } + return url + andStr + paramKey + "=" + encodeURIComponent(paramVal); } -var delParam = function(url,paramKey){ - var urlParam = url.substr(url.indexOf("?")+1); - var beforeUrl = url.substr(0,url.indexOf("?")); - var nextUrl = ""; - - var arr = new Array(); - if(urlParam!=""){ - var urlParamArr = urlParam.split("&"); - - for(var i=0;i0){ - nextUrl = "?"+arr.join("&"); - } - url = beforeUrl+nextUrl; - return url; +var delParam = function (url, paramKey) { + var urlParam = url.substr(url.indexOf("?") + 1); + var beforeUrl = url.substr(0, url.indexOf("?")); + var nextUrl = ""; + + var arr = new Array(); + if (urlParam != "") { + var urlParamArr = urlParam.split("&"); + + for (var i = 0; i < urlParamArr.length; i++) { + var paramArr = urlParamArr[i].split("="); + if (paramArr[0] != paramKey) { + arr.push(urlParamArr[i]); + } + } + } + + if (arr.length > 0) { + nextUrl = "?" + arr.join("&"); + } + url = beforeUrl + nextUrl; + return url; } -var Func=Func||{}; +var Func = Func || {}; var bForcepc = fGetQuery("dv") == "pc"; //获取当前系统 -var fBrowserRedirect = function(){ -//function fBrowserRedirect(){ +var fBrowserRedirect = function () { + //function fBrowserRedirect(){ var sUserAgent = navigator.userAgent.toLowerCase(); var bIsIpad = sUserAgent.match(/ipad/i) == "ipad"; var bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os"; @@ -635,65 +616,65 @@ var fBrowserRedirect = function(){ var bIsAndroid = sUserAgent.match(/android/i) == "android"; var bIsCE = sUserAgent.match(/windows ce/i) == "windows ce"; var bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile"; - if(bIsIpad||bIsIphoneOs){ + if (bIsIpad || bIsIphoneOs) { return ConstVal.OS.apple; } - if(bIsAndroid){ + if (bIsAndroid) { return ConstVal.OS.android; } - if(bIsWM){ + if (bIsWM) { return ConstVal.OS.winphone; } return ConstVal.OS.other; } -var getQueryString =function(name) { - if(typeof(window.location.search)!="undefined"&&window.location.search!=''){ +var getQueryString = function (name) { + if (typeof (window.location.search) != "undefined" && window.location.search != '') { - var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); - var r = window.location.search.substr(1).match(reg); - if (r !== null) { - return r[2]; - } - } - return null; + var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); + var r = window.location.search.substr(1).match(reg); + if (r !== null) { + return r[2]; + } + } + return null; } -var strToJson =function(str){ - var json = eval('(' + str + ')'); - return json; +var strToJson = function (str) { + var json = eval('(' + str + ')'); + return json; //return JSON.parse(str); - + } //获取字符字节长度 -String.prototype.gblen = function() { - var len = 0; - for (var i=0; i127 || this.charCodeAt(i)==94) { - len += 2; - } else { - len ++; - } - } - return len; +String.prototype.gblen = function () { + var len = 0; + for (var i = 0; i < this.length; i++) { + if (this.charCodeAt(i) > 127 || this.charCodeAt(i) == 94) { + len += 2; + } else { + len++; + } + } + return len; } //克隆数组 -Func.cloneArray = function(input_arr){ +Func.cloneArray = function (input_arr) { return [].concat(input_arr); } //精确乘法 -Func.accMul = function(arg1,arg2){ - var m=0,s1=arg1.toString(),s2=arg2.toString(); - try{m+=s1.split(".")[1].length}catch(e){} - try{m+=s2.split(".")[1].length}catch(e){} - return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m); +Func.accMul = function (arg1, arg2) { + var m = 0, s1 = arg1.toString(), s2 = arg2.toString(); + try { m += s1.split(".")[1].length } catch (e) { } + try { m += s2.split(".")[1].length } catch (e) { } + return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m); } //敏感词过滤 -Func.filter = function(str) { +Func.filter = function (str) { for (var i = 0; i < arrBan.length; i++) { - if(str.indexOf(arrBan[i])>=0 && arrBan[i]){ + if (str.indexOf(arrBan[i]) >= 0 && arrBan[i]) { return true; } } @@ -702,46 +683,45 @@ Func.filter = function(str) { } //字符是否为空 -Func.strisNull =function( str ){ - if ( str == "" ) return true; +Func.strisNull = function (str) { + if (str == "") return true; var regu = "^[ ]+$"; var re = new RegExp(regu); return re.test(str); } -Func.setTextArea = function(id,isResize,maxlen){//精灵id,是否禁用大小调整,最大输入长度 +Func.setTextArea = function (id, isResize, maxlen) {//精灵id,是否禁用大小调整,最大输入长度 var obj = null; - obj = gameabc_face.getdiv("div"+id); - if(isResize){ + obj = gameabc_face.getdiv("div" + id); + if (isResize) { obj.style.resize = "none"; } - if(maxlen){ - try{ + if (maxlen) { + try { maxlen = Number(maxlen); - }catch(e){ - return ; - } - obj.maxLength = maxlen; - } + } catch (e) { + return; + } + obj.maxLength = maxlen; + } obj = null; } -Func.setInput = function(id,maxlen){//精灵id,是否禁用大小调整,最大输入长度 - other_setdom("div"+id,"maxlength",maxlen); +Func.setInput = function (id, maxlen) {//精灵id,是否禁用大小调整,最大输入长度 + other_setdom("div" + id, "maxlength", maxlen); } -Func.SetText=function(_msg,len){ - var text_copy=""; - for(var k=0;k<_msg.length;k++){ - text_copy+=_msg[k]; - if(k%len==0&&k!=0){ - text_copy+="\n"; +Func.SetText = function (_msg, len) { + var text_copy = ""; + for (var k = 0; k < _msg.length; k++) { + text_copy += _msg[k]; + if (k % len == 0 && k != 0) { + text_copy += "\n"; } } return text_copy; } -Func.AjaxHttp = function(_data, func_callbackSucc, func_callbackFail, obj_inputmsg) -{ -// +Func.AjaxHttp = function (_data, func_callbackSucc, func_callbackFail, obj_inputmsg) { + // var obj_config = {}; obj_config.url = GameData.AjaxUrl; obj_config.callbackdata = obj_inputmsg; @@ -751,8 +731,7 @@ Func.AjaxHttp = function(_data, func_callbackSucc, func_callbackFail, obj_inputm obj_config.error = func_callbackFail; min_http(obj_config); } -Func.AjaxHttp2 = function(_url,_data, func_callbackSucc, func_callbackFail, obj_inputmsg) -{ +Func.AjaxHttp2 = function (_url, _data, func_callbackSucc, func_callbackFail, obj_inputmsg) { var obj_config = {}; obj_config.url = _url; @@ -763,11 +742,10 @@ Func.AjaxHttp2 = function(_url,_data, func_callbackSucc, func_callbackFail, obj_ obj_config.error = func_callbackFail; min_http(obj_config); } -Func.AjaxHttp3 = function(_url,_data, func_callbackSucc, func_callbackFail, obj_inputmsg) -{ +Func.AjaxHttp3 = function (_url, _data, func_callbackSucc, func_callbackFail, obj_inputmsg) { //var sData = "?"; //for(var key in _data){ - //sData += "&"+key+"="+_data[key]; + //sData += "&"+key+"="+_data[key]; //} var obj_config = {}; obj_config.url = _url; @@ -778,44 +756,44 @@ Func.AjaxHttp3 = function(_url,_data, func_callbackSucc, func_callbackFail, obj_ obj_config.error = func_callbackFail; min_http(obj_config); } -var IDValidator = function() { +var IDValidator = function () { var param = { - error : { - longNumber : '长数字存在精度问题,请使用字符串传值! Long number is not allowed, because the precision of the Number In JavaScript.' + error: { + longNumber: '长数字存在精度问题,请使用字符串传值! Long number is not allowed, because the precision of the Number In JavaScript.' } }; var util = { - checkArg : function(id) { + checkArg: function (id) { var argType = (typeof id); switch (argType) { - case 'number': - // long number not allowed - id = id.toString(); - if (id.length > 15) { - this.error(param.error.longNumber); + case 'number': + // long number not allowed + id = id.toString(); + if (id.length > 15) { + this.error(param.error.longNumber); + return false; + } + break; + case 'string': + break; + default: return false; - } - break; - case 'string': - break; - default: - return false; } id = id.toUpperCase(); var code = null; if (id.length === 18) { // 18位 code = { - body : id.slice(0, 17), - checkBit : id.slice(-1), - type : 18 + body: id.slice(0, 17), + checkBit: id.slice(-1), + type: 18 }; } else if (id.length === 15) { // 15位 code = { - body : id, - type : 15 + body: id, + type: 15 }; } else { return false; @@ -824,13 +802,13 @@ var IDValidator = function() { } // 地址码检查 , - checkAddr : function(addr, GB2260) { + checkAddr: function (addr, GB2260) { var addrInfo = this.getAddrInfo(addr, GB2260); return (addrInfo === false ? false : true); } // 取得地址码信息 , - getAddrInfo : function(addr, GB2260) { + getAddrInfo: function (addr, GB2260) { GB2260 = GB2260 || null; // 查询GB/T2260,没有引入GB2260时略过 if (GB2260 === null) { @@ -856,7 +834,7 @@ var IDValidator = function() { } // 生日码检查 , - checkBirth : function(birth) { + checkBirth: function (birth) { var year, month, day; if (birth.length == 8) { year = parseInt(birth.slice(0, 4), 10); @@ -882,25 +860,25 @@ var IDValidator = function() { } // 顺序码检查 , - checkOrder : function(order) { + checkOrder: function (order) { // 暂无需检测 return true; } // 加权 , - weight : function(t) { + weight: function (t) { return Math.pow(2, t - 1) % 11; } // 随机整数 , - rand : function(max, min) { + rand: function (max, min) { min = min || 1; return Math.round(Math.random() * (max - min)) + min; } // 数字补位 , - str_pad : function(str, len, chr, right) { + str_pad: function (str, len, chr, right) { str = str.toString(); len = len || 2; chr = chr || '0'; @@ -920,13 +898,13 @@ var IDValidator = function() { } // 抛错 , - error : function(msg) { + error: function (msg) { var e = new Error(); e.message = 'IDValidator: ' + msg; throw e; } }; - var _IDValidator = function(GB2260) { + var _IDValidator = function (GB2260) { if (typeof GB2260 !== "undefined") { this.GB2260 = GB2260; } @@ -934,7 +912,7 @@ var IDValidator = function() { this.cache = {}; }; _IDValidator.prototype = { - isValid : function(id) { + isValid: function (id) { var GB2260 = this.GB2260 || null; var code = util.checkArg(id); if (code === false) { @@ -942,7 +920,7 @@ var IDValidator = function() { } // 查询cache if (this.cache.hasOwnProperty(id) - && typeof this.cache[id].valid !== 'undefined') { + && typeof this.cache[id].valid !== 'undefined') { return this.cache[id].valid; } else { if (!this.cache.hasOwnProperty(id)) { @@ -952,11 +930,11 @@ var IDValidator = function() { var addr = code.body.slice(0, 6); var birth = (code.type === 18 ? code.body.slice(6, 14) : code.body - .slice(6, 12)); + .slice(6, 12)); var order = code.body.slice(-3); if (!(util.checkAddr(addr, GB2260) && util.checkBirth(birth) && util - .checkOrder(order))) { + .checkOrder(order))) { this.cache[id].valid = false; return false; } @@ -991,7 +969,7 @@ var IDValidator = function() { checkBit = checkBit % 11; } checkBit = (typeof checkBit === 'number' ? checkBit.toString() - : checkBit); + : checkBit); // 检查校验码 if (checkBit !== code.checkBit) { @@ -1006,7 +984,7 @@ var IDValidator = function() { // 分析详细信息 , - getInfo : function(id) { + getInfo: function (id) { var GB2260 = this.GB2260 || null; // 号码必须有效 if (this.isValid(id) === false) { @@ -1023,7 +1001,7 @@ var IDValidator = function() { var addr = code.body.slice(0, 6); var birth = (code.type === 18 ? code.body.slice(6, 14) : code.body - .slice(6, 12)); + .slice(6, 12)); var order = code.body.slice(-3); var info = {}; @@ -1031,10 +1009,10 @@ var IDValidator = function() { if (GB2260 !== null) { info.addr = util.getAddrInfo(addr, GB2260); } - info.birth = (code.type === 18 ? (([ birth.slice(0, 4), - birth.slice(4, 6), birth.slice(-2) ]).join('-')) : ([ - '19' + birth.slice(0, 2), birth.slice(2, 4), - birth.slice(-2) ]).join('-')); + info.birth = (code.type === 18 ? (([birth.slice(0, 4), + birth.slice(4, 6), birth.slice(-2)]).join('-')) : ([ + '19' + birth.slice(0, 2), birth.slice(2, 4), + birth.slice(-2)]).join('-')); info.sex = (order % 2 === 0 ? 0 : 1); info.length = code.type; if (code.type === 18) { @@ -1049,7 +1027,7 @@ var IDValidator = function() { // 仿造一个号 , - makeID : function(isFifteen) { + makeID: function (isFifteen) { var GB2260 = this.GB2260 || null; // 地址码 @@ -1065,7 +1043,7 @@ var IDValidator = function() { var prov = util.str_pad(util.rand(50), 2, '0'); var city = util.str_pad(util.rand(20), 2, '0'); var area = util.str_pad(util.rand(20), 2, '0'); - var addrTest = [ prov, city, area ].join(''); + var addrTest = [prov, city, area].join(''); if (GB2260[addrTest]) { addr = addrTest; break; @@ -1081,12 +1059,12 @@ var IDValidator = function() { var da = util.str_pad(util.rand(28, 1), 2, '0'); if (isFifteen) { return addr + yr + mo + da - + util.str_pad(util.rand(999, 1), 3, '1'); + + util.str_pad(util.rand(999, 1), 3, '1'); } yr = '19' + yr; var body = addr + yr + mo + da - + util.str_pad(util.rand(999, 1), 3, '1'); + + util.str_pad(util.rand(999, 1), 3, '1'); // 位置加权 var posWeight = []; @@ -1110,7 +1088,7 @@ var IDValidator = function() { checkBit = checkBit % 11; } checkBit = (typeof checkBit === 'number' ? checkBit.toString() - : checkBit); + : checkBit); return (body + checkBit); } @@ -1119,726 +1097,723 @@ var IDValidator = function() { GB2260 = GB2260 == null ? "" : GB2260; return new _IDValidator(GB2260); } -Func.subString=function(str, len, hasDot) -{ - var newLength = 0; - var newStr = ""; - var chineseRegex = /[^\x00-\xff]/g; - var singleChar = ""; - var strLength = str.replace(chineseRegex,"**").length; - for(var i = 0;i < strLength;i++) - { - singleChar = str.charAt(i).toString(); - if(singleChar.match(chineseRegex) != null) - { - newLength += 2; - } - else - { - newLength++; - } - if(newLength > len) - { - break; - } - newStr += singleChar; - } - - if(hasDot && strLength > len) - { - newStr += "..."; - } - return newStr; -} -Func.subString2=function(str, len, hasDot) -{ +Func.subString = function (str, len, hasDot) { var newLength = 0; var newStr = ""; var chineseRegex = /[^\x00-\xff]/g; var singleChar = ""; - var strLength = str.replace(chineseRegex,"**").length; - for(var i = 0;i < strLength;i++) - { + var strLength = str.replace(chineseRegex, "**").length; + for (var i = 0; i < strLength; i++) { singleChar = str.charAt(i).toString(); - if(singleChar.match(chineseRegex) != null) - { + if (singleChar.match(chineseRegex) != null) { newLength += 2; } - else - { + else { newLength++; } - if(newLength > len) - { + if (newLength > len) { break; } newStr += singleChar; } - if(hasDot && strLength > len) - { + if (hasDot && strLength > len) { newStr += "..."; } return newStr; } -Func.getKeywordCount = function(str,keyword){ - var reg = new RegExp(keyword,"g"); +Func.subString2 = function (str, len, hasDot) { + var newLength = 0; + var newStr = ""; + var chineseRegex = /[^\x00-\xff]/g; + var singleChar = ""; + var strLength = str.replace(chineseRegex, "**").length; + for (var i = 0; i < strLength; i++) { + singleChar = str.charAt(i).toString(); + if (singleChar.match(chineseRegex) != null) { + newLength += 2; + } + else { + newLength++; + } + if (newLength > len) { + break; + } + newStr += singleChar; + } + + if (hasDot && strLength > len) { + newStr += "..."; + } + return newStr; +} +Func.getKeywordCount = function (str, keyword) { + var reg = new RegExp(keyword, "g"); var result = str.match(reg); - if(result){ + if (result) { return result.length; } return 0; } //设置普通震动 -Func.vibrator=function(time){ - try{ - if(GameData.appstate){ +Func.vibrator = function (time) { + try { + if (GameData.appstate) { window.settings.vibrator(time); } - }catch(e){ + } catch (e) { } } //是否重复震动 -Func.repeatvibrator=function(repeat){ - try{ - if(GameData.appstate){ +Func.repeatvibrator = function (repeat) { + try { + if (GameData.appstate) { window.settings.repeatvibrator(repeat); } - }catch(e){ + } catch (e) { } } //取消震动 -Func.canclevibrator=function(){ - try{ +Func.canclevibrator = function () { + try { window.settings.canclevibrator(); - }catch(e){ + } catch (e) { } } //横竖屏 orientation 1 为横屏 2 为竖屏 -Func.orientation=function(Orientation){ - try{ +Func.orientation = function (Orientation) { + try { window.settings.orientation(Orientation); - }catch(e){ + } catch (e) { } } //通知 -Func.notification=function(Ticker,title,content){ +Func.notification = function (Ticker, title, content) { //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 //var Ticker//手机状态栏通知 //var title//标题 //var content//内容 - try{ - window.settings.notification(Ticker,title,content); - }catch(e){ + try { + window.settings.notification(Ticker, title, content); + } catch (e) { } } -Func.sharefinend=function(sharefriend,type,webpageUrl,title,description,spidList){ +Func.sharefinend = function (sharefriend, type, webpageUrl, title, description, spidList) { GameData.shareFriendInfo = { - sharefriend:sharefriend, - type:type, - webpageUrl:webpageUrl, - title:title, - description:description, - spidList:spidList + sharefriend: sharefriend, + type: type, + webpageUrl: webpageUrl, + title: title, + description: description, + spidList: spidList }; //h5和非h5 - if(GameData.sysConfig.otherShare == 2){ - if(!GameData.h5Version){ + if (GameData.sysConfig.otherShare == 2) { + if (!GameData.h5Version) { GameUI.openSharePannel(); - }else{ + } else { Func.sharefriend(GameData.shareFriendInfo); } - }else{ - Func.sharefriend(GameData.shareFriendInfo); + } else { + Func.sharefriend(GameData.shareFriendInfo); } } -Func.visitorLogin = function(){ +Func.visitorLogin = function () { //游客身份登入,随机游客数据 - GameData.isVisitor = true; - GameData.isDeviceLogin = false; - var WxInfo = Utl.ReadData(Utl.Config.visitorinfo); - if(WxInfo != null){ + // GameData.isVisitor = true; + // GameData.isDeviceLogin = false; + var WxInfo = Utl.ReadData(Utl.Config.wxinfo); + if (WxInfo != null) { WxInfo = JSON.parse(WxInfo); - sharelogin(WxInfo.openid,WxInfo.headimgurl,WxInfo.nickname,WxInfo.sex,WxInfo.city,WxInfo.Province,WxInfo.unionid); - }else{ - var ram = 100000+ifast_random(100000); - var headLoginList=["http://img5.imgtn.bdimg.com/it/u=110166870,238965605&fm=27&gp=0.jpg", - "http://www.qqzhi.com/uploadpic/2015-01-15/200511535.jpg", - "http://img0.imgtn.bdimg.com/it/u=2722294531,1396252661&fm=27&gp=0.jpg", - "http://p2.gexing.com/touxiang/20130201/1735/510b8c7c1e572_200x200_3.jpg?recache=20131108", - "http://www.qqzhi.com/uploadpic/2015-01-15/200512924.jpg"]; - sharelogin(""+ram,headLoginList[ifast_random(headLoginList.length)],"游客"+ram,ifast_random(2)+1,"nanchang","jiangxi","ylgame"+ram); + sharelogin(WxInfo.openid, WxInfo.headimgurl, WxInfo.nickname, WxInfo.sex, WxInfo.city, WxInfo.Province, WxInfo.unionid); + } else { + var pInfo = Func.simulatePlayerInfo("游客"); + + sharelogin(pInfo.openid, pInfo.openid.headimgurl, pInfo.nickname, pInfo.sex, pInfo.city, pInfo.province, pInfo.unionid); } -} -Func.deviceLogin = function(phone,sms){ +} +Func.simulatePlayerInfo = function (nameString) { + var headLoginList = [ + "https://img2.baidu.com/it/u=1823726962,2692568839&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500", + "https://img0.baidu.com/it/u=320875415,2231067789&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500", + "https://img1.baidu.com/it/u=3407774307,2859661062&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500", + "https://img2.baidu.com/it/u=1161398577,3592656327&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500", + "https://img1.baidu.com/it/u=2061657615,4194426181&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=501", + "https://img2.baidu.com/it/u=3081347414,2363887197&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500", + "https://img1.baidu.com/it/u=1364384963,3982203144&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500", + "https://img1.baidu.com/it/u=3041194995,2386060237&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500", + "https://img2.baidu.com/it/u=2904976445,2884058010&fm=253&fmt=auto&app=120&f=JPEG?w=529&h=500", + "https://img0.baidu.com/it/u=1801052125,1596537112&fm=253&fmt=auto&app=120&f=JPEG?w=529&h=500", + + ]; + var ram = ifast_random(100000); + var resInfo = { + openid: "testopenid_" + ram, + headimgurl: headLoginList[ifast_random(headLoginList.length)], + nickname: ram + '_' + nameString, + sex: ifast_random(2) + 1, + city: "nanchang", + province: "jiangxi", + unionid: "ylgame" + ram + } + return resInfo; +} +Func.deviceLogin = function (phone, sms) { //设备登录 GameData.isVisitor = false; GameData.isDeviceLogin = true; var WxInfo = Utl.getCookie(Utl.Config.devicePlayer); - if(WxInfo){ + if (WxInfo) { WxInfo = JSON.parse(WxInfo); - sharelogin(WxInfo.openid,WxInfo.headimgurl,WxInfo.nickname,WxInfo.sex,WxInfo.city,WxInfo.Province,WxInfo.unionid,phone,sms); - }else{ + sharelogin(WxInfo.openid, WxInfo.headimgurl, WxInfo.nickname, WxInfo.sex, WxInfo.city, WxInfo.Province, WxInfo.unionid, phone, sms); + } else { var unionid = min_randomChar(25); - if(GameData.phoneInfo){ - if(GameData.phoneInfo.PhoneIMEI){ + if (GameData.phoneInfo) { + if (GameData.phoneInfo.PhoneIMEI) { unionid = GameData.phoneInfo.PhoneIMEI; - }else{ + } else { //GameUI.OpenTips("请到设置中打开游戏读取手机信息权限"); GameData.phoneInfo.PhoneIMEI = unionid; - Utl.SaveData(Utl.Config.phoneInfo1,JSON.stringify(GameData.phoneInfo)); + Utl.SaveData(Utl.Config.phoneInfo1, JSON.stringify(GameData.phoneInfo)); } - }else{ + } else { //GameUI.OpenTips("请到设置中打开游戏读取手机信息权限"); GameData.phoneInfo = { - PhoneIMEI:unionid + PhoneIMEI: unionid }; - Utl.SaveData(Utl.Config.phoneInfo1,JSON.stringify(GameData.phoneInfo)); + Utl.SaveData(Utl.Config.phoneInfo1, JSON.stringify(GameData.phoneInfo)); } - var ram = 100000+ifast_random(100000); - - var name2 = String(hex_md5(unionid)).slice(0,6); + var ram = 100000 + ifast_random(100000); + + var name2 = String(hex_md5(unionid)).slice(0, 6); var avatar = ""; - if(GameData.sysConfig.avatarUrl){ + if (GameData.sysConfig.avatarUrl) { var avatar = GameData.sysConfig.avatarUrl + min_random(GameData.sysConfig.avatarRange[0], - GameData.sysConfig.avatarRange[1])+".jpg"; + GameData.sysConfig.avatarRange[1]) + ".jpg"; } - var nickName = "User_"+name2; - sharelogin(unionid,avatar,nickName,ifast_random(2)+1, - "China","HongKong",unionid,phone,sms); + var nickName = "User_" + name2; + sharelogin(unionid, avatar, nickName, ifast_random(2) + 1, + "China", "HongKong", unionid, phone, sms); //var ram1 = 10000+ifast_random(10000); - + } } -Func.phoneLogin = function(phone,sms){ +Func.phoneLogin = function (phone, sms) { //手机登录 GameData.isVisitor = false; GameData.isDeviceLogin = true; var WxInfo = Utl.getCookie(Utl.Config.devicePlayer); - if(WxInfo){ + if (WxInfo) { WxInfo = JSON.parse(WxInfo); - sharelogin(WxInfo.openid,WxInfo.headimgurl,WxInfo.nickname,WxInfo.sex,WxInfo.city,WxInfo.Province,WxInfo.unionid,phone,sms); - }else{ - var unionid = "phone_"+phone; - - - var name2 = String(hex_md5(unionid)).slice(0,6); + sharelogin(WxInfo.openid, WxInfo.headimgurl, WxInfo.nickname, WxInfo.sex, WxInfo.city, WxInfo.Province, WxInfo.unionid, phone, sms); + } else { + var unionid = "phone_" + phone; + + + var name2 = String(hex_md5(unionid)).slice(0, 6); var avatar = ""; - if(GameData.sysConfig.avatarUrl){ + if (GameData.sysConfig.avatarUrl) { var avatar = GameData.sysConfig.avatarUrl + min_random(GameData.sysConfig.avatarRange[0], - GameData.sysConfig.avatarRange[1])+".jpg"; + GameData.sysConfig.avatarRange[1]) + ".jpg"; } - var nickName = "User_"+name2; - sharelogin(unionid,avatar,nickName,ifast_random(2)+1, - "China","ShangHai",unionid,phone,sms); + var nickName = "User_" + name2; + sharelogin(unionid, avatar, nickName, ifast_random(2) + 1, + "China", "ShangHai", unionid, phone, sms); //var ram1 = 10000+ifast_random(10000); - + } } -Func.accreditlogin=function(type){ +Func.accreditlogin = function (type) { //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 catch() 里 GameData.isVisitor = false; GameData.isDeviceLogin = false; -// logmessage("accreditlogin",1); - try{ + // logmessage("accreditlogin",1); + try { var tp = 2; - if(type){ - tp=type; + if (type) { + tp = type; } window.settings.accreditlogin(tp); - - }catch(e){ - if(GameData.h5Version == 1){ - - }else{ - var headLoginList=[ - "https://img2.baidu.com/it/u=1823726962,2692568839&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500", - "https://img0.baidu.com/it/u=320875415,2231067789&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500", - "https://img1.baidu.com/it/u=3407774307,2859661062&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500", - "https://img2.baidu.com/it/u=1161398577,3592656327&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500", - "https://img1.baidu.com/it/u=2061657615,4194426181&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=501", - "https://img2.baidu.com/it/u=3081347414,2363887197&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500", - "https://img1.baidu.com/it/u=1364384963,3982203144&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500", - "https://img1.baidu.com/it/u=3041194995,2386060237&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500", - "https://img2.baidu.com/it/u=2904976445,2884058010&fm=253&fmt=auto&app=120&f=JPEG?w=529&h=500", - "https://img0.baidu.com/it/u=1801052125,1596537112&fm=253&fmt=auto&app=120&f=JPEG?w=529&h=500", - ]; - var ram = ifast_random(100000); - - sharelogin("fff23"+ram,headLoginList[ifast_random(headLoginList.length)],"测试"+ram,ifast_random(2)+1,"nanchang","jiangxi","ylgame"+ram); + } catch (e) { + if (GameData.h5Version == 1) { + + } else { + var pInfo = Func.simulatePlayerInfo("测试"); + + sharelogin(pInfo.openid, pInfo.openid.headimgurl, pInfo.nickname, pInfo.sex, pInfo.city, pInfo.province, pInfo.unionid); // sharelogin("fff23"+ram,headLoginList[ifast_random(headLoginList.length)],"测试"+ram,ifast_random(2)+1,"nanchang","jiangxi","oLVKis6bj3_l8qspMybG60KV2GN4"); } - + } } -var sharelogin = function(openid,headimgurl,nickname,sex,city,Province,unionid,phone,sms){ - if(!sex){ +var sharelogin = function (openid, headimgurl, nickname, sex, city, Province, unionid, phone, sms) { + if (!sex) { sex = 1; } - - if(!nickname && !headimgurl){//全为空时无法登陆 - GameUI.OpenTips("授权失败,请重新授权!"); - }else{ - var wxdata={}; - wxdata.openid = openid; - wxdata.headimgurl = headimgurl; - wxdata.nickname = nickname; - wxdata.sex = sex; - wxdata.city = city; - wxdata.Province = Province; - wxdata.unionid = unionid; - if(phone){ - wxdata.telphone = phone; - C_Player.setTel(phone); - } - wxdata=JSON.stringify(wxdata); - // if(GameData.isVisitor){ - // Utl.SaveData(Utl.Config.visitorinfo,wxdata); - // } - // if(GameData.isDeviceLogin){ - // Utl.SaveData(Utl.Config.devicePlayer,wxdata); - // } - if(!GameData.isVisitor && !GameData.isDeviceLogin){ - Utl.setCookie(Utl.Config.wxinfo,wxdata,Utl.Config.maxtime); - } - - C_Player.SetWxInfo(openid,headimgurl,nickname,sex,city,Province,unionid); - var data={}; - data.agentid = GameData.AgentId; - data.openid = C_Player.openid; - data.nickname = C_Player.nickname; - data.avatar = C_Player.avatar; - data.sex = C_Player.sex; - data.province = C_Player.province; - data.city = C_Player.city; - data.unionid = C_Player.unionid; - data.gameid=GameData.GameId; - data.version = GameData.versionCode; - data.channelid = GameData.ChannelId; - data.marketid = GameData.marketID; - if(phone){ - data.telphone = phone; - } - if(sms){ - if(sms != "telphoneAuto"){ - data.smmcode = sms; - data.telphoneAuto = false; - }else{ - data.telphoneAuto = true; - } - } - Net.Send_login(data); - - } + if (!nickname && !headimgurl) {//全为空时无法登陆 + GameUI.OpenTips("授权失败,请重新授权!"); + } else { + var wxdata = {}; + wxdata.openid = openid; + wxdata.headimgurl = headimgurl; + wxdata.nickname = nickname; + wxdata.sex = sex; + wxdata.city = city; + wxdata.Province = Province; + wxdata.unionid = unionid; + if (phone) { + wxdata.telphone = phone; + C_Player.setTel(phone); + } + wxdata = JSON.stringify(wxdata); + // if(GameData.isVisitor){ + // Utl.SaveData(Utl.Config.visitorinfo,wxdata); + // } + // if(GameData.isDeviceLogin){ + // Utl.SaveData(Utl.Config.devicePlayer,wxdata); + // } + if (!GameData.isVisitor && !GameData.isDeviceLogin) { + Utl.setCookie(Utl.Config.wxinfo, wxdata, Utl.Config.maxtime); + } + + C_Player.SetWxInfo(openid, headimgurl, nickname, sex, city, Province, unionid); + var data = {}; + data.agentid = GameData.AgentId; + data.openid = C_Player.openid; + data.nickname = C_Player.nickname; + data.avatar = C_Player.avatar; + data.sex = C_Player.sex; + data.province = C_Player.province; + data.city = C_Player.city; + data.unionid = C_Player.unionid; + data.gameid = GameData.GameId; + data.version = GameData.versionCode; + data.channelid = GameData.ChannelId; + data.marketid = GameData.marketID; + if (phone) { + data.telphone = phone; + } + if (sms) { + if (sms != "telphoneAuto") { + data.smmcode = sms; + data.telphoneAuto = false; + } else { + data.telphoneAuto = true; + } + } + Net.Send_login(data); + + + } } -var sharesuccess = function(success,type){//分享成功回调 +var sharesuccess = function (success, type) {//分享成功回调 success = Number(success); type = Number(type); - C_Player.sharesuccess(success,type); + C_Player.sharesuccess(success, type); } -Func.getDate = function(){ +Func.getDate = function () { - var today=new Date(); - var h=today.getHours(); - var m=today.getMinutes(); - if(m<10){ - m="0"+m; + var today = new Date(); + var h = today.getHours(); + var m = today.getMinutes(); + if (m < 10) { + m = "0" + m; } - if(h<10){ - h="0"+h; + if (h < 10) { + h = "0" + h; } - return [h,m]; + return [h, m]; } -Func.SetDate=function(){ - set_self(154,7,this.getDate()[0],0,0); - set_self(155,7,this.getDate()[1],0,0); +Func.SetDate = function () { + set_self(154, 7, this.getDate()[0], 0, 0); + set_self(155, 7, this.getDate()[1], 0, 0); } -Func.trim = function(str) { - return str.replace(/\s+/g, ""); +Func.trim = function (str) { + return str.replace(/\s+/g, ""); } -Func.insertFlag = function(str,flg,sn,bTemp){ +Func.insertFlag = function (str, flg, sn, bTemp) { //this.charCodeAt(i)>127 || this.charCodeAt(i)==94 - var newstr=""; - var strLen = str.length; - var count = 0; - var cutIndex = 0; - if(str.gblen()>sn){ - for(var i=0;i127 || str.charCodeAt(i)==94){//中文 + var newstr = ""; + var strLen = str.length; + var count = 0; + var cutIndex = 0; + if (str.gblen() > sn) { + for (var i = 0; i < str.length; i++) { + var delta = 0; + if (str.charCodeAt(i) > 127 || str.charCodeAt(i) == 94) {//中文 count += 2; - delta=2; - - }else{ + delta = 2; + + } else { count++; - delta=1; + delta = 1; } - if(count > sn){ - var tmp = str.slice(cutIndex,i); - if(i==strLen-1){ - if(bTemp){ - newstr += tmp+flg; - }else{ + if (count > sn) { + var tmp = str.slice(cutIndex, i); + if (i == strLen - 1) { + if (bTemp) { + newstr += tmp + flg; + } else { newstr += tmp; } - }else{ - newstr += tmp+flg; - cutIndex=i; + } else { + newstr += tmp + flg; + cutIndex = i; count = delta; } } - if(i==strLen-1 && cutIndex!=i){ - var tmp = str.slice(cutIndex,strLen); - if(bTemp){ - newstr += tmp+flg; - }else{ + if (i == strLen - 1 && cutIndex != i) { + var tmp = str.slice(cutIndex, strLen); + if (bTemp) { + newstr += tmp + flg; + } else { newstr += tmp; } - + } - - - } - }else{ - if(bTemp){ + + + } + } else { + if (bTemp) { newstr = str + flg; - }else{ + } else { newstr = str; } - + } - return newstr; + return newstr; } -Func.countFlag = function(str,flag){ - var rValue=0; - for(var i=0;iGame_Config.Max.reconnecttime){//超过重连时间 - if(Net.ws_tcp.readyState != WebSocket.OPEN){ - - GameData.disType = true; - GameData.ConnectType=false; - GameData.NetType=1; - Logic.TryConnect(); - }else{ - - GameData.ConnectType = false; - GameData.disType = true; - GameData.NetType=1; - GameUI.StartLoad(); - GameData.isClose = true; - //GameData.isCloseTimer = setTimeout(function(){ - //if(GameData.isClose){ - //Logic.DisConnect(); - //} - //},5000); - Net.ws_tcp.close(); - GameData.isCloseTimer = setInterval(function(){ - if(GameData.isClose){ - Net.ws_tcp.close(); - } - },5000); - } - }else{ - - if(Net.ws_tcp.readyState != WebSocket.OPEN){ - - GameData.disType = true; - GameData.ConnectType=false; - GameData.NetType=1; - Logic.TryConnect(); - }else{ - if(Desk.inDesk(C_Player.playerid)){ - if(Game_Modify.updateScene){ - Game_Modify.updateScene(); - } - }else{ - - } - - } - Utl.playMusic(); - + //} + }, ConstVal.Max.heartbeat); } - }else{ - Utl.playMusic(); + //Utl.TurnOnBgm(get_self(4,37,0,0,0)); + if (!ConstVal.isGameHall) { + var exp = new Date(); + if (exp.getTime() - GameData.leaveTime > Game_Config.Max.reconnecttime) {//超过重连时间 + if (Net.ws_tcp.readyState != WebSocket.OPEN) { + + GameData.disType = true; + GameData.ConnectType = false; + GameData.NetType = 1; + Logic.TryConnect(); + } else { + + GameData.ConnectType = false; + GameData.disType = true; + GameData.NetType = 1; + GameUI.StartLoad(); + GameData.isClose = true; + //GameData.isCloseTimer = setTimeout(function(){ + //if(GameData.isClose){ + //Logic.DisConnect(); + //} + //},5000); + Net.ws_tcp.close(); + GameData.isCloseTimer = setInterval(function () { + if (GameData.isClose) { + Net.ws_tcp.close(); + } + }, 5000); + } + } else { + + if (Net.ws_tcp.readyState != WebSocket.OPEN) { + + GameData.disType = true; + GameData.ConnectType = false; + GameData.NetType = 1; + Logic.TryConnect(); + } else { + if (Desk.inDesk(C_Player.playerid)) { + if (Game_Modify.updateScene) { + Game_Modify.updateScene(); + } + } else { + + } + + } + Utl.playMusic(); + + } + } else { + Utl.playMusic(); + } + } else {//切出 + + Utl.stopMusic(); + Game_Modify.stopAllSounds(); + GameData.appstate = false; + for (var i = 0; i < ConstVal.InterEffSoundsList.length; i++) { + Utl.stopSound(ConstVal.InterEffSoundsList[i]); + } + if (ConstVal.netType == 0) { + var exp = new Date(); + GameData.leaveTime = exp.getTime(); + } else { + + } + //关闭震动 + Func.canclevibrator(); + } - }else{//切出 - - Utl.stopMusic(); - Game_Modify.stopAllSounds(); - GameData.appstate=false; - for(var i=0;i0){ - var data={}; - data.agentid=GameData.AgentId; - data.gameid=GameData.GameId; - data.playerid=C_Player.playerid; - data.roomcode=Desk.roomcode; - data.voiceurl=audiourl; - data.time=time; - if(GameData.chatInfo){ + if (Number(time) > 0) { + var data = {}; + data.agentid = GameData.AgentId; + data.gameid = GameData.GameId; + data.playerid = C_Player.playerid; + data.roomcode = Desk.roomcode; + data.voiceurl = audiourl; + data.time = time; + if (GameData.chatInfo) { data.info = GameData.chatInfo; - data.type=2; + data.type = 2; } Net.Send_send_voice(data); } } -Func.mediaTypeAudio=function(audiourl,type,v){ +Func.mediaTypeAudio = function (audiourl, type, v) { //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 catch() 里面使用你自己的函数 - try{ - window.settings.mediaTypeAudio(audiourl,type,v); - }catch(e){ + try { + window.settings.mediaTypeAudio(audiourl, type, v); + } catch (e) { // gameui_play_voice(v); - Net.submit_error("mediaAudio:audiourl="+audiourl+",type="+type+",user="+v,e.stack); + Net.submit_error("mediaAudio:audiourl=" + audiourl + ",type=" + type + ",user=" + v, e.stack); } } -Func.up_imgurl=function(recid,photo){ -//[{photo:????,pid:??id}.....];String -//alert(photo); -//?????????????,?????try{}catch{} try ?? ????????? catch() ?????????? +Func.up_imgurl = function (recid, photo) { + //[{photo:????,pid:??id}.....];String + //alert(photo); + //?????????????,?????try{}catch{} try ?? ????????? catch() ?????????? //return; - if(!ConstVal.isGameHall){ - try{ + if (!ConstVal.isGameHall) { + try { //if(!photo){return;} - var input_data=[]; - var input_obj={}; - input_obj.photourl=photo; - input_obj.pid=String(recid); + var input_data = []; + var input_obj = {}; + input_obj.photourl = photo; + input_obj.pid = String(recid); input_data.push(input_obj); - - - input_data=JSON.stringify(input_data); + + + input_data = JSON.stringify(input_data); window.settings.getphoto(input_data); //Func.getphoto(input_data); - var pho=input_obj; - if(Number(pho.pid)==25){ - up_imgurl(Number(pho.pid),"assets/bmp/00170.png",1); - //}else if(Number(pho.pid)==115 || Number(pho.pid)==5){ - }else if(exceptSrc.indexOf(Number(pho.pid))>=0){ - }else{ - up_imgurl(Number(pho.pid),"assets/bmp/00170.png",1); + var pho = input_obj; + if (Number(pho.pid) == 25) { + up_imgurl(Number(pho.pid), "assets/bmp/00170.png", 1); + //}else if(Number(pho.pid)==115 || Number(pho.pid)==5){ + } else if (exceptSrc.indexOf(Number(pho.pid)) >= 0) { + } else { + up_imgurl(Number(pho.pid), "assets/bmp/00170.png", 1); } - - }catch(e){ - - if(recid==25){ - up_imgurl(recid,"assets/bmp/00170.png",1); + + } catch (e) { + + if (recid == 25) { + up_imgurl(recid, "assets/bmp/00170.png", 1); setTimeout( - function(){ - if(photo){ - up_imgurl(recid,photo,1); - GameData.playerHeadImgState = true; - }else{ - up_imgurl(recid,"assets/bmp/00170.png",1); - } - },ConstVal.Max.headImgTimer); - }else if(exceptSrc.indexOf(recid)>=0){ - up_imgurl(recid,photo,1); - }else{ - - up_imgurl(recid,"assets/bmp/00170.png",1); + function () { + if (photo) { + up_imgurl(recid, photo, 1); + GameData.playerHeadImgState = true; + } else { + up_imgurl(recid, "assets/bmp/00170.png", 1); + } + }, ConstVal.Max.headImgTimer); + } else if (exceptSrc.indexOf(recid) >= 0) { + up_imgurl(recid, photo, 1); + } else { + + up_imgurl(recid, "assets/bmp/00170.png", 1); setTimeout( - function(){ - if(photo){ - up_imgurl(recid,photo,1); - }else{ - up_imgurl(recid,"assets/bmp/00170.png",1); - } - } - ,ConstVal.Max.headImgTimer); - } - - } - }else{ - gameHallImport.up_imgurl(recid,photo); - } -} -var getphoto = function(photo){ - if(!ConstVal.isGameHall){ - var obj = strToJson(photo); - for(var i=0;i=0){ - up_imgurl(Number(pho.pid),pho.photourl,1); - }else{ - //up_imgurl(Number(pho.pid),"assets/bmp/00170.png",1); - setTimeout( - function(){ - if(pho.photourl){ - up_imgurl(Number(pho.pid),pho.photourl,1); - }else{ - up_imgurl(Number(pho.pid),"assets/bmp/00170.png",1); + function () { + if (photo) { + up_imgurl(recid, photo, 1); + } else { + up_imgurl(recid, "assets/bmp/00170.png", 1); } } - ,ConstVal.Max.headImgTimer); - } - } + , ConstVal.Max.headImgTimer); + } + } - }else{ - + } else { + gameHallImport.up_imgurl(recid, photo); + } +} +var getphoto = function (photo) { + if (!ConstVal.isGameHall) { + var obj = strToJson(photo); + for (var i = 0; i < obj.length; i++) { + var pho = obj[i]; + if (pho.photourl) { + if (Number(pho.pid) == 25) { + if (pho.photourl) { + up_imgurl(Number(pho.pid), pho.photourl, 1); + GameData.playerHeadImgState = true; + } else { + up_imgurl(Number(pho.pid), "assets/bmp/00170.png", 1); + } + } else if (exceptSrc.indexOf(Number(pho.pid)) >= 0) { + up_imgurl(Number(pho.pid), pho.photourl, 1); + } else { + //up_imgurl(Number(pho.pid),"assets/bmp/00170.png",1); + setTimeout( + function () { + if (pho.photourl) { + up_imgurl(Number(pho.pid), pho.photourl, 1); + } else { + up_imgurl(Number(pho.pid), "assets/bmp/00170.png", 1); + } + } + , ConstVal.Max.headImgTimer); + } + } + } + } else { + } } //调用手机默认浏览器打开链接 -Func.browser=function(url){ - try{ - if(url){ +Func.browser = function (url) { + try { + if (url) { url = fixUrl(url); var exp = new Date(); url += "×tamp=" + exp.getTime(); window.settings.browser(url); } - }catch(e){ + } catch (e) { console.log(url); } } //主动获取手机电量 -Func.getbattery=function(){ - try{ - var battery=window.settings.getbattery(); +Func.getbattery = function () { + try { + var battery = window.settings.getbattery(); return battery; - }catch(e){ + } catch (e) { //alert(e); return 1; @@ -1846,272 +1821,276 @@ Func.getbattery=function(){ } //手机电量变化调用 -var getBattery = function(Battery){ - GameData.Battery=Battery; - if(GameData.Battery<=0.2){ - set_self(338,43,3,0,0); - }else{ - set_self(338,43,2,0,0); +var getBattery = function (Battery) { + GameData.Battery = Battery; + if (GameData.Battery <= 0.2) { + set_self(338, 43, 3, 0, 0); + } else { + set_self(338, 43, 2, 0, 0); } } //分享图片(链接) -Func.sharephotourl=function(sharetype,url){ - try{ - window.settings.sharephotourl(sharetype,url); - }catch(e){ +Func.sharephotourl = function (sharetype, url) { + try { + window.settings.sharephotourl(sharetype, url); + } catch (e) { //alert(e); } } //获取网络类型 1 未连接网络 2 连接wifi 3 连接2G/3G/4G -Func.getnetwork=function(){ - try{ +Func.getnetwork = function () { + try { var type = window.settings.getnetwork(); return type; - }catch(e){ + } catch (e) { return 1; } } //获取wifi信号ssidname wifi名称 signalLevel wifi信号强度 0-4 弱到强 -Func.getwifisignalLevel=function(){ - try{ +Func.getwifisignalLevel = function () { + try { window.settings.getwifisignalLevel(); - }catch(e){ + } catch (e) { //alert(e); } } //WiFi信号变化调用 -var getwifiLevel=function(ssidname,signalLevel){ - GameData.WifiLevel=signalLevel; - GameData.WifiLevel= Number(GameData.WifiLevel); - switch(GameData.WifiLevel){ +var getwifiLevel = function (ssidname, signalLevel) { + GameData.WifiLevel = signalLevel; + GameData.WifiLevel = Number(GameData.WifiLevel); + switch (GameData.WifiLevel) { case 0: - set_self(336,43,1,0,0); - break; + set_self(336, 43, 1, 0, 0); + break; case 1: case 2: - set_self(336,43,2,0,0); - break; + set_self(336, 43, 2, 0, 0); + break; case 3: case 4: - set_self(336,43,3,0,0); - break; + set_self(336, 43, 3, 0, 0); + break; } } //网络状况改变 -var getnetwork=function(type){ - type=Number(type); - switch(type){ +var getnetwork = function (type) { + type = Number(type); + switch (type) { case 1: - break; + break; case 2: - set_self(336,43,3,0,0); - Func.getwifisignalLevel(); - break; + set_self(336, 43, 3, 0, 0); + Func.getwifisignalLevel(); + break; case 3: - set_self(336,43,4,0,0); - break; + set_self(336, 43, 4, 0, 0); + break; } } //获取版本类型 -Func.getVersionState = function(){ +Func.getVersionState = function () { //获取版本类型 用于判断版本是否高于服务器版本 - try{ + try { //苹果获取结果接口 return Number(window.settings.getcompareCode()); - }catch(e){ + } catch (e) { return 0; - //return 1; + // return 1; } } -Func.startshake = function(){ - if(Utl.ReadData(Utl.Config.shake)==1){ - if(GameData.shakeID != Game_Config.shakeList.nil){ - try{ +Func.startshake = function () { + if (Utl.ReadData(Utl.Config.shake) == 1) { + if (GameData.shakeID != Game_Config.shakeList.nil) { + try { window.settings.startshake(); - }catch(e){ + } catch (e) { } } } } -Func.stopshake = function(){ - try{ +Func.stopshake = function () { + try { window.settings.stopshake(); - }catch(e){ + } catch (e) { } } -Func.switchshakeVoice = function(Voicetype){ - try{ +Func.switchshakeVoice = function (Voicetype) { + try { window.settings.SwitchShake(Voicetype); - }catch(e){ + } catch (e) { } } -var shakeEnd = function(){//摇一摇回调 +var shakeEnd = function () {//摇一摇回调 Game_Modify.shakeEvent(); } //获得渠道名称 -Func.getchannelName = function(){// - try{ - var name=window.settings.getchannelName(); - if(name){ +Func.getchannelName = function () {// + try { + var name = window.settings.getchannelName(); + if (name) { return name; - }else{ - return ""; - } - }catch(e){ - if(GameData.userAgent != ConstVal.userAgent.uAgent_3){ + } else { return ""; - }else{ + } + } catch (e) { + if (GameData.userAgent != ConstVal.userAgent.uAgent_3) { + return ""; + } else { return app_channel; } } } //播放声音 -Func.play_wav = function(src,isloop){ - if(src){ - if(GameData.appstate ||(!GameData.appstate&&isloop==-1)){ - try{ - if(!GameData.isRecord){ - window.settings.srcIsloop(src,isloop); +Func.play_wav = function (src, isloop) { + if (src) { + if (GameData.appstate || (!GameData.appstate && isloop == -1)) { + try { + if (!GameData.isRecord) { + window.settings.srcIsloop(src, isloop); } - }catch(e){ - if(GameData.h5Version == 1 && GameData.OS == ConstVal.OS.apple){ + } catch (e) { + if (GameData.h5Version == 1 && GameData.OS == ConstVal.OS.apple) { //logmessage("apple play"+src+"、"+isloop,1); - switch(isloop){ + switch (isloop) { case 0: case 1: - _gameSoundsObj.play(src,isloop); + _gameSoundsObj.play(src, isloop); break; case -1: _gameSoundsObj.stop(src); - break; + break; } - }else{ - if(!GameData.isRecord){ - play_wav(src,isloop); + } else { + if (!GameData.isRecord) { + play_wav(src, isloop); } } - - } + + } } } } //开启扫一扫 -Func.OpenScan = function(){ - try{ +Func.OpenScan = function () { + try { window.settings.opensaoma(); - }catch(e){ + } catch (e) { - } -} + } +} //扫一扫回调数据 -var getsaomaData = function(data){ +var getsaomaData = function (data) { } //开启定位 -Func.startlocation = function(type){ - try{ +Func.startlocation = function (type) { + try { window.settings.startlocation(type); - }catch(e){ - console.log("Func.startlocation:",type); - getlocationinfo(JSON.stringify({"address":"江西省南昌市青云谱区施尧路靠近上海浦东发展银行(长天支行)","city":"南昌市", -"cityCode":"0791","country":"中国","district":"青云谱区","latitude":28.623546,"longitude":115.900333, -"province":"江西省","street":"施尧路","errorCode":0})); + } catch (e) { + console.log("Func.startlocation:", type); + getlocationinfo(JSON.stringify({ + "address": "江西省南昌市青云谱区施尧路靠近上海浦东发展银行(长天支行)", "city": "南昌市", + "cityCode": "0791", "country": "中国", "district": "青云谱区", "latitude": 28.623546, "longitude": 115.900333, + "province": "江西省", "street": "施尧路", "errorCode": 0 + })); } } //获取定位 -Func.getlocation = function(){ - try{ - if(GameData.otherLocation){ +Func.getlocation = function () { + try { + if (GameData.otherLocation) { GameData.otherLocationTimes++; - if(GameData.otherLocationTimes > GameData.otherLocationAllTimes){ + if (GameData.otherLocationTimes > GameData.otherLocationAllTimes) { return; } } - + window.settings.getlocationinfo(); - }catch(e){ + } catch (e) { console.log("Func.getlocation:"); - getlocationinfo(JSON.stringify({"address":"江西省南昌市青云谱区施尧路靠近上海浦东发展银行(长天支行)","city":"南昌市", -"cityCode":"0791","country":"中国","district":"青云谱区","latitude":28.623546,"longitude":115.900333, -"province":"江西省","street":"施尧路","errorCode":0})); + getlocationinfo(JSON.stringify({ + "address": "江西省南昌市青云谱区施尧路靠近上海浦东发展银行(长天支行)", "city": "南昌市", + "cityCode": "0791", "country": "中国", "district": "青云谱区", "latitude": 28.623546, "longitude": 115.900333, + "province": "江西省", "street": "施尧路", "errorCode": 0 + })); } } /* {"address":"江西省南昌市青云谱区施尧路靠近上海浦东发展银行(长天支行)","city":"南昌市", "cityCode":"0791","country":"中国","district":"青云谱区","latitude":28.623546,"longitude":115.900333, "province":"江西省","street":"施尧路"}*/ -var getlocationinfo=function(locationinfo){ - if(locationinfo){ - try{ +var getlocationinfo = function (locationinfo) { + if (locationinfo) { + try { locationinfo = JSON.parse(locationinfo); C_Player.SetLocationInfo(locationinfo); - if(locationinfo.city&&locationinfo.province){ - if(Game_Modify.onLocationInfo){ + if (locationinfo.city && locationinfo.province) { + if (Game_Modify.onLocationInfo) { Game_Modify.onLocationInfo(locationinfo); } - - if(GameData.isFirstLogin){ + + if (GameData.isFirstLogin) { GameData.isFirstLogin = false; var data = {}; - data.agentid = Utl.getAgentID(); - data.playerid = Utl.getMyPlayerid(); - data.info = locationinfo; - Net.Send_submit_location(data); - } + data.agentid = Utl.getAgentID(); + data.playerid = Utl.getMyPlayerid(); + data.info = locationinfo; + Net.Send_submit_location(data); } - }catch(e){ } + } catch (e) { + } } } // -Func.SwitchOverGameData = function(webtype,Gamedirectory,gamedownloadurl,data){ - - try{ - if(ConstVal.isGameHall){ +Func.SwitchOverGameData = function (webtype, Gamedirectory, gamedownloadurl, data) { + + try { + if (ConstVal.isGameHall) { GameData.hallLogin = false; - if(!gamedownloadurl || !Gamedirectory){ + if (!gamedownloadurl || !Gamedirectory) { gameHallImport.clearGameinfo(); return; } Utl.stopMusic(); } - window.settings.SwitchOverGameData(webtype,Gamedirectory,gamedownloadurl,data); - }catch(e){ - console.log("webtype:"+webtype+"Gamedirectory:"+Gamedirectory+"gamedownloadurl:"+gamedownloadurl+"data:"+data); + window.settings.SwitchOverGameData(webtype, Gamedirectory, gamedownloadurl, data); + } catch (e) { + console.log("webtype:" + webtype + "Gamedirectory:" + Gamedirectory + "gamedownloadurl:" + gamedownloadurl + "data:" + data); } } -Func.backgameData = function(data){// - try{ +Func.backgameData = function (data) {// + try { window.settings.backgameData(data); - }catch(e){ + } catch (e) { } } -var backgameData = function(){ - var data= {}; - if(C_Player.roomcard>-1){ +var backgameData = function () { + var data = {}; + if (C_Player.roomcard > -1) { data.data = C_Player.returnHallData(); data.opt = "updatePlayerInfo"; data.from = 2; data.gamename = app_gamename; data.gameid = GameData.GameId; Func.backgameData(JSON.stringify(data)); - }else{ + } else { data.opt = "saveGameId"; data.from = 2; data.gamename = app_gamename; @@ -2121,95 +2100,95 @@ var backgameData = function(){ Utl.stopMusic(); } -var getWebdata = function(data){ +var getWebdata = function (data) { //gameLog("收到数据:"+data,1); - + //if(data){ - //data = JSON.parse(data); - //C_Player.setRoomcard(data.roomcard); + //data = JSON.parse(data); + //C_Player.setRoomcard(data.roomcard); //} - if(!ConstVal.isGameHall){ - try{ - if(data){ - if(typeof data == "string"){ - data = JSON.parse(data); - } - - if(typeof data.from != "undefined"){ - - data.from = Number(data.from); - switch(data.from){ - case 0://游戏间调用 - switch(data.opt){ - case "uptate_roomcard": - C_Player.setRoomcard(data.roomcard); - break; - case "loginPlayerid": - GameData.loginPlayerid = (data.data == GameData.GameId); - break; - } - break; - case 1://网页调用 - GameData.ConnectType = false; - GameData.disType = true; - GameData.NetType=1; - GameUI.StartLoad(); - GameData.isClose = true; - Net.ws_tcp.close(); - //var _msg = data.gamedata; - GameData.backUrl = data.backurl; - //if(_msg.route==RouteList.platform||_msg.route==RouteList.agent||_msg.route==RouteList.room){ + if (!ConstVal.isGameHall) { + try { + if (data) { + if (typeof data == "string") { + data = JSON.parse(data); + } + + if (typeof data.from != "undefined") { + + data.from = Number(data.from); + switch (data.from) { + case 0://游戏间调用 + switch (data.opt) { + case "uptate_roomcard": + C_Player.setRoomcard(data.roomcard); + break; + case "loginPlayerid": + GameData.loginPlayerid = (data.data == GameData.GameId); + break; + } + break; + case 1://网页调用 + GameData.ConnectType = false; + GameData.disType = true; + GameData.NetType = 1; + GameUI.StartLoad(); + GameData.isClose = true; + Net.ws_tcp.close(); + //var _msg = data.gamedata; + GameData.backUrl = data.backurl; + //if(_msg.route==RouteList.platform||_msg.route==RouteList.agent||_msg.route==RouteList.room){ //if(min_ExitsFunction(Net[_msg.rpc])){ - //Net[_msg.rpc](_msg); + //Net[_msg.rpc](_msg); //} - //}else{ - - //} - break; - case 2: - switch(data.opt){ - case "updateHTML": - Logic.getHTML(); - break; - } - break; + //}else{ + + //} + break; + case 2: + switch (data.opt) { + case "updateHTML": + Logic.getHTML(); + break; + } + break; + } } } + } catch (e) { + } - }catch(e){ - - } - }else{ + } else { GameData.hallLogin = true; gameHallImport.getWebdata(data); } } -Func.ypayType = function(type){// - try{ +Func.ypayType = function (type) {// + try { window.settings.ypayType(type); - }catch(e){ - console.log("ypayType:"+type); + } catch (e) { + console.log("ypayType:" + type); } } -var yPaytype = function(type,num){ +var yPaytype = function (type, num) { //logmessage("type:"+type+"num:"+num,1); - type=Number(type); - num=Number(num); - switch(type){ + type = Number(type); + num = Number(num); + switch (type) { case 1://房卡 - Net._SendData("youle","agent","update_roomcard",{agentid:GameData.AgentId,playerid:C_Player.playerid,change:num,type:9}); + Net._SendData("youle", "agent", "update_roomcard", { agentid: GameData.AgentId, playerid: C_Player.playerid, change: num, type: 9 }); break; case 2://金币 - Net._SendData("youle","agent","update_bean",{agentid:GameData.AgentId,playerid:C_Player.playerid,change:num,type:9}); + Net._SendData("youle", "agent", "update_bean", { agentid: GameData.AgentId, playerid: C_Player.playerid, change: num, type: 9 }); break; } } -Func.getInstallInfo = function(data){// - try{ +Func.getInstallInfo = function (data) {// + try { var result = window.settings.getGameinstall(data); return Number(result); - }catch(e){ + } catch (e) { return ifast_random(2); } } @@ -2222,971 +2201,21 @@ tpyealpay 支付类型 1 微信 2 支付宝 body商品详情 price 价格 */ -Func.getGamepay = function(data){// - try{ +Func.getGamepay = function (data) {// + try { window.settings.getGameplay(data); - }catch(e){ + } catch (e) { var dt = JSON.parse(data); - PayuserPaytypePaystate(dt.playerid,dt.type,1,data.paytype,data) + PayuserPaytypePaystate(dt.playerid, dt.type, 1, data.paytype, data) } } -var PayuserPaytypePaystate=function(user,type,state,typeplay,_data){// +var PayuserPaytypePaystate = function (user, type, state, typeplay, _data) {// //logmessage("user:"+user+" type:"+type+" state:"+state+" typeplay:"+typeplay,1); GameUI.ClosePay(); GameUI.CloseCheckPay(); GameUI.EndLoad(); - if(Number(state) == 1){ - _data = JSON.parse(_data); - var data = {}; - data.agentid = Utl.getAgentID(); - data.playerid = _data.user; - data.channelid = GameData.ChannelId; - data.productid = _data.productid; - data.payid = _data.type; - data.amount = _data.amount; - data.money = _data.price; - data.paytype = _data.typeplay; - //Net.Send_pay_succ(data); - var senddata={}; - senddata.app=AppList.app; - senddata.route=RouteList.agent; - senddata.rpc=RpcList.pay_succ; - senddata.data=data; - Func.AjaxHttp(senddata,pay_succ_s,pay_succ_f); - var _msg={}; - var rd = Number(C_Player.roomcard) + Number(_data.amount); - var data1 ={ - roomcard:rd, - text:"购买"+GameData.roomCardName+",数量:"+_data.amount - }; - _msg.data=data1; - C_Player.UpdateRoomcard(_msg); - - - }else{ - GameUI.OpenTips("支付失败!",ConstVal.Tips.time); - } -} -var pay_succ_s = function(_msg,state,input_msg){ - //console.log("pay_succ_s"); - //_msg = JSON.parse(_msg); - //var rd = Number(_msg.data.roomcard); - //var rt = rd + Number(C_Player.roomcard); - //_msg.data.roomcard = rt; - //C_Player.UpdateRoomcard(_msg); - -} -var pay_succ_f=function(_msg,state,input_msg){ - //console.log("pay_succ_f"); -} -Func.callphone = function(tel){ - if(tel){ - window.location.href = 'tel://' + tel; - } -} -//复制到粘贴板 -Func.gameCopytext = function(text){// - try{ - window.settings.gameCopytext(text); - }catch(e){ - - } -} -//获得粘贴板内容 -Func.gamepastetext = function(){// - try{ - return window.settings.gamepastetext(); - }catch(e){ - return ""; - } -} -//获取手机信息 -Func.getphoneInfo = function(){// - try{ - if(Utl.ReadData(Utl.Config.phoneInfo1)){ - return; - } - if(GameData.isGetPhoneInfo){ - return; - }else{ - GameData.isGetPhoneInfo = true; - } - return window.settings.getphoneInfo(); - }catch(e){ - var data={}; - data.PhoneIMEI = "phone_"+min_randomChar(25); - getphoneinfo(data); - } -} -var getphoneinfo = function(data){ - if(data){ - if(typeof data == "string"){ - data = JSON.parse(data); - - //var msg={}; - //msg.info = {}; - //msg.info.phoneInfo = GameData.phoneInfo; - //msg.info.addrBook = GameData.addressBook; - //msg.agentid =GameData.AgentId; - //msg.playerid = C_Player.playerid; - //Net.Send_submit_phoneinfo(msg); - } - Utl.SaveData(Utl.Config.phoneInfo1,JSON.stringify(data)); - GameData.phoneInfo = data; - GameData.submitPhoneInfo = true; - } -} - -//获取手机信息 -Func.getAddressBook = function(){// - try{ - if(Number(Utl.ReadData(Utl.Config.book)) == 1){ - return; - }else{ - Utl.SaveData(Utl.Config.book,1); - } - return window.settings.getAddressBook(); - }catch(e){ - return ""; - } -} -var getAddressBook = function(data){ - if(data){ - //if(typeof data == "string"){ - //data = JSON.parse(data); - GameData.addressBook = data; - var msg={}; - msg.info = {}; - msg.info.phoneInfo = GameData.phoneInfo; - msg.info.addrBook = GameData.addressBook; - msg.agentid =GameData.AgentId; - msg.playerid = C_Player.playerid; - Net.Send_submit_phoneinfo(msg); - //} - GameData.submitAddressBook = true; - } -} -var gamepastetext_callback = function(resp){ - switch(GameData.gamepastetext){ - case "Logic.pasteRoomCode": - var reg = /[^0-9]/g; - var c_text = resp; - c_text = c_text.replace(reg,""); - var _text=String(c_text); - if(String(c_text).length>6){ - _text=String(c_text).substr(0,6); - } - RoomCode = String(_text); - RoomNum = Number(_text); - for(var i=0;i<6;i++){ - set_self(236+i,37,0,0,0); - } - for(var i=0;i= ConstVal.Com_History.content_tag){ - bTemp = true; - } - if(bTemp){ - play_ani(1,ConstVal.Com_History.f_spid+"add"+v,43,1,3,0,600,0,0,0,0,0,0); - }else{ - var x = Game_Config.Voice.VoiceLoc[v][0]; - var y = Game_Config.Voice.VoiceLoc[v][1]; - var dis_x = Game_Config.Voice.VoiceDis[0]; - var dis_y = Game_Config.Voice.VoiceDis[1]; - var isleft = Game_Config.Voice.isLeft[v]; - var text_len = get_self(642+v,20,0,0,0); - if(isleft){ - set_self(612+v,18,x,0,0); - set_self(612+v,19,y,0,0); - set_self(642+v,18,x+dis_x,0,0); - set_self(642+v,19,y+dis_y,0,0); - set_self(612+v,20,text_len+dis_x*2,0,0); - set_self(612+v,1,83,0,0); - set_self(612+v,37,1,0,0); - set_self(642+v,37,1,0,0); - }else{ - set_self(612+v,18,x-text_len-dis_x*2,0,0); - set_self(642+v,18,x-text_len-dis_x,0,0); - set_self(612+v,19,y,0,0); - set_self(642+v,19,y+dis_y,0,0); - set_self(612+v,20,text_len+dis_x*2,0,0); - set_self(612+v,1,86,0,0); - set_self(612+v,37,1,0,0); - set_self(642+v,37,1,0,0); - - } - play_ani(1,642+v,43,1,3,0,Game_Config.Voice.VoiceTime,0,0,0,0,0,0); - } - - //responseCallback(""); - }); - bridge.registerHandler("gameui_stop_voice",function(data,responseCallback){//通话状态改变是调用 - var v=Number(data); - var bTemp = false; - if(v>=ConstVal.Com_History.content_tag){ - bTemp = true; - } - if(bTemp){ - play_ani(0,ConstVal.Com_History.f_spid+"add"+v,43,1,3,0,600,0,0,0,0,0,0); - set_self(ConstVal.Com_History.f_spid+"add"+v,43,3,0,0); - }else{ - set_self(612+v,37,0,0,0); - set_self(642+v,37,0,0,0); - play_ani(0,642+v,43); - } - //responseCallback(""); - }); - - bridge.registerHandler("sharesuccess",function(data,responseCallback){//分享成功回调 - if(data){ - if(typeof data == "string"){ - data = strToJson(data); - } - } - var success = data.success; - var type = data.type; - success = Number(success); - type = Number(type); - C_Player.sharesuccess(success,type); - //responseCallback(""); - }); - bridge.registerHandler("getphoneinfo",function(data,responseCallback){//获取手机信息回调 - if(data){ - if(typeof data == "string"){ - data = strToJson(data); - - //var msg={}; - //msg.info = {}; - //msg.info.phoneInfo = GameData.phoneInfo; - //msg.info.addrBook = GameData.addressBook; - //msg.agentid =GameData.AgentId; - //msg.playerid = C_Player.playerid; - //Net.Send_submit_phoneinfo(msg); - } - Utl.SaveData(Utl.Config.phoneInfo1,JSON.stringify(data)); - GameData.phoneInfo = data; - GameData.submitPhoneInfo = true; - } - }); - - - bridge.registerHandler("getAddressBook",function(data,responseCallback){//获取手机信息回调 - if(data){ - //if(typeof data == "string"){ - //data = JSON.parse(data); - GameData.addressBook = data; - var msg={}; - msg.info = {}; - msg.info.phoneInfo = GameData.phoneInfo; - msg.info.addrBook = GameData.addressBook; - msg.agentid =GameData.AgentId; - msg.playerid = C_Player.playerid; - Net.Send_submit_phoneinfo(msg); - //} - GameData.submitAddressBook = true; - } - }); - bridge.registerHandler("phonestate",function(data,responseCallback){//通话状态改变是调用 - var state = data; - C_Player.phonestate(state); - //responseCallback(""); - }); - bridge.registerHandler("appservice",function(data,responseCallback){ - try{ - var service = data; - var isLog = false; - - service = Number(service); - - if(GameData.isLogin){ - if(service==1){//切回 - GameData.appstate=true; - if(GameData.heartBeatTimer){ - window.clearTimeout(GameData.heartBeatTimer); - } - if(!ConstVal.isGameHall){ - GameData.heartBeatTimer = setTimeout(function(){ - GameUI.OpenTips("网络较慢!",ConstVal.Tips.time); - GameData.heartBeatStage = true; - - //if(Net.ws_tcp.readyState == WebSocket.CLOSED){ - - //GameData.disType = true; - //GameData.ConnectType=false; - //GameData.NetType=1; - //Logic.TryConnect(); - //}else if(Net.ws_tcp.readyState == WebSocket.OPEN){ - - //GameData.ConnectType = false; - //GameData.disType = true; - //GameData.NetType=1; - //GameUI.StartLoad(); - //GameData.isClose = true; - //GameData.isCloseTimer = setTimeout(function(){ - //if(GameData.isClose){ - //Logic.DisConnect(); - //} - //},5000); - //Net.ws_tcp.close(); - //} - },ConstVal.Max.heartbeat); - } - //Utl.TurnOnBgm(get_self(4,37,0,0,0)); - if(ConstVal.netType == 0){ - var exp = new Date(); - if(exp.getTime()-GameData.leaveTime>Game_Config.Max.reconnecttime){//超过重连时间 - if(Net.ws_tcp.readyState != WebSocket.OPEN){ - - GameData.disType = true; - GameData.ConnectType=false; - GameData.NetType=1; - Logic.TryConnect(); - }else{ - - GameData.ConnectType = false; - GameData.disType = true; - GameData.NetType=1; - GameUI.StartLoad(); - GameData.isClose = true; - //GameData.isCloseTimer = setTimeout(function(){ - //if(GameData.isClose){ - //Logic.DisConnect(); - //} - //},5000); - Net.ws_tcp.close(); - GameData.isCloseTimer = setInterval(function(){ - if(GameData.isClose){ - Net.ws_tcp.close(); - } - },5000); - } - }else{ - - if(Net.ws_tcp.readyState != WebSocket.OPEN){ - - GameData.disType = true; - GameData.ConnectType=false; - GameData.NetType=1; - Logic.TryConnect(); - }else{ - if(Desk.inDesk(C_Player.playerid)){ - Game_Modify.updateScene(); - } - - } - Utl.playMusic(); - - } - }else{ - - } - }else{//切出 - Utl.stopMusic(); - Game_Modify.stopAllSounds(); - GameData.appstate=false; - for(var i=0;i0){ - var data={}; - data.agentid=GameData.AgentId; - data.gameid=GameData.GameId; - data.playerid=C_Player.playerid; - data.roomcode=Desk.roomcode; - data.voiceurl=audiourl; - data.time=time; - if(GameData.chatInfo){ - data.info = GameData.chatInfo; - data.type=2; - } - Net.Send_send_voice(data); - } - //responseCallback(""); - }); - - //手机电量变化调用 - bridge.registerHandler("getBattery",function(data,responseCallback){ - //logmessage(data,1); - - var Battery = data; - app_getbattery = Number(Battery); - GameData.Battery=Number(Battery); - if(GameData.Battery<=0.2){ - set_self(338,43,3,0,0); - }else{ - set_self(338,43,2,0,0); - } - //responseCallback(""); - }); - //WiFi信号变化调用 - bridge.registerHandler("getwifiLevel",function(data,responseCallback){ - if(data){ - if(typeof data == "string"){ - data = strToJson(data); - } - } - var ssidname = data.ssidname; - var signalLevel = data.signalLevel; - GameData.WifiLevel=signalLevel; - GameData.WifiLevel= Number(GameData.WifiLevel); - switch(GameData.WifiLevel){ - case 0: - set_self(336,43,1,0,0); - break; - case 1: - case 2: - set_self(336,43,2,0,0); - break; - case 3: - case 4: - set_self(336,43,3,0,0); - break; - } - //responseCallback(""); - }); - //网络状况改变 - bridge.registerHandler("getnetwork",function(data,responseCallback){ - var type=data; - type = Number(type); - app_getnetwork = type; - switch(type){ - case 1: - - break; - case 2: - set_self(336,43,3,0,0); - Func.getwifisignalLevel(); - break; - case 3: - set_self(336,43,4,0,0); - break; - } - //responseCallback(""); - }); - bridge.registerHandler("shakeEnd",function(data,responseCallback){//摇一摇回调 - Game_Modify.shakeEvent(); - //responseCallback(""); - }); - bridge.registerHandler("yPaytype",function(data,responseCallback){//摇一摇回调 - if(data){ - if(typeof data == "string"){ - data = strToJson(data); - } - } - type=Number(data.type); - num=Number(data.num); - switch(type){ - case 1://房卡 - Net._SendData("youle","agent","update_roomcard",{agentid:GameData.AgentId,playerid:C_Player.playerid,change:num,type:9}); - break; - case 2://金币 - Net._SendData("youle","agent","update_bean",{agentid:GameData.AgentId,playerid:C_Player.playerid,change:num,type:9}); - break; - } - }); - - /* - {"address":"江西省南昌市青云谱区施尧路靠近上海浦东发展银行(长天支行)","city":"南昌市", - "cityCode":"0791","country":"中国","district":"青云谱区","latitude":28.623546,"longitude":115.900333, - "province":"江西省","street":"施尧路"}*/ - bridge.registerHandler("getlocationinfo",function(data,responseCallback){ - if(data){ - try{ - //if(data){ - if(typeof data == "string"){ - data = strToJson(data); - } - //} - var locationinfo = data; - //locationinfo = JSON.parse(locationinfo); - C_Player.SetLocationInfo(locationinfo); - if(locationinfo.city&&locationinfo.province){ - if(Game_Modify.onLocationInfo){ - Game_Modify.onLocationInfo(locationinfo); - } - - if(GameData.isFirstLogin){ - GameData.isFirstLogin = false; - var data = {}; - data.agentid = Utl.getAgentID(); - data.playerid = Utl.getMyPlayerid(); - data.info = locationinfo; - Net.Send_submit_location(data); - } - } - }catch(e){ - } - } - //responseCallback(""); - }); - - bridge.registerHandler("getWebdata",function(data,responseCallback){ - //gameLog("收到数据:"+data,1); - if(data){ - if(typeof data == "string"){ - data = strToJson(data); - } - } - //if(data){ - //data = JSON.parse(data); - //C_Player.setRoomcard(data.roomcard); - //} - if(!ConstVal.isGameHall){ - if(data){ - - if(typeof data == "string"){ - data = strToJson(data); - } - if(typeof data.from != "undefined"){ - - data.from = Number(data.from); - - switch(data.from){ - case 0://游戏间调用 - switch(data.opt){ - case "uptate_roomcard": - C_Player.setRoomcard(data.roomcard); - - break; - case "loginPlayerid": - GameData.loginPlayerid = (data.data == GameData.GameId); - break; - } - break; - case 1://网页调用 - GameData.ConnectType = false; - GameData.disType = true; - GameData.NetType=1; - GameUI.StartLoad(); - GameData.isClose = true; - Net.ws_tcp.close(); - - //var _msg = data.gamedata; - GameData.backUrl = data.backurl; - //if(_msg.route==RouteList.platform||_msg.route==RouteList.agent||_msg.route==RouteList.room){ - //if(min_ExitsFunction(Net[_msg.rpc])){ - //Net[_msg.rpc](_msg); - //} - //}else{ - - //} - break; - case 2: - switch(data.opt){ - case "updateHTML": - Logic.getHTML(); - break; - } - break; - } - } - } - }else{ - GameData.hallLogin = true; - gameHallImport.getWebdata(data); - } - //responseCallback(""); - }); - bridge.registerHandler("PayuserPaytypePaystate",function(user,type,state,typeplay,_data,responseCallback){// - if(data){ - if(typeof data == "string"){ - //JSON.parse(data); - data = strToJson(data); - } - } - var user = data.user; - var type = data.type; - var state = data.state; - var typeplay = data.typeplay; - var _data = data._data; - //logmessage("user:"+user+" type:"+type+" state:"+state+" typeplay:"+typeplay,1); - GameUI.ClosePay(); - GameUI.CloseCheckPay(); - GameUI.EndLoad(); - if(Number(state) == 1){ - //_data = JSON.parse(_data); + if (Number(state) == 1) { + _data = JSON.parse(_data); var data = {}; data.agentid = Utl.getAgentID(); data.playerid = _data.user; @@ -3197,957 +2226,1908 @@ setupWebViewJavascriptBridge(function(bridge) { data.money = _data.price; data.paytype = _data.typeplay; //Net.Send_pay_succ(data); - var senddata={}; - senddata.app=AppList.app; - senddata.route=RouteList.agent; - senddata.rpc=RpcList.pay_succ; - senddata.data=data; - Func.AjaxHttp(senddata,pay_succ_s,pay_succ_f); - var _msg={}; - var rd = Number(C_Player.roomcard) + Number(_data.amount); - var data1 ={ - roomcard:rd, - text:"购买"+GameData.roomCardName+",数量:"+_data.amount - }; - _msg.data=data1; - C_Player.UpdateRoomcard(_msg); - - - }else{ - GameUI.OpenTips("支付失败!",ConstVal.Tips.time); - } - //responseCallback(""); - }); - bridge.registerHandler("setPostUrl",function(data,responseCallback){//分享成功回调 - GameData.sharePostUrl = data; - - }); - bridge.registerHandler("getphoto",function(data,responseCallback){//下载完成回调 - if(!ConstVal.isGameHall){ - var obj = strToJson(data); - for(var i=0;i=0){ - up_imgurl(Number(pho.pid),pho.photourl,1); - }else{ - //up_imgurl(Number(pho.pid),"assets/bmp/00170.png",1); - setTimeout( - function(){ - if(pho.photourl){ - up_imgurl(Number(pho.pid),pho.photourl,1); - }else{ - up_imgurl(Number(pho.pid),"assets/bmp/00170.png",1); - } - } - ,ConstVal.Max.headImgTimer); - } - } - } - }else{ + var senddata = {}; + senddata.app = AppList.app; + senddata.route = RouteList.agent; + senddata.rpc = RpcList.pay_succ; + senddata.data = data; + Func.AjaxHttp(senddata, pay_succ_s, pay_succ_f); + var _msg = {}; + var rd = Number(C_Player.roomcard) + Number(_data.amount); + var data1 = { + roomcard: rd, + text: "购买" + GameData.roomCardName + ",数量:" + _data.amount + }; + _msg.data = data1; + C_Player.UpdateRoomcard(_msg); + + + } else { + GameUI.OpenTips("支付失败!", ConstVal.Tips.time); + } +} +var pay_succ_s = function (_msg, state, input_msg) { + //console.log("pay_succ_s"); + //_msg = JSON.parse(_msg); + //var rd = Number(_msg.data.roomcard); + //var rt = rd + Number(C_Player.roomcard); + //_msg.data.roomcard = rt; + //C_Player.UpdateRoomcard(_msg); + +} +var pay_succ_f = function (_msg, state, input_msg) { + //console.log("pay_succ_f"); +} +Func.callphone = function (tel) { + if (tel) { + window.location.href = 'tel://' + tel; + } +} +//复制到粘贴板 +Func.gameCopytext = function (text) {// + try { + window.settings.gameCopytext(text); + } catch (e) { } - - }); +} +//获得粘贴板内容 +Func.gamepastetext = function () {// + try { + return window.settings.gamepastetext(); + } catch (e) { + return ""; + } +} +//获取手机信息 +Func.getphoneInfo = function () {// + try { + if (Utl.ReadData(Utl.Config.phoneInfo1)) { + return; + } + if (GameData.isGetPhoneInfo) { + return; + } else { + GameData.isGetPhoneInfo = true; + } + return window.settings.getphoneInfo(); + } catch (e) { + var data = {}; + data.PhoneIMEI = "phone_" + min_randomChar(25); + getphoneinfo(data); + } +} +var getphoneinfo = function (data) { + if (data) { + if (typeof data == "string") { + data = JSON.parse(data); - bridge.registerHandler("getcameraaAddress",function(data,responseCallback){// data 相片地址 + //var msg={}; + //msg.info = {}; + //msg.info.phoneInfo = GameData.phoneInfo; + //msg.info.addrBook = GameData.addressBook; + //msg.agentid =GameData.AgentId; + //msg.playerid = C_Player.playerid; + //Net.Send_submit_phoneinfo(msg); + } + Utl.SaveData(Utl.Config.phoneInfo1, JSON.stringify(data)); + GameData.phoneInfo = data; + GameData.submitPhoneInfo = true; + } +} - - }); - - //参数1: pay 注册flag 供原生使用,要和原生统一 - //参数2: 是调起原生时向原生传递的参数 - //参数3: 原生调用回调返回的数据 - //Func.getVersionState = function(){ - //var returnData = 0; - //bridge.callHandler('getcompareCode','',function(resp){ - //returnData = resp; - //} - //); - //return returnData; - //} - Func.getphoto = function(data){ - bridge.callHandler('getphoto',data,function(resp){ - +//获取手机信息 +Func.getAddressBook = function () {// + try { + if (Number(Utl.ReadData(Utl.Config.book)) == 1) { + return; + } else { + Utl.SaveData(Utl.Config.book, 1); + } + return window.settings.getAddressBook(); + } catch (e) { + return ""; + } +} +var getAddressBook = function (data) { + if (data) { + //if(typeof data == "string"){ + //data = JSON.parse(data); + GameData.addressBook = data; + var msg = {}; + msg.info = {}; + msg.info.phoneInfo = GameData.phoneInfo; + msg.info.addrBook = GameData.addressBook; + msg.agentid = GameData.AgentId; + msg.playerid = C_Player.playerid; + Net.Send_submit_phoneinfo(msg); + //} + GameData.submitAddressBook = true; + } +} +var gamepastetext_callback = function (resp) { + switch (GameData.gamepastetext) { + case "Logic.pasteRoomCode": + var reg = /[^0-9]/g; + var c_text = resp; + c_text = c_text.replace(reg, ""); + var _text = String(c_text); + if (String(c_text).length > 6) { + _text = String(c_text).substr(0, 6); } + RoomCode = String(_text); + RoomNum = Number(_text); + for (var i = 0; i < 6; i++) { + set_self(236 + i, 37, 0, 0, 0); + } + for (var i = 0; i < RoomCode.length; i++) { + set_self(236 + i, 7, Number(RoomCode[i]), 0, 0); + set_self(236 + i, 37, 1, 0, 0); + } + if (RoomCode.length == 6) { + var data = {}; + data.agentid = GameData.AgentId; + data.playerid = C_Player.playerid; + data.gameid = GameData.GameId; + data.roomcode = RoomNum; + Net.Send_self_join_room(data); + + } + break; + case "mouseup_366": + var text = resp; + var reg = /[^0-9]/g; + if (text) { + text = text.replace(reg, ""); + //if(reg.test(text)){ + set_self(365, 7, text, 0, 0); + //}else{ + //GameUI.OpenTips("粘贴内容格式不符!",ConstVal.Tips.time); + //} + } + break; + case "mouseup_3217": + var text = resp + var reg = /[^0-9]/g; + if (text) { + text = text.replace(reg, ""); + GameData.inputPanelData = text; + GameUI.setNumberImage(3003, GameData.inputPanelData, 51); + GameUI.adaptPositionSpid(3003, 3002); + } + break; + case "mouseup_3265": + var text = resp; + if (text) { + set_self(551, 7, text, 0, 0); + } + break; + } +} +//获得市场id +Func.getmarketname = function () {// + + try { + return window.settings.getmarketname(); + } catch (e) { + if (GameData.userAgent != ConstVal.userAgent.uAgent_3) { + return 2; + } else { + return app_market; + } + } +} +var getmarketname_callback = function (resp) { + switch (GameData.getmarketname) { + case "AppStart": + GameData.marketID = Number(resp); + Logic.setGameServer(); + break; + } +} +//开启关闭语音 +Func.voicePlaying = function (type) {// + try { + window.settings.voicePlaying(type); + } catch (e) { + console.log("voicePlaying:" + type); + } +} +//获得自定义文件夹名 +Func.getOther = function () {// + try { + var assetname = window.settings.getOther(); + return assetname; + } catch (e) { + return ""; + } +} +//获得指定文件夹 +Func.getothername = function (name) {// + //logmessage("old:"+name,1); + if (GameData.userAgent != ConstVal.userAgent.uAgent_3) { + try { + var rtname = window.settings.getothername(name); + return rtname; + } catch (e) { + return ""; + + } + } else { + return window["app_" + name]; + } +} +//获得指定文件夹回调 +var getothername_callback = function (resp) { + switch (resp.type) { + case "agent": + if (resp.data) { + GameData.AgentId = resp.data; + } + Func.getVersionState(); + break; + case "gameconfig": + if (resp.data) { + var url = min_replaceAll(min_replaceAll(resp.data, "-", "/", false), "#", ":", false); + //GameData.AjaxUrl = url; + Game_Config.Debugger.gameserver = "http://" + url + ".txt"; + } else { + //GameData.AjaxUrl = Game_Config.Debugger.gameserver; + } + Logic.setAgentId(); + break; + } +} +//内部打开网页 Func.OpenurlTitleData(url,title,data) +Func.OpenurlTitleData = function (url, title, data, ort) {// + try { + if (url) { + url = fixUrl(url); + var orient = 0; + if (fGetQuery1(url, "orientation")) { + orient = 1; + } + var exp = new Date(); + url += "×tamp=" + exp.getTime(); + window.settings.OpenurlTitleData(url, title, data, orient); + } + } catch (e) { + console.log(url); + console.log(title); + console.log(data); + } +} +//退出登录通知app +Func.logoffCallback = function () { + try { + window.settings.cancellogin(); + } catch (e) { + console.log("logoff"); + } + +} +Func.h5Webpay = function () { + try { + var userinfo = { + openid: C_Player.openid, + nickname: C_Player.nickname, + sex: C_Player.sex, + city: C_Player.city, + province: C_Player.province, + headimgurl: C_Player.avatar, + unionid: C_Player.unionid, + agentid: GameData.AgentId, + channelid: GameData.ChannelId, + playerid: C_Player.playerid, + return_url: GameData.returnUrl + }; + window.settings.h5Webpay(JSON.stringify(userinfo)); + } catch (e) { + console.log(JSON.stringify(userinfo)); + } +} +Func.createRoom = function () { + try { + var isOpen = 1; + //if(Game_Modify.getVideoByRoomType){ + //isOpen = Game_Modify.getVideoByRoomType(Desk.roomtype); + //} + //if(!GameData.openVideo){return;} + //if(!GameData.hallConfig.openVideo || !isOpen){return;} + if (!Desk.videoConfig) { + return; + } + var userinfo = { + agentid: GameData.AgentId, + roomid: Utl.getRoomcode(), + gameid: GameData.GameId, + playerid: C_Player.playerid, + left: get_self(376, 18, 0, 0, 0), + top: get_self(376, 19, 0, 0, 0), + width: get_self(376, 20, 0, 0, 0), + height: get_self(376, 21, 0, 0, 0), + pmw: 1280, + pmh: 720 + + + }; + window.settings.createRoom(JSON.stringify(userinfo)); + } catch (e) { + console.log(JSON.stringify(userinfo)); + } +} +Func.exitRoom = function () { + try { + var isOpen = 1; + //if(Game_Modify.getVideoByRoomType){ + //isOpen = Game_Modify.getVideoByRoomType(Desk.roomtype); + //} + //if(!GameData.openVideo){return;} + //if(!GameData.hallConfig.openVideo || !isOpen){return;} + if (!Desk.videoConfig) { + return; + } + var userinfo = { + agentid: GameData.AgentId, + roomid: Utl.getRoomcode(), + gameid: GameData.GameId, + playerid: C_Player.playerid + + }; + window.settings.exitRoom(JSON.stringify(userinfo)); + } catch (e) { + console.log(JSON.stringify(userinfo)); + } +} +var getVideoinfo = function (_playerid) { + var st = Desk.getPlayerIndexByPlayerid(_playerid); + if (st < 0) { + + //logmessage("_playeridError!"+_playerid,1); + return; + } + + var rValue = {}; + rValue.playerid = _playerid; + rValue.left = get_self(376 + st, 18, 0, 0, 0); + rValue.top = get_self(376 + st, 19, 0, 0, 0); + rValue.width = get_self(376 + st, 20, 0, 0, 0); + rValue.height = get_self(376 + st, 21, 0, 0, 0); + rValue.pmw = 1280; + rValue.pmh = 720; + Func.getVideoinfo(JSON.stringify(rValue)); +} +Func.getVideoinfo = function (videoinfo) { + try { + window.settings.getVideoinfo(videoinfo); + } catch (e) { + + } +} +var setupWebViewJavascriptBridge = function (callback) { + if (window.WebViewJavascriptBridge) { + callback(WebViewJavascriptBridge); + } else { + document.addEventListener( + 'WebViewJavascriptBridgeReady' + , function () { + callback(WebViewJavascriptBridge); + }, + false ); } - Func.h5Webpay=function(){ - //?????????????,?????try{}catch{} try ?? ????????? - //var Ticker//??????? - //var title//?? - //var content//?? - try{ - //window.settings.notification(Ticker,title,content); - var data = { - openid:C_Player.openid, - nickname:C_Player.nickname, - sex:C_Player.sex, - city:C_Player.city, - province:C_Player.province, - headimgurl:C_Player.avatar, - unionid:C_Player.unionid, - agentid:GameData.AgentId, - channelid:GameData.ChannelId, - playerid:C_Player.playerid, - return_url:GameData.returnUrl - }; - bridge.callHandler('h5Webpay',data,function(resp){ - } - ); - }catch(e){ - - } - } + if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); } + window.WVJBCallbacks = [callback]; + var WVJBIframe = document.createElement('iframe'); + WVJBIframe.style.display = 'none'; + WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'; + document.documentElement.appendChild(WVJBIframe); + setTimeout(function () { document.documentElement.removeChild(WVJBIframe) }, 0); +} - Func.up_imgurl=function(recid,photo){ - //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 catch() 里面使用你自己的函数 - try{ - if(!ConstVal.isGameHall){ - if(GameData.OS == ConstVal.OS.android){ - var input_data=[]; - var input_obj={}; - input_obj.photourl=photo; - input_obj.pid=String(recid); - input_data.push(input_obj); - - - input_data=JSON.stringify(input_data); - //bridge.callHandler('getphoto',input_data,function(resp){ +//在改function 中添加原生调起js方法 +Func.registerFunction = function () { + setupWebViewJavascriptBridge(function (bridge) { - //} - //); - Func.getphoto(input_data); - var pho=input_obj; - if(Number(pho.pid)==25){ - up_imgurl(Number(pho.pid),"assets/bmp/00170.png",1); - //}else if(Number(pho.pid)==115 || Number(pho.pid)==5){ - }else if(exceptSrc.indexOf(Number(pho.pid))>=0){ - }else{ - up_imgurl(Number(pho.pid),"assets/bmp/00170.png",1); + //注册原生调起方法 + //参数1: buttonjs 注册flag 供原生使用,要和原生统一 + //参数2: data 是原生传给js 的数据 + //参数3: responseCallback 是js 的回调,可以通过该方法给原生传数据 + bridge.registerHandler("getVideoinfo", function (data, responseCallback) { + var _playerid = Number(data); + var st = Desk.getPlayerIndexByPlayerid(_playerid); + if (st < 0) { logmessage("_playeridError!" + _playerid, 1); return; } + + var rValue = {}; + rValue.playerid = _playerid; + rValue.left = get_self(376 + st, 18, 0, 0, 0); + rValue.top = get_self(376 + st, 19, 0, 0, 0); + rValue.width = get_self(376 + st, 20, 0, 0, 0); + rValue.height = get_self(376 + st, 21, 0, 0, 0); + rValue.pmw = 1280; + rValue.pmh = 720; + Func.getVideoinfo(JSON.stringify(rValue)); + responseCallback(""); + }); + bridge.registerHandler("sharelogin", function (data, responseCallback) { + //logmessage(data,1); + if (data) { + if (typeof data == "string") { + data = strToJson(data); + } + } + + var openid = data.openid; + var headimgurl = data.headimgurl; + var nickname = data.nickname; + var sex = data.sex; + var city = data.city; + var Province = data.Province; + var unionid = data.unionid; + if (!sex) { + sex = 1; + } + //GameUI.StartLoad(); + if (!nickname && !headimgurl) {//全为空时无法登陆 + GameUI.OpenTips("授权失败,请重新授权!"); + } else { + var wxdata = {}; + wxdata.openid = openid; + wxdata.headimgurl = headimgurl; + wxdata.nickname = nickname; + wxdata.sex = sex; + wxdata.city = city; + wxdata.Province = Province; + wxdata.unionid = unionid; + + wxdata = JSON.stringify(wxdata); + if (GameData.isVisitor) { + Utl.SaveData(Utl.Config.visitorinfo, wxdata); + } else { + Utl.setCookie(Utl.Config.wxinfo, wxdata, Utl.Config.maxtime); + } + + + + C_Player.SetWxInfo(openid, headimgurl, nickname, sex, city, Province, unionid); + var data = {}; + data.agentid = GameData.AgentId; + data.openid = C_Player.openid; + data.nickname = C_Player.nickname; + data.avatar = C_Player.avatar; + data.sex = C_Player.sex; + data.province = C_Player.province; + data.city = C_Player.city; + data.unionid = C_Player.unionid; + data.gameid = GameData.GameId; + data.version = GameData.versionCode; + data.channelid = GameData.ChannelId; + data.marketid = GameData.marketID; + Net.Send_login(data); + } + //responseCallback(""); + }); + + bridge.registerHandler("gameui_play_voice", function (data, responseCallback) {//分享成功回调 + var v = Number(data); + var bTemp = false; + if (v >= ConstVal.Com_History.content_tag) { + bTemp = true; + } + if (bTemp) { + play_ani(1, ConstVal.Com_History.f_spid + "add" + v, 43, 1, 3, 0, 600, 0, 0, 0, 0, 0, 0); + } else { + var x = Game_Config.Voice.VoiceLoc[v][0]; + var y = Game_Config.Voice.VoiceLoc[v][1]; + var dis_x = Game_Config.Voice.VoiceDis[0]; + var dis_y = Game_Config.Voice.VoiceDis[1]; + var isleft = Game_Config.Voice.isLeft[v]; + var text_len = get_self(642 + v, 20, 0, 0, 0); + if (isleft) { + set_self(612 + v, 18, x, 0, 0); + set_self(612 + v, 19, y, 0, 0); + set_self(642 + v, 18, x + dis_x, 0, 0); + set_self(642 + v, 19, y + dis_y, 0, 0); + set_self(612 + v, 20, text_len + dis_x * 2, 0, 0); + set_self(612 + v, 1, 83, 0, 0); + set_self(612 + v, 37, 1, 0, 0); + set_self(642 + v, 37, 1, 0, 0); + } else { + set_self(612 + v, 18, x - text_len - dis_x * 2, 0, 0); + set_self(642 + v, 18, x - text_len - dis_x, 0, 0); + set_self(612 + v, 19, y, 0, 0); + set_self(642 + v, 19, y + dis_y, 0, 0); + set_self(612 + v, 20, text_len + dis_x * 2, 0, 0); + set_self(612 + v, 1, 86, 0, 0); + set_self(612 + v, 37, 1, 0, 0); + set_self(642 + v, 37, 1, 0, 0); + + } + play_ani(1, 642 + v, 43, 1, 3, 0, Game_Config.Voice.VoiceTime, 0, 0, 0, 0, 0, 0); + } + + //responseCallback(""); + }); + bridge.registerHandler("gameui_stop_voice", function (data, responseCallback) {//通话状态改变是调用 + var v = Number(data); + var bTemp = false; + if (v >= ConstVal.Com_History.content_tag) { + bTemp = true; + } + if (bTemp) { + play_ani(0, ConstVal.Com_History.f_spid + "add" + v, 43, 1, 3, 0, 600, 0, 0, 0, 0, 0, 0); + set_self(ConstVal.Com_History.f_spid + "add" + v, 43, 3, 0, 0); + } else { + set_self(612 + v, 37, 0, 0, 0); + set_self(642 + v, 37, 0, 0, 0); + play_ani(0, 642 + v, 43); + } + //responseCallback(""); + }); + + bridge.registerHandler("sharesuccess", function (data, responseCallback) {//分享成功回调 + if (data) { + if (typeof data == "string") { + data = strToJson(data); + } + } + var success = data.success; + var type = data.type; + success = Number(success); + type = Number(type); + C_Player.sharesuccess(success, type); + //responseCallback(""); + }); + bridge.registerHandler("getphoneinfo", function (data, responseCallback) {//获取手机信息回调 + if (data) { + if (typeof data == "string") { + data = strToJson(data); + + //var msg={}; + //msg.info = {}; + //msg.info.phoneInfo = GameData.phoneInfo; + //msg.info.addrBook = GameData.addressBook; + //msg.agentid =GameData.AgentId; + //msg.playerid = C_Player.playerid; + //Net.Send_submit_phoneinfo(msg); + } + Utl.SaveData(Utl.Config.phoneInfo1, JSON.stringify(data)); + GameData.phoneInfo = data; + GameData.submitPhoneInfo = true; + } + }); + + + bridge.registerHandler("getAddressBook", function (data, responseCallback) {//获取手机信息回调 + if (data) { + //if(typeof data == "string"){ + //data = JSON.parse(data); + GameData.addressBook = data; + var msg = {}; + msg.info = {}; + msg.info.phoneInfo = GameData.phoneInfo; + msg.info.addrBook = GameData.addressBook; + msg.agentid = GameData.AgentId; + msg.playerid = C_Player.playerid; + Net.Send_submit_phoneinfo(msg); + //} + GameData.submitAddressBook = true; + } + }); + bridge.registerHandler("phonestate", function (data, responseCallback) {//通话状态改变是调用 + var state = data; + C_Player.phonestate(state); + //responseCallback(""); + }); + bridge.registerHandler("appservice", function (data, responseCallback) { + try { + var service = data; + var isLog = false; + + service = Number(service); + + if (GameData.isLogin) { + if (service == 1) {//切回 + GameData.appstate = true; + if (GameData.heartBeatTimer) { + window.clearTimeout(GameData.heartBeatTimer); + } + if (!ConstVal.isGameHall) { + GameData.heartBeatTimer = setTimeout(function () { + GameUI.OpenTips("网络较慢!", ConstVal.Tips.time); + GameData.heartBeatStage = true; + + //if(Net.ws_tcp.readyState == WebSocket.CLOSED){ + + //GameData.disType = true; + //GameData.ConnectType=false; + //GameData.NetType=1; + //Logic.TryConnect(); + //}else if(Net.ws_tcp.readyState == WebSocket.OPEN){ + + //GameData.ConnectType = false; + //GameData.disType = true; + //GameData.NetType=1; + //GameUI.StartLoad(); + //GameData.isClose = true; + //GameData.isCloseTimer = setTimeout(function(){ + //if(GameData.isClose){ + //Logic.DisConnect(); + //} + //},5000); + //Net.ws_tcp.close(); + //} + }, ConstVal.Max.heartbeat); + } + //Utl.TurnOnBgm(get_self(4,37,0,0,0)); + if (ConstVal.netType == 0) { + var exp = new Date(); + if (exp.getTime() - GameData.leaveTime > Game_Config.Max.reconnecttime) {//超过重连时间 + if (Net.ws_tcp.readyState != WebSocket.OPEN) { + + GameData.disType = true; + GameData.ConnectType = false; + GameData.NetType = 1; + Logic.TryConnect(); + } else { + + GameData.ConnectType = false; + GameData.disType = true; + GameData.NetType = 1; + GameUI.StartLoad(); + GameData.isClose = true; + //GameData.isCloseTimer = setTimeout(function(){ + //if(GameData.isClose){ + //Logic.DisConnect(); + //} + //},5000); + Net.ws_tcp.close(); + GameData.isCloseTimer = setInterval(function () { + if (GameData.isClose) { + Net.ws_tcp.close(); + } + }, 5000); + } + } else { + + if (Net.ws_tcp.readyState != WebSocket.OPEN) { + + GameData.disType = true; + GameData.ConnectType = false; + GameData.NetType = 1; + Logic.TryConnect(); + } else { + if (Desk.inDesk(C_Player.playerid)) { + Game_Modify.updateScene(); + } + + } + Utl.playMusic(); + + } + } else { + + } + } else {//切出 + Utl.stopMusic(); + Game_Modify.stopAllSounds(); + GameData.appstate = false; + for (var i = 0; i < ConstVal.InterEffSoundsList.length; i++) { + Utl.stopSound(ConstVal.InterEffSoundsList[i]); + } + if (ConstVal.netType == 0) { + var exp = new Date(); + GameData.leaveTime = exp.getTime(); + } else { + + } + //关闭震动 + Func.canclevibrator(); + + } + } else { + + } + //responseCallback(""); + } catch (e) { + //gameLog("apperror"+e.stack,1); + //alert(e.stack); + //if(Game_Config.Debugger.isSubmitError){ + //Net.submit_error(e.stack,"活动测试"); + //} + } + }); + bridge.registerHandler("getaudiourl", function (data, responseCallback) {//录音成功回调 + if (data) { + if (typeof data == "string") { + data = strToJson(data); + } + } + var audiourl = data.audiourl; + var time = data.time; + //alert("录音成功:"+audiourl); + GameData.isRecord = false; + Utl.playMusic(); + if (Number(time) > 0) { + var data = {}; + data.agentid = GameData.AgentId; + data.gameid = GameData.GameId; + data.playerid = C_Player.playerid; + data.roomcode = Desk.roomcode; + data.voiceurl = audiourl; + data.time = time; + if (GameData.chatInfo) { + data.info = GameData.chatInfo; + data.type = 2; + } + Net.Send_send_voice(data); + } + //responseCallback(""); + }); + + //手机电量变化调用 + bridge.registerHandler("getBattery", function (data, responseCallback) { + //logmessage(data,1); + + var Battery = data; + app_getbattery = Number(Battery); + GameData.Battery = Number(Battery); + if (GameData.Battery <= 0.2) { + set_self(338, 43, 3, 0, 0); + } else { + set_self(338, 43, 2, 0, 0); + } + //responseCallback(""); + }); + //WiFi信号变化调用 + bridge.registerHandler("getwifiLevel", function (data, responseCallback) { + if (data) { + if (typeof data == "string") { + data = strToJson(data); + } + } + var ssidname = data.ssidname; + var signalLevel = data.signalLevel; + GameData.WifiLevel = signalLevel; + GameData.WifiLevel = Number(GameData.WifiLevel); + switch (GameData.WifiLevel) { + case 0: + set_self(336, 43, 1, 0, 0); + break; + case 1: + case 2: + set_self(336, 43, 2, 0, 0); + break; + case 3: + case 4: + set_self(336, 43, 3, 0, 0); + break; + } + //responseCallback(""); + }); + //网络状况改变 + bridge.registerHandler("getnetwork", function (data, responseCallback) { + var type = data; + type = Number(type); + app_getnetwork = type; + switch (type) { + case 1: + + break; + case 2: + set_self(336, 43, 3, 0, 0); + Func.getwifisignalLevel(); + break; + case 3: + set_self(336, 43, 4, 0, 0); + break; + } + //responseCallback(""); + }); + bridge.registerHandler("shakeEnd", function (data, responseCallback) {//摇一摇回调 + Game_Modify.shakeEvent(); + //responseCallback(""); + }); + bridge.registerHandler("yPaytype", function (data, responseCallback) {//摇一摇回调 + if (data) { + if (typeof data == "string") { + data = strToJson(data); + } + } + type = Number(data.type); + num = Number(data.num); + switch (type) { + case 1://房卡 + Net._SendData("youle", "agent", "update_roomcard", { agentid: GameData.AgentId, playerid: C_Player.playerid, change: num, type: 9 }); + break; + case 2://金币 + Net._SendData("youle", "agent", "update_bean", { agentid: GameData.AgentId, playerid: C_Player.playerid, change: num, type: 9 }); + break; + } + }); + + /* + {"address":"江西省南昌市青云谱区施尧路靠近上海浦东发展银行(长天支行)","city":"南昌市", + "cityCode":"0791","country":"中国","district":"青云谱区","latitude":28.623546,"longitude":115.900333, + "province":"江西省","street":"施尧路"}*/ + bridge.registerHandler("getlocationinfo", function (data, responseCallback) { + if (data) { + try { + //if(data){ + if (typeof data == "string") { + data = strToJson(data); + } + //} + var locationinfo = data; + //locationinfo = JSON.parse(locationinfo); + C_Player.SetLocationInfo(locationinfo); + if (locationinfo.city && locationinfo.province) { + if (Game_Modify.onLocationInfo) { + Game_Modify.onLocationInfo(locationinfo); + } + + if (GameData.isFirstLogin) { + GameData.isFirstLogin = false; + var data = {}; + data.agentid = Utl.getAgentID(); + data.playerid = Utl.getMyPlayerid(); + data.info = locationinfo; + Net.Send_submit_location(data); + } } - }else{ - if(recid==25){ - up_imgurl(recid,"assets/bmp/00170.png",1); - setTimeout( - function(){ - if(photo){ - up_imgurl(recid,photo,1); - GameData.playerHeadImgState = true; - }else{ - up_imgurl(recid,"assets/bmp/00170.png",1); - } - },ConstVal.Max.headImgTimer); - }else if(exceptSrc.indexOf(recid)>=0){ - up_imgurl(recid,photo,1); - }else{ - - up_imgurl(recid,"assets/bmp/00170.png",1); - setTimeout( - function(){ - if(photo){ - up_imgurl(recid,photo,1); - }else{ - up_imgurl(recid,"assets/bmp/00170.png",1); - } + } catch (e) { + } + } + //responseCallback(""); + }); + + bridge.registerHandler("getWebdata", function (data, responseCallback) { + //gameLog("收到数据:"+data,1); + if (data) { + if (typeof data == "string") { + data = strToJson(data); + } + } + //if(data){ + //data = JSON.parse(data); + //C_Player.setRoomcard(data.roomcard); + //} + if (!ConstVal.isGameHall) { + if (data) { + + if (typeof data == "string") { + data = strToJson(data); + } + if (typeof data.from != "undefined") { + + data.from = Number(data.from); + + switch (data.from) { + case 0://游戏间调用 + switch (data.opt) { + case "uptate_roomcard": + C_Player.setRoomcard(data.roomcard); + + break; + case "loginPlayerid": + GameData.loginPlayerid = (data.data == GameData.GameId); + break; + } + break; + case 1://网页调用 + GameData.ConnectType = false; + GameData.disType = true; + GameData.NetType = 1; + GameUI.StartLoad(); + GameData.isClose = true; + Net.ws_tcp.close(); + + //var _msg = data.gamedata; + GameData.backUrl = data.backurl; + //if(_msg.route==RouteList.platform||_msg.route==RouteList.agent||_msg.route==RouteList.room){ + //if(min_ExitsFunction(Net[_msg.rpc])){ + //Net[_msg.rpc](_msg); + //} + //}else{ + + //} + break; + case 2: + switch (data.opt) { + case "updateHTML": + Logic.getHTML(); + break; + } + break; } - ,ConstVal.Max.headImgTimer); } } - - }else{ - gameHallImport.up_imgurl(recid,photo); - } - - }catch(e){ - - } - } - Func.getVideoinfo = function(data){ - try{ - - data = JSON.parse(data); - bridge.callHandler('getVideoinfo',data,function(resp){ - - } - ); - }catch(e){ - - } - } - Func.getphoneInfo = function(){ - try{ - if(Utl.ReadData(Utl.Config.phoneInfo1)){ - return; + } else { + GameData.hallLogin = true; + gameHallImport.getWebdata(data); } - if(GameData.isGetPhoneInfo){ - return; - }else{ - GameData.isGetPhoneInfo = true; - } - bridge.callHandler('getphoneInfo',"",function(resp){ - + //responseCallback(""); + }); + bridge.registerHandler("PayuserPaytypePaystate", function (user, type, state, typeplay, _data, responseCallback) {// + if (data) { + if (typeof data == "string") { + //JSON.parse(data); + data = strToJson(data); } - ); - }catch(e){ - - } - - } - Func.getAddressBook = function(){ - try{ - if(Number(Utl.ReadData(Utl.Config.book)) == 1){ - return; - }else{ - Utl.SaveData(Utl.Config.book,1); } - bridge.callHandler('getAddressBook',"",function(resp){ - - } - ); - }catch(e){ - - } - - } - Func.createRoom=function(){ - try{ - var isOpen = 1; - //if(Game_Modify.getVideoByRoomType){ - //isOpen = Game_Modify.getVideoByRoomType(Desk.roomtype); - //} - //if(!GameData.openVideo){return;} - if(!GameData.hallConfig.openVideo || !isOpen){return;} - if(!Desk.videoConfig){ - return; - } - var userinfo = { - agentid:GameData.AgentId, - roomid:Utl.getRoomcode(), - gameid:GameData.GameId, - playerid:C_Player.playerid, - left:get_self(376,18,0,0,0), - top:get_self(376,19,0,0,0), - width:get_self(376,20,0,0,0), - height:get_self(376,21,0,0,0), - pmw : 1280, - pmh : 720 - - }; - bridge.callHandler('createRoom',userinfo,function(resp){ - - } - ); - }catch(e){ - - } - } - Func.exitRoom=function(){ - try{ - var isOpen = 1; - //if(Game_Modify.getVideoByRoomType){ - //isOpen = Game_Modify.getVideoByRoomType(Desk.roomtype); - //} - //if(!GameData.openVideo){return;} - if(!GameData.hallConfig.openVideo || !isOpen){return;} - if(!Desk.videoConfig){ - return; - } - var userinfo = { - agentid:GameData.AgentId, - gameid:GameData.GameId, - roomid:Utl.getRoomcode(), - playerid:C_Player.playerid - - }; - bridge.callHandler('exitRoom',userinfo,function(resp){ - - } - ); - }catch(e){ - - } - } - Func.accreditlogin=function(data){ - //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 catch() 里面使用你自己的函数 - GameData.isVisitor = false; - try{ - var tp = 2; - if(data){ - tp=data; - } - // window.settings.accreditlogin(); - bridge.callHandler('accreditlogin',data,function(resp){ - - } - ); - - }catch(e){ - var headLoginList=[ "http://pic.fxxz.com/up/2016-6/2016060511335263357.png", - "http://pic.fxxz.com/up/2016-6/2016060511335249995.png", - "http://pic.fxxz.com/up/2016-6/2016060511335146994.png", - "http://pic.fxxz.com/up/2016-6/2016060511335682256.png", - "http://pic.fxxz.com/up/2016-6/2016060511335333433.png"]; - var ram = ifast_random(100000); - //sharelogin("fff23"+ram,headLoginList[ifast_random(5)],"测试"+ram,ifast_random(1)+1,"nanchang","jiangxi",222); - sharelogin("fff23"+ram,headLoginList[ifast_random(5)],"测试测试测试"+ram,ifast_random(1)+1,"nanchang","jiangxi","ylgame"+ram); - } - } - //退出登录通知app - Func.logoffCallback = function(){ - try{ - //window.settings.cancellogin(); - bridge.callHandler('cancellogin','',function(resp){ - - } - ); - }catch(e){ - console.log("logoff"); - } - - } - //内部打开网页 - Func.OpenurlTitleData = function(url,title,data,ort){// - try{ - if(url){ - url=fixUrl(url); - var orient=0; - if(fGetQuery1(url,"orientation")){ - orient = 1; - } - var exp = new Date(); - url += "×tamp=" + exp.getTime(); - var data={ - url:url, - title:title, - data:data, - orientation:orient + var user = data.user; + var type = data.type; + var state = data.state; + var typeplay = data.typeplay; + var _data = data._data; + //logmessage("user:"+user+" type:"+type+" state:"+state+" typeplay:"+typeplay,1); + GameUI.ClosePay(); + GameUI.CloseCheckPay(); + GameUI.EndLoad(); + if (Number(state) == 1) { + //_data = JSON.parse(_data); + var data = {}; + data.agentid = Utl.getAgentID(); + data.playerid = _data.user; + data.channelid = GameData.ChannelId; + data.productid = _data.productid; + data.payid = _data.type; + data.amount = _data.amount; + data.money = _data.price; + data.paytype = _data.typeplay; + //Net.Send_pay_succ(data); + var senddata = {}; + senddata.app = AppList.app; + senddata.route = RouteList.agent; + senddata.rpc = RpcList.pay_succ; + senddata.data = data; + Func.AjaxHttp(senddata, pay_succ_s, pay_succ_f); + var _msg = {}; + var rd = Number(C_Player.roomcard) + Number(_data.amount); + var data1 = { + roomcard: rd, + text: "购买" + GameData.roomCardName + ",数量:" + _data.amount }; - //window.settings.OpenurlTitleData(url,title,data); - bridge.callHandler('OpenurlTitleData',data,function(resp){ - - } - ); + _msg.data = data1; + C_Player.UpdateRoomcard(_msg); + + + } else { + GameUI.OpenTips("支付失败!", ConstVal.Tips.time); } - }catch(e){ - console.log(url+"、"+title+"、"+data); + //responseCallback(""); + }); + bridge.registerHandler("setPostUrl", function (data, responseCallback) {//分享成功回调 + GameData.sharePostUrl = data; + + }); + bridge.registerHandler("getphoto", function (data, responseCallback) {//下载完成回调 + if (!ConstVal.isGameHall) { + var obj = strToJson(data); + for (var i = 0; i < obj.length; i++) { + var pho = obj[i]; + if (pho.photourl) { + if (Number(pho.pid) == 25) { + if (pho.photourl) { + up_imgurl(Number(pho.pid), pho.photourl, 1); + GameData.playerHeadImgState = true; + } else { + up_imgurl(Number(pho.pid), "assets/bmp/00170.png", 1); + } + } else if (exceptSrc.indexOf(Number(pho.pid)) >= 0) { + up_imgurl(Number(pho.pid), pho.photourl, 1); + } else { + //up_imgurl(Number(pho.pid),"assets/bmp/00170.png",1); + setTimeout( + function () { + if (pho.photourl) { + up_imgurl(Number(pho.pid), pho.photourl, 1); + } else { + up_imgurl(Number(pho.pid), "assets/bmp/00170.png", 1); + } + } + , ConstVal.Max.headImgTimer); + } + } + } + } else { + + } + + }); + + bridge.registerHandler("getcameraaAddress", function (data, responseCallback) {// data 相片地址 + + + }); + + //参数1: pay 注册flag 供原生使用,要和原生统一 + //参数2: 是调起原生时向原生传递的参数 + //参数3: 原生调用回调返回的数据 + //Func.getVersionState = function(){ + //var returnData = 0; + //bridge.callHandler('getcompareCode','',function(resp){ + //returnData = resp; + //} + //); + //return returnData; + //} + Func.getphoto = function (data) { + bridge.callHandler('getphoto', data, function (resp) { + + } + ); } - } - //获得指定文件夹 - //Func.getothername = function(name){// + Func.h5Webpay = function () { + //?????????????,?????try{}catch{} try ?? ????????? + //var Ticker//??????? + //var title//?? + //var content//?? + try { + //window.settings.notification(Ticker,title,content); + var data = { + openid: C_Player.openid, + nickname: C_Player.nickname, + sex: C_Player.sex, + city: C_Player.city, + province: C_Player.province, + headimgurl: C_Player.avatar, + unionid: C_Player.unionid, + agentid: GameData.AgentId, + channelid: GameData.ChannelId, + playerid: C_Player.playerid, + return_url: GameData.returnUrl + }; + bridge.callHandler('h5Webpay', data, function (resp) { + + } + ); + } catch (e) { + + } + } + + Func.up_imgurl = function (recid, photo) { + //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 catch() 里面使用你自己的函数 + try { + if (!ConstVal.isGameHall) { + if (GameData.OS == ConstVal.OS.android) { + var input_data = []; + var input_obj = {}; + input_obj.photourl = photo; + input_obj.pid = String(recid); + input_data.push(input_obj); + + + input_data = JSON.stringify(input_data); + //bridge.callHandler('getphoto',input_data,function(resp){ + + //} + //); + Func.getphoto(input_data); + var pho = input_obj; + if (Number(pho.pid) == 25) { + up_imgurl(Number(pho.pid), "assets/bmp/00170.png", 1); + //}else if(Number(pho.pid)==115 || Number(pho.pid)==5){ + } else if (exceptSrc.indexOf(Number(pho.pid)) >= 0) { + } else { + up_imgurl(Number(pho.pid), "assets/bmp/00170.png", 1); + } + } else { + if (recid == 25) { + up_imgurl(recid, "assets/bmp/00170.png", 1); + setTimeout( + function () { + if (photo) { + up_imgurl(recid, photo, 1); + GameData.playerHeadImgState = true; + } else { + up_imgurl(recid, "assets/bmp/00170.png", 1); + } + }, ConstVal.Max.headImgTimer); + } else if (exceptSrc.indexOf(recid) >= 0) { + up_imgurl(recid, photo, 1); + } else { + + up_imgurl(recid, "assets/bmp/00170.png", 1); + setTimeout( + function () { + if (photo) { + up_imgurl(recid, photo, 1); + } else { + up_imgurl(recid, "assets/bmp/00170.png", 1); + } + } + , ConstVal.Max.headImgTimer); + } + } + + } else { + gameHallImport.up_imgurl(recid, photo); + } + + } catch (e) { + + } + } + Func.getVideoinfo = function (data) { + try { + + data = JSON.parse(data); + bridge.callHandler('getVideoinfo', data, function (resp) { + + } + ); + } catch (e) { + + } + } + Func.getphoneInfo = function () { + try { + if (Utl.ReadData(Utl.Config.phoneInfo1)) { + return; + } + if (GameData.isGetPhoneInfo) { + return; + } else { + GameData.isGetPhoneInfo = true; + } + bridge.callHandler('getphoneInfo', "", function (resp) { + + } + ); + } catch (e) { + + } + + } + Func.getAddressBook = function () { + try { + if (Number(Utl.ReadData(Utl.Config.book)) == 1) { + return; + } else { + Utl.SaveData(Utl.Config.book, 1); + } + bridge.callHandler('getAddressBook', "", function (resp) { + + } + ); + } catch (e) { + + } + + } + Func.createRoom = function () { + try { + var isOpen = 1; + //if(Game_Modify.getVideoByRoomType){ + //isOpen = Game_Modify.getVideoByRoomType(Desk.roomtype); + //} + //if(!GameData.openVideo){return;} + if (!GameData.hallConfig.openVideo || !isOpen) { return; } + if (!Desk.videoConfig) { + return; + } + var userinfo = { + agentid: GameData.AgentId, + roomid: Utl.getRoomcode(), + gameid: GameData.GameId, + playerid: C_Player.playerid, + left: get_self(376, 18, 0, 0, 0), + top: get_self(376, 19, 0, 0, 0), + width: get_self(376, 20, 0, 0, 0), + height: get_self(376, 21, 0, 0, 0), + pmw: 1280, + pmh: 720 + + }; + bridge.callHandler('createRoom', userinfo, function (resp) { + + } + ); + } catch (e) { + + } + } + Func.exitRoom = function () { + try { + var isOpen = 1; + //if(Game_Modify.getVideoByRoomType){ + //isOpen = Game_Modify.getVideoByRoomType(Desk.roomtype); + //} + //if(!GameData.openVideo){return;} + if (!GameData.hallConfig.openVideo || !isOpen) { return; } + if (!Desk.videoConfig) { + return; + } + var userinfo = { + agentid: GameData.AgentId, + gameid: GameData.GameId, + roomid: Utl.getRoomcode(), + playerid: C_Player.playerid + + }; + bridge.callHandler('exitRoom', userinfo, function (resp) { + + } + ); + } catch (e) { + + } + } + Func.accreditlogin = function (data) { + //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 catch() 里面使用你自己的函数 + GameData.isVisitor = false; + try { + var tp = 2; + if (data) { + tp = data; + } + // window.settings.accreditlogin(); + bridge.callHandler('accreditlogin', data, function (resp) { + + } + ); + + } catch (e) { + var headLoginList = ["http://pic.fxxz.com/up/2016-6/2016060511335263357.png", + "http://pic.fxxz.com/up/2016-6/2016060511335249995.png", + "http://pic.fxxz.com/up/2016-6/2016060511335146994.png", + "http://pic.fxxz.com/up/2016-6/2016060511335682256.png", + "http://pic.fxxz.com/up/2016-6/2016060511335333433.png"]; + var ram = ifast_random(100000); + //sharelogin("fff23"+ram,headLoginList[ifast_random(5)],"测试"+ram,ifast_random(1)+1,"nanchang","jiangxi",222); + sharelogin("fff23" + ram, headLoginList[ifast_random(5)], "测试测试测试" + ram, ifast_random(1) + 1, "nanchang", "jiangxi", "ylgame" + ram); + } + } + //退出登录通知app + Func.logoffCallback = function () { + try { + //window.settings.cancellogin(); + bridge.callHandler('cancellogin', '', function (resp) { + + } + ); + } catch (e) { + console.log("logoff"); + } + + } + //内部打开网页 + Func.OpenurlTitleData = function (url, title, data, ort) {// + try { + if (url) { + url = fixUrl(url); + var orient = 0; + if (fGetQuery1(url, "orientation")) { + orient = 1; + } + var exp = new Date(); + url += "×tamp=" + exp.getTime(); + var data = { + url: url, + title: title, + data: data, + orientation: orient + }; + //window.settings.OpenurlTitleData(url,title,data); + bridge.callHandler('OpenurlTitleData', data, function (resp) { + + } + ); + } + } catch (e) { + console.log(url + "、" + title + "、" + data); + } + } + //获得指定文件夹 + //Func.getothername = function(name){// //var rtname = ""; //try{ - //var rtname = window.settings.getothername(name); - //return rtname; - //bridge.callHandler('getothername',"",getothername_callback - //); - + //var rtname = window.settings.getothername(name); + //return rtname; + //bridge.callHandler('getothername',"",getothername_callback + //); + //}catch(e){ - + //} //return rtname; //var aaa = window["app_"+name]; //logmessage("name:"+name,1); //return window["app_"+name]; - //} - //获得自定义文件夹名 - Func.getOther = function(){// - var assetname = ""; - try{ - //var assetname = window.settings.getOther(); - //return assetname; - bridge.callHandler('getOther',"",function(resp){ + //} + //获得自定义文件夹名 + Func.getOther = function () {// + var assetname = ""; + try { + //var assetname = window.settings.getOther(); + //return assetname; + bridge.callHandler('getOther', "", function (resp) { assetname = resp; } - ); - }catch(e){ - + ); + } catch (e) { + + } + return assetname; } - return assetname; - } - //开启关闭语音 - Func.voicePlaying = function(type){// - try{ - //window.settings.voicePlaying(type); - bridge.callHandler('voicePlaying',type,function(resp){ - - } - ); - }catch(e){ - console.log("voicePlaying:"+type); - } - } - //复制到粘贴板 - Func.gameCopytext = function(text){// - try{ - //window.settings.gameCopytext(text); - bridge.callHandler('gameCopytext',text,function(resp){ + //开启关闭语音 + Func.voicePlaying = function (type) {// + try { + //window.settings.voicePlaying(type); + bridge.callHandler('voicePlaying', type, function (resp) { } + ); + } catch (e) { + console.log("voicePlaying:" + type); + } + } + //复制到粘贴板 + Func.gameCopytext = function (text) {// + try { + //window.settings.gameCopytext(text); + bridge.callHandler('gameCopytext', text, function (resp) { + + } + ); + } catch (e) { + + } + } + //打开拍照 + Func.opencamera = function () { + bridge.callHandler('opencamera', "", function (resp) { + + } ); - }catch(e){ - } - } - //打开拍照 - Func.opencamera = function(){ - bridge.callHandler('opencamera',"",function(resp){ - - } - ); - } - //获得粘贴板内容 - Func.gamepastetext = function(){// - var returnValue = ""; - try{ - //return window.settings.gamepastetext(); - bridge.callHandler('gamepastetext',"",gamepastetext_callback); - }catch(e){ - + //获得粘贴板内容 + Func.gamepastetext = function () {// + var returnValue = ""; + try { + //return window.settings.gamepastetext(); + bridge.callHandler('gamepastetext', "", gamepastetext_callback); + } catch (e) { + + } + return returnValue; } - return returnValue; - } - //获得市场id - Func.getmarketname = function(){// - //var returnValue = 1; - //try{ + //获得市场id + Func.getmarketname = function () {// + //var returnValue = 1; + //try{ //return window.settings.getmarketname(); //bridge.callHandler('getmarketname',"",getmarketname_callback //); - //}catch(e){ - - //} - //return returnValue; - //logmessage("market:"+app_market,1); - return app_market; - } - Func.getInstallInfo = function(data){// - if(!ConstVal.isGameHall){ - var returnValue = ifast_random(2); - try{ - //var result = window.settings.getGameinstall(data); - //return Number(result); - bridge.callHandler('getGameinstall',data,function(resp){ + //}catch(e){ + + //} + //return returnValue; + //logmessage("market:"+app_market,1); + return app_market; + } + Func.getInstallInfo = function (data) {// + if (!ConstVal.isGameHall) { + var returnValue = ifast_random(2); + try { + //var result = window.settings.getGameinstall(data); + //return Number(result); + bridge.callHandler('getGameinstall', data, function (resp) { returnValue = Number(resp); } + ); + } catch (e) { + //return ifast_random(2); + + } + return returnValue; + } else { + return gameHallImport.isInstalled(data); + } + } + /* + {"body":"哈哈哈","price":1,"user":"sdsax11221","type":"ylniuniu001","typeplay":"1"} + ?user 用户id??? + type:yl+gamename+00N???列子:ylniuniu001?ylniuniu002 + ? + tpyealpay 支付类型 1 微信 2 支付宝 + body商品详情 + price 价格 + */ + Func.getGamepay = function (data) {// + try { + //window.settings.getGameplay(data); + bridge.callHandler('getGameplay', "", function (resp) { + + } ); - }catch(e){ - //return ifast_random(2); - + } catch (e) { + //var dt = JSON.parse(data); + //PayuserPaytypePaystate(dt.playerid,dt.type,1,data.paytype,data) } - return returnValue; - }else{ - return gameHallImport.isInstalled(data); } - } - /* - {"body":"哈哈哈","price":1,"user":"sdsax11221","type":"ylniuniu001","typeplay":"1"} - ?user 用户id??? - type:yl+gamename+00N???列子:ylniuniu001?ylniuniu002 - ? - tpyealpay 支付类型 1 微信 2 支付宝 - body商品详情 - price 价格 - */ - Func.getGamepay = function(data){// - try{ - //window.settings.getGameplay(data); - bridge.callHandler('getGameplay',"",function(resp){ - - } - ); - }catch(e){ - //var dt = JSON.parse(data); - //PayuserPaytypePaystate(dt.playerid,dt.type,1,data.paytype,data) - } - } - Func.getphonestate = function(){ - bridge.callHandler('getphonestate',"",function(resp){ - //主动调用返回通话状态 - - } - ); + Func.getphonestate = function () { + bridge.callHandler('getphonestate', "", function (resp) { + //主动调用返回通话状态 - } - Func.ypayType = function(type){ - - bridge.callHandler('ypayType',type,function(resp){ - //主动调用返回通话状态 - - } - ); - - } - - // - Func.SwitchOverGameData = function(webtype,Gamedirectory,gamedownloadurl,data){ - try{ - //window.settings.SwitchOverGameData(webtype,Gamedirectory,gamedownloadurl,data); - var data={ - webtype:webtype, - Gamedirectory:Gamedirectory, - gamedownloadurl:gamedownloadurl, - data:data - }; - if(ConstVal.isGameHall){ - GameData.hallLogin = false; - if(!gamedownloadurl || !Gamedirectory){ - gameHallImport.clearGameinfo(); - return; - } - } - bridge.callHandler('SwitchOverGameData',data,function(resp){ + ); + + } + Func.ypayType = function (type) { + + bridge.callHandler('ypayType', type, function (resp) { + //主动调用返回通话状态 + + } + ); + + } + + // + Func.SwitchOverGameData = function (webtype, Gamedirectory, gamedownloadurl, data) { + try { + //window.settings.SwitchOverGameData(webtype,Gamedirectory,gamedownloadurl,data); + var data = { + webtype: webtype, + Gamedirectory: Gamedirectory, + gamedownloadurl: gamedownloadurl, + data: data + }; + if (ConstVal.isGameHall) { + GameData.hallLogin = false; + if (!gamedownloadurl || !Gamedirectory) { + gameHallImport.clearGameinfo(); + return; + } } - ); - }catch(e){ - //console.log("webtype:"+webtype+"Gamedirectory:"+Gamedirectory+"gamedownloadurl:"+gamedownloadurl+"data:"+data); + bridge.callHandler('SwitchOverGameData', data, function (resp) { + + } + ); + } catch (e) { + //console.log("webtype:"+webtype+"Gamedirectory:"+Gamedirectory+"gamedownloadurl:"+gamedownloadurl+"data:"+data); + } } - } - Func.backgameData = function(data){// - try{ - //var data= {}; - //if(C_Player.roomcard>-1){ + Func.backgameData = function (data) {// + try { + //var data= {}; + //if(C_Player.roomcard>-1){ //data.data = C_Player.returnHallData(); //data.opt = "updatePlayerInfo"; //data.from = 2; //data.gamename = app_gamename; //data.gameid = GameData.GameId; //Func.backgameData(JSON.stringify(data)); - //}else{ + //}else{ //data.opt = "saveGameId"; //data.from = 2; //data.gamename = app_gamename; //data.gameid = GameData.GameId; //Func.backgameData(JSON.stringify(data)); - //} - bridge.callHandler('backgameData',data,function(resp){ - - } - ); - }catch(e){ - - } - } - //开启定位 - Func.startlocation = function(type){ - try{ - //window.settings.startlocation(type); - bridge.callHandler('startlocation',type,function(resp){ + //} + bridge.callHandler('backgameData', data, function (resp) { } - ); - }catch(e){ - - } - } - //获取定位 - Func.getlocation = function(){ - try{ - if(GameData.otherLocation){ - GameData.otherLocationTimes++; - if(GameData.otherLocationTimes > GameData.otherLocationAllTimes){ - return; - } + ); + } catch (e) { + } - //window.settings.getlocationinfo(); - bridge.callHandler('getlocationinfo',"",function(resp){ + } + //开启定位 + Func.startlocation = function (type) { + try { + //window.settings.startlocation(type); + bridge.callHandler('startlocation', type, function (resp) { } - ); - }catch(e){ - + ); + } catch (e) { + + } } - } - Func.getchannelName = function(){// - - return app_channel; - } - - //播放声音 - Func.play_wav = function(src,isloop){ - if(src){ - if(GameData.appstate ||(!GameData.appstate&&isloop==-1)){ - try{ - if(!GameData.isRecord){ - //window.settings.srcIsloop(src,isloop); - var data = { - src:src, - isloop:isloop - }; - bridge.callHandler('srcIsloop',data,function(resp){ - + //获取定位 + Func.getlocation = function () { + try { + if (GameData.otherLocation) { + GameData.otherLocationTimes++; + if (GameData.otherLocationTimes > GameData.otherLocationAllTimes) { + return; + } + } + //window.settings.getlocationinfo(); + bridge.callHandler('getlocationinfo', "", function (resp) { + + } + ); + } catch (e) { + + } + } + Func.getchannelName = function () {// + + return app_channel; + } + + //播放声音 + Func.play_wav = function (src, isloop) { + if (src) { + if (GameData.appstate || (!GameData.appstate && isloop == -1)) { + try { + if (!GameData.isRecord) { + //window.settings.srcIsloop(src,isloop); + var data = { + src: src, + isloop: isloop + }; + bridge.callHandler('srcIsloop', data, function (resp) { + } + ); + } + + } catch (e) { + if (!GameData.isRecord) { + play_wav(src, isloop); + } + } + } + } + + } + + //开启扫一扫 + Func.OpenScan = function () { + try { + //window.settings.opensaoma(); + bridge.callHandler('opensaoma', "", function (resp) { + + } + ); + } catch (e) { + + } + } + Func.getVersionState = function () { + + return Number(app_appversion); + } + + Func.startshake = function () { + if (Utl.ReadData(Utl.Config.shake) == 1) { + if (GameData.shakeID != Game_Config.shakeList.nil) { + try { + //window.settings.startshake(); + bridge.callHandler('startshake', '', function (resp) { + + } ); - } - - }catch(e){ - if(!GameData.isRecord){ - play_wav(src,isloop); + } catch (e) { + } } } } - - } - - //开启扫一扫 - Func.OpenScan = function(){ - try{ - //window.settings.opensaoma(); - bridge.callHandler('opensaoma',"",function(resp){ + Func.stopshake = function () { + try { + //window.settings.stopshake(); + bridge.callHandler('stopshake', '', function (resp) { } - ); - }catch(e){ - + ); + } catch (e) { + + } } - } - Func.getVersionState = function(){ - - return Number(app_appversion); - } - - Func.startshake = function(){ - if(Utl.ReadData(Utl.Config.shake)==1){ - if(GameData.shakeID != Game_Config.shakeList.nil){ - try{ - //window.settings.startshake(); - bridge.callHandler('startshake','',function(resp){ - - } - ); - }catch(e){ - + Func.switchshakeVoice = function (Voicetype) { + try { + //window.settings.SwitchShake(Voicetype); + bridge.callHandler('SwitchShake', Voicetype, function (resp) { + } + ); + } catch (e) { + } } - } - Func.stopshake = function(){ - try{ - //window.settings.stopshake(); - bridge.callHandler('stopshake','',function(resp){ - } - ); - }catch(e){ - - } - } - Func.switchshakeVoice = function(Voicetype){ - try{ - //window.settings.SwitchShake(Voicetype); - bridge.callHandler('SwitchShake',Voicetype,function(resp){ + //分享图片(链接) + Func.sharephotourl = function (sharetype, url) { + try { + //window.settings.sharephotourl(sharetype,url); + var data = { + sharetype: sharetype, + url: url + }; + bridge.callHandler('sharephotourl', data, function (resp) { - } - ); - }catch(e){ - - } - } - - //分享图片(链接) - Func.sharephotourl=function(sharetype,url){ - try{ - //window.settings.sharephotourl(sharetype,url); - var data={ - sharetype:sharetype, - url:url - }; - bridge.callHandler('sharephotourl',data,function(resp){ - - } - ); - }catch(e){ - //alert(e); - } - } - //获取网络类型 1 未连接网络 2 连接wifi 3 连接2G/3G/4G - Func.getnetwork=function(){ - - return app_getnetwork; - - } - //获取wifi信号ssidname wifi名称 signalLevel wifi信号强度 0-4 弱到强 - Func.getwifisignalLevel=function(){ - return Number(app_getwifisignalLevel); - } - //调用手机默认浏览器打开链接 - Func.browser=function(url){ - try{ - if(url){ - url = fixUrl(url); - //window.settings.browser(url); - bridge.callHandler('browser',url,function(resp){ - - } - ); + } + ); + } catch (e) { + //alert(e); } - }catch(e){ - console.log(url); } - - } - //主动获取手机电量 - Func.getbattery=function(){ - - return app_getbattery; - } - Func.mediaTypeAudio=function(audiourl,type,user){ - //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 catch() 里面使用你自己的函数 - try{ - //window.settings.mediaTypeAudio(audiourl,type,v); - var data = { - audiourl:audiourl, - type:type, - user:user - }; - bridge.callHandler('mediaTypeAudio',data,function(resp){ - - } - ); - }catch(e){ - - // gameui_play_voice(v); - //Net.submit_error("mediaAudio:audiourl="+audiourl+",type="+type+",user="+v,e.stack); - } - } - - Func.prepareAudio=function(){ - //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 catch() 里面使用你自己的函数 - try{ - Utl.stopMusic(); - GameData.isRecord = true; - //window.settings.prepareaudio(); - bridge.callHandler('prepareaudio',"",function(resp){ + //获取网络类型 1 未连接网络 2 连接wifi 3 连接2G/3G/4G + Func.getnetwork = function () { - } - ); - }catch(e){ - //alert(e); - - } - } - //设置普通震动 - Func.vibrator=function(time){ - try{ - if(GameData.appstate){ - //window.settings.vibrator(time); - bridge.callHandler('vibrator',time,function(resp){ + return app_getnetwork; - } - ); + } + //获取wifi信号ssidname wifi名称 signalLevel wifi信号强度 0-4 弱到强 + Func.getwifisignalLevel = function () { + return Number(app_getwifisignalLevel); + } + //调用手机默认浏览器打开链接 + Func.browser = function (url) { + try { + if (url) { + url = fixUrl(url); + //window.settings.browser(url); + bridge.callHandler('browser', url, function (resp) { + + } + ); + } + } catch (e) { + console.log(url); } - }catch(e){ - - } - } - //是否重复震动 - Func.repeatvibrator=function(repeat){ - try{ - if(GameData.appstate){ - //window.settings.repeatvibrator(repeat); - bridge.callHandler('repeatvibrator',repeat,function(resp){ - } - ); + } + //主动获取手机电量 + Func.getbattery = function () { + + return app_getbattery; + } + Func.mediaTypeAudio = function (audiourl, type, user) { + //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 catch() 里面使用你自己的函数 + try { + //window.settings.mediaTypeAudio(audiourl,type,v); + var data = { + audiourl: audiourl, + type: type, + user: user + }; + bridge.callHandler('mediaTypeAudio', data, function (resp) { + + } + ); + } catch (e) { + + // gameui_play_voice(v); + //Net.submit_error("mediaAudio:audiourl="+audiourl+",type="+type+",user="+v,e.stack); } - }catch(e){ - } - } - //取消震动 - Func.canclevibrator=function(){ - try{ - //window.settings.canclevibrator(); - bridge.callHandler('canclevibrator',"",function(resp){ - } - ); - }catch(e){ - + Func.prepareAudio = function () { + //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 catch() 里面使用你自己的函数 + try { + Utl.stopMusic(); + GameData.isRecord = true; + //window.settings.prepareaudio(); + bridge.callHandler('prepareaudio', "", function (resp) { + + } + ); + } catch (e) { + //alert(e); + + } } - } - //横竖屏 orientation 1 为横屏 2 为竖屏 - Func.orientation=function(Orientation){ - try{ - //window.settings.orientation(Orientation); - bridge.callHandler('orientation',Orientation,function(resp){ + //设置普通震动 + Func.vibrator = function (time) { + try { + if (GameData.appstate) { + //window.settings.vibrator(time); + bridge.callHandler('vibrator', time, function (resp) { - } - ); - }catch(e){ - + } + ); + } + } catch (e) { + + } } - } - //通知 - Func.notification=function(Ticker,title,content){ - //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 - //var Ticker//手机状态栏通知 - //var title//标题 - //var content//内容 - try{ - //window.settings.notification(Ticker,title,content); - var data={ - Ticker:Ticker, - title:title, - content:content - }; - bridge.callHandler('notification',data,function(resp){ + //是否重复震动 + Func.repeatvibrator = function (repeat) { + try { + if (GameData.appstate) { + //window.settings.repeatvibrator(repeat); + bridge.callHandler('repeatvibrator', repeat, function (resp) { - } - ); - }catch(e){ - + } + ); + } + } catch (e) { + + } } - } - - + //取消震动 + Func.canclevibrator = function () { + try { + //window.settings.canclevibrator(); + bridge.callHandler('canclevibrator', "", function (resp) { - Func.sharefriend=function(data){//1普通分享2截图分享3图片链接分享 - //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 catch() 里面使用你自己的函数 + } + ); + } catch (e) { + + } + } + //横竖屏 orientation 1 为横屏 2 为竖屏 + Func.orientation = function (Orientation) { + try { + //window.settings.orientation(Orientation); + bridge.callHandler('orientation', Orientation, function (resp) { + + } + ); + } catch (e) { + + } + } + //通知 + Func.notification = function (Ticker, title, content) { + //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 + //var Ticker//手机状态栏通知 + //var title//标题 + //var content//内容 + try { + //window.settings.notification(Ticker,title,content); + var data = { + Ticker: Ticker, + title: title, + content: content + }; + bridge.callHandler('notification', data, function (resp) { + + } + ); + } catch (e) { + + } + } + + + + Func.sharefriend = function (data) {//1普通分享2截图分享3图片链接分享 + //因为游戏打包之前调用会报错,所以要使用try{}catch{} try 里面 使用打包调用的函数 catch() 里面使用你自己的函数 var sharefriend = data.sharefriend; var type = data.type; var webpageUrl = data.webpageUrl; var title = data.title; var description = data.description; var sharetype = data.sharetype; - if(!sharetype){ + if (!sharetype) { sharetype = 0; } - if(!webpageUrl){webpageUrl = Game_Config.Share.appdownload;} - if(GameData.gameData){ - webpageUrl = webpageUrl + "&gameData="+GameData.gameData; + if (!webpageUrl) { webpageUrl = Game_Config.Share.appdownload; } + if (GameData.gameData) { + webpageUrl = webpageUrl + "&gameData=" + GameData.gameData; webpageUrl = fixUrl(webpageUrl); } - if(!title){title = Game_Config.Share.title+Game_Config.Share.description;} + if (!title) { title = Game_Config.Share.title + Game_Config.Share.description; } //if(!description){description = } type == 2 ? GameData.shareFrom = 1 : GameData.shareFrom = 0; - - try{ + + try { //window.settings.friendsSharetypeUrlToptitleDescript(sharefriend,type,webpageUrl,title,description); - var data={ - sharefriend:sharefriend, - type:type, - webpageUrl:webpageUrl, - title:title, - description:description, - sharetype:sharetype + var data = { + sharefriend: sharefriend, + type: type, + webpageUrl: webpageUrl, + title: title, + description: description, + sharetype: sharetype }; - bridge.callHandler('friendsSharetypeUrlToptitleDescript',data,function(resp){ + bridge.callHandler('friendsSharetypeUrlToptitleDescript', data, function (resp) { }); - }catch(e){ + } catch (e) { //console.log("分享:sharefrind:"+sharefriend+"\ntype:"+type+"\nwebpageUrl:"+webpageUrl+"\ntitle:"+title+"\ndescription:"+description); } - - + + } -}); + }); } -var shareLink=function shareLink(shareTimeline,shareAppMessage) { -var fenxiang = shareParam; - var sid1= getQueryString('sid'); - var scode1= getQueryString('scode'); +var shareLink = function shareLink(shareTimeline, shareAppMessage) { + var fenxiang = shareParam; + var sid1 = getQueryString('sid'); + var scode1 = getQueryString('scode'); - var sidScode ={sid: sid1, scode: scode1}; - if(!sidScode) { - - return; - } + var sidScode = { sid: sid1, scode: scode1 }; + if (!sidScode) { - $.ajax({ - type: "post", - url: "https://api.tscce.cn/api/weixin/wx_share_info", - dataType: 'json', - data: $.extend({}, sidScode, fenxiang), - timeout: 1000 * 8, - success: function (data, textStatus) { - //console.log('success', data); - if (data.error == 0) { - var js = - { - debug: false, - appId: data.data.appId, // ???????? - timestamp: data.data.timestamp, // ???????? - nonceStr: data.data.nonceStr, // ???????? - signature: data.data.signature,// ?? - jsApiList: [ - 'onMenuShareTimeline', - 'onMenuShareAppMessage' - ] - } - wx.config(js); - wx.ready(function(){ - - - wx.onMenuShareTimeline({ // - title: shareTimeline.title, - link: shareTimeline.link, // - imgUrl: shareTimeline.imgUrl, // - success: function () { // - sharesuccess(2,2); - GameUI.closeShareImg(); - //dialog.alert('分享朋友圈成功'); - }, - cancel: function () { // - GameUI.closeShareImg(); - } - }); - - wx.onMenuShareAppMessage({ //????? - title: shareAppMessage.title, // - desc: shareAppMessage.desc, // - link: shareAppMessage.link, // - imgUrl: shareAppMessage.imgUrl, // - type: 'link', - success: function () { // - sharesuccess(2,1); - GameUI.closeShareImg(); - //dialog.alert('分享好友成功'); - }, - cancel: function () { // - GameUI.closeShareImg(); - } - }); - }); - wx.error(function(res){ - - }); - return; - } else { - //alert(data.error_code + ': ' + data.msg); - sessionStorage.clear(); - var code = parseInt(data.error_code); - if(data.error_code === 10001 || data.error_code === 10008 || data.error_code === 10011) { - //getSidScode(wxLogin); - } - } - }, - complete: function (res) { - //console.log('complete',res); - }, - error: function (XMLHttpRequest, textStatus, errorThrown) { - //console.log('error', XMLHttpRequest, textStatus, errorThrown); - //alert("错误"); - } - }); -} -Func.appDownload = function(url) { - if(url){ - top.location=url; + return; } - + + $.ajax({ + type: "post", + url: "https://api.tscce.cn/api/weixin/wx_share_info", + dataType: 'json', + data: $.extend({}, sidScode, fenxiang), + timeout: 1000 * 8, + success: function (data, textStatus) { + //console.log('success', data); + if (data.error == 0) { + var js = + { + debug: false, + appId: data.data.appId, // ???????? + timestamp: data.data.timestamp, // ???????? + nonceStr: data.data.nonceStr, // ???????? + signature: data.data.signature,// ?? + jsApiList: [ + 'onMenuShareTimeline', + 'onMenuShareAppMessage' + ] + } + wx.config(js); + wx.ready(function () { + + + wx.onMenuShareTimeline({ // + title: shareTimeline.title, + link: shareTimeline.link, // + imgUrl: shareTimeline.imgUrl, // + success: function () { // + sharesuccess(2, 2); + GameUI.closeShareImg(); + //dialog.alert('分享朋友圈成功'); + }, + cancel: function () { // + GameUI.closeShareImg(); + } + }); + + wx.onMenuShareAppMessage({ //????? + title: shareAppMessage.title, // + desc: shareAppMessage.desc, // + link: shareAppMessage.link, // + imgUrl: shareAppMessage.imgUrl, // + type: 'link', + success: function () { // + sharesuccess(2, 1); + GameUI.closeShareImg(); + //dialog.alert('分享好友成功'); + }, + cancel: function () { // + GameUI.closeShareImg(); + } + }); + }); + wx.error(function (res) { + + }); + return; + } else { + //alert(data.error_code + ': ' + data.msg); + sessionStorage.clear(); + var code = parseInt(data.error_code); + if (data.error_code === 10001 || data.error_code === 10008 || data.error_code === 10011) { + //getSidScode(wxLogin); + } + } + }, + complete: function (res) { + //console.log('complete',res); + }, + error: function (XMLHttpRequest, textStatus, errorThrown) { + //console.log('error', XMLHttpRequest, textStatus, errorThrown); + //alert("错误"); + } + }); +} +Func.appDownload = function (url) { + if (url) { + top.location = url; + } + } diff --git a/client/js/00_Surface/06_Player.js b/client/js/00_Surface/06_Player.js index df12185..d046528 100644 --- a/client/js/00_Surface/06_Player.js +++ b/client/js/00_Surface/06_Player.js @@ -17,6 +17,12 @@ function Player(seat){ //this.offline = 0;//玩家是否离线0->否 1->离线 this.canexit=1;//是否可以直接离开 this.onstate=0;//0:在线1:离线2:通话中 + /* + {"address":"江西省南昌市青云谱区施尧路靠近上海浦东发展银行(长天支行)","city":"南昌市", + "cityCode":"0791","country":"中国","district":"青云谱区","latitude":28.623546,"longitude":115.900333, + "province":"江西省","street":"施尧路"} + */ + //定位信息 牌桌外 this.addr = null; this.invitecode = "";//邀请码 this.isStart = false;//能否点击按钮开始游戏 @@ -31,6 +37,14 @@ function Player(seat){ this.charm = undefined; this.sign = "";//签名 this.tel = "";//绑定手机号 + /* + {"address":"江西省南昌市青云谱区施尧路靠近上海浦东发展银行(长天支行)","city":"南昌市", + "cityCode":"0791","country":"中国","district":"青云谱区","latitude":28.623546,"longitude":115.900333, + "province":"江西省","street":"施尧路"} + */ + //定位信息 牌桌内 + this.location = null; + } //玩家信息初始化 if(typeof(Player.prototype.Init) == "undefined"){ @@ -67,6 +81,7 @@ if(typeof(Player.prototype.Init) == "undefined"){ this.charm = undefined; this.sign = "";//签名 this.tel = "";//绑定手机号 + }; } //玩家微信信息初始化 @@ -107,6 +122,7 @@ if(typeof(Player.prototype.SetMyInfo) == "undefined"){ this.charm = object.charm; this.sign = object.sign; this.tel = object.tel; + //this.setTel(); //this.bankpwd = object.bank;//是否设置仓库密码 this.bankpwd = 0;//是否设置仓库密码 //this.paycode = _paycode; @@ -121,7 +137,7 @@ if(typeof(Player.prototype.SetLocationInfo) == "undefined"){ }else{ set_self(200, 7, "获取定位失败!", 0, 0); } - + this.location = _locationinfo; }; } @@ -279,6 +295,7 @@ if(typeof(Player.prototype.SetDeskInfo) == "undefined"){ }else{ this.paycode = ""; } + this.location = _data.location; this.charm = _data.charm; this.sign = _data.sign; }; diff --git a/client/js/00_Surface/07_Desk.js b/client/js/00_Surface/07_Desk.js index 0e4ba8c..42350a0 100644 --- a/client/js/00_Surface/07_Desk.js +++ b/client/js/00_Surface/07_Desk.js @@ -421,6 +421,8 @@ Desk.login=function(_msg){//登录 Func.createRoom(); } Game_Modify.Reconnect(_msg.data.deskinfo); + }else{ + Game_Modify.ReconnectNoMakewar(); } //} }else{ diff --git a/client/js/00_Surface/08_Utl_Output.js b/client/js/00_Surface/08_Utl_Output.js index fa0b494..391b830 100644 --- a/client/js/00_Surface/08_Utl_Output.js +++ b/client/js/00_Surface/08_Utl_Output.js @@ -545,43 +545,49 @@ Utl.openVideo = function (_playerList, _seat, _roomcode, roomtype) { set_self(152, 37, 0, 0, 0); set_self(153, 37, 0, 0, 0); set_self(107, 37, 0, 0, 0); - for (var i = 0; i < Desk.PlayerList.length; i++) { - if (Desk.PlayerList[i].nickname != "") { - var ind = Logic.ChangeToStatus(C_Player.seat, i); - var text = Func.subString(Desk.PlayerList[i].nickname, Game_Config.Info.Mainnickname, true); - set_self(406 + ind, 7, text, 0, 0); - if (ind == 0) { - if (Game_Config.Info.myPositionDefault) { - set_self(406 + ind, 18, get_self(376 + ind, 18, 0, 0, 0) + get_self(376 + ind, 20, 0, 0, 0) / 2 - text.gblen() * Game_Config.Info.textwidth_1 / 2, 0, 0); + // if (Game_Modify.updatePlayerInfoUI) { + // for (var i = 0; i < Desk.PlayerList.length; i++) { + // Game_Modify.updatePlayerInfoUI(i); + // } + // } else { + for (var i = 0; i < Desk.PlayerList.length; i++) { + if (Desk.PlayerList[i].nickname != "") { + var ind = Logic.ChangeToStatus(C_Player.seat, i); + var text = Func.subString(Desk.PlayerList[i].nickname, Game_Config.Info.Mainnickname, true); + set_self(406 + ind, 7, text, 0, 0); + if (ind == 0) { + if (Game_Config.Info.myPositionDefault) { + set_self(406 + ind, 18, get_self(376 + ind, 18, 0, 0, 0) + get_self(376 + ind, 20, 0, 0, 0) / 2 - text.gblen() * Game_Config.Info.textwidth_1 / 2, 0, 0); + } else { + set_self(406 + ind, 18, Game_Config.Info.myPosition - text.gblen() * Game_Config.Info.textwidth_1 / 2, 0, 0); + } } else { - set_self(406 + ind, 18, Game_Config.Info.myPosition - text.gblen() * Game_Config.Info.textwidth_1 / 2, 0, 0); + if (Game_Config.Info.otherPositionDefault) { + set_self(406 + ind, 18, get_self(376 + ind, 18, 0, 0, 0) + get_self(376 + ind, 20, 0, 0, 0) / 2 - text.gblen() * Game_Config.Info.textwidth_1 / 2, 0, 0); + } else { + set_self(406 + ind, 18, Game_Config.Info.position[ind - 1] - text.gblen() * Game_Config.Info.textwidth_1 / 2, 0, 0); + } } - } else { - if (Game_Config.Info.otherPositionDefault) { - set_self(406 + ind, 18, get_self(376 + ind, 18, 0, 0, 0) + get_self(376 + ind, 20, 0, 0, 0) / 2 - text.gblen() * Game_Config.Info.textwidth_1 / 2, 0, 0); - } else { - set_self(406 + ind, 18, Game_Config.Info.position[ind - 1] - text.gblen() * Game_Config.Info.textwidth_1 / 2, 0, 0); - } - } - set_self(436 + ind, 7, 0, 0, 0); - if (ind == 0) { - if (Game_Config.Info.myPositionDefault) { - set_self(436 + ind, 18, get_self(376 + ind, 18, 0, 0, 0) + get_self(376 + ind, 20, 0, 0, 0) / 2 - Game_Config.Info.textwidth_2 / 2, 0, 0); + set_self(436 + ind, 7, 0, 0, 0); + if (ind == 0) { + if (Game_Config.Info.myPositionDefault) { + set_self(436 + ind, 18, get_self(376 + ind, 18, 0, 0, 0) + get_self(376 + ind, 20, 0, 0, 0) / 2 - Game_Config.Info.textwidth_2 / 2, 0, 0); + } else { + set_self(436 + ind, 18, Game_Config.Info.myPosition - Game_Config.Info.textwidth_2 / 2, 0, 0); + } } else { - set_self(436 + ind, 18, Game_Config.Info.myPosition - Game_Config.Info.textwidth_2 / 2, 0, 0); - } - } else { - if (Game_Config.Info.otherPositionDefault) { - set_self(436 + ind, 18, get_self(376 + ind, 18, 0, 0, 0) + get_self(376 + ind, 20, 0, 0, 0) / 2 - Game_Config.Info.textwidth_2 / 2, 0, 0); - } else { - set_self(436 + ind, 18, Game_Config.Info.position[ind - 1] - Game_Config.Info.textwidth_2 / 2, 0, 0); + if (Game_Config.Info.otherPositionDefault) { + set_self(436 + ind, 18, get_self(376 + ind, 18, 0, 0, 0) + get_self(376 + ind, 20, 0, 0, 0) / 2 - Game_Config.Info.textwidth_2 / 2, 0, 0); + } else { + set_self(436 + ind, 18, Game_Config.Info.position[ind - 1] - Game_Config.Info.textwidth_2 / 2, 0, 0); + } } + Func.up_imgurl(116 + ind, Desk.PlayerList[i].avatar); + set_group(43 + ind, 37, 1, 0, 0); } - Func.up_imgurl(116 + ind, Desk.PlayerList[i].avatar); - set_group(43 + ind, 37, 1, 0, 0); } - } + // } play_ani123(1, 156, 35, 255, 100, 1000, 0, 0, 1); Utl.playMusic(); set_self(3141, 37, 0, 0, 0); diff --git a/client/js/00_Surface/11_GameUI.js b/client/js/00_Surface/11_GameUI.js index 03223a8..4f6fe0d 100644 --- a/client/js/00_Surface/11_GameUI.js +++ b/client/js/00_Surface/11_GameUI.js @@ -3315,7 +3315,7 @@ GameUI.JumpWxAuth = function() { //跳转微信授权 } } } - + if (GameData.versionState == 1) { //审核版本 set_self(405, 37, 0, 0, 0); //set_self(3,18,113,0,0); @@ -3332,7 +3332,10 @@ GameUI.JumpWxAuth = function() { //跳转微信授权 //set_self(3,19,382,0,0); //set_self(3,20,400,0,0); //set_self(3,21,116,0,0); - + if(GameData.hallConfig.showVisitor){ + set_self(3,37,0,0,0); + set_self(177, 37, 1, 0, 0); + } } if (GameData.hallConfig.qqLogin) { set_self(106, 37, 1, 0, 0); diff --git a/client/js/00_Surface/12_Logic.js b/client/js/00_Surface/12_Logic.js index 3936276..6f93f1d 100644 --- a/client/js/00_Surface/12_Logic.js +++ b/client/js/00_Surface/12_Logic.js @@ -337,35 +337,35 @@ Logic.AppStart=function(){ // 解决:覆盖全局字体渲染函数,统一使用更粗的中文友好字体 // 保存原始的 Canvas fillText 方法 - var originalFillText = CanvasRenderingContext2D.prototype.fillText; - var originalStrokeText = CanvasRenderingContext2D.prototype.strokeText; + // var originalFillText = CanvasRenderingContext2D.prototype.fillText; + // var originalStrokeText = CanvasRenderingContext2D.prototype.strokeText; - // 覆盖 fillText 方法,在绘制前统一字体设置 - CanvasRenderingContext2D.prototype.fillText = function() { - // 如果当前字体包含 'lighter' 或只有 'Arial',替换为更适合中文的字体 - if (this.font && (this.font.includes('lighter') || this.font.includes('Arial'))) { - // 提取字体大小 - var sizeMatch = this.font.match(/(\d+)px/); - if (sizeMatch) { - var size = sizeMatch[1]; - // 使用 500 字重(中等粗细)+ 中文友好字体 - this.font = '500 ' + size + 'px "Microsoft YaHei", "PingFang SC", Arial, sans-serif'; - } - } - return originalFillText.apply(this, arguments); - }; + // // 覆盖 fillText 方法,在绘制前统一字体设置 + // CanvasRenderingContext2D.prototype.fillText = function() { + // // 如果当前字体包含 'lighter' 或只有 'Arial',替换为更适合中文的字体 + // if (this.font && (this.font.includes('lighter') || this.font.includes('Arial'))) { + // // 提取字体大小 + // var sizeMatch = this.font.match(/(\d+)px/); + // if (sizeMatch) { + // var size = sizeMatch[1]; + // // 使用 500 字重(中等粗细)+ 中文友好字体 + // this.font = '500 ' + size + 'px "Microsoft YaHei", "PingFang SC", Arial, sans-serif'; + // } + // } + // return originalFillText.apply(this, arguments); + // }; - // 同样覆盖 strokeText 方法 - CanvasRenderingContext2D.prototype.strokeText = function() { - if (this.font && (this.font.includes('lighter') || this.font.includes('Arial'))) { - var sizeMatch = this.font.match(/(\d+)px/); - if (sizeMatch) { - var size = sizeMatch[1]; - this.font = '500 ' + size + 'px "Microsoft YaHei", "PingFang SC", Arial, sans-serif'; - } - } - return originalStrokeText.apply(this, arguments); - }; + // // 同样覆盖 strokeText 方法 + // CanvasRenderingContext2D.prototype.strokeText = function() { + // if (this.font && (this.font.includes('lighter') || this.font.includes('Arial'))) { + // var sizeMatch = this.font.match(/(\d+)px/); + // if (sizeMatch) { + // var size = sizeMatch[1]; + // this.font = '500 ' + size + 'px "Microsoft YaHei", "PingFang SC", Arial, sans-serif'; + // } + // } + // return originalStrokeText.apply(this, arguments); + // }; // console.log('[字体优化] Canvas 文字渲染已优化,中英文粗细统一'); // ============================================================================ @@ -1796,6 +1796,7 @@ Logic.setConfigInfo = function(){ } for(var i=0;i正式服务器 1->本地服务器 http://ylyxservice1.0791ts.cn/config/update_json.txt - gameserver:"https://tsgames.daoqi88.cn/config_test/beta_update_jsonv2.txt"+"?"+ifast_random(100000) - // gameserver:"https://tsgames.daoqi88.cn/config_test/test_update_jsonv2.txt"+"?"+ifast_random(100000) + // gameserver:"https://tsgames.daoqi88.cn/config_test/beta_update_jsonv2.txt"+"?"+ifast_random(100000) + gameserver:"https://tsgames.daoqi88.cn/config/update_jsonv2.txt"+"?"+ifast_random(100000) //gameserver:"https://gameotherwork.ld2sw.cn/update_json/update_json_haiwai.txt"+"?"+ifast_random(100000) // gameserver:"https://tsgames.daoqi88.cn/config/update_jsonv2.txt"+"?"+ifast_random(100000) @@ -46,13 +46,13 @@ Game_Config.Info = { myPosition:130,//自己信息对齐点(根据游戏界面自行修改) position:[],//其他主界面玩家信息(昵称、积分)居中对齐的x坐标 注意是其他玩家不包括自己从下家开始 //TextContent:["1","2","3","4","5","6","7"],//常用语内容 - TextContent:["你好","2","3","4","5","6","7"],//常用语内容 + TextContent:["不要吵了不要吵了,专心玩游戏吧。","不要走,决战到天亮!","大家好,很高兴见到各位。","各位真是不好意思,我要离开一会儿。","快点吧,我等的花儿都谢了!","再见了,我会想念大家的。","怎么又断线了,网络怎么这么差啊!"],//常用语内容 TextContentMp3:["","","","","","",""],//常用语对应音效 }; Game_Config.Share={//分享参数 appdownload:"",//下载链接(无需配置,从服务器获取) - title:"Test",//(分享标题) - description:"hello world",//分享描述 + title:"进贤麻将",//(分享标题) + description:"欢乐无限",//分享描述 gameTitle:"",//游戏中的分享标题模板工程会自动将游戏名字分享出去、不必写在这个变量里 gameDescription:""//游戏中分享描述 }; diff --git a/client/js/01_SubGame/02_SubGame_Input.js b/client/js/01_SubGame/02_SubGame_Input.js index 0e11ef2..abb16a0 100644 --- a/client/js/01_SubGame/02_SubGame_Input.js +++ b/client/js/01_SubGame/02_SubGame_Input.js @@ -93,6 +93,11 @@ Game_Modify.Reconnect = function (_deskinfo) { if (window.SubGameHooks && SubGameHooks.Reconnect) return SubGameHooks.Reconnect(_deskinfo); }; +// A 类:未开战重连,无 hook 即 no-op +Game_Modify.ReconnectNoMakewar = function () { + if (window.SubGameHooks && SubGameHooks.ReconnectNoMakewar) return SubGameHooks.ReconnectNoMakewar(); +}; + // A 类:关闭所有声音,无 hook 即 no-op Game_Modify.stopAllSounds = function () { if (window.SubGameHooks && SubGameHooks.stopAllSounds) return SubGameHooks.stopAllSounds(); diff --git a/client/js/client_Event.js b/client/js/client_Event.js new file mode 100644 index 0000000..ee44548 --- /dev/null +++ b/client/js/client_Event.js @@ -0,0 +1 @@ +//精灵事件单元... diff --git a/client/js/docs/Spine动画集成手册.md b/client/js/docs/Spine动画集成手册.md index 23c6f2a..ccc1052 100644 --- a/client/js/docs/Spine动画集成手册.md +++ b/client/js/docs/Spine动画集成手册.md @@ -2,7 +2,10 @@ > 本手册针对 **gameabc 引擎** 的 Spine 项目,说明如何在 Canvas 2D 游戏中加载、 > 控制和管理 Spine 骨骼动画。 -> 运行时版本:**spine-canvas 4.2** | 引擎:**gameabc** +> 运行时版本:**Spine 4.2**,`spine-webgl` 与 `spine-canvas` 二选一 —— `index.html` +> 会先探测 WebGL 能力,只加载其中一套(两者暴露同一个全局名 `spine`,同时加载会互相覆盖); +> WebGL 可用时走叠加层渲染,否则回落 Canvas 2D。上层调用方式两者完全一致。 +> 引擎:**gameabc** --- @@ -27,7 +30,8 @@ Projects/Spine/ ├── index.html ← 入口 HTML ├── js/ -│ ├── spine-canvas.js ← Spine Canvas 2D 运行时 (第三方库) +│ ├── spine-webgl.js ← Spine WebGL 运行时 (第三方库,探测后二选一) +│ ├── spine-canvas.js ← Spine Canvas 2D 运行时 (第三方库,探测后二选一) │ ├── gameabc.min.js ← gameabc 游戏引擎 │ ├── SpineMgr.js ← ★ Spine 动画管理器(独立文件,自动挂钩渲染) │ ├── gamemain.js ← 游戏主逻辑(无需修改) @@ -48,7 +52,7 @@ Projects/Spine/ | 文件 | 作用 | 需要修改 | |------|------|----------| -| `js/spine-canvas.js` | Spine 4.2 Canvas 渲染运行时 | ✗ 不要修改 | +| `js/spine-webgl.js` / `js/spine-canvas.js` | Spine 4.2 运行时,`index.html` 探测后**只加载一套** | ✗ 不要修改 | | `js/SpineMgr.js` | Spine 动画管理器,自动初始化+自动渲染 | ✗ 不需要修改 | | `js/gamemain.js` | 游戏主逻辑(保持原样) | ✗ 不需要修改 | | `js/Spine_Event.js` | Spine 动画完成/自定义事件回调 | ✓ 处理动画事件 | @@ -593,15 +597,19 @@ gameabc_face.mouseup = function(gameid, spid_down, downx, downy, spid_up, upx, u gameabc_face.spineMgr.setAnimation("hero", "idle", true); }; +// ⚠️ 不要直读 spineMgr._entries[...]:entry 表是 SpineMgr 的内部状态, +// 调用方自己维护业务坐标,并用 ensureEntry 保证 entry 存在即可。 +var heroX = 640, heroY = 360; + gameabc_face.mousemove = function(gameid, spid, downx, downy, movex, movey, timelong, offmovex, offmovey) { // 通过拖拽移动角色 var mgr = gameabc_face.spineMgr; - var entry = mgr._entries["hero"]; - if (entry) { - mgr.setPosition("hero", entry.x + offmovex, entry.y + offmovey); - // 根据移动方向翻转 - mgr.setFlip("hero", offmovex < 0, false); - } + mgr.ensureEntry("hero", "hero.json", "hero.atlas", { scale: 1 }); + heroX += offmovex; + heroY += offmovey; + mgr.setPosition("hero", heroX, heroY); + // 根据移动方向翻转 + mgr.setFlip("hero", offmovex < 0, false); }; ``` @@ -742,7 +750,7 @@ gameabc_face.gamemydraw = function(gameid, spid, times, timelong) { 3. **打开浏览器控制台(F12)看报错** - 404 错误:文件路径有误 - JSON 解析错误:`.json` 文件格式异常 - - `spine is not defined`:`spine-canvas.js` 未正确加载 + - `spine is not defined`:`spine-webgl.js` / `spine-canvas.js` 均未加载(探测脚本未执行或路径错) 4. **坐标是否在可见范围内?** - 项目设计尺寸为 1280×720,检查 `x` 和 `y` 是否在此范围 @@ -762,11 +770,17 @@ gameabc_face.gamemydraw = function(gameid, spid, times, timelong) { - 检查 `gameabc_Project` 中的 `fps` 设置(默认 30) - SpineMgr 内部是用 `Date.now()` 计算真实时间差的,不依赖帧率 -- 如果需要倍速播放,修改 `state.timeScale`: +- 如果需要倍速播放,用 `setAnimation` 的返回值(Spine 的 TrackEntry)改 `timeScale`: ```javascript - var entry = gameabc_face.spineMgr._entries["hero"]; - entry.state.timeScale = 2.0; // 2 倍速 + var mgr = gameabc_face.spineMgr; + mgr.ensureEntry("hero", "hero.json", "hero.atlas", { scale: 1 }); + var track = mgr.setAnimation("hero", "run", true); + if (track) { track.timeScale = 2.0; } // 2 倍速 + // 资源尚未就绪时 setAnimation 会把命令排队并返回 null,下一帧就绪后自动执行 ``` + ⚠️ 不要直读 `spineMgr._entries[...]` 拿 `state` —— entry 表是 SpineMgr 的内部状态, + 其生命周期(何时 load / 何时因 scale 变化重建)由 SpineMgr 独占管理, + 外部持有的引用随时可能失效(如 WebGL context 恢复后整表重建)。 ### Q4: 切换动画时有跳帧 @@ -778,9 +792,9 @@ gameabc_face.gamemydraw = function(gameid, spid, times, timelong) { - 确认没有同一个 id 加载两次 - 检查 `ctx.save()` / `ctx.restore()` 是否配对(SpineMgr 内部已处理) -### Q6: spine-canvas.js 版本与 Spine 编辑器版本不匹配 +### Q6: Spine 运行时版本与 Spine 编辑器版本不匹配 -- **spine-canvas.js 4.2** 需搭配 **Spine 编辑器 4.2.x** 导出的数据 +- **spine-webgl / spine-canvas 4.2** 需搭配 **Spine 编辑器 4.2.x** 导出的数据 - 如果使用 Spine 4.1 编辑器,请下载对应版本的运行时: ``` https://unpkg.com/@esotericsoftware/spine-canvas@4.1/dist/iife/spine-canvas.js @@ -793,13 +807,16 @@ gameabc_face.gamemydraw = function(gameid, spid, times, timelong) { `index.html` 中的 script 标签加载顺序至关重要: ``` -1. spine-canvas.js ← 先加载 Spine 运行时 (定义 window.spine) +1. spine-webgl.js 或 spine-canvas.js + ← 先加载 Spine 运行时 (定义 window.spine),探测后只加载一套 2. gameabc.min.js ← 再加载游戏引擎 -3. SpineMgr.js ← Spine 管理器 + defineProperty 自动挂钩渲染 -4. gamemain.js ← 游戏主逻辑(不需修改,直接调用 API 即可) -5. Spine_Event.js ← Spine 事件回调 (依赖 gameabc_face) -6. Project1_Event.js ← 精灵事件 -7. gameabc_data.min.js ← 项目配置数据 (引擎初始化) +3. SpineOverlayTransform.js / SpineBackendCanvas.js / SpineBackendWebGL.js + ← 渲染后端,必须在 SpineMgr.js 之前(SpineMgr 末尾会立即执行预加载块) +4. SpineMgr.js ← Spine 管理器 + defineProperty 自动挂钩渲染 +5. gamemain.js ← 游戏主逻辑(不需修改,直接调用 API 即可) +6. Spine_Event.js ← Spine 事件回调 (依赖 gameabc_face) +7. Project1_Event.js ← 精灵事件 +8. gameabc_data.min.js ← 项目配置数据 (引擎初始化) ``` > **不能调换顺序**,`SpineMgr.js` 必须在 `gamemain.js` 之前加载, diff --git a/client/js/gameabc-framework/core/GameABCUtils.js b/client/js/gameabc-framework/core/GameABCUtils.js index d60c560..1906f3b 100644 --- a/client/js/gameabc-framework/core/GameABCUtils.js +++ b/client/js/gameabc-framework/core/GameABCUtils.js @@ -832,7 +832,7 @@ var GameABCUtils = (function() { }; // console.log('📐 注册裁剪区域: 容器=' + containerId + - // ', 区域=(' + x + ',' + y + ',' + w + ',' + h + ')'); + // ', 区域=(' + x + ',' + y + ',' + w + ',' + h + ')'); return true; }, diff --git a/client/js/gameabc-framework/core/SpriteManager.js b/client/js/gameabc-framework/core/SpriteManager.js index 7b5b30a..4ed4188 100644 --- a/client/js/gameabc-framework/core/SpriteManager.js +++ b/client/js/gameabc-framework/core/SpriteManager.js @@ -283,7 +283,7 @@ var SpriteManager = (function() { return true; } - console.log('🎨 SpriteManager: 开始初始化 (重构版 v2.0)'); + // console.log('🎨 SpriteManager: 开始初始化 (重构版 v2.0)'); // 检查依赖 if (typeof GameABCUtils === 'undefined') { @@ -292,8 +292,8 @@ var SpriteManager = (function() { } _isInitialized = true; - console.log('✅ SpriteManager: 初始化完成'); - console.log('ℹ️ SpriteManager: 设计原则 - 精灵由编辑器创建,代码只操作属性'); + // console.log('✅ SpriteManager: 初始化完成'); + // console.log('ℹ️ SpriteManager: 设计原则 - 精灵由编辑器创建,代码只操作属性'); return true; }, diff --git a/client/js/gameabc-framework/network/RpcHelper.js b/client/js/gameabc-framework/network/RpcHelper.js index 3dd2b70..6c7c5ce 100644 --- a/client/js/gameabc-framework/network/RpcHelper.js +++ b/client/js/gameabc-framework/network/RpcHelper.js @@ -95,21 +95,21 @@ var RpcHelper = { } // 5. 调试信息输出 - if (debug || Game_Config.Debugger.isDebugger) { - console.log('RpcHelper发送RPC:', { - app: app, - route: route, - rpc: rpc, - platform_data: { - agentid: data.agentid, - gameid: data.gameid, - playerid: data.playerid, - roomcode: data.roomcode - }, - game_data: gameData, - custom_data: customData - }); - } + // if (debug || Game_Config.Debugger.isDebugger) { + // console.log('RpcHelper发送RPC:', { + // app: app, + // route: route, + // rpc: rpc, + // platform_data: { + // agentid: data.agentid, + // gameid: data.gameid, + // playerid: data.playerid, + // roomcode: data.roomcode + // }, + // game_data: gameData, + // custom_data: customData + // }); + // } // 6. 通过框架发送RPC请求 Utl.sendData(app, route, rpc, data); diff --git a/client/js/gameabc-framework/spine/SpineBackendCanvas.js b/client/js/gameabc-framework/spine/SpineBackendCanvas.js new file mode 100644 index 0000000..c48ccc7 --- /dev/null +++ b/client/js/gameabc-framework/spine/SpineBackendCanvas.js @@ -0,0 +1,69 @@ +// ============================================================ +// SpineBackendCanvas —— Canvas 2D 渲染后端 +// 由 SpineMgr 在 WebGL 不可用时使用。逻辑迁自 SpineMgr.updateAndDraw,行为不变。 +// +// 已知性能特征:开启 triangleRendering 后,spine-canvas 对每个三角形都执行一次 +// clip() 加一次整张图集的 drawImage。mesh 密集的骨架(如 qixingshisanlan 2784 +// 三角形)在 iOS WKWebView 上会因 clip 叠加非轴对齐变换失去 GPU 快路径而卡顿。 +// 故本后端仅作回退,主路径见 SpineBackendWebGL。 +// ============================================================ +(function(){ + +var SpineBackendCanvas = { + + name: "canvas", + + _renderer: null, + _ctx: null, + + // 是否可用:spine 运行时须提供 Canvas 2D 的 SkeletonRenderer + isAvailable: function() { + return !!(window.spine && window.spine.SkeletonRenderer && !window.spine.SceneRenderer); + }, + + createAssetManager: function(basePath) { + return new spine.AssetManager(basePath); + }, + + // Canvas 后端:骨骼位置归零,实际位置由 drawEntry 的 ctx.translate 控制。 + // 由 SpineMgr 在 updateWorldTransform 之前调用 —— 之后再改 skeleton.x/y 不会重算 + // 世界变换,本帧不生效。 + placeEntry: function(entry) { + entry.skeleton.x = 0; + entry.skeleton.y = 0; + }, + + // 每帧开始:取 gameabc 的绘制上下文 + beginFrame: function() { + var ctx = gameabc_face.dc; + if (!ctx) return false; + this._ctx = ctx; + if (!this._renderer) { + this._renderer = new spine.SkeletonRenderer(ctx); + this._renderer.triangleRendering = true; // ★ 启用三角形渲染以支持 Mesh 网格附件 + } + // 确保 renderer 用的是当前 ctx (gameabc可能重建) + this._renderer.ctx = ctx; + return true; + }, + + drawEntry: function(entry) { + var ctx = this._ctx; + ctx.save(); + ctx.translate(entry.x, entry.y); + ctx.scale(1, -1); // ★ Spine Y-up → Canvas Y-down(scale 已烘焙进 SkeletonJson.scale) + this._renderer.draw(entry.skeleton); + ctx.restore(); + }, + + endFrame: function() { + this._ctx = null; + } +}; + +if (typeof module !== "undefined" && module.exports) { + module.exports = SpineBackendCanvas; +} +window.SpineBackendCanvas = SpineBackendCanvas; + +})(); diff --git a/client/js/gameabc-framework/spine/SpineBackendWebGL.js b/client/js/gameabc-framework/spine/SpineBackendWebGL.js new file mode 100644 index 0000000..e196c7f --- /dev/null +++ b/client/js/gameabc-framework/spine/SpineBackendWebGL.js @@ -0,0 +1,315 @@ +// ============================================================ +// SpineBackendWebGL —— WebGL 渲染后端(主路径) +// +// 在主画布之上叠加一张透明 canvas 绘制 Spine。相比 Canvas 2D 后端,mesh 密集的 +// 骨架从"每三角形一次 clip + 整图 drawImage"变为一次 draw call。 +// +// 坐标标定:不逆向混淆的 gameabc.min.js,而是每帧从 ctx.getTransform() 读取 +// 权威变换矩阵,交由 SpineOverlayTransform 换算成 MVP。 +// +// 真机实测确认的完整链路(gameabc_face.dc 属于一张离屏画布,并非 DOM 中可见的 +// #canvas,两者是完全不同的两个对象): +// Spine 坐标 --ctx.getTransform()--> 离屏画布像素(gameabc_face.dc.canvas, +// 实测 backing 1280x720,不在 DOM,getBoundingClientRect() 恒为 0) +// --gameabc 内部 blit--> 显示画布 #canvas(DOM 中可见,实测 backing 1912x880) +// --CSS--> 屏幕(实测 rect 956x440) +// +// 因此本文件区分两个几何来源,各司其职、不可合并成一个: +// - NDC 分母(buildMvp 的 canvasW/canvasH):取 gameabc_face.dc.canvas 的 +// width/height —— Spine 坐标是喂给 dc 的,分母必须与其同源。 +// - 叠加层的定位/CSS 尺寸/drawing buffer:取显示画布 #canvas 的 +// getBoundingClientRect() 与 width/height(backing) —— 叠加层要盖在屏幕上 +// 可见的画面上,且 drawing buffer 尺寸须与主画布有效分辨率一致。 +// 历史教训:曾把两者当成同一个对象 —— 用 #canvas 的尺寸做 NDC 分母则缩放错 +// (X/Y 倍数不同、宽高比歪);后又改成全部从 dc.canvas 取,结果叠加层去对齐 +// 离屏画布拿到的 rect(0,0,0,0),_syncSize 每帧提前 return,特效完全不显示。 +// ============================================================ +(function(){ + +// gameabc 的全局 logmessage 默认走 mode 0,是空操作(见 gameabc.min.js 的实现), +// 诊断日志必须直接走 console 才能在浏览器与真机 WebView 里看到。 +function spineLog(msg) { + if (typeof console !== "undefined" && console.log) { + console.log(msg); + } +} +function spineWarn(msg) { + if (typeof console !== "undefined" && console.warn) { + console.warn(msg); + } +} + +var SpineBackendWebGL = { + + name: "webgl", + + _canvas: null, + _gl: null, + _context: null, // spine.ManagedWebGLRenderingContext + _shader: null, + _batcher: null, + _renderer: null, + _mvp: null, // 复用的 16 元素数组,避免每帧分配 + _loggedCanvasIdentity: false, // 权威画布诊断日志只打一次,避免每帧刷屏 + _contextLost: false, + _hadVisible: false, // 上一帧是否有可见 entry(用于空闲帧跳过) + _assetManager: null, + _lossHandlersBound: false, // context lost 监听只绑一次 + + // 是否可用:spine 运行时须是 webgl 版(提供 SceneRenderer 等 GL 专有类) + isAvailable: function() { + return !!(window.spine && window.spine.SceneRenderer && window.SpineOverlayTransform); + }, + + // (内部) 惰性初始化 GL 资源。失败返回 false,SpineMgr 侧不再绘制。 + _ensureGL: function() { + if (this._gl) return true; + + this._canvas = document.getElementById("spine_gl"); + if (!this._canvas) { + spineWarn("[SpineBackendWebGL] 缺少 spine_gl 元素"); + return false; + } + + var gl = null; + try { + // alpha:true 让叠加层透出下方主画布;premultipliedAlpha 交由 spine 按图集 pma 标记处理 + var opts = { alpha: true, premultipliedAlpha: true, antialias: true, depth: false, stencil: false }; + gl = this._canvas.getContext("webgl", opts) || this._canvas.getContext("experimental-webgl", opts); + } catch (err) { + spineWarn("[SpineBackendWebGL] getContext 异常: " + err.message); + return false; + } + if (!gl) { + spineWarn("[SpineBackendWebGL] 无法取得 WebGL context"); + return false; + } + + this._gl = gl; + this._bindContextLossHandlers(); + + // context 恢复时复用同一个 ManagedWebGLRenderingContext: + // canvas.getContext() 恢复后返回的是同一个 WebGLRenderingContext 对象, + // 重新 new 会让新纹理注册到新 managed context,而 _assetManager 仍挂在旧的上, + // 造成新旧分叉。shader / batcher / renderer 持有失效的 GPU 资源,则必须重建。 + if (!this._context) { + this._context = new spine.ManagedWebGLRenderingContext(gl); + } + + // 复用 _context 的代价:Shader / Mesh 构造时都会 context.addRestorable(this), + // 只有 dispose() 才 removeRestorable。每次 context 恢复都会重走本段, + // 旧对象若不释放就永久堆在 restorables 里(旧 shader 程序 + batcher 顶点/索引缓冲), + // 恢复次数越多占用越大。context 已丢失时 gl.deleteShader/deleteBuffer 按规范是 no-op, + // 安全;仍加 try/catch 防御,释放失败不能挡住重建。 + // (SkeletonRenderer 不持有 GL 资源、无 dispose,不需处理。) + if (this._shader) { + try { + this._shader.dispose(); + } catch (errShader) { + spineWarn("[SpineBackendWebGL] 释放旧 shader 失败(已忽略): " + errShader.message); + } + this._shader = null; + } + if (this._batcher) { + try { + this._batcher.dispose(); + } catch (errBatcher) { + spineWarn("[SpineBackendWebGL] 释放旧 batcher 失败(已忽略): " + errBatcher.message); + } + this._batcher = null; + } + + this._shader = spine.Shader.newTwoColoredTextured(this._context); + this._batcher = new spine.PolygonBatcher(this._context); + // 中和 blend 模式:spine-canvas 的 drawTriangles 只跟踪 slot.data.blendMode 却从不应用 + // (该文件全文无 globalCompositeOperation),即迁移前所有槽都是按 source-over 画的。 + // spine-webgl 的 SkeletonRenderer 会真的调 batcher.setBlendMode(),在"清成透明黑"的 + // 叠加层上,screen 槽会输出非预乘颜色导致过亮/白边,multiply 槽会因 srcRgb=DST_COLOR + // 而 RGB 恒 0 变成纯黑剪影(本项目 start 有 9 个 screen 槽,而 game_start 每局必播)。 + // additive 在叠加层上恰好等价于 source-over,无差异。 + // 本次迁移只求性能、不引入视觉变化,故在此中和,保持 begin() 设定的 Normal 混合 + // (SkeletonRenderer.premultipliedAlpha 默认 false,与 PolygonBatcher 构造时的 + // SRC_ALPHA / ONE_MINUS_SRC_ALPHA 默认值一致,即"未中和时 Normal 槽会设成的那一组")。 + // 是否放开真实 blend,留作将来一次独立的、经美术确认的改动。 + // ⚠️ 必须紧跟每一次 new PolygonBatcher —— context 恢复会重建 batcher,写在别处即失效。 + this._batcher.setBlendMode = function() {}; + this._renderer = new spine.SkeletonRenderer(this._context); + this._mvp = new Array(16); + + gl.disable(gl.DEPTH_TEST); + gl.enable(gl.BLEND); + return true; + }, + + // (内部) WebGL context lost / restored。 + // iOS 在内存压力或切后台返回时会真实触发;不处理的表现是"特效突然全部消失且不再恢复"。 + // ⚠️ 只能绑一次:context restored 后 _gl 被置 null,_ensureGL 会重新走一遍, + // 若不加此闩,每恢复一次就多挂一对监听器,重复触发且泄漏。 + _bindContextLossHandlers: function() { + if (this._lossHandlersBound) return; + this._lossHandlersBound = true; + var self = this; + this._canvas.addEventListener("webglcontextlost", function(ev){ + ev.preventDefault(); // 必须 preventDefault,否则不会触发 restored + self._contextLost = true; + spineWarn("[SpineBackendWebGL] context lost"); + }, false); + this._canvas.addEventListener("webglcontextrestored", function(){ + spineLog("[SpineBackendWebGL] context restored,重建 GL 资源与纹理"); + self._contextLost = false; + self._gl = null; // 迫使 _ensureGL 重建 shader/batcher/renderer + self._hadVisible = false; // 复位空闲帧状态机,避免恢复后多发一次 clear + if (self._onContextRestored) self._onContextRestored(); + }, false); + }, + + // 由 SpineMgr 注入的纹理重建回调(Task 7 接入) + _onContextRestored: null, + + createAssetManager: function(basePath) { + if (!this._ensureGL()) { + // GL 不可用时不静默降级成"看似成功",直接抛出让 SpineMgr.init 失败, + // 由 index.html 的探测脚本保证不会走到这里。 + throw new Error("[SpineBackendWebGL] GL 初始化失败,无法创建 AssetManager"); + } + this._assetManager = new spine.AssetManager(this._context, basePath); + return this._assetManager; + }, + + // WebGL 后端:位移并入骨骼,使所有 entry 共用同一 MVP,可批量绘制。 + // y 取负是因为 MVP 中含 Spine Y-up → 画布 Y-down 的翻转(见 SpineOverlayTransform 推导)。 + placeEntry: function(entry) { + entry.skeleton.x = entry.x; + entry.skeleton.y = -entry.y; + }, + + beginFrame: function(visibleCount) { + if (this._contextLost) return false; + if (!this._ensureGL()) return false; + + // 绘制缓冲画布(NDC 分母来源):Spine 坐标是喂给 dc 的,分母必须与其同源, + // 只能每帧从 dc 派生(createAssetManager 阶段 dc 可能还不存在,故不能在 + // _ensureGL 里固定取一次)。数据源唯一,取不到即报错跳帧,禁止 || 兜底。 + var ctx = gameabc_face.dc; + if (!ctx) return false; + var drawCanvas = ctx.canvas; + if (!drawCanvas) { + spineWarn("[SpineBackendWebGL] gameabc_face.dc.canvas 不存在(非标准 CanvasRenderingContext2D 实现),本帧跳过"); + return false; + } + + // 显示画布(叠加层定位/CSS 尺寸/drawing buffer 来源):index.html 中 + //
是 gameabc 平台约定的固定 + // 显示画布契约,并非按 id 猜——但仍须校验存在性/在 DOM/rect 有效, + // 任一项不满足都不能静默继续绘制。 + var displayCanvas = (typeof document !== "undefined" && document.getElementById) ? document.getElementById("canvas") : null; + if (!displayCanvas) { + spineWarn("[SpineBackendWebGL] 找不到显示画布 document.getElementById(\"canvas\"),本帧跳过"); + return false; + } + if (!displayCanvas.parentNode) { + spineWarn("[SpineBackendWebGL] 显示画布 #canvas 不在 DOM 中,本帧跳过"); + return false; + } + var displayRect = displayCanvas.getBoundingClientRect(); + if (!displayRect || displayRect.width <= 0 || displayRect.height <= 0) { + spineWarn("[SpineBackendWebGL] 显示画布 #canvas 的 rect 尺寸无效,本帧跳过"); + return false; + } + + this._logCanvasIdentityOnce(drawCanvas, displayCanvas, displayRect); + + // 空闲帧跳过:麻将大部分时间无特效在播,不能因叠加层存在就每帧空 clear 全屏。 + // 仅在从"有"变"无"的那一帧 clear 一次收尾。 + if (visibleCount === 0) { + if (!this._hadVisible) return false; + this._hadVisible = false; + this._syncSize(displayCanvas); + this._gl.clearColor(0, 0, 0, 0); + this._gl.clear(this._gl.COLOR_BUFFER_BIT); + return false; + } + this._hadVisible = true; + + if (!this._syncSize(displayCanvas)) return false; + + var m = this._readTransform(ctx); + SpineOverlayTransform.buildMvp(m, drawCanvas.width, drawCanvas.height, this._mvp); + + var gl = this._gl; + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + + this._shader.bind(); + this._shader.setUniformi(spine.Shader.SAMPLER, 0); + this._shader.setUniform4x4f(spine.Shader.MVP_MATRIX, this._mvp); + this._batcher.begin(this._shader); + return true; + }, + + // (内部) 读取 gameabc 绘制上下文的权威变换矩阵。 + // getTransform() 自 iOS Safari 11 起支持,远低于本项目已验证的 WebView 基线; + // 取不到时退化为单位矩阵(此时叠加层按绘制缓冲画布 dc.canvas 的 backing 尺寸直接映射)。 + _readTransform: function(ctx) { + if (typeof ctx.getTransform === "function") { + var t = ctx.getTransform(); + return { a: t.a, b: t.b, c: t.c, d: t.d, e: t.e, f: t.f }; + } + return { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }; + }, + + // (内部) 一次性诊断日志:同时记录两个几何来源的身份与数值,便于后续核对 + // ——绘制缓冲画布(dc.canvas,NDC 分母)与显示画布(#canvas,叠加层定位/尺寸) + // 是否为同一个对象、各自的 backing 与显示画布的 rect。 + _logCanvasIdentityOnce: function(drawCanvas, displayCanvas, displayRect) { + if (this._loggedCanvasIdentity) return; + this._loggedCanvasIdentity = true; + var drawIdDesc = drawCanvas.id ? ("#" + drawCanvas.id) : "(无 id)"; + spineLog("[SpineBackendWebGL] 绘制缓冲画布(gameabc_face.dc.canvas) = " + drawIdDesc + + ",backing=" + drawCanvas.width + "x" + drawCanvas.height + + ";显示画布(#canvas) backing=" + displayCanvas.width + "x" + displayCanvas.height + + ",rect=(" + displayRect.left + "," + displayRect.top + "," + displayRect.width + "," + displayRect.height + ")" + + ",两者是否同一对象=" + (drawCanvas === displayCanvas)); + }, + + // (内部) 每帧把叠加层的位置与尺寸镜像到显示画布(#canvas)的实际显示区域。 + // drawing buffer 尺寸直接取显示画布的 backing(width/height),不再用 + // rect × devicePixelRatio 计算——与主画布有效分辨率一致即可,用 DPR 会开出 + // 比主画布 backing 还大的 buffer,白白多占显存。 + _syncSize: function(displayCanvas) { + var rect = displayCanvas.getBoundingClientRect(); + if (rect.width <= 0 || rect.height <= 0) return false; + + var host = this._canvas.parentNode; + host.style.left = rect.left + "px"; + host.style.top = rect.top + "px"; + this._canvas.style.width = rect.width + "px"; + this._canvas.style.height = rect.height + "px"; + + var bw = displayCanvas.width; + var bh = displayCanvas.height; + if (bw <= 0 || bh <= 0) return false; + if (this._canvas.width !== bw || this._canvas.height !== bh) { + this._canvas.width = bw; + this._canvas.height = bh; + } + this._gl.viewport(0, 0, bw, bh); + return true; + }, + + drawEntry: function(entry) { + this._renderer.draw(this._batcher, entry.skeleton); + }, + + endFrame: function() { + this._batcher.end(); + this._shader.unbind(); + } +}; + +if (typeof module !== "undefined" && module.exports) { + module.exports = SpineBackendWebGL; +} +window.SpineBackendWebGL = SpineBackendWebGL; + +})(); diff --git a/client/js/gameabc-framework/spine/SpineMgr.js b/client/js/gameabc-framework/spine/SpineMgr.js index 7d97f37..6cec30d 100644 --- a/client/js/gameabc-framework/spine/SpineMgr.js +++ b/client/js/gameabc-framework/spine/SpineMgr.js @@ -5,12 +5,25 @@ // ============================================================ (function(){ +// gameabc 的全局 logmessage 默认走 mode 0,是空操作(见 gameabc.min.js 的实现), +// 诊断日志必须直接走 console 才能在浏览器与真机 WebView 里看到。 +function spineLog(msg) { + if (typeof console !== "undefined" && console.log) { + console.log(msg); + } +} +function spineWarn(msg) { + if (typeof console !== "undefined" && console.warn) { + console.warn(msg); + } +} + var SpineMgr = { // --- 内部状态 --- _entries: {}, // {id: EntryObject} _assetManager: null, - _renderer: null, // spine.SkeletonRenderer (Canvas 2D) + _backend: null, // 渲染后端(SpineBackendWebGL / SpineBackendCanvas) _lastTime: 0, // 上一帧时间戳(ms) _inited: false, _loadedPaths: {}, // 已请求加载的资源路径,避免重复请求 @@ -27,15 +40,50 @@ var SpineMgr = { // ---------------------------------------------------------- init: function(basePath) { if (!window.spine) { - logmessage("[SpineMgr] spine-canvas.js 未加载,请检查引用"); + spineWarn("[SpineMgr] spine 运行时未加载,请检查 index.html 的探测脚本"); return; } + this._backend = this._selectBackend(); + if (!this._backend) { + spineWarn("[SpineMgr] 无可用渲染后端"); + return; + } + spineLog("[SpineMgr] 渲染后端: " + this._backend.name); this._basePath = basePath || this._basePath; - this._assetManager = new spine.AssetManager(this._basePath); + // 挂接 context lost 恢复回调(仅 WebGL 后端有此机制) + var self = this; + if (this._backend.name === "webgl") { + this._backend._onContextRestored = function() { + self._rebuildAfterContextRestored(); + }; + } + // 后端初始化失败必须显式记录并让 _inited 保持 false,但不能让异常向上抛: + // init 由文件末尾的预加载块经 _ensureInit() 调用,异常会中断整个 IIFE, + // 导致后面的 gameenddraw 拦截根本不安装 —— Spine 从此永不绘制且无迹可循。 + // _inited 保持 false 时,各 API 走既有的 if (!this._inited) return 静默路径。 + try { + this._assetManager = this._backend.createAssetManager(this._basePath); + } catch (err) { + spineWarn("[SpineMgr] 后端初始化失败: " + err.message); + this._backend = null; + return; + } this._lastTime = Date.now(); this._inited = true; }, + // (内部) 选定渲染后端。index.html 的探测脚本已决定加载哪套 spine 运行时, + // 此处按运行时实际提供的能力对应上后端实现。 + _selectBackend: function() { + if (window.SpineBackendWebGL && SpineBackendWebGL.isAvailable()) { + return SpineBackendWebGL; + } + if (window.SpineBackendCanvas && SpineBackendCanvas.isAvailable()) { + return SpineBackendCanvas; + } + return null; + }, + // (内部) 确保已初始化 _ensureInit: function() { if (!this._inited) { @@ -43,6 +91,42 @@ var SpineMgr = { } }, + // ---------------------------------------------------------- + // (内部) _preloadAll() + // 按 gameabc_face.spineAssets 清单,把全部 Spine 资源注入当前 AssetManager 并发起加载。 + // ⚠️ 必须整批注入,不能只补"当前已存在的 entry": + // 规避 file:// 下 XHR CORS 用的 rawDataUris 是 Downloader 实例私有的 + // (AssetManagerBase 构造时默认 new Downloader()),换一个新 AssetManager + // 就等于换了一份空 rawDataUris。若只补已存在的 entry,context 恢复之后 + // 首次触发的新特效(如天胡)会走真实 XHR 被 CORS 拦掉,_tryBuild 里 require() + // 抛异常 → ready 恒 false → 每帧重试且永不显示。 + // 返回本次注册的资源组数。 + // ---------------------------------------------------------- + _preloadAll: function() { + var list = gameabc_face.spineAssets; + if (!list || list.length === 0) return 0; + var textData = gameabc_face.spineTextData || {}; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + var jsonKey = name + ".json"; + var atlasKey = name + ".atlas"; + // 将嵌入文本数据注册为 rawDataURI,Spine Downloader 会优先从内存读取 + if (textData[jsonKey]) { + this._assetManager.setRawDataURI(jsonKey, "data:," + textData[jsonKey]); + } + if (textData[atlasKey]) { + this._assetManager.setRawDataURI(atlasKey, "data:," + textData[atlasKey]); + } + this._assetManager.loadText(jsonKey); + this._loadedPaths[jsonKey] = true; + this._assetManager.loadTextureAtlas(atlasKey); + this._loadedPaths[atlasKey] = true; + } + spineLog("[SpineMgr] 预加载 " + list.length + " 组 Spine 资源" + + (Object.keys(textData).length > 0 ? "(使用嵌入数据)" : "(使用网络请求)")); + return list.length; + }, + // (内部) 自动加载:根据 id 约定文件名 id.json / id.atlas // 主流 SkeletonJson.scale 方案:从 _scaleMap 读取目标缩放,传入 load() 在解析时烘焙 _autoLoad: function(id) { @@ -101,16 +185,45 @@ var SpineMgr = { visible: true, ready: false, _hideOnComplete: false, // 播放完成后是否自动隐藏 - _hideAfterCompletes: 0 // 剩余多少次 complete 后触发隐藏 + _hideAfterCompletes: 0, // 剩余多少次 complete 后触发隐藏 + _buildFailLogged: false // 构建失败日志只记一次(_tryBuild 每帧调用) }; }, + // ---------------------------------------------------------- + // ensureEntry(id, jsonFile, atlasFile, option) + // 确保 id 对应的 entry 存在并达到 option 指定的状态。 + // entry 生命周期归 SpineMgr 管,调用方无需掌握"不在就 load、在就 setScale"的内部规则, + // 也无需从 id 推导文件名(entryId 与资源文件名不一定同名,如 ting_0 -> ting.json)。 + // ---------------------------------------------------------- + ensureEntry: function(id, jsonFile, atlasFile, option) { + var e = this._entries[id]; + if (!e) { + this.load(id, jsonFile, atlasFile, option); + return; + } + if (option && option.scale !== undefined) { + this.setScale(id, option.scale); + } + }, + + // ---------------------------------------------------------- + // isReady() 后端是否已就绪、能真正播放 Spine + // 探测阶段的 canvas 兜底只覆盖"WebGL 不可用";若探测通过但 GL 初始化失败 + // (叠加层 DOM 缺失 / 并发 context 耗尽 / shader 编译失败),此时 canvas 运行时 + // 并未加载、回不去,调用方应据此走各自既有的帧动画降级路径, + // 而不是让 Spine 静默失效却以为播成功了。 + // ---------------------------------------------------------- + isReady: function() { + return !!this._inited; + }, + // ---------------------------------------------------------- // (内部) 资源加载完成后实例化骨骼 // 同一 jsonFile+scale 的 SkeletonData 只解析一次,多个 entry 共享 // ---------------------------------------------------------- _buildEntry: function(entry) { - logmessage("[SpineMgr] _buildEntry: " + entry._id + " skelJson.scale=" + entry.scale); + spineLog("[SpineMgr] _buildEntry: " + entry._id + " skelJson.scale=" + entry.scale); var cacheKey = entry.jsonFile + "_s" + entry.scale; var skelData = this._skelDataCache[cacheKey]; if (!skelData) { @@ -122,9 +235,9 @@ var SpineMgr = { this._assetManager.require(entry.jsonFile) ); this._skelDataCache[cacheKey] = skelData; - logmessage("[SpineMgr] SkeletonData 解析并缓存: " + cacheKey); + spineLog("[SpineMgr] SkeletonData 解析并缓存: " + cacheKey); } else { - logmessage("[SpineMgr] SkeletonData 命中缓存: " + cacheKey); + spineLog("[SpineMgr] SkeletonData 命中缓存: " + cacheKey); } entry.skeleton = new spine.Skeleton(skelData); @@ -179,10 +292,15 @@ var SpineMgr = { e._id = id; try { this._buildEntry(e); - logmessage("[SpineMgr] " + id + " 构建完成"); + spineLog("[SpineMgr] " + id + " 构建完成"); this._flushCmds(id); } catch(err) { - logmessage("[SpineMgr] " + id + " 构建失败: " + err.message); + // 重试本身必须保留(资源可能只是还没到齐),但日志只记一次: + // 本方法每帧调用,持续失败时会以约 60 条/秒刷屏并淹没其他日志。 + if (!e._buildFailLogged) { + e._buildFailLogged = true; + spineWarn("[SpineMgr] " + id + " 构建失败(仅记一次): " + err.message); + } e.ready = false; } } @@ -190,6 +308,79 @@ var SpineMgr = { return true; }, + // ---------------------------------------------------------- + // (内部) WebGL context 恢复后重建全部 GPU 资源 + // context lost 会让 AssetManager 中缓存的 GLTexture 与 shader 一并作废, + // 必须重新加载资源并重建所有 entry,否则表现为"特效再也不显示"。 + // ---------------------------------------------------------- + _rebuildAfterContextRestored: function() { + spineLog("[SpineMgr] 重建 Spine 资源(context restored)"); + + // 记录当前 entry 的声明式状态,重建后按原样恢复 + var saved = []; + for (var id in this._entries) { + var e = this._entries[id]; + saved.push({ + id: id, + jsonFile: e.jsonFile, + atlasFile: e.atlasFile, + x: e.x, + y: e.y, + scale: e.scale, + skin: e.skin, + mixDur: e.mixDur + }); + } + + // 丢弃全部缓存:SkeletonData 持有已作废的 GLTexture 引用,不能复用 + this._entries = {}; + this._pendingCmds = {}; + this._skelDataCache = {}; + this._loadedPaths = {}; + + // 先释放旧 AssetManager 再换新的:GLTexture 构造时会 context.addRestorable(this), + // 只有 dispose() 才 removeRestorable。本后端刻意复用同一个 ManagedWebGLRenderingContext + // (见 SpineBackendWebGL._ensureGL 注释),若不释放,每恢复一次就把 23 页图集的 + // GLTexture 永久留在 restorables 里(解码位图约 137MB)—— 而 context lost 的诱因 + // 正是内存压力,泄漏会把 lost/restore 变成越恢复越糟的死循环。 + // context 已丢失时 gl.deleteTexture 等按规范是 no-op,安全;仍加 try/catch 防御, + // 释放失败不能挡住后面的重建。 + if (this._assetManager) { + try { + this._assetManager.dispose(); + } catch (errDispose) { + spineWarn("[SpineMgr] 释放旧 AssetManager 失败(已忽略): " + errDispose.message); + } + this._assetManager = null; + } + + // 本方法在 webglcontextrestored 事件回调中执行,异常会逸出到事件循环, + // 故与 init 同样显式捕获:重建失败就停在不可用状态并留下日志。 + try { + this._assetManager = this._backend.createAssetManager(this._basePath); + } catch (err) { + spineWarn("[SpineMgr] context 恢复后重建 AssetManager 失败: " + err.message); + this._inited = false; + return; + } + + // 整批重注入 rawDataURI 并重新发起加载:新 AssetManager = 新 Downloader = 空 rawDataUris, + // 只补 saved 里的资源会让恢复后首次触发的新特效在 file:// 下被 CORS 拦死(见 _preloadAll 注释)。 + // _preloadAll 会把全部资源写进 _loadedPaths,故下面按 saved 重建 entry 时 + // load() 的 if (!this._loadedPaths[...]) 判断会正确跳过重复请求。 + this._preloadAll(); + + for (var i = 0; i < saved.length; i++) { + var s = saved[i]; + this.load(s.id, s.jsonFile, s.atlasFile, { + x: s.x, y: s.y, scale: s.scale, skin: s.skin, mixDuration: s.mixDur + }); + // 重建后默认不可见:正在播的动画已随 context 丢失, + // 强行续播会出现半截动画,交由下一次业务触发重新播放。 + this._entries[s.id].visible = false; + } + }, + // ---------------------------------------------------------- // updateAndDraw(ctx) 每帧自动调用 // ctx: gameabc_face.dc (Canvas 2D Context) @@ -203,29 +394,33 @@ var SpineMgr = { this._lastTime = now; if (dt <= 0 || dt > 0.5) dt = 1/30; - if (!this._renderer) { - this._renderer = new spine.SkeletonRenderer(ctx); - this._renderer.triangleRendering = true; // ★ 启用三角形渲染以支持 Mesh 网格附件 - } - // 确保 renderer 用的是当前 ctx (gameabc可能重建) - this._renderer.ctx = ctx; - + // 先推进动画状态:即使本帧无法绘制(后端未就绪 / context lost), + // 动画时间轴与 complete 事件也必须照常推进,否则回调链会卡死。 + var visibleList = []; for (var id in this._entries) { var e = this._entries[id]; if (!e.ready || !e.visible) continue; e.state.update(dt); e.state.apply(e.skeleton); - // 骨骼位置归零,由 ctx.translate 控制实际位置 - e.skeleton.x = 0; - e.skeleton.y = 0; + // 骨骼位置由后端决定:Canvas 后端归零(用 ctx.translate 定位), + // WebGL 后端写入 x/-y(位移并入骨骼,使所有 entry 共用同一 MVP)。 + // 必须在 updateWorldTransform 之前设置,否则不生效于本帧。 + this._backend.placeEntry(e); e.skeleton.updateWorldTransform(spine.Physics.update); + visibleList.push(e); + } - ctx.save(); - ctx.translate(e.x, e.y); - ctx.scale(1, -1); // ★ Spine Y-up → Canvas Y-down(scale 已烘焙进 SkeletonJson.scale) - this._renderer.draw(e.skeleton); - ctx.restore(); + if (!this._backend.beginFrame(visibleList.length)) return; + // endFrame 必须配对执行:WebGL 后端的 PolygonBatcher 只在 endFrame 里 end(), + // 若 drawEntry 抛出而漏了 end(),batcher.isDrawing 会永久停在 true, + // 下一帧 begin() 即抛 "PolygonBatch is already drawing" 并冒到 gameenddraw —— Spine 永久黑屏。 + try { + for (var i = 0; i < visibleList.length; i++) { + this._backend.drawEntry(visibleList[i]); + } + } finally { + this._backend.endFrame(); } }, @@ -281,10 +476,13 @@ var SpineMgr = { return; } if (e.scale === sx) return; // 已是目标 scale,无需重建 - // 目标 scale 与已烘焙 scale 不同 → 清除旧 entry,下次 _autoLoad 将以新 scale 重建 + // 目标 scale 与已烘焙 scale 不同 → 清除旧 entry 并以新 scale 重建。 + // 文件名必须取自 entry(load 时记录的权威值):entryId 与资源文件名不一定同名 + // (如 entryId=ting_0 对应 ting.json),按 id 推导会去加载不存在的文件。 var savedX = e.x, savedY = e.y; + var savedJson = e.jsonFile, savedAtlas = e.atlasFile; this.remove(id); - this.load(id, id + ".json", id + ".atlas", { scale: sx, x: savedX, y: savedY }); + this.load(id, savedJson, savedAtlas, { scale: sx, x: savedX, y: savedY }); }, setFlip: function(id, flipX, flipY) { @@ -423,26 +621,16 @@ gameabc_face.spineMgr = SpineMgr; // 彻底避免 file:// 协议下 XHR CORS 拦截问题 if (gameabc_face.spineAssets && gameabc_face.spineAssets.length > 0) { SpineMgr._ensureInit(); - var list = gameabc_face.spineAssets; - var textData = gameabc_face.spineTextData || {}; - for (var i = 0; i < list.length; i++) { - var name = list[i]; - var jsonKey = name + ".json"; - var atlasKey = name + ".atlas"; - // 将嵌入文本数据注册为 rawDataURI,Spine Downloader 会优先从内存读取 - if (textData[jsonKey]) { - SpineMgr._assetManager.setRawDataURI(jsonKey, "data:," + textData[jsonKey]); - } - if (textData[atlasKey]) { - SpineMgr._assetManager.setRawDataURI(atlasKey, "data:," + textData[atlasKey]); - } - SpineMgr._assetManager.loadText(jsonKey); - SpineMgr._loadedPaths[jsonKey] = true; - SpineMgr._assetManager.loadTextureAtlas(atlasKey); - SpineMgr._loadedPaths[atlasKey] = true; + if (!SpineMgr._inited) { + // 后端未就绪:跳过预加载,但必须继续往下走完 gameenddraw 拦截的安装。 + // 此处不能 return —— 预加载块在 IIFE 函数体内,return 会退出整个 IIFE, + // 反而导致拦截装不上,正是本守卫要避免的后果。 + // 回归锁:codes/test/node/spineMgr.gameEndDrawGuard.test.js + spineWarn("[SpineMgr] 后端未就绪,跳过 Spine 资源预加载"); + } else { + // 与 context 恢复后的重注入共用同一份实现,避免两处清单分叉 + SpineMgr._preloadAll(); } - logmessage("[SpineMgr] 预加载 " + list.length + " 组 Spine 资源" + - (Object.keys(textData).length > 0 ? "(使用嵌入数据)" : "(使用网络请求)")); } // ★ 用 defineProperty 拦截 gameenddraw 赋值 diff --git a/client/js/gameabc-framework/spine/SpineOverlayTransform.js b/client/js/gameabc-framework/spine/SpineOverlayTransform.js new file mode 100644 index 0000000..d5cffd1 --- /dev/null +++ b/client/js/gameabc-framework/spine/SpineOverlayTransform.js @@ -0,0 +1,88 @@ +// ============================================================ +// SpineOverlayTransform —— WebGL 叠加层坐标标定(纯函数) +// +// 职责:把 gameabc 主画布的权威变换矩阵换算成 WebGL 的 MVP 矩阵。 +// 无副作用、无 DOM 依赖,可独立单测。 +// +// 为什么不逆向 gameabc.min.js:那是混淆代码(变量名全打乱),读不出它内部如何 +// 映射坐标。而 Spine 绘制发生在 gameenddraw(gameabc 绘制流程末尾),此刻 ctx +// 上已带着 gameabc 设好的全局变换 —— 直接向 ctx 要矩阵即可,权威、且 gameabc +// 后续改缩放/响应旋转时自动跟随。 +// +// ⚠️ 真机实测确认:Spine 实际画在 gameabc_face.dc.canvas 这张离屏画布上 +// (backing 约 1280x720,不在 DOM),gameabc 再把它 blit 到 DOM 中可见的显示 +// 画布 #canvas(backing 约 1912x880),最后经 CSS 缩放到屏幕。本函数的 +// canvasW/canvasH 必须传绘制缓冲画布(dc.canvas)的 backing 尺寸,因为 +// Spine 坐标正是喂给这张画布的,分母须与其同源;叠加层自身的定位/CSS 尺寸/ +// drawing buffer 则是另一个来源(显示画布 #canvas),由调用方 +// SpineBackendWebGL 负责,不在本函数职责内。 +// +// 推导(Spine 世界坐标 Y-up,画布 Y-down): +// 位移由调用方经 skeleton.x = e.x; skeleton.y = -e.y 承担,本矩阵只处理 +// scale(1,-1) 与投影,等价于 Canvas 后端的 ctx.translate(e.x,e.y)+ctx.scale(1,-1)。 +// +// 1) Spine 世界 → 逻辑坐标: Lx = vx, Ly = -vy +// 2) 逻辑 → 画布像素: Px = a*Lx + c*Ly + e, Py = b*Lx + d*Ly + f +// 3) 画布像素 → NDC: x = 2*Px/W - 1, y = 1 - 2*Py/H +// +// 合并: +// x_ndc = (2a/W)*vx + (-2c/W)*vy + (2e/W - 1) +// y_ndc = (-2b/H)*vx + ( 2d/H)*vy + (1 - 2f/H) +// +// 注意:叠加层 drawing buffer 尺寸在推导中被约掉(gl.viewport 覆盖整个 buffer, +// NDC 自动铺满),故本矩阵只依赖 ctx 变换与绘制缓冲画布 backing 尺寸。因此所有 +// entry 共用同一个 MVP,可一次 batcher.begin/end 批量绘制。 +// ============================================================ +(function(){ + +var SpineOverlayTransform = { + + // ---------------------------------------------------------- + // buildMvp(m, canvasW, canvasH, out) + // m : {a,b,c,d,e,f} —— ctx.getTransform() 的六元素 + // canvasW : 绘制缓冲画布(gameabc_face.dc.canvas)的 backing 宽(实测约 1280) + // canvasH : 绘制缓冲画布(gameabc_face.dc.canvas)的 backing 高(实测约 720) + // out : 可选,长度 16 的复用数组(避免每帧分配) + // 返回列主序 4x4 矩阵 + // ---------------------------------------------------------- + buildMvp: function(m, canvasW, canvasH, out) { + var r = out || new Array(16); + + var sx = 2 / canvasW; + var sy = 2 / canvasH; + + // 第 0 列:vx 的系数 + r[0] = sx * m.a; + r[1] = -sy * m.b; + r[2] = 0; + r[3] = 0; + + // 第 1 列:vy 的系数 + r[4] = -sx * m.c; + r[5] = sy * m.d; + r[6] = 0; + r[7] = 0; + + // 第 2 列:z 保持 + r[8] = 0; + r[9] = 0; + r[10] = 1; + r[11] = 0; + + // 第 3 列:平移 + r[12] = sx * m.e - 1; + r[13] = 1 - sy * m.f; + r[14] = 0; + r[15] = 1; + + return r; + } +}; + +if (typeof module !== "undefined" && module.exports) { + module.exports = SpineOverlayTransform; +} +// 友乐运行时有 module 无 require 且共享全局作用域,须无条件暴露全局名 +window.SpineOverlayTransform = SpineOverlayTransform; + +})(); diff --git a/client/js/gameabc-framework/system/AnimationManager.js b/client/js/gameabc-framework/system/AnimationManager.js index 0c2206b..c7e0812 100644 --- a/client/js/gameabc-framework/system/AnimationManager.js +++ b/client/js/gameabc-framework/system/AnimationManager.js @@ -810,7 +810,7 @@ var AnimationManager = AnimationManager || {}; } _initialized = true; - console.log('[AnimationManager] Initialized (v2.0.0 optimized)'); + // console.log('[AnimationManager] Initialized (v2.0.0 optimized)'); }; /** diff --git a/client/js/gameabc-framework/system/AudioManager.js b/client/js/gameabc-framework/system/AudioManager.js index bdba8e9..fca8d98 100644 --- a/client/js/gameabc-framework/system/AudioManager.js +++ b/client/js/gameabc-framework/system/AudioManager.js @@ -164,7 +164,7 @@ var AudioManager = AudioManager || {}; return; } _initialized = true; - console.log('[AudioManager] Initialized (v4.0.0)'); + // console.log('[AudioManager] Initialized (v4.0.0)'); }; // ============================================================================ diff --git a/client/js/gameabc-framework/system/EventBus.js b/client/js/gameabc-framework/system/EventBus.js index 9b343e3..e3fb2ff 100644 --- a/client/js/gameabc-framework/system/EventBus.js +++ b/client/js/gameabc-framework/system/EventBus.js @@ -80,7 +80,7 @@ var EventBus = { }; this._listeners[eventName].push(listener); - console.log('✅ EventBus: 订阅事件', eventName); + // console.log('✅ EventBus: 订阅事件', eventName); // 返回取消订阅函数 var self = this; @@ -121,7 +121,7 @@ var EventBus = { // 如果没有指定callback,取消该事件的所有监听器 if (!callback) { delete this._listeners[eventName]; - console.log('✅ EventBus: 取消所有', eventName, '监听器'); + // console.log('✅ EventBus: 取消所有', eventName, '监听器'); return true; } @@ -130,7 +130,7 @@ var EventBus = { for (var i = listeners.length - 1; i >= 0; i--) { if (listeners[i].callback === callback) { listeners.splice(i, 1); - console.log('✅ EventBus: 取消', eventName, '监听器'); + // console.log('✅ EventBus: 取消', eventName, '监听器'); return true; } } @@ -152,7 +152,7 @@ var EventBus = { var listeners = this._listeners[eventName].slice(); // 复制数组,避免迭代中修改 var count = 0; - console.log('📡 EventBus: 触发事件', eventName, data); + // console.log('📡 EventBus: 触发事件', eventName, data); for (var i = 0; i < listeners.length; i++) { try { @@ -204,7 +204,7 @@ var EventBus = { */ clear: function() { this._listeners = {}; - console.log('✅ EventBus: 已清空所有监听器'); + // console.log('✅ EventBus: 已清空所有监听器'); }, /** @@ -214,7 +214,7 @@ var EventBus = { clearEvent: function(eventName) { if (this._listeners[eventName]) { delete this._listeners[eventName]; - console.log('✅ EventBus: 已清空', eventName, '的所有监听器'); + // console.log('✅ EventBus: 已清空', eventName, '的所有监听器'); } } }; diff --git a/client/js/gameabc-framework/templates/UIBootstrap.template.js b/client/js/gameabc-framework/templates/UIBootstrap.template.js index dd92c38..73f0362 100644 --- a/client/js/gameabc-framework/templates/UIBootstrap.template.js +++ b/client/js/gameabc-framework/templates/UIBootstrap.template.js @@ -79,7 +79,7 @@ UIBootstrap.init = function () { return true; } - console.log('[UIBootstrap] 开始初始化 UI 系统...'); + // console.log('[UIBootstrap] 开始初始化 UI 系统...'); try { if (!this._checkDependencies()) { return false; } @@ -102,7 +102,7 @@ UIBootstrap.init = function () { this._registerViews(); this.initialized = true; - console.log('[UIBootstrap] UI 系统初始化完成,共', Object.keys(this.views).length, '个组件'); + // console.log('[UIBootstrap] UI 系统初始化完成,共', Object.keys(this.views).length, '个组件'); return true; } catch (err) { console.error('[UIBootstrap] 初始化失败:', err); diff --git a/client/js/gameabc-framework/templates/subgame-entry/00_SubGame_Config.template.js b/client/js/gameabc-framework/templates/subgame-entry/00_SubGame_Config.template.js index 85cbce1..9f0d41a 100644 --- a/client/js/gameabc-framework/templates/subgame-entry/00_SubGame_Config.template.js +++ b/client/js/gameabc-framework/templates/subgame-entry/00_SubGame_Config.template.js @@ -1,36 +1,38 @@ // ============================================================================ -// 00_SubGame_Config.template.js —— 平台配置项模板(结构由平台定义,子游戏填【值】) -// 这是配置文件(C 类,非转发壳)。复制后按本游戏界面/玩法调整各项值。 -// 严格 ES5。 +// 游戏配置 (Game Configuration) // ============================================================================ -var Game_Config = Game_Config || {}; +var Game_Config = Game_Config||{};//相关配置 -Game_Config.Debugger={//调试配置 +Game_Config.Debugger={//调试配置 isDebugger : true,// debugger模式下会将所有收发的包输出到控制台(正式发布改为false) AutoLogin : true,//debugger模式下是否需要记住登录状态自动登录(正式发布改为true) - isSubmitError : false,//是否需要服务器收集错误信息调试时可根据需要(正式发布改为true) - visitorLogin : true,//隐藏式游客登录 + isSubmitError : false,//是否需要服务器收集错误信息调试时可根据需要(正式发布改为true) + visitorLogin : true,//隐藏式游客登录 visiblePay:true,//审核通过后是否显示支付按钮 serverType:1,//0->正式服务器 1->本地服务器 http://ylyxservice1.0791ts.cn/config/update_json.txt - gameserver:""//子游戏填自己的更新地址 -}; + gameserver:"https://tsgames.daoqi88.cn/config_test/beta_update_jsonv2.txt"+"?"+ifast_random(100000) + // gameserver:"https://tsgames.daoqi88.cn/config_test/test_update_jsonv2.txt"+"?"+ifast_random(100000) + //gameserver:"https://gameotherwork.ld2sw.cn/update_json/update_json_haiwai.txt"+"?"+ifast_random(100000) + // gameserver:"https://tsgames.daoqi88.cn/config/update_jsonv2.txt"+"?"+ifast_random(100000) + +}; Game_Config.Max = { - SumOfRoomtype:3,//创建时房间类型roomtype数组长度 + SumOfRoomtype:3,//创建时房间类型roomtype数组长度 ShowChat:2000,//聊天停留时间 - PlayerCnt:4,//房间最大人数(按房间最大人数设置) + PlayerCnt:4,//房间最大人数 group:500,//游戏最大群组号 - showtime:10,//加载等待最少时间 - reconnecttime:30000,//唤醒游戏间隔(超过间隔断线重连) + showtime:10,//加载等待最少时间 + reconnecttime:30000,//唤醒游戏间隔(超过间隔断线重连) Mainnickname:10,//主界面玩家昵称显示长度(字符长度) - Infonickname:16//个人信息显示长度(字符长度) + Infonickname:16//个人信息显示长度(字符长度) }; Game_Config.Combat = { - height:80,//战绩页单行高度高度 - up_y:190,//战绩页裁剪y坐标 + height:80,//战绩页单行高度高度 + up_y:190,//战绩页裁剪y坐标 bannerheight:60,//战绩横幅高度 bannery:80,//战绩横幅Y左边(相对48精灵) btnbg:50 @@ -42,46 +44,46 @@ Game_Config.Info = { otherPositionDefault:true,//其他主界面玩家信息(昵称、积分)是否采用默认对齐方式对齐居中点为头像中点 myPositionDefault:true,//其他主界面玩家信息(昵称、积分)是否采用默认对齐方式对齐居中点为头像中点 myPosition:130,//自己信息对齐点(根据游戏界面自行修改) - position:[],//其他主界面玩家信息(昵称、积分)居中对齐的x坐标 注意是其他玩家不包括自己从下家开始 + position:[],//其他主界面玩家信息(昵称、积分)居中对齐的x坐标 注意是其他玩家不包括自己从下家开始 //TextContent:["1","2","3","4","5","6","7"],//常用语内容 - TextContent:["你好","谢谢","再来","快点","不要","加油",":)"],//常用语内容 - TextContentMp3:["","","","","","",""],//常用语对应音效 + TextContent:["你好","2","3","4","5","6","7"],//常用语内容 + TextContentMp3:["","","","","","",""],//常用语对应音效 }; -Game_Config.Share={//分享参数 - appdownload:"",//下载链接(无需配置,从服务器获取) - title:"游戏名",//(分享标题) - description:"",//分享描述 +Game_Config.Share={//分享参数 + appdownload:"",//下载链接(无需配置,从服务器获取) + title:"Test",//(分享标题) + description:"hello world",//分享描述 gameTitle:"",//游戏中的分享标题模板工程会自动将游戏名字分享出去、不必写在这个变量里 - gameDescription:""//游戏中分享描述 + gameDescription:""//游戏中分享描述 }; Game_Config.Chat={//游戏内聊天配置信息 LimitLength:40,//聊天最大长度(字节长度) textwidth:12.5,//聊天显示文字的宽度(未改动聊天显示文字大小无需改动无需修改) ChatDis:[30,12],//聊天气泡与内容的间隔0位置左右间隔(最好不要低于30)1位置上下间隔 - isLeft:[1,0,0,1,1],//聊天气泡是否为以左边为基准线(坐标/基准按各游戏界面调整) - ChatLoc:[[35,517],[1100,315],[1100,105],[175,105],[175,315]]//聊天气泡的基准点位置(注意是基准点位置!)(坐标/基准按各游戏界面调整) + isLeft:[1,0,0,1,1],//聊天气泡是否为以左边为基准线 + ChatLoc:[[35,517],[1100,315],[1100,105],[175,105],[175,315]]//聊天气泡的基准点位置(注意是基准点位置!) }; Game_Config.Voice={//游戏内聊天配置信息 VoiceTime:600,//播放语音动画的时间一般情况无需无需修改 VoiceDis:[30,12],//语音气泡与内容的间隔0位置左右间隔(最好不要低于30)1位置上下间隔 - isLeft:[1,0,0,1,1],//气泡是否为以左边为基准线(坐标/基准按各游戏界面调整) - VoiceLoc:[[35,517],[1100,315],[1100,105],[175,105],[175,315]]//气泡的基准点位置(注意是基准点位置!)(坐标/基准按各游戏界面调整) + isLeft:[1,0,0,1,1],//气泡是否为以左边为基准线 + VoiceLoc:[[35,517],[1100,315],[1100,105],[175,105],[175,315]]//气泡的基准点位置(注意是基准点位置!) }; Game_Config.Setting={ - Ads1:"本游戏仅供娱乐休闲使用,\n道具及虚拟货币不可兑换\n现金或实物,不代表任何\n真实财富价值。", - //Ads2:"\n 或客服号:\n", - board:"",//从后台获取设置无效 + Ads1:"本游戏仅为娱乐休\n闲使用,道具所有\n 游戏通用\n\n游戏问题请联系微\n 信公众号:\n", + //Ads2:"\n 或客服号:\n", + board:"",//从后台获取设置无效 //info:[" 客服信息","QQ:","",""],//客服QQ提醒 - info:[" 客服信息","QQ:","手机:","微信:"],//客服QQ提醒 - board_blength:24,//通知页面一行最大字节数(无需设置) - charge:"充值提示",//充值提示 + info:[" 客服信息","QQ:","手机:","微信:"],//客服QQ提醒 + board_blength:24,//通知页面一行最大字节数(无需设置) + charge:"关注友乐微信公众号充值",//充值提示 }; Game_Config.Protocol={ - x:270,//协议图片初始x坐标 + x:270,//协议图片初始x坐标 y:70,//协议图片初始y坐标 - h:560,//协议图片显示高度 - w:729//协议图片显示宽度 + h:560,//协议图片显示高度 + w:729//协议图片显示宽度 }; Game_Config.Help={//帮助 x:300,//帮助图片初始x坐标 @@ -89,27 +91,27 @@ Game_Config.Help={//帮助 w:729,//帮助图片显示高度 h:450//帮助图片显示宽度 }; -Game_Config.Notice={//滚动公告 - x1:0,//无需设置 - x2:0,//无需设置 - y:0,//无需设置 +Game_Config.Notice={//滚动公告 + x1:0,//无需设置 + x2:0,//无需设置 + y:0,//无需设置 h:0,//无需设置 - //以上参数用来截取滚动公告的显示,截取位置是与滚动公告底大小位置一致 - speed:0.1,//滚动公告的滚动速度 - width:15//滚动公告的内容字体的字节长度(汉字是两个字节) + //以上参数用来截取滚动公告的显示,截取位置是与滚动公告底大小位置一致 + speed:0.1,//滚动公告的滚动速度 + width:15//滚动公告的内容字体的字节长度(汉字是两个字节) }; -Game_Config.Feedback = {//反馈配置 - maxLen:250 //反馈内容最大长度 +Game_Config.Feedback = {//反馈配置 + maxLen:250 //反馈内容最大长度 }; -Game_Config.shakeList ={//摇一摇事件的回调ID、需要添加时在此处添加回调事件写在Utl_Input.js中的Utl.shakeEvent()中 +Game_Config.shakeList ={//摇一摇事件的回调ID、需要添加时在此处添加回调事件写在Utl_Input.js中的Utl.shakeEvent()中 nil:0, startwar:1 }; -Game_Config.soundList ={//声音资源名 - MenuSceneMusic:"",//大厅界面背景音 - MainSceneMusic:""//游戏主界面背景音 +Game_Config.soundList ={//声音资源名 + MenuSceneMusic:"",//大厅界面背景音 + MainSceneMusic:""//游戏主界面背景音 }; -Game_Config.ClickButton = {//需要设置点击音效的按钮(只有有弹窗的按钮设置此音效有效、按钮已经设置好、子游戏不允许修改) +Game_Config.ClickButton = {//需要设置点击音效的按钮(只有有弹窗的按钮设置此音效有效、按钮已经设置好、子游戏不允许修改) src_1:"",//点击时播放的声音资源文件( 不需要播放则不填,下同) src_2:""//弹窗时播放的音效 } @@ -120,11 +122,28 @@ Game_Config.loginButton = {//登录按钮信息 x3:488,//审核版本游客登录按钮x }; Game_Config.sysConfig = { - mainMenuButton:false,//是否进入主菜单界面隐藏四个按钮 - mainScenePlayerInfo:false,//是否隐藏主界面玩家信息 - mainSceneButton:false,//是否隐藏主界面按钮 - shareRoom:false,//接收到星星场是否屏蔽平台框架显示 - changeSeat:false,//是否屏蔽平台自动刷新换座后界面 - hideNotice:false,//隐藏公告栏 - vipInfinite:false,//是否为百人场 + mainMenuButton:false,//是否进入主菜单界面隐藏四个按钮 + mainScenePlayerInfo:false,//是否隐藏主界面玩家信息 + mainSceneButton:false,//是否隐藏主界面按钮 + shareRoom:false,//接收到星星场是否屏蔽平台框架显示 + changeSeat:false,//是否屏蔽平台自动刷新换座后界面 + hideNotice:false,//隐藏公告栏 + vipInfinite:false,//是否为百人场 } + + + + + + + + + + + + + + + + + diff --git a/client/js/gameabc-framework/templates/subgame-entry/01_SubGame_modify.template.js b/client/js/gameabc-framework/templates/subgame-entry/01_SubGame_modify.template.js index 94c2e67..5c7c958 100644 --- a/client/js/gameabc-framework/templates/subgame-entry/01_SubGame_modify.template.js +++ b/client/js/gameabc-framework/templates/subgame-entry/01_SubGame_modify.template.js @@ -46,6 +46,52 @@ Game_Modify.CreateRoomData = { Type_2: 0 }; +// ---------- 玩家信息/头像默认布局(供 02 转发壳 updatePlayerInfoUI 的默认实现使用)---------- +// 02_SubGame_Input.js 的 updatePlayerInfoUI 在【无 SubGameHooks 实现】时提供默认头像等 UI 渲染; +// 转发壳不得引用 codes,故把默认实现所需布局放在此处(Game_Modify 下),与子游戏 codes 内 +// GameView.updatePlayerInfoUI 使用的布局逻辑保持一致。子游戏若自定义头像 UI,则用 hook 覆盖、此配置不生效。 +// POSITIONS[configIndex]:ind0=南(自己)/ind1=东/ind2=北/ind3=西;渲染精灵 346+ind 底框、376+ind 头像框、 +// 406+ind 昵称、436+ind 分数、116+ind 头像图、群组 43+ind。坐标基于设计分辨率 1280x720。 +Game_Modify.PLAYER_INFO_LAYOUT = { + POSITIONS: { + 0: { FRAME_X: 6, FRAME_Y: 592, FRAME_WIDTH: 90, FRAME_HEIGHT: 115, + AVATAR: { OFFSET_X: 5, OFFSET_Y: 5, WIDTH: 80, HEIGHT: 80, + NAME_OFFSET_X: -400, NAME_OFFSET_Y: 888, SCORE_OFFSET_X: 0, SCORE_OFFSET_Y: 88 }, + NAME_CENTER_ALIGN: true }, + 1: { FRAME_X: 1186, FRAME_Y: 85, FRAME_WIDTH: 90, FRAME_HEIGHT: 115, + AVATAR: { OFFSET_X: 5, OFFSET_Y: 5, WIDTH: 80, HEIGHT: 80, + NAME_OFFSET_X: 905, NAME_OFFSET_Y: -888, SCORE_OFFSET_X: 0, SCORE_OFFSET_Y: 88 }, + NAME_CENTER_ALIGN: true }, + 2: { FRAME_X: 1006, FRAME_Y: 5, FRAME_WIDTH: 90, FRAME_HEIGHT: 115, + AVATAR: { OFFSET_X: 5, OFFSET_Y: 5, WIDTH: 80, HEIGHT: 80, + NAME_OFFSET_X: 905, NAME_OFFSET_Y: -888, SCORE_OFFSET_X: 0, SCORE_OFFSET_Y: 88 }, + NAME_CENTER_ALIGN: true }, + 3: { FRAME_X: 7, FRAME_Y: 59, FRAME_WIDTH: 90, FRAME_HEIGHT: 115, + AVATAR: { OFFSET_X: 5, OFFSET_Y: 5, WIDTH: 80, HEIGHT: 80, + NAME_OFFSET_X: -605, NAME_OFFSET_Y: -888, SCORE_OFFSET_X: 0, SCORE_OFFSET_Y: 88 }, + NAME_CENTER_ALIGN: true } + }, + TEXT_STYLE: { NAME_FONT_SIZE: 14, NAME_MAX_LENGTH: 6, SCORE_FONT_SIZE: 12, CHAR_WIDTH: 9 } +}; + +// ---------- 桌面聊天/语音气泡默认布局(供 02 转发壳 ShowChat/gameui_play_voice/gameui_stop_voice 使用)---------- +// 平台默认按固定显示位序取 Game_Config.Chat/Voice 的固定坐标(固定人数模式);此处提供可变人数版: +// 按 updatePlayerInfoUI 的 configIndex(物理位) 定位,使气泡随人数(2/3/4)贴合各玩家。 +// 仅定义每个物理位(0南/1东/2北/3西)的气泡框左上角锚点 X/Y 与朝向 IS_LEFT;气泡内边距/字宽/显示时长等 +// 尺寸复用平台 Game_Config.Chat/Voice/Max(与人数无关)。精灵:聊天 背景552+ind/文字582+ind, +// 语音 背景612+ind/内容642+ind。IS_LEFT=true 气泡向右展开(用 IMG_LEFT)、false 向左展开(用 IMG_RIGHT)。 +// 坐标基于 1280x720,锚点参考 PLAYER_INFO_LAYOUT 各位底框,可按实际界面微调。 +Game_Modify.BUBBLE_LAYOUT = { + IMG_LEFT: 83, // 左向气泡背景图资源ID(气泡向右展开) + IMG_RIGHT: 86, // 右向气泡背景图资源ID(气泡向左展开) + POSITIONS: { + 0: { X: 100, Y: 540, IS_LEFT: true }, // 南(自己) + 1: { X: 1176, Y: 120, IS_LEFT: false }, // 东 + 2: { X: 970, Y: 20, IS_LEFT: false }, // 北 + 3: { X: 120, Y: 70, IS_LEFT: true } // 西 + } +}; + // ---------- 接口转发壳(A 类:无 hook 即 no-op) ---------- Game_Modify.utlmousedown = function (gameid, spid, downx, downy, no1, no2, no3, no4, no5, no6) { diff --git a/client/js/gameabc-framework/templates/subgame-entry/02_SubGame_Input.template.js b/client/js/gameabc-framework/templates/subgame-entry/02_SubGame_Input.template.js index 32d178b..0e11ef2 100644 --- a/client/js/gameabc-framework/templates/subgame-entry/02_SubGame_Input.template.js +++ b/client/js/gameabc-framework/templates/subgame-entry/02_SubGame_Input.template.js @@ -1,7 +1,7 @@ // ============================================================================ -// 02_SubGame_Input.template.js —— 平台输入/回调接口「转发壳」模板(框架维护,子游戏不碰) +// 02_SubGame_Input.js —— 平台输入/回调接口「转发壳」(框架维护,子游戏不碰) // 平台按全局名调用 gameHallImport.* / Game_Modify.*;本文件统一转发到 SubGameHooks 同名 hook。 -// 子游戏只需在 codes/ 的 SubGameHooks 里实现需要的接口(见 SubGameHooks.template.js)。 +// 子游戏只需在 codes/ 的 SubGameHooks 里实现需要的接口(见 codes/SubGameHooks.js)。 // 严格 ES5。接口清单与默认值依据 spec §9。 // ============================================================================ @@ -293,8 +293,210 @@ Game_Modify.getMaxPlayerCount = function (roomtype) { return (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4; }; -// B 类:更新玩家信息 UI,无 hook 返回 false(让平台默认处理) +// 内部辅助(非平台接口):把相对显示位序 relPos 映射为 { ind:精灵槽, configIndex:物理布局位 }。 +// 2/3 人时 ind≠configIndex;无效返回 null。updatePlayerInfoUI 与桌面气泡默认实现共用此映射, +// 保证头像面板与聊天/语音气泡落在同一玩家位。 +Game_Modify._resolveDisplaySlot = function (relPos, playerCount) { + var ind = -1, configIndex = -1; + if (playerCount === 2) { + if (relPos === 0) { ind = 0; configIndex = 0; } + else if (relPos === 1) { ind = 1; configIndex = 2; } + } else if (playerCount === 3) { + if (relPos === 0) { ind = 0; configIndex = 0; } + else if (relPos === 1) { ind = 1; configIndex = 1; } + else if (relPos === 2) { ind = 2; configIndex = 3; } + } else { + if (relPos === 0) { ind = 0; configIndex = 0; } + else if (relPos === 1) { ind = 1; configIndex = 1; } + else if (relPos === 2) { ind = 2; configIndex = 2; } + else if (relPos === 3) { ind = 3; configIndex = 3; } + } + if (ind === -1) return null; + return { ind: ind, configIndex: configIndex }; +}; + +// B 类:更新指定座位的玩家信息 UI(昵称/分数/头像)。 +// 有 hook 则委托子游戏;无 hook 时由本模板提供默认头像等 UI 的显示逻辑,其逻辑与子游戏 +// codes 内 GameView.updatePlayerInfoUI 保持一致,布局取自 Game_Modify.PLAYER_INFO_LAYOUT(见 01)。 +// 精灵操作一律经框架 SpriteManager(setPosition/setSize/setText/show|hideGroup),不直接调 +// set_self/set_group 等引擎原语;头像加载走平台 Func.up_imgurl(非精灵原语,SpriteManager 无对应能力)。 +// 不引用任何 codes 模块。平台 GameUI.updatePlayerInfoUI 会对每个座位逐一调用本接口,故按单座位渲染。 Game_Modify.updatePlayerInfoUI = function (targetSeat) { if (window.SubGameHooks && SubGameHooks.updatePlayerInfoUI) return SubGameHooks.updatePlayerInfoUI(targetSeat); - return false; + + // ---- 模板默认:与 GameView.updatePlayerInfoUI 一致的单座位渲染 ---- + if (typeof Desk === 'undefined' || typeof C_Player === 'undefined' || typeof SpriteManager === 'undefined') return false; + var layout = Game_Modify.PLAYER_INFO_LAYOUT; + if (!layout || !layout.POSITIONS) return false; + if (!Desk.PlayerList || targetSeat < 0 || targetSeat >= Desk.PlayerList.length) return false; + + var selfSeat = (typeof C_Player.seat === 'number') ? C_Player.seat : 0; + var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4; + var relPos = (targetSeat - selfSeat + playerCount) % playerCount; + + // 显示槽 ind 与布局位 configIndex(2/3 人时两者不同) + var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount); + if (!slot) return false; + var ind = slot.ind, configIndex = slot.configIndex; + + var player = Desk.PlayerList[targetSeat]; + // 空座位:隐藏该位玩家信息群组 + if (!player || !player.playerid || player.playerid === -1) { + SpriteManager.hideGroup(43 + ind); + return true; + } + + var posConfig = layout.POSITIONS[configIndex]; + if (!posConfig) return false; + + // 底框(346+ind) + if (posConfig.FRAME_X !== undefined) { + SpriteManager.setPosition(346 + ind, posConfig.FRAME_X, posConfig.FRAME_Y); + SpriteManager.setSize(346 + ind, posConfig.FRAME_WIDTH, posConfig.FRAME_HEIGHT); + } + + // 头像框(376+ind):基于底框 + 相对偏移 + var avatarX = posConfig.FRAME_X + posConfig.AVATAR.OFFSET_X; + var avatarY = posConfig.FRAME_Y + posConfig.AVATAR.OFFSET_Y; + var avatarWidth = posConfig.AVATAR.WIDTH; + var avatarHeight = posConfig.AVATAR.HEIGHT; + var nameOffsetX = posConfig.AVATAR.NAME_OFFSET_X || 0; + var nameOffsetY = posConfig.AVATAR.NAME_OFFSET_Y || 0; + var scoreOffsetX = posConfig.AVATAR.SCORE_OFFSET_X || 0; + var scoreOffsetY = posConfig.AVATAR.SCORE_OFFSET_Y || 0; + SpriteManager.setPosition(376 + ind, avatarX, avatarY); + SpriteManager.setSize(376 + ind, avatarWidth, avatarHeight); + + var textStyle = layout.TEXT_STYLE || {}; + var maxLen = textStyle.NAME_MAX_LENGTH || 8; + var charWidth = textStyle.CHAR_WIDTH || 7; + + // 昵称(406+ind) + var nickname = Func.subString(player.nickname || '', maxLen, true); + SpriteManager.setText(406 + ind, nickname); + var nameX = avatarX + nameOffsetX; + if (posConfig.NAME_CENTER_ALIGN) { + var textWidth = (typeof nickname.gblen === 'function') ? nickname.gblen() * charWidth : nickname.length * charWidth; + nameX = avatarX + avatarWidth / 2 - textWidth / 2; + } + SpriteManager.setPosition(406 + ind, nameX, avatarY + nameOffsetY); + + // 分数(436+ind) + var score = (typeof player.score === 'number') ? player.score : 0; + SpriteManager.setText(436 + ind, score); + var scoreX = avatarX + scoreOffsetX; + if (posConfig.NAME_CENTER_ALIGN) { + var scoreWidth = String(score).length * charWidth; + scoreX = avatarX + avatarWidth / 2 - scoreWidth / 2; + } + SpriteManager.setPosition(436 + ind, scoreX, avatarY + scoreOffsetY); + + // 头像图(116+ind):Func.up_imgurl 为平台头像加载接口(非引擎精灵原语) + if (player.avatar && typeof Func !== 'undefined' && typeof Func.up_imgurl === 'function') { + Func.up_imgurl(116 + ind, player.avatar); + } + + // 显示该座位玩家信息群组 + SpriteManager.showGroup(43 + ind); + return true; }; +// 桌面文字聊天气泡:有 hook 委托子游戏;无 hook 时按【可变人数】默认渲染,使气泡贴合各玩家。 +// seat 为绝对座位;经 SpriteManager 操作精灵(背景552+ind/文字582+ind),位置取自 Game_Modify.BUBBLE_LAYOUT +// 的物理位配置,尺寸(内边距/字宽/显示时长)复用 Game_Config.Chat/Max;不直接调引擎原语、不引用 codes。 +Game_Modify.ShowChat = function (seat, text) { + if (window.SubGameHooks && SubGameHooks.ShowChat) return SubGameHooks.ShowChat(seat, text); + GameUI.CloseChat(); + if (typeof Desk === 'undefined' || typeof C_Player === 'undefined' || typeof SpriteManager === 'undefined') return; + var layout = Game_Modify.BUBBLE_LAYOUT; + if (!layout || !layout.POSITIONS) return; + var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4; + var relPos = (seat - C_Player.seat + playerCount) % playerCount; + var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount); + if (!slot) return; + var pos = layout.POSITIONS[slot.configIndex]; + if (!pos) return; + var ind = slot.ind; + + text = String(text); + var chat = Game_Config.Chat || {}; + var dis_x = (chat.ChatDis && chat.ChatDis[0]) || 0; + var dis_y = (chat.ChatDis && chat.ChatDis[1]) || 0; + var text_w = chat.textwidth || 14; + var text_len = (typeof text.gblen === 'function') ? text.gblen() : text.length; + var bgW = text_len * text_w + dis_x * 2; + + SpriteManager.setText(582 + ind, text); + if (pos.IS_LEFT) { + SpriteManager.setPosition(552 + ind, pos.X, pos.Y); + SpriteManager.setPosition(582 + ind, pos.X + dis_x, pos.Y + dis_y); + SpriteManager.setImage(552 + ind, layout.IMG_LEFT); + } else { + SpriteManager.setPosition(552 + ind, pos.X - bgW, pos.Y); + SpriteManager.setPosition(582 + ind, pos.X - text_len * text_w - dis_x, pos.Y + dis_y); + SpriteManager.setImage(552 + ind, layout.IMG_RIGHT); + } + SpriteManager.setWidth(552 + ind, bgW); + SpriteManager.show(552 + ind); + SpriteManager.show(582 + ind); + + // 自动隐藏:复用平台配置的显示时长(观感与固定人数版一致),按槽位去重定时器 + var dur = (Game_Config.Max && Game_Config.Max.ShowChat) || 3000; + Game_Modify._chatHideTimers = Game_Modify._chatHideTimers || {}; + if (Game_Modify._chatHideTimers[ind]) { clearTimeout(Game_Modify._chatHideTimers[ind]); } + Game_Modify._chatHideTimers[ind] = setTimeout(function () { + SpriteManager.hide(552 + ind); + SpriteManager.hide(582 + ind); + Game_Modify._chatHideTimers[ind] = null; + }, dur); +}; + +// 桌面语音气泡(播放):有 hook 委托子游戏;无 hook 时按【可变人数】默认渲染。 +// uiIndex 已是相对显示位序(relPos);经 SpriteManager 操作精灵(背景612+ind/内容642+ind), +// 位置取自 Game_Modify.BUBBLE_LAYOUT,气泡宽度依据内容精灵当前宽度;尺寸复用 Game_Config.Voice。 +Game_Modify.gameui_play_voice = function (uiIndex) { + if (window.SubGameHooks && SubGameHooks.gameui_play_voice) return SubGameHooks.gameui_play_voice(uiIndex); + if (typeof SpriteManager === 'undefined') return; + var layout = Game_Modify.BUBBLE_LAYOUT; + if (!layout || !layout.POSITIONS) return; + var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4; + var relPos = ((Number(uiIndex) % playerCount) + playerCount) % playerCount; + var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount); + if (!slot) return; + var pos = layout.POSITIONS[slot.configIndex]; + if (!pos) return; + var ind = slot.ind; + + var voice = Game_Config.Voice || {}; + var dis_x = (voice.VoiceDis && voice.VoiceDis[0]) || 0; + var dis_y = (voice.VoiceDis && voice.VoiceDis[1]) || 0; + var contentSize = SpriteManager.getSize(642 + ind); + var text_len = (contentSize && typeof contentSize.width === 'number') ? contentSize.width : 0; + var bgW = text_len + dis_x * 2; + + if (pos.IS_LEFT) { + SpriteManager.setPosition(612 + ind, pos.X, pos.Y); + SpriteManager.setPosition(642 + ind, pos.X + dis_x, pos.Y + dis_y); + SpriteManager.setImage(612 + ind, layout.IMG_LEFT); + } else { + SpriteManager.setPosition(612 + ind, pos.X - bgW, pos.Y); + SpriteManager.setPosition(642 + ind, pos.X - text_len - dis_x, pos.Y + dis_y); + SpriteManager.setImage(612 + ind, layout.IMG_RIGHT); + } + SpriteManager.setWidth(612 + ind, bgW); + SpriteManager.show(612 + ind); + SpriteManager.show(642 + ind); + play_ani(1, 642 + ind, 43, 1, 3, 0, Game_Config.Voice.VoiceTime, 0, 0, 0, 0, 0, 0); +}; + +// 桌面语音气泡(停止):有 hook 委托子游戏;无 hook 时隐藏对应槽位的语音气泡。 +Game_Modify.gameui_stop_voice = function (uiIndex) { + if (window.SubGameHooks && SubGameHooks.gameui_stop_voice) return SubGameHooks.gameui_stop_voice(uiIndex); + if (typeof SpriteManager === 'undefined') return; + var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4; + var relPos = ((Number(uiIndex) % playerCount) + playerCount) % playerCount; + var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount); + if (!slot) return; + var ind = slot.ind; + SpriteManager.hide(612 + ind); + SpriteManager.hide(642 + ind); +}; \ No newline at end of file diff --git a/client/js/gameabc-framework/ui/BaseComponent.js b/client/js/gameabc-framework/ui/BaseComponent.js index b8fe9e0..99c1248 100644 --- a/client/js/gameabc-framework/ui/BaseComponent.js +++ b/client/js/gameabc-framework/ui/BaseComponent.js @@ -241,7 +241,7 @@ var BaseComponent = (function() { this.isDestroyed = false; this.isInitialized = true; - console.log('🎨 BaseComponent: 初始化组件 "' + this.name + '" (图层: ' + this.layer + ')'); + // // console.log('🎨 BaseComponent: 初始化组件 "' + this.name + '" (图层: ' + this.layer + ')'); // 调用子类的init方法 try { @@ -274,7 +274,7 @@ var BaseComponent = (function() { return; } - console.log('🙈 BaseComponent: 隐藏组件 "' + this.name + '" 的所有精灵 (数量: ' + this.sprites.length + ')'); + // console.log('🙈 BaseComponent: 隐藏组件 "' + this.name + '" 的所有精灵 (数量: ' + this.sprites.length + ')'); for (var i = 0; i < this.sprites.length; i++) { var spriteId = this.sprites[i]; @@ -293,7 +293,7 @@ var BaseComponent = (function() { */ init: function(config) { // 子类覆盖此方法 - console.log('📝 BaseComponent.init: 请在子类中覆盖此方法'); + // console.log('📝 BaseComponent.init: 请在子类中覆盖此方法'); }, /** @@ -312,11 +312,11 @@ var BaseComponent = (function() { } if (this.isVisible) { - console.log('ℹ️ BaseComponent.show: 组件已可见,跳过:', this.name); + // console.log('ℹ️ BaseComponent.show: 组件已可见,跳过:', this.name); return true; } - console.log('👁️ BaseComponent: 显示组件 "' + this.name + '" (图层: ' + this.layer + ')'); + // console.log('👁️ BaseComponent: 显示组件 "' + this.name + '" (图层: ' + this.layer + ')'); // 显示图层 SpriteManager.showGroup(this.layer); @@ -344,11 +344,11 @@ var BaseComponent = (function() { } if (!this.isVisible) { - console.log('ℹ️ BaseComponent.hide: 组件已隐藏,跳过:', this.name); + // console.log('ℹ️ BaseComponent.hide: 组件已隐藏,跳过:', this.name); return true; } - console.log('🙈 BaseComponent: 隐藏组件 "' + this.name + '" (图层: ' + this.layer + ')'); + // console.log('🙈 BaseComponent: 隐藏组件 "' + this.name + '" (图层: ' + this.layer + ')'); // 隐藏图层 SpriteManager.hideGroup(this.layer); @@ -375,7 +375,7 @@ var BaseComponent = (function() { return false; } - console.log('💥 BaseComponent: 销毁组件 "' + this.name + '"'); + // console.log('💥 BaseComponent: 销毁组件 "' + this.name + '"'); // 移除所有事件监听 this._removeAllEventListeners(); @@ -447,7 +447,7 @@ var BaseComponent = (function() { // 记录监听器 this.eventListeners[eventName] = wrappedHandler; - console.log('📡 BaseComponent: 组件 "' + this.name + '" 注册事件:', eventName); + // console.log('📡 BaseComponent: 组件 "' + this.name + '" 注册事件:', eventName); return true; }, @@ -467,7 +467,7 @@ var BaseComponent = (function() { EventBus.off(eventName, handler); delete this.eventListeners[eventName]; - console.log('📴 BaseComponent: 组件 "' + this.name + '" 移除事件:', eventName); + // console.log('📴 BaseComponent: 组件 "' + this.name + '" 移除事件:', eventName); return true; }, @@ -483,7 +483,7 @@ var BaseComponent = (function() { return; } - console.log('📤 BaseComponent: 组件 "' + this.name + '" 触发事件:', eventName); + // console.log('📤 BaseComponent: 组件 "' + this.name + '" 触发事件:', eventName); EventBus.emit(eventName, data); }, @@ -511,7 +511,7 @@ var BaseComponent = (function() { } this.sprites.push(spriteId); - // console.log('➕ BaseComponent: 组件 "' + this.name + '" 添加精灵:', spriteId); + // // console.log('➕ BaseComponent: 组件 "' + this.name + '" 添加精灵:', spriteId); return true; }, @@ -529,7 +529,7 @@ var BaseComponent = (function() { } this.sprites.splice(index, 1); - console.log('➖ BaseComponent: 组件 "' + this.name + '" 移除精灵:', spriteId); + // console.log('➖ BaseComponent: 组件 "' + this.name + '" 移除精灵:', spriteId); return true; }, @@ -596,7 +596,7 @@ var BaseComponent = (function() { */ printState: function() { var state = this.getState(); - console.log('📊 组件状态:', JSON.stringify(state, null, 2)); + // console.log('📊 组件状态:', JSON.stringify(state, null, 2)); } }; diff --git a/client/js/gameabc-framework/ui/DynamicSpriteList.js b/client/js/gameabc-framework/ui/DynamicSpriteList.js index 9bc3d2a..3c71ec8 100644 --- a/client/js/gameabc-framework/ui/DynamicSpriteList.js +++ b/client/js/gameabc-framework/ui/DynamicSpriteList.js @@ -84,7 +84,21 @@ * scrollSensitivity: 5, // 移动5px以上才触发滚动 * bounceSpeed: 1 // 回弹速度 * }); - * + * + * 【横向列表(左右滑动)】 + * var themeList = new DynamicSpriteList({ + * containerId: sprites.LIST_CONTAINER, + * clipArea: { x: 340, y: 240, width: 600, height: 160 }, + * orientation: 'horizontal', // 默认 'vertical' + * itemWidth: 262, // 主轴步长(项宽 + 项间距),与纵向 rowHeight 对称 + * renderRow: function (ctx) { + * // 横向下 ctx.addSprite 的 x 会叠加该项的主轴基准,y 原样 + * var sid = ctx.addSprite('preview', TPL_ID, 0, 0); + * } + * }); + * // 事件转发:横向传 offmovex(纵向传 offmovey) + * themeList.handleMouseMove(event.spriteId, event.offset.x); + * * 【设置数据(触发渲染)】 * // 数据数组中每个元素对应一行 * // setData 会清除旧行、重新创建新行 @@ -176,6 +190,26 @@ * } * } */ +/** + * 主轴/交叉轴的引擎操作码与 clipArea 字段映射 + * 前缀 DSL_ 是必要的:友乐运行时所有