3 『継承』
3.1 オブジェクトの動作を理解するためのサンプルプログラム
3.1.1 サンプルプログラム
3.1.1.1 サンプルプログラム(1)(インスタンス1つ)
リスト 3.1.1.1.1 Example1.java
1:
9: public class Example1 {
10:
11: public static void main(String[] args) {
12: Example1 example = new Example1();
13: example.main();
14: }
15:
16: private ClassA a;
17:
18: private void main() {
19:
20: a = new ClassA();
21: a.setX(1000);
22: a.setY(1000);
23:
24:
25: System.out.print("a: ");
26: a.display();
27: }
28:
29: }
3.1.1.2 サンプルプログラム(2)(複数のインスタンス)
リスト 3.1.1.2.1 Example2.java
1: import java.util.ArrayList;
2:
3:
12: public class Example2 {
13:
14: public static void main(String[] args) {
15: Example2 example = new Example2();
16: example.main();
17: }
18:
19: private ArrayList<ClassA> aInstances;
20:
21: private void main() {
22:
23:
24: aInstances = new ArrayList<ClassA>();
25:
26:
27: initialize(aInstances);
28:
29:
30: display(aInstances);
31: }
32:
33: private void initialize(ArrayList<ClassA> targets) {
34: for (int i = 0; i < 3; i++) {
35: ClassA a = new ClassA();
36: a.setX(100 * i);
37: a.setY(100 * i);
38: targets.add(a);
39: }
40: }
41:
42: private void display(ArrayList<ClassA> targets) {
43:
44: for (int i = 0; i < targets.size(); i++) {
45: ClassA a = targets.get(i);
46: System.out.print("targets [" + i + "]: ");
47: a.display();
48: }
49: }
50: }
3.1.1.3 サンプルプログラム(3)(継承)
リスト 3.1.1.3.1 Example3.java
1:
9: public class Example3 {
10:
11: public static void main(String[] args) {
12: Example3 example = new Example3();
13: example.main();
14: }
15:
16: private ClassA a;
17: private ClassB b;
18: private ClassC c;
19: private ClassD d;
20:
21: private void main() {
22:
23: a = new ClassA();
24: b = new ClassB();
25: c = new ClassC(100);
26: d = new ClassD(100);
27:
28:
29: a.setX(1000);
30: a.setY(1000);
31: b.setX(2000);
32: b.setY(2000);
33: b.setW(2000);
34: b.setH(2000);
35: c.setX(3000);
36: c.setY(3000);
37: d.setX(4000);
38: d.setY(4000);
39: d.addZ(50);
40:
41:
42: System.out.print("a: ");
43: a.display();
44: System.out.print("b: ");
45: b.display();
46: System.out.print("c: ");
47: c.display();
48: System.out.print("d: ");
49: d.display();
50: }
51: }
3.1.2 サンプルプログラムが利用するクラスたち
3.1.2.1 クラスA
リスト 3.1.2.1.1 ClassA.java
1:
9: public class ClassA {
10:
11: private int x = 100;
12: private int y = 200;
13:
14:
17: public int getX() {
18: return x;
19: }
20:
21:
24: public void setX(int x) {
25: this.x = x;
26: }
27:
28:
31: public int getY() {
32: return y;
33: }
34:
35:
38: public void setY(int y) {
39: this.y = y;
40: }
41:
42:
45: public void display() {
46: System.out.println("x=" + getX() + ", y=" + getY());
47: }
48:
49: }
3.1.2.2 クラスB(クラスAを継承)
リスト 3.1.2.2.1 ClassB.java
1:
9: public class ClassB extends ClassA {
10:
11: private int w = 300;
12: private int h = 400;
13:
14:
17: public int getW() {
18: return w;
19: }
20:
21:
24: public void setW(int w) {
25: this.w = w;
26: }
27:
28:
31: public int getH() {
32: return h;
33: }
34:
35:
38: public void setH(int h) {
39: this.h = h;
40: }
41:
42:
45: public void display() {
46: System.out.println("x=" + getX() + ", y=" + getY() + ", w=" + getW()
47: + ", h=" + getH());
48: }
49:
50: }
3.1.2.3 クラスC(クラスAを継承)
リスト 3.1.2.3.1 ClassC.java
1:
9: public class ClassC extends ClassA {
10:
11: private int z;
12:
13: public ClassC(int z) {
14: this.z = z;
15: }
16:
17:
20: public int getZ() {
21: return z;
22: }
23:
24:
27: public void setZ(int z) {
28: this.z = z;
29: }
30:
31:
34: public void display() {
35: System.out.println("x=" + getX() + ", y=" + getY() + ", z=" + getZ());
36: }
37: }
3.1.2.4 クラスD(クラスAを継承)
リスト 3.1.2.4.1 ClassD.java
1:
9: public class ClassD extends ClassC {
10:
11:
14: public ClassD(int z) {
15: super(z);
16: }
17:
18:
21: public void addZ(int addZ) {
22: int z = getZ();
23: setZ(z + addZ);
24: }
25:
26: }
3.2 シューティングゲーム
3.2.1 シューティングゲーム(3)(シューティングゲーム(2)と同じ)
リスト 3.2.1.1 ShootingGame3.java
1: import java.util.ArrayList;
2:
3: import obpro.gui.BCanvas;
4: import obpro.gui.BWindow;
5:
6:
14: public class ShootingGame3 {
15:
16: public static void main(String[] args) {
17: ShootingGame3 shootingGame = new ShootingGame3();
18: shootingGame.main();
19: }
20:
21: BWindow window;
22:
23: PlayerAircraft player;
24: EnemyAircraft enemy;
25: ArrayList<Bullet> bullets = new ArrayList<Bullet>();
26:
27: void main() {
28: openWindow();
29: doAnimation();
30: }
31:
32:
33: void openWindow() {
34: window = new BWindow();
35: window.setLocation(100, 100);
36: window.setSize(640, 480);
37: window.show();
38: }
39:
40:
41: void doAnimation() {
42: BCanvas canvas = window.getCanvas();
43: initializeObjects();
44:
45:
46: while (true) {
47:
48: processOneStep(canvas);
49:
50:
51: canvas.clear();
52: draw(canvas);
53: canvas.update();
54:
55:
56: canvas.sleep(0.05);
57: }
58: }
59:
60:
61: private void initializeObjects() {
62: player = new PlayerAircraft(50, 50, 100, 50);
63: enemy = new EnemyAircraft(400, 50, 100, 50);
64: for (int i = 0; i < 3; i++) {
65: bullets.add(new Bullet(-1, -1, 20, 10));
66: }
67: }
68:
69:
70: private void processOneStep(BCanvas canvas) {
71:
72: if (canvas.isKeyPressing(37)) {
73: player.move(-5, 0);
74: }
75: if (canvas.isKeyPressing(38)) {
76: player.move(0, -5);
77: }
78: if (canvas.isKeyPressing(39)) {
79: player.move(5, 0);
80: }
81: if (canvas.isKeyPressing(40)) {
82: player.move(0, 5);
83: }
84:
85:
86: if (canvas.isKeyDown()) {
87: int keyCode = canvas.getKeyCode();
88: if (keyCode == 70) {
89:
90: for (Bullet bullet : bullets) {
91: if (bullet.isAlive() == false) {
92: bullet.fire(player);
93: break;
94: }
95: }
96: }
97: }
98:
99:
100: player.processOneStep();
101: enemy.processOneStep();
102: for (Bullet bullet : bullets) {
103: bullet.processOneStep(canvas);
104: }
105:
106:
107: if (player.intersects(enemy)) {
108: player.explode();
109: }
110: }
111:
112:
113: private void draw(BCanvas canvas) {
114: player.draw(canvas);
115: enemy.draw(canvas);
116: for (Bullet bullet : bullets) {
117: bullet.draw(canvas);
118: }
119: }
120: }
3.2.2 シューティングゲームのキャラクターを表現するクラス
リスト 3.2.2.1 ShootingCharacter.java
1:
4: public class ShootingCharacter {
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 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:
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: }
3.2.3 自機を表現するクラス
リスト 3.2.3.1 PlayerAircraft.java
1: import java.awt.Color;
2:
3: import obpro.cui.Random;
4: import obpro.gui.BCanvas;
5:
6:
9: public class PlayerAircraft extends ShootingCharacter {
10:
11:
12: private final int ALIVE = 1;
13: private final int EXPLODING = 2;
14: private final int DEAD = 3;
15:
16: private final int EXPLODING_ANIMATION_SIZE = 10;
17:
18:
19: private int liveState = ALIVE;
20: private int explodingCount = 0;
21:
22:
25: public PlayerAircraft(int x, int y, int width, int height) {
26: super(x, y, width, height);
27: }
28:
29:
32: public void move(int moveX, int moveY) {
33: if (liveState == ALIVE) {
34: super.move(moveX, moveY);
35: }
36: }
37:
38:
41: public void processOneStep() {
42: processExplore();
43: }
44:
45:
48: private void processExplore() {
49: if (liveState == EXPLODING) {
50: explodingCount++;
51: if (explodingCount == EXPLODING_ANIMATION_SIZE) {
52: liveState = DEAD;
53: }
54: }
55: }
56:
57:
60: public void explode() {
61: if (liveState == ALIVE) {
62: liveState = EXPLODING;
63: explodingCount = 0;
64: }
65: }
66:
67:
70: public boolean intersects(EnemyAircraft enemy) {
71: int player_leftX = this.getX();
72: int player_rightX = this.getX() + this.getWidth();
73: int enemy_leftX = enemy.getX();
74: int enemy_rightX = enemy.getX() + enemy.getWidth();
75: int player_topY = this.getY();
76: int player_bottomY = this.getY() + this.getHeight();
77: int enemy_topY = enemy.getY();
78: int enemy_bottomY = enemy.getY() + enemy.getHeight();
79:
80: return (enemy_leftX < player_rightX && enemy_rightX > player_leftX
81: && enemy_topY < player_bottomY && enemy_bottomY > player_topY);
82: }
83:
84:
87: public void draw(BCanvas canvas) {
88: if (liveState == ALIVE) {
89: drawAircraft(canvas);
90: } else if (liveState == EXPLODING) {
91: drawAircraft(canvas);
92: drawExplosion(canvas);
93: }
94: }
95:
96:
99: private void drawAircraft(BCanvas canvas) {
100:
101:
102: int headX = getX() + getWidth() * 11 / 13;
103: int headY = getY() + getHeight() * 4 / 5;
104:
105:
106: int bodyX = getX() + getWidth() / 13;
107: int bodyY = getY() + getHeight() * 2 / 5;
108: int bodyWidth = getWidth() * 10 / 13;
109: int bodyHeight = getHeight() * 2 / 5;
110:
111:
112: int verticalWingX1 = getX() + getWidth() * 2 / 13;
113: int verticalWingX2 = getX() + getWidth() * 7 / 13;
114:
115:
116: int tailWingY = getY() + getHeight() * 3 / 5;
117: int tailWingWidth = getWidth() / 13;
118: int tailWingHeight = getHeight() / 5;
119:
120:
121: drawFillRectangle(canvas, Color.BLUE, bodyX, bodyY, bodyWidth,
122: bodyHeight);
123: canvas.drawFillTriangle(Color.BLUE, headX, bodyY, headX, headY, getX()
124: + getWidth(), headY);
125:
126:
127: drawFillRectangle(canvas, Color.BLACK, getX(), tailWingY,
128: tailWingWidth, tailWingHeight);
129:
130:
131: canvas.drawFillTriangle(Color.GRAY, verticalWingX1, getY(),
132: verticalWingX1, bodyY, verticalWingX2, bodyY);
133:
134:
135: canvas.drawFillTriangle(Color.CYAN, verticalWingX1, tailWingY,
136: verticalWingX2, tailWingY, bodyX, getY() + getHeight());
137: }
138:
139:
142: private void drawExplosion(BCanvas canvas) {
143:
144: int fireCount = explodingCount * 4;
145:
146:
147: for (int i = 0; i < fireCount; i++) {
148: int fireX = getX() + Random.getInt(getWidth());
149: int fireY = getY() + Random.getInt(getHeight());
150: drawFire(canvas, fireX, fireY);
151: }
152: }
153:
154:
157: private void drawFire(BCanvas canvas, int x, int y) {
158: canvas.drawFillArc(Color.RED, x, y, 20, 20, 0, 360);
159: canvas.drawFillArc(Color.MAGENTA, x + 2, y + 2, 16, 16, 0, 360);
160: canvas.drawFillArc(Color.WHITE, x + 1, y + 1, 14, 14, 0, 360);
161: canvas.drawFillArc(Color.RED, x + 8, y + 1, 3, 3, 0, 360);
162: canvas.drawFillArc(Color.RED, x + 2, y + 8, 3, 3, 0, 360);
163: canvas.drawFillArc(Color.RED, x + 10, y + 8, 2, 3, 0, 360);
164: canvas.drawFillArc(Color.RED, x, y + 1, 2, 2, 0, 360);
165: canvas.drawFillArc(Color.RED, x + 15, y + 18, 2, 2, 0, 360);
166: }
167:
168:
171: private void drawFillRectangle(BCanvas canvas, Color color, int x, int y,
172: int width, int height) {
173: canvas.drawFillTriangle(color, x, y, x + width, y, x + width, y
174: + height);
175: canvas.drawFillTriangle(color, x, y, x, y + height, x + width, y
176: + height);
177: }
178:
179: }
3.2.4 敵機を表現するクラス
リスト 3.2.4.1 EnemyAircraft.java
1: import java.awt.Color;
2:
3: import obpro.gui.BCanvas;
4:
5:
8: public class EnemyAircraft extends ShootingCharacter {
9:
10:
13: public EnemyAircraft(int x, int y, int width, int height) {
14: super(x, y, width, height);
15: }
16:
17:
20: public void processOneStep() {
21: move(-5, 0);
22: }
23:
24:
27: public void draw(BCanvas canvas) {
28:
29:
30: int bodyHeight = getHeight() * 2 / 5;
31: int bodyY = getY() + bodyHeight;
32: int bodyWidth = getWidth() * 10 / 11;
33:
34:
35: int verticalWingX = getX() + getWidth() * 5 / 11;
36:
37:
38: int tailWingX = getX() + getWidth() * 10 / 11;
39: int tailWingY = getY() + getHeight() * 3 / 5;
40: int tailWingWidth = getWidth() / 11;
41: int tailWingHeight = getHeight() / 5;
42:
43:
44: int cockpitX = getX() + tailWingWidth;
45: int cockpitY = bodyY - tailWingWidth;
46: int cockpitWidth = getWidth() * 2 / 11;
47:
48:
49: int mainWingX1 = getX() + getWidth() * 3 / 11;
50: int mainWingX2 = getX() + getWidth() * 8 / 11;
51:
52:
53: drawFillRectangle(canvas, Color.BLACK, getX(), bodyY, bodyWidth,
54: bodyHeight);
55: canvas.drawFillArc(Color.GRAY, cockpitX, cockpitY, cockpitWidth,
56: cockpitWidth, 0, 180);
57:
58:
59: drawFillRectangle(canvas, Color.BLUE, tailWingX, tailWingY,
60: tailWingWidth, tailWingHeight);
61:
62:
63: canvas.drawFillTriangle(Color.RED, verticalWingX, bodyY, tailWingX,
64: getY(), tailWingX, bodyY);
65:
66:
67: canvas.drawFillTriangle(Color.CYAN, mainWingX1, tailWingY, mainWingX2,
68: tailWingY, tailWingX, getY() + getHeight());
69: }
70:
71:
74: private void drawFillRectangle(BCanvas canvas, Color color, int x, int y,
75: int width, int height) {
76: canvas.drawFillTriangle(color, x, y, x + width, y, x + width, y
77: + height);
78: canvas.drawFillTriangle(color, x, y, x, y + height, x + width, y
79: + height);
80: }
81:
82: }
3.2.5 弾を表現するクラス
リスト 3.2.5.1 Bullet.java
1: import java.awt.Color;
2:
3: import obpro.gui.BCanvas;
4:
5:
8: public class Bullet extends ShootingCharacter {
9:
10:
11: private final int LIVE = 1;
12: private final int DEAD = 2;
13:
14:
15: private int liveState = DEAD;
16:
17:
18: private Color color = new Color(0, 0, 255);
19:
20:
23: public Bullet(int x, int y, int width, int height) {
24: super(x, y, width, height);
25: }
26:
27:
30: public void processOneStep(BCanvas canvas) {
31: if (liveState == LIVE) {
32:
33: move(15, 0);
34:
35:
36: if (getX() > canvas.getCanvasWidth()) {
37: destroy();
38: }
39: }
40: }
41:
42:
45: public void fire(PlayerAircraft player) {
46: if (liveState == DEAD) {
47: int x = player.getX() + player.getWidth() / 2 - getWidth() / 2;
48: int y = player.getY() + player.getHeight() / 2 - getHeight() / 2;
49: setLocation(x, y);
50: liveState = LIVE;
51: }
52: }
53:
54:
57: public void destroy() {
58: if (liveState == LIVE) {
59: liveState = DEAD;
60: }
61: }
62:
63:
66: public boolean isAlive() {
67: return liveState == LIVE;
68: }
69:
70:
73: public void draw(BCanvas canvas) {
74: if (isAlive()) {
75: canvas.drawFillTriangle(color, getX(), getY(), getX() + getWidth(),
76: getY(), getX(), getY() + getHeight());
77: canvas.drawFillTriangle(color, getX(), getY() + getHeight(), getX()
78: + getWidth(), getY() + getHeight(), getX() + getWidth(),
79: getY());
80: }
81: }
82:
83: }