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

Project1

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

[RMVA发布] VA简易鼠标完整

[复制链接]

Lv2.观梦者

傻♂逼

梦石
0
星屑
374
在线时间
1606 小时
注册时间
2007-3-13
帖子
6562

烫烫烫开拓者

跳转到指定楼层
1
发表于 2012-1-2 01:54:17 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 yangff 于 2012-1-2 14:43 编辑

基本和VX鼠标统一接口了,有几个函数不是很理解就暂时没弄。。
WndProc的代码使用了@晴兰http://rpg.blue/thread-216658-1-1.html 不过他的那段有点问题所以这里放的是修改好的。
  1. $apicache = {}
  2. class String
  3.    def apicall(*args)
  4.        $apicache[self] = Win32API.new(*self.split("|")) unless $apicache.include? self
  5.        $apicache[self].call(*args)
  6.    end
  7. end

  8. class Symbol
  9.   def method_missing(*args, &block)
  10.         self.to_s.send(*args, &block)
  11.   end
  12. end
  13. class Win32API
  14.   WM_ACTIVATEAPP=0x1C
  15.   WM_MOUSEMOVE=0x200
  16.   WM_MOUSEWHEEL = 0x020A
  17.   WM_LBUTTONDOWN = 0x201
  18.   WM_RBUTTONDOWN = 0x204
  19.   WM_MOUSEDOWN = 0x210
  20.   WM_LBUTTONUP = 0x202
  21.   WM_RBUTTONUP = 0x205
  22.   WM_LBUTTONDBLCLK  = 0x203
  23.   WM_RBUTTONDBLCLK  = 0x204
  24. end
  25. module Roost   
  26.     module MainWindow
  27.         def self.getwndproc
  28.            @wndproc
  29.          end
  30.         def self.setwndproc(obj)
  31.            @wndproc=obj
  32.         end
  33.         def self.addwndproc(obj)
  34.           @@wndprocs.push(obj)
  35.         end
  36.         @@wndprocs=[]
  37.         @wndproc = lambda {|hwnd, msg, wp, lp|
  38.           @@handle=false
  39.           for i in @@wndprocs
  40.             i.call(hwnd, msg, wp, lp)
  41.           end
  42.           return Roost::MainWindow.use_rm_proc(hwnd, msg, wp, lp)
  43.         }
  44.         def self.use_rm_proc(hwnd,msg,wp,lp)
  45.           if (not @@handle)
  46.             @@handle=true
  47.             return :"user32|CallWindowProc|iiiii|i".apicall(@@oHandle,hwnd,msg,wp,lp)
  48.           end
  49.         end
  50.         def self.disable_rm_proc
  51.           @@handle=true
  52.         end
  53.         def self.enable
  54.               Roost::MainWindow.instance_eval do
  55.                 def self.enable
  56.                 end
  57.               end
  58.             Roost::MainWindow.instance_eval do
  59.               @msg = "\0"*24
  60.               @hwnd = 0
  61.               while @hwnd==0
  62.                :"user32|GetMessage|piii|v".apicall(@msg, 0, 0, 0)
  63.                @kmsg = @msg
  64.                :"user32|TranslateMessage|p|v".apicall(@kmsg)
  65.                :"user32|DispatchMessage|p|v".apicall(@kmsg)
  66.                @hwnd = @msg.unpack("i*")[0]
  67.              end
  68.             @hdc = :"user32|GetDC|i|i".apicall(@hwnd)
  69.             def self.hwnd
  70.                return @hwnd
  71.             end
  72.             def self.hdc
  73.               return @hdc
  74.             end
  75.             
  76.             def self.findProc(l, n)
  77.                    lib = :"kernel32|LoadLibrary|p|i".apicall(l);
  78.                    ret = :"kernel32|GetProcAddress|ip|l".apicall(lib, n);
  79.                    :"kernel32|FreeLibrary|l|v".apicall(lib)
  80.                    return ret
  81.             end
  82.                  def self.loadfindProc(l, n)
  83.                    lib = :"kernel32|LoadLibrary|p|i".apicall(l);
  84.                    ret = :"kernel32|GetProcAddress|ip|l".apicall(lib, n);
  85.                    return ret
  86.             end
  87.             def self.enableWndProc
  88.               Roost::MainWindow.instance_eval do
  89.                 def self.enableWndProc
  90.                 end
  91.               end
  92.               @malloc = :"msvcrt|malloc|i|i"
  93.               @memcpy = :"msvcrt|memcpy|ipi|v"
  94.               
  95.               
  96.              sprintf    = self.findProc("msvcrt",    "sprintf")
  97.              rgsseval   = self.findProc("RGSS300",  "RGSSGetInt")
  98.              old        = :"user32|GetWindowLong|ll|l".apicall(@hwnd, -4)
  99.              buf        = @malloc.apicall(1024)  
  100.              fmt        = @malloc.apicall(2048)
  101.              sprintfvar = @malloc.apicall(8)
  102.              rgssevalvar= @malloc.apicall(8)
  103.              oldvar     = @malloc.apicall(8)
  104.              fmtvar     = @malloc.apicall(8)
  105.              bufvar     = @malloc.apicall(8)
  106.              defvar     = @malloc.apicall(8)
  107.             
  108.              :"msvcrt|strcpy|pp|p".apicall(fmt, "Roost::MainWindow.getwndproc.call(%d,%d,%d,%d)")
  109.             
  110.              @memcpy.apicall(sprintfvar, [sprintf].pack("i"),  4)
  111.              @memcpy.apicall(rgssevalvar,[rgsseval].pack("i"), 4)
  112.              @memcpy.apicall(oldvar,     [old].pack("i"),      4)
  113.              @memcpy.apicall(fmtvar,     [fmt].pack("i"),      4)
  114.              @memcpy.apicall(bufvar,     [buf].pack("i"),      4)
  115.              @memcpy.apicall(defvar,     [self.findProc("user32", "DefWindowProcA")].pack("i"),      4)
  116.             
  117.              @code = [0x55,0x89,0xe5,0xff,0x75,0x14,
  118.                       0xff,0x75,0x10,0xff,0x75,0x0c,
  119.                       0xff,0x75,0x08,0xff,0x35].pack('C*')
  120.              @code << [fmtvar].pack('l') << [0xff, 0x35].pack('C*')
  121.              @code << [bufvar].pack('l') << [0xff, 0x15].pack('C*')
  122.              @code << [sprintfvar].pack("l")
  123.              @code << [0xff, 0x15].pack('C*')
  124.              @code << [rgssevalvar].pack("l")
  125. =begin
  126.              @code << [0x83,0xc4,0x18, 0xff, 0x75, 0x14,
  127.                        0xff,0x75, 0x10, 0xff, 0x75, 0x0c,
  128.                        0xff,0x75, 0x08, 0xff, 0x15].pack('C*')
  129.              @code << [oldvar].pack("l")
  130. =end
  131.              @code << [0x83,0xc4,0x18].pack('C*')
  132.              @code << [0xc9,0xc2,0x10,0x00].pack('C*')
  133.              #0xD1, 0xE8
  134.              @shellcode = @malloc.apicall(2048)  
  135.              @memcpy.apicall(@shellcode, @code, @code.size)
  136.              @@oHandle= :"user32|SetWindowLong|iii|i".apicall(@hwnd, -4, @shellcode)
  137.               #Returning Test : should be 5
  138.               #Roost::MainWindow.setwndproc (lambda{|hwnd, msg, wp, lp| 5})
  139.               #p :"user32|CallWindowProc|iiiii|i".apicall(@shellcode, 0, 0, 0, 0)
  140.             end
  141.           end
  142.          
  143.         end
  144.         
  145.   end
  146. end

  147. Roost::MainWindow.enable
  148. Roost::MainWindow.enableWndProc
  149. module Mouse
  150.   module_function
  151.   LKEY,RKEY,MKEY   = 1,2,4
  152.   DBLCTIME         = (Win32API.new('user32','GetDoubleClickTime','','l').call * 60.0 / 1000).round
  153.   @count    = 0     ## 双击时间计数
  154.   @dblc     = []    ## 双击记录[key,wait,[mouse_x,mouse_y]]
  155.   @move_pos = []    ## 移动记录
  156.   @clicks   = []    ## 单击记录
  157.   def _init_
  158.     @press,@toggled=0,0
  159.    
  160.     @pos=[0,0]

  161.     Roost::MainWindow.addwndproc (lambda {|hwnd, msg, wp, lp|
  162.       Mouse.onLMouseDown if msg==Win32API::WM_LBUTTONDOWN
  163.       Mouse.onRMouseDown if msg==Win32API::WM_RBUTTONDOWN
  164.       Mouse.onLMouseUp if msg==Win32API::WM_LBUTTONUP
  165.       Mouse.onRMouseUp if msg==Win32API::WM_RBUTTONUP
  166.       Mouse.onLMouseDD if msg==Win32API::WM_LBUTTONDBLCLK
  167.       Mouse.onRMouseDD if msg==Win32API::WM_RBUTTONDBLCLK
  168.       if msg==Win32API::WM_MOUSEMOVE
  169.         Mouse.setMouse([lp&0xffff,lp>>16])
  170.       end
  171.     })
  172.     @ldown=false
  173.     @ltd=false
  174.     @rdown=false
  175.     @rtd=false
  176.     @lup=false
  177.     @rup=false
  178.   end
  179.   def onLMouseDown
  180.     @ltd=true
  181.     @ltd=false if @ldown
  182.     @ldown=true
  183.   end
  184.   def onLMouseUp
  185.     @ldown=false
  186.     @ltd=false
  187.   end
  188.   def onLMouseDD
  189.    
  190.   end
  191.   def onRMouseDown
  192.     @rtd=true
  193.     @rtd=false if @rdown
  194.     @rdown=true
  195.    
  196.   end
  197.   def onRMouseUp
  198.     @rdown=false
  199.     @rtd=false
  200.   end
  201.   def onRMouseDD
  202.    
  203.   end
  204.   def setMouse(p)
  205.     @pos=p
  206.   end
  207.   
  208.   #--------------------------------------------------------------------------
  209.   # ## 触发?
  210.   #--------------------------------------------------------------------------
  211.   def self.toggled?(key)
  212.     return @toggled & key != 0
  213.   end
  214.   #--------------------------------------------------------------------------
  215.   # ## 按下?
  216.   #--------------------------------------------------------------------------
  217.   def Mouse.press?(key)
  218.     return @press & key != 0
  219.   end
  220.   #--------------------------------------------------------------------------
  221.   # ## 单击?
  222.   #--------------------------------------------------------------------------
  223.   def self.click?(key)
  224.     return false if key == LKEY and !$click_abled
  225.     return @clicks[0] & key == 0 && @clicks[1] & key != 0
  226.   end
  227.   #--------------------------------------------------------------------------
  228.   # ## 双击?
  229.   #--------------------------------------------------------------------------
  230.   def self.dbl_click?(key)
  231.     return false if @dblc.size < 2
  232.     ## 键值有效
  233.     if @dblc[1][0] & key != 0 and @dblc[0][0] & key != 0
  234.       ## 间隔有效
  235.       if @dblc[1][1] - @dblc[0][1] < DBLCTIME
  236.         ## 坐标有效
  237.         if @dblc[1][2] == @dblc[0][2]
  238.           return @clicks[0] & key == 0 && @clicks[1] & key != 0
  239.         end
  240.       end
  241.     end
  242.     return false
  243.   end
  244.   def pos
  245.     return @pos
  246.   end
  247.   def update
  248.     @press,@toggled=0,0
  249.     @press += LKEY   if @ldown
  250.     @press += RKEY   if @rdown
  251.     @toggled += LKEY if @ltd
  252.     @toggled += RKEY  if @rtd
  253.     @clicks.shift if @clicks.size >=2
  254.     @clicks.push @press
  255.     if @dblc.size >= 2
  256.       @dblc.clear
  257.       @count = 0
  258.     end
  259.     if @dblc.size == 1 and @count - @dblc[0][1] > DBLCTIME
  260.       @dblc.clear
  261.       @count = 0
  262.     end
  263.     if @clicks[0] == 0 and @clicks[1] != 0
  264.       if @dblc.size == 1 and @dblc[0][0] != @clicks[1]
  265.         @dblc.clear
  266.         @count = 0
  267.       end
  268.       @dblc.push [@press,@count,@pos]
  269.     end
  270.     @count += 1 unless @dblc.empty?
  271.     @move_pos.shift if @move_pos.size >= 2
  272.     @move_pos.push @pos
  273.     $click_abled=true
  274.   end
  275.   def down(p)
  276.     if (p==LEFT)
  277.       return @ldown
  278.     else
  279.       return @rdown
  280.     end
  281.   end
  282. end

  283. Mouse._init_






  284. class << Mouse
  285.   Win32API.new('user32', 'ShowCursor', 'l', 'l').call(0)
  286.   $mousec = Sprite.new
  287.   $mousec.z = 10001
  288.   $mousec.x = $mousec.y = 1000
  289.   $mouse_icon = 'Pointer'
  290.   $mousec.bitmap = Cache.system($mouse_icon)
  291.   
  292.   alias wor_mouse_upd_mouse update unless $@
  293.   def Mouse.update
  294.     wor_mouse_upd_mouse
  295.     if $mouse_old_icon.nil? or $mouse_old_icon != $mouse_icon
  296.       $mouse_old_icon = $mouse_icon
  297.       $mousec.bitmap = Cache.system($mouse_old_icon)
  298.     end
  299.     if @pos.nil?
  300.       $mousec.x = 1000 if $mousec.x != 1000
  301.       $mousec.y = 1000 if $mousec.y != 1000
  302.       Win32API.new('user32', 'ShowCursor', 'l', 'l').call(1)
  303.     else
  304.       $mousec.x = @pos[0] if $mousec.x != @pos[0]
  305.       $mousec.y = @pos[1] if $mousec.y != @pos[1]
  306.       Win32API.new('user32', 'ShowCursor', 'l', 'l').call(0)
  307.     end
  308.     ## 鼠标刷新
  309.     $mousec.update
  310.   end
  311.   #--------------------------------------------------------------------------
  312.   # ## 经过?
  313.   #     obj       : 对象实例
  314.   #                 **支持Sprite,Window,Viewport,Rect,Plane,可补充
  315.   #--------------------------------------------------------------------------
  316.   def Mouse.over?(obj)
  317.     case obj
  318.     when Sprite
  319.       x = obj.x-obj.ox; y = obj.y-obj.oy
  320.       unless obj.viewport.nil?
  321.         x += obj.viewport.rect.x
  322.         y += obj.viewport.rect.y
  323.       end
  324.       return Mouse.area?(x, y, obj.width, obj.height)
  325.     when Window
  326.       x = obj.x;y = obj.y
  327.       unless obj.viewport.nil?
  328.         x += obj.viewport.rect.x
  329.         y += obj.viewport.rect.y
  330.       end
  331.       return Mouse.area?(x, y, obj.width, obj.height)
  332.     when Viewport
  333.       return Mouse.area?(obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height)
  334.     when Rect
  335.       return Mouse.area?(obj.x, obj.y, obj.width, obj.height)
  336.     when Plane
  337.       x = obj.x;y = obj.y
  338.       unless obj.viewport.nil?
  339.         x += obj.viewport.rect.x
  340.         y += obj.viewport.rect.y
  341.       end
  342.       return Mouse.area?(x, y, obj.width, obj.height)
  343.     end
  344.   end
  345.   #--------------------------------------------------------------------------
  346.   # * Mouse in_area
  347.   #--------------------------------------------------------------------------
  348.   def Mouse.area?(x, y, width=32, height=32)
  349.     return false if @pos == nil
  350.     return true if @pos[0] >= x and @pos[0] <= (x+width) and @pos[1] >= y and @pos[1] <= (y+height)
  351.     return false
  352.   end

  353. end







  354. #==============================================================================
  355. # ## Window_Selectable
  356. #==============================================================================
  357. class Window_Selectable < Window_Base
  358.   alias wor_winsel_ini_mouse initialize
  359.   alias wor_winsel_upd_mouse update
  360.   def initialize(*args)
  361.     wor_winsel_ini_mouse(*args)
  362.     @scroll_wait = 0
  363.     @cursor_wait = 0
  364.   end

  365.   def update
  366.     wor_winsel_upd_mouse
  367.     if self.active and self.visible
  368.       update_mouse
  369.     end
  370.   end
  371.   
  372.   def update_mouse
  373.     @cursor_wait -= 1 if @cursor_wait > 0
  374.     (0...item_max).each do |i|
  375.       irect = mouse_rect(i)
  376.       irx = self.x + 16 + irect.x - self.ox
  377.       iry = self.y + 16 + irect.y - self.oy
  378.       result = Mouse.area?(irx, iry, irect.width, irect.height)
  379.       move_cursor(i) if result
  380.       ## 控制单击条件
  381.       $click_abled = false if i == @index and !result
  382.     end

  383.   end
  384.   
  385.   ## 鼠标区域
  386.   def mouse_rect(i)
  387.     rect = item_rect(i)
  388.     return rect if rect.width <= 32
  389.     rect.x += 4
  390.     rect.y += 4
  391.     rect.width -= 8
  392.     rect.height -= 8
  393.     return rect
  394.   end
  395.   def column_max
  396.     return row_max
  397.   end
  398.   def move_cursor(index)
  399.     ## 不响应
  400.     return if @cursor_wait > 0
  401.     return if self.index == index
  402.     @scroll_wait -= 1 if @scroll_wait > 0
  403.     row1 = self.index / column_max
  404.     row2 = index / column_max
  405.     bottom = self.top_row + (self.page_row_max - 1)
  406.     if row1 == self.top_row and row2 < self.top_row
  407.       return if @scroll_wait > 0
  408.       self.index = [self.index - column_max, 0].max
  409.       @scroll_wait = 4
  410.     elsif row1 == bottom and row2 > bottom
  411.       return if @scroll_wait > 0
  412.       self.index = [self.index + column_max, item_max - 1].min
  413.       @scroll_wait = 4
  414.     else
  415.       self.index = index
  416.     end
  417.     return if @cursor_wait > 0
  418.     Sound.play_cursor
  419.     @cursor_wait += 2
  420.   end
  421. end

  422. #==============================================================================
  423. # ** Input
  424. #==============================================================================
  425. class << Input
  426.   alias wor_input_upd_mouse update unless $@
  427.   alias wor_input_trig_mouse trigger? unless $@
  428.   alias wor_input_rep_mouse repeat? unless $@
  429.   def Input.update
  430.     wor_input_upd_mouse
  431.     Mouse.update
  432.   end
  433.   def Input.trigger?(input)

  434.     return wor_input_trig_mouse(input) if Mouse.pos.nil?
  435.     case input
  436.     when Input::B
  437.       return (wor_input_trig_mouse(input) or Mouse.click?(Mouse::RKEY))
  438.     when Input::C
  439.       if SceneManager.scene.is_a?(Scene_Map) and !$game_message.visible
  440.         return wor_input_trig_mouse(input)
  441.       else
  442.         return (wor_input_trig_mouse(input) or Mouse.click?(Mouse::LKEY))
  443.       end
  444.     else
  445.       return wor_input_trig_mouse(input)
  446.     end
  447.   end
  448.   
  449.   def Input.repeat?(input)

  450.     if input == Input::B
  451.       return (wor_input_rep_mouse(input) or Mouse.click?(Mouse::RKEY))
  452.     else
  453.       return wor_input_rep_mouse(input)
  454.     end
  455.   end
  456. end


