系統公告
化學成分
個人圖檔
ID:qootm2
暱稱:Q—S.T.

文章分類
好時光貼曆
人氣指數
當日人次:
累積人次:
自由欄位





我推了誰
誰推了我
誤擊清單
RSS 訂閱
RSS2
ATOM
贊助商
其它資訊
本部落所刊登之內容,皆由作者個人所提供,不代表 yam天空部落 本身立場。
POWERED BY
POWERED BY
會員登入免費註冊
October 31, 2009

※ 09/11/2 全螢幕動畫顯示改造的腳本修正



自從逛到某家blog後突然萌生發這篇教學文的內容
本教學就是把RMXP內建的縱向戰鬥改成橫向動態戰鬥
基本上這教學有一半是現學現賣


有意願的就請看下去吧
改造上其實不難,比較麻煩的其實是那些角色動作...

↑基本示意圖,不過要變成這樣還得配合諸多腳本...教學應該不會改到這樣...






步驟1.

既然是橫向戰鬥,那首先咱們的位置當然要改成橫的
敵方只要在"隊伍"的編輯頁調整位置就好,我方呢?

請去Game_Actor這個腳本裡修改screen_x 、screen_y、screen_z三個方法
調整到自己喜歡的位置便可,以下是俺的設定範例:


def screen_x
   if self.index != nil
     return self.index * 30 + 450
   else
     return 0
   end
 end

 def screen_y
   return self.index * 30 + 230
 end
 
 def screen_z  
   if self.index != nil
     return self.index
   else
     return 0
   end
 end

設定好後,執行看看,人物應該跑到畫面右端了



步驟2.
把人物位置改變後會出現一個問題,請直接看圖解

沒錯,我方的人物圖像壓在視窗上,優先度沒調整
內建情況會出現這種選擇視窗的只有技能和道具以及角色命令,
咱們在Scene_Battle這個類可以找到處理的方法。

直接貼圖解
用井字號隔開的部分就是追加項目,作用就是生成視窗後將z軸調到最大,大到保證能蓋過角色
而角色命令視窗的話在main找到
(前略)
@actor_command_window = Window_Command.new(160, [s1, s2, s3, s4])
@actor_command_window.y = 160
@actor_command_window.back_opacity = 160
@actor_command_window.active = false
(後略)
一樣,補個@actor_command_window.z = 9999上去就好

這樣視窗部分就算搞定了...


啊?你問我一開始示意圖的狀態視窗怎麼變透明?
一樣是在main這個方法,在@status_window = Window_BattleStatus.new的下一行補上

@status_window.opacity = 0

但這樣一改又有問題,因為內建的戰鬥背景只有640x320,
所以原本顯示狀態視窗的部分就剩黑底白字,以後找張640x480的圖當戰鬥背景吧~
.....吭?你說圖片已經換了但下面那塊還是黑的?......等下會講。



狀態視窗的文字在行動過程中會閃來閃去很不順眼?
請到Window_BattleStatus找到update這個方法
# 主界面的不透明度下降這註解下面的if...else...end內容全部砍掉或註解掉,
但別把剩下的兩個end砍掉了,會出問題



