2018年 1月31日
エフェクト表示の物理攻撃と魔法の半分(火、水、風)が出来たので報告。
いやあ、意外と手間だよ、コレ。
エフェクト表示は初めてという事もあるけど、やはり2ヶ月も費やす事になりそうだし、グラのデータ容量も結構大きいし、プログラムも意外とややこしいし、絶対必要という訳でも無いし、初心者はやらない方が良いと思った。
少なくとも最初の RUN(プログラム実効)時にグラの読み込みで遅くなるので、一通りゲームが完成してから最後に付けた方が良いと思う。
それじゃあ今回はブログ初の試みで動画で。
今回投稿が遅れたのはこの動画のせいもあって、録画とブログに埋め込む方法を模索していたからというのもある。
ではまず物理アタックから
武器名の表示がワンテンポずれてるが、現在これは確認用なので。
次は素アタック
うわっ!ゆっくり実況音声が混ざってるよ(笑)
自分でビックリッしたけど気にしないで下さい。
動画は引っかきと噛み付きだけだけど、まあそんな感じ。
最後に魔法の一部を
う~ん、プログラムの都合上こっちは名前表示がずれてないみたいだけど、まあ大体こんな感じ。
それじゃあソースがどんな事になってるか公開。
今回エフェクトは始めてなので、要領が悪くソースはベタベタのグチャグチャになってる。
まず表示関係から
; エフェクト表示 efb=20 ; 最大数 efd=12 ; データ数 dim ef,efd*efb ; データ ;(0=種類、1=グラNo.2=表示場所、3=アニメc、4=速さc、5=速さ、 ; 6=x、7=y、8=x動き、9=y動き、10=透明 or 加算、11=移動時間) ddim eff,4*efb ; 実数データ ; (0=反転x、1=反転y、2=回転、3=回転速度) #deffunc efsx ; 座標x if efsn2<=3 : ef(efg+6)=bcx1(efsn2)+40 ; x if efsn2>=4 : ef(efg+6)=bcx2(efsn2-3)+40 ; x return #deffunc efsm int efsmf ; 向き repeat 1 if efsmf=1 : eff(efg2+0)=1.0 : eff(efg2+1)=1.0 : break ; 正 if efsmf=2 : eff(efg2+0)=-1.0 : eff(efg2+1)=1.0 : break ; 左右反転 if efsmf=3 : eff(efg2+0)=1.0 : eff(efg2+1)=-1.0 : break ; 上下反転 if efsmf=4 : eff(efg2+0)=-1.0 : eff(efg2+1)=-1.0 : break ; 全反転 loop if efsn2<=3 : eff(efg2+0)*=-1.0 ; 左の隊の場合の反転 return #deffunc efs int efsf,int efsn1,int efsn3,int efsd,int efsa,int efse ; int efsx,int efsy,int dfsr,int dfsrn ; エフェクトセット(フラグ、グラ、速さ、反転、移動時間、透明か加算か); 動きx、動きy、回転、回転速度) if efsf=0 : return f=0 repeat efb ; No,ピック if ef(efd*cnt)=0 : efg=efd*cnt : efg2=4*cnt : f=1 : break loop if f=0 : return ; 空きが無い ef(efg)=efsf ; 表示種類 ef(efg+1)=efsn1 ; グラNo. ef(efg+2)=efsn2 ; 表示場所 ef(efg+3)=0 ; アニメカウント ef(efg+4)=0 ; アニメ速さカウント ef(efg+5)=efsn3 ; アニメ速さ ef(efg+6)=0 ; x ef(efg+7)=btly1+65 ; y ef(efg+8)=0 ; 動きx ef(efg+9)=0 ; 動きy ef(efg+10)=efse ; 表示種類(0=通常、1=加算) ef(efg+11)=efsa ; 移動時間 repeat 4 eff(efg2+cnt)=0.0 ; リセット loop switch efsf ; 表示種類 case 1 ; 敵固定 if fs=1 : efsn2=et+3 : else : efsn2=et ; 場所x efsx ; x efsm efsd ; 向き swbreak case 2 ; 投射 if fs=1 : efsn2=ut : else : efsn2=ut+3 ; 場所x if itn=289 : if fs=1 : efsn2=4 : else : efsn2=1 efsx ; x n=ut+et-1 : ef(efg+8)=(btlxk*n+btlck)/efsa : if fs=2 : ef(efg+8)*=-1 ; 距離とスピード if itn=289 : ef(efg+8)=(btlxk*2)/efsa : if fs=2 : ef(efg+8)*=-1 efsm efsd ; 向き if id(ig+19)=7 : nf1=-1.0 : nf2=1.0 : else : nf1=1.0 : nf2=-1.0 ; 弓 ; if fs=1 : eff(efg2+0)=nf1 : else : eff(efg2+0)=nf2 ; 向きx ;eff(efg2+1)=1.0 ; 向きxy swbreak case 3 ; 自分固定 if fs=1 : efsn2=ut : else : efsn2=ut+3 ; 場所x efsx ; x efsm efsd ; 向き swbreak case 4 ; 全体 et=2 : if fs=1 : efsn2=et+3 : else : efsn2=et ; 場所x efsx ; x efsm efsd ; 向き swbreak swend ; 回転 if efsn1=5 : if efsn2<=3 : eff(efg2+2)=0.6 : else : eff(efg2+2)=-0.6 ; 曲刀 if efsn1=7 : if efsn2<=3 : eff(efg2+2)=-0.3 : else : eff(efg2+2)=0.3 ; 刺突剣 if efsn1=11 : if efsn2<=3 : eff(efg2+2)=-0.9 : else : eff(efg2+2)=0.9 ; 大剣 if efsn1=13 : if efsn2<=3 : eff(efg2+2)=0.6 : else : eff(efg2+2)=-0.6 ; 槌 if efsn1=19 : if efsn2<=3 : eff(efg2+2)=1.6 : else : eff(efg2+2)=-1.6 ; 大砲 if efsn1=20 : if efsn2<=3 : eff(efg2+2)=1.6 : else : eff(efg2+2)=-1.6 ; フャイヤー if efsn1=24 : if efsn2<=3 : eff(efg2+2)=0.6 : else : eff(efg2+2)=-0.6 ; フレイムアロー if efsn1=30 : if efsn2<=3 : eff(efg2+2)=-1.9 : else : eff(efg2+2)=1.9 ; アイスニードル if efsn1=31 : if efsn2<=3 : eff(efg2+2)=1.6 : else : eff(efg2+2)=-1.6 ; ウォーターストリーム if efsn1=32 : eff(efg2+0)=0.8 : eff(efg2+1)=0.8 ; ピュリファイ if efsn1=33 : eff(efg2+0)=0.8 : eff(efg2+1)=0.8 ; アイスエンチャント if efsn1=34 { ; アイスジャベリン eff(efg2+0)=0.2 : eff(efg2+1)=1.8 ef(efg+3)=10 : ef(efg+11)=30 if efsn2<=3 : eff(efg2+2)=-1.6 : else : eff(efg2+2)=1.6 } if efsn1=35 : eff(efg2+2)=-1.7 : eff(efg2+2)=1.7 ; アイスピラー if efsn1=38 { ; メイルシュトローム eff(efg2+0)=2.5 : eff(efg2+1)=1.0 ef(efg+7)+=24 } if itn=270 { ; ブリザード n1=ef(efg+6)-btlxk : n2=ef(efg+6)+btlxk ; x eff(efg2+0)=0.8 : eff(efg2+1)=0.8 repeat 2 : cnt2=cnt ; 左右のブリザード repeat efb ; No,ピック efg=efd*cnt : efg2=4*cnt : if ef(efg)>0 : continue ef(efg)=efsf ; 表示種類 ef(efg+1)=efsn1 ; グラNo. ef(efg+3)=0 ; アニメカウント ef(efg+4)=0 ; アニメ速さカウント ef(efg+5)=efsn3 ; アニメ速さ if cnt2=0 : ef(efg+6)=n1 ; x if cnt2=1 : ef(efg+6)=n2 ; x ef(efg+7)=btly1+65 ; y ef(efg+8)=0 ; 動きx ef(efg+9)=0 ; 動きy ef(efg+10)=efse ; 表示種類(0=通常、1=加算) ef(efg+11)=efsa ; 移動時間 repeat 4 eff(efg2+cnt)=0.0 ; リセット loop efsm efsd ; 向き eff(efg2+0)=0.8 : eff(efg2+1)=0.8 break loop loop } if efsn1=40 : eff(efg2+0)=1.0 : eff(efg2+1)=0.3 ; ウインドカッター if efsn1=41 : eff(efg2+0)=0.7 : eff(efg2+1)=0.7 ; ウインドムーブ if efsn1=42 : eff(efg2+0)=0.6 : eff(efg2+1)=0.6 ; サンダー if efsn1=43 : eff(efg2+0)=0.8 : eff(efg2+1)=0.8 ; ウィンドエンチャント if efsn1=44 : eff(efg2+0)=0.8 : eff(efg2+1)=1.8 ; サンダーウエポン if efsn1=47 { ; ライトニングボルト eff(efg2+0)=0.5 : eff(efg2+1)=3.0 if efsn2<=3 : eff(efg2+2)=1.6 : else : eff(efg2+2)=-1.6 } if efsn1=48 { eff(efg2+0)=1.4 : eff(efg2+1)=1.4 ; ウィンドストーム} if fs=1 : ef(efg+6)-=40 : else : ef(efg+6)+=40 ; x } return #deffunc efp ; エフェクトプット repeat efb efg=efd*cnt : efg2=4*cnt ; データの先頭 if ef(efg)=0 : continue ; 無い ef(efg+4)+ : if ef(efg+4)>=ef(efg+5) : ef(efg+3)+ : ef(efg+4)=0 : ; アニメウエイト処理 if ef(efg+10)=0 : gmode 3,,,255 : else : gmode 5,,,255 ; 透明、加算 pos ef(efg+6),ef(efg+7) celput efw(ef(efg+1)),ef(efg+3),eff(efg2+0),eff(efg2+1),eff(efg2+2) if ef(efg+3)>=efga(ef(efg+1)) : ef(efg)=0 : break ; アニメ if ef(efg+3)<=ef(efg+11) : ef(efg+6)+=ef(efg+8) ; 動きx ef(efg+7)+=ef(efg+9) ; 動きy eff(efg2+2)+=eff(efg2+3) ; 回転 loop return #deffunc bts1 ; 素アタック if us=6 or us=11 or us=13 or us=33 or us=36 or us=46 or us=51 or us=72 or us=74 or us=97 or us=111 or us=167 or us=181 or us=185 or us=205 : efs 1,3,2,1 : return ; 牙 if us=71 or us=92 or us=96 or us=118 or us=132 or us=184 : efs 1,2,2,2 : return ; 爪 if us=7 or us=16 or us=52 or us=135 or us=168 : efs 1,4,2,2 : return ; 尾 if us=1 or us=8 or us=12 or us=32 or us=35 or us=43 or us=50 or us=73 or us=94 or us=95 or us=112 or us=120 or us=151 or us=152 or us=153 or us=169 or us=183 or us=190 or us=192 : efs 1,9,2,1 : return ; 体当たり efs 1,1,2,1 ; 素手 return #deffunc bts2 ; 近接武器アタック if itn=10 or itn=11 or itn=16 or itn=24 : efs 1,5,1,1 : return ; 曲刀 if itn=12 or itn=15 or itn=23 : efs 1,7,2,2 : return ; 刺突剣 if id(ig+19)=1 : efs 1,15,2,2 : return ; 剣 if id(ig+19)=2 : efs 1,11,2,1 : return ; 大剣 if id(ig+19)=3 : efs 1, 8,2,1 : return ; 槍 if id(ig+19)=4 : efs 1,12,2,2 : return ; 斧 if id(ig+19)=5 : efs 1,13,2,2 : return ; 槌 if id(ig+19)=6 : efs 1,14,2,4 : return ; 杖 return #deffunc bts3 ; 投射武器アタック if id(ig+19)=7 : efs 2,16,1,1,8 : return ; 弓 if id(ig+19)=8 : efs 2,18,1,2,9 : return ; ボウ if itn=90 : efs 2,19,2,1,11 : return ; 大砲 if id(ig+19)=9 : efs 1,17,1,1,0 : return ; 銃 return #deffunc bts4 ; 魔法 if itn=251 : efs 2,20,2,3,17,1 : return ; ファイヤー if itn=252 : efs 3,21,1,1,0 ,1 : return ; ファイヤーウェポン if itn=253 : efs 3,22,2,1,0 ,1 : return ; バーサーク if itn=254 : efs 1,23,2,1,0 ,1 : return ; ファイヤーピレイム if itn=255 : efs 2,24,1,1,15,1 : return ; フレイムアロー if itn=256 : efs 3,25,1,1,0 ,1 : return ; バトルソング if itn=257 : efs 2,26,1,1,7 ,1 : return ; ファイアーボール if itn=258 : efs 4,28,3,1,0 ,1 : return ; ファイヤーウォール if itn=259 : efs 4,29,3,1,0 ,1 : return ; エクスプロージョン if itn=261 : efs 2,30,1,3,18,1 : return ; アイスニードル if itn=262 : efs 2,31,2,3,15,1 : return ; ウォーターストリーム if itn=263 : efs 3,32,1,1,0 ,1 : return ; ピュリファイ if itn=264 : efs 3,33,1,1,0 ,1 : return ; アイスエンチャント if itn=265 : efs 2,34,1,1,18,1 : return ; アイスジャベリン if itn=266 : efs 1,35,3,4,0 ,0 : return ; アイスピラー if itn=267 : efs 3,36,2,1,0 ,1 : return ; ウォータースクリーン if itn=268 : efs 4,37,3,1,0 ,1 : return ; 津波 if itn=269 : efs 4,38,3,1,0 ,1 : return ; メイルシュトローム if itn=270 : efs 4,39,2,1,0 ,1 : return ; ブリザード if itn=281 : efs 2,40,1,1,8 ,1 : return ; ウインドカッター if itn=282 : efs 3,41,2,1,0 ,1 : return ; ウインドムーブ if itn=283 : efs 1,42,1,1,0 ,0 : return ; サンダー if itn=284 : efs 3,43,1,1,0 ,0 : return ; ウィンドエンチャント if itn=285 : efs 3,44,1,1,0 ,1 : return ; サンダーウエポン if itn=286 : efs 4,45,2,1,0 ,0 : return ; セイレーンボイス if itn=287 : efs 3,46,2,1,0 ,1 : return ; ウィンドウォール if itn=288 : efs 4,47,2,1,0 ,1 : return ; ライトニングボルト if itn=289 : efs 2,48,3,1,20,1 : return ; ウィンドストーム return #deffunc bts5 ; その他のエフェクト if itn=257 : efs 1,27,1,1,0 ,1 : return ; ファイアーボールの爆発 return
まあ、なんとも要領の悪いプログラムになってるね。
慣れたらアイテムデータの方に表示種類とか表示方法のデータを埋め込んだ方が良いんだろうけど。
efsという命令でセット、efpという命令で 1フレーム表示になってる。
戦闘プログラムからの呼び出しはワンクッション置いて、bts1~bts4から efsを呼び出す事にした。
種類が多かったので。
次に戦闘プログラムの方はどうなってるかと言うと。
bts1~bts4と言うのがエフェクトを設定するコマンドで、bw 10というのは 10フレーム待つという事。
#deffunc bw int bwn ; バトルウエイト repeat bwn redraw 0 color 0,0,0 : boxf : color 255,255,255 btl_put efp dmp_put bp bpn dg_put redraw 1 await 1000/20 loop return #deffunc atk int atkf,int atkn,int atkrg ; 攻撃(フラグ(0=素手、1=武器、2=魅惑)、攻撃値、射程) ------- atkn2=atkn : atkf2=atkf ; 攻撃処理用フラグ switch atkf case 0 ; 素手 if us=129 or us=94 : swbreak ; 物理アタックしない rang atkrg : if rangf=0 : swbreak ; 射程外 bts1 : atk_syo : bw 20 ; 表示、攻撃処理 swbreak case 1 ; 武器 if id(ig+19)=7 or id(ig+19)=8 or id(ig+19)=9 or id(ig+19)=10 { ; 弓、ボウガン、銃、手裏剣 if ud(ug+8)=24 : brang atkrg : if rangf>0 : bts3 : atk_syo : bw 20 : swbreak ; スナイピング if ud(ug+8)=25 : rang atkrg+1 : if rangf>0 : bts3 : atk_syo : bw 20 : swbreak ; 強弓 if ud(ug+8)=26 { ; 貫通 repeat 3,1 : et=cnt if atkrg<(ut-1)+et : break ; 射程外 en=ffn(et) : if en=0 : continue ; 隊列にいない eg=en*udb : if ud(eg+26)<=0 : continue ; HPが0 bts3 : atk_syo : bw 20 : gsr-=25 ; 攻撃処理 loop swbreak } rang atkrg : if rangf=0 : swbreak ; 射程外 bts3 : atk_syo : bw 20 ; 投射武器、表示、攻撃処理 } rang atkrg : if rangf=0 : swbreak bts2 : atk_syo : bw 20 ; 近接武器、表示、攻撃処理 swbreak case 2 ; 魅惑 bts1 : atk_syo : bw 20 ; 攻撃処理 swbreak swend return #deffunc matk_syo ; 魔法攻撃処理 zk1=zk_syo(ud(ug+7)) ; 種族属性補整 zk2=zk2_syo(mzk2,matkn2) ; アイテム属性補整 dmg 2,ud(ug+22) return #deffunc matk int matkf,int mzk,int matkn,int matkrg ; 魔法攻撃(フラグ、属性、攻撃値、射程) ------- mzk2=mzk : matkn2=matkn switch matkf case 0 ; 手前の一体 -------------- rang matkrg : if rangf=0 : swbreak ; 射程判定 bts4 : matk_syo : bw 20 swbreak case 1 ; 後列の一体 -------------- brang matkrg : if rangf=0 : swbreak ; 射程判定 bts4 : matk_syo : bw 20 swbreak case 2 ; 貫通 -------------- n1=ut+2 : if n1>matkrg : n2=matkrg : else : n2=n1 ; 距離 rang n2 : if rangf=0 : swbreak ; 射程判定 et=n2-ut+1 ; 最後尾 bts4 : matk_efg=efg : bwc=0 ; エフェクト表示 repeat 3,1 : et=cnt repeat ; 移動ウエイト bwc+ : bw 1 : if bwc>20 : break if itn=268 or itn=288 : break ; 津波 if fs=1 : if ef(matk_efg+6)>=btlx2+btlxk*(et-1)+0 : break ; 対象の座標xに来た if fs=2 : if ef(matk_efg+6)<=btlx1+btlxk*(3-ut)+0 : break loop if matkrg<(ut-1)+et : break ; 射程外 en=ffn(et) : if en=0 : continue ; 隊列にいない eg=en*udb : if ud(eg+26)<=0 : continue ; HPが0 matk_syo gsr-=25 ; 威力減衰 loop repeat ; 残りのエフェクトウエイト if bwc>20 : break bwc+ : bw 1 loop swbreak case 3 ; 全列 -------------- rang matkrg : if rangf=0 : swbreak ; 射程判定 et=2 : bts4 : et=2 ; エフェクト表示 repeat matkrg-ut+1,1 if cnt=4 : break et=cnt : en=ffn(et) : if en=0 : continue ; 隊列にいない eg=en*udb : if ud(eg+26)<=0 : continue ; HPが0 matk_syo loop bw 20 ; 表示ウエイト swbreak case 4 ; 着弾範囲型 -------------- f=0 repeat 3,1 ; 3体いるか if ffn(cnt)=0 or ud(ffn(cnt)*udb+26)<=0 : f=1 : break loop if matkrg<(ut-1)+2 : f=1 ; 真ん中に射程が届くか if f=0 { ; 3体の場合 et=2 : bts4 : bw 10 ; 弾道エフェクト gsr=100 ; 中央 et=2 : en=ffn(et) : bts5 : eg=en*udb : matk_syo gsr=75 ; 左右 et=1 : en=ffn(et) : bts5 : eg=en*udb : matk_syo et=3 : en=ffn(et) : bts5 : eg=en*udb : matk_syo bw 10 ; 爆発ウエイト swbreak } rang matkrg : if rangf=0 : swbreak ; 射程内に敵がいなかった bts4 : bw 10 ; 弾道エフェクト bts5 : matk_syo ; 1体目 et+ : if et>3 : swbreak ; 範囲外 en=ffn(et) : if en=0 : swbreak ; 2体目にいない eg=en*udb : if ud(eg+26)<=0 : swbreak ; HPが0 gsr=75 : bts5 : matk_syo ; 2体目 swbreak case 5 ; 押し出し rang matkrg : if rangf=0 : swbreak ; 射程判定 bts4 : matk_syo : bw 15 if et=3 : swbreak ; 最後列 if fs=1 : if fn2(fs2+et+1)=0 or ud(fn2(fs2+et+1)*udb+26)<=0 : fn2(fs2+et+1)=fn2(fs2+et) : fn2(fs2+et)=0 ; 押し出し if fs=2 : if fn1(fs1+et+1)=0 or ud(fn1(fs1+et+1)*udb+26)<=0 : fn1(fs1+et+1)=fn1(fs2+et) : fn1(fs1+et)=0 ; 押し出し ffn(et+1)=ffn(et) : ffn(et)=0 bw 5 swbreak case 6 ; 引き寄せ rang matkrg : if rangf=0 : swbreak ; 射程判定 if et=1 : swbreak ; 最前列 if fs=1 : if fn2(fs2+et-1)=0 or ud(fn2(fs2+et-1)*udb+26)<=0 : fn2(fs2+et-1)=fn2(fs2+et) : fn2(fs2+et)=0 if fs=2 : if fn1(fs1+et-1)=0 or ud(fn1(fs1+et-1)*udb+26)<=0 : fn1(fs1+et-1)=fn1(fs1+et) : fn1(fs1+et)=0 ffn(et-1)=ffn(et) : ffn(et)=0 swbreak case 7 ; ランダム1体 if fs=1 : n=2 : else : n=1 en=rdp(n) : if en=0 : swbreak ; unNo.決定 repeat 3,1 if fs=1 : if fn2(fs2+cnt)=en : et=cnt : break if fs=2 : if fn1(fs1+cnt)=en : et=cnt : break loop eg=en*udb : bts4 : matk_syo : bw 20 swbreak swend return
着弾範囲型のファイアーボールとか、貫通攻撃なんかのエフェクトとダメージのタイミングをプログラムするのが手間です。
最後に画像を読み込むソースを一部だけ
*effect_syoki efwb=10 ; エフェクト画像数 dim efw,efwb ; 画像No, dim efgx,efwb ; 大きさx dim efgy,efwb ; 大きさy dim efga,efwb ; アニメ数 fi2="effect/" ; ファイル名 n2=effectw ; 画像No, n1=1 : efw(n1)=n2 : n2+ efgx(n1)=120 : efgy(n1)=120 : efga(n1)=9 celload fi+fi2+"pipo-btleffect002.png",efw(n1) ; 素手1 celdiv efw(n1),efgx(n1),efgy(n1),efgx(n1)/2,efgy(n1)/2 n1=2 : efw(n1)=n2 : n2+ efgx(n1)=120 : efgy(n1)=120 : efga(n1)=8 celload fi+fi2+"pipo-btleffect121.png",efw(n1) ; 牙2 celdiv efw(n1),efgx(n1),efgy(n1),efgx(n1)/2,efgy(n1)/2 n1=3 : efw(n1)=n2 : n2+ efgx(n1)=120 : efgy(n1)=120 : efga(n1)=8 celload fi+fi2+"pipo-btleffect122.png",efw(n1) ; 爪3 celdiv efw(n1),efgx(n1),efgy(n1),efgx(n1)/2,efgy(n1)/2 return
こんな感じだけど、今半分で 50個くらい読み込んでる。
このデータ量はモンスターカードやアイテム画像なんかより遥かに多い。
動画なので。
と、まあそんな感じでプログラムといい、グラを用意する手間といい、データ量といい、エフェクト表示は思ったより簡単でない事が分かりました。
では、次回はエフェクトの後半を作っていきます。
初めまして。HSPでのアプリの作り方を調べていたらこのサイトを見つけました。
無理をしない様に気を付けながら頑張ってください。応援してます。
おおっ!
なんと初コメをもらいました、ありがとうございます。
なにしろ初めての事なので発見が遅れました済みません。
お気遣いと応援ありがとうございます m(_ _)m