查看: 2948|回复: 1

[胡扯] 略可使用的玩物

[复制链接]
梦石
0
星屑
48
在线时间
784 小时
注册时间
2013-1-4
回帖
1057
发表于 2015-11-28 02:40:48 | 显示全部楼层 |阅读模式

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

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

×
RUI。放弃了之前对大而全的追求。果然过早优化就是万恶的深渊啊
基本的event没问题。
目前只有Button、PictureBox、ProgressBar
支持鼠标和键盘
不过鼠标的代码不是我写的
本来大算今天再加个SpriteNumber和TextBox什么的 结果折腾了一天MV和黑科技。。。囧
代码没怎么整理 精简的空间应该会很大 不过也算是之后的事情了
会移植到MV【实际上MV的button和PictureBox已经写好了
差不多就这样了。

范例 链接:http://pan.baidu.com/s/1o6y9cca 密码:p95a
[fold=代码][pre lang="ruby"]# encoding: utf-8
# 项目说明 <RRUI RMVA RUI库>
# 更新作者 © <shitake>
# 许可协议 <FSL 自由脚本协议> [https://github.com/DeathKing/fscript/blob/master/LICENSE.md]
# 项目分类 <VA>
# 衍生关系 <RGSS3>  
# 项目版本 <0.1.0>
# 创建日期 <2015.11.26>
# 更新时间 <2015.11.26>

class Class
  def attr_cascade(i,call_back)
    attr_accessor i
    define_method(i) do |val = nil|
      return instance_variable_get('@'+i.id2name) if val == nil || val == instance_variable_get('@'+i.id2name)
      instance_variable_set('@'+i.id2name, val)
      call_back.call
      self
    end
  end
end

module RUI
  VERSION = "v0.1.0"
   
  def self.boundary(min, max, val)
    val < min ? min : val > max ? max : val
  end
  
  def self.hit(x, y, rect)
    return rect.x < x && x < rect.x + rect.width && rect.y < y && y < rect.y + rect.height
  end
end

class RUI::Event
  
  def initialize(object)
    @object = object
    @events = {}
  end
  
  def on(event_type, call_back)
    @events[event_type] = call_back
  end

  def event_hook(event)
    @events[event].call if @events[event]
  end
  
  def update
    update_mouse
    update_keyboad
  end
  
  def update_mouse
    if !@object.disable && @object.visible
      x,y = Input.mouse_pos
      @object.get_focus if RUI.hit(x, y, @object.rect) && !@object.focus
      @object.lost_focus if !RUI.hit(x, y, @object.rect) && @object.focus
      @object.sure if Input.mouse_repeat?(:MOUSE_LB) && @object.focus
      event_hook(:MOUSE_RB) if Input.mouse_repeat?(:MOUSE_RB)
      event_hook(:MOUSE_MB) if Input.mouse_repeat?(:MOUSE_MB)
    end
  end
  
  def update_keyboad
    event_hook(:UP) if Input.press?(:UP)
    event_hook(:DOWN) if Input.press?(:DOWN)
    event_hook(:LEFT) if Input.press?(:LEFT)
    event_hook(:RIGHT) if Input.press?(:RIGHT)
    event_hook(:A) if Input.press?(:A)
    event_hook(:B) if Input.press?(:B)  
    event_hook(:C) if Input.press?(:C)
    event_hook(:X) if Input.press?(:X)
    event_hook(:Y) if Input.press?(:Y)
    event_hook(:Z) if Input.press?(:Z)
    event_hook(:L) if Input.press?(:L)
    event_hook(:R) if Input.press?(:R)
  end
  
end

