MAGI JAVA -Make a game in Java-
JAVA Game作成講座 010回
壁オブジェを作成する


kouza010 jarファイル



[今回追加したもの]
・GameDataクラスに壁オブジェ関連の処理を追加
・合わせて他の部分も微妙にいじった


[GameDataクラスの変更点]

public ArrayList blocks=new ArrayList();
前回作ってそのまま放置していたArrayListを使う。


//仮データを打ち込み、マップ表示テストを行う
public void maptipKariSet() {

maptipNumber=new String[101][101];
int[][] kariBlock=new int [101][101]; //こっちはstring型じゃなくてもいい。1=壁 0=空白 の2種類だけの現状データ。
//中略…
//・
//・
//この仮データで行くと、約200個のblockクラスをArraylistに登録することになる。
//最大100*100置いて10000個ほどになるが、実際はそこまでブロックを置く事は無い。
//ArrayListを使った理由は、出し入れが容易だから。
//普通に用意すると10000個BlockObjectの入れ物を用意しなければいけない。大半使わんのに。
for (int y=0;y<=100;y++) {
for (int x=0;x<=100;x++) {
if (kariBlock[x][y]==1) {
//kariBlockデータを総サーチして、1=壁 の場所を読み込む。
//その座標をキープし、BlockObjectクラスを作成して座標セット。
BlockObject nb=new BlockObject();
nb.dataSet(x*32,y*32); //ブロックのx,yもプレイヤー同様実座標で管理する
blocks.add(nb); //ArrayListのケツ番にブロックを放り込む。
}
}
}


}

[BlockObjectクラスのデータセットだけ抜粋]
mapKariSet関数でブロックを作成、ブロックのx,y座標をセットしていく。

public void dataSet(int sx, int sy) {

x=sx;
y=sy;
live=true; //セットした時点で存在を確定させる。
size=32; //大体サイズは32。

}

GameDataクラスの追加はこのくらいだと思う。
次はARPanelでブロックとプレイヤーの当たり判定をチェックするようにする。


[ARPanelクラス]

private Collision collision=null;

まずCollisionクラスを作成する。
このクラスに2つのオブジェクト(プレイヤー含む)の
x,y座標と縦横幅(size)を放り込むと、
そのオブジェクトの半径が重なっているか/否かを判定。
重なっていた場合はその重なり具合のx,y量を返すクラス。
それほど難しいことをするわけではないが、汎用性が高い。

public void run(){

time++;

if(time % 2 == 0){
gData.pPlatform.keyCheck(keyPressTbl);
gData.pPlatform.move(gData);
//ブロック衝突チェック
blockHitCheck();

gData.cameraSet(1);
}else{
repaint();
}
} // end run


run関数で追加したのは
blockHitCheck();
だけ。

//----------------------------------------------------------
//ブロック衝突チェック
//----------------------------------------------------------

これがメインの追加部分。
登録されている壁とプレイヤーの当たり判定チェックをしている。
手順が回ってくるたびにやるので、30フレームごとに全壁オブジェとのチェックをする。

collisionを使う時はx,y,sizeを引っこ抜いてintにまとめる。
int pxy[]=gData.pPlatform.getxy();
int bxy[]=gData.blocks.get(i).getxy();
この二つの処理がそれ。

public int[] getxy() {
int gxy[]= {(int)x,(int)y,size,shift};
return gxy;
}

blockのゲッターもこれとほぼ同じ処理。
shiftの帰りが無いだけ。blockに向きなどないので。

それをチェックしたい二つのオブジェ分用意し、放り込む。
結果、重なったx,yの量が戻ってくるので、
gData.PPlatform.movexyに重なり値を放り込む。
その分だけ押し戻すことで壁にめり込まなくなるのだ。

private void blockHitCheck() {

//まず、ブロックが有効なものをピックしてその対応する番号だけblockNum配列に放り込む。
int blocksSize=gData.blocks.size();
//ブロックが一個以上あれば当たり判定チェックに入る。
if (blocksSize >= 1) {
//プレイヤーとブロックのチェックから
int pxy[]=gData.pPlatform.getxy(); //プレイヤーの座標とサイズを抜く。
for (int i=0; i<= blocksSize-1; i++) {
int bxy[]=gData.blocks.get(i).getxy();
//int bxy[]=gData.blocksGetxy(i);
//collision.blockで処理後、重なっているx,yの長さを返してくる。
int oxy[]=collision.block(pxy,bxy);
//重なっている分を強引に押し戻す。
if (oxy[2]!=0) gData.pPlatform.movexy(oxy[0], oxy[1]);
}

//ここから先はコメントなので実行しない。
//そのうち使うのでそのままキープ。
//何やってるのかというと、
//プレイヤー以外のオブジェ(店員、敵キャラetc)と壁のヒットチェック。
/*int objSize=gData.objs.size();
if (objSize >=1) {
for (int i=0; i<= objSize-1; i++) {
//moveType
ObjectBase cObj=gData.objs.get(i);
//移動タイプが0のオブジェは壁とのヒットチェックをしない。
if (cObj.moveType>=1 && cObj.blockPassing==false) {
int obxy[]=cObj.getxy(); //プレイヤーの座標とサイズを抜く。
//System.out.println("pxy="+pxy[0]+","+pxy[1]+" size="+pxy[2]);
for (int j=0; j<= (gData.blocks.size()-1); j++) {
int bxy[]=gData.blocksGetxy(j);
//System.out.println("bxy="+bxy[0]+","+bxy[1]);
int oxy2[]=collision.block(obxy,bxy);
if (oxy2[2]!=0) cObj.movexy(oxy2[0], oxy2[1]);
}
}
}
}*/

}

}

collisionクラスに関してはまるまる貼っても仕方ないので省略。
ソースコードそのまんまの処理なので言う事は無い…。
ActionScriptのコードを丸コピーしただけなので意味が分かってない部分も多い。



これで壁とプレイヤーを衝突させることができた。
壁をもっと複雑に配置し、建物を作ったりできる。

次回はオブジェクトを用意する。
役割は壁と似ているが、イベントを仕込むことで色々な要素を持たせられる。
イベント実行クラスも合わせて作りたいが、
これに手を付けると凄く長い説明になる。

次回はオブジェクトの登録と配置、
オブジェクトとプレイヤーの衝突チェックだけ作る。
それが出来たらいよいよイベントクラスを作成する予定。
その準備を進めておく。

会話、場所移動、ステータス画面呼び出し、戦闘…
全てイベントクラスの中で処理される。


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