スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Dxruby談:サイドビュー自動戦闘システムの紹介その弐(オブジェクト使用版) + 小物 #Advent Calender 用記事

前回の続きです。前回はオブジェクト指向なしに、動きだけをっ再現してみました。
それはいいのですが、やはりコードとして見ると、見づらすぎるという方がいらっしゃいます。
Ruby を初めて4ヶ月なのですが、ここに来て自分のコーティングを完璧に改めることになりそうです・・・!


今回の記事はDxruby #Advent Calender 用記事となっております。
前回はそう、DXRuby開発者、 mirichiさんの「DXRuby機能リクエストにお答えする」でした!!
特に私にはマイナーすぎてまずちんぷんかんぷんです!でもいずれそんな機能達にもうまくふれあいたいですね・・・

前回の記事もあります! http://mirenoteu.blog.fc2.com/blog-entry-40.html

上を見て、そして今回を見るとまず「成長したなー」と感じる人と「低レベルだなー」と思う方といらっしゃるかも知れませんw

ではでは、オブジェクト指向ばりのコードを用いたやり方で記述しましょう。
まずは結果論として、コードを載せました。




#クラスをよく理解していない例。module Flamework に playerが管理しきれて
#ダメージモーションが変な人にある。つまりターゲットにキャラが向かわない。

#! ruby -Ku
require 'dxruby'

#グローバル変数の定義
$turn = 0

#メンバー変数の為のクラス定義
class Person
def initialize(side,mem)
@side = side
@mem = mem
end

def side
@side
end

def mem
@mem
end

end

#インクルード用モジュールの定義
module Flamework

def self.description # モジュールメソッドの定義
"戦闘フレームワーク"
end

#initは初回動作用
def init
#変数群

@@font3 = Font.new( 15,'HGP行書体') #フォントの定義

@@b_x = [[100,100,100,100],[540,540,540,540]] #表示X始点座標 を、4*2箱作る。
@@b_y = [[100,160,220,280],[100,160,220,280]] #表示Y始点座標 を、4*2箱作る。

@@b_sx = [[100,100,100,100],[540,540,540,540]] #表示X始点座標 を、4*2箱作る。
@@b_sy = [[100,160,220,280],[100,160,220,280]] #表示Y始点座標 を、4*2箱作る。


@@image = Image.loadTiles('mireiyu.png', 3,10) #画像のリンク。ここでは横が3個分、縦が10個分と認識する。
@@b_motion = [[0,0,0,0],[0,0,0,0]]
@@b_motioned = [[0,0,0,0],[0,0,0,0]]

@@b_wtime = [[0,0,0,0],[0,0,0,0]]
@@b_doskill = [[0,0,0,0],[0,0,0,0]]

@@b_time = [[0,0,0,0],[0,0,0,0]] #コマ送りの時間 を、4*2箱作る。
@@b_stats = [[0,0,0,0],[0,0,0,0]]
@@b_speed = [[5,10,15,20],[25,30,35,40]]

@@b_attack = [[10,20,30,40],[10,20,30,40]]
@@b_hp = [[300,200,400,100],[300,200,400,100]]
@@b_shp = [[300,200,400,100],[300,200,400,100]]
@@b_target = [[0,0,0,0],[0,0,0,0]]
@@b_id = [[0,1,2,3],[0,1,2,3]]

end
#変数群

#アクションインスタンスを定義
#ターン処理をするもの

def action

if @@b_doskill[self.side].all?{|a| a == 0 } && @@b_doskill[1 - self.side].all?{|b| b == 0 } #誰もが移動行動を取らなければ実行する条件
@@b_stats[self.side][self.mem] += @@b_speed[self.side][self.mem]
@@b_stats[self.side][self.mem] = @@b_stats[self.side][self.mem].floor
end

ok = 0
ok = 1 if @@b_stats[self.side][self.mem] >= 400
if ok != 1
@@b_motion[self.side][self.mem] = 0

elsif ok == 1

case @@b_wtime[self.side][self.mem]
when 0

@@b_doskill[self.side][self.mem] = 2
@@b_target[self.side][self.mem] = @@b_hp[1 - self.side].index(@@b_hp[1 - self.side].select{|c| c > 0}.sample)
@@b_wtime[self.side][self.mem] = 79 if @@b_target[self.side][self.mem] == nil

when 20..39

@@b_x[self.side][self.mem] += 20 if self.side == 0 && @@b_x[self.side][self.mem] <= @@b_x[1 - self.side][self.mem]
@@b_x[self.side][self.mem] -= 20 if self.side == 1 && @@b_x[self.side][self.mem] >= @@b_x[1 - self.side][self.mem]

@@b_y[self.side][self.mem] += 20 if @@b_y[self.side][self.mem] <= @@b_y[1 - self.side][@@b_target[self.side][self.mem]]
@@b_y[self.side][self.mem] -= 20 if @@b_y[self.side][self.mem] <= @@b_y[1 - self.side][@@b_target[self.side][self.mem]]


@@b_motion[self.side][self.mem] = 1

when 40..58

@@b_x[self.side][self.mem] += 20 if self.side == 0 && @@b_x[self.side][self.mem] <= @@b_x[1 - self.side][self.mem]
@@b_x[self.side][self.mem] -= 20 if self.side == 1 && @@b_x[self.side][self.mem] >= @@b_x[1 - self.side][self.mem]

@@b_y[self.side][self.mem] += 20 if @@b_y[self.side][self.mem] <= @@b_y[1 - self.side][@@b_target[self.side][self.mem]]
@@b_y[self.side][self.mem] -= 20 if @@b_y[self.side][self.mem] <= @@b_y[1 - self.side][@@b_target[self.side][self.mem]]

@@b_motion[self.side][self.mem] = 1

when 59

@@b_hp[1 - self.side][@@b_target[self.side][self.mem]] -= @@b_attack[self.side][self.mem]
@@b_motion[1 - self.side][@@b_target[self.side][self.mem]] = 2

when 60..79

@@b_x[self.side][self.mem] += -40 if self.side == 0 && @@b_x[self.side][self.mem] >= @@b_sx[self.side][self.mem]
@@b_x[self.side][self.mem] -= -40 if self.side == 1 && @@b_x[self.side][self.mem] <= @@b_sx[self.side][self.mem]

@@b_y[self.side][self.mem] += 20 if @@b_y[self.side][self.mem] <= @@b_sy[self.side][self.mem]
@@b_y[self.side][self.mem] -= 20 if @@b_y[self.side][self.mem] <= @@b_sy[self.side][self.mem]

@@b_motion[self.side][self.mem] = 1

when 80

@@b_doskill[self.side][self.mem] = 0
@@b_motion[self.side][self.mem] = 0
@@b_motion[1 - self.side][@@b_target[self.side][self.mem]] = 0 #敵のモーションも戻してあげる
@@b_wtime[self.side][self.mem] = -1
@@b_stats[self.side][self.mem] = -100
end
@@b_wtime[self.side][self.mem] += 1
end

$turn += 1 if @@b_doskill[self.side][self.mem] == 0 #ターンは、プレイヤーの行動順番を決める。
$turn = 0 if $turn == @@b_time.flatten.length #一周して戻す
end

#描写。action とわけないと何者かの移動発生中に描写が起こらない。
def render

#画面外対策
@@b_time[self.side][self.mem] = 0 if @@b_motioned[self.side][self.mem] != @@b_motion[self.side][self.mem]
@@b_x[self.side][self.mem] = 0 if @@b_x[self.side][self.mem] < 0
@@b_x[self.side][self.mem] = 640 if @@b_x[self.side][self.mem] > 640

#モーションタイムリセット
@@b_time[self.side][self.mem] = 0 if @@b_motion[self.side][self.mem] != @@b_motioned[self.side][self.mem]
#死亡画像を起こすために常にモーション画像固定
@@b_motion[self.side][self.mem] = 3 if @@b_hp[self.side][self.mem] <= 0
#モーション画像の設定
imagenum = 0
imagenum = 0 if @@b_motion[self.side][self.mem] >= 0 && @@b_motion[self.side][self.mem] <= 0
imagenum = 3 if @@b_motion[self.side][self.mem] >= 1 && @@b_motion[self.side][self.mem] <= 1
imagenum = 6 if @@b_motion[self.side][self.mem] >= 2 && @@b_motion[self.side][self.mem] <= 2
imagenum = 9 if @@b_motion[self.side][self.mem] >= 3 && @@b_motion[self.side][self.mem] <= 3

case @@b_time[self.side][self.mem]
when 120..999
@@b_time[self.side][self.mem] = 0
Window.draw_scale(self.side == 0 ? @@b_x[self.side][self.mem] - 32 : @@b_x[self.side][self.mem], @@b_y[self.side][self.mem], @@image[imagenum] ,self.side == 0 ? 1 : -1 ,1 , 16 ,16 , 1)
when 90..119
Window.draw_scale(self.side == 0 ? @@b_x[self.side][self.mem] - 32 : @@b_x[self.side][self.mem], @@b_y[self.side][self.mem], @@image[imagenum] ,self.side == 0 ? 1 : -1 ,1 , 16 ,16 , 1)
@@b_time[self.side][self.mem] += 2

when 60..89
Window.draw_scale(self.side == 0 ? @@b_x[self.side][self.mem] - 32 : @@b_x[self.side][self.mem], @@b_y[self.side][self.mem], @@image[imagenum + 1] ,self.side == 0 ? 1 : -1 ,1 , 16 ,16 , 1)
@@b_time[self.side][self.mem] += 2

when 30..59
Window.draw_scale(self.side == 0 ? @@b_x[self.side][self.mem] - 32 : @@b_x[self.side][self.mem], @@b_y[self.side][self.mem], @@image[imagenum + 2] ,self.side == 0 ? 1 : -1 ,1 , 16 ,16 , 1)
@@b_time[self.side][self.mem] += 2

when 0..29
Window.draw_scale(self.side == 0 ? @@b_x[self.side][self.mem] - 32 : @@b_x[self.side][self.mem], @@b_y[self.side][self.mem], @@image[imagenum + 1] ,self.side == 0 ? 1 : -1 ,1 , 16 ,16 , 1)
@@b_time[self.side][self.mem] += 2
end

@@b_time[self.side][self.mem] += 1
Window.draw_font(self.side * 200 + 20 , self.mem * 20 + 400 ,"400:" + @@b_stats[self.side][self.mem].to_s + "/" + @@b_speed[self.side][self.mem].to_s , @@font3, hash={color: [122,255,122]})

Window.draw_font(self.side * 200 + 100 , self.mem * 20 + 400 ,"400:" + @@b_hp[self.side][self.mem].to_s + "/" + @@b_shp[self.side][self.mem].to_s , @@font3, hash={color: [255,122,122]})
end
end

#チーム所属とエントリー番号を持つ人のクラス定義
class PersonInBattle < Person #Personで定義したものの継承
include Flamework # Flameworkモジュールを読み込む
def initialize(side,mem)
super(side,mem) #Personで定義したものの継承
end
end

#今回は4対4を再現する。新しいプレイヤーの定義
#()内の意味=>チーム所属:エントリー

player1 = PersonInBattle.new(0,0)
player2 = PersonInBattle.new(0,1)
player3 = PersonInBattle.new(0,2)
player4 = PersonInBattle.new(0,3)

player9 = PersonInBattle.new(1,0)
player10 = PersonInBattle.new(1,1)
player11 = PersonInBattle.new(1,2)
player12 = PersonInBattle.new(1,3)

#初回定義
player1.init
player2.init
player3.init
player4.init
player9.init
player10.init
player11.init
player12.init

Window.loop do #ループを起こす為の記述
#タイムラインシステム
#行動システム
#ミスクシステム
case $turn #順番ごとに実行する。直列動作を起こせる。
when 0 then player1.action
when 1 then player2.action
when 2 then player3.action
when 3 then player4.action
when 4 then player9.action
when 5 then player10.action
when 6 then player11.action
when 7 then player12.action
end
#表示システムは並列。
player1.render
player2.render
player3.render
player4.render
player9.render
player10.render
player11.render
player12.render

end

#さあ、実行!!


team_sample.png

http://pastebin.com/wDUEb05x

これは、クラスオブジェクト初心者のみれいゆーが、なんとかかんとかで使った場合のコードとなります。
できることは、起動すればまた分かるのですが
・4対4の擬似対戦
・体力を削り合う対戦をランダムターゲットで行う
・体力を失った敵は倒れ、ターゲットにされなくなる


ここまで出来ることが出来ました。

(かわいそうなことに)このコードを書く上で初めてクラス変数 @@ の意義を知りました・・・wインスタンス変数@ とも使い分けが重要なのですね!

今回、冗長な事に 各player の action だけを直列処理で実行したくて、 $turn なる変数を使ったりもしました。

また、コードにはあるのに
・敵のダメージモーションが変な人にある
・つまりターゲットの方向に動いていない
等の問題がまだあります。


こう作っていくと、上級者のコードはものすごくエレガントで、奥が深いと改めて感じます。
このチーム戦サイドビューはすでに私の処女作にも使われていて、そこではしっかりターゲットを狙うよう機能しております!!

今回題目にしたサイドビュー自動戦闘システムの他にも私は二個作品を作ってみました。いずれもDXRubyの勉強がてら作ったものです。

①:DXRuby 1.5devより追加されたIME機能とSpriteの組み合わせ
http://pastebin.com/kdq6fb5V
imput_sample.png
②:3つのクラスをそれぞれ操作して拡張、色変更、移動する。(本当は一部同期をしたかった)
http://pastebin.com/XTf9ex9y
class_sample.png

では、次回は、wannabe53 さんの DXRuby を Wine から使う ですーー
私の記事の前も後ろもすごい人ばかり!頑張らなくちゃ!!ではまたーー
スポンサーサイト

コメント

コメントの投稿

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。