设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 1819|回复: 2
打印 上一主题 下一主题

[已经解决] 怎样在特定区内播放AVI,但不影响其他事件的运行?

[复制链接]

Lv2.观梦者

梦石
0
星屑
624
在线时间
463 小时
注册时间
2009-9-29
帖子
67

开拓者

跳转到指定楼层
1
发表于 2010-6-20 11:40:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
怎样在游戏中特定区内播放AVI,但不影响其他事件的运行?是在窗口内某一范围内播放视频文件,但是角色和NPC什么的该内走还能走,求教……

点评

你的问题有人解答了,请做出回应。若10天内没有回应,将由斑竹做出认可。  发表于 2010-6-30 11:03

Lv3.寻梦者 (暗夜天使)

精灵族の天使

梦石
0
星屑
1697
在线时间
3038 小时
注册时间
2007-3-16
帖子
33731

开拓者贵宾

2
发表于 2010-6-20 18:53:03 | 只看该作者
avi播放器呢。
我知道一个,但是必须是全屏才可以播放的说……
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
3
发表于 2010-6-21 04:06:05 | 只看该作者
你用的是 FantasyDR 那个脚本么? FDR 用的是 MCI,MCI 本身就支持异步播放(默认模式),但是他为了实现同步而加了一个循环和计时机制……至于在某个区域播放,FDR 的脚本本身就支持,只不过只支持原始尺寸,不支持拉伸视频画面。你要在某个区域播放,说明你的视频尺寸没有占据整个窗口,那么直接选一个位置播放就行了

