じ☆ve冰风 发表于 2024-4-19 22:06:58

游戏更新提示 - 让你的游戏更新后,玩家运行游戏时得到提示~

    功能:游戏有更新版本时提醒玩家
    作者:后知后觉(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 的时候 才会显示# 那个参数可以缺省.缺省时为 trueDisplayUpdateFalse = 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    endend#--------------------------------------------------------------------------# ● 显示更新或无更新#--------------------------------------------------------------------------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)    endend#--------------------------------------------------------------------------# ● 显示无更新或连接网络失败#--------------------------------------------------------------------------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.transitionend#--------------------------------------------------------------------------# ● 显示更新#--------------------------------------------------------------------------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).width448            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, .max)    spriteB.bitmap = bitmapB    bitmapB.font.color = UpdateTrueFontColor    bitmapB.font.size = UpdateTrueFontSize    view_oy_line = 0    view_oy_max_line = .max    view_target_oy = 0    if not nlogs.empty?      for i in 0...nlogs.size      bitmapB.draw_text(0, i * 32, 448, 32, nlogs)      end    end    Graphics.transition    loop do      Graphics.update      Input.update      viewport.update      spriteA.update      spriteB.update      if viewport.oy > view_target_oy      viewport.oy = .max      elsif viewport.oy < view_target_oy      viewport.oy = .min      end      if Input.trigger?(Input::L)      view_oy_line = .max      view_target_oy = view_oy_line * 32      end      if Input.trigger?(Input::R)      view_oy_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.transitionendend#==================================================# 本脚本来自 www.66rpg.com 使用和转载请保留此信息#==================================================#------------------------------------------------------------------------------# Moonlight INN# http://cgi.members.interq.or.jp/aquarius/rasetsu/# RaTTiE# #------------------------------------------------------------# EasyConv::s2u(text) : S-JIS -> UTF-8# EasyConv::u2s(text) : UTF-8 -> S-JIS#==============================================module EasyConvHCP_ACP = 0CP_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 retendmodule_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 retendmodule_function :u2send#==================================================# 本脚本来自 www.66rpg.com 使用和转载请保留此信息#==================================================class Get_Http_InfoAGENT = "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 hInternetend    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 hServiceend    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 = .pack('L')      irf.call( hService, buf, read_size, red )      if (red.unpack('L') == )      # 读到文件末端      break      end      buf.delete!("\0")      content += buf    end    return contentend    HTTP_QUERY_STATUS_CODE = 19    def Get_Http_Info.HttpQueryInfo(hService)    read_size = 1024    buf = "\0" * read_size    red = .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 bufend    def Get_Http_Info.InternetCloseHandle(hInternet)    ich = Win32API.new('winInet', 'InternetCloseHandle', %(l), 'i')    isOk = ich.call(hInternet)    return isOkend    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.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 infoendend#==================================================# 本脚本来自 www.66rpg.com 使用和转载请保留此信息#==================================================Hzhj.check_for_update(false)复制代码



             本帖来自P1论坛作者后知后觉,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=182474若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
页: [1]
查看完整版本: 游戏更新提示 - 让你的游戏更新后,玩家运行游戏时得到提示~