Report8
オリジナルのJavaアプレットを作れ。
<<もぐらたたきゲーム>>
// mole
// もぐらたたきゲーム
import java.applet.Applet;
import java.awt.*;
import java.util.*;
import java.lang.*;
public class mole2 extends java.applet.Applet implements Runnable {
MediaTracker mt;
Image pict[] = new Image[4] ; // 穴やもぐらの絵を入れる配列
int speed = 800; // もぐらを出すスピード
int time; // もぐらが出る回数
int mole; // もぐらが出てくる穴の番号
int score; // 点数
int card[] = new int[12]; // 表示する絵(番号)を入れる配列
int x[] = new int[12]; // 穴の位置(x座標)
int y[] = new int[12]; // 穴の位置(y座標)
int cardWidth = 32, cardHeight = 32; // 穴の絵の幅、高さ
Thread kicker = null; // アニメーションのためのスレッド変数
Dimension d; // 表示領域
Image offs; // オフスクリーン
Graphics grf;
public void init(){
int i ,j; // カウンター
int k; // カード番号
int yy; // 段毎のy座標
mt = new MediaTracker(this);
/* イメージファイルの読み込み */
for( i = 0 ; i < 4 ; i++ ){
pict[i] = getImage(getCodeBase(), "img" + (i) + ".gif");
mt.addImage(pict[i],0);
}
/* 絵の位置(x、y座標)の設定 */
k = 0;
for( i = 0 ; i < 3 ; i++ ){
yy = i * cardHeight + 5;
for( j = 0 ; j < 4 ; j++ ){
x[k] = j * cardWidth + 5;
y[k] = yy;
k = k + 1;
}
}
/* オフスクリーンの設定 */
d = size(); // 表示領域の取得
offs = createImage( d.width, d.height);
grf = offs.getGraphics();
/* 変数の初期化 */
time = -1; // もぐらの出る回数をセット
score = 0; // 点数のリセット
for( i = 0 ; i < 12 ; i++ ){
card[i] = 0; // すべて穴だけの状態に戻す
}
}
public void paint(Graphics g) {
update(g);
}
public void update(Graphics g){
int i; // カウンター
/* 読み込み中メッセージの表示 */
if (mt.checkID(0) == false) {
g.setColor(Color.black);
g.fillRect(0, 0, d.width, d.height);
g.setColor(Color.yellow);
g.setFont(new Font("TimesRoman", Font.PLAIN, 14));
g.drawString("Loading...", 40, 50);
return;
}
/* バックをオレンジで塗る */
grf.setColor(Color.orange);
grf.fillRect(0,0,223,106);
/* タイトルの描画 */
grf.setColor(Color.red);
grf.drawString("MOGU! MOGU!", 138, 20);
/* カードの描画 */
for( i = 0 ; i < 12 ; i++ ){
/* セットされている絵を描く */
grf.drawImage( pict[card[i]], x[i], y[i], this);
}
/* STARTボタンの描画 */
grf.setColor(Color.green);
grf.fillRect( 138, 70, 65, 25 );
grf.setColor(Color.black);
grf.drawString("START", 150, 88);
/* 点数の表示 */
grf.setColor(Color.black);
grf.drawString("Score : "+score, 142, 40);
grf.setColor(Color.blue);
if ( time == 0 ) {
/* 点数によってメッセージを出力 */
if ( score >= 35 ) {
grf.drawString("I'm crazy for you!", 142, 60);
} else {
if ( score >= 25 ) {
grf.drawString("Great!!!", 142, 60);
} else {
grf.drawString("good!", 142, 60);
}
}
} else {
if ( time > 0 ) {
/* 残り時間の表示 */
grf.drawString("time", 142, 55);
for( i = 0 ; i < time ; i++ ){
grf.drawString("|", 142+i, 65);
}
}
}
/* オフスクリーンのイメージを一挙に実際の表示領域に描く */
g.drawImage(offs, 0, 0, this);
}
public boolean mouseDown(java.awt.Event evt, int ix, int iy){
int i; // カウンター
int row, col; // マウスが押された位置(行、列)
int nn; // マウスが押された穴の番号
if ( ix > 138 & ix < 203 & iy > 70 & iy < 95 ) {
/* マウスの座標(ix,iy)がSTARTボタン内 */
/* だったら穴の絵をセットし直す */
stop();
gameStart();
repaint();
return true; // このメソッドを抜ける
}
/* マウスで何列目が押されたか */
col = 0;
if( ix > cardWidth + 5 ) col = 1;
if( ix > cardWidth * 2 + 5 ) col = 2;
if( ix > cardWidth * 3 + 5 ) col = 3;
if( ix > cardWidth * 4 + 5 ) col = -1;
if( col < 0 ) return true; // 穴の無い場所だったらこのメソッドを
抜ける
if ( time == 0 ) return true;
/* マウスで何行目が押されたか */
row = 0;
if( iy > cardHeight + 5 ) row = 1;
if( iy > cardHeight * 2 + 5 ) row = 2;
if( iy > cardHeight * 3 + 5 ) row = -1;
if( row < 0 ) return true; // 穴の無い場所だったらこのメソッドを
抜ける
/* 穴の番号の計算 */
nn = row * 4 + col;
if ( mole == nn ) {
score = score + 1; // 点数を加算
card[nn] = 3; // 叩かれているもぐらの絵(番号)をセット
} else {
card[nn] = 2; // トンカチの絵(番号)をセット
}
repaint(x[nn], y[nn], 32, 32);
return true;
}
public void start() {
if(kicker == null) {
/* スレッドを実行させる */
kicker = new Thread(this);
kicker.start();
}
}
public void stop() {
/* スレッドを止める */
if ( kicker != null ) {
kicker.stop();
kicker = null;
}
}
public void run() {
int i;
/* 全てのイメージの読み込みを待つ */
try{
mt.waitForID(0);
} catch (InterruptedException e) {
return;
}
/* timeが0になるまで繰り返し */
while( time > 0) {
/* 乱数でもぐらが出る穴を決める */
mole = (int)( Math.random() * (float)(12) );
card[mole] = 1;
/* 再描画 */
repaint();
try{
Thread.sleep(speed);
} catch (InterruptedException e){}
for( i = 0 ; i < 12 ; i++ ){
card[i] = 0; // すべて穴だけの状態に戻す
}
time = time -1; // 残りの回数を減らす
}
repaint();
}
public void gameStart(){
int i;
/* 変数の初期化 */
time = 40; // もぐらの出る回数をセット
score = 0; // 点数のリセット
for( i = 0 ; i < 12 ; i++ ){
card[i] = 0; // すべて穴だけの状態に戻す
}
start();
}
}
考察
for( i = 0 ; i < 4 ; i++ ){
pict[i] = getImage(getCodeBase(), "img" + (i) + ".gif");
mt.addImage(pict[i],0);
}
|
作成した描画を読み込んでいます。
描画は穴だけの絵、もぐらが出てくる絵、トンカチの絵、もぐらが叩かれている絵の4種類です。
public void run() {
int i;
/* 全てのイメージの読み込みを待つ */
try{
mt.waitForID(0);
} catch (InterruptedException e) {
return;
}
/* timeが0になるまで繰り返し */
while( time > 0) {
/* 乱数でもぐらが出る穴を決める */
mole = (int)( Math.random() * (float)(12) );
card[mole] = 1;
/* 再描画 */
repaint();
try{
Thread.sleep(speed);
} catch (InterruptedException e){}
for( i = 0 ; i < 12 ; i++ ){
card[i] = 0; // すべて穴だけの状態に戻す
}
time = time -1; // 残りの回数を減らす
}
repaint();
}
|
このrunメソッドでは基本的なルールの設定をしています。
mouseDownとは
これはマウスが押された、というイベントに対しての処理を表します。
このプログラムではどの穴が叩かれたかの判定をします。
gameStartメソッド
このメソッドでは、4つの機能があります。
1、変数の初期化
2、モグラの出る回数をセット
3、点数のリセット
4、すべて穴だけの状態に戻す
Graphicsクラス
タイトルやスタートボタンを表示するには数多くのGraphicsクラスが使われている。
メソッド | 意味 |
drawImage(Image img,int x,inty,ImageObsever io) |
座標x,yに左上隅が配置されるようにイメージimgを描画する。描画処理の進行状況は、ioに送られる |
drawRect(int x,int y,int w,int h) |
座標x,yに左上隅が配置される幅w,高さhの四角形を描画する |
drawString(String str,int x,int y) | strを座標x,yに描画する |
setColor(Color c) | グラフィックコンテキストの現在のカラーとしてcを設定する |
setFont(Font f) | 現在のオブジェクトのフォントとしてfを設定する |
Color getColor() | 現在のオブジェクトのカラーを取得する |
Font getFont() | 現在のオブジェクトのフォントを取得する |
FontMetrics getFontMetrics() | 現在のオブジェクトのフォントメトリックスを取得する |
Dimensionコンストラクタ
Dimension()
Dimension(Dimension d)
Dimension(int w,int h)
dはDimensionオブジェクトです。wは幅、hは高さを表すピクセル値です。いずれも省略すると幅、高さ0を指定したものと見なされます。このクラスには、int型の
インスタンス変数widthとheightがあります。
getImage()メソッド
Image getImage(URL ur1)
Image getImage(URL base, String fileName)
1つ目の形式では、イメージリソースを表す絶対URLを引数として受け取ります。
2つ目の形式では、イメージファイルをダウンロードするベースのURLを1つ目の引数として受け取り、目的のファイル名を2つ目の引数として受け取ります。
Componentクラス
メソッド | 意味 |
createImage(int width,int height) |
幅width、高さheightのImageオブジェクトを返す |
Font getFont() | 現在のフォントを返す |
void repaint() |
JVMに対して、update()メソッドの呼び出しを要求する |
public void update(Graphics g) |
コンポーネントを背景色で塗りつぶしてpaint()メソッドを呼び出す |
Appletクラス
メソッド | 意味 |
void destroy() | アプレットを破棄する |
getCodeBase() | コードベースを返す |
void init() | アプレットを初期化する |
void start() | アプレットを起動する |
void stop() | アプレットを停止する |
ダブルバッファリング
update()メソッドの規定の実装では、ウィンドウ全体を背景色で塗りつぶして消去する。その後で、paint()メソッドを呼び出してアプレットの出力を表示して
います。しかし、これは見苦しい「ちらつき」の原因となります。ウィンドウがちらついて見えるのは、1色による全面の塗りつぶしと別の色にとる描画が頻繁に行
われるからである。その「ちらつきを」防ぐのがダブルバッファリングという手法である。
↓↓↓<もぐらたたきゲーム>↓↓↓
感想・反省
今回のレポートはゲームをつくるということで楽しく出来ました。ほとんどが
オリジナルのものではありませんが、こういう風につくるんだぁと新たな発見
がたくさんあったレポートでした。春休みになったらもっとゲームを作って
今年の琉大祭で自分の作ったゲームで出てみたいなと思いました。
参考文献
・第2版 独習Java ジョゼフ・オニール著
・たまじゃば http://www.horae.dti.ne.jp/~yoji/TamaJava/Chapter6/frame.html