关于异步播放,我厚颜无耻地把 FDR 的脚本改了一下,给 MoviePlayer#play 新加了一个参数 sync,如果是 false 的话就表示异步播放视频,期间游戏继续运行
  1. #==============================================================================
  2. # ☆★☆ AVI播放器 ☆★☆
  3. #------------------------------------------------------------------------------
  4. # - FantasyDR
  5. # - 2006.3.8
  6. #------------------------------------------------------------------------------
  7. # MSN: [email protected]
  8. #------------------------------------------------------------------------------
  9. # Note:
  10. #
  11. #   1.游戏必须使用游戏样板工程附带的RGSS102J.dll
  12. #  
  13. #   2.在下方 PROJECT_NAME = 后面填写你的游戏工程名.
  14. #
  15. #   3.在游戏中,调用脚本事件播放你的视频文件,如果一行写不下可以在逗号后换行.
  16. #
  17. #   $MP.play(movie_name, movie_length,
  18. #            skip, fullscr,
  19. #            x, y, width, height)
  20. #
  21. # 参数说明:
  22. #
  23. #     movie_name   : 视频文件名(*.avi),必须
  24. #     movie_length : 电影时间,单位是秒,必须
  25. #             skip : 是否可以按A键跳过,true/false,默认是true
  26. #          fullscr : 是否强制为全屏幕播放,true/false,默认是false
  27. #              x,y : 视频播放的左上角坐标,默认是0,0
  28. #     width,height : 视频的宽度,可以任意.默认是640,480
  29. #
  30. # 例如:
  31. #        $MP.play("logo.avi",13,false,true)
  32. #==============================================================================


  33. # ------------------------------------------------------------------------
  34. # 高精度计时器 by FantasyDR
  35. # ------------------------------------------------------------------------
  36. # E-mail: [email protected]
  37. # ------------------------------------------------------------------------
  38. # 2005.10.18
  39. # ------------------------------------------------------------------------
  40. # 该类已经被定义为全局变量 $sys_timer
  41. # 如果只需要精确到毫秒,请设置初始化参数为true
  42. # decimal属性设置返回时间值的小数位数。
  43. # ------------------------------------------------------------------------
  44. # 下面是一些有用的方法列表,调用时写:$sys_timer.方法名
  45. # 例如 $sys_timer.clear()
  46. # ------------------------------------------------------------------------
  47. # clear() :计时器清零
  48. #   now() :获取当前经过的时间,单位毫秒
  49. # now_s() :获取当前经过的时间,单位秒
  50. # ------------------------------------------------------------------------

  51. class SystemTimer

  52. attr_accessor:decimal  #小数位数设定,默认为3

  53. def initialize(use_GetTime=false)
  54.    # 初始化,根据系统选择不同精度计时器
  55.    @qpFrequency = Win32API.new("kernel32","QueryPerformanceFrequency",'p','L')
  56.    @qpCounter = Win32API.new("kernel32","QueryPerformanceCounter",'p','L')
  57.    @tGetTime = Win32API.new("winmm","timeGetTime",'','L')
  58.    
  59.    @decimal=3
  60.    @perf_cnt=" " * 8
  61.    @time_start=" " * 8
  62.    @time_now=" " * 8
  63.    
  64.    result = @qpFrequency.call(@perf_cnt)
  65.    
  66.    if use_GetTime
  67.      result = 0
  68.    end
  69.    
  70.    if result!=0
  71.      @perf_flag=true
  72.    else
  73.      @perf_flag=false
  74.      @perf_cnt=[1000,0].pack('LL')
  75.    end
  76.    
  77.    #设置时间比例因数
  78.    @time_scale=@perf_cnt.unpack('LL')
  79.    @time_scale[0] /= 1000.0
  80.    @time_scale[1] /= 1000.0
  81.    
  82.    #起始时间清零
  83.    self.clear()
  84. end

  85. #-=====================-#
  86. # 计时器清零
  87. #-=====================-#
  88. def clear()
  89.    if @perf_flag
  90.      @qpCounter.call(@time_start)
  91.    else
  92.      @time_start=[@tGetTime.call(),0].pack('LL')
  93.    end
  94. end

  95. #-==============================-#
  96. # 获取当前经过的时间,单位毫秒
  97. #-==============================-#
  98. def now()
  99.    now_time = 0.0e1
  100.    now_time += self.timer() - self.start()
  101.    now_time /= self.scale()
  102.    return self.debug(now_time)
  103. end

  104. #-==============================-#
  105. # 获取当前经过的时间,单位秒
  106. #-==============================-#
  107. def now_s()
  108.    now_time = 0.0e1
  109.    now_time += self.timer() - self.start()
  110.    now_time /= (self.scale()*1000)   
  111.    return self.debug(now_time)
  112. end

  113. #-==============================-#
  114. # 帧错...
  115. #-==============================-#
  116. def debug(now_time)
  117.    if @decimal>0
  118.     now_time = (now_time * (10**@decimal)).floor/(10.0**@decimal)
  119.    else
  120.     now_time = now_time.floor
  121.    end
  122.    return now_time
  123.    
  124.    #以下用于debug模式
  125.    if now_time < 0
  126.      p "Timer Wrong!! Clear...",now_time,\
  127.        @perf_flag,@qpCounter,@tGetTime,
  128.        @time_now.unpack('LL')[0],@time_now.unpack('LL')[1],
  129.        @time_start.unpack('LL')[0],@time_start.unpack('LL')[1]
  130.      self.clear()
  131.      return 0.0
  132.    else
  133.      return now_time
  134.    end
  135. end

  136. #-=====================-#
  137. # 获取时间比例因数
  138. #-=====================-#
  139. def scale()
  140.    return @time_scale[0]+\
  141.           @time_scale[1]*0xffffffff
  142. end

  143. #-=====================-#
  144. # 获取起始滴答数
  145. #-=====================-#
  146. def start()
  147.    return @time_start.unpack('LL')[0]+\
  148.           @time_start.unpack('LL')[1]*0xffffffff
  149. end

  150. #-=====================-#
  151. # 获取当前的嘀哒数
  152. #-=====================-#
  153. def timer()
  154.    if @perf_flag
  155.      @qpCounter.call(@time_now)
  156.    else
  157.      @time_now=[@tGetTime.call(),0].pack('LL')
  158.    end
  159.    return @time_now.unpack('LL')[0]+\
  160.           @time_now.unpack('LL')[1]*0xffffffff
  161. end
  162. end

  163. #-------------------------------------#
  164. # 初始化自身成一个全局变量
  165. #-------------------------------------#
  166. $sys_timer=SystemTimer.new()
  167. #-------------------------------------#




  168. #==============================================================================
  169. # ☆★☆ AVI播放器 ☆★☆
  170. #------------------------------------------------------------------------------
  171. # - FantasyDR
  172. # - 2006.3.8
  173. #------------------------------------------------------------------------------
  174. # MSN: [email protected]
  175. #------------------------------------------------------------------------------
  176. # Note:
  177. #
  178. #   1.游戏必须使用游戏样板工程附带的RGSS102J.dll
  179. #  
  180. #   2.在下方 PROJECT_NAME = 后面填写你的游戏工程名.
  181. #
  182. #   3.在游戏中,调用脚本事件播放你的视频文件,如果一行写不下可以在逗号后换行.
  183. #
  184. #   $MP.play(movie_name, movie_length,
  185. #            skip, fullscr,
  186. #            x, y, width, height, loop)
  187. #
  188. # 参数说明:
  189. #
  190. #     movie_name   : 视频文件名(*.avi),必须
  191. #     movie_length : 电影时间,单位是秒,必须
  192. #             skip : 是否可以按A键跳过,true/false,默认是true
  193. #          fullscr : 是否强制为全屏幕播放,true/false,默认是false
  194. #              x,y : 视频播放的左上角坐标,默认是0,0
  195. #     width,height : 视频的宽度,可以任意.默认是640,480
  196. #             loop : 循环播放,true/false,默认是true
  197. #
  198. # 例如播放logo.avi,时间13秒,禁止跳过,强制全屏,范围(是0,0)-(640,480),循环播放
  199. #        $MP.play("logo.avi",13,false,true)
  200. #==============================================================================

  201. # ★★★请先这里填写游戏的工程名★★★

  202. PROJECT_NAME = "Project1"

  203. #==============================================================================
  204. # ■ Win32API
  205. #------------------------------------------------------------------------------
  206. #  需要用到的API
  207. #==============================================================================

  208. # 切换到全屏延时
  209. SWITCH_DELAY = 0.1

  210. # API使用的一些常数
  211. WS_EX_TOPMOST = 0x8
  212. WS_EX_TOOLWINDOW= 0x80
  213. WS_VISIBLE = 0x10000000
  214. WS_POPUP = 0x80000000
  215. GWL_HINSTANCE = (-6)
  216. WM_CLOSE = 0x10
  217. WS_CHILD = 0x40000000
  218. WS_NONE = 0x16000000
  219. CP_ACP = 0
  220. CP_UTF8 = 65001

  221. # 字符编码转换API
  222. $MP_m2w = Win32API.new('kernel32', 'MultiByteToWideChar', '%w(i,l,p,i,p,i)', 'i')
  223. $MP_w2m = Win32API.new('kernel32', 'WideCharToMultiByte', '%w(i,l,p,i,p,i,p,p)', 'i')
  224.   
  225. # 按键API
  226. $MP_keybd = Win32API.new('user32', 'keybd_event', '%w(i,i,l,l)', 'v')

  227. # 视频播放API
  228. $MP_mciSendString = Win32API.new('winmm','mciSendString','%w(p,p,l,l)','V')

  229. # 锁定窗口
  230. # hWnd,ifEnable
  231. $MP_EnableWindow = Win32API.new('user32','EnableWindow','%w(l,l)','L')

  232. # 激活窗口
  233. # hWnd
  234. $MP_SetActiveWindow = Win32API.new('user32','SetActiveWindow','%w(l)','L')

  235. # 当前活动窗口
  236. $MP_GetActiveWindow = Win32API.new('user32','GetActiveWindow','%w()','L')

  237. # hWnd,wMsg,wParam,lParam
  238. $MP_PostMessage = Win32API.new('user32','PostMessage','%w(l,l,l,p)','L')

  239. # 获取当前窗口句柄
  240. $MP_FindWindowEX = Win32API.new('user32','FindWindowEx','%w(l,l,p,p)','L')

  241. # 获取屏幕坐标
  242. $MP_ClientToScreen = Win32API.new("user32", "ClientToScreen", 'ip', 'i')

  243. # 获取hInt
  244. $MP_GetWindowLong= Win32API.new('user32','GetWindowLong','%w(l,l)','L')

  245. # 获取类名
  246. # hWnd,lpClassName,maxCount
  247. $MP_GetClassName= Win32API.new('user32','GetClassName','%w(l,p,l)','L')

  248. # 建立窗体
  249. # ExStyle,ClassName,WindowName,
  250. # style,x,y,width,height
  251. # 0,0,hInstance,0
  252. $MP_CreateWindowEX = Win32API.new('user32','CreateWindowEx','%w(l,p,p,l,l,l,l,l,l,l,l,p)','L')

  253. #==============================================================================
  254. # ■ MoviePlayer
  255. #------------------------------------------------------------------------------
  256. #  处理视频播放画面的类。
  257. #==============================================================================

  258. class MoviePlayer
  259. #--------------------------------------------------------------------------
  260. # ● 初始化
  261. #     project_name : 工程名称
  262. #--------------------------------------------------------------------------
  263. def initialize(project_name = PROJECT_NAME)
  264.    @sys_timer=SystemTimer.new()
  265.    buffer = "\0\0" * project_name.size
  266.    @project_name = "\0" * project_name.size
  267.    
  268.    $MP_m2w.call(CP_UTF8, 0, project_name, -1, buffer, project_name.size)
  269.    $MP_w2m.call(CP_ACP,0,buffer,-1,@project_name,project_name.size,0,0)
  270.    
  271.    @hWnd = $MP_FindWindowEX.call(0,0,nil,@project_name)
  272.    @hInt = $MP_GetWindowLong.call(@hWnd,GWL_HINSTANCE)
  273.    @class_name = " " * 256
  274.    $MP_GetClassName.call(@hWnd,@class_name,256)
  275. end
  276. #--------------------------------------------------------------------------
  277. # ● 是否已经全屏幕
  278. #--------------------------------------------------------------------------
  279. def is_full?
  280.    # 播放起始坐标
  281.    point = [0, 0].pack('ll')
  282.    if $MP_ClientToScreen.call(@hWnd, point) == 0
  283.      return false
  284.    end
  285.    x, y = point.unpack('ll')
  286.    if x == 0 and y == 0
  287.      return true
  288.    else
  289.      return false
  290.    end
  291. end
  292. #--------------------------------------------------------------------------
  293. # ● 切换全屏
  294. #--------------------------------------------------------------------------
  295. def switch_full
  296.    $MP_keybd.call (0xA4, 0, 0, 0)
  297.    $MP_keybd.call (13, 0, 0, 0)
  298.    $MP_keybd.call (13, 0, 2, 0)
  299.    $MP_keybd.call (0xA4, 0, 2, 0)
  300.    Graphics.update
  301.    sleep(SWITCH_DELAY)
  302.    Graphics.update
  303. end
  304. #--------------------------------------------------------------------------
  305. # ● 播放电影
  306. #     movie_name : 视频文件名(*.avi)
  307. #     movie_length : 电影时间,单位是秒
  308. #     skip : 是否可以按键跳过
  309. #     fullscr : 是否强制为全屏幕播放
  310. #     x,y,width,height: 播放的位置以及宽度
  311. #     loop : 循环播放
  312. #     sync : 同步播放
  313. #--------------------------------------------------------------------------
  314. def play(movie_name,movie_length,
  315.           skip = true,fullscr = false,
  316.           x = 0,y = 0,width = 640,height = 480,loop = true, sync = true)
  317.    # 数据不合法则退出
  318.    return true if movie_name == nil or movie_length <= 0
  319.    # 文件不存在
  320.    movie_name = Dir.getwd()+"\\"+movie_name
  321.    return true unless FileTest.exist?(movie_name)

  322.    # 窗口宽度
  323.    width -= (x + width)- 640 if (x + width) > 640
  324.    height -= (y + height)- 480 if (y + height) > 480
  325.    
  326.    if fullscr and !is_full?
  327.      self.switch_full
  328.    end
  329.    
  330.    fullscr = self.is_full?
  331.    
  332.    # 播放起始坐标
  333.    point = [x, y].pack('ll')
  334.    if $MP_ClientToScreen.call(@hWnd, point) == 0
  335.      return true
  336.    end
  337.    x, y = point.unpack('ll')
  338.    return true  if (x + width) < 0 or (y+height) < 0
  339.    
  340.    if fullscr
  341.      wnd = $MP_CreateWindowEX.call(WS_EX_TOPMOST,@class_name,@project_name,
  342.                                    WS_VISIBLE | WS_POPUP,x,y,width,height,
  343.                                    0,0,@hInt,0)
  344.    else
  345.      wnd = $MP_CreateWindowEX.call(WS_EX_TOOLWINDOW,@class_name,@project_name,
  346.                                    WS_VISIBLE | WS_POPUP,x,y,width,height,
  347.                                    0,0,@hInt,0)
  348.    end                              
  349.    # 窗体建立失败
  350.    return true if wnd == 0
  351.    
  352.    # 屏蔽原窗体
  353.    $MP_EnableWindow.call(@hWnd,0)
  354.    
  355.    $MP_mciSendString.call("open \"" + movie_name + "\"" +
  356.                           " alias FILE style 1073741824 parent " +\
  357.                            wnd.to_s,0,0,0)
  358.    if loop
  359.      $MP_mciSendString.call("play FILE repeat window",0,0,0)
  360.    else
  361.      $MP_mciSendString.call("play FILE window",0,0,0)
  362.    end
  363.    
  364.    playing = Proc.new {
  365.      @sys_timer.clear()
  366.      step = 0.1
  367.      begin
  368.        loop do
  369.          # 如果在窗口模式
  370.          unless fullscr
  371.            # 变成全屏
  372.            if self.is_full?
  373.              break
  374.            elsif sync
  375.              Graphics.update
  376.            end
  377.          end
  378.          #sleep(step)
  379.          if skip
  380.            Input.update
  381.            break if Input.trigger?(Input::A)
  382.          end
  383.          if @sys_timer.now_s >= movie_length
  384.            break
  385.          end
  386.          if sync && $MP_GetActiveWindow.call() != wnd
  387.            $MP_SetActiveWindow.call(wnd)
  388.          end
  389.        end
  390.      rescue Hangup
  391.        retry
  392.      end
  393.      # 关闭当前窗体
  394.      $MP_PostMessage.call(wnd,WM_CLOSE,0,0)
  395.      $MP_mciSendString.call("close FILE",0,0,0)
  396.      $MP_EnableWindow.call(@hWnd,1)
  397.      $MP_SetActiveWindow.call(@hWnd)
  398.    }
  399.    
  400.    sync ? playing.call : Thread.new { playing.call }
  401.    
  402.    return true
  403. end
  404. end

  405. $MP = MoviePlayer.new
复制代码
然后调用
$MP.play("split.avi",10, true, false, 10, 10, 320, 240, false, true)

参数分别是:
#     movie_name   : 视频文件名(*.avi),必须
#     movie_length : 电影时间,单位是秒,必须
#             skip : 是否可以按A键跳过,true/false,默认是true
#          fullscr : 是否强制为全屏幕播放,true/false,默认是false
#              x,y : 视频播放的左上角坐标,默认是0,0
#     width,height : 视频的宽度,可以任意.默认是640,480
#             sync : 是否同步播放

评分

参与人数 1星屑 +200 收起 理由
「旅」 + 200 认可答案

查看全部评分

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-4-25 13:40

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表