背景太亮讓字看不到?
這個請去Window_Base改文字顏色,或者在生成方法裡填色
不過因為很繁瑣,所以僅提供填色方法,剩下請自己體悟(拖
self.contents.font.color = Color.new(紅, 綠, 藍, 透明度)



步驟3.
再來是戰鬥動畫的顯示,內建的縱向戰鬥變到橫版有兩個問題:
問題一.敵方的戰鬥動畫顯示範圍只有640x320,所以你放全螢幕動畫時會有一小部分被砍掉

到Spriteset_Battle找到initialize這個方法,
把@viewport1的數值改一下,這是管理敵方畫面顯示和戰鬥背景的
@viewport1 = Viewport.new(0, 0, 640, 480)
這樣就能確保戰鬥動畫能顯示完整

然後剛剛擴張到全畫面的戰鬥背景問題,為什麼放了640x480的圖還是無法顯示完整咧?
是update...我忘了update...

在update裡面找到@battleback_sprite.src_rect.set(0, 0, 640, 320)
改成@battleback_sprite.src_rect.set(0, 0, 640, 480)

大功告成


問題二.全螢幕動畫顯示位置不一致


上面是我方攻擊敵方,下面是敵方攻擊我方
這設置在縱向戰鬥很正常,但換成橫向就變成打狀態欄了

這裡就麻煩點,要去腳本說明書挖腳本,打開說明書找到RPG::Sprite這個條目
然後把animation_set_sprites這個方法挖出來貼到腳本編輯器裡
並且找到  if position == 3 這行,這行的意思就是動畫設定如果是全畫面接下來要幹嘛
然後在裡面會看到它以判定敵我雙方做分歧調整動畫顯示位置,改成一樣或刪掉條件分歧都可以
以下是俺的設定:

 module RPG
  class Sprite < ::Sprite
   def animation_set_sprites(sprites, cell_data, position)
      for i in 0..15
        sprite = sprites[i]
        pattern = cell_data[i, 0]
        if sprite == nil or pattern == nil or pattern == -1
          sprite.visible = false if sprite != nil
          next
        end
        sprite.visible = true
        sprite.src_rect.set(pattern % 5 * 192, pattern / 5 * 192, 192, 192)
        if position == 3  #動畫設定為全畫面時
          if self.viewport != nil
            sprite.x = self.viewport.rect.width / 2
            if $game_temp.in_battle and self.battler.is_a?(Game_Enemy)
              sprite.y = self.viewport.rect.height - 320 #敵方動畫位置   
            else
              sprite.y = self.viewport.rect.height - 320  #我方動畫位置
            end
          else
            sprite.x = 320
            sprite.y = 240
          end
        else
          sprite.x = self.x + self.viewport.rect.x -
                      self.ox + self.src_rect.width / 2
          if $game_temp.in_battle and self.battler.is_a?(Game_Enemy)
            sprite.y = self.y - self.oy * self.zoom_y / 2 +
                        self.viewport.rect.y
            if position == 0
              sprite.y -= self.src_rect.height * self.zoom_y / 4
            elsif position == 2
              sprite.y += self.src_rect.height * self.zoom_y / 4
            end
          else
            sprite.y = self.y + self.viewport.rect.y -
                        self.oy + self.src_rect.height / 2
            sprite.y -= self.src_rect.height / 4 if position == 0
            sprite.y += self.src_rect.height / 4 if position == 2
          end
        end
        sprite.x += cell_data[i, 1]
        sprite.y += cell_data[i, 2]
        sprite.z = 2000
        sprite.ox = 96
        sprite.oy = 96
        sprite.zoom_x = cell_data[i, 3] / 100.0
        sprite.zoom_y = cell_data[i, 3] / 100.0
        if position != 3
          sprite.zoom_x *= self.zoom_x
          sprite.zoom_y *= self.zoom_y
        end
        sprite.angle = cell_data[i, 4]
        sprite.mirror = (cell_data[i, 5] == 1)
        sprite.opacity = cell_data[i, 6] * self.opacity / 255.0
        sprite.blend_type = cell_data[i, 7]
      end
    end
  end
 end
啊啊對了,這其實是從齒車的RTAB系統抓下來改的,與原始定義還是有點出入,請直接使用表格內的內容



這兩個問題解決後,就是改造戰鬥圖了






步驟4.
接下來,咱們來把戰鬥圖改成會動的模式,為了能立刻看見效果,咱們可以先把戰鬥圖設置成內建行走圖來看看

將Sprite_Battler複製一份貼到main腳本之上,改造錯了還可以刪掉重改
首先在initialize先宣告一些東西
  
    def initialize(viewport, battler = nil)
    super(viewport)
    @battler = battler
    @battler_visible = false
    #########################
      @step = 0       #單一動作的分解
      @type = 0      #各種動作
      @damage_point = 0  #受傷點數
      @damage_wait = 0   #受傷等待數
      @dead = false #死亡判斷
      @nowtype = @type #動作轉換判斷
  #########################
  end

接下來,重頭戲,找到update這個方法
在self.bitmap = RPG::Cache.battler(@battler_name, @battler_hue)這行下面,
把原本的
     @width = bitmap.width
     @height = bitmap.height
 改成
    @width = bitmap.width / 4  #寬的格數有多少就除多少
    @height = bitmap.height / 4  #長的格數有多少就除多少

這樣我們就把剛剛4x4的行走圖裁成16格了(註:因為是行走圖,所以各除4,到時需自行修正)

然後在 self.oy = @height下面追加
# 顯示裁切範圍
  self.src_rect.set(0, 0, @width, @height)


這樣就只會顯示行走圖長寬各除以4的32x32大小,而且是顯示第一格圖片(前面的兩個0, 0你可以想成座標)
現在執行遊戲看看,應該會看到人物以行走圖的樣子面向下,表示成功了

啊?你說人物沒像圖中這樣?但是變得支離破碎的??你沒用行走圖來當戰鬥圖啊!(巴頭


 
那麼接下來,把剛剛那個式子改成self.src_rect.set(0, 1*@height, @width, @height)
應該會看到人物面向左邊

然後,再把式子改成self.src_rect.set(1*@width, 1*@height, @width, @height)
此時人物不但面向左邊而且雙腳是開著的。

了解這行是做什麼了沒?
不了解也沒關係,反正咱們也不是要改這行,單靠這行也不能讓戰鬥圖動
改回 self.src_rect.set(0, 0, @width, @height) 吧(爆

接下來往下拉,會看到一個註解
# 應該被顯示的角色的情況下

一樣,到# 明滅這個註解之前全部砍掉或註釋掉,不然角色會和狀態視窗一樣一閃一閃但不亮晶晶...


然後再往下拉...拉到傷害這個註解(以後井號省略)
在條件分歧裡面加個兩行變成(位置別放錯,不然會無效):
   # 傷害
      if @battler.damage_pop
        damage(@battler.damage, @battler.critical)
   #############################################  
      # 損傷點數寫入
      @damage_point = @battler.damage
      # 損傷動作禎數
      @damage_wait = 20
  ############################################## 
        @battler.damage = nil
        @battler.critical = false
        @battler.damage_pop = false



接下來,先在設定活動區塊的座標這註解前加入下列東西
 
#==============================================================================
#■動作設定 
#==============================================================================




   # 當@step的值大於3時歸0,以免超出顯示範圍
   @step = 0 if @step > 3

  # 更新角色動作
  if  Graphics.frame_count % 7 == 0
      self.src_rect.set(@step*@width,@type*@height,@width,@height)  
      @step += 1 
    end
   
   
    #如果有換動作@step重新計算
    if @nowtype != @type
      @step = 0
      @nowtype = @type #重新代入
    end

這堆就是讓戰鬥圖能"動"的基本要素,想知道運作原理就去解讀吧,算蠻好懂的
現在運行遊戲,你會看到人物在動了



好,接下來咱們就來寫第一個動作判別式(先感謝您耐心的看到這)
當@step的值大於3時歸0,以免超出顯示範圍這個註解前貼上下列這玩意
   #受傷
    if   @damage_point.is_a?(Numeric)
      if @damage_point > 0
        # 動作為3
        @type = 3
        # 損傷點數歸零
        @damage_point = 0
     end  
  end
    # 損傷動作禎數減算
    @damage_wait -= 1 if @damage_wait > 0
    # 損傷動作禎數為0時,動作改為0
    @type = 0 if @damage_wait == 0

運行遊戲,此時當角色被攻擊時,如果面朝上一下子
恭喜你,第一個動作判別式完成了!



第一部分完!!



下一回...其他動作的判斷式寫法(倒






誰推薦這篇文章
引用 (你可以針對此文寫一篇屬於自己的blog/想法,並給作者一個通告)
引用
留言 (2筆)
1.
某家blog= =!!??
 
寫的不錯,讓我想起我的事件版橫版戰鬥擺到積灰塵了XD
現在回頭去看,完全看不懂自己在寫什麼(80%都事件XD)
 
板主回覆:
就是您府上啊 !!(握拳


步驟4的內容幾乎是從ooxx工作室挖來的(網頁已被和諧),只是那個教學是用RTAB在教

自戰的話感覺會比改RGSS好掌握吧,只是好複雜的感覺(看著精美的白い絆...)
a870053jjkj 2009-11-01 10:57:07 留言 |
2.
基本上比效能和自由的話是RGSS佳,除非是為了腳本盲新手...
事件搞行走圖動畫會比較方便一些些,但是要設很多是大缺點
當初搞4對4跑過去跑回來,光這樣就需要設32個以上移動路線...
我寫橫版戰鬥主要是用來搞自己的遊戲
那個時候我連數組是什麼東西都不知道= =+
用事件隨便搞出了CP條、戰鬥位置系統...
但某些系統完全靠事件太困難了...(角色狀態窗口....冒汗....)
 
板主回覆:
嗯,我也是因為效能才改用RGSS的

不過俺到現在還是不太會用數組...Orz
a870053jjkj 2009-11-01 14:24:20 留言 |
發表你的留言 (字數限制 最多 2000 個中文字)
私密留言:
Name:






內容: