查看: 4462|回复: 6

[已经解决] 如何在游戏中呼出一个窗口?

[复制链接]

梦石
1
星屑
23236
在线时间
9564 小时
注册时间
2012-6-19
回帖
7018

开拓者短篇九导演组冠军

发表于 2013-8-24 01:21:43 来自手机 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 喵呜喵5 于 2013-8-24 16:45 编辑

我希望用脚本显示一个简单的窗口,这个窗口类似地图名显示那样有淡入淡出的效果,请问该怎么写这个窗口?
淡入淡出应该是在update里修改透明度吧?但是怎么在游戏中呼出这个窗口呢?
梦石
0
星屑
55
在线时间
323 小时
注册时间
2010-8-21
回帖
638
发表于 2013-8-24 02:33:37 | 显示全部楼层
本帖最后由 沙漠点灰 于 2013-8-24 02:35 编辑

将一个实例变量赋为所写窗口的新实例,即可,所有Scene都继承Scene_Base,窗口类不必再写x.update,也不必写x.dispose,
值得注意的是半路上(不是跳转Scene)释放窗口的话,还使实例变量为nil,否则RGSSError错误。

比如事先写好了Window_Mine类
@window_mine = Window_Mine.new(xx)
需要半路释放的时候
@window_mine.dispose
@window_mine = nil
----------------------------------------------
好了,回到lz所说的上面。建议lz使用一个“阶段”,自己一般划为3步骤,入、平、出。
这样的话,步骤就是先入,再平,最后出
[pre lang="ruby" line="1"]class Window_Mine < Window_XXXX
  CHANGE_COUNT = 16 # 自己一般将特效设为16帧
  def initialize(xxxx, block=nil)
     super(xxx)
     @counterr = 0
     @BLock = block
     @step = :in
  end
****************
  def f(x) # 2次函数用于非平均渐变
    (x-1)**2
  end
  def update
    case @step
    when :in # 入
      self.opacity = self.contents_opacity = 255 - f(@counter.to_f/CHANGE_COUNT) * 255
      return @step = :nor if @counter >= CHANGE_COUNT # 跳转步骤设为平
    when :nor # 平
       super # 正常刷新
    when :out # 出
      self.opacity = self.contents_opacity = f(@counter.to_f/CHANGE_COUNT) * 255
      if @counter >= CHANGE_COUNT # 销毁步骤
        @block.call if @block
        return @step=nil
      end
    end
    @counter += 1
  end
  def end!
    @step = :out # 设置跳转步骤为 出
  end
****************
end[/pre]
上面的代码示例而已,直接打的,或许有问题,明白意思就行。还能随意增加/改变步骤。
用一个@step记录步骤,用一个@counter记录时(zhen)间(shu),什么时候该改变步骤。
一个代码块方便销毁窗口,否则到时直接dispose,就不会渐出了。
使用的话。这样:

@window_mine = Window_Mine.new(xx){
  @window_mine.dispose
  @window_mine = nil
}

半路销毁就
@window_mine.end!


不过看实际吧,上面的适合半路杀出来的窗口。
一般的开始时直接生成,要显示时修改内容与不透明度╮( ̄▽ ̄)╭

P.S.像地图名字窗口那样简单的窗口可以直接使用单体方法,就像
@window_mine = Window_Base.new(xxx)
calss << @window_mine
  def refresh
     xxxxxx
   end
  def update
   xxxx
   end
end
这样  
>>猛戳>>MetalSagaR游戏主页<<这里<<
欢迎提供您的意见
回复

使用道具 举报

梦石
1
星屑
23236
在线时间
9564 小时
注册时间
2012-6-19
回帖
7018

开拓者短篇九导演组冠军

 楼主| 发表于 2013-8-24 12:31:38 | 显示全部楼层
沙漠点灰 发表于 2013-8-24 02:33
将一个实例变量赋为所写窗口的新实例,即可,所有Scene都继承Scene_Base,窗口类不必再写x.update,也不必 ...

按照你所说的写了脚本

[pre lang="ruby" line="1"]class Window_Mine < Window_Base
  
  CHANGE_COUNT = 16 # 自己一般将特效设为16帧
  
  def initialize(block=nil)
     super(0, 0, Graphics.width, Graphics.height)
     @counterr = 0
     @BLock = block
     @step = :in
  end

  def f(x) # 2次函数用于非平均渐变
    (x-1)**2
  end
  
  def update
    case @step
    when :in # 入
      self.opacity = self.contents_opacity = 255 - f(@counter.to_f/CHANGE_COUNT) * 255
      return @step = :nor if @counter >= CHANGE_COUNT # 跳转步骤设为平
    when :nor # 平
       super # 正常刷新
    when :out # 出
      self.opacity = self.contents_opacity = f(@counter.to_f/CHANGE_COUNT) * 255
      if @counter >= CHANGE_COUNT # 销毁步骤
        @block.call if @block
        return @step=nil
      end
    end
    @counter += 1
  end
  
  def end!
    @step = :out # 设置跳转步骤为 出
  end
  
