4 『ポリモーフィズム』

4.1 ポリモーフィズムを理解するためのサンプルプログラム

4.1.1 Sample1クラス図

4.1.2 サンプルプログラム(1)

リスト 4.1.2.1 Example1.java
  1: /**
  2:  * オブプロ第10回例題 (ポリモーフィズム1)
  3:  * 
  4:  * @author macchan
  5:  * @version 1.0
  6:  */
  7: public class Example1 {
  8: 
  9: 	public static void main(String[] args) {
 10: 		Example1 example = new Example1();
 11: 		example.main();
 12: 	}
 13: 
 14: 	void main() {
 15: 		A a1 = new A();
 16: 		a1.display();
 17: 
 18: 		A a2 = new B();
 19: 		a2.display();
 20: 
 21: 		A a3 = new C();
 22: 		a3.display();
 23: 	}
 24: 
 25: 	class A {
 26: 		public void display() {
 27: 			System.out.println("A#display()");
 28: 		}
 29: 	}
 30: 
 31: 	class B extends A {
 32: 		public void display() {
 33: 			System.out.println("B#display()");
 34: 		}
 35: 	}
 36: 
 37: 	class C extends A {
 38: 		public void display() {
 39: 			System.out.println("C#display()");
 40: 		}
 41: 	}
 42: }
 43: 
 44: /**********************************************
 45: 問題:このプログラムをコンパイルして実行するとどうなるか
 46: 
 47: (A)
 48: A#display()
 49: A#display()
 50: A#display()
 51: 
 52: (B)
 53: A#display()
 54: B#display()
 55: C#display()
 56:   
 57: (C)
 58: コンパイルエラー
 59: 
 60: ***********************************************/

4.1.3 Sample2クラス図

4.1.4 サンプルプログラム(2)(配列)

リスト 4.1.4.1 Example2.java
  1: /**
  2:  * オブプロ第10回例題 (ポリモーフィズム2 配列)
  3:  * 
  4:  * @author macchan
  5:  * @version 1.0
  6:  */
  7: public class Example2 {
  8: 
  9: 	public static void main(String[] args) {
 10: 		Example2 example = new Example2();
 11: 		example.main();
 12: 	}
 13: 
 14: 	void main() {
 15: 		A[] aList = new A[5];
 16: 		aList[0] = new B();
 17: 		aList[1] = new A();
 18: 		aList[2] = new C();
 19: 		aList[3] = new B();
 20: 		aList[4] = new C();
 21: 
 22: 		for (int i = 0; i < aList.length; i++) {
 23: 			aList[i].display();
 24: 		}
 25: 	}
 26: 
 27: 	class A {
 28: 		public void display() {
 29: 			System.out.println("A#display()");
 30: 		}
 31: 	}
 32: 
 33: 	class B extends A {
 34: 		public void display() {
 35: 			System.out.println("B#display()");
 36: 		}
 37: 	}
 38: 
 39: 	class C extends A {
 40: 		public void display() {
 41: 			System.out.println("C#display()");
 42: 		}
 43: 	}
 44: }
 45: 
 46: /**********************************************
 47: 問題:このプログラムをコンパイルして実行するとどうなるか
 48: 
 49: (A)
 50: A#display()
 51: A#display()
 52: A#display()
 53: A#display()
 54: A#display()
 55: 
 56: (B)
 57: B#display()
 58: A#display()
 59: C#display()
 60: B#display()
 61: C#display()
 62: 
 63: (C)
 64: コンパイルエラー
 65: 
 66: ***********************************************/

4.1.5 サンプルプログラム(3)(エラー)

