查看: 3741|回复: 3

[已经解决] 8v求类似于xp里的鼠标系统(翻页功能)和图片响应

[复制链接]
梦石
0
星屑
50
在线时间
977 小时
注册时间
2011-5-13
回帖
245
发表于 2012-9-2 16:44:15 来自手机 | 显示全部楼层 |阅读模式
悬赏8星屑已解决
本帖最后由 纳尔德 于 2012-9-2 18:05 编辑

如果有能力可以移植,xp-va,或者vx-va都行。鼠标系统要求简单,能达到点击效果,右键返回,结合图片响应。
当鼠标点到这个图片执行公共事件。
另外还有一个翻页功能,就是当物品数达到一页满鼠标可以翻页,详情参考以下。
http://rpg.blue/forum.php?mod=viewthread&tid=225935
http://rpg.blue/forum.php?mod=viewthread&tid=224428

至少达到以上两个帖子内的效果。当然能优化的可以适当优化。
求va大师帮帮忙。

最佳答案

查看完整内容

首先鼠标脚本基本上通用。。不过我用的是杨菲菲的鼠标。。如果是用其他的就不一定能用。。因为方法不一样。。首先是杨菲菲的脚本 [pre lang="ruby" line="1"]$apicache = {} class String def apicall(*args) $apicache[self] = Win32API.new(*self.split("|")) unless $apicache.include? self $apicache[self].call(*args) end end class Symbol def method_missing(*args, &block) self.to_s.se ...
梦石
0
星屑
2306
在线时间
1010 小时
注册时间
2012-4-30
回帖
1455

开拓者

发表于 2012-9-2 16:44:16 | 显示全部楼层
首先鼠标脚本基本上通用。。不过我用的是杨菲菲的鼠标。。如果是用其他的就不一定能用。。因为方法不一样。。首先是杨菲菲的脚本
[pre lang="ruby" line="1"]$apicache = {}
class String
   def apicall(*args)
       $apicache[self] = Win32API.new(*self.split("|")) unless $apicache.include? self
       $apicache[self].call(*args)
   end
end

class Symbol
  def method_missing(*args, &block)
        self.to_s.send(*args, &block)
  end
end
class Win32API
  WM_ACTIVATEAPP=0x1C
  WM_MOUSEMOVE=0x200
  WM_MOUSEWHEEL = 0x020A
  WM_LBUTTONDOWN = 0x201
  WM_RBUTTONDOWN = 0x204
  WM_MOUSEDOWN = 0x210
  WM_LBUTTONUP = 0x202
  WM_RBUTTONUP = 0x205
  WM_LBUTTONDBLCLK  = 0x203
  WM_RBUTTONDBLCLK  = 0x204
end
module Roost   
    module MainWindow
        def self.getwndproc
           @wndproc
         end
        def self.setwndproc(obj)
           @wndproc=obj
        end
        def self.addwndproc(obj)
          @@wndprocs.push(obj)
        end
        @@wndprocs=[]
        @wndproc = lambda {|hwnd, msg, wp, lp|
          @@handle=false
          for i in @@wndprocs
            i.call(hwnd, msg, wp, lp)
          end
          return Roost::MainWindow.use_rm_proc(hwnd, msg, wp, lp)
        }
        def self.use_rm_proc(hwnd,msg,wp,lp)
          if (not @@handle)
            @@handle=true
            return :"user32|CallWindowProc|iiiii|i".apicall(@@oHandle,hwnd,msg,wp,lp)
          end
        end
        def self.disable_rm_proc
          @@handle=true
        end
        def self.enable
              Roost::MainWindow.instance_eval do
                def self.enable
                end
              end
            Roost::MainWindow.instance_eval do
              @msg = "\0"*24
              @hwnd = 0
              while @hwnd==0
               :"user32|GetMessage|piii|v".apicall(@msg, 0, 0, 0)
               @kmsg = @msg
               :"user32|TranslateMessage|p|v".apicall(@kmsg)
               :"user32|DispatchMessage|p|v".apicall(@kmsg)
               @hwnd = @msg.unpack("i*")[0]
             end
            @hdc = :"user32|GetDC|i|i".apicall(@hwnd)
            def self.hwnd
               return @hwnd
            end
            def self.hdc
              return @hdc
            end
            
            def self.findProc(l, n)
                   lib = :"kernel32|LoadLibrary|p|i".apicall(l);
                   ret = :"kernel32|GetProcAddress|ip|l".apicall(lib, n);
                   :"kernel32|FreeLibrary|l|v".apicall(lib)
                   return ret
            end
                 def self.loadfindProc(l, n)
                   lib = :"kernel32|LoadLibrary|p|i".apicall(l);
                   ret = :"kernel32|GetProcAddress|ip|l".apicall(lib, n);
                   return ret
            end
            def self.enableWndProc
              Roost::MainWindow.instance_eval do
                def self.enableWndProc
                end
              end
              @malloc = :"msvcrt|malloc|i|i"
              @memcpy = :"msvcrt|memcpy|ipi|v"
              
              
             sprintf    = self.findProc("msvcrt",    "sprintf")
             rgsseval   = self.findProc("RGSS300",  "RGSSGetInt")
             old        = :"user32|GetWindowLong|ll|l".apicall(@hwnd, -4)
             buf        = @malloc.apicall(1024)  
             fmt        = @malloc.apicall(2048)
             sprintfvar = @malloc.apicall(8)
             rgssevalvar= @malloc.apicall(8)
             oldvar     = @malloc.apicall(8)
             fmtvar     = @malloc.apicall(8)
             bufvar     = @malloc.apicall(8)
             defvar     = @malloc.apicall(8)
            
             :"msvcrt|strcpy|pp|p".apicall(fmt, "Roost::MainWindow.getwndproc.call(%d,%d,%d,%d)")
            
             @memcpy.apicall(sprintfvar, [sprintf].pack("i"),  4)
             @memcpy.apicall(rgssevalvar,[rgsseval].pack("i"), 4)
             @memcpy.apicall(oldvar,     [old].pack("i"),      4)
             @memcpy.apicall(fmtvar,     [fmt].pack("i"),      4)
             @memcpy.apicall(bufvar,     [buf].pack("i"),      4)
             @memcpy.apicall(defvar,     [self.findProc("user32", "DefWindowProcA")].pack("i"),      4)
            
             @code = [0x55,0x89,0xe5,0xff,0x75,0x14,
                      0xff,0x75,0x10,0xff,0x75,0x0c,
                      0xff,0x75,0x08,0xff,0x35].pack('C*')
             @code << [fmtvar].pack('l') << [0xff, 0x35].pack('C*')
             @code << [bufvar].pack('l') << [0xff, 0x15].pack('C*')
             @code << [sprintfvar].pack("l")
             @code << [0xff, 0x15].pack('C*')
             @code << [rgssevalvar].pack("l")
=begin
             @code << [0x83,0xc4,0x18, 0xff, 0x75, 0x14,
                       0xff,0x75, 0x10, 0xff, 0x75, 0x0c,
                       0xff,0x75, 0x08, 0xff, 0x15].pack('C*')
             @code << [oldvar].pack("l")
=end
             @code << [0x83,0xc4,0x18].pack('C*')
             @code << [0xc9,0xc2,0x10,0x00].pack('C*')
             #0xD1, 0xE8
             @shellcode = @malloc.apicall(2048)  
             @memcpy.apicall(@shellcode, @code, @code.size)
             @@oHandle= :"user32|SetWindowLong|iii|i".apicall(@hwnd, -4, @shellcode)
              #Returning Test : should be 5
              #Roost::MainWindow.setwndproc (lambda{|hwnd, msg, wp, lp| 5})
              #p :"user32|CallWindowProc|iiiii|i".apicall(@shellcode, 0, 0, 0, 0)
            end
          end
         
        end
        
  end
