RPG01

MAGI JAVA -Make a game in Java-
JAVA Game作成講座 018回
場所移動イベント+HP回復イベント設定


kouza018 jarファイル



[今回追加したもの]

・場所移動イベントを作成
・回復イベントを作成

回復イベントから作り方を書いていく。
…まぁそんなに大したもんでもないんだけど。
何らかのヒントになればいいと思って書き続けている。
将来的にやり易いようにアレンジして作り直してくれればいい。

[EventExecutionクラス dataSet関数 の一部]
if (evnum==4) { //全回復イベント

datablock[0][0]=7;
datablock[0][1]=someData[0];
datablock[1][0]=8;
datablock[2][0]=999;


}

phase0 イベント番号7 画面をフラッシュさせるイベント。
someData[0]をデータとして渡しているが、色の指定をするための番号。
白以外にもフラッシュさせられるようにする。今は白しかできないけど。

[eventSet関数]
case 7: //(007)フラッシュさせる
flashEffectSet(data[1]);
説明するまでもないが、イベント前にここを通って初期データを設定する。

[eventStart関数]
if (eventMode==5) flashEventStart(); セットがおわったらmode=5に切り替わり、条件を満たすまでこのイベントをループし続ける。

//---------------------------------------------------------------------------
// (007) flashさせる
//---------------------------------------------------------------------------
public void flashEffectSet (int dt1) {

//dt1の指定でフラッシュの色変えられるといいかも。
ct[1]=10;
ct[2]=0;
eventMode=5;
blindAlpha=0;


}

ct[0]がct[10]になるまでイベントを抜けない。

public void flashPaint() {
gSet.rectSet(g,0,0,800,608,3,blindAlpha,0);
}

paint自体は常に同じ画像を表示し続ける。alpha値の変動は下記関数で行う。

public void flashEventStart() {

if (ct[0]<=ct[1]) {
System.out.println("ct[0]="+ct[0]+" / "+ct[1]);
ct[0]++;
if (ct[2]==0) blindAlpha=ct[0]*50;
if (ct[2]==1) blindAlpha=(10-ct[0])*50;
if (blindAlpha<=0) blindAlpha=0;
if (blindAlpha>=255) blindAlpha=255;
} else {
phasePlus=1;
}


}

カウントアップごとにalpha値を上げ、真っ白にフラッシュさせる。
10カウントで終了し、phaseを進ませてイベント終わり。
ただのエフェクトなので自動で進む。

次はイベントナンバー8の全回復イベント。
これよりもっとシンプルで短い。

//---------------------------------------------------------------------------
// (008) HP,MP,SP操作
//---------------------------------------------------------------------------
public void healEvent() {

//生きているユニット全体にEXPをプラスする。max越えたらレベルアップ処理。
//指定が無ければ完全回復する。
for (int i=0;i<=9;i++) {
if (unitLive(i) ) {
gData.uData[i].heal();
}
}
phasePlus=1;


}

public Boolean unitLive(int num) {

if (gData.uData[num].live) {
return true;
}
return false;


}

回復の実行はuDataに組み込んでいる。
hp,mp,kpを上限値まで増やしているのだが、あえて書くまでもあるまい…。
unitLive関数は各所で使うのでシンプルだけど関数かしておくと便利なので作った。
if (gData.uData[x].live==true)
という文を各所に書いているといつかどこかでタイプミスする。

と、いう感じの二つの処理を組み合わせて、フラッシュ→回復というイベントを作った。
フラッシュ無しだと味気ないし、メッセージが出るとボタンを押すのが煩わしい。
何度も使う回復イベントなので、探索で疲れ果てる→触って回復→また探索
という無限ループにストレスを感じさせない演出を維持する。
ついでに効果音とか出すと回復したな、とわかっていいかもしれない。
あとで音はつけられるので、今は先に進む。

次は場所移動イベント。これが実に引数が多く理解しづらい。

[EventExecutionクラス dataSet関数 の一部]
if (evnum==5) { //場所移動イベント

datablock[0][0]=9;
datablock[0][1]=0;
datablock[1][0]=10;
datablock[1][1]=someData[0];
datablock[1][2]=someData[1];
datablock[1][3]=someData[2];
datablock[1][4]=someData[3];
datablock[1][5]=someData[4];
datablock[1][6]=someData[5];
datablock[2][0]=9;
datablock[2][1]=1;
datablock[3][0]=999;


}

場所移動イベント自体はphase1 イベント10だが、
その前にイベント9、イベント10の後にもイベント9を挟んでいる。
画面をブラックアウトし、その間にマップを配置し直して、
再び画面を元に戻すという処理を行っている。
10だけでも移動イベントは作れるが、急にパッと画面が切り替わるので不自然さがある。
漫画のコマをまたぐように、映画でシーンを切り替えるように、
暗転してるあいだにササっと次の場面を用意するわけだ。

まずはイベント9の暗転イベントを見ていく。

