| 赞 | 1 |
| VIP | 0 |
| 好人卡 | 0 |
| 积分 | 5 |
| 经验 | 0 |
| 最后登录 | 2026-6-3 |
| 在线时间 | 67 小时 |
Lv2.观梦者
- 梦石
- 0
- 星屑
- 509
- 在线时间
- 67 小时
- 注册时间
- 2025-5-4
- 帖子
- 3
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 HFDange 于 2026-4-2 21:09 编辑
效果图:
2026.4.2更新:根据回帖建议优化了脚本,并增加了渐变描边功能。
#============================================================================== # ■ XP行走图描边脚本 - Character Stroker 2026.3.21 By HFDange #------------------------------------------------------------------------------ # 使用方法:在需要描边的事件名中添加“.stX”后缀。 # X为标记描边颜色的数字,如“.st0”为灰色描边、“.st1”为红色描边。 # 若要更改描边颜色,在CSC_COLORSET中添加或修改。 # # 2026.4.2更新:描边渐变 # # 使用方法:事件名后缀“.stXgX” # 如“.st1g0”为红->灰->红渐变 # #============================================================================== #============================================================================== # ● 设置部分 #============================================================================== module CharSt_Config # 是否八方向描边(默认FALSE) CSC_IF_8_DIRECTIONS = FALSE # 描边颜色表(RGBA),默认颜色为:灰 红 绿 蓝 黄 紫 青 白 黑 CSC_COLORSET = [ [64, 56, 56, 255], [255, 18, 18, 255], [18, 255, 18, 255], [18, 18, 255, 255], [255, 255, 18, 255], [255, 18, 255, 255], [18, 255, 255, 255], [255, 255, 255, 255], [0, 0, 0, 255] ] # 渐变周期长度 - 以帧为单位(默认20) CSC_GRADIENT_CYCLE = 20 end #============================================================================== # ● 描边脚本 #============================================================================== module CharactorStroker include CharSt_Config def self.need?(name) # 从事件名判断是否需要描边 return false if CharactorStroker.type(name) == nil return name.include?(".st") end def self.needgd?(name) # 判断描边是否需要渐变 reg = name.match(/\.st\d+g/) return reg != nil end def self.type(name) # 判断描边颜色 type = name.match(/(?<=\.st)\d+/) return 0 unless type return type[0].to_i end def self.gdtype(name) # 判断描边渐变颜色 type = name.match(/\.st\d+g(\d+)/i) return type[1].to_i end def self.gdrate # 计算渐变比率 (0~1) frame = Graphics.frame_count prirate = frame % (CSC_GRADIENT_CYCLE * 2) rate = prirate.to_f / CSC_GRADIENT_CYCLE if prirate < CSC_GRADIENT_CYCLE rate = (CSC_GRADIENT_CYCLE * 2 - prirate.to_f) / CSC_GRADIENT_CYCLE if prirate >= CSC_GRADIENT_CYCLE return rate end def self.gdcolor(name) # 计算渐变颜色 col = CSC_COLORSET[CharactorStroker.type(name)] colgd = CSC_COLORSET[CharactorStroker.gdtype(name)] rate = CharactorStroker.gdrate r = (col[0] + (colgd[0] - col[0]) * rate).to_i g = (col[1] + (colgd[1] - col[1]) * rate).to_i b = (col[2] + (colgd[2] - col[2]) * rate).to_i a = (col[3] + (colgd[3] - col[3]) * rate).to_i return [r, g, b, a] end def self.sync(event, lists, states, viewport) # 事件描边同步行走图 id = event.id lists[id].x = event.screen_x - 1 lists[id].y = event.screen_y - 1 lists[id].z = event.screen_z - 2 name = event.event.name if CharactorStroker.needgd?(name) gd = 1 else gd = 0 end new_state = [event.character_name, name, event.direction, event.pattern, gd] if states[id] != new_state if CharactorStroker.need?(name) col = CharactorStroker.type(name) CharactorStroker.draw(lists, states, col, id, viewport) else lists[id].bitmap.dispose lists[id].dispose lists.delete(id) states.delete(id) end end end #-------------------------------------------------------------------------- # ● 绘制描边精灵图 #-------------------------------------------------------------------------- def self.draw(lists, states, col, id, viewport) lists[id] = Sprite.new(viewport) if !lists[id] || lists[id].disposed? lists[id].color.set(CSC_COLORSET[col][0],CSC_COLORSET[col][1],CSC_COLORSET[col][2],CSC_COLORSET[col][3]) tevent = $game_map.events[id] if CharactorStroker.needgd?(tevent.event.name) gd = 1 else gd = 0 end states[id] = [tevent.character_name, tevent.event.name, tevent.direction, tevent.pattern, gd] t1 = RPG::Cache.character(tevent.character_name, tevent.character_hue) rw = t1.width / 4 rh = t1.height / 4 lists[id].ox = rw / 2 lists[id].oy = rh if lists[id].bitmap != nil && !lists[id].bitmap.disposed? lists[id].bitmap.dispose end lists[id].bitmap = Bitmap.new(rw+2, rh+2) rx = tevent.pattern * rw case tevent.direction when 2 dir = 0 when 4 dir = 1 when 6 dir = 2 when 8 dir = 3 end ry = dir * rh evcrect = Rect.new(rx, ry, rw, rh) t2 = lists[id].bitmap t2.blt(0, 1, t1, evcrect) t2.blt(2, 1, t1, evcrect) t2.blt(1, 0, t1, evcrect) t2.blt(1, 2, t1, evcrect) if CSC_IF_8_DIRECTIONS t2.blt(2, 2, t1, evcrect) t2.blt(0, 0, t1, evcrect) t2.blt(2, 0, t1, evcrect) t2.blt(0, 2, t1, evcrect) end end end #============================================================================== # ● 公开event变量 #============================================================================== class Game_Event < Game_Character attr_reader :event end #============================================================================== # ● 修改Spriteset_Map初始化、释放、刷新函数 #============================================================================== class Spriteset_Map alias cst_old_initialize initialize alias cst_old_dispose dispose alias cst_old_update update def initialize cst_old_initialize @cst_lists = {} @cst_states = {} cst_refresh end def dispose cst_old_dispose @cst_lists.each_value{ |cstcheck| next unless cstcheck.respond_to?(:dispose) if cstcheck.bitmap && !cstcheck.bitmap.disposed? cstcheck.bitmap.dispose end cstcheck.dispose unless cstcheck.disposed? } @cst_lists.clear @cst_states.clear end def update cst_old_update if @cst_lists @cst_lists.each_key{ |cstid| event = $game_map.events[cstid] CharactorStroker.sync(event, @cst_lists, @cst_states, @viewport1) if @cst_states[cstid][4] == 1 gdcol = CharactorStroker.gdcolor(event.event.name) @cst_lists[cstid].color.set(gdcol[0], gdcol[1], gdcol[2], gdcol[3]) end } end end def cst_refresh @cst_lists.each_value{ |cstcheck| next unless cstcheck.respond_to?(:dispose) if cstcheck.bitmap && !cstcheck.bitmap.disposed? cstcheck.bitmap.dispose end cstcheck.dispose unless cstcheck.disposed? } @cst_lists.clear @cst_states.clear $game_map.events.each_value{ |value| event = value.event name = event.name if CharactorStroker.need?(name) && value.character_name != "" col = CharactorStroker.type(name) CharactorStroker.draw(@cst_lists, @cst_states, col, event.id, @viewport1) end } end end
#==============================================================================
# ■ XP行走图描边脚本 - Character Stroker 2026.3.21 By HFDange
#------------------------------------------------------------------------------
# 使用方法:在需要描边的事件名中添加“.stX”后缀。
# X为标记描边颜色的数字,如“.st0”为灰色描边、“.st1”为红色描边。
# 若要更改描边颜色,在CSC_COLORSET中添加或修改。
#
# 2026.4.2更新:描边渐变
#
# 使用方法:事件名后缀“.stXgX”
# 如“.st1g0”为红->灰->红渐变
#
#==============================================================================
#==============================================================================
# ● 设置部分
#==============================================================================
module CharSt_Config
# 是否八方向描边(默认FALSE)
CSC_IF_8_DIRECTIONS = FALSE
# 描边颜色表(RGBA),默认颜色为:灰 红 绿 蓝 黄 紫 青 白 黑
CSC_COLORSET = [
[64, 56, 56, 255], [255, 18, 18, 255], [18, 255, 18, 255],
[18, 18, 255, 255], [255, 255, 18, 255], [255, 18, 255, 255],
[18, 255, 255, 255], [255, 255, 255, 255], [0, 0, 0, 255]
]
# 渐变周期长度 - 以帧为单位(默认20)
CSC_GRADIENT_CYCLE = 20
end
#==============================================================================
# ● 描边脚本
#==============================================================================
module CharactorStroker
include CharSt_Config
def self.need?(name) # 从事件名判断是否需要描边
return false if CharactorStroker.type(name) == nil
return name.include?(".st")
end
def self.needgd?(name) # 判断描边是否需要渐变
reg = name.match(/\.st\d+g/)
return reg != nil
end
def self.type(name) # 判断描边颜色
type = name.match(/(?<=\.st)\d+/)
return 0 unless type
return type[0].to_i
end
def self.gdtype(name) # 判断描边渐变颜色
type = name.match(/\.st\d+g(\d+)/i)
return type[1].to_i
end
def self.gdrate # 计算渐变比率 (0~1)
frame = Graphics.frame_count
prirate = frame % (CSC_GRADIENT_CYCLE * 2)
rate = prirate.to_f / CSC_GRADIENT_CYCLE if prirate < CSC_GRADIENT_CYCLE
rate = (CSC_GRADIENT_CYCLE * 2 - prirate.to_f) / CSC_GRADIENT_CYCLE if prirate >= CSC_GRADIENT_CYCLE
return rate
end
def self.gdcolor(name) # 计算渐变颜色
col = CSC_COLORSET[CharactorStroker.type(name)]
colgd = CSC_COLORSET[CharactorStroker.gdtype(name)]
rate = CharactorStroker.gdrate
r = (col[0] + (colgd[0] - col[0]) * rate).to_i
g = (col[1] + (colgd[1] - col[1]) * rate).to_i
b = (col[2] + (colgd[2] - col[2]) * rate).to_i
a = (col[3] + (colgd[3] - col[3]) * rate).to_i
return [r, g, b, a]
end
def self.sync(event, lists, states, viewport) # 事件描边同步行走图
id = event.id
lists[id].x = event.screen_x - 1
lists[id].y = event.screen_y - 1
lists[id].z = event.screen_z - 2
name = event.event.name
if CharactorStroker.needgd?(name)
gd = 1
else
gd = 0
end
new_state = [event.character_name, name, event.direction, event.pattern, gd]
if states[id] != new_state
if CharactorStroker.need?(name)
col = CharactorStroker.type(name)
CharactorStroker.draw(lists, states, col, id, viewport)
else
lists[id].bitmap.dispose
lists[id].dispose
lists.delete(id)
states.delete(id)
end
end
end
#--------------------------------------------------------------------------
# ● 绘制描边精灵图
#--------------------------------------------------------------------------
def self.draw(lists, states, col, id, viewport)
lists[id] = Sprite.new(viewport) if !lists[id] || lists[id].disposed?
lists[id].color.set(CSC_COLORSET[col][0],CSC_COLORSET[col][1],CSC_COLORSET[col][2],CSC_COLORSET[col][3])
tevent = $game_map.events[id]
if CharactorStroker.needgd?(tevent.event.name)
gd = 1
else
gd = 0
end
states[id] = [tevent.character_name, tevent.event.name, tevent.direction, tevent.pattern, gd]
t1 = RPG::Cache.character(tevent.character_name, tevent.character_hue)
rw = t1.width / 4
rh = t1.height / 4
lists[id].ox = rw / 2
lists[id].oy = rh
if lists[id].bitmap != nil && !lists[id].bitmap.disposed?
lists[id].bitmap.dispose
end
lists[id].bitmap = Bitmap.new(rw+2, rh+2)
rx = tevent.pattern * rw
case tevent.direction
when 2
dir = 0
when 4
dir = 1
when 6
dir = 2
when 8
dir = 3
end
ry = dir * rh
evcrect = Rect.new(rx, ry, rw, rh)
t2 = lists[id].bitmap
t2.blt(0, 1, t1, evcrect)
t2.blt(2, 1, t1, evcrect)
t2.blt(1, 0, t1, evcrect)
t2.blt(1, 2, t1, evcrect)
if CSC_IF_8_DIRECTIONS
t2.blt(2, 2, t1, evcrect)
t2.blt(0, 0, t1, evcrect)
t2.blt(2, 0, t1, evcrect)
t2.blt(0, 2, t1, evcrect)
end
end
end
#==============================================================================
# ● 公开event变量
#==============================================================================
class Game_Event < Game_Character
attr_reader :event
end
#==============================================================================
# ● 修改Spriteset_Map初始化、释放、刷新函数
#==============================================================================
class Spriteset_Map
alias cst_old_initialize initialize
alias cst_old_dispose dispose
alias cst_old_update update
def initialize
cst_old_initialize
@cst_lists = {}
@cst_states = {}
cst_refresh
end
def dispose
cst_old_dispose
@cst_lists.each_value{ |cstcheck|
next unless cstcheck.respond_to?(:dispose)
if cstcheck.bitmap && !cstcheck.bitmap.disposed?
cstcheck.bitmap.dispose
end
cstcheck.dispose unless cstcheck.disposed?
}
@cst_lists.clear
@cst_states.clear
end
def update
cst_old_update
if @cst_lists
@cst_lists.each_key{ |cstid|
event = $game_map.events[cstid]
CharactorStroker.sync(event, @cst_lists, @cst_states, @viewport1)
if @cst_states[cstid][4] == 1
gdcol = CharactorStroker.gdcolor(event.event.name)
@cst_lists[cstid].color.set(gdcol[0], gdcol[1], gdcol[2], gdcol[3])
end
}
end
end
def cst_refresh
@cst_lists.each_value{ |cstcheck|
next unless cstcheck.respond_to?(:dispose)
if cstcheck.bitmap && !cstcheck.bitmap.disposed?
cstcheck.bitmap.dispose
end
cstcheck.dispose unless cstcheck.disposed?
}
@cst_lists.clear
@cst_states.clear
$game_map.events.each_value{ |value|
event = value.event
name = event.name
if CharactorStroker.need?(name) && value.character_name != ""
col = CharactorStroker.type(name)
CharactorStroker.draw(@cst_lists, @cst_states, col, event.id, @viewport1)
end
}
end
end
范例工程:
描边脚本260402.zip
(207.13 KB, 下载次数: 3)
|
|