リスト 4.1.5.1 Example3.java.error
  1: /**
  2:  * オブプロ第10回例題 (ポリモーフィズム3)
  3:  * 
  4:  * @author macchan
  5:  * @version 1.0
  6:  */
  7: public class Example3 {
  8: 
  9: 	public static void main(String[] args) {
 10: 		Example3 example = new Example3();
 11: 		example.main();
 12: 	}
 13: 
 14: 	void main() {
 15: 		A a = new B();
 16: 		a.display2();
 17: 
 18: 		B b = new A();
 19: 		b.display();
 20: 	}
 21: 
 22: 	class A {
 23: 		public void display() {
 24: 			System.out.println("A#display()");
 25: 		}
 26: 	}
 27: 
 28: 	class B extends A {
 29: 		public void display() {
 30: 			System.out.println("B#display()");
 31: 		}
 32: 		public void display2() {
 33: 			System.out.println("B#display2()");
 34: 		}
 35: 	}
 36: 
 37: 	class C extends A {
 38: 		public void display() {
 39: 			System.out.println("C#display()");
 40: 		}
 41: 	}
 42: }
 43: 
 44: /**********************************************
 45: 問題:このプログラムをコンパイルして実行するとどうなるか
 46: 
 47: (A)
 48: B#display2()
 49: B#display()
 50: 
 51: (B)
 52: B#display2()
 53: A#display()
 54: 
 55: (C)
 56: コンパイルエラー
 57: 
 58: ***********************************************/

4.1.6 サンプルプログラム(4)(ダウンキャスト)

リスト 4.1.6.1 Example4.java
  1: /**
  2:  * オブプロ第10回例題 (ポリモーフィズム 4 ダウンキャスト)
  3:  * 
  4:  * @author macchan
  5:  * @version 1.0
  6:  */
  7: public class Example4 {
  8: 
  9: 	public static void main(String[] args) {
 10: 		Example4 example = new Example4();
 11: 		example.main();
 12: 	}
 13: 
 14: 	void main() {
 15: 		A a = new B();
 16: 		B b = (B) a;
 17: 
 18: 		a.display();
 19: 		b.display();
 20: 		b.display2();
 21: 	}
 22: 
 23: 	class A {
 24: 		public void display() {
 25: 			System.out.println("A#display()");
 26: 		}
 27: 	}
 28: 
 29: 	class B extends A {
 30: 		public void display() {
 31: 			System.out.println("B#display()");
 32: 		}
 33: 		public void display2() {
 34: 			System.out.println("B#display2()");
 35: 		}
 36: 	}
 37: 
 38: 	class C extends A {
 39: 		public void display() {
 40: 			System.out.println("C#display()");
 41: 		}
 42: 	}
 43: }
 44: 
 45: /**********************************************
 46: 問題:このプログラムをコンパイルして実行するとどうなるか
 47: 
 48: (A)
 49: A#display()
 50: B#display()
 51: B#display2()
 52: 
 53: (B)
 54: B#display()
 55: B#display()
 56: B#display2()
 57: 
 58: (C)
 59: コンパイルエラー
 60: 
 61: ***********************************************/

4.1.7 サンプルプログラム(5)(instanceof演算子)

リスト 4.1.7.1 Example5.java
  1: /**
  2:  * オブプロ第10回例題 (ポリモーフィズム5 instanceof演算子)
  3:  * 
  4:  * @author macchan
  5:  * @version 1.0
  6:  */
  7: public class Example5 {
  8: 
  9: 	public static void main(String[] args) {
 10: 		Example5 example = new Example5();
 11: 		example.main();
 12: 	}
 13: 
 14: 	void main() {
 15: 		A[] aList = new A[3];
 16: 		aList[0] = new B();
 17: 		aList[1] = new A();
 18: 		aList[2] = new C();
 19: 
 20: 		for (int i = 0; i < aList.length; i++) {
 21: 			System.out.println("aList[" + i + "] instanceof A = "
 22: 					+ (aList[i] instanceof A));
 23: 			System.out.println("aList[" + i + "] instanceof B = "
 24: 					+ (aList[i] instanceof B));
 25: 			System.out.println("aList[" + i + "] instanceof C = "
 26: 					+ (aList[i] instanceof C));
 27: 		}
 28: 
 29: 		for (int i = 0; i < aList.length; i++) {
 30: 			if (aList[i] instanceof B) {
 31: 				B b = (B) aList[i];
 32: 				b.display2();
 33: 			}
 34: 		}
 35: 	}
 36: 	class A {
 37: 		public void display() {
 38: 			System.out.println("A#display()");
 39: 		}
 40: 	}
 41: 
 42: 	class B extends A {
 43: 		public void display() {
 44: 			System.out.println("B#display()");
 45: 		}
 46: 		public void display2() {
 47: 			System.out.println("B#display2()");
 48: 		}
 49: 	}
 50: 
 51: 	class C extends A {
 52: 		public void display() {
 53: 			System.out.println("C#display()");
 54: 		}
 55: 	}
 56: 
 57: }
 58: 
 59: /******************************************************
 60:  問題:このプログラムをコンパイルして実行するとどのような出力になるか記述せよ.
 61:  instanceof 演算子はそのクラスのインスタンスかどうかを真偽値を求める
 62:  (結果はtrue もしくは false となる)
 63:  *******************************************************/
 64: 

