/** * 初始化 start */ "use strict"; // /** // * @type {CoreMixin} // */ // const core = (() => { function core () { this._WIDTH_ = 15; this._HEIGHT_ = 15; this._PX_ = this._WIDTH_ * 32; this._PY_ = this._HEIGHT_ * 32; this._HALF_WIDTH_ = Math.floor(this._WIDTH_ / 2); this._HALF_HEIGHT_ = Math.floor(this._HEIGHT_ / 2); this.__SIZE__ = main.mode == 'editor' ? 15 : this._HEIGHT_; this.__PIXELS__ = this.__SIZE__ * 32; this.__HALF_SIZE__ = Math.floor(this.__SIZE__ / 2); this.material = { 'animates': {}, 'images': {}, 'bgms': {}, 'sounds': {}, 'items': {}, 'enemys': {}, 'icons': {}, 'ground': null, 'grundCanvas': null, 'groundPattern': null, 'autotileEdges': {}, } this.timeout = { 'turnHeroTimeout': null, 'onDownTimeout': null, 'sleepTimeout': null, } this.interval = { 'heroMoveInterval': null, 'onDownInterval': null, } this.animateFrame = { 'totalTime': 0, 'totalTimeStart': 0, 'globalAnimate': false, 'globalTime': 0, 'selectorTime': 0, 'selectorUp': true, 'animateTime': 0, 'moveTime': 0, 'lastLegTime': 0, 'leftLeg': true, 'weather': { 'time': 0, 'type': null, 'level': 1, 'nodes': [], 'data': null, 'fog': null, 'cloud': null, 'sun': null }, "tip": null, "asyncId": {}, "lastAsyncId": null } this.musicStatus = { 'audioContext': null, // WebAudioContext 'bgmStatus': false, // 是否播放BGM 'soundStatus': true, // 是否播放SE 'playingBgm': null, // 正在播放的BGM 'pauseTime': 0, // 上次暂停的时间 'lastBgm': null, // 上次播放的bgm 'gainNode': null, 'playingSounds': {}, // 正在播放的SE 'userVolume': 1.0, // 用户音量 'designVolume': 1.0, //设计音量 'bgmSpeed': 100, // 背景音乐速度 'bgmUsePitch': null, // 是否同时修改音调 'cachedBgms': [], // 缓存BGM内容 'cachedBgmCount': 8, // 缓存的bgm数量 } this.platform = { 'isOnline': true, // 是否http 'isPC': true, // 是否是PC 'isAndroid': false, // 是否是Android 'isIOS': false, // 是否是iOS 'string': 'PC', 'isWeChat': false, // 是否是微信 'isQQ': false, // 是否是QQ 'isChrome': false, // 是否是Chrome 'supportCopy': false, // 是否支持复制到剪切板 'fileInput': null, // FileInput 'fileReader': null, // 是否支持FileReader 'successCallback': null, // 读取成功 'errorCallback': null, // 读取失败 } // 样式 this.domStyle = { scale: 1.0, ratio: 1.0, hdCanvas: ["damage", "ui", "data"], availableScale: [], isVertical: false, showStatusBar: true, toolbarBtn: false, } this.bigmap = { canvas: ["bg", "event", "event2", "fg", "damage"], offsetX: 0, // in pixel offsetY: 0, posX: 0, // posY: 0, width: main.mode == 'editor' ? this.__SIZE__ : this._WIDTH_, // map width and height height: main.mode == 'editor' ? this.__SIZE__ : this._HEIGHT_, v2: false, threshold: 1024, extend: 10, scale: 1.0, tempCanvas: null, // A temp canvas for drawing cacheCanvas: null, // A cache canvas } this.saves = { "saveIndex": null, "ids": {}, "autosave": { "data": null, "time": 0, "updated": false, "storage": true, // 是否把自动存档写入文件a "max": 20, // 自动存档最大回退数 "now": 0, }, "favorite": [], "favoriteName": {}, "cache": {} } this.initStatus = { 'played': false, 'gameOver': false, // 勇士属性 'hero': {}, 'heroCenter': { 'px': null, 'py': null }, // 当前地图 'floorId': null, 'thisMap': null, 'maps': null, 'bgmaps': {}, 'fgmaps': {}, 'mapBlockObjs': {}, 'checkBlock': {}, // 每个点的阻激夹域信息 'damage': { // 每个点的显伤绘制 'posX': 0, 'posY': 0, 'data': [], 'extraData': [], }, 'lockControl': false, // 勇士移动状态 'heroMoving': 0, 'heroStop': true, // 自动寻路相关 'automaticRoute': { 'autoHeroMove': false, 'autoStep': 0, 'movedStep': 0, 'destStep': 0, 'destX': null, 'destY': null, 'offsetX': null, 'offsetY': null, 'autoStepRoutes': [], 'moveStepBeforeStop': [], 'lastDirection': null, 'cursorX': 0, 'cursorY': 0, "moveDirectly": false, }, // 按下键的时间:为了判定双击 'downTime': null, 'ctrlDown': false, 'preview': { 'enabled': false, 'prepareDragging': false, 'dragging': false, 'px': 0, 'py': 0, }, // 路线&回放 'route': [], 'replay': { 'replaying': false, 'pausing': false, 'animate': false, // 正在某段动画中 'failed': false, 'toReplay': [], 'totalList': [], 'speed': 1.0, 'steps': 0, 'save': [], }, // 录像折叠 'routeFolding': {}, // event事件 'shops': {}, 'event': { 'id': null, 'data': null, 'selection': null, 'ui': null, 'interval': null, }, 'autoEvents': [], 'textAttribute': { 'position': "center", "offset": 0, "title": [255, 215, 0, 1], "background": [0, 0, 0, 0.85], "text": [255, 255, 255, 1], "titlefont": 22, "textfont": 16, "bold": false, "time": 0, "letterSpacing": 0, "animateTime": 0, }, "globalAttribute": { 'equipName': main.equipName || [], "statusLeftBackground": main.styles.statusLeftBackground || "url(project/materials/ground.png) repeat", "statusTopBackground": main.styles.statusTopBackground || "url(project/materials/ground.png) repeat", "toolsBackground": main.styles.toolsBackground || "url(project/materials/ground.png) repeat", "borderColor": main.styles.borderColor || [204, 204, 204, 1], "statusBarColor": main.styles.statusBarColor || [255, 255, 255, 1], "floorChangingStyle": main.styles.floorChangingStyle || "background-color: black; color: white", "selectColor": main.styles.selectColor || [255, 215, 0, 1], "font": main.styles.font || "Verdana" }, 'curtainColor': null, // 动画 'globalAnimateObjs': [], 'floorAnimateObjs': [], 'boxAnimateObjs': [], 'autotileAnimateObjs': [], "globalAnimateStatus": 0, 'animateObjs': [], }; // 标记的楼层列表,用于数据统计 this.markedFloorIds = {}; this.status = {}; this.dymCanvas = {}; if (main.mode == 'editor') { document.documentElement.style.setProperty('--size', this.__SIZE__); document.documentElement.style.setProperty('--pixel', this.__PIXELS__ + 'px'); } } /////////// 系统事件相关 /////////// ////// 初始化 ////// core.prototype.init = function (coreData, callback) { this._forwardFuncs(); for (var key in coreData) core[key] = coreData[key]; this._init_flags(); this._init_platform(); this._init_others(); this._init_plugins(); var b = main.mode == 'editor'; // 初始化画布 for (var name in core.canvas) { if (core.domStyle.hdCanvas.indexOf(name) >= 0) core.maps._setHDCanvasSize(core.canvas[name], b ? core.__PIXELS__ : core._PX_, b ? core.__PIXELS__ : core._PY_); else { core.canvas[name].canvas.width = (b ? core.__PIXELS__ : core._PX_); core.canvas[name].canvas.height = (b ? core.__PIXELS__ : core._PY_); } } core.loader._load(function () { core.extensions._load(function () { core._afterLoadResources(callback); }); }); core.dom.musicBtn.style.display = 'block'; core.setMusicBtn(); } core.prototype._init_flags = function () { core.flags = core.clone(core.data.flags); core.values = core.clone(core.data.values); core.firstData = core.clone(core.data.firstData); this._init_sys_flags(); // 让你总是拼错! window.on = true; window.off = false; window.ture = true; window.flase = false; core.dom.versionLabel.innerText = core.firstData.version; core.dom.logoLabel.innerText = core.firstData.title; document.title = core.firstData.title + " - HTML5魔塔"; document.getElementById("startLogo").innerText = core.firstData.title; (core.firstData.shops || []).forEach(function (t) { core.initStatus.shops[t.id] = t; }); core.maps._initFloors(); // 初始化怪物、道具等 core.material.enemys = core.enemys.getEnemys(); core.material.items = core.items.getItems(); core.material.icons = core.icons.getIcons(); // 初始化自动事件 for (var floorId in core.floors) { var autoEvents = core.floors[floorId].autoEvent || {}; for (var loc in autoEvents) { var locs = loc.split(","), x = parseInt(locs[0]), y = parseInt(locs[1]); for (var index in autoEvents[loc]) { var autoEvent = core.clone(autoEvents[loc][index]); if (autoEvent && autoEvent.condition && autoEvent.data) { autoEvent.floorId = floorId; autoEvent.x = x; autoEvent.y = y; autoEvent.index = index; autoEvent.symbol = floorId + "@" + x + "@" + y + "@" + index; autoEvent.condition = core.replaceValue(autoEvent.condition); autoEvent.data = core.precompile(autoEvent.data); core.initStatus.autoEvents.push(autoEvent); } } } } // 道具的穿上/脱下,视为自动事件 for (var equipId in core.material.items) { var equip = core.material.items[equipId]; if (equip.cls != 'equips' || !equip.equip) continue; if (!equip.equip.equipEvent && !equip.equip.unequipEvent) continue; var equipFlag = '_equipEvent_' + equipId; var autoEvent1 = { symbol: "_equipEvent_" + equipId, currentFloor: false, multiExecute: true, condition: "core.hasEquip('" + equipId + "') && !core.hasFlag('" + equipFlag + "')", data: core.precompile([{ "type": "setValue", "name": "flag:" + equipFlag, "value": "true" }].concat(equip.equip.equipEvent || [])), }; var autoEvent2 = { symbol: "_unequipEvent_" + equipId, currentFloor: false, multiExecute: true, condition: "!core.hasEquip('" + equipId + "') && core.hasFlag('" + equipFlag + "')", data: core.precompile([{ "type": "setValue", "name": "flag:" + equipFlag, "value": "null" }].concat(equip.equip.unequipEvent || [])), }; core.initStatus.autoEvents.push(autoEvent1); core.initStatus.autoEvents.push(autoEvent2); } core.initStatus.autoEvents.sort(function (e1, e2) { if (e1.floorId == null) return 1; if (e2.floorId == null) return -1; if (e1.priority != e2.priority) return e2.priority - e1.priority; if (e1.floorId != e2.floorId) return core.floorIds.indexOf(e1.floorId) - core.floorIds.indexOf(e2.floorId); if (e1.x != e2.x) return e1.x - e2.x; if (e1.y != e2.y) return e1.y - e2.y; return e1.index - e2.index; }) } core.prototype._init_sys_flags = function () { if (core.flags.equipboxButton) core.flags.equipment = true; core.flags.displayEnemyDamage = core.getLocalStorage('enemyDamage', true); core.flags.displayCritical = core.getLocalStorage('critical', true); core.flags.displayExtraDamage = core.getLocalStorage('extraDamage', true); core.flags.enableEnemyPoint = core.getLocalStorage('enableEnemyPoint', core.flags.enableEnemyPoint); core.flags.leftHandPrefer = core.getLocalStorage('leftHandPrefer', false); core.flags.extraDamageType = core.getLocalStorage('extraDamageType', 2); // 行走速度 core.values.moveSpeed = core.getLocalStorage('moveSpeed', core.values.moveSpeed || 100); core.values.floorChangeTime = core.getLocalStorage('floorChangeTime', core.values.floorChangeTime); if (core.values.floorChangeTime == null) core.values.floorChangeTime = 500; core.flags.enableHDCanvas = core.getLocalStorage('enableHDCanvas', !core.platform.isIOS); } core.prototype._init_platform = function () { core.platform.isOnline = location.protocol.indexOf("http") == 0; if (!core.platform.isOnline) alert("请勿直接打开html文件!使用启动服务或者APP进行离线游戏。"); window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext; core.musicStatus.bgmStatus = core.getLocalStorage('bgmStatus', true); core.musicStatus.soundStatus = core.getLocalStorage('soundStatus', true); //新增 userVolume 默认值0.7 core.musicStatus.userVolume = core.getLocalStorage('userVolume', 0.7); try { core.musicStatus.audioContext = new window.AudioContext(); core.musicStatus.gainNode = core.musicStatus.audioContext.createGain(); core.musicStatus.gainNode.gain.value = core.musicStatus.userVolume; core.musicStatus.gainNode.connect(core.musicStatus.audioContext.destination); } catch (e) { console.log("该浏览器不支持AudioContext"); core.musicStatus.audioContext = null; } ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"].forEach(function (t) { if (navigator.userAgent.indexOf(t) >= 0) { if (t == 'iPhone' || t == 'iPad' || t == 'iPod') core.platform.isIOS = true; if (t == 'Android') core.platform.isAndroid = true; core.platform.isPC = false; } }); core.platform.string = core.platform.isPC ? "PC" : core.platform.isAndroid ? "Android" : core.platform.isIOS ? "iOS" : ""; core.platform.supportCopy = document.queryCommandSupported && document.queryCommandSupported("copy"); var chrome = /Chrome\/(\d+)\./i.exec(navigator.userAgent); if (chrome && parseInt(chrome[1]) >= 50) core.platform.isChrome = true; core.platform.isSafari = /Safari/i.test(navigator.userAgent) && !/Chrome/i.test(navigator.userAgent); core.platform.isQQ = /QQ/i.test(navigator.userAgent); core.platform.isWeChat = /MicroMessenger/i.test(navigator.userAgent); if (window.FileReader) { core.platform.fileReader = new FileReader(); core.platform.fileReader.onload = function () { core.readFileContent(core.platform.fileReader.result); }; core.platform.fileReader.onerror = function () { if (core.platform.errorCallback) core.platform.errorCallback(); } } core.flags.enableHDCanvas = core.getLocalStorage('enableHDCanvas', !core.platform.isIOS); if (main.mode != 'editor') { core.domStyle.scale = core.getLocalStorage('scale', 1); if (core.flags.enableHDCanvas) core.domStyle.ratio = Math.max(window.devicePixelRatio || 1, core.domStyle.scale); } } core.prototype._init_others = function () { // 一些额外的东西 core.material.groundCanvas = document.createElement('canvas').getContext('2d'); core.material.groundCanvas.canvas.width = core.material.groundCanvas.canvas.height = 32; core.material.groundPattern = core.material.groundCanvas.createPattern(core.material.groundCanvas.canvas, 'repeat'); core.bigmap.tempCanvas = document.createElement('canvas').getContext('2d'); core.bigmap.cacheCanvas = document.createElement('canvas').getContext('2d'); core.loadImage("materials", 'fog', function (name, img) { core.animateFrame.weather.fog = img; }); core.loadImage("materials", "cloud", function (name, img) { core.animateFrame.weather.cloud = img; }) core.loadImage("materials", "sun", function (name, img) { core.animateFrame.weather.sun = img; }) core.loadImage("materials", 'keyboard', function (name, img) { core.material.images.keyboard = img; }); // 记录存档编号 core.saves.saveIndex = core.getLocalStorage('saveIndex', 1); core.control.getSaveIndexes(function (indexes) { core.saves.ids = indexes; }); } core.prototype._afterLoadResources = function (callback) { // 初始化地图 core.initStatus.maps = core.maps._initMaps(); core.control._setRequestAnimationFrame(); // 图片裁剪 (main.splitImages || []).forEach(function (one) { var name = core.getMappedName(one.name); if (!core.material.images.images[name]) { console.warn('找不到图片:' + name + ',无法裁剪'); return; } if (!name.endsWith('.png')) { console.warn('无法裁剪非png格式图片:' + name); return; } var arr = core.splitImage(core.material.images.images[name], one.width, one.height); for (var i = 0; i < arr.length; ++i) { core.material.images.images[(one.prefix || "") + i + '.png'] = arr[i]; } }); if (core.plugin._afterLoadResources) core.plugin._afterLoadResources(); core.showStartAnimate(); if (callback) callback(); } core.prototype._init_plugins = function () { core.plugin = new function () { }; for (var name in plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1) { if (plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1[name] instanceof Function) { try { plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1[name].apply(core.plugin); } catch (e) { console.error(e); console.error("无法初始化插件" + name); } } } core._forwardFunc("plugin"); } core.prototype._forwardFuncs = function () { for (var i = 0; i < main.loadList.length; ++i) { var name = main.loadList[i]; if (name == 'core') continue; this._forwardFunc(name); } } core.prototype._forwardFunc = function (name, funcname) { if (funcname == null) { for (funcname in core[name]) { if (funcname.charAt(0) != "_" && core[name][funcname] instanceof Function) { this._forwardFunc(name, funcname); } } return; } if (core[funcname]) { console.error("ERROR: 无法转发 " + name + " 中的函数 " + funcname + " 到 core 中!同名函数已存在。"); return; } var parameterInfo = /^\s*function\s*[\w_$]*\(([\w_,$\s]*)\)\s*\{/.exec(core[name][funcname].toString()); var parameters = (parameterInfo == null ? "" : parameterInfo[1]).replace(/\s*/g, '').replace(/,/g, ', '); // core[funcname] = new Function(parameters, "return core."+name+"."+funcname+"("+parameters+");"); eval("core." + funcname + " = function (" + parameters + ") {\n\treturn core." + name + "." + funcname + ".apply(core." + name + ", arguments);\n}"); } core.prototype.doFunc = function (func, _this) { if (typeof func == 'string') { func = core.plugin[func]; _this = core.plugin; } return func.apply(_this, Array.prototype.slice.call(arguments, 2)); } // return new Core(); // })(); var core = new core();