RPG01

MAGI JAVA -Make a game in Java-
JAVA Game作成講座2 01回
マップエディター作成1


RPGkouza2-01 zipファイル



タイトル画面にマップエディタを立ち上げるコマンドを追加した。
立ち上げても黒バックにx,y座標が表示され続けるだけの状態。
Dキーを押すとタイトル画面に戻る。それだけ。
だが、これが全ての始まりになる。

[新シリーズ開始]
前回までの物をさらにバージョンアップしていく。
マップチップの配置が今までソースコード上で行っていたが、エディタに置き換える。
そのための下準備を今回作った。
エディタを立ち上げてただマウスの座標が表示されるだけのプログラムだが、
今までキーボードしか使えなかったものにマウスというデバイスが加わるので、
この意義は非常に大きい。マウスで遊べるゲームが作れるようになるからだ。

未知の処理なのでかなり時間がかかったが、それなりの回答をやっと出せた。
では具体的に何を追加したかを書いていく。
まだ何も出来ない状態だが、その分シンプルで理解しやすい段階だと思う。
どこの解説書でもそうだが、訳の分からないマイルールを知ってる前提でぶちかますからいけない。
初心者がそんなに一気に覚えられるか!! となる。

[ARPanelクラス]
今回の追加部分の大半はここ。

追加したグローバル変数。
public int[] mouseEv=null;
public int[] mouseEvDragged=null;

mouseEv=new int[10];
mouseEvDragged=new int[10];
for (int i=0;i<=9;i++) {
mouseEv[i]=0;
mouseEvDragged[i]=0;
}

mouseEVには、
要素[0]=マウスを右クリック=1,左クリック=3
要素[1]=クリックしたときのX座標
要素[2]=クリックしたときのY座標
…が入る。

mouseEvDraggedには、
要素[0]=現在のボタン状態 マウスを右クリック=1,左クリック=3
要素[1]=現在のマウスX座標
要素[2]=現在のマウスY座標
Draggedは随時更新され続ける。
上のとまとめてもいいのだが、今の所わけておいた。
ドラッグしているか否かは要素0の状態が維持されているかどうかで判断する。

mgka = new MGKeyAdapter();
this.addKeyListener(mgka);

addMouseListener(new MyMouseAdapter()); //マウスがクリックされた時だけ感知するリスナー
addMouseMotionListener(new MyMouseMotion()); //マウスの移動、ドラッグなどを感知するリスナー

キーアダプターを追加している部分に、マウスの動作を察知する処理を追加する。
これで今後マウスをクリックしたり動かしたりするたびにここからメッセージが送られてくる。

public void run(){
//省略
gData.pPlatform.mouseCheck(mouseEv,mouseEvDragged);
//省略
}

runにも追加。mouseEv,mouseEvDraggedを使っているが、これはすぐ後で入力している。

private class MyMouseAdapter extends MouseAdapter {

@Override
public void mouseEntered(MouseEvent e) {
System.out.println("mouseEntered");
}
@Override
public void mousePressed(MouseEvent e) {
mouseEv[0]=e.getButton();
mouseEv[1]=e.getX();
mouseEv[2]=e.getY();
System.out.println("mouse pressed="+mouseEv[0]+" x="+mouseEv[1]+" y="+mouseEv[2]);
}
@Override
public void mouseReleased(MouseEvent e) {
mouseEv[0]=0;
mouseEv[1]=0;
mouseEv[2]=0;
System.out.println("mouse release="+mouseEv[0]+" x="+mouseEv[1]+" y="+mouseEv[2]);
}



}

public class MyMouseMotion extends JPanel implements MouseMotionListener {

@Override
public void mouseDragged(MouseEvent e){
//System.out.println("MMMotion mouse dragged");
mouseEvDragged[0]=e.getButton();
mouseEvDragged[1]=e.getX();
mouseEvDragged[2]=e.getY();
}

@Override
public void mouseMoved(MouseEvent e) {
// TODO 自動生成されたメソッド・スタブ
mouseEvDragged[1]=e.getX();
mouseEvDragged[2]=e.getY();
//System.out.println("MMMotion mouse Moved");
System.out.println("mouse Moved="+mouseEvDragged[0]+" x="+mouseEvDragged[1]+" y="+mouseEvDragged[2]);
}


}

これがマウスを使うために必要な処理。意味わからないが最低限のデータで使える形がコレ。
(ここまでコンパクトにするのに数日かかった。このくらい誰かまとめておいてくれよ…。
専用クラスを作ったり意味不明な記述が多くて他人のプログラムはほとんど使い物にならなかった)

mouseEVやmouseEvDraggedに代入することでpPlatformにマウスの状態を反映できるようになる。
なんでこうしたら動くのか説明できないが、こうするとマウスのデータを抜き出せる、という回答がコレ。