4.2 シューティングゲーム

4.2.1 シューティングゲームクラス図,インスタンス図

4.2.2 シューティングゲーム(4)(ポリモーフィズム)

リスト 4.2.2.1 ShootingGame4.java
  1: import obpro.gui.BCanvas;
  2: import obpro.gui.BWindow;
  3: import obpro.sound.BSound;
  4: 
  5: /**
  6:  * シューティングゲームサンプル(その4 ポリモーフィズム) 
  7:  * 
  8:  * @author macchan
  9:  * @date 2005/06/22 オブプロ第10回
 10:  * @version 1.0
 11:  */
 12: public class ShootingGame4 {
 13: 
 14: 	public static void main(String[] args) {
 15: 		ShootingGame4 shootingGame = new ShootingGame4();
 16: 		shootingGame.main();
 17: 	}
 18: 
 19: 	//ウインドウ
 20: 	private BWindow window;
 21: 
 22: 	//アニメーションオブジェクトの集合
 23: 	private AnimationElement[] elements = new AnimationElement[1000];
 24: 	private int elementSize = 0;
 25: 
 26: 	//種類別アニメーションオブジェクト
 27: 	private Background background;
 28: 	private PlayerAircraft player;
 29: 	private EnemyAircraft[] enemies = new EnemyAircraft[100];
 30: 	private Bullet[] bullets = new Bullet[20];
 31: 
 32: 	//BGM
 33: 	private BSound bgm;
 34: 
 35: 	private void main() {
 36: 		openWindow();
 37: 		doAnimation();
 38: 	}
 39: 
 40: 	//ウインドウを開く
 41: 	private void openWindow() {
 42: 		window = new BWindow();
 43: 		window.setLocation(100, 100);
 44: 		window.setSize(640, 480);
 45: 		window.show();
 46: 	}
 47: 
 48: 	//アニメーションする
 49: 	void doAnimation() {
 50: 		BCanvas canvas = window.getCanvas();//キャンバスを取得する
 51: 		initializeElements();//オブジェクトを初期化する
 52: 		initializeSounds();//サウンドを初期化する
 53: 
 54: 		//アニメーションする
 55: 		bgm.loop();
 56: 		while (true) {
 57: 			//1コマの処理を行う
 58: 			processOneStepForGame(canvas);
 59: 			processOneStepForElements(canvas);
 60: 
 61: 			//図形を描く
 62: 			canvas.clear();
 63: 			draw(canvas);
 64: 			canvas.update();
 65: 
 66: 			//眠る
 67: 			canvas.sleep(0.01);
 68: 		}
 69: 	}
 70: 
 71: 	/**
 72: 	 * 各オブジェクトを初期化する
 73: 	 */
 74: 	private void initializeElements() {
 75: 		//背景
 76: 		background = new Background();
 77: 		addElement(background);
 78: 
 79: 		//プレイヤー
 80: 		player = new PlayerAircraft(50, 50, 100, 50);
 81: 		addElement(player);
 82: 
 83: 		//敵
 84: 		for (int i = 0; i < enemies.length; i++) {
 85: 			enemies[i] = new EnemyAircraft(-100, -100, 100, 50);
 86: 			addElement(enemies[i]);
 87: 		}
 88: 
 89: 		//弾
 90: 		for (int i = 0; i < bullets.length; i++) {
 91: 			bullets[i] = new Bullet(-1, -1, 20, 10);
 92: 			addElement(bullets[i]);
 93: 		}
 94: 	}
 95: 
 96: 	/**
 97: 	 * サウンドを初期化する
 98: 	 */
 99: 	private void initializeSounds() {
100: 		//BGM
101: 		bgm = new BSound("sound/bgm.mp3");
102: 
103: 		//効果音はメモリ上に読み込む
104: 		BSound.load("sound/explode_enemy.mp3");
105: 		BSound.load("sound/explode_player.mp3");
106: 		BSound.load("sound/fire.mp3");
107: 	}
108: 
109: 	/**
110: 	 * ゲーム全体としての1ステップの処理を行う
111: 	 */
112: 	private void processOneStepForGame(BCanvas canvas) {
113: 		// (キー入力によって)自機を操作する
114: 		if (canvas.isKeyPressing(37)) {// 左キー
115: 			player.move(-5, 0);
116: 		}
117: 		if (canvas.isKeyPressing(38)) {// 上キー
118: 			player.move(0, -5);
119: 		}
120: 		if (canvas.isKeyPressing(39)) {// 右キー
121: 			player.move(5, 0);
122: 		}
123: 		if (canvas.isKeyPressing(40)) {// 下キー
124: 			player.move(0, 5);
125: 		}
126: 
127: 		// キー入力によって弾を出す
128: 		if (canvas.isKeyDown() && player.isAlive()) {
129: 			int keyCode = canvas.getKeyCode();
130: 			if (keyCode == 70) {// fキー
131: 				// (有効でない弾を探して)弾を発射する
132: 				for (int i = 0; i < bullets.length; i++) {
133: 					if (bullets[i].isAlive() == false) {
134: 						bullets[i].fire(player);
135: 						break;
136: 					}
137: 				}
138: 			}
139: 		}
140: 
141: 		// 敵を出す
142: 		int rnd = (int) (Math.random() * 30);// 確率1/30コマの抽選
143: 		if (rnd == 0) {
144: 			int i = (int) (Math.random() * 100);// 敵の添字決め抽選
145: 			int y = (int) (Math.random() * canvas.getCanvasHeight());// y座標決め抽選
146: 			enemies[i].show(canvas.getCanvasWidth(), y);
147: 		}
148: 
149: 		// 自機と敵の当たり判定とあたった場合の処理を行う
150: 		for (int i = 0; i < enemies.length; i++) {
151: 			if (enemies[i].isAlive() && player.intersects(enemies[i])) {
152: 				player.explode();
153: 			}
154: 		}
155: 
156: 		// 弾と敵の当たり判定とあたった場合の処理を行う
157: 		for (int i = 0; i < enemies.length; i++) {
158: 			for (int j = 0; j < bullets.length; j++) {
159: 				if (bullets[j].isAlive() && enemies[i].isAlive()
160: 						&& enemies[i].intersects(bullets[j])) {
161: 					enemies[i].explode();
162: 					bullets[j].destroy();
163: 				}
164: 			}
165: 		}
166: 	}
167: 
168: 	/**
169: 	 * すべてのアニメーションオブジェクトにstep命令を送る
170: 	 */
171: 	private void processOneStepForElements(BCanvas canvas) {
172: 		for (int i = 0; i < elementSize; i++) {
173: 			elements[i].processOneStep(canvas);
174: 		}
175: 	}
176: 
177: 	/**
178: 	 * アニメーションオブジェクトを描画する
179: 	 */
180: 	private void draw(BCanvas canvas) {
181: 		for (int i = 0; i < elementSize; i++) {
182: 			elements[i].draw(canvas);
183: 		}
184: 	}
185: 
186: 	/**
187: 	 * アニメーションオブジェクトを追加する
188: 	 */
189: 	private void addElement(AnimationElement element) {
190: 		elements[elementSize] = element;
191: 		elementSize++;
192: 	}
193: }