end

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

    Roost::MainWindow.addwndproc (lambda {|hwnd, msg, wp, lp|
      Mouse.onLMouseDown if msg==Win32API::WM_LBUTTONDOWN
      Mouse.onRMouseDown if msg==Win32API::WM_RBUTTONDOWN
      Mouse.onLMouseUp if msg==Win32API::WM_LBUTTONUP
      Mouse.onRMouseUp if msg==Win32API::WM_RBUTTONUP
      Mouse.onLMouseDD if msg==Win32API::WM_LBUTTONDBLCLK
      Mouse.onRMouseDD if msg==Win32API::WM_RBUTTONDBLCLK
      if msg==Win32API::WM_MOUSEMOVE
        Mouse.setMouse([lp&0xffff,lp>>16])
      end
    })
    @ldown=false
    @ltd=false
    @rdown=false
    @rtd=false
    @lup=false
    @rup=false
  end
  def onLMouseDown
    @ltd=true
    @ltd=false if @ldown
    @ldown=true
  end
  def onLMouseUp
    @ldown=false
    @ltd=false
  end
  def onLMouseDD
   
  end
  def onRMouseDown
    @rtd=true
    @rtd=false if @rdown
    @rdown=true
   
  end
  def onRMouseUp
    @rdown=false
    @rtd=false
  end
  def onRMouseDD
   
  end
  def setMouse(p)
    @pos=p
  end
  
  #--------------------------------------------------------------------------
  # ## 触发?
  #--------------------------------------------------------------------------
  def self.toggled?(key)
    return @toggled & key != 0
  end
  #--------------------------------------------------------------------------
  # ## 按下?
  #--------------------------------------------------------------------------
  def Mouse.press?(key)
    return @press & key != 0
  end
  #--------------------------------------------------------------------------
  # ## 单击?
  #--------------------------------------------------------------------------
  def self.click?(key)
    return false if key == LKEY and !$click_abled
    return @clicks[0] & key == 0 && @clicks[1] & key != 0
  end
  #--------------------------------------------------------------------------
  # ## 双击?
  #--------------------------------------------------------------------------
  def self.dbl_click?(key)
    return false if @dblc.size < 2
    ## 键值有效
    if @dblc[1][0] & key != 0 and @dblc[0][0] & key != 0
      ## 间隔有效
      if @dblc[1][1] - @dblc[0][1] < DBLCTIME
        ## 坐标有效
        if @dblc[1][2] == @dblc[0][2]
          return @clicks[0] & key == 0 && @clicks[1] & key != 0
        end
      end
    end
    return false
  end
  def pos
    return @pos
  end
  def update
    @press,@toggled=0,0
    @press += LKEY   if @ldown
    @press += RKEY   if @rdown
    @toggled += LKEY if @ltd
    @toggled += RKEY  if @rtd
    @clicks.shift if @clicks.size >=2
    @clicks.push @press
    if @dblc.size >= 2
      @dblc.clear
      @count = 0
    end
    if @dblc.size == 1 and @count - @dblc[0][1] > DBLCTIME
      @dblc.clear
      @count = 0
    end
    if @clicks[0] == 0 and @clicks[1] != 0
      if @dblc.size == 1 and @dblc[0][0] != @clicks[1]
        @dblc.clear
        @count = 0
      end
      @dblc.push [@press,@count,@pos]
    end
    @count += 1 unless @dblc.empty?
    @move_pos.shift if @move_pos.size >= 2
    @move_pos.push @pos
    $click_abled=true
  end
  def down(p)
    if (p==LEFT)
      return @ldown
    else
      return @rdown
    end
  end
end

Mouse._init_






