↓↓クリックして頂けると励みになります。
【30 | イベント処理】 << 【ホーム】 >> 【32 | ジャンプゲーム】
ゲームなどで使用する乱数や指数関数、対数関数、平方根、および三角関数といった基本的な数値処理はjava.lang.Mathクラス
の各メソッドを利用します。
Mathクラスのメソッドはstaticなメソッドですので、直接メソッドを使用します。
今回使用するメソッドを紹介します。
//ramdomは0.0〜1.0までの疑似乱数を発生。適当な値を掛けて使用します。 int a = (int)(Math.ramdom()*100); //doubleの平方根を返します。引数もdoubleです。 int a = (int)Math.sqrt(9.0); //doubleのsin値を返します。 //引数はdouble型のラジアンなので、度から求めるには「(2π/360)*度」=「度*π/180」 double a = Math.sin(90*Math.PI/180);
Visual Studio Codeで以下のサンプルプログラムを作成して下さい。
新規作成 【AwtMathTest1.java】
import java.awt.*; import java.awt.event.*; public class AwtMathTest1 extends Canvas implements MouseListener, Runnable { //キャンバスの幅と高さ private final int WIDTH = 500; private final int HEIGHT = 400; private Graphics offg; //ダブルバッファリング用 private Image offImage; private int x = 0; //矩形の座標 private int y = 100; private int w = 40; //矩形の幅と高さ private int h = 40; private int mx, my; //マウスの座標取得用 private int sec = 20; //制限時間は20秒 private int score = 0; //スコアは0から; /**コンストラクタ*/ public AwtMathTest1() { //super();が省略されている setSize(WIDTH, HEIGHT); setBackground(Color.black); //Canvasで発生したイベントを通知 addMouseListener(this); } /**メインの処理(スレッド処理)*/ public void run() { while (sec >= 0) { //secが0未満になるまで繰り返し try { Thread.sleep(1000); //1000ミリ秒(1秒)スリープ } catch (InterruptedException ex) { System.err.println(ex); } repaint(); sec--; //1秒減らす } } /**再描写が必要な場合の処理*/ public void update(Graphics g) { //全画面消去をオフスクリーン・バッファへの描き込み offg.setColor(Color.black); offg.fillRect(0, 0, WIDTH, HEIGHT); //矩形の座標を乱数で決定 x = (int)(Math.random()*(WIDTH-w)); //キャンバス幅 - 矩形幅の範囲 y = (int)(Math.random()*(HEIGHT-h)); //キャンバス高さ - 矩形高さの範囲 //オフスクリーン・バッファへの矩形描き込み offg.setColor(Color.red); offg.fillRect(x, y, w, h); //残り時間を描画 offg.setColor(Color.yellow); offg.drawString("Time: " + sec, 10, 10); //スコアを描画 offg.setColor(Color.yellow); offg.drawString("Score: " + score, 300, 10); //オフスクリーン・バッファに描かれたものを画面に表示 g.drawImage(offImage, 0, 0, this); } /**キャンバスで描画の必要があるときに呼ばれるメソッド*/ public void paint(Graphics g) { //オフスクリーン・バッファの領域がない場合は作成 if (offg == null) { //キャンバスと同じ大きさの仮想画面を生成 offImage = createImage(getSize().width, getSize().height); //offImageから仮想画面描画用のグラフィックスコンテキストを取得 offg = offImage.getGraphics(); } //矩形と文字列の描画 g.setColor(Color.red); g.fillRect(x, y, w, h); g.setColor(Color.yellow); g.drawString("Time: " + sec, 10, 10); g.setColor(Color.yellow); g.drawString("Score: " + score, 300, 10); } /**マウスがクリックされたときの処理*/ public void mouseClicked(MouseEvent evt) { mx = evt.getX(); my = evt.getY(); hantei(); //判定メソッドへ } /**その他のマウス処理*/ public void mouseEntered(MouseEvent evt) { } public void mouseExited(MouseEvent evt) { } public void mousePressed(MouseEvent evt) { } public void mouseReleased(MouseEvent evt) { } public void hantei() { //クリックした座標が矩形の中だった場合当たり if (mx >= x && mx <= x+w && my >= y && my <= y+h) { score++; } } /**main()*/ public static void main(String[] args) { AwtMathTest1 canvas = new AwtMathTest1(); MyFrame frame = new MyFrame("MathTest1"); frame.add(canvas); frame.pack(); frame.setVisible(true); //スレッドを生成して開始(runメソッドの呼び出し) new Thread(canvas).start(); } }
これまでのプログラムでオブジェクトのメソッドを利用する際は、生成したインスタンスに対しての参照先を変数などで指定して「変数.メソッド()
」のように呼び出していました。
このようなメソッドを「インスタンス・メソッド(instance method)」あるいは「非static」メソッドと呼ばれます。
これに対してstaticなメソッドは「クラス・メソッド(class method)」とも呼ばれ、特定のオブジェクトへの参照無しで呼び出すことが出来ますから、一般にインスタンス生成に伴う余分なオーバーヘッドなどを避けることが出来ます。
JavaのプログラムはJVMからmain()
を呼び出すことで始まりますが、最初の時点ではオブジェクトは1つも生成されていないので、main()
はstaticとなっています。
これまでクラスを継承したプログラムを作成する際、特に子クラス(サブクラス)のコンストラクタでは何も指定していませんでしたが、正確に記述するならばサブクラスのコンストラクタの始めで「super();
」が実行されています。
つまり「親クラス(スーパークラス)のコンストラクタを引数無しで呼び出し」しているわけです(superはコンストラクタの先頭でのみ使用できます)。
このことは逆に言うとスーパークラスで引数無しのコンストラクタがない場合は、今までのようにコンストラクタで何も記述しないとコンパイル時にエラーとなることを示しています。
またクラスでコンストラクタの定義をしない場合は、「引数無しのコンストラクタが定義される」という規則になっています。
ではサンプルプログラムを実行してみましょう。
前のセッションで作成した「MyFrame.java」を利用していますのでクローズボタンを使って終了できます。
乱数を用いて、逃げる四角を時間内にマウスでクリックし、点数を表示します。
~/Desktop/Programming/JP $ javac AwtMathTest1.java ~/Desktop/Programming/JP $ java AwtMathTest1
Visual Code Studioで以下のサンプルプログラム「AwtMathTest2.java」を作成します。
新規作成 【AwtMathTest2.java】
/** *sin関数を利用した動き */ import java.awt.*; public class AwtMathTest2 extends Canvas implements Runnable { //キャンバスの幅と高さ private final int WIDTH = 600; private final int HEIGHT = 350; private Graphics offg; //ダブルバッファリング用 private Image offImage; private int x = 0; //矩形の座標 private int y = 300; private int w = 40; //矩形の幅と高さ private int h = 40; private int step = 20; //矩形のx座標移動距離 private int angle = 0; //sin関数で利用する角度 /**コンストラクタ*/ public AwtMathTest2() { setSize(WIDTH, HEIGHT); setBackground(Color.black); } /**メインの処理(スレッド処理)*/ public void run() { while (true) { //永久に繰り返し try { Thread.sleep(100); //100ミリ秒(0.1秒)スリープ } catch (InterruptedException ex) { System.err.println(ex); } repaint(); } } /**再描写が必要な場合の処理*/ public void update(Graphics g) { //全画面消去をオフスクリーン・バッファへの描き込み offg.setColor(Color.black); offg.fillRect(0, 0, WIDTH, HEIGHT); //矩形のx座標は端まで行くと方向転換 if (x >= WIDTH-w) { step = -20; } else if (x <=0) { step = 20; } x += step; //矩形のy座標をsin関数で決定 y = 300-(int)(Math.sin(angle*Math.PI/180)*100); //値を表示 System.out.println("angle=" + angle + " x=" + x + " y=" + y); angle += 15; if (angle >= 180) { angle = 0; } //オフスクリーン・バッファへの矩形描き込み offg.setColor(Color.red); offg.fillRect(x, y, w, h); //オフスクリーン・バッファに描かれたものを画面に表示 g.drawImage(offImage, 0, 0, this); } /**キャンバスで描画の必要があるときに呼ばれるメソッド*/ public void paint(Graphics g) { //オフスクリーン・バッファの領域がない場合は作成 if (offg == null) { offImage = createImage(getSize().width, getSize().height); offg = offImage.getGraphics(); } //矩形の描画 g.setColor(Color.red); g.fillRect(x, y, w, h); } /**main()*/ public static void main(String[] args) { AwtMathTest2 canvas = new AwtMathTest2(); MyFrame frame = new MyFrame("AwtMathTest2"); frame.add(canvas); frame.pack(); frame.setVisible(true); new Thread(canvas).start(); } }
実行結果を確認してみましょう。
前のセッションで作成した「MyFrame.java」を利用していますのでクローズボタンを使って終了できます。
sin関数を用いて、矩形がsin波上を移動します。
コマンドプロンプト上に矩形の位置をリアルタイムで表示します。
~/Desktop/Programming/JP $ javac AwtMathTest2.java ~/Desktop/Programming/JP $ java AwtMathTest2 angle=0 x=20 y=300 angle=15 x=40 y=275 angle=30 x=60 y=251 angle=45 x=80 y=230 angle=60 x=100 y=214 angle=75 x=120 y=204 angle=90 x=140 y=200 angle=105 x=160 y=204 angle=120 x=180 y=214 angle=135 x=200 y=230 angle=150 x=220 y=251 angle=165 x=240 y=275 angle=0 x=260 y=300 angle=15 x=280 y=275 angle=30 x=300 y=251 angle=45 x=320 y=230 angle=60 x=340 y=214 angle=75 x=360 y=204 ・ ・ ・
【30 | イベント処理】 << 【ホーム】 >> 【32 | ジャンプゲーム】
↓↓クリックして頂けると励みになります。