4.2.3 アニメーションするオブジェクトすべてのスーパークラス

リスト 4.2.3.1 AnimationElement.java
  1: import obpro.gui.BCanvas;
  2: 
  3: /**
  4:  * アニメーションするオブジェクトすべてのスーパークラス
  5:  */
  6: public class AnimationElement {
  7: 
  8: 	/**
  9: 	 * 1ステップの処理をする
 10: 	 */
 11: 	public void processOneStep(BCanvas canvas) {
 12: 	}
 13: 
 14: 	/**
 15: 	 * 描画する
 16: 	 */
 17: 	public void draw(BCanvas canvas) {
 18: 	}
 19: 
 20: }

4.2.4 背景を表現するクラス

リスト 4.2.4.1 Background.java
  1: import obpro.gui.BCanvas;
  2: 
  3: /**
  4:  * 背景を表現するクラス
  5:  */
  6: public class Background extends AnimationElement {
  7: 
  8: 	private int x;
  9: 
 10: 	/**
 11: 	 * 1ステップの処理をする(オーバーライド)
 12: 	 */
 13: 	public void processOneStep(BCanvas canvas) {
 14: 		x--;
 15: 	}
 16: 
 17: 	/**
 18: 	 * 描画する(オーバーライド)
 19: 	 */
 20: 	public void draw(BCanvas canvas) {
 21: 		canvas.drawImage("img/background.jpg", x, 0);
 22: 	}
 23: 
 24: }

