6 『フレームワークとコンポーネント』
6.1 CUIアプリケーションフレームワーク
6.1.1 2つのアプリケーションの抽象化
6.1.1.1 成績管理アプリケーション
6.1.1.2 作文さんアプリケーション
6.1.1.3 抽象CUIアプリケーション
6.1.2 CUIアプリケーションフレームワークの構築
6.1.2.1 CUIアプリケーションフレームワーククラス図
6.1.2.2 CUIアプリケーション実行エンジン
リスト 6.1.2.2.1 CUIApplicationEngine.java
1: import obpro.cui.Input;
2:
3:
7:
8:
15: public class CUIApplicationEngine {
16:
17: public static void main(String[] args) {
18: if (args.length != 1) {
19: System.out.println("起動には引数が必要です");
20: return;
21: }
22:
23:
24: AbstractCUIApplication application = (AbstractCUIApplication) BReflection
25: .createInstanceByName(args[0]);
26: CUIApplicationEngine engine = new CUIApplicationEngine(application);
27: engine.run();
28: }
29:
30:
31: private AbstractCUIApplication application;
32:
33:
36: private CUIApplicationEngine(AbstractCUIApplication application) {
37: this.application = application;
38: }
39:
40:
41: private void run() {
42:
43: application.showTitle();
44:
45:
46: application.initializeData();
47: executeProcessLoop();
48:
49:
50: application.showEndTitle();
51: }
52:
53:
54: private void executeProcessLoop() {
55:
56: while (true) {
57:
58: String command = getCommand();
59:
60:
61: if (command.equals(application.getQuitCommand())) {
62: break;
63: } else {
64: application.executeCommand(command);
65: }
66: }
67: }
68:
69:
70: private String getCommand() {
71:
72: application.showCommandMenu();
73:
74:
75: String command = Input.getString();
76: return command;
77: }
78:
79: }
6.1.2.3 抽象CUIアプリケーションクラス(スーパークラス)
リスト 6.1.2.3.1 AbstractCUIApplication.java
1:
5:
6:
13: public class AbstractCUIApplication {
14:
15:
18: public void showTitle() {
19: }
20:
21:
24: public void showEndTitle() {
25: }
26:
27:
30: public void initializeData() {
31: }
32:
33:
36: public void showCommandMenu() {
37: }
38:
39:
42: public String getQuitCommand() {
43: return "q";
44: }
45:
46:
49: public void executeCommand(String command) {
50: }
51:
52: }
6.1.3 適用例(1) 成績管理アプリケーション
6.1.3.1 成績管理アプリケーション(抽象CUIアプリケーションクラスを継承)
リスト 6.1.3.1.1 ScoreManager.java
1: import java.util.ArrayList;
2: import java.util.List;
3:
4: import obpro.cui.Input;
5:
6:
21: public class ScoreManagerApplication extends AbstractCUIApplication {
22:
23:
24: final int NULL_INDEX = -1;
25:
26: final String ADD = "add";
27: final String DELETE = "del";
28: final String SEARCH = "search";
29: final String SHOW = "show";
30:
31:
32: private List scoreList;
33:
34:
35: public void showTitle() {
36: System.out.println("★★★★★★成績管理アプリケーション★★★★★★");
37: }
38:
39:
40: public void showEndTitle() {
41: System.out.println("アプリケーションを終了します。");
42: }
43:
44:
45: public void initializeData() {
46: scoreList = new ArrayList();
47: }
48:
49:
50: public void showCommandMenu() {
51: System.out.print("コマンドを入力してください");
52: System.out.print("(" + ADD + ":成績の追加");
53: System.out.print(", " + DELETE + ":成績の削除");
54: System.out.print(", " + SEARCH + ":成績の検索");
55: System.out.print(", " + SHOW + ":成績一覧と平均点の表示");
56: System.out.print(", " + getQuitCommand() + ":終了" + ")");
57: System.out.println();
58: }
59:
60:
61: public void executeCommand(String command) {
62: if (command.equals(ADD)) {
63: addScore();
64: } else if (command.equals(DELETE)) {
65: deleteScore();
66: } else if (command.equals(SEARCH)) {
67: searchScore();
68: } else if (command.equals(SHOW)) {
69: showScoreList();
70: } else {
71: System.out.println("そのようなコマンドはありません");
72: }
73: }
74:
75:
76: private void addScore() {
77:
78: System.out.println("名前を入力してください");
79: String name = Input.getString();
80: System.out.println("成績を入力してください");
81: int score = Input.getInt();
82:
83:
84: scoreList.add(new Score(score, name));
85:
86:
87: System.out.println("成績を登録しました");
88: }
89:
90: private void deleteScore() {
91:
92: System.out.println("削除する成績の名前を入力してください");
93: String name = Input.getString();
94:
95:
96: int deleteIndex = searchScoreIndexByName(name);
97: scoreList.remove(deleteIndex);
98:
99:
100: System.out.println("成績を削除しました");
101: }
102:
103:
104: private void searchScore() {
105:
106: System.out.println("検索する成績の名前を入力してください");
107: String name = Input.getString();
108:
109:
110: int searchIndex = searchScoreIndexByName(name);
111:
112:
113: Score score = (Score) scoreList.get(searchIndex);
114: System.out.println(score.getName() + "さんの点数は" + score.getScore()
115: + "点です");
116: }
117:
118:
119: private int searchScoreIndexByName(String name) {
120: for (int i = 0; i < scoreList.size(); i++) {
121: if (((Score) scoreList.get(i)).getName().equals(name)) {
122: return i;
123: }
124: }
125: return NULL_INDEX;
126: }
127:
128:
129: private void showScoreList() {
130:
131: System.out.println("★★★★★★成績一覧表★★★★★★");
132: for (int i = 0; i < scoreList.size(); i++) {
133: Score score = (Score) scoreList.get(i);
134: System.out.println(score.getName() + "さん" + score.getScore() + "点");
135: }
136:
137:
138: System.out.println("★★★★★★平均点★★★★★★");
139: double average = getAverageScore();
140: System.out.println("平均点:" + average + "点");
141: }
142:
143:
144: private double getAverageScore() {
145:
146: double total = 0d;
147: for (int i = 0; i < scoreList.size(); i++) {
148: total = total + ((Score) scoreList.get(i)).getScore();
149: }
150:
151:
152: double average = total / scoreList.size();
153:
154: return average;
155: }
156:
157: }
6.1.3.2 成績を表現するクラス
リスト 6.1.3.2.1 Score.java
1:
7: public class Score {
8:
9: private int score;
10: private String name;
11:
12:
15: public Score(int score, String name) {
16: this.score = score;
17: this.name = name;
18: }
19:
20:
23: public String getName() {
24: return this.name;
25: }
26:
27:
30: public int getScore() {
31: return this.score;
32: }
33: }
6.1.4 適用例(2)作文さんアプリケーション
6.1.4.1 作文さんアプリケーション(抽象CUIアプリケーションクラスを継承)
リスト 6.1.4.1.1 SakubunApplication.java
1: import java.util.ArrayList;
2: import java.util.List;
3:
4: import obpro.cui.Input;
5:
6:
10:
11:
18: public class SakubunApplication extends AbstractCUIApplication {
19:
20: private List nouns = new ArrayList();
21: private List verbs = new ArrayList();
22:
23:
24: public void showTitle() {
25: System.out.println("作文さん開始");
26: }
27:
28:
29: public void showEndTitle() {
30: System.out.println("作文さん終了");
31: }
32:
33:
34: public void showCommandMenu() {
35: System.out.println("メニュー(1.名詞追加 2.動詞追加 3.作文 q.終了)");
36: }
37:
38:
39: public void executeCommand(String command) {
40: if (command.equals("1")) {
41: addNoun();
42: } else if (command.equals("2")) {
43: addVerb();
44: } else if (command.equals("3")) {
45: makeSentence();
46: } else {
47: System.out.println("無効なコマンドです");
48: }
49: }
50:
51:
52: private void addNoun() {
53: System.out.println("名詞を入力してください");
54: String noun = Input.getString();
55: nouns.add(noun);
56: System.out.println("名詞" + noun + "を追加しました");
57: }
58:
59:
60: private void addVerb() {
61: System.out.println("動詞を入力してください");
62: String verb = Input.getString();
63: verbs.add(verb);
64: System.out.println("動詞" + verb + "を追加しました");
65: }
66:
67:
68: private void makeSentence() {
69:
70: String noun = (String) nouns.get((int) (Math.random() * nouns.size()));
71: String verb = (String) verbs.get((int) (Math.random() * verbs.size()));
72:
73:
74: System.out.println(noun + "は" + verb);
75: }
76:
77: }
6.2 GUIアニメーションアプリケーションフレームワーク
6.2.1 Rectangleアニメーション
6.2.2 抽象GUIアプリケーション
6.2.3 CUIアプリケーションフレームワーククラス図
6.2.4 GUIアプリケーション実行エンジン
リスト 6.2.4.1 GUIAnimationApplicationEngine.java
1: import java.util.ArrayList;
2: import java.util.List;
3:
4: import obpro.gui.BCanvas;
5: import obpro.gui.BWindow;
6:
7:
11:
12:
19: public class GUIAnimationApplicationEngine {
20:
21: public static void main(String[] args) {
22: if (args.length != 1) {
23: System.out.println("起動には引数が必要です");
24: return;
25: }
26:
27:
28: AbstractGUIAnimationApplication application = (AbstractGUIAnimationApplication) BReflection
29: .createInstanceByName(args[0]);
30: GUIAnimationApplicationEngine engine = new GUIAnimationApplicationEngine(
31: application);
32: engine.run();
33: }
34:
35:
36: private AbstractGUIAnimationApplication application;
37:
38:
39: private BWindow window;
40:
41:
42: private List elements = new ArrayList();
43:
44:
45: private double stepInterval = 0.03d;
46:
47:
50: public GUIAnimationApplicationEngine(
51: AbstractGUIAnimationApplication application) {
52: this.application = application;
53: application.setEngine(this);
54: }
55:
56:
57: private void run() {
58: openWindow();
59: application.prepareAnimationStart();
60: doAnimation();
61: }
62:
63:
64: private void openWindow() {
65: window = new BWindow();
66: application.initializeWindow(window);
67: window.show();
68: }
69:
70:
71: private void doAnimation() {
72:
73: BCanvas canvas = window.getCanvas();
74:
75:
76: while (true) {
77: {
78:
79: application.processOneStepForApplication(canvas);
80:
81:
82: for (int i = 0; i < elements.size(); i++) {
83: AnimationElement element = (AnimationElement) elements
84: .get(i);
85: element.processOneStep(canvas);
86: }
87: }
88:
89:
90: canvas.clear();
91: application.drawForApplication(canvas);
92: for (int i = 0; i < elements.size(); i++) {
93: AnimationElement element = (AnimationElement) elements.get(i);
94: element.draw(canvas);
95: }
96: canvas.update();
97:
98:
99: canvas.sleep(stepInterval);
100: }
101: }
102:
103:
106: public void setStepInterval(double stepInterval) {
107: this.stepInterval = stepInterval;
108: }
109:
110:
113: public void addElement(AnimationElement element) {
114: elements.add(element);
115: }
116:
117:
120: public void removeElement(AnimationElement element) {
121: elements.remove(element);
122: }
123:
124: }
6.2.5 抽象GUIアプリケーションクラス(スーパークラス)
リスト 6.2.5.1 AbstractGUIAnimationApplication.java
1: import obpro.gui.BCanvas;
2: import obpro.gui.BWindow;
3:
4:
8:
9:
16: public class AbstractGUIAnimationApplication {
17:
18: private GUIAnimationApplicationEngine engine;
19:
20:
23: public final GUIAnimationApplicationEngine getEngine() {
24: return this.engine;
25: }
26:
27:
30: public final void setEngine(GUIAnimationApplicationEngine engine) {
31: this.engine = engine;
32: }
33:
34:
37: public void initializeWindow(BWindow window) {
38: window.setLocation(100, 100);
39: window.setSize(640, 480);
40: }
41:
42:
45: public void prepareAnimationStart() {
46: }
47:
48:
51: public void processOneStepForApplication(BCanvas canvas) {
52: }
53:
54:
57: public void drawForApplication(BCanvas canvas) {
58: }
59:
60: }
6.3 シューティングゲーム
6.3.1 シューティングゲーム(6)(フレームワークのコンポーネントとする)
リスト 6.3.1.1 ShootingGame6.java
1: import java.util.ArrayList;
2: import java.util.List;
3:
4: import obpro.gui.BCanvas;
5: import obpro.sound.BSound;
6:
7:
14: public class ShootingGame6 extends AbstractGUIAnimationApplication {
15:
16:
17: private Background background;
18: private ScoreBoard scoreBoard;
19: private PlayerAircraft player;
20: private List enemies = new ArrayList();
21: private List bullets = new ArrayList();
22:
23:
24: BSound bgm;
25:
26:
29: public void prepareAnimationStart() {
30:
31: getEngine().setStepInterval(0.01);
32:
33:
34: initializeSounds();
35: bgm.loop();
36:
37:
38: background = new Background();
39: getEngine().addElement(background);
40:
41:
42: scoreBoard = new ScoreBoard(100, 30, 0, 0);
43: getEngine().addElement(scoreBoard);
44:
45:
46: player = new PlayerAircraft(50, 50, this);
47: getEngine().addElement(player);
48: }
49:
50:
53: private void initializeSounds() {
54:
55: bgm = new BSound("sound/bgm.mp3");
56:
57:
58: BSound.load("sound/explode_enemy.mp3");
59: BSound.load("sound/explode_player.mp3");
60: BSound.load("sound/fire.mp3");
61: BSound.load("sound/optionvoice.mp3");
62: BSound.load("sound/powerup.mp3");
63: }
64:
65:
68: public void processOneStepForApplication(BCanvas canvas) {
69:
70: int randomNumber = (int) (Math.random() * 30);
71: if (randomNumber == 0) {
72: int y = (int) (Math.random() * canvas.getCanvasHeight());
73: EnemyAircraft enemy = new EnemyAircraft(canvas.getCanvasWidth(), y,
74: this);
75: addEnemy(enemy);
76: }
77:
78:
79: for (int i = 0; i < enemies.size(); i++) {
80: EnemyAircraft enemy = (EnemyAircraft) enemies.get(i);
81: if (enemy.isAlive() && player.intersects(enemy)) {
82: player.explode();
83: }
84: }
85:
86:
87: for (int i = 0; i < enemies.size(); i++) {
88: EnemyAircraft enemy = (EnemyAircraft) enemies.get(i);
89: for (int j = 0; j < bullets.size(); j++) {
90: Bullet bullet = (Bullet) bullets.get(j);
91: if (bullet.isAlive() && enemy.isAlive()
92: && enemy.intersects(bullet)) {
93: enemy.explode();
94: bullet.destroy();
95: scoreBoard.addScore(100);
96: }
97: }
98: }
99: }
100:
101:
104: public void addEnemy(EnemyAircraft enemy) {
105: enemies.add(enemy);
106: getEngine().addElement(enemy);
107: }
108:
109:
112: public void removeEnemy(EnemyAircraft enemy) {
113: enemies.remove(enemy);
114: getEngine().removeElement(enemy);
115: }
116:
117:
120: public void addBullet(Bullet bullet) {
121: bullets.add(bullet);
122: getEngine().addElement(bullet);
123: }
124:
125:
128: public void removeBullet(Bullet bullet) {
129: bullets.remove(bullet);
130: getEngine().removeElement(bullet);
131: }
132:
133: }
6.3.2 アニメーションするオブジェクトすべてのスーパークラス
リスト 6.3.2.1 AnimationElement.java
1: import obpro.gui.BCanvas;
2:
3:
6: public class AnimationElement {
7:
8:
11: public void processOneStep(BCanvas canvas) {
12: }
13:
14:
17: public void draw(BCanvas canvas) {
18: }
19:
20: }
6.3.3 背景を表現するクラス
リスト 6.3.3.1 Background.java
1: import obpro.gui.BCanvas;
2:
3:
6: public class Background extends AnimationElement {
7:
8: private int x1 = 0;
9: private int x2 = 1000;
10:
11:
14: public void processOneStep(BCanvas canvas) {
15: x1--;
16: if (x1 < -1000) {
17: x1 = 1000;
18: }
19: x2--;
20: if (x2 < -1000) {
21: x2 = 1000;
22: }
23: }
24:
25:
28: public void draw(BCanvas canvas) {
29: canvas.drawImage("img/background.jpg", x1, 0);
30: canvas.drawImage("img/background.jpg", x2, 0);
31: }
32:
33: }
6.3.4 ゲームのキャラクターを表現するクラス
リスト 6.3.4.1 Character.java
1:
4: public class Character 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:
15: public Character(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:
25: public int getHeight() {
26: return this.height;
27: }
28:
29:
32: public int getWidth() {
33: return this.width;
34: }
35:
36:
39: public int getX() {
40: return this.x;
41: }
42:
43:
46: public int getY() {
47: return this.y;
48: }
49:
50:
53: public void setLocation(int newX, int newY) {
54: x = newX;
55: y = newY;
56: }
57:
58:
61: public void move(int moveX, int moveY) {
62: x = x + moveX;
63: y = y + moveY;
64: }
65:
66:
69: public boolean intersects(Character 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: }
6.3.5 自機を表現するクラス
リスト 6.3.5.1 PlayerAircraft.java
1: import java.util.ArrayList;
2: import java.util.List;
3:
4: import obpro.gui.BCanvas;
5: import obpro.sound.BSound;
6:
7:
10: public class PlayerAircraft extends Character {
11:
12:
13: private final int ALIVE = 1;
14: private final int EXPLODING = 2;
15: private final int DEAD = 3;
16:
17: private final int EXPLODING_ANIMATION_SIZE = 11;
18:
19:
20: private int liveState = ALIVE;
21: private int explodingCount = 0;
22:
23:
24: private ShootingGame6 game;
25: private List options = new ArrayList();
26:
27:
30: public PlayerAircraft(int x, int y, ShootingGame6 game) {
31: super(x, y, 100, 50);
32: this.game = game;
33: }
34:
35:
38: public void move(int moveX, int moveY) {
39:
40: super.move(moveX, moveY);
41:
42:
43: for (int i = 0; i < options.size(); i++) {
44: Option option = (Option) options.get(i);
45: option.move(moveX, moveY);
46: }
47: }
48:
49:
52: public void processOneStep(BCanvas canvas) {
53: if (liveState == ALIVE) {
54:
55: if (canvas.isKeyPressing(37)) {
56: move(-5, 0);
57: }
58: if (canvas.isKeyPressing(38)) {
59: move(0, -5);
60: }
61: if (canvas.isKeyPressing(39)) {
62: move(5, 0);
63: }
64: if (canvas.isKeyPressing(40)) {
65: move(0, 5);
66: }
67:
68:
69: if (canvas.isKeyDown()) {
70: int keyCode = canvas.getKeyCode();
71: if (keyCode == 70) {
72: fire();
73: }
74: }
75:
76:
77: if (canvas.isKeyDown()) {
78: int keyCode = canvas.getKeyCode();
79: if (keyCode == 71) {
80: BSound.play("sound/optionvoice.mp3", 100);
81: BSound.play("sound/powerup.mp3");
82: options.add(new Option(getX(), getY(), getWidth(),
83: getHeight(), options.size() + 1));
84: }
85: }
86:
87:
88: for (int i = 0; i < options.size(); i++) {
89: Option option = (Option) options.get(i);
90: option.processOneStep(canvas);
91: }
92: } else if (liveState == EXPLODING) {
93: processExplode();
94: }
95: }
96:
97:
100: public boolean isAlive() {
101: return liveState == ALIVE;
102: }
103:
104:
107: private void processExplode() {
108: explodingCount++;
109: if (explodingCount >= EXPLODING_ANIMATION_SIZE) {
110: liveState = DEAD;
111: }
112: }
113:
114:
117: public void explode() {
118: if (liveState == ALIVE) {
119: liveState = EXPLODING;
120: explodingCount = 0;
121: BSound.play("sound/explode_player.mp3");
122: }
123: }
124:
125:
128: public void draw(BCanvas canvas) {
129: if (liveState == ALIVE) {
130:
131: drawAircraft(canvas);
132:
133:
134: for (int i = 0; i < options.size(); i++) {
135: Option option = (Option) options.get(i);
136: option.draw(canvas);
137: }
138: } else if (liveState == EXPLODING) {
139: drawExplosion(canvas);
140: }
141: }
142:
143:
146: private void drawAircraft(BCanvas canvas) {
147: canvas.drawImage("img/player.png", getX(), getY(), getWidth(),
148: getHeight());
149: }
150:
151:
154: private void drawExplosion(BCanvas canvas) {
155: canvas.drawImage("img/explode" + (explodingCount + 1) + ".gif",
156: getX(), getY(), getWidth(), getHeight());
157: }
158:
159:
162: private void fire() {
163: if (liveState == ALIVE) {
164: BSound.play("sound/fire.mp3");
165:
166:
167: fire(this);
168:
169:
170: for (int i = 0; i < options.size(); i++) {
171: Option option = (Option) options.get(i);
172: fire(option);
173: }
174: }
175: }
176:
177:
180: private void fire(Character shooter) {
181: Bullet bullet = new Bullet(0, 0, 20, 10, game);
182: int x = shooter.getX() + shooter.getWidth() / 2 - bullet.getWidth() / 2;
183: int y = shooter.getY() + shooter.getHeight() / 2 - bullet.getHeight()
184: / 2;
185: bullet.setLocation(x, y);
186: game.addBullet(bullet);
187: }
188: }
6.3.6 敵機を表現するクラス
リスト 6.3.6.1 EnemyAircraft.java
1: import obpro.gui.BCanvas;
2: import obpro.sound.BSound;
3:
4:
7: public class EnemyAircraft extends Character {
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: private ShootingGame6 game;
22:
23:
26: public EnemyAircraft(int x, int y, ShootingGame6 game) {
27: super(x, y, 100, 50);
28: this.game = game;
29: }
30:
31:
34: public void processOneStep(BCanvas canvas) {
35: if (liveState == ALIVE) {
36:
37: move(-5, 0);
38:
39:
40: if (getX() < -100) {
41: destroy();
42: }
43: } else if (liveState == EXPLODING) {
44: processExplode();
45: }
46: }
47:
48:
51: public boolean isAlive() {
52: return liveState == ALIVE;
53: }
54:
55:
58: public void destroy() {
59: game.removeEnemy(this);
60: liveState = DEAD;
61: }
62:
63:
66: private void processExplode() {
67: explodingCount++;
68: if (explodingCount >= EXPLODING_ANIMATION_SIZE) {
69: destroy();
70: }
71: }
72:
73:
76: public void explode() {
77: if (liveState == ALIVE) {
78: liveState = EXPLODING;
79: explodingCount = 0;
80: BSound.play("sound/explode_enemy.mp3");
81: }
82: }
83:
84:
87: public void draw(BCanvas canvas) {
88: if (liveState == ALIVE) {
89: drawAircraft(canvas);
90: } else if (liveState == EXPLODING) {
91: drawExplosion(canvas);
92: }
93: }
94:
95:
98: private void drawAircraft(BCanvas canvas) {
99: canvas.drawImage("img/enemy.png", getX(), getY(), getWidth(),
100: getHeight());
101: }
102:
103:
106: private void drawExplosion(BCanvas canvas) {
107: canvas.drawImage("img/explode" + (explodingCount + 1) + ".gif",
108: getX(), getY(), getWidth(), getHeight());
109: }
110:
111: }
6.3.7 弾を表現するクラス
リスト 6.3.7.1 Bullet.java
1: import java.awt.Color;
2:
3: import obpro.gui.BCanvas;
4:
5:
8: public class Bullet extends Character {
9:
10:
11: private final int ALIVE = 1;
12: private final int DEAD = 2;
13:
14:
15: private int liveState = ALIVE;
16:
17:
18: private ShootingGame6 game;
19:
20:
21: private Color color = new Color(0, 0, 255);
22:
23:
26: public Bullet(int x, int y, int width, int height, ShootingGame6 game) {
27: super(x, y, width, height);
28: this.game = game;
29: }
30:
31:
34: public void processOneStep(BCanvas canvas) {
35: if (liveState == ALIVE) {
36:
37: move(15, 0);
38:
39:
40: if (getX() > canvas.getCanvasWidth()) {
41: destroy();
42: }
43: }
44: }
45:
46:
49: public void destroy() {
50: if (liveState == ALIVE) {
51: liveState = DEAD;
52: game.removeBullet(this);
53: }
54: }
55:
56:
59: public boolean isAlive() {
60: return liveState == ALIVE;
61: }
62:
63:
66: public void draw(BCanvas canvas) {
67: if (liveState == ALIVE) {
68: canvas.drawFillTriangle(color, getX(), getY(), getX() + getWidth(),
69: getY(), getX(), getY() + getHeight());
70: canvas.drawFillTriangle(color, getX(), getY() + getHeight(), getX()
71: + getWidth(), getY() + getHeight(), getX() + getWidth(),
72: getY());
73: }
74: }
75:
76: }
6.3.8 オプションを表現するクラス
リスト 6.3.8.1 Option.java
1: import java.util.LinkedList;
2:
3: import obpro.gui.BCanvas;
4:
5:
8: public class Option extends Character {
9:
10:
11: private final int HISTORY_INTERVAL = 15;
12: private final int SCALE_UP = 1;
13: private final int SCALE_DOWN = 2;
14:
15:
16: private int animationState = SCALE_UP;
17: private int animationCount = 0;
18:
19:
20: private LinkedList playerMoveHistories = new LinkedList();
21:
22:
25: public Option(int x, int y, int width, int height, int index) {
26: super(x, y, width, height);
27: initializeHistories(index);
28: }
29:
30:
33: private void initializeHistories(int index) {
34: for (int i = 0; i < HISTORY_INTERVAL * index; i++) {
35: playerMoveHistories.add(new MoveData());
36: }
37: }
38:
39:
43: public void move(int moveX, int moveY) {
44:
45: MoveData moveData = (MoveData) playerMoveHistories.removeFirst();
46: super.move(moveData.dx, moveData.dy);
47:
48:
49: moveData.dx = moveX;
50: moveData.dy = moveY;
51: playerMoveHistories.addLast(moveData);
52: }
53:
54:
57: public void processOneStep(BCanvas canvas) {
58:
59: if (animationState == SCALE_UP) {
60: animationCount++;
61: } else if (animationState == SCALE_DOWN) {
62: animationCount--;
63: }
64:
65:
66: if (animationState == SCALE_UP && animationCount >= 10) {
67: animationState = SCALE_DOWN;
68: } else if (animationState == SCALE_DOWN && animationCount <= 0) {
69: animationState = SCALE_UP;
70: }
71: }
72:
73:
76: public void draw(BCanvas canvas) {
77: int w = getWidth() / 3 + animationCount;
78: int h = getHeight() / 3 + animationCount;
79: int x = getX() + (getWidth() - w) / 2;
80: int y = getY() + (getHeight() - h) / 2;
81: canvas.drawImage("img/option.png", x, y, w, h);
82: }
83:
84:
88: class MoveData {
89: int dx = 0;
90: int dy = 0;
91: }
92: }
6.3.9 得点板を表現するクラス
リスト 6.3.9.1 ScoreBoard.java
1: import java.awt.Color;
2: import java.awt.Font;
3:
4: import obpro.gui.BCanvas;
5:
6:
9: public class ScoreBoard extends Character {
10:
11: private Font font = new Font("Dialog", Font.PLAIN, 24);
12: private Color color = new Color(255, 255, 255);
13: private int score;
14:
15:
18: public ScoreBoard(int x, int y, int width, int height) {
19: super(x, y, width, height);
20: }
21:
22:
25: public void addScore(int score) {
26: this.score += score;
27: }
28:
29:
32: public void resetScore() {
33: this.score = 0;
34: }
35:
36:
39: public void draw(BCanvas canvas) {
40: canvas.drawText(color, "SCORE " + score, getX(), getY(), font);
41: }
42:
43: }