功能:游戏有更新版本时提醒玩家
作者:后知后觉(66rpg.com)
版本:Ver 1.0 2011-5-20
申明:本脚本中包含一个 获取网络数据 和一个 转码 的脚本
这两个脚本不是我写的,从哪里A来的也忘记了= =b
使用说明:
1.在下面写入你的游戏的 ini 文件名
2.在你的游戏ini文件内写入新的节名 Version 和新项目 version=游戏版本号
具体可参见范例工程
3.建立一个txt文档.在该文档内写入如下3组数据.
version=游戏最新的版本号
time=最新版本发布的时间
log=更新的日志
需要注意的是 log= 右边的内容以及以下的内容全都算是日志内容的一部分
4.将这个txt文档上传至网络 这里推荐 66rpg 的 FTP
特别注意的是.你上传以后.
要确保以后再次上传时.该文档的网络地址不会发生改变.
5.在下面写入该文档的网络地址
游戏运行时就会先下载该文档.
然后获取版本信息与本地ini里的版本信息进行比对
如果不一样则表示有新版本发布了.
所以当你发布新版本后需要更新该网络地址处的文档的内容
并且也要注意在新版本游戏的ini文件里更新那个version=新的版本号
其实这个脚本最主要使用的还是6R的FTP
66rpg的FTP开通及使用教程传送门
下图为此范例工程的更新日志.存放在6r的FTP 我的个人文件夹内
该文档的url是
http://ftp.66rpg.com/user/后知后觉/CheckGameUpdateCode.txt
用 FlashFXP 登陆 可以看见
当你的游戏更新后.更新游戏的ini以及这个txt文档.并再次将该文档上传
点击覆盖即可
这个文档的名字可以自己随便取.一个游戏用一个名字.
这是有更新提示时候的截图
这是没有更新或连接网络失败时候的截图
这两种提示的底图都可以自定义图片.
我这默认的是直接用fill_rect填充的...
不过对图片的大小有要求.具体见脚本开头处的说明.
如果不想每次运行游戏都自动检查更新.而是想做个按钮.点击后才检查更新的话.
可以把代码的最后那一行删除或者注释掉.
增加按钮的方法可以参考范例工程的 Scene_Title
在代码的开头处还提供了一些参数的设置.
其中 游戏的ini文件名和更新日志的url是核心的参数.
别的东西就是些小修小改.修改外观什么的.
- #==================================================# 本脚本来自 www.66rpg.com 使用和转载请保留此信息#===================================================begin 功能:游戏有更新版本时提醒玩家 作者:后知后觉(66rpg.com) 版本:Ver 1.0 2011-5-20 申明:本脚本中包含一个 获取网络数据 和一个 转码 的脚本 这两个脚本不是我写的,从哪里A来的也忘记了= =b 使用说明: 1.在下面写入你的游戏的 ini 文件名 2.在你的游戏ini文件内写入新的节名 Version 和新项目 version=游戏版本号 具体可参见范例工程 3.建立一个txt文档.在该文档内写入如下3组数据. version=游戏最新的版本号 time=最新版本发布的时间 log=更新的日志 需要注意的是 log= 右边的内容以及以下的内容全都算是日志内容的一部分 4.将这个txt文档上传至网络 这里推荐 66rpg 的 FTP 特别注意的是.你上传以后. 要确保以后再次上传时.该文档的网络地址不会发生改变. 5.在下面写入该文档的网络地址 游戏运行时就会先下载该文档. 然后获取版本信息与本地ini里的版本信息进行比对 如果不一样则表示有新版本发布了. 所以当你发布新版本后需要更新该网络地址处的文档的内容 并且也要注意在新版本游戏的ini文件里更新那个version=新的版本号=end#==============================================================================# ■ Hzhj#==============================================================================# 预设默认使用的字体.Font.default_name = (["黑体", "宋体"])module Hzhj # 设置游戏的 ini 文件名 IniFileName = ".\\Game.ini" # 设置更新文档所在的网络地址 UpdateLogUrl = "http://ftp.66rpg.com/user/后知后觉/CheckGameUpdateCode.txt" # 下面这 5 个字符串要注意别太长.这 5 个东西没有自动换行处理 TextVer = "最新版本:" TextTime = "发布时间:" TextLog = "更新日志:" TextLogHelp = "(PageUp/PageDown键滚动内容)" TextUpdateFalse = "已是最新版或连接网络失败" # 设置提示有更新时的背景图片名.记得打上路径.空字符串表示默认 # 图片规格 480*296 像素 边框为 16 像素 UpdateTrueBackPic = "" # 有更新时的文字色和大小 UpdateTrueFontColor = Color.new(0, 0, 0, 255) UpdateTrueFontSize = 22 # 设置提示无更新时的背景图片名.记得打上路径.空字符串表示默认 # 图片规格 480*64 像素 边框为 16 像素 UpdateFalseBackPic = "" # 无更新时的文字色和大小 UpdateFalseFontColor = Color.new(0, 0, 0, 255) UpdateFalseFontSize = 28 # 默认背景色.在没有设置背景图片时.会用背景色描绘窗口 DefaultColorA = Color.new(0, 0, 0, 255) DefaultColorB = Color.new(255, 255, 255, 255) # 设置是否提示无更新 (true/false) # 需要注意的是 在调用 Hzhj.check_for_update 的时候可以传递一个参数 也是 true/false # 只有当这 2 个都为 true 的时候 才会显示 # 那个参数可以缺省.缺省时为 true DisplayUpdateFalse = true # 更新日志内容上下滚动的速度.越大越快.最小值为 1.小于 1 会各种异常 ViewRoll = 8 module_function #-------------------------------------------------------------------------- # ● 检查更新 #-------------------------------------------------------------------------- def check_for_update(display_false = true) # 获取更新数据 info = Get_Http_Info.get_html(EasyConvH.u2s(UpdateLogUrl)) if info.nil? display_update(0, display_false) return else info = EasyConvH.s2u(info) info.gsub!(/\r/){""} info.gsub!(/\000/){""} info.sub!(/(version=)(.+)$/i){""} u_ver = $2.nil? ? "" : $2 info.sub!(/(time=)(.+)$/i){""} u_time = $2.nil? ? "" : $2 info.sub!(/(log=)(.+)/m){""} update_log = $2.nil? ? "" : $2 logs = update_log.split(/\n/) # 获取本地版本号 lpFileName = EasyConvH.u2s(IniFileName) lpReturnedString = "\0" * 256 gpps = Win32API.new("kernel32", "GetPrivateProfileString", "pppplp", "l") gpps.call("Version", "version", "", lpReturnedString, 256, lpFileName) lpReturnedString.delete!("\0") # 判断网络上提供的版本号和本地读取的版本号 if u_ver == lpReturnedString display_update(0, display_false) return end display_update(1, u_ver, u_time, logs) return end end #-------------------------------------------------------------------------- # ● 显示更新或无更新 #-------------------------------------------------------------------------- def display_update(mode, ver, time = "", logs = []) # 考虑到某些龟速网络下载更新文档可能花费大量时间. # 所以刷新一下来给接下来可能的换行处理赚取时间. Graphics.update case mode when 0 # 无更新或获取网络失败 display_no if DisplayUpdateFalse and ver when 1 # 有更新 display_yes(ver, time, logs) end end #-------------------------------------------------------------------------- # ● 显示无更新或连接网络失败 #-------------------------------------------------------------------------- def display_no Graphics.freeze sprite = Sprite.new if UpdateFalseBackPic.empty? bitmap = Bitmap.new(480, 64) bitmap.fill_rect(0, 0, 480, 64, DefaultColorA) bitmap.fill_rect(8, 8, 464, 48, DefaultColorB) else bitmap = Bitmap.new(UpdateFalseBackPic) end sprite.bitmap = bitmap sprite.ox = 240 sprite.oy = 32 sprite.x = 320 sprite.y = 240 sprite.z = 6000 bitmap.font.color = UpdateFalseFontColor bitmap.font.size = UpdateFalseFontSize bitmap.draw_text(16, 16, 448, 32, TextUpdateFalse, 1) Graphics.transition loop do Graphics.update Input.update sprite.update break if Input.trigger?(12) or Input.trigger?(13) end Graphics.freeze bitmap.dispose sprite.dispose Graphics.transition end #-------------------------------------------------------------------------- # ● 显示更新 #-------------------------------------------------------------------------- def display_yes(ver, time, logs) Graphics.freeze spriteA = Sprite.new if UpdateTrueBackPic.empty? bitmapA = Bitmap.new(480, 296) bitmapA.fill_rect(0, 0, 480, 296, DefaultColorA) bitmapA.fill_rect(8, 8, 464, 280, DefaultColorB) bitmapA.fill_rect(8, 112, 464, 8, DefaultColorA) else bitmapA = Bitmap.new(UpdateTrueBackPic) end spriteA.bitmap = bitmapA spriteA.x = 80 spriteA.y = 92 spriteA.z = 6000 bitmapA.font.color = UpdateTrueFontColor bitmapA.font.size = UpdateTrueFontSize bitmapA.draw_text(16, 16, 448, 32, TextVer + ver) bitmapA.draw_text(16, 48, 448, 32, TextTime + time) bitmapA.draw_text(16, 80, 448, 32, TextLog + TextLogHelp) viewport = Viewport.new(96, 212, 448, 160) viewport.z = 6500 spriteB = Sprite.new(viewport) nlogs = [] if not logs.empty? temp = Bitmap.new(448, 32) temp.font.size = UpdateTrueFontSize logs.each do |text| if temp.text_size(text).width 448 nlogs.push(str) str = c next end str += c end nlogs.push(str) if not str.empty? end end temp.dispose temp = nil end bitmapB = Bitmap.new(448, [nlogs.size * 32, 32].max) spriteB.bitmap = bitmapB bitmapB.font.color = UpdateTrueFontColor bitmapB.font.size = UpdateTrueFontSize view_oy_line = 0 view_oy_max_line = [nlogs.size - 5, 0].max view_target_oy = 0 if not nlogs.empty? for i in 0...nlogs.size bitmapB.draw_text(0, i * 32, 448, 32, nlogs[i]) end end Graphics.transition loop do Graphics.update Input.update viewport.update spriteA.update spriteB.update if viewport.oy > view_target_oy viewport.oy = [viewport.oy - ViewRoll, view_target_oy].max elsif viewport.oy < view_target_oy viewport.oy = [viewport.oy + ViewRoll, view_target_oy].min end if Input.trigger?(Input::L) view_oy_line = [view_oy_line - 4, 0].max view_target_oy = view_oy_line * 32 end if Input.trigger?(Input::R) view_oy_line = [view_oy_line + 4, view_oy_max_line].min view_target_oy = view_oy_line * 32 end break if Input.trigger?(12) or Input.trigger?(13) end Graphics.freeze bitmapA.dispose bitmapB.dispose spriteA.dispose spriteB.dispose viewport.dispose Graphics.transition endend#==================================================# 本脚本来自 www.66rpg.com 使用和转载请保留此信息#==================================================#------------------------------------------------------------------------------# Moonlight INN# http://cgi.members.interq.or.jp/aquarius/rasetsu/# RaTTiE# [email protected]#------------------------------------------------------------# EasyConv::s2u(text) : S-JIS -> UTF-8# EasyConv::u2s(text) : UTF-8 -> S-JIS#==============================================module EasyConvH CP_ACP = 0 CP_UTF8 = 65001 #-------------------------------------------------------------------------- # 仠 S-JIS -> UTF-8 #-------------------------------------------------------------------------- def s2u(text) m2w = Win32API.new('kernel32', 'MultiByteToWideChar', 'ilpipi', 'i') w2m = Win32API.new('kernel32', 'WideCharToMultiByte', 'ilpipipp', 'i') # S-JIS -> Unicode len = m2w.call(CP_ACP, 0, text, -1, nil, 0); buf = "\0" * (len*2) m2w.call(CP_ACP, 0, text, -1, buf, buf.size/2); # Unicode -> UTF-8 len = w2m.call(CP_UTF8, 0, buf, -1, nil, 0, nil, nil); ret = "\0" * len w2m.call(CP_UTF8, 0, buf, -1, ret, ret.size, nil, nil); return ret end module_function :s2u #-------------------------------------------------------------------------- # 仠 UTF-8 -> S-JIS #-------------------------------------------------------------------------- def u2s(text) m2w = Win32API.new('kernel32', 'MultiByteToWideChar', 'ilpipi', 'i') w2m = Win32API.new('kernel32', 'WideCharToMultiByte', 'ilpipipp', 'i') # UTF-8 -> Unicode len = m2w.call(CP_UTF8, 0, text, -1, nil, 0); buf = "\0" * (len*2) m2w.call(CP_UTF8, 0, text, -1, buf, buf.size/2); # Unicode -> S-JIS len = w2m.call(CP_ACP, 0, buf, -1, nil, 0, nil, nil); ret = "\0" * len w2m.call(CP_ACP, 0, buf, -1, ret, ret.size, nil, nil); return ret end module_function :u2send#==================================================# 本脚本来自 www.66rpg.com 使用和转载请保留此信息#==================================================class Get_Http_Info AGENT = "RGSS PLAYER" INTERNET_OPEN_TYPE_PRECONFIG = 0 # IEの設定を仕様 INTERNET_OPEN_TYPE_DIRECT = 1 # プロキシを使用しない def Get_Http_Info.InternetOpen() io = Win32API.new('wininet', 'InternetOpen', %(p, l, p, p, l), 'l') hInternet = io.call(AGENT, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0) return hInternet end def Get_Http_Info.InternetOpenUrl(hSession, url) iou = Win32API.new('wininet', 'InternetOpenUrl', %(l, p, p, l, l, l), 'l') hService = iou.call(hSession, url, nil, 0, 0, 0) return hService end def Get_Http_Info.InternetReadFile(hService) content = "" read_size = 1024 # 一次读入文件的尺寸 irf = Win32API.new('wininet', 'InternetReadFile', %(l, p, i, p), 'i') while(true) buf = "\0" * read_size red = [0].pack('L') irf.call( hService, buf, read_size, red ) if (red.unpack('L') == [0]) # 读到文件末端 break end buf.delete!("\0") content += buf end return content end HTTP_QUERY_STATUS_CODE = 19 def Get_Http_Info.HttpQueryInfo(hService) read_size = 1024 buf = "\0" * read_size red = [read_size-1].pack('L') hqi = Win32API.new('wininet', 'HttpQueryInfo', %(l, l, p, p, p), 'i') isOk = hqi.call( hService, HTTP_QUERY_STATUS_CODE, buf, red, nil) buf.delete!("\0") return buf end def Get_Http_Info.InternetCloseHandle(hInternet) ich = Win32API.new('winInet', 'InternetCloseHandle', %(l), 'i') isOk = ich.call(hInternet) return isOk end HTTP_CODE_OK = "200" def Get_Http_Info.get_info(url) info = nil begin hInternet = InternetOpen() if (hInternet != 0) hService = InternetOpenUrl(hInternet, url) if (hService != 0) status_code = HttpQueryInfo(hService) if (status_code == HTTP_CODE_OK) info = InternetReadFile(hService) end InternetCloseHandle(hService) end InternetCloseHandle(hInternet) end rescue # 例外发生 return nil end ary = [] info.each_line do |line| next if line.empty? ary.push line end return ary[271].scan(/\w+/) end def Get_Http_Info.get_html(url) info = nil begin hInternet = InternetOpen() if (hInternet != 0) hService = InternetOpenUrl(hInternet, url) if (hService != 0) status_code = HttpQueryInfo(hService) if (status_code == HTTP_CODE_OK) info = InternetReadFile(hService) end InternetCloseHandle(hService) end InternetCloseHandle(hInternet) end rescue # 例外发生 return nil end return info endend#==================================================# 本脚本来自 www.66rpg.com 使用和转载请保留此信息#==================================================Hzhj.check_for_update(false)复制代码
复制代码
本帖来自P1论坛作者后知后觉,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:
https://rpg.blue/forum.php?mod=viewthread&tid=182474 若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。