mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-10-09 03:45:23 +00:00
[adapters] 增加小游戏适配部分源码
This commit is contained in:
471
adapters/common/engine/AssetManager.js
Normal file
471
adapters/common/engine/AssetManager.js
Normal file
@@ -0,0 +1,471 @@
|
||||
const cacheManager = require('../cache-manager');
|
||||
const { fs, downloadFile, readText, readArrayBuffer, readJson, loadSubpackage, getUserDataPath, exists } = window.fsUtils;
|
||||
|
||||
const REGEX = /^https?:\/\/.*/;
|
||||
const cachedSubpackageList = {};
|
||||
const downloader = cc.assetManager.downloader;
|
||||
const parser = cc.assetManager.parser;
|
||||
const presets = cc.assetManager.presets;
|
||||
const isSubDomain = __globalAdapter.isSubContext;
|
||||
downloader.maxConcurrency = 8;
|
||||
downloader.maxRequestsPerFrame = 64;
|
||||
presets['scene'].maxConcurrency = 10;
|
||||
presets['scene'].maxRequestsPerFrame = 64;
|
||||
|
||||
let SUBCONTEXT_ROOT, REMOTE_SERVER_ROOT;
|
||||
let subpackages = {}, remoteBundles = {};
|
||||
|
||||
function downloadScript (url, options, onComplete) {
|
||||
if (typeof options === 'function') {
|
||||
onComplete = options;
|
||||
options = null;
|
||||
}
|
||||
if (REGEX.test(url)) {
|
||||
onComplete && onComplete(new Error('Can not load remote scripts'));
|
||||
}
|
||||
else {
|
||||
__cocos_require__(url);
|
||||
onComplete && onComplete(null);
|
||||
}
|
||||
}
|
||||
|
||||
function handleZip (url, options, onComplete) {
|
||||
let cachedUnzip = cacheManager.cachedFiles.get(url);
|
||||
if (cachedUnzip) {
|
||||
cacheManager.updateLastTime(url);
|
||||
onComplete && onComplete(null, cachedUnzip.url);
|
||||
}
|
||||
else if (REGEX.test(url)) {
|
||||
downloadFile(url, null, options.header, options.onFileProgress, function (err, downloadedZipPath) {
|
||||
if (err) {
|
||||
onComplete && onComplete(err);
|
||||
return;
|
||||
}
|
||||
cacheManager.unzipAndCacheBundle(url, downloadedZipPath, options.__cacheBundleRoot__, onComplete);
|
||||
});
|
||||
}
|
||||
else {
|
||||
cacheManager.unzipAndCacheBundle(url, url, options.__cacheBundleRoot__, onComplete);
|
||||
}
|
||||
}
|
||||
|
||||
function downloadDomAudio (url, options, onComplete) {
|
||||
if (typeof options === 'function') {
|
||||
onComplete = options;
|
||||
options = null;
|
||||
}
|
||||
|
||||
let dom;
|
||||
let sys = cc.sys;
|
||||
if (sys.platform === sys.TAOBAO || sys.platform === sys.TAOBAO_MINIGAME) {
|
||||
dom = window.document.createElement('audio');
|
||||
} else {
|
||||
dom = document.createElement('audio');
|
||||
}
|
||||
dom.src = url;
|
||||
|
||||
// HACK: wechat does not callback when load large number of assets
|
||||
onComplete && onComplete(null, dom);
|
||||
}
|
||||
|
||||
function download (url, func, options, onFileProgress, onComplete) {
|
||||
var result = transformUrl(url, options);
|
||||
if (result.inLocal) {
|
||||
func(result.url, options, onComplete);
|
||||
}
|
||||
else if (result.inCache) {
|
||||
cacheManager.updateLastTime(url);
|
||||
func(result.url, options, function (err, data) {
|
||||
if (err) {
|
||||
cacheManager.removeCache(url);
|
||||
}
|
||||
onComplete(err, data);
|
||||
});
|
||||
}
|
||||
else {
|
||||
downloadFile(url, null, options.header, onFileProgress, function (err, path) {
|
||||
if (err) {
|
||||
onComplete(err, null);
|
||||
return;
|
||||
}
|
||||
func(path, options, function (err, data) {
|
||||
if (!err) {
|
||||
cacheManager.tempFiles.add(url, path);
|
||||
cacheManager.cacheFile(url, path, options.cacheEnabled, options.__cacheBundleRoot__, true);
|
||||
}
|
||||
onComplete(err, data);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function parseArrayBuffer (url, options, onComplete) {
|
||||
readArrayBuffer(url, onComplete);
|
||||
}
|
||||
|
||||
function parseText (url, options, onComplete) {
|
||||
readText(url, onComplete);
|
||||
}
|
||||
|
||||
function parseJson (url, options, onComplete) {
|
||||
readJson(url, onComplete);
|
||||
}
|
||||
|
||||
function downloadText (url, options, onComplete) {
|
||||
download(url, parseText, options, options.onFileProgress, onComplete);
|
||||
}
|
||||
|
||||
var downloadJson = !isSubDomain ? function (url, options, onComplete) {
|
||||
download(url, parseJson, options, options.onFileProgress, onComplete);
|
||||
} : function (url, options, onComplete) {
|
||||
var { url } = transformUrl(url, options);
|
||||
url = url.slice(SUBCONTEXT_ROOT.length + 1); // remove subcontext root in url
|
||||
var content = __cocos_require__(cc.path.changeExtname(url, '.js'));
|
||||
onComplete && onComplete(null, content);
|
||||
}
|
||||
|
||||
var loadFont = !isSubDomain ? function (url, options, onComplete) {
|
||||
var fontFamily = __globalAdapter.loadFont(url);
|
||||
onComplete(null, fontFamily || 'Arial');
|
||||
} : function (url, options, onComplete) {
|
||||
onComplete(null, 'Arial');
|
||||
}
|
||||
|
||||
function doNothing (content, options, onComplete) {
|
||||
exists(content, (existence) => {
|
||||
if (existence) {
|
||||
onComplete(null, content);
|
||||
} else {
|
||||
onComplete(new Error(`file ${content} does not exist!`));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function downloadAsset (url, options, onComplete) {
|
||||
download(url, doNothing, options, options.onFileProgress, onComplete);
|
||||
}
|
||||
|
||||
function subdomainTransformUrl (url, options, onComplete) {
|
||||
var { url } = transformUrl(url, options);
|
||||
onComplete(null, url);
|
||||
}
|
||||
|
||||
function downloadBundle (nameOrUrl, options, onComplete) {
|
||||
let bundleName = cc.path.basename(nameOrUrl);
|
||||
var version = options.version || cc.assetManager.downloader.bundleVers[bundleName];
|
||||
const suffix = version ? `${version}.` : '';
|
||||
|
||||
function getConfigPathForSubPackage () {
|
||||
let sys = cc.sys;
|
||||
if (sys.platform === sys.TAOBAO_MINIGAME) {
|
||||
return `${bundleName}/config.${suffix}json`;
|
||||
}
|
||||
return `subpackages/${bundleName}/config.${suffix}json`;
|
||||
}
|
||||
|
||||
function appendBaseToJsonData (data) {
|
||||
if (!data) return;
|
||||
|
||||
let sys = cc.sys;
|
||||
if (sys.platform === sys.TAOBAO_MINIGAME) {
|
||||
data.base = `${bundleName}/`;
|
||||
} else {
|
||||
data.base = `subpackages/${bundleName}/`;
|
||||
}
|
||||
}
|
||||
|
||||
if (subpackages[bundleName]) {
|
||||
var config = getConfigPathForSubPackage();
|
||||
let loadedCb = function () {
|
||||
downloadJson(config, options, function (err, data) {
|
||||
appendBaseToJsonData(data);
|
||||
onComplete(err, data);
|
||||
});
|
||||
};
|
||||
if (cachedSubpackageList[bundleName]) {
|
||||
return loadedCb();
|
||||
}
|
||||
loadSubpackage(bundleName, options.onFileProgress, function (err) {
|
||||
if (err) {
|
||||
onComplete(err, null);
|
||||
return;
|
||||
}
|
||||
cachedSubpackageList[bundleName] = true;
|
||||
loadedCb();
|
||||
});
|
||||
}
|
||||
else {
|
||||
let js, url;
|
||||
if (REGEX.test(nameOrUrl) || (!isSubDomain && nameOrUrl.startsWith(getUserDataPath()))) {
|
||||
url = nameOrUrl;
|
||||
js = `src/scripts/${bundleName}/index.js`;
|
||||
cacheManager.makeBundleFolder(bundleName);
|
||||
}
|
||||
else {
|
||||
if (remoteBundles[bundleName]) {
|
||||
url = `${REMOTE_SERVER_ROOT}remote/${bundleName}`;
|
||||
js = `src/scripts/${bundleName}/index.js`;
|
||||
cacheManager.makeBundleFolder(bundleName);
|
||||
}
|
||||
else {
|
||||
url = `assets/${bundleName}`;
|
||||
js = `assets/${bundleName}/index.js`;
|
||||
}
|
||||
}
|
||||
__cocos_require__(js);
|
||||
options.__cacheBundleRoot__ = bundleName;
|
||||
var config = `${url}/config.${version ? version + '.' : ''}json`;
|
||||
downloadJson(config, options, function (err, data) {
|
||||
if (err) {
|
||||
onComplete && onComplete(err);
|
||||
return;
|
||||
}
|
||||
if (data.isZip) {
|
||||
let zipVersion = data.zipVersion;
|
||||
let zipUrl = `${url}/res.${zipVersion ? zipVersion + '.' : ''}zip`;
|
||||
handleZip(zipUrl, options, function (err, unzipPath) {
|
||||
if (err) {
|
||||
onComplete && onComplete(err);
|
||||
return;
|
||||
}
|
||||
data.base = unzipPath + '/res/';
|
||||
// PATCH: for android alipay version before v10.1.95 (v10.1.95 included)
|
||||
// to remove in the future
|
||||
let sys = cc.sys;
|
||||
if (sys.platform === sys.ALIPAY_GAME && sys.os === sys.OS_ANDROID) {
|
||||
let resPath = unzipPath + 'res/';
|
||||
if (fs.accessSync({path: resPath}).success) {
|
||||
data.base = resPath;
|
||||
}
|
||||
}
|
||||
onComplete && onComplete(null, data);
|
||||
});
|
||||
}
|
||||
else {
|
||||
data.base = url + '/';
|
||||
onComplete && onComplete(null, data);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const originParsePVRTex = parser.parsePVRTex;
|
||||
let parsePVRTex = function (file, options, onComplete) {
|
||||
readArrayBuffer(file, function (err, data) {
|
||||
if (err) return onComplete(err);
|
||||
originParsePVRTex(data, options, onComplete);
|
||||
});
|
||||
};
|
||||
|
||||
const originParseASTCTex = parser.parseASTCTex;
|
||||
let parseASTCTex = function (file, options, onComplete) {
|
||||
readArrayBuffer(file, function (err, data) {
|
||||
if (err) return onComplete(err);
|
||||
originParseASTCTex(data, options, onComplete);
|
||||
});
|
||||
};
|
||||
|
||||
const originParsePKMTex = parser.parsePKMTex;
|
||||
let parsePKMTex = function (file, options, onComplete) {
|
||||
readArrayBuffer(file, function (err, data) {
|
||||
if (err) return onComplete(err);
|
||||
originParsePKMTex(data, options, onComplete);
|
||||
});
|
||||
};
|
||||
|
||||
function parsePlist (url, options, onComplete) {
|
||||
readText(url, function (err, file) {
|
||||
var result = null;
|
||||
if (!err) {
|
||||
result = cc.plistParser.parse(file);
|
||||
if (!result) err = new Error('parse failed');
|
||||
}
|
||||
onComplete && onComplete(err, result);
|
||||
});
|
||||
}
|
||||
|
||||
let downloadImage = isSubDomain ? subdomainTransformUrl : downloadAsset;
|
||||
downloader.downloadDomAudio = downloadDomAudio;
|
||||
downloader.downloadScript = downloadScript;
|
||||
parser.parsePVRTex = parsePVRTex;
|
||||
parser.parsePKMTex = parsePKMTex;
|
||||
parser.parseASTCTex = parseASTCTex;
|
||||
|
||||
downloader.register({
|
||||
'.js' : downloadScript,
|
||||
|
||||
// Audio
|
||||
'.mp3' : downloadAsset,
|
||||
'.ogg' : downloadAsset,
|
||||
'.wav' : downloadAsset,
|
||||
'.m4a' : downloadAsset,
|
||||
|
||||
// Image
|
||||
'.png' : downloadImage,
|
||||
'.jpg' : downloadImage,
|
||||
'.bmp' : downloadImage,
|
||||
'.jpeg' : downloadImage,
|
||||
'.gif' : downloadImage,
|
||||
'.ico' : downloadImage,
|
||||
'.tiff' : downloadImage,
|
||||
'.image' : downloadImage,
|
||||
'.webp' : downloadImage,
|
||||
'.pvr': downloadAsset,
|
||||
'.pkm': downloadAsset,
|
||||
'.astc': downloadAsset,
|
||||
|
||||
'.font': downloadAsset,
|
||||
'.eot': downloadAsset,
|
||||
'.ttf': downloadAsset,
|
||||
'.woff': downloadAsset,
|
||||
'.svg': downloadAsset,
|
||||
'.ttc': downloadAsset,
|
||||
|
||||
// Txt
|
||||
'.txt' : downloadAsset,
|
||||
'.xml' : downloadAsset,
|
||||
'.vsh' : downloadAsset,
|
||||
'.fsh' : downloadAsset,
|
||||
'.atlas' : downloadAsset,
|
||||
|
||||
'.tmx' : downloadAsset,
|
||||
'.tsx' : downloadAsset,
|
||||
'.plist' : downloadAsset,
|
||||
'.fnt' : downloadAsset,
|
||||
|
||||
'.json' : downloadJson,
|
||||
'.ExportJson' : downloadAsset,
|
||||
|
||||
'.binary' : downloadAsset,
|
||||
'.bin': downloadAsset,
|
||||
'.dbbin': downloadAsset,
|
||||
'.skel': downloadAsset,
|
||||
|
||||
'.mp4': downloadAsset,
|
||||
'.avi': downloadAsset,
|
||||
'.mov': downloadAsset,
|
||||
'.mpg': downloadAsset,
|
||||
'.mpeg': downloadAsset,
|
||||
'.rm': downloadAsset,
|
||||
'.rmvb': downloadAsset,
|
||||
|
||||
'bundle': downloadBundle,
|
||||
|
||||
'default': downloadText,
|
||||
});
|
||||
|
||||
parser.register({
|
||||
'.png' : downloader.downloadDomImage,
|
||||
'.jpg' : downloader.downloadDomImage,
|
||||
'.bmp' : downloader.downloadDomImage,
|
||||
'.jpeg' : downloader.downloadDomImage,
|
||||
'.gif' : downloader.downloadDomImage,
|
||||
'.ico' : downloader.downloadDomImage,
|
||||
'.tiff' : downloader.downloadDomImage,
|
||||
'.image' : downloader.downloadDomImage,
|
||||
'.webp' : downloader.downloadDomImage,
|
||||
'.pvr': parsePVRTex,
|
||||
'.pkm': parsePKMTex,
|
||||
'.astc': parseASTCTex,
|
||||
|
||||
'.font': loadFont,
|
||||
'.eot': loadFont,
|
||||
'.ttf': loadFont,
|
||||
'.woff': loadFont,
|
||||
'.svg': loadFont,
|
||||
'.ttc': loadFont,
|
||||
|
||||
// Audio
|
||||
'.mp3' : downloadDomAudio,
|
||||
'.ogg' : downloadDomAudio,
|
||||
'.wav' : downloadDomAudio,
|
||||
'.m4a' : downloadDomAudio,
|
||||
|
||||
// Txt
|
||||
'.txt' : parseText,
|
||||
'.xml' : parseText,
|
||||
'.vsh' : parseText,
|
||||
'.fsh' : parseText,
|
||||
'.atlas' : parseText,
|
||||
|
||||
'.tmx' : parseText,
|
||||
'.tsx' : parseText,
|
||||
'.fnt' : parseText,
|
||||
'.plist' : parsePlist,
|
||||
|
||||
'.binary' : parseArrayBuffer,
|
||||
'.bin': parseArrayBuffer,
|
||||
'.dbbin': parseArrayBuffer,
|
||||
'.skel': parseArrayBuffer,
|
||||
|
||||
'.ExportJson' : parseJson,
|
||||
});
|
||||
|
||||
var transformUrl = !isSubDomain ? function (url, options) {
|
||||
var inLocal = false;
|
||||
var inCache = false;
|
||||
var isInUserDataPath = url.startsWith(getUserDataPath());
|
||||
if (isInUserDataPath) {
|
||||
inLocal = true;
|
||||
}
|
||||
else if (REGEX.test(url)) {
|
||||
if (!options.reload) {
|
||||
var cache = cacheManager.cachedFiles.get(url);
|
||||
if (cache) {
|
||||
inCache = true;
|
||||
url = cache.url;
|
||||
}
|
||||
else {
|
||||
var tempUrl = cacheManager.tempFiles.get(url);
|
||||
if (tempUrl) {
|
||||
inLocal = true;
|
||||
url = tempUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
inLocal = true;
|
||||
}
|
||||
return { url, inLocal, inCache };
|
||||
} : function (url, options) {
|
||||
if (!REGEX.test(url)) {
|
||||
url = SUBCONTEXT_ROOT + '/' + url;
|
||||
}
|
||||
return { url };
|
||||
}
|
||||
|
||||
if (!isSubDomain) {
|
||||
cc.assetManager.transformPipeline.append(function (task) {
|
||||
var input = task.output = task.input;
|
||||
for (var i = 0, l = input.length; i < l; i++) {
|
||||
var item = input[i];
|
||||
var options = item.options;
|
||||
if (!item.config) {
|
||||
if (item.ext === 'bundle') continue;
|
||||
options.cacheEnabled = options.cacheEnabled !== undefined ? options.cacheEnabled : false;
|
||||
}
|
||||
else {
|
||||
options.__cacheBundleRoot__ = item.config.name;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var originInit = cc.assetManager.init;
|
||||
cc.assetManager.init = function (options) {
|
||||
originInit.call(cc.assetManager, options);
|
||||
options.subpackages && options.subpackages.forEach(x => subpackages[x] = 'subpackages/' + x);
|
||||
options.remoteBundles && options.remoteBundles.forEach(x => remoteBundles[x] = true);
|
||||
REMOTE_SERVER_ROOT = options.server || '';
|
||||
if (REMOTE_SERVER_ROOT && !REMOTE_SERVER_ROOT.endsWith('/')) REMOTE_SERVER_ROOT += '/';
|
||||
cacheManager.init();
|
||||
};
|
||||
}
|
||||
else {
|
||||
var originInit = cc.assetManager.init;
|
||||
cc.assetManager.init = function (options) {
|
||||
originInit.call(cc.assetManager, options);
|
||||
SUBCONTEXT_ROOT = options.subContextRoot || '';
|
||||
};
|
||||
}
|
||||
|
69
adapters/common/engine/Audio.js
Normal file
69
adapters/common/engine/Audio.js
Normal file
@@ -0,0 +1,69 @@
|
||||
const Audio = cc._Audio;
|
||||
|
||||
if (Audio) {
|
||||
let originGetDuration = Audio.prototype.getDuration;
|
||||
Object.assign(Audio.prototype, {
|
||||
_createElement () {
|
||||
let elem = this._src._nativeAsset;
|
||||
// Reuse dom audio element
|
||||
if (!this._element) {
|
||||
this._element = __globalAdapter.createInnerAudioContext();
|
||||
}
|
||||
this._element.src = elem.src;
|
||||
},
|
||||
|
||||
destroy () {
|
||||
if (this._element) {
|
||||
this._element.destroy();
|
||||
this._element = null;
|
||||
}
|
||||
},
|
||||
|
||||
setCurrentTime (num) {
|
||||
let self = this;
|
||||
this._src && this._src._ensureLoaded(function () {
|
||||
self._element.seek(num);
|
||||
});
|
||||
},
|
||||
|
||||
stop () {
|
||||
let self = this;
|
||||
this._src && this._src._ensureLoaded(function () {
|
||||
// HACK: some platforms won't set currentTime to 0 when stop audio
|
||||
self._element.seek(0);
|
||||
self._element.stop();
|
||||
self._unbindEnded();
|
||||
self.emit('stop');
|
||||
self._state = Audio.State.STOPPED;
|
||||
});
|
||||
},
|
||||
|
||||
_bindEnded () {
|
||||
let elem = this._element;
|
||||
if (elem && elem.onEnded && !this._onended._binded) {
|
||||
this._onended._binded = true;
|
||||
elem.onEnded(this._onended);
|
||||
}
|
||||
},
|
||||
|
||||
_unbindEnded () {
|
||||
let elem = this._element;
|
||||
if (elem && elem.offEnded && this._onended._binded) {
|
||||
this._onended._binded = false;
|
||||
elem.offEnded && elem.offEnded(this._onended);
|
||||
}
|
||||
},
|
||||
|
||||
getDuration () {
|
||||
let duration = originGetDuration.call(this);
|
||||
// HACK: in mini game, if dynamicly load audio, can't get duration from audioClip
|
||||
// because duration is not coming from audio deserialization
|
||||
duration = duration || (this._element ? this._element.duration : 0);
|
||||
return duration;
|
||||
},
|
||||
|
||||
// adapt some special operations on web platform
|
||||
_touchToPlay () { },
|
||||
_forceUpdatingState () { },
|
||||
});
|
||||
}
|
3
adapters/common/engine/AudioEngine.js
Normal file
3
adapters/common/engine/AudioEngine.js
Normal file
@@ -0,0 +1,3 @@
|
||||
if (cc && cc.audioEngine) {
|
||||
cc.audioEngine._maxAudioInstance = 10;
|
||||
}
|
37
adapters/common/engine/DeviceMotionEvent.js
Normal file
37
adapters/common/engine/DeviceMotionEvent.js
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
const inputManager = cc.internal.inputManager;
|
||||
const globalAdapter = window.__globalAdapter;
|
||||
|
||||
Object.assign(inputManager, {
|
||||
setAccelerometerEnabled (isEnable) {
|
||||
let scheduler = cc.director.getScheduler();
|
||||
scheduler.enableForTarget(this);
|
||||
if (isEnable) {
|
||||
this._registerAccelerometerEvent();
|
||||
scheduler.scheduleUpdate(this);
|
||||
}
|
||||
else {
|
||||
this._unregisterAccelerometerEvent();
|
||||
scheduler.unscheduleUpdate(this);
|
||||
}
|
||||
},
|
||||
|
||||
// No need to adapt
|
||||
// setAccelerometerInterval (interval) { },
|
||||
|
||||
_registerAccelerometerEvent () {
|
||||
this._accelCurTime = 0;
|
||||
let self = this;
|
||||
this._acceleration = new cc.Acceleration();
|
||||
globalAdapter.startAccelerometer(function (res) {
|
||||
self._acceleration.x = res.x;
|
||||
self._acceleration.y = res.y;
|
||||
self._acceleration.z = res.y;
|
||||
});
|
||||
},
|
||||
|
||||
_unregisterAccelerometerEvent () {
|
||||
this._accelCurTime = 0;
|
||||
globalAdapter.stopAccelerometer();
|
||||
},
|
||||
});
|
177
adapters/common/engine/Editbox.js
Normal file
177
adapters/common/engine/Editbox.js
Normal file
@@ -0,0 +1,177 @@
|
||||
(function () {
|
||||
if (!(cc && cc.EditBox)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const EditBox = cc.EditBox;
|
||||
const js = cc.js;
|
||||
const KeyboardReturnType = EditBox.KeyboardReturnType;
|
||||
const MAX_VALUE = 65535;
|
||||
const KEYBOARD_HIDE_TIME = 600;
|
||||
let _hideKeyboardTimeout = null;
|
||||
let _currentEditBoxImpl = null;
|
||||
|
||||
function getKeyboardReturnType (type) {
|
||||
switch (type) {
|
||||
case KeyboardReturnType.DEFAULT:
|
||||
case KeyboardReturnType.DONE:
|
||||
return 'done';
|
||||
case KeyboardReturnType.SEND:
|
||||
return 'send';
|
||||
case KeyboardReturnType.SEARCH:
|
||||
return 'search';
|
||||
case KeyboardReturnType.GO:
|
||||
return 'go';
|
||||
case KeyboardReturnType.NEXT:
|
||||
return 'next';
|
||||
}
|
||||
return 'done';
|
||||
}
|
||||
|
||||
const BaseClass = EditBox._ImplClass;
|
||||
function MiniGameEditBoxImpl () {
|
||||
BaseClass.call(this);
|
||||
|
||||
this._eventListeners = {
|
||||
onKeyboardInput: null,
|
||||
onKeyboardConfirm: null,
|
||||
onKeyboardComplete: null,
|
||||
};
|
||||
}
|
||||
|
||||
js.extend(MiniGameEditBoxImpl, BaseClass);
|
||||
EditBox._ImplClass = MiniGameEditBoxImpl;
|
||||
|
||||
Object.assign(MiniGameEditBoxImpl.prototype, {
|
||||
init (delegate) {
|
||||
if (!delegate) {
|
||||
cc.error('EditBox init failed');
|
||||
return;
|
||||
}
|
||||
this._delegate = delegate;
|
||||
},
|
||||
|
||||
beginEditing () {
|
||||
// In case multiply register events
|
||||
if (this._editing) {
|
||||
return;
|
||||
}
|
||||
this._ensureKeyboardHide(() => {
|
||||
let delegate = this._delegate;
|
||||
this._showKeyboard();
|
||||
this._registerKeyboardEvent();
|
||||
this._editing = true;
|
||||
_currentEditBoxImpl = this;
|
||||
delegate.editBoxEditingDidBegan();
|
||||
});
|
||||
},
|
||||
|
||||
endEditing () {
|
||||
this._hideKeyboard();
|
||||
let cbs = this._eventListeners;
|
||||
cbs.onKeyboardComplete && cbs.onKeyboardComplete();
|
||||
},
|
||||
|
||||
_registerKeyboardEvent () {
|
||||
let self = this;
|
||||
let delegate = this._delegate;
|
||||
let cbs = this._eventListeners;
|
||||
|
||||
cbs.onKeyboardInput = function (res) {
|
||||
if (delegate._string !== res.value) {
|
||||
delegate.editBoxTextChanged(res.value);
|
||||
}
|
||||
}
|
||||
|
||||
cbs.onKeyboardConfirm = function (res) {
|
||||
delegate.editBoxEditingReturn();
|
||||
let cbs = self._eventListeners;
|
||||
cbs.onKeyboardComplete && cbs.onKeyboardComplete(res);
|
||||
}
|
||||
|
||||
cbs.onKeyboardComplete = function (res) {
|
||||
self._editing = false;
|
||||
_currentEditBoxImpl = null;
|
||||
self._unregisterKeyboardEvent();
|
||||
if (res && res.value && delegate._string !== res.value) {
|
||||
delegate.editBoxTextChanged(res.value);
|
||||
}
|
||||
delegate.editBoxEditingDidEnded();
|
||||
}
|
||||
|
||||
__globalAdapter.onKeyboardInput(cbs.onKeyboardInput);
|
||||
__globalAdapter.onKeyboardConfirm(cbs.onKeyboardConfirm);
|
||||
__globalAdapter.onKeyboardComplete(cbs.onKeyboardComplete);
|
||||
},
|
||||
|
||||
_unregisterKeyboardEvent () {
|
||||
let cbs = this._eventListeners;
|
||||
|
||||
if (cbs.onKeyboardInput) {
|
||||
__globalAdapter.offKeyboardInput(cbs.onKeyboardInput);
|
||||
cbs.onKeyboardInput = null;
|
||||
}
|
||||
if (cbs.onKeyboardConfirm) {
|
||||
__globalAdapter.offKeyboardConfirm(cbs.onKeyboardConfirm);
|
||||
cbs.onKeyboardConfirm = null;
|
||||
}
|
||||
if (cbs.onKeyboardComplete) {
|
||||
__globalAdapter.offKeyboardComplete(cbs.onKeyboardComplete);
|
||||
cbs.onKeyboardComplete = null;
|
||||
}
|
||||
},
|
||||
|
||||
_otherEditing () {
|
||||
return !!_currentEditBoxImpl && _currentEditBoxImpl !== this && _currentEditBoxImpl._editing;
|
||||
},
|
||||
|
||||
_ensureKeyboardHide (cb) {
|
||||
let otherEditing = this._otherEditing();
|
||||
if (!otherEditing && !_hideKeyboardTimeout) {
|
||||
return cb();
|
||||
}
|
||||
if (_hideKeyboardTimeout) {
|
||||
clearTimeout(_hideKeyboardTimeout);
|
||||
}
|
||||
if (otherEditing) {
|
||||
_currentEditBoxImpl.endEditing();
|
||||
}
|
||||
_hideKeyboardTimeout = setTimeout(() => {
|
||||
_hideKeyboardTimeout = null;
|
||||
cb();
|
||||
}, KEYBOARD_HIDE_TIME);
|
||||
},
|
||||
|
||||
_showKeyboard () {
|
||||
let delegate = this._delegate;
|
||||
let multiline = (delegate.inputMode === EditBox.InputMode.ANY);
|
||||
let maxLength = (delegate.maxLength < 0 ? MAX_VALUE : delegate.maxLength);
|
||||
|
||||
__globalAdapter.showKeyboard({
|
||||
defaultValue: delegate._string,
|
||||
maxLength: maxLength,
|
||||
multiple: multiline,
|
||||
confirmHold: false,
|
||||
confirmType: getKeyboardReturnType(delegate.returnType),
|
||||
success (res) {
|
||||
|
||||
},
|
||||
fail (res) {
|
||||
cc.warn(res.errMsg);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_hideKeyboard () {
|
||||
__globalAdapter.hideKeyboard({
|
||||
success (res) {
|
||||
|
||||
},
|
||||
fail (res) {
|
||||
cc.warn(res.errMsg);
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
165
adapters/common/engine/Game.js
Normal file
165
adapters/common/engine/Game.js
Normal file
@@ -0,0 +1,165 @@
|
||||
const inputManager = cc.internal.inputManager;
|
||||
const renderer = cc.renderer;
|
||||
const game = cc.game;
|
||||
const dynamicAtlasManager = cc.dynamicAtlasManager;
|
||||
|
||||
let originRun = game.run;
|
||||
Object.assign(game, {
|
||||
_banRunningMainLoop: __globalAdapter.isSubContext,
|
||||
_firstSceneLaunched: false,
|
||||
|
||||
run () {
|
||||
cc.director.once(cc.Director.EVENT_AFTER_SCENE_LAUNCH, () => {
|
||||
this._firstSceneLaunched = true;
|
||||
});
|
||||
originRun.apply(this, arguments);
|
||||
},
|
||||
|
||||
setFrameRate (frameRate) {
|
||||
this.config.frameRate = frameRate;
|
||||
if (__globalAdapter.setPreferredFramesPerSecond) {
|
||||
__globalAdapter.setPreferredFramesPerSecond(frameRate);
|
||||
}
|
||||
else {
|
||||
if (this._intervalId) {
|
||||
window.cancelAnimFrame(this._intervalId);
|
||||
}
|
||||
this._intervalId = 0;
|
||||
this._paused = true;
|
||||
this._setAnimFrame();
|
||||
this._runMainLoop();
|
||||
}
|
||||
},
|
||||
|
||||
_runMainLoop () {
|
||||
if (this._banRunningMainLoop) {
|
||||
return;
|
||||
}
|
||||
var self = this, callback, config = self.config,
|
||||
director = cc.director,
|
||||
skip = true, frameRate = config.frameRate;
|
||||
|
||||
cc.debug.setDisplayStats(config.showFPS);
|
||||
|
||||
callback = function () {
|
||||
if (!self._paused) {
|
||||
self._intervalId = window.requestAnimFrame(callback);
|
||||
if (frameRate === 30 && !__globalAdapter.setPreferredFramesPerSecond) {
|
||||
skip = !skip;
|
||||
if (skip) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
director.mainLoop();
|
||||
}
|
||||
};
|
||||
|
||||
self._intervalId = window.requestAnimFrame(callback);
|
||||
self._paused = false;
|
||||
},
|
||||
|
||||
_initRenderer () {
|
||||
// Avoid setup to be called twice.
|
||||
if (this._rendererInitialized) return;
|
||||
|
||||
// frame and container are useless on minigame platform
|
||||
let sys = cc.sys;
|
||||
if (sys.platform === sys.TAOBAO || sys.platform === sys.TAOBAO_MINIGAME) {
|
||||
this.frame = this.container = window.document.createElement("DIV");
|
||||
} else {
|
||||
this.frame = this.container = document.createElement("DIV");
|
||||
}
|
||||
|
||||
let localCanvas;
|
||||
if (__globalAdapter.isSubContext) {
|
||||
localCanvas = window.sharedCanvas || __globalAdapter.getSharedCanvas();
|
||||
}
|
||||
else if (sys.platform === sys.TAOBAO || sys.platform === sys.TAOBAO_MINIGAME) {
|
||||
localCanvas = window.canvas;
|
||||
}
|
||||
else {
|
||||
localCanvas = canvas;
|
||||
}
|
||||
this.canvas = localCanvas;
|
||||
|
||||
this._determineRenderType();
|
||||
// WebGL context created successfully
|
||||
if (this.renderType === this.RENDER_TYPE_WEBGL) {
|
||||
var opts = {
|
||||
'stencil': true,
|
||||
// MSAA is causing serious performance dropdown on some browsers.
|
||||
'antialias': cc.macro.ENABLE_WEBGL_ANTIALIAS,
|
||||
'alpha': cc.macro.ENABLE_TRANSPARENT_CANVAS,
|
||||
'preserveDrawingBuffer': false,
|
||||
};
|
||||
renderer.initWebGL(localCanvas, opts);
|
||||
this._renderContext = renderer.device._gl;
|
||||
|
||||
// Enable dynamic atlas manager by default
|
||||
if (!cc.macro.CLEANUP_IMAGE_CACHE && dynamicAtlasManager) {
|
||||
dynamicAtlasManager.enabled = true;
|
||||
}
|
||||
}
|
||||
if (!this._renderContext) {
|
||||
this.renderType = this.RENDER_TYPE_CANVAS;
|
||||
// Could be ignored by module settings
|
||||
renderer.initCanvas(localCanvas);
|
||||
this._renderContext = renderer.device._ctx;
|
||||
}
|
||||
|
||||
this._rendererInitialized = true;
|
||||
},
|
||||
|
||||
_initEvents () {
|
||||
let sys = cc.sys;
|
||||
// register system events
|
||||
if (this.config.registerSystemEvent) {
|
||||
inputManager.registerSystemEvent(this.canvas);
|
||||
}
|
||||
|
||||
var hidden = false;
|
||||
|
||||
function onHidden() {
|
||||
if (!hidden) {
|
||||
hidden = true;
|
||||
game.emit(game.EVENT_HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
function onShown(res) {
|
||||
if (hidden) {
|
||||
hidden = false;
|
||||
if (game.renderType === game.RENDER_TYPE_WEBGL) {
|
||||
game._renderContext.finish();
|
||||
}
|
||||
game.emit(game.EVENT_SHOW, res);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: onAudioInterruptionEnd and onAudioInterruptionBegin on ByteDance platform is not designed to behave the same as the ones on WeChat platform,
|
||||
// the callback is invoked on game show or hide on ByteDance platform, while is not invoked on WeChat platform.
|
||||
// See the docs on WeChat: https://developers.weixin.qq.com/minigame/dev/api/base/app/app-event/wx.onAudioInterruptionBegin.html
|
||||
if (sys.platform !== sys.BYTEDANCE_GAME) {
|
||||
__globalAdapter.onAudioInterruptionEnd && __globalAdapter.onAudioInterruptionEnd(function () {
|
||||
if (cc.audioEngine) cc.audioEngine._restore();
|
||||
|
||||
});
|
||||
__globalAdapter.onAudioInterruptionBegin && __globalAdapter.onAudioInterruptionBegin(function () {
|
||||
if (cc.audioEngine) cc.audioEngine._break();
|
||||
});
|
||||
}
|
||||
|
||||
// Maybe not support in open data context
|
||||
__globalAdapter.onShow && __globalAdapter.onShow(onShown);
|
||||
__globalAdapter.onHide && __globalAdapter.onHide(onHidden);
|
||||
|
||||
this.on(game.EVENT_HIDE, function () {
|
||||
game.pause();
|
||||
});
|
||||
this.on(game.EVENT_SHOW, function () {
|
||||
game.resume();
|
||||
});
|
||||
},
|
||||
|
||||
end () { }, // mini game platform not support this api
|
||||
});
|
42
adapters/common/engine/InputManager.js
Normal file
42
adapters/common/engine/InputManager.js
Normal file
@@ -0,0 +1,42 @@
|
||||
const mgr = cc.internal.inputManager;
|
||||
const canvasPosition = {
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight
|
||||
};
|
||||
|
||||
if (mgr) {
|
||||
Object.assign(mgr, {
|
||||
_updateCanvasBoundingRect () {},
|
||||
|
||||
registerSystemEvent (element) {
|
||||
if(this._isRegisterEvent) return;
|
||||
|
||||
this._glView = cc.view;
|
||||
let self = this;
|
||||
|
||||
//register touch event
|
||||
let _touchEventsMap = {
|
||||
onTouchStart: this.handleTouchesBegin,
|
||||
onTouchMove: this.handleTouchesMove,
|
||||
onTouchEnd: this.handleTouchesEnd,
|
||||
onTouchCancel: this.handleTouchesCancel,
|
||||
};
|
||||
|
||||
let registerTouchEvent = function (eventName) {
|
||||
let handler = _touchEventsMap[eventName];
|
||||
__globalAdapter[eventName](function (event) {
|
||||
if (!event.changedTouches) return;
|
||||
handler.call(self, self.getTouchesByEvent(event, canvasPosition));
|
||||
});
|
||||
};
|
||||
|
||||
for (let eventName in _touchEventsMap) {
|
||||
registerTouchEvent(eventName);
|
||||
}
|
||||
|
||||
this._isRegisterEvent = true;
|
||||
},
|
||||
});
|
||||
}
|
5
adapters/common/engine/Screen.js
Normal file
5
adapters/common/engine/Screen.js
Normal file
@@ -0,0 +1,5 @@
|
||||
Object.assign(cc.screen, {
|
||||
autoFullScreen: function (element, onFullScreenChange) {
|
||||
// Not support on mini game
|
||||
}
|
||||
});
|
12
adapters/common/engine/Texture2D.js
Normal file
12
adapters/common/engine/Texture2D.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const Texture2D = cc.Texture2D;
|
||||
|
||||
if (Texture2D) {
|
||||
Object.assign(Texture2D.prototype, {
|
||||
initWithElement (element) {
|
||||
if (!element)
|
||||
return;
|
||||
this._image = element;
|
||||
this.handleLoadedTexture();
|
||||
},
|
||||
});
|
||||
}
|
67
adapters/common/engine/globalAdapter/BaseSystemInfo.js
Normal file
67
adapters/common/engine/globalAdapter/BaseSystemInfo.js
Normal file
@@ -0,0 +1,67 @@
|
||||
function adaptSys (sys, env) {
|
||||
if (!env) {
|
||||
env = __globalAdapter.getSystemInfoSync();
|
||||
}
|
||||
|
||||
var language = env.language || '';
|
||||
var system = env.system || 'iOS';
|
||||
var platform = env.platform || 'iOS';
|
||||
|
||||
sys.isNative = false;
|
||||
sys.isBrowser = false;
|
||||
sys.isMobile = true;
|
||||
sys.language = language.substr(0, 2);
|
||||
sys.languageCode = language.toLowerCase();
|
||||
|
||||
platform = platform.toLowerCase();
|
||||
if (platform === "android") {
|
||||
sys.os = sys.OS_ANDROID;
|
||||
}
|
||||
else if (platform === "ios") {
|
||||
sys.os = sys.OS_IOS;
|
||||
}
|
||||
|
||||
system = system.toLowerCase();
|
||||
// Adaptation to Android P
|
||||
if (system === 'android p') {
|
||||
system = 'android p 9.0';
|
||||
}
|
||||
|
||||
var version = /[\d\.]+/.exec(system);
|
||||
sys.osVersion = version ? version[0] : system;
|
||||
sys.osMainVersion = parseInt(sys.osVersion);
|
||||
sys.browserType = null;
|
||||
sys.browserVersion = null;
|
||||
|
||||
var w = env.windowWidth;
|
||||
var h = env.windowHeight;
|
||||
var ratio = env.pixelRatio || 1;
|
||||
sys.windowPixelResolution = {
|
||||
width: ratio * w,
|
||||
height: ratio * h
|
||||
};
|
||||
|
||||
sys.localStorage = window.localStorage;
|
||||
|
||||
var _supportWebGL = __globalAdapter.isSubContext ? false : true;;
|
||||
var _supportWebp = false;
|
||||
try {
|
||||
var _canvas = document.createElement("canvas");
|
||||
_supportWebp = _canvas.toDataURL('image/webp').startsWith('data:image/webp');
|
||||
}
|
||||
catch (err) { }
|
||||
|
||||
sys.capabilities = {
|
||||
"canvas": true,
|
||||
"opengl": !!_supportWebGL,
|
||||
"webp": _supportWebp
|
||||
};
|
||||
sys.__audioSupport = {
|
||||
ONLY_ONE: false,
|
||||
WEB_AUDIO: false,
|
||||
DELAY_CREATE_CTX: false,
|
||||
format: ['.mp3']
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = adaptSys;
|
25
adapters/common/engine/globalAdapter/ContainerStrategy.js
Normal file
25
adapters/common/engine/globalAdapter/ContainerStrategy.js
Normal file
@@ -0,0 +1,25 @@
|
||||
function adaptContainerStrategy (containerStrategyProto) {
|
||||
containerStrategyProto._setupContainer = function (view, width, height) {
|
||||
// Setup pixel ratio for retina display
|
||||
var devicePixelRatio = view._devicePixelRatio = 1;
|
||||
if (view.isRetinaEnabled()) {
|
||||
devicePixelRatio = view._devicePixelRatio = Math.min(view._maxPixelRatio, window.devicePixelRatio || 1);
|
||||
}
|
||||
// size of sharedCanvas is readonly in subContext
|
||||
if (__globalAdapter.isSubContext) {
|
||||
return;
|
||||
}
|
||||
let locCanvas = cc.game.canvas;
|
||||
// Setup canvas
|
||||
width *= devicePixelRatio;
|
||||
height *= devicePixelRatio;
|
||||
// FIX: black screen on Baidu platform
|
||||
// reset canvas size may call gl.clear(), especially when you call cc.director.loadScene()
|
||||
if (locCanvas.width !== width || locCanvas.height !== height) {
|
||||
locCanvas.width = width;
|
||||
locCanvas.height = height;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = adaptContainerStrategy;
|
43
adapters/common/engine/globalAdapter/View.js
Normal file
43
adapters/common/engine/globalAdapter/View.js
Normal file
@@ -0,0 +1,43 @@
|
||||
function adaptView (viewProto) {
|
||||
Object.assign(viewProto, {
|
||||
_adjustViewportMeta () {
|
||||
// minigame not support
|
||||
},
|
||||
|
||||
setRealPixelResolution (width, height, resolutionPolicy) {
|
||||
// Reset the resolution size and policy
|
||||
this.setDesignResolutionSize(width, height, resolutionPolicy);
|
||||
},
|
||||
|
||||
enableAutoFullScreen (enabled) {
|
||||
cc.warn('cc.view.enableAutoFullScreen() is not supported on minigame platform.');
|
||||
},
|
||||
|
||||
isAutoFullScreenEnabled () {
|
||||
return false;
|
||||
},
|
||||
|
||||
setCanvasSize () {
|
||||
cc.warn('cc.view.setCanvasSize() is not supported on minigame platform.');
|
||||
},
|
||||
|
||||
setFrameSize () {
|
||||
cc.warn('frame size is readonly on minigame platform.');
|
||||
},
|
||||
|
||||
_initFrameSize () {
|
||||
let locFrameSize = this._frameSize;
|
||||
if (__globalAdapter.isSubContext) {
|
||||
let sharedCanvas = window.sharedCanvas || __globalAdapter.getSharedCanvas();
|
||||
locFrameSize.width = sharedCanvas.width;
|
||||
locFrameSize.height = sharedCanvas.height;
|
||||
}
|
||||
else {
|
||||
locFrameSize.width = window.innerWidth;
|
||||
locFrameSize.height = window.innerHeight;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = adaptView;
|
9
adapters/common/engine/globalAdapter/index.js
Normal file
9
adapters/common/engine/globalAdapter/index.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const adapter = window.__globalAdapter;
|
||||
|
||||
Object.assign(adapter, {
|
||||
adaptSys: require('./BaseSystemInfo'),
|
||||
|
||||
adaptView: require('./View'),
|
||||
|
||||
adaptContainerStrategy: require('./ContainerStrategy'),
|
||||
});
|
10
adapters/common/engine/index.js
Normal file
10
adapters/common/engine/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
require('./Audio');
|
||||
require('./AudioEngine');
|
||||
require('./DeviceMotionEvent');
|
||||
require('./Editbox');
|
||||
require('./Game');
|
||||
require('./InputManager');
|
||||
require('./AssetManager');
|
||||
require('./Screen');
|
||||
require('./Texture2D');
|
||||
require('./misc');
|
1
adapters/common/engine/misc.js
Normal file
1
adapters/common/engine/misc.js
Normal file
@@ -0,0 +1 @@
|
||||
cc.macro.DOWNLOAD_MAX_CONCURRENT = 10;
|
Reference in New Issue
Block a user