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

Project1

 找回密码
 注册会员
搜索

【小周实践系列第一季第一弹】教你制作状态窗口

查看数: 2895 | 评论数: 9 | 收藏 2
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2014-4-4 22:30

正文摘要:

本帖最后由 天地有正气 于 2014-4-7 14:28 编辑 【小周实践系列第一季】教你制作状态窗口

回复

cxyhn 发表于 2014-5-3 13:29:37
刷新事件肯定是要放到脚本里的没错,用事件会太麻烦。
不过LZ小周教的还是挺好的,感觉学到不少。
有空的话继续更新不要放弃啊。

评分

参与人数 1星屑 +60 收起 理由
天地有正气 + 60 我不会放弃的~

查看全部评分

myownroc 发表于 2014-4-18 01:00:38
窗口的生成与刷新个人认为应该在Scene_Map中完成,而不是通过事件

点评

噶卡,我在更新 的回帖里吧刷新放进Scene_Map了。  发表于 2014-4-19 14:57
化螺耕 发表于 2014-4-14 13:47:55
好东西啊,果断顶,对于我们新手来说真是学习的好帖子,支持楼主
fux2 发表于 2014-4-14 08:15:07
本帖最后由 fux2 于 2014-4-14 08:19 编辑

如果刷新放在事件里面过了地图这个窗口不是泄露了么,win7下停止工作什么的。
另外每帧refresh你在差点的机器上就能发现很明显的卡顿,正确做法是记录需要描绘的数值,发生变动才描绘。
当然你这里的refresh相当于把update和refresh写到一起了,
refresh的作用如字面一样是刷新,重新描绘,update是用于检查更新。
以下给出一个范例。

地图血条.rar (187.65 KB, 下载次数: 59)
  1. # 加入刷新部分,可以自己换位置
  2. class Scene_Map
  3.   alias _fux_main main
  4.   def main
  5.     @state_window = Window_MapState.new
  6.     _fux_main
  7.     @state_window.dispose
  8.   end
  9.   alias _fux_update update
  10.   def update
  11.     @state_window.update
  12.     _fux_update
  13.   end
  14. end
  15. #渐变描绘
  16. class Bitmap
  17.   def gradient_fill_rect(x,y,w,h,color_pack)
  18.     color1,color2 = *color_pack
  19.     tempcolor = [ color2.red-color1.red,
  20.                   color2.green-color1.green,
  21.                   color2.blue-color1.blue,
  22.                   color2.alpha-color1.alpha ]
  23.     h.times do |i|
  24.       this_color = Color.new(color1.red+tempcolor[0]*i/(h-1),
  25.                              color1.green+tempcolor[1]*i/(h-1),
  26.                              color1.blue+tempcolor[2]*i/(h-1),
  27.                              color1.alpha+tempcolor[3]*i/(h-1))
  28.       self.fill_rect(x,y+i,w,1,this_color)
  29.     end
  30.   end
  31. end

  32. # 正片
  33. class Window_MapState < Window_Base
  34.   # 初始化
  35.   def initialize
  36.     super(0,0,224,72)
  37.     self.contents = Bitmap.new(self.width-32,self.height-32)
  38.     self.contents.font.size = 14
  39.     self.opacity = 180
  40.     @remmer_symbol = [:hp,:maxhp,:sp,:maxsp]
  41.     @remmer_value =  [-1]*@remmer_symbol.size
  42.     @color_list = [ [[Color.new(0xff,0x33,0x33),Color.new(0x66,0,0)],
  43.                       Color.new(0,0,0),Color.new(255,255,255)],
  44.                     [[Color.new(0x33,0x99,0xff),Color.new(0x00,0x00,0x33)],
  45.                       Color.new(0,0,0),Color.new(255,255,255)] ]
  46.     update
  47.   end
  48.   def refresh(hp,maxhp,sp,maxsp)
  49.     self.contents.clear
  50.     x,y,w,h = 0,1,40,14
  51.     self.contents.draw_text(x,y,w,h,"HP:")
  52.     w,h = 142,14
  53.     self.contents.fill_rect(x+39,y-1,w+2,h+2,@color_list[0][2])
  54.     self.contents.fill_rect(x+40,y,w,h,@color_list[0][1])
  55.     rw = (w-2)*hp/maxhp
  56.     self.contents.gradient_fill_rect(x+41,y+1,rw,h-2,@color_list[0][0])
  57.     y,w,h = 25,40,14
  58.     self.contents.draw_text(x,y,w,h,"SP:")
  59.     w,h = 142,14
  60.     self.contents.fill_rect(x+39,y-1,w+2,h+2,@color_list[1][2])
  61.     self.contents.fill_rect(x+40,y,w,h,@color_list[1][1])
  62.     rw = maxsp > 0 ? (w-2)*sp/maxsp : 0
  63.     self.contents.gradient_fill_rect(x+41,y+1,rw,h-2,@color_list[1][0])
  64.   end
  65.   def update
  66.     pointer = $game_party.actors[0]
  67.     return unless pointer
  68.     need_refresh = false
  69.     @remmer_symbol.each_with_index do |s,i|
  70.       now_value = pointer.method(s).call
  71.       if now_value != @remmer_value[i]
  72.         @remmer_value[i] = now_value
  73.         need_refresh = true
  74.       end
  75.     end
  76.     refresh(*@remmer_value) if need_refresh
  77.   end
  78.   def dispose
  79.     @color_list = nil
  80.     @remmer_symbol = nil
  81.     @remmer_value = nil
  82.     super
  83.   end
  84. end