class RUI::Button

  attr_cascade :viewport, lambda{self.create_viewport(self.viewport)}
  attr_reader :bitmaps
  attr_reader :x
  attr_reader :y
  attr_reader :width
  attr_reader :height
  attr_reader :state
  attr_reader :sprite
  attr_reader :focus
  attr_reader :disable
  attr_reader :visible
  attr_reader :event
  attr_reader :rect
  def initialize(bitmaps, viewport = nil, x, y)
    @viewport = viewport
    @bitmaps = {:default => bitmaps[0],:focus => bitmaps[1], :down => bitmaps[2], :enfeeble => bitmaps[3]}
    @x = x
    @y = y
    @state = 0
    @focus = false
    @disable = false
    @visible = true
    @sprite = Sprite.new
    @sprite.x = x
    @sprite.y = y
    create_viewport(@viewport)
    create_sprite
    #bitmap is a method.
    @width = bitmap.width
    @height = bitmap.height
    @rect = Rect.new
    create_rect
    @event = RUI::Event.new(self)
  end

  def bitmap
    return @sprite.bitmap
  end
  
  def get_focus
    return if @disable
    @focus = true
    @state = 1
    create_sprite
    @event.event_hook(:get_focus)
  end
  
  def lost_focus
    return if @disable
    @focus = false
    @state = 0
    create_sprite
    @event.event_hook(:lost_focus)
  end
  
  def move(x, y)
    return if @disable
    @x = x
    @y = y
    @sprite.x = x
    @sprite.y = y
    create_rect
    @event.event_hook(:move)
  end
  
  def show
    return if @disable
    @visible =true
    @sprite.visible = @visible
    @event.event_hook(:show)
  end   
  
  def hide
    return if @disable
    @visible = false
    @sprite.visible = @visible
    @event.event_hook(:hide)
  end
  
  def enfeeble
    @disable = true
    @state = 3
    create_sprite
    @event.event_hook(:enfeeble)
  end
  
  def enable
    @disable = false
    @state = 0
    create_sprite
    @event.event_hook(:enable)
  end
  
  def sure
    return if @disable
    @state = 2
    create_sprite
    @event.event_hook(:click)
  end
  
  def create_rect
    @rect.x = @x
    @rect.y = @y
    @rect.width = @width
    @rect.height = @height
  end
  
  def create_viewport(viewport)
    @sprite.viewport = viewport if viewport.instance_of?(Viewport)
  end
  
  def create_sprite
    case @state
    when 0
      @sprite.bitmap = @bitmaps[:default]
    when 1
      @sprite.bitmap = @bitmaps[:focus]
    when 2
      @sprite.bitmap = @bitmaps[:down]
    when 3
      @sprite.bitmap = @bitmaps[:enfeeble]
    else
      raise "RUI.Button:type error"
    end
  end
  
  def on(event_type, &block)
    call_back = lambda &block
    @event.on(event_type, call_back)
  end

  def update
    @event.update
  end
  
  def dispose
    @bitmaps.each{|key,val| val.dispose}
    @sprite.bitmap.dispose unless @sprite.bitmap.disposed?
    @sprite.dispose
  end
  
end

