排行榜系统 by 沉影不器
指定某个变量做为成绩, 然后依成绩排名, 记录姓名.成绩.时间, 图标分类显示新上榜的成绩.排名下降和未变化的成绩, 将生成新文件sort.rvdata记录排行榜数据,重新排名的方法就是删掉该文件.
使用说明: ① 复制脚本插入到Main之前
① 调用的方法: 事件脚本中输入 $scene = Scene_Sort.new
如果指定的变量值能够排得上名次,则自动打开姓名输入窗口,否则当作
普通查看排行榜处理
脚本第10-18行为用户自定义部分(特别注意第10行设定,指定变量号)



#==============================================================================
# 排行榜系统 by 沉影不器
#------------------------------------------------------------------------------
# 使用说明: ① 复制脚本插入到Main之前
# ① 调用的方法: 事件脚本中输入 $scene = Scene_Sort.new
# 如果指定的变量值能够排得上名次,则自动打开姓名输入窗口,否则当作
# 普通查看排行榜处理
# 脚本第10-18行为用户自定义部分
#==============================================================================
VAR_INDEX = 1 # 设定接受成绩的变量号
DADA_NAME = "Data/Sort.rvdata" # 设定数据库文件名(包含路径)
SORT_MAX = 10 # 设定排行榜最大上榜数
NAME = "无名英雄" # 设定姓名输入的默认名称
NAME_SIZE = 10 # 设定姓名输入的最大字数
NOMAL_ICON = 101 # 设定排名无变化的图标 ID
NEW_ICON = 142 # 设定新排名的图标 ID
DOWN_ICON = 143 # 设定排名下降的图标 ID
#==============================================================================
# ■ Window_NameShow
#==============================================================================
class Window_NameShow < Window_Base
#--------------------------------------------------------------------------
# ● 定义实例变量
#--------------------------------------------------------------------------
attr_reader :name # 名称
attr_reader :index # 光标位置
attr_reader :max_char # 名称最大字数
#--------------------------------------------------------------------------
# ● 初始化对象
# default_name : 默认名称
# max_char : 最大字数
#--------------------------------------------------------------------------
def initialize(default_name, max_char)
super(88, 20, 368, 128)
@max_char = max_char
@name = default_name
name_array = @name.split(//)[0...@max_char]
@name = ""
for i in 0...name_array.size
@name += name_array[i]
end
@default_name = @name
@index = name_array.size
self.active = false
refresh
update_cursor
end
#--------------------------------------------------------------------------
# ● 还原为默认名称
#--------------------------------------------------------------------------
def restore_default
@name = @default_name
@index = @name.split(//).size
refresh
update_cursor
end
#--------------------------------------------------------------------------
# ● 添加文字
# character : 单个字符
#--------------------------------------------------------------------------
def add(character)
if @index < @max_char and character != ""
@name += character
@index += 1
refresh
update_cursor
end
end
#--------------------------------------------------------------------------
# ● 删除文字
#--------------------------------------------------------------------------
def back
if @index > 0
name_array = @name.split(//)
@name = ""
for i in 0...name_array.size-1
@name += name_array[i]
end
@index -= 1
refresh
update_cursor
end
end
#--------------------------------------------------------------------------
# ● 获取项目描绘的矩形
# index : 项目编号
#--------------------------------------------------------------------------
def item_rect(index)
rect = Rect.new(0, 0, 0, 0)
rect.x = 220 - (@max_char + 1) * 12 + index * 24
rect.y = 36
rect.width = 24
rect.height = WLH
return rect
end
#--------------------------------------------------------------------------
# ● 刷新
#--------------------------------------------------------------------------
def refresh
self.contents.clear
self.contents.draw_text(4, 0, 240, 24, "请输入尊姓大名: ")
name_array = @name.split(//)
for i in 0...@max_char
c = name_array[i]
c = '_' if c == nil
self.contents.draw_text(item_rect(i), c, 1)
end
end
#--------------------------------------------------------------------------
# ● 更新光标
#--------------------------------------------------------------------------
def update_cursor
self.cursor_rect = item_rect(@index)
end
#--------------------------------------------------------------------------
# ● 更新画面
#--------------------------------------------------------------------------
def update
super
update_cursor
end
end
#==============================================================================
# ■ Window_Sort
#==============================================================================
class Window_Sort < Window_Selectable#Window_Base
#--------------------------------------------------------------------------
# ● 初始化对像
#--------------------------------------------------------------------------
def initialize
super(0, 56, 544, 416-56)
@data = $data_sort == nil ? [] : $data_sort # 载入排行榜数据
@column_max = 1
@new_index = -1 # 初始化最新排名 ID
refresh
self.index = 0
end
#--------------------------------------------------------------------------
# ● 获取排名
#--------------------------------------------------------------------------
def item
return @data[self.index]
end
#--------------------------------------------------------------------------
# ● 格式化时间
# time : 时间对象
#--------------------------------------------------------------------------
def format_time(time)
time_text = time.strftime("%X: %x")
time_text.sub!(/:/) {|i| "时" }
time_text.sub!(/:/) {|i| "分" }
time_text.sub!(/:/) {|i| "秒" }
time_text.sub!(/\//) {|i| "月" }
time_text.sub!(/\//) {|i| "日" }
time_text += "年"
return time_text
end
#--------------------------------------------------------------------------
# ● 添加排名
# item_name : 名字
# time : 时间印
#--------------------------------------------------------------------------
def add_item(item_name, time)
sort_item = [$game_variables[VAR_INDEX].to_i, item_name, time]
#p sort_item, time
@data.push(sort_item)
@data.sort!
@data.reverse!
@data.pop if @data.size > SORT_MAX
# 以时间为次键再倒序
for i in 0...@data.size
for j in i+1...@data.size
if @data[i][0] == @data[j][0] and @data[i][2] > @data[j][2]
@data[i][2],@data[j][2] = @data[j][2],@data[i][2]
end
end
end
# 怪事 -.-b
#p sort_item, time
find_item = [$game_variables[VAR_INDEX].to_i, item_name, time]
@new_index = @data.index(find_item)
if @new_index == nil
@new_index = -1
else
self.index = @new_index
end
save_data(@data, DADA_NAME)
end
#--------------------------------------------------------------------------
# ● 列表中包含的物品
# item : 物品
#--------------------------------------------------------------------------
def include?(item)
return false if item == nil
return true
end
#--------------------------------------------------------------------------
# ● 刷新
#--------------------------------------------------------------------------
def refresh
@data.push(nil) if include?(nil)
@item_max = @data.size
create_contents
for i in 0...@item_max
draw_item(i)
end
end
#--------------------------------------------------------------------------
# ● 描绘项目
# index : 项目编号
#--------------------------------------------------------------------------
def draw_item(index)
x = 4
y = index * WLH
item = @data[index]
self.contents.font.color = normal_color
self.contents.fill_rect(x, y, 544, WLH, Color.new(0, 0, 0, 0))
draw_icon(sort_icon(index), x+32, y)
self.contents.draw_text(x, y, WLH, WLH, (index+1).to_s, 0)
self.contents.draw_text(x + 56, y, 120, WLH, item[1], 0)
self.contents.draw_text(x + 370, y, 64, WLH, "分数:", 1)
self.contents.draw_text(x + 430, y, 64, WLH, item[0].to_s, 2)
end
#--------------------------------------------------------------------------
# ● 获取图标 ID
# index : 项目编号
#--------------------------------------------------------------------------
def sort_icon(index)
return NOMAL_ICON if @new_index == -1
if index > @new_index
return DOWN_ICON
elsif index == @new_index
return NEW_ICON
else
return NOMAL_ICON
end
end
#--------------------------------------------------------------------------
# ● 更新帮助文本
#--------------------------------------------------------------------------
def update_help
text = item == nil ? "暂无记录" : "记录时间: " + format_time(item[2])
@help_window.set_text(text)
end
end
#==============================================================================
# ■ Scene_Sort
#==============================================================================
class Scene_Sort < Scene_Base
#--------------------------------------------------------------------------
# ● 开始处理
#--------------------------------------------------------------------------
def start
super
@map_sprite = Spriteset_Map.new # 取代快照
setup_data # 获取数据
@sort_window = Window_Sort.new
@help_window = Window_Help.new
@sort_window.help_window = @help_window
@name_window = Window_NameShow.new(NAME, NAME_SIZE)
@input_window = Window_NameInput.new
@sort_window.visible = @help_window.visible = !add_item?
@name_window.visible = @input_window.visible = add_item?
end
#--------------------------------------------------------------------------
# ● 结束处理
#--------------------------------------------------------------------------
def terminate
super
@map_sprite.dispose
@sort_window.dispose
@help_window.dispose
@name_window.dispose
@input_window.dispose
end
#--------------------------------------------------------------------------
# ● 返回排名画面 (完成上榜操作)
#--------------------------------------------------------------------------
def return_sort
@sort_window.add_item(@name,Time.now)
@sort_window.refresh
@sort_window.visible = @help_window.visible = true
@name_window.visible = @input_window.visible = false
end
#--------------------------------------------------------------------------
# ● 获取数据
#--------------------------------------------------------------------------
def setup_data
$data_sort = load_data(DADA_NAME) if FileTest.exist?(DADA_NAME)
end
#--------------------------------------------------------------------------
# ● 添加排名的公式
#--------------------------------------------------------------------------
def add_item?
return false if $game_variables[VAR_INDEX].to_i <= 0
return true if $data_sort == nil
test = $data_sort.size < SORT_MAX ? 0 : $data_sort[SORT_MAX-1][0]
return true if $game_variables[VAR_INDEX].to_i > test
end
#--------------------------------------------------------------------------
# ● 更新画面
#--------------------------------------------------------------------------
def update
super
update_menu_background
@sort_window.update
@help_window.update
@name_window.update
@input_window.update
if @sort_window.visible
if Input.trigger?(Input::B)
Sound.play_cancel
$scene = Scene_Map.new
return
end
end
if @input_window.visible
if Input.repeat?(Input::B)
if @name_window.index > 0 # 左边有文字的情况下
Sound.play_cancel
@name_window.back
end
elsif Input.trigger?(Input::C)
if @input_window.is_decision # 光标位置在 [确定] 的情况下
if @name_window.name == "" # 名称为空的情况下
@name_window.restore_default # 还原至默认名称
if @name_window.name == ""
Sound.play_buzzer
else
Sound.play_decision
end
else
Sound.play_decision
@name = @name_window.name # 更改名称
return_sort
end
elsif @input_window.character != "" # 文字不是空的情况下
if @name_window.index == @name_window.max_char # 达到最大字数
Sound.play_buzzer
else
Sound.play_decision
@name_window.add(@input_window.character) # 添加文字
end
end
end
end
end
end
>>点此下载范例工程<<--------------------------------------------------------------------
2008-05-06 更新 1.01
① 把Time对象直接压入数据库,避免字符串排序时可能出现的顺序问题
② 部分脚本改改写法