复制代码

点评

这个不错,收了,但有个小问题,可不可以加个开关,事件标题的时候直接就出来了。  发表于 2015-7-21 08:24
命名而已没必要那么规范。我叫XXOO也不会有问题。  发表于 2014-5-3 19:07
发现个小错误,第五行中的 Window_Mapstate.new 应该是Window_MapStatus.new 其他没有什么问题  发表于 2014-5-3 13:46
RyanBern 发表于 2014-4-8 14:26:56
提供几个建议:

1.没有必要将hp设置为attr_accessor,因为在这里你不希望外界用圆点运算符"."对实例变量进行操作,而且整个过程中也没有用到$w.hp这样的语句,应该删去。
2.没有必要将宽度w设置为实例变量,在这里设置一个局部临时变量w就可以了。
3.建议刷新的内容全部放到update中去,refresh只是单纯的描绘作用,因为面向对象编程讲究看标识符知其含义,因此在地图用update不变,重写MapStatus的update方法,这是写脚本的一个好习惯。

另外提醒一下3L的朋友,Hp和Sp有所不同,最大Sp允许取0值,因此计算宽度的时候,如果遇到无Sp的角色会发生除0错误,在这里改一下以增强代码安全性。

评分

参与人数 2星屑 +112 收起 理由
heiwang1997 + 12 我很赞同
怪蜀黍 + 100 认真评论奖

查看全部评分

天地有正气 发表于 2014-4-7 14:46:54
本帖最后由 天地有正气 于 2014-4-7 20:00 编辑

现在我们写的血条脚本,只能通过地图上的事件来显示。而且血条会把菜单什么的都遮住,很不爽。

我将告诉大家怎么来把血条的生成,刷新都写在脚本里。

首先介绍alias的用法。

alias的用处是把脚本降低冲突率,完全“插件”化。

比如说,小周定义了一个类:

class XiaoZhou
  def damage
      $hp -= 100
  end
end

而P叔(@protosssonny )也定义了一个类,是

class XiaoZhou
  def damage
    p "你受伤了!"
  end
end

但是两个定义冲突了,P叔把小周的定义的方法damage重定义了一遍,于是小周就不会-hp了。

聪明的P叔想了一个办法,他用alias避免了冲突:

class XiaoZhou
  alias xz_damage damage
  def damage
    p "你受伤了!"
    xz_damage
  end
end

当使用alias后,xz_damage 相当于完全复制了damage,然后P叔重新定义damage,之后在调用xz_damage,这样就避免了冲突。

把窗口的生成、释放、刷新写在Scene_Map里,如果不用alias,就要重新复制一遍main、update这两个方法,麻烦不说,还有很大的冲突率。

于是我们要用alias。
  1. class Scene_Map
  2.   alias old_main main
  3.   def main
  4.     @map_status = Window_MapStatus.new
  5.     old_main
  6.     @map_status.dispose
  7.   end
  8.   alias old_update update
  9.   def update
  10.     old_update
  11.     @map_status.refresh
  12.   end  
  13. end  
复制代码
此时就可以删掉那个事件了!

点评

这里表示没看懂...  发表于 2014-5-11 17:15
↓我觉得不是这样的吧…………只要不是两个人都用old_方法名来取别名就好了。  发表于 2014-4-19 14:55
其实alias做成的插件脚本更容易起冲突,试想两个脚本都对默认脚本中的某方法进行alias  发表于 2014-4-7 22:36
@protosssonny LZ说“聪明的P叔想了一个办法”,你快来看看吧!old_damage写错了,是xz_damage,改一下吧。  发表于 2014-4-7 16:33
heiwang1997 发表于 2014-4-6 13:09:54
交作业啦!

还有脚本:
先@w
RUBY 代码复制
  1. class Window_MapStatus < Window_Base
  2.   def initialize
  3.     super(0,0,200,120)
  4.     self.contents = Bitmap.new(width - 32, height - 32)
  5.     @hp = 0
  6.     @sp = 0
  7.     refresh
  8.   end
  9.   def refresh
  10.     if @hp != $game_party.actors[0].hp or @sp != $game_party.actors[0].sp
  11.       @hp = $game_party.actors[0].hp
  12.       @sp = $game_party.actors[0].sp
  13.       self.contents.clear
  14.       self.contents.draw_text(0,0,60,32,"HP")
  15.       self.contents.draw_text(0,52,60,32,"SP")
  16.       self.contents.fill_rect(60,0,100,32,Color.new(255,255,255))
  17.       self.contents.fill_rect(60,52,100,32,Color.new(255,255,255))
  18.       [url=home.php?mod=space&uid=133944]@w[/url] = 96 * @hp / $game_party.actors[0].maxhp  
  19.       for i in 0..@w-5
  20.         self.contents.fill_rect(64+i,4,1,24,Color.new(255,i*2,0))
  21.       end
  22.       @w = 96 * @sp / $game_party.actors[0].maxsp  
  23.       for i in 0..@w-5
  24.         self.contents.fill_rect(64+i,56,1,24,Color.new(0,i*2,255))
  25.       end
  26.     end  
  27.   end
  28.   def update
  29.     super
  30.     refresh
  31.   end
  32. end
  

评分

参与人数 1星屑 +45 收起 理由
天地有正气 + 45 塞糖

查看全部评分

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

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

GMT+8, 2024-11-29 01:07

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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