//--------------------------------------------------------------------------
// (009) ブラインドイベント 縦横もしくは黒くするだけ…色々
//--------------------------------------------------------------------------
public void blindSet(int dt1) {

eventMode=6;
blind=true;

ctInit(13);
if (dt1==0) {
ct[2]=0;
blindAlpha=0;
} else {
ct[2]=1;
blindAlpha=255;
}


}

dt1=0で入ってくると、真っ黒に塗り潰す。
アルファ値をどんどん上げていくわけだ。
そして、この黒はマップより後に描画するので、
常に黒い幕が画面にかかりっぱなしになる。
dt1=1で元に戻す処理を入れないと真っ黒のままマップが見えない!
という風にならないように、イベントモード抜ける時にblindフラグをfalseにしておく。

public void ctInit(int num) {

ct=new int[3];
for (int i=0;i<=2;i++) {
ct[i]=0;
}
ct[1]=num;


}

public void blindModePaint() {
gSet.rectSet(g,0,0,800,608,2,blindAlpha,0);

}

public void blindEventStart() {

ct[0]++;
if (ct[2]==0) blindAlpha+=20;
if (ct[2]==1) blindAlpha-=20;
if (blindAlpha<=0) blindAlpha=0;
if (blindAlpha>=255) blindAlpha=255;
if (ct[0]>=ct[1]) {
if (ct[2]==1) blind=false;
phasePlus=1;
}


}

ここらへんはあえて解説するまでもない。10カウントで真っ黒にしたり、
10カウントで透明に戻したりするだけの処理。カウント仕切ったらphaseを進める。

ではいよいよ今回の心臓部、場所移動イベントを見て行こう。


[GameDataクラス] //仮データを打ち込み、マップ表示テストを行う。適当な座標に一体出してみる。 public void objKariSet(int mnum,int fnum) {

objCount=0;
objs=new ArrayList();
if (mnum==0) {
objKariSet2(6,6,0,2,1,2);
objKariSet2(10,6,0,3,1,1);
objKariSet2(14,6,0,3,4,1);
objKariSet2(18,6,0,3,4,2);
objKariSet2(22,6,0,3,2,1);
objKariSet2(26,6,0,3,3,1);
objKariSet2(6,10,0,4,0,0);
objKariSet3(10,10,0,5,0,1,1,15,15,8);
}
if (mnum==1) {
objKariSet3(10,10,0,5,0,0,1,18,10,2);
}


}

オブジェのデータ入力を一行に切り替えている。
さらに場所移動イベント専用のデータ入力も追加している。
通常イベントはkariset2でいいが、
場所移動は設定要素が多いため、サブデータが2つでは足りないのだ。

固定場所移動か否か、行き先のマップナンバー、フロア数、x,y,shift
という6つのデータが必要になる。

public void objKariSet2(int x,int y,int shift,int evnum,int dt1,int dt2) {

ObjectBase obj=new ObjectBase();
obj=odtSet.dataSetEasy(x*32,y*32,shift,objCount,evnum,dt1,dt2);
obj.setMapSize(mapSize[0]*32, mapSize[1]*32);
objs.add(obj);
objCount++;


}

データ入力をまとめたバージョン。イベントナンバー、dt1,dt2の3種類で済むイベントはこちらを使う。
戦闘や宝入手、会話イベントなどはこれだけで事足りる。

//設定データを増やしたパターン。指定要素の多い場所移動イベントに使う。1行き先固定か否か 2mapnum 3floor 4x 5y 6shift
public void objKariSet3(int x,int y,int shift,int evnum,int dt0,int dt1,int dt2,int dt3,int dt4,int dt5) {

ObjectBase obj=new ObjectBase();
int[] dt= {dt0,dt1,dt2,dt3,dt4,dt5};
obj=odtSet.dataSetEasy2(x*32,y*32,shift,objCount,evnum,dt);
obj.setMapSize(mapSize[0]*32, mapSize[1]*32);
objs.add(obj);
objCount++;


}

設定データが一気に4つ増えている関数。
データ並びは1行き先固定か否か 2mapnum 3floor 4x 5y 6shift の通り。
これをobjDataSetクラスを経由してobjに組み込ませる。
そして実際にイベントを起こしたときにそれらの数値がどう使われるかがポイント。

//---------------------------------------------------------------------------
// (010) 場所移動イベント。最も多用するので、正確に作る。
//---------------------------------------------------------------------------
public void mapChangeSet(int[] dt) {

int[] goalPlace=new int[10];
int [] gp=new int[10];
//オブジェのsomeDataから行先を取り出すケース
System.out.println("mapChange dt0="+dt[0]);
if (dt[1]==0) {
gData.mapNumberSet(dt[2],dt[3]);
mapMoveDataSet(dt);
}
phasePlus++;


}

もう一遍入力されたdataBlockの中身を書いておく。
dt[0]には10が入り、dt[1]には0or1。今回のケースでは0で通っている。
1,2はmapNumber,floorNumber。3,4,5がx,y,shift。