4.2.5 シューティングゲームのキャラクターを表現するクラス

リスト 4.2.5.1 ShootingCharacter.java
  1: /**
  2:  * ゲームのキャラクターを表現するクラス
  3:  */
  4: public class ShootingCharacter extends AnimationElement {
  5: 
  6: 	//属性
  7: 	private int x = 0;
  8: 	private int y = 0;
  9: 	private int width = 0;
 10: 	private int height = 0;
 11: 
 12: 	/**
 13: 	 * コンストラクタ
 14: 	 */
 15: 	public ShootingCharacter(int x, int y, int width, int height) {
 16: 		this.x = x;
 17: 		this.y = y;
 18: 		this.width = width;
 19: 		this.height = height;
 20: 	}
 21: 
 22: 	/**
 23: 	 * 高さを取得する
 24: 	 */
 25: 	public int getHeight() {
 26: 		return this.height;
 27: 	}
 28: 
 29: 	/**
 30: 	 * 幅を取得する
 31: 	 */
 32: 	public int getWidth() {
 33: 		return this.width;
 34: 	}
 35: 
 36: 	/**
 37: 	 * X座標を取得する
 38: 	 */
 39: 	public int getX() {
 40: 		return this.x;
 41: 	}
 42: 
 43: 	/**
 44: 	 * Y座標を取得する
 45: 	 */
 46: 	public int getY() {
 47: 		return this.y;
 48: 	}
 49: 
 50: 	/**
 51: 	 * 位置を再設定する
 52: 	 */
 53: 	public void setLocation(int newX, int newY) {
 54: 		x = newX;
 55: 		y = newY;
 56: 	}
 57: 
 58: 	/**
 59: 	 * 動かす
 60: 	 */
 61: 	public void move(int moveX, int moveY) {
 62: 		x = x + moveX;
 63: 		y = y + moveY;
 64: 	}
 65: 
 66: 	/**
 67: 	 * 他のキャラクターとの衝突判定をする
 68: 	 */
 69: 	public boolean intersects(ShootingCharacter another) {
 70: 		int self_leftX = this.getX();
 71: 		int self_rightX = this.getX() + this.getWidth();
 72: 		int another_leftX = another.getX();
 73: 		int another_rightX = another.getX() + another.getWidth();
 74: 		int self_topY = this.getY();
 75: 		int self_bottomY = this.getY() + this.getHeight();
 76: 		int another_topY = another.getY();
 77: 		int another_bottomY = another.getY() + another.getHeight();
 78: 
 79: 		return (another_leftX < self_rightX && another_rightX > self_leftX
 80: 				&& another_topY < self_bottomY && another_bottomY > self_topY);
 81: 	}
 82: }

4.2.6 自機を表現するクラス