复制代码

点评

alias wor_input_rep_mouse repeat? unless $@ 这种代码改掉吧(异常信息可能会被清空的 对于某些脚本(:比如cc.call  发表于 2012-1-12 19:27

评分

参与人数 2星屑 +14 +2 收起 理由
hys111111 + 14
退屈£无聊 + 2

查看全部评分

哎呀,蛋疼什么的最有爱了

Lv1.梦旅人

梦石
0
星屑
67
在线时间
29 小时
注册时间
2009-7-24
帖子
69
2
发表于 2012-1-2 16:09:51 | 只看该作者
貌似不能和图片存档脚本兼容?打开存档选中图片存档就会报错。
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
152 小时
注册时间
2010-7-4
帖子
144
3
发表于 2012-1-11 21:53:02 | 只看该作者
本帖最后由 a88953327 于 2012-1-11 21:54 编辑

应该不能与图片存档一起 我的也错误了 缺少图片的说
[/img]
回复 支持 反对

使用道具 举报

Lv2.观梦者

虚構歪曲

梦石
0
星屑
364
在线时间
1198 小时
注册时间
2010-12-18
帖子
3928

贵宾

4
发表于 2012-1-11 21:58:22 | 只看该作者
400 行……
回复 支持 反对

使用道具 举报

Lv2.观梦者

傻♂逼

梦石
0
星屑
374
在线时间
1606 小时
注册时间
2007-3-13
帖子
6562

烫烫烫开拓者

5
 楼主| 发表于 2012-1-11 22:23:21 | 只看该作者
忧雪の伤 发表于 2012-1-11 21:58
400 行……

大部分是兼容VX的鼠标接口,核心貌似就10行。。

点评

鼠标也分版本的么。  发表于 2012-1-11 23:02
哎呀,蛋疼什么的最有爱了
回复 支持 反对

使用道具 举报

Lv2.观梦者

梦石
0
星屑
271
在线时间
2088 小时
注册时间
2011-7-28
帖子
1145
6
发表于 2012-1-12 14:09:02 | 只看该作者
如果不嫌弃就把 拿去
顺带图名要为Pointer
[color=Red][b]我没有签名[/b][/color]
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
144 小时
注册时间
2011-11-26
帖子
161
7
发表于 2012-1-14 17:32:07 | 只看该作者
貌似不能用鼠标来移动人

点评

@yangff 球搜索关键字!!另有没有点中NPC事件能触发对话等事件的脚本~~~  发表于 2013-2-5 11:37
请自行搜索相关脚本  发表于 2012-1-14 20:05
回复 支持 反对

使用道具 举报

Lv1.梦旅人

王牌

梦石
0
星屑
50
在线时间
188 小时
注册时间
2011-5-16
帖子
224
8
发表于 2012-1-28 22:05:32 | 只看该作者
为什么用了以后 就是一张鼠标的图片挂在左上角 不能移动 而起标题画面那里还连那张鼠标图片都看不见==

点评

我也是- -。。  发表于 2012-6-10 06:52
      
回复 支持 反对

使用道具 举报

Lv2.观梦者

梦石
0
星屑
626
在线时间
282 小时
注册时间
2006-4-9
帖子
203
9
发表于 2012-1-28 22:40:01 | 只看该作者
[ 本帖最后由 忧雪の伤 于 2012-1-29 12:00 编辑 ]

http://www.rpgmakervxace.net/index.php?/topic/152-mouse-system/
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
18 小时
注册时间
2009-11-6
帖子
15
10
发表于 2012-2-14 22:00:31 | 只看该作者
全屏后鼠标有卡顿现象..望解决
          另求<8向寻路脚本>
喜欢RPG
喜欢玩RPG
喜欢做RPG
喜欢玩自己的RPG
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-11-28 10:02

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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