class RUI::PictureBox

  attr_cascade :bitmap,lambda{self.create_sprite}
  attr_cascade :x, lambda{self.sprite.x = self.x;self.create_rect}
  attr_cascade :y, lambda{self.sprite.y = self.y;self.create_rect}
  attr_cascade :width, lambda{self.create_sprite;self.create_rect}
  attr_cascade :height, lambda{self.create_sprite;self.create_rect}
  attr_cascade :viewport, lambda{self.create_viewport(self.viewport)}
  attr_cascade :type, lambda{self.create_sprite}
  attr_reader :wheel_x
  attr_reader :wheel_y
  attr_reader :sprite
  attr_reader :focus
  attr_reader :disable
  attr_reader :visible
  attr_reader :event
  attr_reader :rect
  def initialize(bitmap,viewport = nil, x, y, width, height, type)
    @viewport = viewport
    @bitmap = bitmap
    @x = x
    @y = y
    @width = width
    @height = height
    @type = type
    @wheel_x = 0
    @wheel_y = 0
    @focus = false
    @disable = false
    @visible = true
    @sprite = Sprite.new
    @sprite.x, @sprite.y = x, y
    create_viewport(@viewport)
    create_sprite
    @rect = Rect.new
    create_rect
    @event = RUI::Event.new(self)
  end

  def roll_x(wheel_x)
    return if @type == 1
    rect = @sprite.src_rect
    @wheel_x = RUI.boundary(0, @bitmap.width - @width, @wheel_x + wheel_x)
    rect.x = @wheel_x
    @sprite.src_rect = rect
    @event.event_hook(:roll_x)
  end

  def roll_y(wheel_y)
    return if @type == 1
    rect = @sprite.src_rect
    @wheel_y = RUI.boundary(0, @bitmap.height - @height, @wheel_y + wheel_y)
    rect.y = @wheel_y
    @sprite.src_rect = rect
    @event.event_hook(:roll_y)
  end
  
  def move(x, y)
    return if @disable
    @x = x
    @y = y
    @sprite.x = x
    @sprite.y = y
    create_rect
    @event.event_hook(:move)
  end
  
  def show
    return if @disable
    @visible =true
    @sprite.visible = @visible
    @event.event_hook(:show)
  end   
  
  def hide
    return if @disable
    @visible = false
    @sprite.visible = @visible
    @event.event_hook(:hide)
  end
  
  def enfeeble
    @disable = true
    @event.event_hook(:enfeeble)
  end
  
  def enable
    @disable = false
    @event.event_hook(:enable)
  end
  
  def sure
    return if @disable
    @event.event_hook(:click)
  end
  
  def get_focus
    return if @disable
    @focus = true
    @event.event_hook(:get_focus)
  end
  
  def lost_focus
    return if @disable
    @focus = false
    @event.event_hook(:lost_focus)   
  end

  def create_rect
    @rect.x = @x
    @rect.y = @y
    @rect.width = @width
    @rect.height = @height
  end
  
  def create_viewport(viewport)
    @sprite.viewport = viewport if viewport.instance_of?(Viewport)
  end
  
  def create_sprite
    @sprite.bitmap = @bitmap
    if @type == 0
      rect = @sprite.src_rect
      rect.width = @width
      rect.height = @height
      @sprite.src_rect = rect
    else
      if @type == 1
        bitmap = Bitmap.new(@width, @height)
        bitmap.stretch_blt(Rect.new(0, 0, @width, @width), @sprite.bitmap, Rect.new(0, 0, @sprite.bitmap.width, @sprite.bitmap.height))
        @sprite.bitmap = bitmap
      else
        raise "RUI.PictureBox:type error"
      end
    end
  end
  
  def on(event_type, &block)
    call_back = lambda &block
    @event.on(event_type, call_back)
  end

  def update
    @event.update
  end
  
  def dispose
    @bitmap.dispose
    @sprite.bitmap.dispose unless @sprite.bitmap.disposed?
    @sprite.dispose
  end
  
end

class RUI::ProgressBar

  attr_cascade :bitmap,lambda{self.create_sprite}
  attr_cascade :x, lambda{self.sprite.x = self.x;self.create_rect}
  attr_cascade :y, lambda{self.sprite.y = self.y;self.create_rect}
  attr_cascade :width, lambda{self.create_sprite;self.create_rect}
  attr_cascade :height, lambda{self.create_sprite;self.create_rect}
  attr_cascade :viewport, lambda{self.create_viewport(self.viewport)}
  attr_reader :sprite
  attr_reader :focus
  attr_reader :disable
  attr_reader :visible
  attr_reader :event
  attr_reader :rect
  def initialize(bitmap,viewport = nil, x, y, width, height, value)
    @viewport = viewport
    @bitmap = bitmap
    @x = x
    @y = y
    @width = width
    @height = height
    @value = value
    @focus = false
    @disable = false
    @visible = true
    @sprite = Sprite.new
    create_viewport(@viewport)
    @sprite.x, @sprite.y = x, y
    create_sprite
    @rect = Rect.new
    create_rect
    @event = RUI::Event.new(self)
  end
  
  def value
    return @value
  end
  
  def value=(val)
    return @value if val == nil || @value == val
    @value = val
    @event.event_hook(:progress)
    create_sprite
  end
  
  def move(x, y)
    return if @disable
    @x = x
    @y = y
    @sprite.x = x
    @sprite.y = y
    create_rect
    @event.event_hook(:move)
  end
  
  def show
    return if @disable
    @visible =true
    @sprite.visible = @visible
    @event.event_hook(:show)
  end   
  
  def hide
    return if @disable
    @visible = false
    @sprite.visible = @visible
    @event.event_hook(:hide)
  end
  
  def enfeeble
    @disable = true
    @event.event_hook(:enfeeble)
  end
  
  def enable
    @disable = false
    @event.event_hook(:enable)
  end
  
  def sure
    return if @disable
    @event.event_hook(:click)
  end
  
  def get_focus
    return if @disable
    @focus = true
    @event.event_hook(:get_focus)
  end
  
  def lost_focus
    return if @disable
    @focus = false
    @event.event_hook(:lost_focus)   
  end

  def create_rect
    @rect.x = @x
    @rect.y = @y
    @rect.width = @width
    @rect.height = @height
  end
  
  def create_viewport(viewport)
    @sprite.viewport = viewport if viewport.instance_of?(Viewport)
  end
  
  def create_sprite
    @sprite.bitmap = @bitmap
    rect = @sprite.src_rect
    @value = RUI.boundary(0,1,@value)
    rect.width = @width * @value
    rect.height = @height
    @sprite.src_rect = rect
  end
  
  def on(event_type, &block)
    call_back = lambda &block
    @event.on(event_type, call_back)
  end

  def update
    @event.update
  end
  
  def dispose
    @bitmap.dispose
    @sprite.bitmap.dispose unless @sprite.bitmap.disposed?
    @sprite.dispose
  end
  