リスト 4.2.6.1 PlayerAircraft.java
  1: import obpro.gui.BCanvas;
  2: import obpro.sound.BSound;
  3: 
  4: /**
  5:  * 自機を表現するクラス
  6:  */
  7: public class PlayerAircraft extends ShootingCharacter {
  8: 
  9: 	//定数
 10: 	private final int ALIVE = 1;
 11: 	private final int EXPLODING = 2;
 12: 	private final int DEAD = 3;
 13: 
 14: 	private final int EXPLODING_ANIMATION_SIZE = 11;
 15: 
 16: 	//状態
 17: 	private int liveState = ALIVE;
 18: 	private int explodingCount = 0;
 19: 
 20: 	/**
 21: 	 * コンストラクタ
 22: 	 */
 23: 	public PlayerAircraft(int x, int y, int width, int height) {
 24: 		super(x, y, width, height);
 25: 	}
 26: 
 27: 	/**
 28: 	 * 1ステップの処理をする(オーバーライド)
 29: 	 */
 30: 	public void processOneStep(BCanvas canvas) {
 31: 		if (liveState == EXPLODING) {
 32: 			processExplode();
 33: 		}
 34: 	}
 35: 
 36: 	/**
 37: 	 * 活きているかどうか調べる
 38: 	 */
 39: 	public boolean isAlive() {
 40: 		return liveState == ALIVE;
 41: 	}
 42: 
 43: 	/**
 44: 	 * 爆発の処理をする
 45: 	 */
 46: 	private void processExplode() {
 47: 		explodingCount++;
 48: 		if (explodingCount >= EXPLODING_ANIMATION_SIZE) {
 49: 			liveState = DEAD;
 50: 		}
 51: 	}
 52: 
 53: 	/**
 54: 	 * 爆発する(爆発状態に遷移する)
 55: 	 */
 56: 	public void explode() {
 57: 		if (liveState == ALIVE) {
 58: 			liveState = EXPLODING;
 59: 			explodingCount = 0;
 60: 			BSound.play("sound/explode_player.mp3");
 61: 		}
 62: 	}
 63: 
 64: 	/**
 65: 	 * 描画する(オーバーライド)
 66: 	 */
 67: 	public void draw(BCanvas canvas) {
 68: 		if (liveState == ALIVE) {
 69: 			drawAircraft(canvas);
 70: 		} else if (liveState == EXPLODING) {
 71: 			drawExplosion(canvas);
 72: 		}
 73: 	}
 74: 
 75: 	/**
 76: 	 * 飛行機を描画する
 77: 	 */
 78: 	private void drawAircraft(BCanvas canvas) {
 79: 		canvas.drawImage("img/player.png", getX(), getY(), getWidth(),
 80: 				getHeight());
 81: 	}
 82: 
 83: 	/**
 84: 	 * 爆発を描画する
 85: 	 */
 86: 	private void drawExplosion(BCanvas canvas) {
 87: 		canvas.drawImage("img/explode" + (explodingCount + 1) + ".gif",
 88: 				getX(), getY(), getWidth(), getHeight());
 89: 	}
 90: }

4.2.7 敵機を表現するクラス

リスト 4.2.7.1 EnemyAircraft.java
  1: import obpro.gui.BCanvas;
  2: import obpro.sound.BSound;
  3: 
  4: /**
  5:  * 敵機を表現するクラス
  6:  */
  7: public class EnemyAircraft extends ShootingCharacter {
  8: 
  9: 	// 定数
 10: 	private final int ALIVE = 1;
 11: 	private final int EXPLODING = 2;
 12: 	private final int DEAD = 3;
 13: 
 14: 	private final int EXPLODING_ANIMATION_SIZE = 11;
 15: 
 16: 	// 状態
 17: 	private int liveState = DEAD;
 18: 	private int explodingCount = 0;
 19: 
 20: 	/**
 21: 	 * コンストラクタ
 22: 	 */
 23: 	public EnemyAircraft(int x, int y, int width, int height) {
 24: 		super(x, y, width, height);
 25: 	}
 26: 
 27: 	/**
 28: 	 * 1ステップの処理をする(オーバーライド)
 29: 	 */
 30: 	public void processOneStep(BCanvas canvas) {
 31: 		if (liveState == ALIVE) {
 32: 			move(-5, 0);
 33: 		} else if (liveState == EXPLODING) {
 34: 			processExplode();
 35: 		}
 36: 	}
 37: 
 38: 	/**
 39: 	 * 活きているかどうか調べる
 40: 	 */
 41: 	public boolean isAlive() {
 42: 		return liveState == ALIVE;
 43: 	}
 44: 
 45: 	/**
 46: 	 * 出現させる
 47: 	 */
 48: 	public void show(int x, int y) {
 49: 		if (liveState == DEAD) {
 50: 			setLocation(x, y);
 51: 			liveState = ALIVE;
 52: 		}
 53: 	}
 54: 
 55: 	/**
 56: 	 * 爆発の処理をする
 57: 	 */
 58: 	private void processExplode() {
 59: 		explodingCount++;
 60: 		if (explodingCount >= EXPLODING_ANIMATION_SIZE) {
 61: 			liveState = DEAD;
 62: 		}
 63: 	}
 64: 
 65: 	/**
 66: 	 * 爆発する(爆発状態に遷移する)
 67: 	 */
 68: 	public void explode() {
 69: 		if (liveState == ALIVE) {
 70: 			liveState = EXPLODING;
 71: 			explodingCount = 0;
 72: 			BSound.play("sound/explode_enemy.mp3");
 73: 		}
 74: 	}
 75: 
 76: 	/**
 77: 	 * 描画する(オーバーライド)
 78: 	 */
 79: 	public void draw(BCanvas canvas) {
 80: 		if (liveState == ALIVE) {
 81: 			drawAircraft(canvas);
 82: 		} else if (liveState == EXPLODING) {
 83: 			drawExplosion(canvas);
 84: 		}
 85: 	}
 86: 
 87: 	/**
 88: 	 * 飛行機を描画する
 89: 	 */
 90: 	private void drawAircraft(BCanvas canvas) {
 91: 		canvas.drawImage("img/enemy.png", getX(), getY(), getWidth(),
 92: 				getHeight());
 93: 	}
 94: 
 95: 	/**
 96: 	 * 爆発を描画する
 97: 	 */
 98: 	private void drawExplosion(BCanvas canvas) {
 99: 		canvas.drawImage("img/explode" + (explodingCount + 1) + ".gif", getX(),
100: 				getY(), getWidth(), getHeight());
101: 	}
102: 
103: }