gData.mapNumberSet(dt[2],dt[3]);
この処理はセーブ・ロード時に重要になる。
記憶されたマップナンバー、フロアナンバーを元に再びマップを作る時に必要になる。
mapMoveDataSet(dt); データを丸投げする。


[EventExecutionクラス dataSet関数 の一部]
if (evnum==5) { //場所移動イベント

datablock[0][0]=9;
datablock[0][1]=0;
datablock[1][0]=10;
datablock[1][1]=someData[0];
datablock[1][2]=someData[1];
datablock[1][3]=someData[2];
datablock[1][4]=someData[3];
datablock[1][5]=someData[4];
datablock[1][6]=someData[5];
datablock[2][0]=9;
datablock[2][1]=1;
datablock[3][0]=999;


}

public void mapMoveDataSet(int gp[]) {

System.out.println("gp mapNumber="+gp[2]+","+gp[3]+" x y="+gp[4]+","+gp[5]+" shift="+gp[6]);
//0番目は場所固定移動イベントか否かのフラグに使用しているので使わない。
//int[] sPos= {gp[3],gp[4],gp[5]}; //3x 4y 5shift(8246上下左右)
gData.pPlatform.setxy(gp[4]*32,gp[5]*32,gp[6]);
gData.maptipKariSet(gp[2],gp[3]);
gData.objKariSet(gp[2],gp[3]);
//状況次第ではカメラ移動しないケースもある。
//ついでにプレイヤーも消す場合もあるが、現時点では無視。
gData.cameraSet(0);


}

丸投げされたデータ値を元にマップを読込み、プレイヤーの座標と向きを変える。
プレイヤーの座標セットは見たままなので省略。

maptipKariSetとobjKariSetでマップナンバーとフロアの二つの引数を元に、
マップデータ、オブジェデータを作成する。

再びGameDataクラスに移る。

[GameDataクラス、maptipKariSetクラスの一部]
public void maptipKariSet(int mnum,int fnum) {

mapTipNumberInit();
if (mnum==0) {
//草原チップでうめつくす
for (int i=0;i<=100;i++) {
for (int j=0;j<=100;j++) {
maptipNumber[i][j]="01"; //[x][y]の順にチップを記憶する
}
}
//y0, x0-100を丘チップ00にする
//同じくx0,y 0-100を丘チップにする
//xy順に利用する為、ちなみに10ならx32 y0の板、11ならx32 y32 土の床 31ならx96 y32 草チップになる。
for (int i=0;i<=100;i++) {
maptipNumber[i][0]="00";
maptipNumber[0][i]="00";
}
}
if (mnum==1) {
//草原チップでうめつくす
for (int i=0;i<=100;i++) {
for (int j=0;j<=100;j++) {
maptipNumber[i][j]="01"; //[x][y]の順にチップを記憶する
}
}
//y0, x0-100を丘チップ00にする
//同じくx0,y 0-100を丘チップにする
//xy順に利用する為、ちなみに10ならx32 y0の板、11ならx32 y32 土の床 31ならx96 y32 草チップになる。
for (int i=0;i<=100;i++) {
maptipNumber[i][0]="00";
maptipNumber[i][20]="00";
maptipNumber[0][i]="00";
}
}
//ブロックをセットする。本来はファイルから読み込むが、マップチップ同様ここでやってしまう。
//丘チップにした場所をブロックで埋め尽くす。
int[][] kariBlock=new int [101][101]; //こっちはstring型じゃなくてもいい。1=壁 0=空白 の2種類だけの現状データ。
blocksInit();
//ホントはここのデーはは他所から引っ張ってくる。
if (mnum==0) {
for (int i=0;i<=100;i++) {
kariBlock[i][0]=1;
kariBlock[0][i]=1;
}
}
if (mnum==1) {
for (int i=0;i<=100;i++) {
kariBlock[i][0]=1;
kariBlock[i][20]=1;
kariBlock[0][i]=1;
}
}


以下略…

mnum==0のケースは今まで使っていたマップを描画するパターン。
mnum==1が今回追加したパターン。
手っ取り早く移動したことを知りたいだけなので、y20の位置にズラッと壁を並べただけ。
それと同時にブロックの設定でもy20の位置にブロックを設定している。
objkariSetに関しては上に書いている。

かなり駆け足だがこんな感じ。
データセットでオブジェにデータを渡し、イベント実行時にまたそこからデータを取り出す。
受け渡すデータが多く、指定する変数を間違えるととんでもない結果になりかねない。
場所移動イベントはちょっとややこしいが、毎回固定の場所に動かすわけではないケースが大半なので、
手入力でサクサク座標とマップを指定できた方が使いやすい。

色々数値を変えると何処がどう作用しているかよくわかると思う。
黒く塗りつぶす処理もあえて省いて実行してみるのも一興。
無くても良いな、と思うかもしれないし、
やっぱり暗転させる意味あるわ、と思うかもしれない。
説明不足な気もするが、とりあえず今回はここまで。

次回は特技・魔法を設定する。



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