質問するログイン新規登録

回答編集履歴

1

コード追加

2020/01/22 11:51

投稿

jimbe
jimbe

スコア13395

answer CHANGED
@@ -1,4 +1,323 @@
1
1
  かなりひどいコードです.
2
2
  命名規則を無視し変数名はテキトウ, スコープを理解せずオブジェクトをそこら中で作りまくり, static 変数だらけです.
3
3
 
4
- Fishing を new するのはメインメソッドでの1回のみとなるように, スコープを理解して修正してみてください.
4
+ Fishing を new するのはメインメソッドでの1回のみとなるように, スコープを理解して修正してみてください.
5
+
6
+ ---
7
+ ```java
8
+ import java.awt.CardLayout;
9
+ import java.awt.event.*;
10
+ import java.util.Random;
11
+ import javax.swing.*;
12
+
13
+ public class JFishing extends JFrame {
14
+ /** 魚 */
15
+ private static class Fish {
16
+ private ImageIcon icon;
17
+ private int score;
18
+ Fish(String iconName, int score) {
19
+ icon = new ImageIcon(iconName);
20
+ this.score = score;
21
+ }
22
+ Icon getIcon() { return icon; }
23
+ int getScore() { return score; }
24
+ }
25
+ /** 釣り上げチャンス */
26
+ private static class CatchChance {
27
+ private static Random random = new Random(System.currentTimeMillis());
28
+ private int ratio;
29
+ private Icon icon;
30
+ private int time;
31
+ private Fish[] fishes;
32
+ /**
33
+ * コンストラクタ
34
+ * @param ratio 確率(全体に占める割合)
35
+ * @param iconName イメージファイル名
36
+ * @param time 継続時間
37
+ * @param fishes 釣れる可能性のある魚の配列
38
+ */
39
+ CatchChance(int ratio, String iconName, int time, Fish ... fishes) {
40
+ this.ratio = ratio;
41
+ this.icon = new ImageIcon(iconName);
42
+ this.time = time;
43
+ this.fishes = fishes;
44
+ }
45
+ int getRatio() { return ratio; }
46
+ Icon getIcon() { return icon; }
47
+ int getTime() { return time; }
48
+ Fish getFish() {
49
+ if(fishes.length == 0) return null;
50
+ int j = random.nextInt(fishes.length);
51
+ return fishes[j];
52
+ }
53
+ };
54
+ /** 魚が掛かっていない状態 */
55
+ private static class NormalState extends CatchChance {
56
+ private Random random = new Random(System.currentTimeMillis());
57
+ NormalState(String iconName) {
58
+ super(0, iconName, 0);
59
+ }
60
+ /** 魚が掛かっていない時間 */
61
+ int getTime() {
62
+ return 100 * (random.nextInt(50) + 1); // 100 - 5000
63
+ }
64
+ }
65
+ private static final CatchChance CATCH_CHANCES[] = {
66
+ new NormalState("しーん.jpg"),
67
+ new CatchChance(11,"!.jpg", 600, new Fish("N0.jpg" , 0), new Fish("N1.jpg" , 50), new Fish("N2.jpg" , 50), new Fish("N3.jpg" ,100), new Fish("N4.jpg" , 100)),
68
+ new CatchChance( 7,"!!.jpg", 400, new Fish("R0.jpg" ,150), new Fish("R1.jpg" ,150), new Fish("R2.jpg" , 200), new Fish("R3.jpg" ,200), new Fish("R4.jpg" , 250)),
69
+ new CatchChance( 2,"!!!.jpg",300, new Fish("SR0.jpg",300), new Fish("SR1.jpg",300), new Fish("SR2.jpg", 400), new Fish("SR3.jpg",400), new Fish("SR4.jpg", 500)),
70
+ new CatchChance( 0,"?.jpg", 0, new Fish("SC0.jpg",-50), new Fish("SC1.jpg",-50), new Fish("SC2.jpg",-100), new Fish("SC3.jpg", 0), new Fish("SC4.jpg",1000))
71
+ };
72
+
73
+ public static void main(String[] args) {
74
+ new JFishing().setVisible(true);
75
+ }
76
+
77
+ //private int flag = 0; //使い道不定
78
+ private int gamescore = 0;
79
+ private int alltime = 0; //60sカウントに使う。
80
+
81
+ private CardLayout mgr;
82
+ private CatchPanel catchPanel;
83
+
84
+ JFishing() {
85
+ super();
86
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
87
+ setBounds(550, 100, 770, 800);
88
+
89
+ mgr = new CardLayout();
90
+ getContentPane().setLayout(mgr);
91
+ add(new TitlePanel(), "Title");
92
+ add(new ExplainPanel(), "Explain");
93
+ add(new GamePanel(), "Game");
94
+
95
+ catchPanel = new CatchPanel();
96
+ add(catchPanel, "Catch");
97
+
98
+ showTitlePanel();
99
+ }
100
+ private void showTitlePanel() {
101
+ gamescore = 0;
102
+ alltime = 0;
103
+ mgr.show(getContentPane(), "Title");
104
+ }
105
+ private void showExplainPanel() {
106
+ mgr.show(getContentPane(), "Explain");
107
+ }
108
+ private void showGamePanel() {
109
+ mgr.show(getContentPane(), "Game");
110
+ }
111
+ private void showCatchPanel(Fish fish) {
112
+ catchPanel.setFish(fish);
113
+ mgr.show(getContentPane(), "Catch");
114
+ }
115
+
116
+ /** タイトルパネル */
117
+ private class TitlePanel extends JPanel {
118
+ TitlePanel() {
119
+ super(null);
120
+ setTitle("魚釣りゲーム~タイトル~");
121
+
122
+ JLabel titleLabel = new JLabel(new ImageIcon("タイトル画像.jpg"));
123
+ titleLabel.setBounds(-10, 0, 770, 760);
124
+ add(titleLabel);
125
+
126
+ JButton startButton = new JButton("スタート");
127
+ startButton.setBounds(310, 580, 130, 30);
128
+ startButton.addActionListener(e -> showGamePanel()); // スタート→メイン画面へ遷移
129
+ add(startButton);
130
+
131
+ JButton explainButton = new JButton("あそびかた");
132
+ explainButton.setBounds(310, 650, 130, 30);
133
+ explainButton.addActionListener(e -> showExplainPanel());
134
+ add(explainButton);
135
+ }
136
+ }
137
+
138
+ /** ルール説明パネル */
139
+ private class ExplainPanel extends JPanel {
140
+ private Icon rule1Icon = new ImageIcon("ルール1.jpg");
141
+ private Icon rule2Icon = new ImageIcon("ルール2.jpg");
142
+ private JLabel ruleLabel;
143
+ private JButton titleButton;
144
+ private JButton nextButton;
145
+
146
+ ExplainPanel() {
147
+ super(null);
148
+ setTitle("魚釣りゲームのルール説明");
149
+
150
+ ruleLabel = new JLabel(rule1Icon);
151
+ ruleLabel.setBounds(0, 150, 760, 460);
152
+ add(ruleLabel);
153
+
154
+ titleButton = new JButton("タイトルへ");
155
+ titleButton.setBounds(50, 520, 180, 30);
156
+ titleButton.addActionListener(e -> showTitlePanel());
157
+ add(titleButton);
158
+
159
+ nextButton = new JButton("つぎへ");
160
+ nextButton.setBounds(100, 540, 130, 30);
161
+ nextButton.addActionListener(e -> showRule2());
162
+ add(nextButton);
163
+
164
+ addComponentListener(new ComponentAdapter() {
165
+ @Override
166
+ public void componentShown(ComponentEvent e) {
167
+ showRule1();
168
+ }
169
+ });
170
+ }
171
+ private void showRule1() {
172
+ ruleLabel.setIcon(rule1Icon);
173
+ nextButton.setVisible(true);
174
+ titleButton.setVisible(false);
175
+ }
176
+ private void showRule2() {
177
+ ruleLabel.setIcon(rule2Icon);
178
+ nextButton.setVisible(false);
179
+ titleButton.setVisible(true);
180
+ }
181
+ }
182
+
183
+ /** ゲームパネル */
184
+ private class GamePanel extends JPanel {
185
+ private long starttime;
186
+ private CatchAction catchAction;
187
+ private JLabel scoreLabel;
188
+
189
+ GamePanel() {
190
+ super(null);
191
+ setTitle("魚釣りゲーム");
192
+
193
+ scoreLabel = new JLabel();
194
+ scoreLabel.setBounds(100, 0, 400, 400);
195
+ add(scoreLabel);
196
+
197
+ JLabel seaLabel = new JLabel(new ImageIcon("海.jpg"));
198
+ seaLabel.setBounds(195, 400, 560, 350);
199
+ add(seaLabel);
200
+
201
+ JLabel fisherLabel = new JLabel(new ImageIcon("釣りbasic2.jpg"));
202
+ fisherLabel.setBounds(0, 180, 380, 380);
203
+ add(fisherLabel);
204
+
205
+ catchAction = new CatchAction(CATCH_CHANCES);
206
+ catchAction.setOnCatchListener(fish -> {
207
+ gamescore += fish.getScore();
208
+ rewriteScoreLabel();
209
+ showCatchPanel(fish);
210
+ });
211
+
212
+ JButton catchButton = new JButton(catchAction);
213
+ catchButton.setBounds(378, 120, 375, 280);
214
+ add(catchButton);
215
+
216
+ addComponentListener(new ComponentAdapter() {
217
+ @Override
218
+ public void componentShown(ComponentEvent e) {
219
+ starttime = System.currentTimeMillis();
220
+ rewriteScoreLabel();
221
+ catchAction.start();
222
+ }
223
+ @Override
224
+ public void componentHidden(ComponentEvent e) {
225
+ alltime += (int)(System.currentTimeMillis() - starttime);
226
+ catchAction.stop();
227
+ }
228
+ });
229
+ rewriteScoreLabel();
230
+ }
231
+ private void rewriteScoreLabel() {
232
+ scoreLabel.setText("SCORE: " + gamescore + "点");
233
+ }
234
+ }
235
+ /** 釣り上げ */
236
+ private static class CatchAction extends AbstractAction {
237
+ interface OnCatchListener {
238
+ void onCatch(Fish fish);
239
+ }
240
+ private OnCatchListener listener;
241
+ private CatchChance[] catchChances;
242
+ private int totalRatio;
243
+ private Random random = new Random(System.currentTimeMillis());
244
+ private Timer timer;
245
+ private CatchChance chance;
246
+
247
+ CatchAction(CatchChance[] catchChances) {
248
+ this.catchChances = catchChances;
249
+ totalRatio = 0;
250
+ for(CatchChance cr : catchChances) totalRatio += cr.getRatio();
251
+
252
+ chance = catchChances[0];
253
+ putValue(LARGE_ICON_KEY, chance.getIcon());
254
+ }
255
+ void setOnCatchListener(OnCatchListener listener) {
256
+ this.listener = listener;
257
+ }
258
+ void start() {
259
+ chance = catchChances[0];
260
+ putValue(LARGE_ICON_KEY, chance.getIcon());
261
+ int delay = chance.getTime();
262
+ timer = new Timer(delay, new ActionListener() {
263
+ public void actionPerformed(ActionEvent e) {
264
+ timer.stop();
265
+ chance = (chance == catchChances[0] ? getChance() : catchChances[0]);
266
+ putValue(LARGE_ICON_KEY, chance.getIcon());
267
+ timer.setInitialDelay(chance.getTime());
268
+ timer.restart();
269
+ }
270
+ });
271
+ timer.setRepeats(false);
272
+ timer.start();
273
+ }
274
+ private CatchChance getChance() {
275
+ int v = random.nextInt(totalRatio);
276
+ int i = 1;
277
+ while(v>=catchChances[i].getRatio()) v-=catchChances[i++].getRatio();
278
+ return catchChances[i];
279
+ }
280
+ void stop() {
281
+ if(timer != null) {
282
+ timer.stop();
283
+ timer = null;
284
+ }
285
+ }
286
+ @Override
287
+ public void actionPerformed(ActionEvent e) {
288
+ Fish fish = chance.getFish();
289
+ if(fish != null && listener != null) {
290
+ stop();
291
+ listener.onCatch(fish);
292
+ }
293
+ }
294
+ }
295
+ /** 釣り上げパネル */
296
+ private class CatchPanel extends JPanel {
297
+ private JLabel imageLabel;
298
+ CatchPanel() {
299
+ JButton returnButton = new JButton("もどる");
300
+ returnButton.setBounds(280, 650, 130, 30);
301
+ returnButton.addActionListener(e -> {
302
+ if(alltime < 60000) {
303
+ showGamePanel();
304
+ } else {
305
+ //game end
306
+ }
307
+ });
308
+ add(returnButton);
309
+
310
+ imageLabel = new JLabel();
311
+ imageLabel.setBounds(150, 200, 400, 400);
312
+ add(imageLabel);
313
+
314
+ JLabel catchLabel = new JLabel("釣り上げた!");
315
+ catchLabel.setBounds(305, 120, 100, 100);
316
+ add(catchLabel);
317
+ }
318
+ void setFish(Fish fish) {
319
+ imageLabel.setIcon(fish.getIcon());
320
+ }
321
+ }
322
+ }
323
+ ```