4.2.8 弾を表現するクラス

リスト 4.2.8.1 Bullet.java
  1: import java.awt.Color;
  2: 
  3: import obpro.gui.BCanvas;
  4: import obpro.sound.BSound;
  5: 
  6: /**
  7:  * 弾を表現するクラス
  8:  */
  9: public class Bullet extends ShootingCharacter {
 10: 
 11: 	//定数
 12: 	private final int ALIVE = 1;
 13: 	private final int DEAD = 2;
 14: 
 15: 	//状態
 16: 	private int liveState = DEAD;
 17: 
 18: 	//属性
 19: 	private Color color = new Color(0, 0, 255);
 20: 
 21: 	/**
 22: 	 * コンストラクタ
 23: 	 */
 24: 	public Bullet(int x, int y, int width, int height) {
 25: 		super(x, y, width, height);
 26: 	}
 27: 
 28: 	/**
 29: 	 * 1ステップの処理をする(オーバーライド)
 30: 	 */
 31: 	public void processOneStep(BCanvas canvas) {
 32: 		if (liveState == ALIVE) {
 33: 			//動かす
 34: 			move(15, 0);
 35: 
 36: 			//画面外に出た場合の処理
 37: 			if (getX() > canvas.getCanvasWidth()) {
 38: 				destroy();
 39: 			}
 40: 		}
 41: 	}
 42: 
 43: 	/**
 44: 	 * 弾を発射する(有効化する)
 45: 	 */
 46: 	public void fire(PlayerAircraft player) {
 47: 		if (liveState == DEAD) {
 48: 			int x = player.getX() + player.getWidth() / 2 - getWidth() / 2;
 49: 			int y = player.getY() + player.getHeight() / 2 - getHeight() / 2;
 50: 			setLocation(x, y);
 51: 			liveState = ALIVE;
 52: 			BSound.play("sound/fire.mp3");
 53: 		}
 54: 	}
 55: 
 56: 	/**
 57: 	 * 弾を消滅させる(無効化する)
 58: 	 */
 59: 	public void destroy() {
 60: 		if (liveState == ALIVE) {
 61: 			liveState = DEAD;
 62: 		}
 63: 	}
 64: 
 65: 	/**
 66: 	 * 弾が有効かどうか調べる
 67: 	 */
 68: 	public boolean isAlive() {
 69: 		return liveState == ALIVE;
 70: 	}
 71: 
 72: 	/**
 73: 	 * 描画する(オーバーライド)
 74: 	 */
 75: 	public void draw(BCanvas canvas) {
 76: 		if (liveState == ALIVE) {
 77: 			canvas.drawFillTriangle(color, getX(), getY(), getX() + getWidth(),
 78: 					getY(), getX(), getY() + getHeight());
 79: 			canvas.drawFillTriangle(color, getX(), getY() + getHeight(), getX()
 80: 					+ getWidth(), getY() + getHeight(), getX() + getWidth(),
 81: 					getY());
 82: 		}
 83: 	}
 84: 
 85: }