RPG01

MAGI JAVA -Make a game in Java-
JAVA Game作成講座 019回
術技追加


kouza019 jarファイル



[今回追加したもの]

・術技データを作成
・ステータスウィンドウから回復系術技を使えるようにした
・戦闘突入エフェクトを作成

今までの応用なので難しくはない処理だが、追加変数の調整に時間を食った。
これが出来たら次はいよいよ戦闘シーンに取り掛かる。
欲を言えば店処理を先に作りたかったが、後でいい。

その下準備が今回の「術技」の登録だ。
今はデフォルトで登録した物をつかうが、将来的には20枠に自由に特技や魔法をセットできるようにする。
ドラクエみたいに膨大な技と魔法から使うものを選ぶのではなく、ロマサガ2以降のやり方をパクるのだ。
よく使うものを事前に登録できるようにする。

例によって細かく各所をいじっているが、追加部分だけ追っていく。

[MagicAndSkillDataクラス]
public class MagicAndSkillData {

public String name="";
public int masNumber=0; //技・魔法の固有ナンバー。categolyとセットで記憶し、セーブ・ロード時にこれらをもとに作り直す。
public int lv=0; //これもセーブ・ロード時にセットする。魔法の設定レベルを表す変数。同じ魔法でも高レベルで使うと威力が上がる。
public int damageType=0; //0物理 1魔法 攻撃魔力をつかって物理属性の魔法もある。
public int attackAnime=0; //shapeで決まる。ドラクエ型にしたらレンジを使うかどうか微妙だが…。

public int type=0;//使用目的 (1=HP回復 2=MP回復 3=HP MP両方回復 4=状態回復 5=能力向上 6=ダメージを与える)
public int power=0;//回復、攻撃等の効力値。この数値+αが効果になる。
public int hit=0; //命中補正。0が基本で1=5%の補正がかかる。-10だと-50%。10なら+50%。
public int range=0;//効果範囲(0=単体 1=全体)
public int useMp=0;//消費MP
public int useKp=0;//消費KP MPKP両方使うものも設定可能

public MagicAndSkillData() {
init();
}

public void init() {
name="";
masNumber=0;
lv=0; //LV上げてセットした術技は消費MP,KPも跳ね上がる。同じ魔法のレベル違いを幾つかセットするのも有効。
damageType=0;
attackAnime=0;
type=0;
power=0;
hit=0;
range=0;
useMp=0;
useKp=0;
}


}

アイテムと似たデータにしてある。
実際使い方もアイテムと同じ。違いはアニメのナンバー、消費MP、KPがある点くらいかも。
バトルを作り出したら多分いくらか修正入れると思う。

では、eventExeクラスで魔法使用コマンドを実用化する。


[StatusWindowクラス eventStart関数 の一部]
public void eventStart(GameData gdt) {

case 10: //魔法・特技使うキャラ選択
if (pushKey==1) {
if (unitLiveCheck(cursorPos[mode]) ) {
selectUnitNumber=cursorPos[mode];
modeChange=11;
}
}
if (pushKey==2) modeChange=1;
break;
case 11: //使う魔法・特技を選ぶ
if (pushKey==1) {
MagicAndSkillData cmas=gData.uData[selectUnitNumber].masData[cursorPos[mode]+1];
int mtype=cmas.type;
int ump=cmas.useMp;
int ukp=cmas.useKp;
int cmp=gData.uData[selectUnitNumber].vst_total[1];
int ckp=gData.uData[selectUnitNumber].vst_total[2];
if (mtype>=1 && mtype<=4 && cmp>=ump && ckp>=ukp) {
selectMasNumber=cursorPos[mode]+1;
//アイテム同様、キャラを選ぶ前に効力をインプットしておく
healPlusInit();
if (mtype==1 || mtype==4) healPlus[0]=cmas.power;
if (mtype==2 || mtype==4) healPlus[1]=cmas.power;
if (mtype==3 || mtype==4) healPlus[2]=cmas.power;
if (mtype==5) healPlus[3]=cmas.power;
healPlus[5]=ump;
healPlus[6]=ukp;
modeChange=12;
}
}
if (pushKey==2) modeChange=10;
break;
case 12:
if (pushKey==1) {
UnitData cUnit=gData.uData[cursorPos[mode]];
if (cUnit.live) {
healPlus[4]=cursorPos[mode];
heal(1);
modeChange=13;
}
}
if (pushKey==2) modeChange=11;
break;
case 13:
healUsing(mode);
break;
}


以下略。

流れはほとんどアイテムの使用と同じ。
mode10 術技を使うキャラを選び
mode11 使う術技を選び
mode12 使う対象を選ぶ
mode13 使用した結果を一定時間表示

10に関してはそのまんまなので省略。
11に少し補足を入れる。
MagicAndSkillData cmas=gData.uData[selectUnitNumber].masData[cursorPos[mode]+1];
なぜcursorPos[mode +1 ]にしているのかというと、0番目は通常攻撃のデータが入っているから。

あとは…大体アイテム使用とと同じだが、消費MP,KP分のMP,KPがあるかどうかのチェックが入る。
条件を満たしていれば使用対象を選ぶmode12に切り替える。

mode12はあまり補足する事は無いが、術技の対象にできるのはlive==trueのキャラだけ。
死亡したキャラに復活魔法はつかえないのか! と思うかもしれないが、
liveは存在そのものを表す変数なので、気絶フラグは別に用意してある。
パーティーに加わっていないキャラがlive==falseになる。