MyMouseAdapterはクリックしたときしかデータを読み取らない。
それでも出来ることはあるのだが、同じマップチップを置くのに何十回もクリック連打するのは疲れる。
押しっぱなしにすることで自動的にチップを配置することが出来ないとエディタとしては不完全だ。
画面のスクロールもそうだけど、一回押すごとに1チップスクロールする、という形では地獄だ。
だから必要なのがドラッグしていることを感知する処理と、リアルタイムにマウスの座標を読み取る処理。

MouseMotionListenerの方はクリックしなくてもデータを送信し続ける。
リアルタイムにマウスの状態を読み取っている、と考えればいい。
これでマップチップの配置が楽にできるようになる。

では次にMapEditorクラスを見ていく。

[MapEditorクラス]
100行ちょっとなので丸コピーしておく。

import java.awt.Graphics;

public class MapEditor {

public Graphics g;
private GameData gData=null;
public int mode=0;
public int[] cursorX=new int[60];
public int[] cursorY=new int[60];
public int[] cursorPos=new int[60];
public int[] cursorMax=new int[60];
public boolean mEditEnd=false;
public GraphicSet gSet=null;
public int mouseX=0;
public int mouseY=0;

public MapEditor() {
gData=new GameData();
gSet=new GraphicSet();
init();
}

public void init() {
mode=1;
mEditEnd=false;
mouseX=0;
mouseY=0;
for (int i=0;i<=59;i++) {
cursorX[i]=0;
cursorY[i]=0;
cursorPos[i]=0;
cursorMax[i]=0;
}
}

public void dataSet(GameData gdt) {
init();
gData=gdt;
}

public void eventStart(GameData gdt) {
gData=gdt;
System.out.println("<---mEdit start--->");
int pushKey=0;
int cPlus=0;
mouseX=gData.pPlatform.mouseEvDragged[1];
mouseY=gData.pPlatform.mouseEvDragged[2];

gData=gdt;
if (gData.pPlatform.keyPush[4]) {
gData.pPlatform.keyPush[4]=false;
pushKey=1;
gData.sePlay(1);
}
if (gData.pPlatform.keyPush[5]) {
gData.pPlatform.keyPush[5]=false;
pushKey=2;
gData.sePlay(2);
}
if (gData.pPlatform.keyPush[0]) {
gData.pPlatform.keyPush[0]=false;
cPlus=-1;
}
if (gData.pPlatform.keyPush[1]) {
gData.pPlatform.keyPush[1]=false;
cPlus=1;
}
if (gData.pPlatform.keyPush[2]) {
gData.pPlatform.keyPush[2]=false;

}
if (gData.pPlatform.keyPush[3]) {
gData.pPlatform.keyPush[3]=false;
}
cursorPos[mode]+=cPlus;
if (cursorPos[mode] > cursorMax[mode]) cursorPos[mode]=0;
if (cursorPos[mode] < 0) cursorPos[mode]=cursorMax[mode];

int cpos=cursorPos[mode];
switch (mode) {
case 1://総合メニュー
if (pushKey==1) {

}
if (pushKey==2) {
mEditEnd=true;
}
break;
}
}

public void paint(Graphics gr) {
g=gr;
int stx=300;
int sty=400;
gSet.wordDisp_short2(g,"(X,Y="+mouseX+","+mouseY+")",0,550,0);
}


}

何の処理も入れていない骨組みだけの形。
statusWindowも戦闘シーンもこういう形が基本になっている。
基本パターンなのでどこのクラスでも使いまわせる。
ここらへんは無駄が多いな、とか思ったら自由に切り貼りすればいいと思う。
キー入力に関してはpPlatformに依存している。
マウス入力もそちらに追加した。

よく使う処理を外部クラスに分担しておくとこのように使いまわしが出来て便利。
文字や四角の表示はgSetに丸投げしているので、gSetクラスさえ呼び出せばどこでも文字や四角を出せる。

今の所やっていることはマウスの状態を読み取って、座標を表示しているだけ。
mouseX=gData.pPlatform.mouseEvDragged[1];
mouseY=gData.pPlatform.mouseEvDragged[2];
この部分で、pPlatformからマウス状態を抜き出している。
pPlatformへはARPanelから自動的にマウス座標を送り続けている。

Dキーを押したら"mEditEnd=true;"
にしている。
そうなったらどうなるかevExeクラスを見ると分かる。

[EventExecutionクラス]
//---------------------------------------------------------------------------
// (019) マップエディタ
//---------------------------------------------------------------------------
public void mEditStart () {
mEdit.eventStart(gData);
if (mEdit.mEditEnd) {
staticEventDataSet(2); //再びタイトル画面を強制起動
}
}

public void mEditPaint() {
mEdit.paint(gData.g);
//System.out.println("<--mEdit Paint-->");
}

エディタ終了と共に強制的にタイトル呼び出しイベントを起動している。
書き忘れていたが、マップエディタを呼び出すときも
staticEventDataSet(3);
で呼び出している。

今回はここまで。次回はボタンを幾つか画面に表示。
クリックしたら何らかのイベントを起こすテストをする。



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