end
[/pre]
鼠标脚本:
[pre lang="ruby"]
#==============================================================================
# ■ module Input.mouse
#------------------------------------------------------------------------------
#  マウス入力情報を取得
#==============================================================================

=begin
  key = :MOUSE_LB or :MOUSE_RB or :MOUSE_MB
  Input.mouse_trigger?(key, ignore_swap = false)
  Input.mouse_press?(key, ignore_swap = false)
  Input.mouse_repeat?(key, ignore_swap = false)
  Input.mouse_pos    return x, y
=end

module Input
  @mouse_name = {:MOUSE_LB=>0, :MOUSE_RB=>1, :MOUSE_MB=>2}
  VK_LBUTTON = 1
  VK_RBUTTON = 2
  VK_MBUTTON = 4
  SM_SWAPBUTTON = 23
  @mouse_status = [[0, VK_LBUTTON, false], [0, VK_RBUTTON, false],
  [0, VK_MBUTTON, false]]

  # システム状態の検出
  gsm = Win32API.new('user32', 'GetSystemMetrics', 'i', 'i')

  # マウスカーソルの表示切替
  ShowCursor = Win32API.new("user32", "ShowCursor", "i", "i")

  # クラス変数
  # マウスボタンの左右の入れ替えの可否
  @swapped = gsm.call(SM_SWAPBUTTON) != 0
  # キー(ボタン)状態取得
  @gaks = Win32API.new('user32', 'GetAsyncKeyState', 'i', 'i')
  # マウスカーソル座標の取得
  @cursor_pos = Win32API.new('user32', 'GetCursorPos', 'p', 'i')
  
  # スクリーン座標からクライアント座標へ変換
  $scr2cli = Win32API.new('user32', 'ScreenToClient', %w(l p), 'i')
  #クライアント領域取得
  $client_rect = Win32API.new('user32', 'GetClientRect', %w(l p), 'i')
  # iniファイル読み込み
  $readini = Win32API.new('kernel32', 'GetPrivateProfileStringA', %w(p p p p l p), 'l')
  # ウィンドウハンドル取得
  $findwindow = Win32API.new('user32', 'FindWindowA', %w(p p), 'l')

  module_function
  #--------------------------------------------------------------------------
  # ● マウスのスクリーン座標
  #--------------------------------------------------------------------------
  def mouse_global_pos
    pos = [0, 0].pack('ll')
    # 呼び出しに成功した場合
    if @cursor_pos.call(pos) != 0
      return pos.unpack('ll')
    # 失敗した場合
    else
      return nil
    end
  end
  #--------------------------------------------------------------------------
  # ● マウスのクライアント座標
  #     catch_anywhere : ウィンドウ外にカーソルがあっても構わず座標を返す
  #--------------------------------------------------------------------------
  def mouse_pos(catch_anywhere = false)
    # スクリーン上のマウスカーソルの座標をクライアント座標に
    x, y = screen_to_client(*mouse_global_pos)
    # クライアント領域の大きさを取得
    width, height = client_size
    # 画面外でも構わない場合か画面内にカーソルがある場合
    if catch_anywhere or (x >= 0 and y >= 0 and x < width and y < height)
      return x, y
    else
      return -1,-1
    end
  end
  #----------------------------------------------------------
  # ● 更新
  #----------------------------------------------------------
  def mouse_update
    for i in @mouse_status
      num1 = false
      num2 = @gaks.call(i[1])
      if num2 != 1 and num2 != 0
        num1 = true
      end
      if num1 == false
        if i[0] > 0
          i[2] = (i[0] < 25)    # シングルクリック判定
          i[0] = i[0] * -1
        else
          i[2] = false
          i[0] = 0
        end
      else
        if i[0] > 0
          i[0] += 1
        else
          i[2] = false
          i[0] = 1
        end
      end
    end
  end
  #----------------------------------------------------------
  # ● キー情報を返す。Inputとおなじ。
  #     id   キーID   ignore_swap 入れ替えを許可するかしないか
  #----------------------------------------------------------
  def mouse_press?(value, ignore_swap = false)
    id = @mouse_name[value]
    id = @mouse_name[:MOUSE_RB] if value == :MOUSE_LB && @swapped && ignore_swap
    id = @mouse_name[:MOUSE_LB] if value == :MOUSE_RB && @swapped && ignore_swap
    if @mouse_status[id][0] > 0
      return true
    else
      return false
    end
  end
  def mouse_trigger?(value, ignore_swap = false)
    id = @mouse_name[value]
    id = @mouse_name[:MOUSE_RB] if value == :MOUSE_LB && @swapped && ignore_swap
    id = @mouse_name[:MOUSE_LB] if value == :MOUSE_RB && @swapped && ignore_swap
    if @mouse_status[id][0] == 1
      return true
    else
      return false
    end
  end
  def mouse_repeat?(value, ignore_swap = false)
    id = @mouse_name[value]
    id = @mouse_name[:MOUSE_RB] if value == :MOUSE_LB && @swapped && ignore_swap
    id = @mouse_name[:MOUSE_LB] if value == :MOUSE_RB && @swapped && ignore_swap
    if @mouse_status[id][0] <= 0
      return false
    else
      if @mouse_status[id][0] % 5 == 1 and @mouse_status[id][0] / 5 != 1
        return true
      else
        return false
      end
    end
  end
  
  def mouse_single_click?(value, ignore_swap = false)
    id = @mouse_name[value]
    id = @mouse_name[:MOUSE_RB] if value == :MOUSE_LB && @swapped && ignore_swap
    id = @mouse_name[:MOUSE_LB] if value == :MOUSE_RB && @swapped && ignore_swap
    return @mouse_status[id][2]
  end
  #--------------------------------------------------------------------------
  # ● スクリーン座標からクライアント座標へ変換
  #     x, y : スクリーン座標
  #--------------------------------------------------------------------------
  def screen_to_client(x, y)
    # 座標が無効なら失敗
    return nil unless x and y
    pos = [x, y].pack('ll')
    # 呼び出しに成功した場合
    if $scr2cli.call(hwnd, pos) != 0
      return pos.unpack('ll')
    # 失敗した場合
    else
      return nil
    end
  end
  #--------------------------------------------------------------------------
  # ● ウィンドウハンドル取得
  #--------------------------------------------------------------------------
  def hwnd
    # ゲーム名を取得する
    game_name = "\0" * 256
    $readini.call('Game', 'Title', '', game_name, 255, ".\\Game.ini")
    game_name.delete!("\0")
    # ウィンドウハンドルを取得
    h = $findwindow.call('RGSS Player', game_name)
    if h == 0
      h = $findwindow.call('RGSS Player', nil)
    end
    return h
  end
  #--------------------------------------------------------------------------
  # ● クライアント領域取得
  #--------------------------------------------------------------------------
  def client_size
    rect = [0, 0, 0, 0].pack('l4')
    $client_rect.call(hwnd, rect)
    # topとleftは常に0なので省略
    right, bottom = rect.unpack('l4')[2..3]
    return right, bottom
  end
  
  class << self
    alias :shitake_151126_update :update
    def update
      shitake_151126_update
      mouse_update
    end
  end
  
end[/pre][/fold]  
RM-GUI延期。。。最近被黑心老板压迫T_T
二次元少女的shitake,长着长脸,身高165,蓝色卷双马尾,FCUP,瞳色黑色,病气和御宅属性,是天才少女。
梦石
1
星屑
7574
在线时间
2650 小时
注册时间
2013-8-23
回帖
2152

开拓者

发表于 2015-11-28 03:27:50 | 显示全部楼层

2015-11-28_032551.png

2015-11-28_032534.png


友情补图
回复

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部