- 学籍番号:055704J
- 氏 名 :伊志嶺拓人
課題
-
Java Applet/AWTについて学び、Java Appletのオリジナルプログロムを作成し解説せよ。
●プログラム
import java.applet.Applet;
import java.awt.*;
import java.util.*;
import java.awt.event.*;
public class FinalBlock extends java.applet.Applet
implements Runnable, MouseMotionListener,MouseListener{
int speed=40;//表示時間
int num=3;//ボールの残数
int bx,by;//ボールの位置(x座標、y座標)
int rx=60,ry=250;//ラケットの位置
int ballWidth=8, ballHeight=8;//ボールの絵の幅、高さ
int racketWidth=19,racketHeight=3;//ラケットの絵の幅、高さ
int margin=6;//端まで行かないように余裕を取る
int score;//スコア
int playWidth = 250 , playHeight = 270; // ボールが跳ねる範囲の幅、高さ
int meterWidth = 60 , meterHeight =250; //その他のパラメーターの幅、高さ
int width = 330, height = 290; //ウィンドウ全体の幅、高さ
int block[]=new int[600];//ブロックがあるかどうかの配列
int x[]= new int[600];//ブロックのx座標
int y[]= new int[600];//ブロックのy座標
int blockWidth=10,blockHeight=2;//ブロックの幅、高さ
boolean loop=true;//繰り返すための変数
Thread kicker=null;//アニメーションのためのスレッド変数
Dimension d;//表示領域
Image offs;//オフスクリーン
Graphics grf;//
public void init(){
int i,j; //カウンタ
int k; //ブロック番号
int yy; //段ごとのy座標
/*ブロックの位置(x、y座標)の設定*/
k=0;
for(i=0; i<30; i++){
yy=i*(blockHeight+1)+margin*3;//i段目のブロックのy座標の計算
for(j=0; j<20; j++){
x[k]=j*(blockWidth+1)+margin+2;//i段目のブロックのx座標
y[k]=yy;//i段目のブロックのy座標
block[k]=1;//ブロックがある
k=k+1;
}
}
/*オフスクリーンの設定*/
offs = createImage( width, height);
grf=offs.getGraphics();
/*ボールの初期値の設定*/
bx=margin+(int)(Math.random()*(float)(width/2-(margin*2+ballWidth+1)));
by=130;
/*マウスモーション・リスナーとして自分自身を登録*/
addMouseMotionListener(this);
/*マウス・リスナーとして自分自身を登録*/
addMouseListener(this);
}
public void paint(Graphics g){
update(g);
}
public void update(Graphics g){
int i;//カウンタ
/* バックをブルーで塗る */
grf.setColor(Color.blue); //色を決める
grf.fillRect(0,0,width, height); //範囲を決めて線を引く
grf.setColor(Color.black);
grf.fillRect(margin,margin, playWidth-margin*2, playHeight);
grf.setColor(Color.black);
grf.fillRect(margin+playWidth,margin, meterWidth , meterHeight);
/*ラケットを描く*/
grf.setColor(Color.blue);
grf.fillRect(rx,ry,racketWidth,racketHeight);
/*ブロックを描く*/
for(i=0; i<600; i++){
grf.setColor(Color.blue);
if(block[i] == 1){
/*ブロックがあればブロックを描く*/
grf.fillRect(x[i],y[i],blockWidth,blockHeight);
}
}
/*ボールを描く*/
if(score<3000){
grf.setColor(Color.blue);
grf.fillOval(bx,by,ballWidth,ballHeight);
grf.setColor(Color.black);
grf.drawOval(bx,by,ballWidth,ballHeight);
}
if(3000<=score & score<5000){
grf.setColor(Color.orange);
grf.fillOval(bx,by,ballWidth,ballHeight);
grf.setColor(Color.black);
grf.drawOval(bx,by,ballWidth,ballHeight);
}
if(5000<=score & score <=6000){
grf.setColor(Color.red);
grf.fillOval(bx,by,ballWidth,ballHeight);
grf.setColor(Color.black);
grf.drawOval(bx,by,ballWidth,ballHeight);
}
/* 点数、残りボール数の表示 */
grf.setColor(Color.blue);
grf.drawString("Score ", 260, 21); //Scoreの文字の表示
grf.drawString(" "+score, 265, 38); //スコアの表示
grf.drawRect( 261, 25, 50, 15);
grf.drawString("Boals ", 260, 61); //Boalsの文字の表示
grf.drawString(" "+num, 260, 78); //残りボール数の表示
if(num<0){
grf.setColor(Color.red);
grf.drawString("GAME OVER!",85,168);
}
if(score==600){
grf.setColor(Color.red);
grf.drawString("PERFECT!",85,168);
}
if(!loop ){
/*RESTARTボタンの描画*/
grf.setColor(Color.black);
grf.fillRect(88,120,65,25);
grf.setColor(Color.red);
grf.drawString("RESTAT!",95,138);
grf.setColor(Color.red);
grf.drawLine(88,120,153,120);
grf.drawLine(88,120,88,145);
grf.setColor(Color.red);
grf.drawLine(88,145,153,145);
grf.drawLine(153,145,153,120);
}
/*オフスクリーンのイメージを一挙に実際の表示領域に描く*/
g.drawImage(offs,0,0,this);
}
public void mouseDragged(MouseEvent e){
/*マウスが押されてドラッグされた*/
}
public void mouseMoved(MouseEvent e){
/*マウスが移動した*/
rx=e.getX();
/*ラケットがコートを出ないための処理*/
if(rx< margin){
rx=margin;
}
if(rx+racketWidth> playWidth -margin){
rx= playWidth -margin-racketWidth;
}
repaint();
}
public void start(){
if(kicker==null){
/*スレッドを実行される*/
kicker=new Thread(this);
kicker.start();
}
}
public void stop(){
/*スレッドを止める*/
kicker=null;
}
public void run(){
int dx=4,dy=4;//ボールの進む量
int i;//カウンタ
/*実行中のスレッドをチェック*/
Thread thisThread =Thread.currentThread();
/*繰り返し*/
while(loop & kicker==thisThread){
/*ラケットが当たったをきの処理*/
if(by+ballHeight>=ry & by +ballHeight<=ry+racketHeight &
bx+ballWidth>=rx & bx <=rx+racketWidth){
/*ラケットに当たったら上へ返す*/
dy=-4;
if(bx < rx || bx+ballWidth>rx+racketWidth){
/*ラケットの端に当たったとき*/
if(dx==0){
/*垂直にきたボール*/
if(bx< rx){
/*左端に当たったら左斜めに返す*/
dx=-4;
}
if(bx+ballWidth>rx+racketWidth){
/*右端に当たったら右斜め上に返す*/
dx=+4;
}
}else{
/*斜めにきたボールは垂直に返す*/
dx=2;
}
}
}
/*左端、右端、上端に来たときの処理*/
if(bx< 0+margin){
/*左端にきたら反転*/
dx=4;
}
if(bx+ballWidth >playWidth-margin){
/*右端に来たら反転*/
dx=-4;
}
if(by < 0+margin){
/*上端に来たら反転*/
dy=4;
}
/*ラケットの下に行った時の処理*/
if(by+ballHeight>playHeight-margin){
/*下端に来たらボールを初期値へ*/
bx=margin+(int)(Math.random()*(float)(playWidth/2-(margin*2+ballWidth+1)));
by=130;
num=num-1;
}
/*ブロックに当たったときの処理*/
for(i=0; i< 600; i++){
if(block[i]==1){
if(by+ballHeight >= y[i] & by <= y[i]+blockHeight &bx+ballWidth >= x[i] & bx <= x[i]+blockWidth){
/*ブロックに当たったら反転*/
dy=-dy;
score=score+10;
/*スピードアップさせる*/
if(1000 <=score & score < 2000)speed=40;
if(2000 <=score & score < 4000)speed=30;
if(4000 <=score & score < 5000)speed=20;
if(5000 <=score )speed=10;
block[i]=0;
}
}
}
}
/*ゲーム終了判定*/
if(num< 0 || score == 6000){
loop=false;
}
bx=bx+dx;
by=by+dy;
repaint();
try{
Thread.sleep(speed);
}catch(InterruptedException e){}
}
}
public void mousePressed(MouseEvent e){
int ix,iy;
/*マウスが押された座標を得る*/
ix=e.getX();
iy=e.getY();
if(ix>88 & ix< 153 & iy>120 & iy<145){
/*マウスの座標(ix,iy)がRESTARTボタン内だったらゲーム再スタート*/
stop();
gameStart();
repaint();
}
}
public void mouseReleased(MouseEvent e){
/*マウスが離れたら*/
}
public void mouseClicked(MouseEvent e){
/*マウスボタンがクリックされた*/
}
public void mouseEntered(MouseEvent e){
/*マウスが入ってきた*/
}
public void mouseExited(MouseEvent e){
/*マウスが出て行った*/
}
public void gameStart(){
int i;
/*変数初期化*/
num=3;
score=0;
speed=40;
for(i=0; i<600; i++){
block[i]=1;
}
bx=margin+(int)(Math.random()*(float)(width/2-(margin*2+ballWidth+1)));
by=130;
loop=true;
start();
}
}
<実行結果>はこちらです。
考察
/*ボールを描く*/
if(score<3000){
grf.setColor(Color.blue);
grf.fillOval(bx,by,ballWidth,ballHeight);
grf.setColor(Color.black);
grf.drawOval(bx,by,ballWidth,ballHeight);
}
if(3000<=score &score<5000){
grf.setColor(Color.orange);
grf.fillOval(bx,by,ballWidth,ballHeight);
grf.setColor(Color.black);
grf.drawOval(bx,by,ballWidth,ballHeight);
}
if(5000<=score &score <=6000){
grf.setColor(Color.red);
grf.fillOval(bx,by,ballWidth,ballHeight);
grf.setColor(Color.black);
grf.drawOval(bx,by,ballWidth,ballHeight);
}
ボールの大きさ、形、色を指定しています。
grf.setColor(Color.色); 色の部分に色を指定する事で好きな色に出来ます。
grf.fillOval(bx,by,ballWidth,ballHeight); 色塗られた円を描くメソッドです。
ballWith, ballHeightは最初に定義されている様に8です。
grf.drawOval(bx,by,ballWidth,ballHeight); 円を描くメソッドです。背景も黒に指定しているので余り意味はないですな。
/* バックをブルーで塗る */
grf.setColor(Color.blue); //色を決める
grf.fillRect(0,0,width, height); //範囲を決めて線を引く
grf.setColor(Color.black);
grf.fillRect(margin,margin, playWidth-margin*2, playHeight);
grf.setColor(Color.black);
grf.fillRect(margin+playWidth,margin, meterWidth , meterHeight);
背景を作っています。
grf.fillRect(0,0,width, height); で青の四角形を画面いっぱいに表示しています。
grf.fillRect(margin,margin, playWidth-margin*2, playHeight);
grf.fillRect(margin+playWidth,margin, meterWidth , meterHeight);
青の四角形の上に黒の四角形を二つ表示しています。
/*ブロックに当たったときの処理*/
for(i=0; i< 600; i++){
if(block[i]==1){
if(by+ballHeight >= y[i] &by <= y[i]+blockHeightbx+ballWidth >= x[i] &bx <= x[i]+blockWidth){
/*ブロックに当たったら反転*/
dy=-dy;
score=score+10;
/*スピードアップさせる*/
if(1000 <=score &score < 2000)speed=40;
if(2000 <=score &score < 4000)speed=30;
if(4000 <=score &score < 5000)speed=20;
if(5000 <=score )speed=10;
block[i]=0;
ブロックとボールが重なったときの処理です。
dy=-dyでy軸方向の速度を反転させています。なのでボールのx軸方向の速度は変わりません。
score=score+10でスコアに10点プラスしています。
スコアに応じてボールのスピードを変化させています。
block[i]=0;でブロックを消します。
/*ゲーム終了判定*/
if(num< 0 || score == 6000){
loop=false;
}
numが0以下またはscoreが6000点という事は、クリアしたかゲームオーバしたときです。
なのでゲームを終了させます。
loop を falseにすることで
if(!loop ){
/*RESTARTボタンの描画*/
grf.setColor(Color.black);
grf.fillRect(88,120,65,25);
grf.setColor(Color.red);
grf.drawString("RESTAT!",95,138);
grf.setColor(Color.red);
grf.drawLine(88,120,153,120);
grf.drawLine(88,120,88,145);
grf.setColor(Color.red);
grf.drawLine(88,145,153,145);
grf.drawLine(153,145,153,120);
}
を実行してRESTARTボタンを表示させます。
public void mousePressed(MouseEvent e){
int ix,iy;
/*マウスが押された座標を得る*/
ix=e.getX();
iy=e.getY();
if(ix>88 &ix< 153 &iy>120 &iy<145){
/*マウスの座標(ix,iy)がRESTARTボタン内だったら
ゲーム再スタート*/
stop();
gameStart();
repaint();
}
}
RESTARTボタンを押したかどうか判断します。
ボタンが表示されている座標と同じ範囲の座標を押したか判断します。
押した場合は、
stop();
gameStart();
repaint();
を呼び出します。
public void gameStart(){
int i;
/*変数初期化*/
num=3;
score=0;
speed=40;
for(i=0; i<600; i++){
block[i]=1;
}
bx=margin+(int)(Math.random()*(float)(width/2-(margin*2+ballWidth+1)));
by=130;
loop=true;
start();
}
gameStart()では初期化を行います。
num=3 でボールの数を3に戻します。
socre=0 でスコアを0に戻します。
spped=40で最初のスピードに戻します。
ブロックを全部描画してloopをtrueに戻します。
●メソッドの説明
Runnableメソッド: このメソッドがメインになるわけですが、
ここでこれから使用する変数の宣言をしています。
initメソッド: イメージファイルのラケットやボールを読み込みます、
そして30行20列、600個のブロックの位置(x、y座標)を設定します。
この、ブロックの状態(1=ある、0=なし)の配列block[]はすべて、1にしておきます。
ボールの初期設定はbx,byにそれぞれ代入して設定します。
updateメソッド: ここではblock[]が1のブロックだけ描画するようにします、
背景やフォント、ボタン、画面表示に必要な物の設定も行い
ます。
mouseMoveメソッド: ラケットの移動を設定します。
このメソッドは、mouseDownメソッドと同じように、イベントを取り扱うメソッドです。
mouseMoveは、マウスがアプレット範囲内で動かされると呼ばれるメソッドで、x , yには
そのときの x 座標、y座標の値が入ります。ここで、マウスの x 座標をラケットの x 座標としています。
スクリーンをはみ出さないようにラケットの x 座標を調整してます。
startメソッド: スレッドを実行させます。
stopメソッド: スレッドを停止させます。
mouseDownメソッド: mouseMoveメソッドと同じようにイベントを取り扱うメソッドです。
RESTARTボタンを押すとゲームが再スタートされるように設定しています。
gameStartメソッド: ゲームを再スタートさせるメソッドです。
残りボールの数、点数、ボールスピード、ブロックを元の状態に戻します。
ボールも元の位置に戻します。
反省・感想
ついに最後のレポートが終わりました。ものすごい達成感です。
時間があればもっと工夫したかったけど、自分的には上出来です。
一年間ありがとうございました〜おつかれさまです
<参考文献>
独習JAVA ジョセフ・オニール 著 翔泳社
java学習用ページ「たまじゃば」
http://www.horae.dti.ne.jp/~yoji/
浅煎り珈琲Java アプリケーション入門
http://msugai.fc2web.com/java/index.html