end[/pre]


之后在游戏中的事件脚本里用

@window_mine = Window_Mine.new

显示了窗口

但是,使用

@window_mine.end!

却无法消除窗口,请问是怎么回事?
回复

使用道具 举报

梦石
0
星屑
55
在线时间
323 小时
注册时间
2010-8-21
回帖
638
发表于 2013-8-24 13:05:35 | 显示全部楼层
本帖最后由 沙漠点灰 于 2013-8-24 13:28 编辑
喵呜喵5 发表于 2013-8-24 12:31
按照你所说的写了脚本

class Window_Mine < Window_Base


代码中的“@BLock = block"是啥,请检查一下。

lz生成实例时没有制定代码块
@window_mine = Window_Mine.new(xx){
  @window_mine.dispose
  @window_mine = nil
}

半路销毁就
@window_mine.end!

所以,应该:
  1. @window_mine = Window_Mine.new{
  2.   @window_mine.dispose
  3.   @window_mine = nil
  4. }
复制代码
>>猛戳>>MetalSagaR游戏主页<<这里<<
欢迎提供您的意见
回复

使用道具 举报

梦石
1
星屑
23236
在线时间
9564 小时
注册时间
2012-6-19
回帖
7018

开拓者短篇九导演组冠军

 楼主| 发表于 2013-8-24 14:51:08 | 显示全部楼层
沙漠点灰 发表于 2013-8-24 13:05
代码中的“@BLock = block"是啥,请检查一下。

lz生成实例时没有制定代码块



不论是合在一起写
[pre lang="ruby" line="1"]@window_mine = Window_Mine.new{
  @window_mine.dispose
  @window_mine = nil
}
@window_mine.end![/pre]

还是分开来写,
未命名.PNG

窗口仍然没有消除掉,请问是怎么回事?

(url那个是论坛自己添加的,你的脚本里面也有)
回复

使用道具 举报

梦石
0
星屑
55
在线时间
323 小时
注册时间
2010-8-21
回帖
638
发表于 2013-8-24 15:49:57 | 显示全部楼层
本帖最后由 沙漠点灰 于 2013-8-24 16:01 编辑

lz写在事件编辑器里面啊,这样不行。

首先,自己这里2各地方错了,定义end!的时候,忘记清空计数器了。即:
  1. def end!
  2.   @step = :out # 设置跳转步骤为 出
  3.   @conter = 0
  4. end
复制代码
其次,自己似乎记得XP时代代码块直接会变成参数传递给方法,这里似乎不行,不知道是不是自己记错了。
改为:
  1. @window_mine = Window_Mine.new(Proc.new{
  2.   @window_mine.dispose
  3.   @window_mine = nil
  4. })
复制代码
当然,这种代码不能直接写在事件编辑器里面。不会刷新的

添加这几行代码,直接加到Scene_Base即可
  1. class Scene_Base
  2.   def eval(*a)
  3.     self.instance_eval(*a)
  4.   end
  5. end
复制代码
使用时记得打引号(貌似instance_eval能接受代码块),即:
  1. SceneManager.scene.eval(
  2. "@m = Window_Mine.new(Proc.new{
  3.       @m.dispose
  4.       @m = nil
  5. })")
复制代码
消除时:
  1. SceneManager.scene.eval("@m.end!")
复制代码
反正记得打引号就行

点评

哦,就是说比如这个提示是一个地图名提示就在Scene_Map里面写,然后在地图上就会自动刷新了是吧?  发表于 2013-8-24 16:51

评分

参与人数 2星屑 +30 梦石 +2 收起 理由
Sion + 2 认可答案
喵呜喵5 + 30 感谢帮忙

查看全部评分

>>猛戳>>MetalSagaR游戏主页<<这里<<
欢迎提供您的意见
回复

使用道具 举报

梦石
1
星屑
23236
在线时间
9564 小时
注册时间
2012-6-19
回帖
7018

开拓者短篇九导演组冠军

 楼主| 发表于 2013-8-24 16:45:26 | 显示全部楼层
沙漠点灰 发表于 2013-8-24 15:49
lz写在事件编辑器里面啊,这样不行。

首先,自己这里2各地方错了,定义end!的时候,忘记清空计数器了。即 ...

感谢帮忙,现在可以正常的淡入淡出了


再问一下,如果希望呼出一个能够自动update的窗口除了你所说的在Scene_Base中添加一个窗口外还有其他方法吗?

比如我想做一个能够显示任意提示的窗口……写完了窗口的语句之后应该从哪里呼出这个窗口?呼出的语句是写在Game_Interpreter里面吗?

点评

如果全局适用,还可以在Graphics.update里面动手刷新窗口  发表于 2013-8-24 16:51
时间编辑器里面写的自然在解释器里面刷新,可以参考Scene_Base的update_all_windows方法,自己全在需要显示窗口的Scene里面写,事件编辑器里面写这还是头次  发表于 2013-8-24 16:50
回复

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部