public void heal(int type) {

UnitData cUnit=gData.uData[healPlus[4]];
if (type==0) {
gData.siData[selectItemNumber].quantity--;
if (gData.siData[selectItemNumber].quantity<=0) gData.siData[selectItemNumber].init();
}
//キープした消費mp,kpをvstから引いておく
if (type==1) {
gData.uData[healPlus[4]].vst_total[1]-=healPlus[5];
gData.uData[healPlus[4]].vst_total[2]-=healPlus[6];
}
for (int i=0;i<=2;i++) {
cUnit.vst_total[i]+=healPlus[i];
if (cUnit.vst_total[i]>cUnit.vst_max_total[i]) {
cUnit.vst_total[i]=cUnit.vst_max_total[i];
}
}


}

術技でも使えるようにtypeを加えた。
0で入ってきたらアイテムを消費。1ならmp,kpを消費する。

paintはそのまんま過ぎるので省略。
10-13は関連しているので、一度出したウィンドウを出しっぱなしにする。

描画関連はあまり補足する事は無いが、少しだけ。
回復の効果を表示するやつを少し変えた。

private void healResultDisp(int mode) {

int stx=610;
int sty=320;
gSet.rectSet2(g,stx-24,sty-24,210,100,2,0);
//rectSet(stx,sty,200,80);
String[] moji= {"HP","MP","KP"};
gSet.wordDisp_short2(g,charaName[healPlus[4]],stx-10,sty,0);
UnitData sud=gData.uData[selectUnitNumber];

for (int i=0;i<=2;i++) {
if (healPlus[i]!=0) {
int per=sud.vst_total[i]*100/sud.vst_max_total[i];
String str=moji[i]+" ";
if (healPlus[i]>=1) str+="+";
str+=( healPlus[i]+"("+per+" %)" );
gSet.wordDisp_short2(g,str,stx-10,sty+22+i*22,0);
}
}


}

int per=sud.vst_total[i]*100/sud.vst_max_total[i];
perってのはそのままパーセント。vstの現在値がマックスの何パーセントまであるかを計算している。
100ならフル回復、50なら半分しかない、ということ。
回復した量の後ろにこれをつけて、どこまで回復したかを分かるようにした。
現在値の実数だしてもいいのだが、情報が多くなりすぎる。
30フレームでそこまで読み取る時間はない。

あとは戦闘突入エフェクトか。
ドラクエ6の入り方をパクった。

[EventExcutionクラス dataSetの一部]
if (evnum==6) { //戦闘イベント

datablock[0][0]=11;
datablock[0][1]=0;
datablock[1][0]=12;
datablock[1][1]=someData[0];
datablock[1][2]=someData[1];
datablock[2][0]=999;


}

イベント11がその戦闘入るエフェクト。
黒い四角を回転させながら拡大し、画面一杯にフェードアウトする。
イベント12は戦闘イベントに入る。
今回はまだ作ってないので、すぐにフェーズを進めて終了するだけ。
いよいよ次回手を付ける。
今回はイベント11を見ていく。

someEffectSet(data[1]);
データセット。

//---------------------------------------------------------------------------
// (011) エフェクト各種
//---------------------------------------------------------------------------
public void someEffectSet (int dt) {

ct[1]=40;
ct[2]=0;
eventMode=7;
eventMode2=0;
blindAlpha=0;
effectDisp=true;


}

public void someEffectPaint() {

int c=ct[0];
Graphics2D g2 = (Graphics2D)g;
AffineTransform at = new AffineTransform();
at.setToRotation(Math.toRadians(c*9),400,304);

g2.setTransform(at);
//左上隅を基準に描画するので、描画始点を拡大幅の半分ずつずらしながら大きくすることで、
//四角形ブン回しのドラクエ6みたいな戦闘開始エフェクトを作れる。
g2.fillRect(400-c*12,304-c*12,c*24, c*24);


}
public void someEffectStart() {

if (ct[0]<=ct[1]) {
ct[0]+=2;
} else {
phasePlus=1;
}


}

テクニカルなことはあまり詳しく語れない…。
前回作ったやつをそのまま流用しただけなので。
x,yをずらしつつ、サイズを拡大し、回転させる。
そういう処理をやっている。

startでまわすのはカウンターを増やしていることだけ。
40で終了なので、20回のループで終わる。
1ずつ増やすともうちょい長い時間かかるが、
もっさりしているので倍速にした。

effectDisp=true;
のあいだは無条件にこの黒いバックを表示し続けるのだが、
戦闘入ったら解除する。
戦闘画面を用意する間の時間稼ぎでフェードアウトさせるわけだ。

今回はこのくらいか。何か足りなかったら後で追加する。
さて、次回はやっと戦闘イベントを作成にかかる。
多分今まで以上に時間がかかるので、次の更新は時間がかかる思う。
もしくは、段階的に作成するかもしれない。
まずは敵とデータの表示だけ、とか。

そもそもターン制にするか、行動ポイントを生かしたターン制にするか、
距離の概念は入れるのか。陣形はとか作るのか。何も考えてない…。
FFみたいに前列、後列でもいいんだけど。
戦闘まで完成するとゲームっぽくなる。
今週中にある程度形にしたいと思う。



・トップページへ戻る
inserted by FC2 system