cocos2dx lua 열 업데이트
게임 에 로그 인 할 때마다 cocos 의 assetManager 를 이용 하여 서버 에서 현재 최신 두 파일 을 끌 어 옵 니 다.하 나 는 version. mainifest, 하나의 procject. mainifest 입 니 다. 이 두 파일 은 모두 xml 설명 파일 입 니 다.하 나 는 버 전 정 보 를 포함 하고, 두 번 째 는 게임 의 모든 자원 을 포함 하 는 MD5 코드 입 니 다.먼저 version 파일 을 통 해 로 컬 버 전이 같은 지, 다른 경우 로 컬 procject 파일 과 MD5 코드 를 비교 하여 어떤 파일 을 다시 다운로드 하고 자원 을 교체 해 야 하 는 지 판단 합 니 다.
단계:
1. 파일 다운로드 열 업데이트 서버 가 있 습 니 다. 최신 프로젝트 자원 (res / src / 디 렉 터 리) 를 열 업데이트 서버 에 넣 고 버 전 정보 모 파일 (version info. json) 과 python 스 크 립 트 파일 eneate Manifest. py (procject. manifest, version. manifest 파일 생 성) 를 추가 합 니 다.
2.version_info. json 파일: 주로 정 보 를 설정 하 는 데 사 용 됩 니 다.
{
"packageUrl" : "http://ip:port/update/MyProj/assets/",
"remoteManifestUrl" : "http://ip:port/update/MyProj/version/project.manifest",
"remoteVersionUrl" : "http://ip:port/update/MyProj/version/version.manifest",
"engineVersion" : "3.3",
"update_channel" : "Android",
"bundle" : "2018111701",
"version" : "1.0.0",
}
3. eneateManifest. py 파일: 이 파일 은 python 입 니 다.대응 하 는 version 과 procject 파일 을 만 드 는 것 이 목적 입 니 다.procject 파일 은 모든 자원 에 유일한 MD5 코드 를 만 들 수 있 습 니 다. 모든 자원 의 태그 에 해당 합 니 다.다음은 python 파일 의 코드 입 니 다.
#coding:utf-8
import os
import sys
import json
import hashlib
import subprocess
import getpass
username = getpass.getuser()
#
#os.chdir('/Users/' + username + '/Documents/client/MyProj/')
assetsDir = {
#MyProj
"searchDir" : ["src", "res"],
#
"ignorDir" : ["cocos", "framework", ".svn"],
#
"ignorFile":[".DS_Store"],
}
versionConfigFile = "version/version_info.json" #
versionManifestPath = "version/version.manifest" # version.manifest
projectManifestPath = "version/project.manifest" # project.manifest
# projectManifestPath = "/Users/ximi/Documents/client/MyProj/res/version/project.manifest" # project.manifest (mac )
class SearchFile:
def __init__(self):
self.fileList = []
for k in assetsDir:
if (k == "searchDir"):
for searchdire in assetsDir[k]:
self.recursiveDir(searchdire)
def recursiveDir(self, srcPath):
''' '''
dirList = [] #
files = os.listdir(srcPath) # , ( )
for f in files:
#
if (os.path.isdir(srcPath + '/' + f)):
if (f[0] == '.' or (f in assetsDir["ignorDir"])):
#
pass
else:
#
dirList.append(f)
#
elif (os.path.isfile(srcPath + '/' + f)) and (f not in assetsDir["ignorFile"]):
self.fileList.append(srcPath + '/' + f) #
# ,
for dire in dirList:
#
self.recursiveDir(srcPath + '/' + dire)
def getAllFile(self):
''' get all file path'''
return tuple(self.fileList)
def CalcMD5(filepath):
"""generate a md5 code by a file path"""
with open(filepath,'rb') as f:
md5obj = hashlib.md5()
md5obj.update(f.read())
return md5obj.hexdigest()
def getVersionInfo():
'''get version config data'''
configFile = open(versionConfigFile,"r")
json_data = json.load(configFile)
configFile.close()
# json_data["version"] = json_data["version"] + '.' + str(GetSvnCurrentVersion())
json_data["version"] = json_data["version"]
return json_data
def GenerateVersionManifestFile():
''' version.manifest'''
json_str = json.dumps(getVersionInfo(), indent = 2)
fo = open(versionManifestPath,"w")
fo.write(json_str)
fo.close()
def GenerateProjectManifestFile():
searchfile = SearchFile()
fileList = list(searchfile.getAllFile())
project_str = {}
project_str.update(getVersionInfo())
dataDic = {}
for f in fileList:
dataDic[f] = {"md5" : CalcMD5(f)}
print f
project_str.update({"assets":dataDic})
json_str = json.dumps(project_str, sort_keys = True, indent = 2)
fo = open(projectManifestPath,"w")
fo.write(json_str)
fo.close()
if __name__ == "__main__":
GenerateVersionManifestFile()
GenerateProjectManifestFile()
version. manifest 생 성 은 다음 과 같 습 니 다.
{
"packageUrl": "http://ip:port/update/MyProj/assets/",
"engineVersion": "3.3",
"version": "1.0.0",
"remoteVersionUrl": "http://ip:port/update/MyProj/version/version.manifest",
"remoteManifestUrl": "http://ip:port/update/MyProj/version/project.manifest"
}
procject. manifest 생 성 은 다음 과 같 습 니 다.
{
"assets": {
"src/packages/mvc/init.lua": {
"md5": "6b9173481a1300c5e737ad5885ebef00"
},
"src/protobuf.lua": {
"md5": "f790fe35eb179a4341ff41d94e488a5d"
}
...
},
"packageUrl": "http://ip:port/update/MyProj/assets/",
"engineVersion": "3.3",
"version": "1.0.0",
"remoteVersionUrl": "http://ip:port/update/MyProj/version/version.manifest",
"remoteManifestUrl": "http://ip:port/update/MyProj/version/project.manifest"
}
4. 게임 클 라 이언 트: cocos assetManager 를 이용 하여 서버 에서 파일 을 가 져 오고 자원 을 교체 합 니 다. (여기 서 바 꾸 는 것 은 실제 바 꾸 는 것 이 아니 라 Fileutils - > searchPath () 를 이용 하여 자원 파일 을 읽 는 우선 순 위 를 설정 합 니 다. 즉, 오래된 자원 과 코드 는 삭제 되 지 않 고 버 리 는 것 입 니 다.
--region *.lua
--Date
local AssetsManager = class("AssetsManager",function ()
return cc.LayerColor:create(cc.c4b(20, 20, 20, 220))
end)
function AssetsManager:ctor()
self:onNodeEvent("exit", handler(self, self.onExitCallback))
self:initUI()
self:setAssetsManage()
end
function AssetsManager:onExitCallback()
self.assetsManagerEx:release()
end
function AssetsManager:initUI()
local hintLabel = cc.Label:createWithTTF(" ...", CONFIG.TTF_FONT_2, 20)
:addTo(self)
:move(600, 80)
local progressBg = display.newSprite("sprites/hyd_progress_bg.png")
:addTo(self)
:move(600, 40)
self.progress = cc.ProgressTimer:create(display.newSprite("sprites/hyd_progress.png"))
:addTo(progressBg)
:move(380, 19)
self.progress:setType(cc.PROGRESS_TIMER_TYPE_BAR)
self.progress:setBarChangeRate(cc.p(1, 0))
self.progress:setMidpoint(cc.p(0.0, 0.5))
self.progress:setPercentage(0)
--
self.listener = cc.EventListenerTouchOneByOne:create()
self.listener:setSwallowTouches(true)
local onTouchBegan = function (touch, event)
return true
end
self.listener:registerScriptHandler(onTouchBegan, cc.Handler.EVENT_TOUCH_BEGAN)
cc.Director:getInstance():getEventDispatcher():addEventListenerWithSceneGraphPriority(self.listener, self)
end
function AssetsManager:setAssetsManage()
--
local storagePath = cc.FileUtils:getInstance():getWritablePath() .. "NewRes/"
local resPath = storagePath.. '/res/'
local srcPath = storagePath.. '/src/'
if not (cc.FileUtils:getInstance():isDirectoryExist(storagePath)) then
cc.FileUtils:getInstance():createDirectory(storagePath)
cc.FileUtils:getInstance():createDirectory(resPath)
cc.FileUtils:getInstance():createDirectory(srcPath)
end
local searchPaths = cc.FileUtils:getInstance():getSearchPaths()
table.insert(searchPaths, 1, storagePath)
table.insert(searchPaths, 2, resPath)
table.insert(searchPaths, 3, srcPath)
cc.FileUtils:getInstance():setSearchPaths(searchPaths)
self.assetsManagerEx = cc.AssetsManagerEx:create("version/project.manifest", storagePath)
self.assetsManagerEx:retain()
local eventListenerAssetsManagerEx = cc.EventListenerAssetsManagerEx:create(self.assetsManagerEx,
function (event)
self:handleAssetsManagerEvent(event)
end)
local dispatcher = cc.Director:getInstance():getEventDispatcher()
dispatcher:addEventListenerWithFixedPriority(eventListenerAssetsManagerEx, 1)
--
self.assetsManagerEx:update()
end
function AssetsManager:handleAssetsManagerEvent(event)
local eventCodeList = cc.EventAssetsManagerEx.EventCode
local eventCodeHand = {
[eventCodeList.ERROR_NO_LOCAL_MANIFEST] = function ()
print(" : ")
end,
[eventCodeList.ERROR_DOWNLOAD_MANIFEST] = function ()
print(" : ") -- ,
self:downloadManifestError()
end,
[eventCodeList.ERROR_PARSE_MANIFEST] = function ()
print(" : ")
end,
[eventCodeList.NEW_VERSION_FOUND] = function ()
print(" ")
end,
[eventCodeList.ALREADY_UP_TO_DATE] = function ()
print(" ")
self:updateFinished()
end,
[eventCodeList.UPDATE_PROGRESSION]= function ()
print(" ")
self.progress:setPercentage(event:getPercentByFile())
end,
[eventCodeList.ASSET_UPDATED] = function ()
print(" ")
end,
[eventCodeList.ERROR_UPDATING] = function ()
print(" : ")
end,
[eventCodeList.UPDATE_FINISHED] = function ()
print(" ")
self:updateFinished()
end,
[eventCodeList.UPDATE_FAILED] = function ()
print(" ")
end,
[eventCodeList.ERROR_DECOMPRESS] = function ()
print(" ")
end
}
local eventCode = event:getEventCode()
if eventCodeHand[eventCode] ~= nil then
eventCodeHand[eventCode]()
end
end
function AssetsManager:updateFinished()
self:setVisible(false)
self.listener:setEnabled(false)
end
function AssetsManager:downloadManifestError()
self:setVisible(false)
self.listener:setEnabled(false)
end
return AssetsManager
--endregion
Android apk 가 설 치 된 후에 도 핸드폰 에 apk 가 존재 합 니 다. apk 는 기록 하고 삭제 할 수 없 기 때문에 핫 업데이트 로 다운로드 한 최신 자원 은 모두 캐 시 에 존재 하고 캐 시 디 렉 터 리 를 최고 우선 순위 검색 디 렉 터 리 로 추가 합 니 다. 자원 을 불 러 올 때 최고 우선 순위 디 렉 터 리 에서 불 러 와 업 데 이 트 를 대체 하 는 역할 을 합 니 다.
cocos2dx 에는 열 업데이트 클래스 Assets Manager Ex 가 있 습 니 다. 이 클래스 로 열 경 기능 을 실현 하려 면 두 개의 파일 이 필요 합 니 다. procject. manifest 와 version. manifest 입 니 다. 여 기 는 주로 procject. manifest 파일 입 니 다.
코 코스 자체 도 핫 업데이트 모듈
AssetsManager
, AssetsManagerEx
을 봉 했다.AssetsManager
업그레이드 패 키 지 를 관리 하 는 방식 으로 먼저 버 전 번 호 를 비교 한 다음 에 URL 에 따라 해당 하 는 업그레이드 패 키 지 를 가 져 오고 업그레이드 패 키 지 를 압축 해제 하 며 자원 로드 경 로 를 설정 하고 로드 writepath
를 통 해디 렉 터 리 아래 의 최신 파일 방식 으로 업 데 이 트 를 실현 합 니 다. 문 제 는 버 전 업데이트 와 관련 되 거나 한 파일 만 바 뀌 었 을 때 사용 자 는 앞의 모든 업그레이드 내용 을 다운로드 해 야 합 니 다. 업그레이드 패 키 지 는 점점 커 집 니 다.AssetsManagerEx
는 AssetsManager
강화 판 으로 업그레이드 패 키 지 를 사용 하지 않 고 하나의 파일 로 끌 어 내 는 방식 이 다 릅 니 다. 먼저 로 컬 업데이트 설정 을 가 져 온 다음 서버 의 업데이트 설정 과 비교 하여 차이 파일 을 얻 은 다음 에 하나의 차이 점 을 가 져 옵 니 다. 로 컬 버 전이 서버 버 전 보다 클 때 로 컬 업데이트 캐 시 를 지 웁 니 다. AssetsManagerEx
여러 업데이트 시퀀스 가 병행 되 지 않 아 순서대로 시작 할 수 밖 에 없 는 문제 도 있 습 니 다. 또한 버 전 후기 에는 프로젝트 의 방대 한 프로필 에 거의 모든 파일 정보 가 포함 되 어 있어 파일 에 비해 시간 이 오래 걸 립 니 다.레 퍼 런 스
Cocos2dx Lua 열 업데이트
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Rails Turbolinks를 페이지 단위로 비활성화하는 방법원래 Turobolinks란? Turbolinks는 링크를 생성하는 요소인 a 요소의 클릭을 후크로 하고, 이동한 페이지를 Ajax에서 가져옵니다. 그 후, 취득 페이지의 데이터가 천이 전의 페이지와 동일한 것이 있...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.