class << Mouse
  Win32API.new('user32', 'ShowCursor', 'l', 'l').call(0)
  $mousec = Sprite.new
  $mousec.z = 10001
  $mousec.x = $mousec.y = 1000
  $mouse_icon = 'Pointer'
  $mousec.bitmap = Cache.system($mouse_icon)
  
  alias wor_mouse_upd_mouse update unless $@
  def Mouse.update
    wor_mouse_upd_mouse
    if $mouse_old_icon.nil? or $mouse_old_icon != $mouse_icon
      $mouse_old_icon = $mouse_icon
      $mousec.bitmap = Cache.system($mouse_old_icon)
    end
    if @pos.nil?
      $mousec.x = 1000 if $mousec.x != 1000
      $mousec.y = 1000 if $mousec.y != 1000
      Win32API.new('user32', 'ShowCursor', 'l', 'l').call(1)
    else
      $mousec.x = @pos[0] if $mousec.x != @pos[0]
      $mousec.y = @pos[1] if $mousec.y != @pos[1]
      Win32API.new('user32', 'ShowCursor', 'l', 'l').call(0)
    end
    ## 鼠标刷新
    $mousec.update
  end
  #--------------------------------------------------------------------------
  # ## 经过?
  #     obj       : 对象实例
  #                 **支持Sprite,Window,Viewport,Rect,Plane,可补充
  #--------------------------------------------------------------------------
  def Mouse.over?(obj)
    case obj
    when Sprite
      x = obj.x-obj.ox; y = obj.y-obj.oy
      unless obj.viewport.nil?
        x += obj.viewport.rect.x
        y += obj.viewport.rect.y
      end
      return Mouse.area?(x, y, obj.width, obj.height)
    when Window
      x = obj.x;y = obj.y
      unless obj.viewport.nil?
        x += obj.viewport.rect.x
        y += obj.viewport.rect.y
      end
      return Mouse.area?(x, y, obj.width, obj.height)
    when Viewport
      return Mouse.area?(obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height)
    when Rect
      return Mouse.area?(obj.x, obj.y, obj.width, obj.height)
    when Plane
      x = obj.x;y = obj.y
      unless obj.viewport.nil?
        x += obj.viewport.rect.x
        y += obj.viewport.rect.y
      end
      return Mouse.area?(x, y, obj.width, obj.height)
    end
  end
  #--------------------------------------------------------------------------
  # * Mouse in_area
  #--------------------------------------------------------------------------
  def Mouse.area?(x, y, width=32, height=32)
    return false if @pos == nil
    return true if @pos[0] >= x and @pos[0] <= (x+width) and @pos[1] >= y and @pos[1] <= (y+height)
    return false
  end

end







#==============================================================================
# ## Window_Selectable
#==============================================================================
class Window_Selectable < Window_Base
  alias wor_winsel_ini_mouse initialize
  alias wor_winsel_upd_mouse update
  def initialize(*args)
    wor_winsel_ini_mouse(*args)
    @scroll_wait = 0
    @cursor_wait = 0
  end

  def update
    wor_winsel_upd_mouse
    if self.active and self.visible
      update_mouse
    end
  end
  
  def update_mouse
    @cursor_wait -= 1 if @cursor_wait > 0
    (0...item_max).each do |i|
      irect = mouse_rect(i)
      irx = self.x + 16 + irect.x - self.ox
      iry = self.y + 16 + irect.y - self.oy
      result = Mouse.area?(irx, iry, irect.width, irect.height)
      move_cursor(i) if result
      ## 控制单击条件
      $click_abled = false if i == @index and !result
    end

  end
  
  ## 鼠标区域
  def mouse_rect(i)
    rect = item_rect(i)
    return rect if rect.width <= 32
    rect.x += 4
    rect.y += 4
    rect.width -= 8
    rect.height -= 8
    return rect
  end
  def column_max
    return row_max
  end
  def move_cursor(index)
    ## 不响应
    return if @cursor_wait > 0
    return if self.index == index
    @scroll_wait -= 1 if @scroll_wait > 0
    row1 = self.index / column_max
    row2 = index / column_max
    bottom = self.top_row + (self.page_row_max - 1)
    if row1 == self.top_row and row2 < self.top_row
      return if @scroll_wait > 0
      self.index = [self.index - column_max, 0].max
      @scroll_wait = 4
    elsif row1 == bottom and row2 > bottom
      return if @scroll_wait > 0
      self.index = [self.index + column_max, item_max - 1].min
      @scroll_wait = 4
    else
      self.index = index
    end
    return if @cursor_wait > 0
    Sound.play_cursor
    @cursor_wait += 2
  end
