JAVAプログラミング講座 宇宙のJAVAさん外伝
「 第七銀河の彼方に 」

- 第2話 時 空 -
くまがフィールドを歩くプログラム(1)
さて、iアプリプログラミングの続きです。
今回はRPGっぽいフィールドをキャラが移動するプログラムを説明します。
はーい!
こんな感じで、くまが前後左右に移動します。

まずは、プログラムをダウンロードしてください。
くまが歩くプログラム
展開すると、「SampleiApp」というフォルダができます。
そのフォルダ中にプログラムソースと画像ファイルが入ってます。
前回の講座で作った「C:\DoJa」の下に、この「SampleiApp」というフォルダを移動してください。
GiGA-Appli Developer's Kit の「プロジェクトを開く」を押して、C:\DoJa の下の「SampleiApp」を開いてください。
できたみゃ。
では、最初にエミュレータで動かしてみましょう。
ダウンロードしたファイルには、すでにコンパイル済みのファイルが入っているので「エミュレータ起動」ボタンを押すと、プログラムが動作します。
上下左右ボタンで、くまさんが移動すると思います。
ほんとだも〜
では、「SampleiApp.java」を選んで、「ソース編集」を押してください。
エディタ(メモ帳等)でソースファイルが開いたと思います。
さっそく、プログラムの説明をしましょう。
本当は「JAVA講座
宇宙のJAVAさん」みたいに、順を追ってプログラムを作りながら説明したいのですが、今回は完成(?)しているプログラムを説明していきます(*1)。
これが、ソースファイルです。
では、上から見ていきましょう。
| import com.nttdocomo.ui.*; import com.nttdocomo.io.*; // ========================================== |
import com.nttdocomo.ui.*;
import com.nttdocomo.io.*;
iアプリのクラスファイルを読み込んでます。
この2行は、お決まりの宣言です。
public class SampleiApp extends IApplication
{
<中略>
} // End of Class
IApplication から継承された SampleiAppクラスがこのプログラムのメインクラスになります。
なんとか extends IApplication
で、「なんとか」が IApplication から継承されることになります。
public void start() {
// MyCanvasクラスを画面に表示
MyCanvas c = new MyCanvas();
Display.setCurrent(c);
}
iアプリはメインクラスの中の「start()」から始まる! というお約束があるので、start()
関数を書きます。
プログラムはここから始まります。
で、何をやっているかというと、MyCanvas クラスを作成して、
MyCanvas c = new MyCanvas();
作成した MyCanvasクラスを画面にセットしています。
Display.setCurrent(c);
これで、画面全体に MyCanvasクラスが表示されます。
これで、メインクラス「SampleiApp」は全部です!
あれ?
MyCanvasクラスなんて、iアプリのクラスライブラリにあったかにゃ??
Canvasクラスなら聞いたことがあるみゃーが?
MyCanvas
クラスは自作のクラスですよ。
それは、これから説明します。
ってゆぅーかぁー、
プログラムは MyCanvasクラスに書いてあるのです。
SampleiAppクラスは、ほとんど何もしていません。
次に
MyCanvas クラスを見ていきましょう。
|
// ========================================== <中略> } // End of Class |
<中略>と書いてありますけど、全部で96行ほどあるプログラムリストです。
} // End of Class は、プログラムの一番下の行です。
class MyCanvas extends Canvas {
MyCanvas
は、Canvasクラスから派生しています。
Canvasクラスから派生した MyCanvas には、自由にCGが描けます。
ここにゲーム画面を作画していきます。
では、MyCanvas
の中身を上から見ていきましょう。
| class MyCanvas extends Canvas { // === グローバル変数 === int x, y; Image img[]; char map[][]; boolean isK = true; |
すぐ下にグローバル変数の宣言があります。
グローバル変数は、MyCanvas全体で使用可能な変数です。
グローバル変数の内容は次のとおりです。
int x, y;
くまさんの現在座標
Image img[];
画像(くまや背景)
char map[][];
マップデータ
boolean isK = true;
くまさんの状態(左足を上げているかどうか?)
次にコンストラクタを見てみましょう。
コンストラクタとは、MyCanvasクラスが実行される時に最初の動作する関数です。
JAVAアプレットの init() 関数と同じと考えて下さい。
コンストラクタはクラス名とおなじ名前の関数名を付けます。
よって、MyCanvasクラスのコンストラクタは MyCanvas() です。
| // === コンストラクタ === MyCanvas() { x=20; y=20; img = new Image[5]; // GIF画像読込み for(int i=0; i<5; i++){ MediaImage mImg = MediaManager.getImage("resource:///"+i+".gif"); try { mImg.use(); } catch (com.nttdocomo.io.ConnectionException e) { System.out.println("Image Read Error !"); } img[i] = mImg.getImage(); } // マップ初期宣言 map = new char[50][50]; for(int xx=0; xx<50; xx++) for(int yy=0; yy<50; yy++) map[xx][yy]=3; for(int xx=5; xx<45; xx++) for(int yy=5; yy<45; yy++) map[xx][yy]=1; // ランダムで岩山を配置(200個) java.util.Random rnd; rnd = new java.util.Random() ; for(int xx=0; xx<200; xx++){ int r1 = rnd.nextInt(); if(r1<0) r1=-r1; int r2 = rnd.nextInt(); if(r2<0) r2=-r2; map[r1%40+5][r2%40+5]=2; } // ファンクションキー設定(Exit) setSoftLabel(Frame.SOFT_KEY_1, "Exit"); } // Constructor |
け、結構長いですね・・・
では、上から説明しましょう。
x=20; y=20;
img = new Image[5];
xに20、yに20を代入しています。
よってゲームスタート時のくまさんの最初の座標は(20,20)になります。
次に img を配列宣言しています。
くまさんと背景を合わせて5枚の画像があるからです。
// GIF画像読込み
for(int i=0; i<5; i++){
MediaImage mImg = MediaManager.getImage("resource:///"+i+".gif");
try {
mImg.use();
} catch (com.nttdocomo.io.ConnectionException e) {
System.out.println("Image Read Error !");
}
img[i] = mImg.getImage();
}
ここでは、画像ファイル(GIFファイル)を
img 変数に読み込んでいます。
画像ファイルは resource フォルダに入っています。
resource フォルダを見てください。 次の5つの画像があると思います。
0.gif
1.gif
2.gif
3.gif
4.gif
このプログラムで、各画像を
img[] に収納しています。
img[0] は ![]()
img[1] は ![]()
img[2] は ![]()
img[3] は ![]()
img[4] は ![]()
// マップ初期宣言
map = new char[50][50];
map[][]
を配列宣言します。 50x50 の2次元配列です。
これで全体のマップのサイズは 50 x 50 になります。
しつもんだも〜
なんで、map[][] は数字を入れるのに char 型なんだも??
普通 int型 にするも〜
それはですね。 メモリーがもったいないからなんですよ。
私が普通のコンピュータのプログラムを作るときは、もちろん int型にします。
しかし iアプリはメモリーが少なそうなので、念のため(?) char 型にしました。
多分 int型にしても問題ないとは思いますが・・・(ページ下、「追加コメント」参照)
なるほども。
640kの壁 を思い出すも〜
for(int xx=0; xx<50; xx++)
for(int yy=0; yy<50; yy++) map[xx][yy]=3;
次に
map[][]のすべての変数に 3 を代入します。
ちなみにこの数字は img[][] と連動しているので、すべて海の画像にしたことになります。
ちょっとわかりづらいプログラムですが、次のプログラムと同じ事をしています。
for(int xx=0; xx<50; xx++) {
for(int yy=0; yy<50; yy++) {
map[xx][yy]=3;
}
}
for(int xx=5; xx<45; xx++)
for(int yy=5; yy<45; yy++) map[xx][yy]=1;
そして次に、(5,5)-(44,44)
までのmap[][]に、 1番(平原)を代入します。
この時点で、map[][]
は、イメージ的には次のようになってます。
33333333333333333333333333333333333333333333333333 33333333333333333333333333333333333333333333333333 33333333333333333333333333333333333333333333333333 33333333333333333333333333333333333333333333333333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333111111111111111111111111111111111111111133333 33333333333333333333333333333333333333333333333333 33333333333333333333333333333333333333333333333333 33333333333333333333333333333333333333333333333333 33333333333333333333333333333333333333333333333333
ちなみに、map[][]
は縦50、横50あるので、 本当はもっと巨大なマップです。
// ランダムで岩山を配置(200個)
java.util.Random rnd;
rnd = new java.util.Random() ;
for(int xx=0; xx<200; xx++){
int r1 = rnd.nextInt();
if(r1<0) r1=-r1;
int r2 = rnd.nextInt();
if(r2<0) r2=-r2;
map[r1%40+5][r2%40+5]=2;
}
map[][]の
(5,5)-(44,44)の部分(平野の部分)に、ランダムで200個、2番(岩)を代入します。
これで、所々に岩があるマップが出来上がりました。
// ファンクションキー設定(Exit)
setSoftLabel(Frame.SOFT_KEY_1, "Exit");
左側のファンクションキーに「Exit」という文字を設定します。
この文字は画面左下に出ます。
あとで、このボタンを押したらiアプリが終了するプログラムを作ります。 <イベント関数で
さて。
あとイベント関数の processEvent( ) と、作画関数の paint() が残ってますが、 これらは次回にしましょう。
では、さようなら! また次回!
なんか、中途半端な終わり方だも〜
なんか、説明するのに疲れた感じがとてもででいるみゃ。
そのとおり!
続く!
(*1) さいきん時間が無いでぷ〜(T_T)
J2ME Wireless SDK for the DoJa
いちおう
DoCoMo開発ツール「J2ME Wireless SDK for the DoJa」用のサンプルソースも置いておきます。「J2ME Wireless
SDK for the DoJa」をお使いの方はこれをダウンロードして、展開してください。
それで、J2MEWSDK4DOJAフォルダの下のappsフォルダに、展開してできた SampleiAppフォルダを移動してください。
追加コメント (2001.06.08.)
裕樹さんからメールを頂き、「iアプリではintよりcharの方が、逆にファイルサイズが大きくなる場合があります」との事。
私のほうでもやってみましたら、本当にjarファイルのサイズがわずかに増えました。
こりはビックリ。 メモリー節約で char を使った私の立場は?
裕樹さん、情報ありがとうございます。
|
宇宙のJAVAさん外伝 (C) BakuretuKen 2001 |