Javaゲームプログラミング

シューティングゲームを作ってみようの連載5回目です。弾が発射できるように改造します。



弾の発射

このページには、以下のサンプルを掲載しています。 下の項目をクリックをすると各サンプルにジャンプします。 ※2週間以内の新着記事はNewアイコン、更新記事はUpアイコンが表示されます。

前回は、弾の表示をしたので今回は、弾が発射出来るようにしたいと思います。
■弾クラス (Bullet.java)
  1. import java.awt.Color;
  2. import java.awt.Graphics2D;
  3. import java.awt.Rectangle;
  4. import java.awt.geom.Ellipse2D;
  5. public class Bullet {
  6.   private Ellipse2D bullet;
  7.   private Rectangle r = new Rectangle(8,-15,10,15);
  8.   public Bullet() {
  9.     bullet = new Ellipse2D.Double();  
  10.     bullet.setFrame(r);
  11.   }
  12.   public Bullet(int x, int y ) {
  13.     this();
  14.     r.x += x;
  15.     r.y += y;
  16.     bullet.setFrame(r);
  17.   }
  18.   public void draw(Graphics2D g2) {
  19.     g2.setColor(Color.YELLOW);
  20.     g2.fill(bullet);
  21.     g2.setColor(Color.BLACK);
  22.     g2.draw(bullet);
  23.   }
  24.   public void setBulletY(int y) {
  25.     r.y = y;
  26.     bullet.setFrame(r);
  27.   }
  28.   public int getBulletY(){
  29.     return r.y;
  30.   }
  31. }
赤字の部分は、前回から追加となった部分です。メソッドを2つ追加しています。 弾を移動させるために弾の位置情報の取得メソッド(getBulletYメソッド)と弾の位置を設定出来るメソッド(setBulletYメソッド)を追加しました。 弾オブジェクトの移動は、縦方向のみなので表示位置情報の取得と設定は、縦方向(XY座標のY軸方向)のみで行っています。

■自機クラス(Gun.java)
自機クラスは、前回と同じです。変更はありません。
 →前回分を見たい方はここをクリック

■アプレットクラス 自機オブジェクト弾の表示機能追加改造 (ShootGame.java)
  1. import java.awt.Graphics;
  2. import java.awt.Graphics2D;
  3. import java.awt.event.KeyEvent;
  4. import java.awt.event.KeyListener;
  5. import javax.swing.JApplet;
  6. public class ShootGame extends JApplet implements KeyListener {
  7.   private static final long serialVersionUID = 1L;
  8.   public Gun gun = new Gun(87, 180);
  9.   public Bullet bullet;
  10.   public static Thread t;
  11.   
  12.   public void init() {
  13.     addKeyListener(this);
  14.   }
  15.   public void start(){
  16.     t = new Thread(){
  17.       public void run(){
  18.         Thread ct = Thread.currentThread();
  19.         while( t == ct ){
  20.           try {
  21.             Thread.sleep(10);
  22.             repaint();
  23.           } catch(Exception e) {
  24.             e.printStackTrace();
  25.           }
  26.       
  27.         }
  28.       }
  29.     };
  30.     t.start();
  31.   }
  32.   public void paint(Graphics g) {
  33.     Graphics2D g2 = (Graphics2D)g;
  34.     g2.clearRect(0,0,getWidth(), getHeight()); 
  35.     gun.draw(g2);
  36.     if ( bullet != null ) {
  37.       if ( bullet.getBulletY() > 0 ) {
  38.         bullet.draw(g2);
  39.         bullet.setBulletY(bullet.getBulletY() - 5 );
  40.       } else {
  41.         bullet = null;
  42.       }
  43.     }
  44.   }
  45.   public void update(Graphics g){
  46.     paint(g);
  47.   }
  48.   public void destroy() {
  49.     t = null;
  50.   }
  51.   public void keyPressed(KeyEvent e) {
  52.     if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
  53.       gun.moveRightGun();
  54.     } else if (e.getKeyCode() == KeyEvent.VK_LEFT ) {
  55.       gun.moveLeftGun();
  56.     } else if (e.getKeyCode() == KeyEvent.VK_SPACE ) {
  57.       bullet = bullet == null ? new Bullet(gun.getGun().x, gun.getGun().y) : bullet;
  58.     }
  59.     repaint();
  60.   }
  61.   public void keyReleased(KeyEvent e) {
  62.   }
  63.   public void keyTyped(KeyEvent e) {
  64.   }
  65. }
赤字部分が前回から追加、修正された部分になります。弾オブジェクトは、ユーザがスペースキー押した瞬間に生成され表示されます。 しかしこのままでは、表示されただけで弾は移動しません。スペースキー押されたら自機から弾を画面上部に向かって移動させたいわけですが、 これを実現するためにこのサンプルでは、スレッドを使っています。スレッドは、平行してなんらかの処理を実行したいときなどに使います。 ここでは、アップレット開始時にスレッドを生成して10ミリ秒間隔で画面の再描画を行っています。(20行目〜41行目)そして、描画処理の中で 弾オブジェクトの移動を行っています。(50行目)
サンプルでは、スレッドによって下の順番で描画処理が10ミリ秒ごとに行われています。
 1. 画面のクリア(45行目)
 2. 自機の描画(46行目)
 3. 弾オブジェクトが生成されている場合
  3-1. 弾オブジェクトが画面の描画範囲内にある場合
   3-1-1. 弾オブジェクトの描画(49行目)
   3-1-2. 弾オブジェクトを移動(50行目)
  3-2. 弾オブジェクトが画面の描画範囲外の場合
   3-2-1. 弾オブジェクトが生成されていない状態にする(52行目)
 4. 描画処理終了

61〜63行目のdestroyメソッドは、アプレットを終了するときに呼び出されるアプレットクラスのメソッドです。
ここでは、アプレット開始時に生成したスレッドオブジェクトを破棄しています。

下記のボタンを押すと前述プログラムを実行してみることが出来ます。
※実行は、別ウィンドウで開きます。実行には時間がかかることがありますのでご注意ください。




最終更新日:2019/02/13

2015-03-01からの訪問者数
  5090 人