end

#==============================================================================
# ** Input
#==============================================================================
class << Input
  alias wor_input_upd_mouse update unless $@
  alias wor_input_trig_mouse trigger? unless $@
  alias wor_input_rep_mouse repeat? unless $@
  def Input.update
    wor_input_upd_mouse
    Mouse.update
  end
  def Input.trigger?(input)

    return wor_input_trig_mouse(input) if Mouse.pos.nil?
    case input
    when Input::B
      return (wor_input_trig_mouse(input) or Mouse.click?(Mouse::RKEY))
    when Input::C
      if SceneManager.scene.is_a?(Scene_Map) and !$game_message.visible
        return wor_input_trig_mouse(input)
      else
        return (wor_input_trig_mouse(input) or Mouse.click?(Mouse::LKEY))
      end
    else
      return wor_input_trig_mouse(input)
    end
  end
  
  def Input.repeat?(input)

    if input == Input::B
      return (wor_input_rep_mouse(input) or Mouse.click?(Mouse::RKEY))
    else
      return wor_input_rep_mouse(input)
    end
  end
end[/pre]

然后是鼠标响应图片。。命名规则就是cmd+公共事件ID  鼠标移动到上面显示cmd+公共事件ID+"_2"的形式[pre lang="ruby" line="1"]class Game_Picture
def name=(str)
   @name = str
end
end
class Sprite_Picture
alias update_old update
def update
   update_old
   return if @picture.name == "" or @picture.name[/cmd/].nil?
   picx = self.x
   picy = self.y
   picw = self.bitmap.width
   pich = self.bitmap.height
   
   if Mouse.area?(picx, picy, picw, pich)

     if @picture.name.split(/_/)[1].nil?
       @picture.name = @picture.name + "_2"
      #self.tone.set(199, 255, 255)#如果不用显示cmd+公共事件ID+"_2"的形式的话把上面的那句注释掉把这句的#删掉 则只是把图片色调变了
     end

     
     if Mouse.click?(Mouse::LKEY) && @picture.name.split(/_/)[0] != nil
       @picture.name.split(/_/)[0].sub(/cmd([0-9]+)/,"")
       $game_temp.reserve_common_event($1.to_i)
     end
     
   else
     
     @picture.name = @picture.name.split(/_/)[0]
     
   end
end
end[/pre]

这个就是自动翻页的脚本。。。突然觉得很简单。。。(´Д`)[pre lang="ruby" line="1"]class Window_Selectable
  def update
    if self.active and item_max > 0
      mouse_x, mouse_y = Mouse.pos
      rect_last = item_rect(item_max)
      rect_last_x = rect_last.x + rect_last.width
      rect_last_y = rect_last.y + rect_last.height
      
      rect_first = item_rect(top_row)
      rect_first_x = rect_first.x + rect_first.width
      rect_first_y = rect_first.y + rect_first.height
      if mouse_y > rect_last_y
        cursor_down
      end
      if mouse_y < rect_first_y
        cursor_up
      end
    end
  end
end[/pre]

评分

参与人数 1星屑 +200 收起 理由
千葉玖濑 + 200 谢谢前辈。

查看全部评分

回复

使用道具 举报

Assassin-K

梦石
0
星屑
4138
在线时间
2281 小时
注册时间
2012-5-23
回帖
3964

贵宾

发表于 2012-9-2 20:48:39 | 显示全部楼层
帮你找人过来,看他接不接活
@铅笔描绘的思念

点评

正在翻脚本的样子。。  发表于 2012-9-2 20:53

◆ROZONE◆
>洛子又要去流浪地球了……
>如果你看到我在线,又没动静,那只能说明我在挂机……
回复

使用道具 举报

梦石
0
星屑
50
在线时间
116 小时
注册时间
2012-8-12
回帖
58
发表于 2012-9-2 23:13:43 | 显示全部楼层
好像外站有一个比较完整的鼠标脚本!鼠标系统  by  Jet
回复

使用道具 举报

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

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部