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

回答編集履歴

2

少し修正

2018/01/04 16:03

投稿

退会済みユーザー
answer CHANGED
@@ -139,6 +139,7 @@
139
139
  @Override
140
140
  public void actionPerformed(ActionEvent e) {
141
141
  callCounter++;
142
+ if (hitObject) hitObject = false;
142
143
  long pastTime = System.currentTimeMillis() - startTime;
143
144
  if (pastTime >= TIMEUP) {
144
145
  timer.stop();

1

コードの追加

2018/01/04 16:02

投稿

退会済みユーザー
answer CHANGED
@@ -8,4 +8,254 @@
8
8
  - ゲームの状態を管理するには、「開始待ち」「ゲーム中」「結果表示中」など、自分のゲームに合わせたステートの管理が重要です。ステートによって、どういう画面を判断します。
9
9
  - ゲームの開始は、ボタンではなく、タイトル画面クリックにしてはどうでしょう。
10
10
 
11
- 楽しいゲームを作ってくださいね。
11
+ 楽しいゲームを作ってくださいね。
12
+ ---
13
+ 我慢できず作ってみました。コメントも少し入れました。
14
+ 調整不十分ですけど、だいたいこんな感じでいかがですか。
15
+ あとは適当にいじり倒してください。
16
+ ```java
17
+ import java.awt.Dimension;
18
+ import java.awt.Graphics;
19
+ import java.awt.Image;
20
+ import java.awt.Point;
21
+ import java.awt.Rectangle;
22
+ import java.awt.event.ActionEvent;
23
+ import java.awt.event.ActionListener;
24
+ import java.awt.event.MouseAdapter;
25
+ import java.awt.event.MouseEvent;
26
+ import java.io.FileInputStream;
27
+ import java.io.IOException;
28
+ import java.util.ArrayList;
29
+ import java.util.Random;
30
+
31
+ import javax.imageio.ImageIO;
32
+ import javax.swing.JFrame;
33
+ import javax.swing.JPanel;
34
+ import javax.swing.Timer;
35
+
36
+ public class WaniWaniPanic extends JFrame {
37
+ public WaniWaniPanic() {
38
+ super("わにわにパニック");
39
+ setContentPane(new WaniPaniCanvas());
40
+ pack();
41
+ setDefaultCloseOperation(EXIT_ON_CLOSE);
42
+ setResizable(false);
43
+ setVisible(true);
44
+ }
45
+
46
+ public static void main(String[] args) {
47
+ new WaniWaniPanic();
48
+ }
49
+ }
50
+
51
+ class WaniPaniCanvas extends JPanel {
52
+
53
+ private static final long serialVersionUID = 1L;
54
+
55
+ static final int START_WAITING = 0;
56
+ static final int PLAYING = 1;
57
+ static final int ENDING = 2;
58
+
59
+ static final int IMG_TITLE = 0;
60
+ static final int IMG_WANI_NORMAL = 1;
61
+ static final int IMG_WANI_DAMAGED = 2;
62
+ static final int IMG_BOMB_NORMAL = 3;
63
+ static final int IMG_BOMB_BOMB = 4;
64
+ static final int IMG_ENDING = 5;
65
+
66
+ static final int WANI_SELECTED = 0;
67
+ static final int BOMB_SELECTED = 1;
68
+
69
+ static final int SPEED_LOW = 3;
70
+ static final int SPEED_MIDDLE = 2;
71
+ static final int SPEED_HIGH = 1;
72
+
73
+ static final String IMG_NAMES[] = { // 適当に画像作ってください。
74
+ "title.png", //640 x 480
75
+ "wani_normal.png", //70 x 70
76
+ "wani_damaged.png", //70 x 70
77
+ "bomb_normal.png", //70 x 70
78
+ "bomb_bomb.png", //70 x 70
79
+ "ending.png" //640 x 480
80
+ };
81
+
82
+ static final int TIMER_INTERVAL = 400; //タイマー処理の間隔 0.4秒
83
+ static final int TIMEUP = 60000; //タイムアップまでの時間 60秒
84
+
85
+ static final int CANVAS_WIDTH = 640;
86
+ static final int CANVAS_HEIGHT = 480;
87
+
88
+ static final int OBJECT_WIDTH = 70; // ワニやボム画像の幅
89
+ static final int OBJECT_HEIGHT = 70; // ワニやボム画像の高さ
90
+
91
+ static final Point LOCATION[] = { // 出現位置
92
+ new Point( 50, 150),
93
+ new Point(150, 150),
94
+ new Point(250, 150),
95
+ new Point(350, 150),
96
+ new Point(450, 150),
97
+ new Point(550, 150)
98
+ };
99
+
100
+ static final ArrayList<Image> images = new ArrayList<Image>();
101
+
102
+ static {
103
+ loadGameImages();
104
+ }
105
+
106
+ static void loadGameImages() {
107
+ for (String name : IMG_NAMES) {
108
+ try {
109
+ FileInputStream in = new FileInputStream(name);
110
+ Image img = ImageIO.read(in);
111
+ images.add(img);
112
+ in.close();
113
+ } catch (IOException ex) {
114
+ System.err.println("画像ファイル " + name + " が存在しません。");
115
+ System.exit(1);
116
+ }
117
+ }
118
+ }
119
+
120
+ final GameState gameStates[] = {
121
+ new StartWaiting(),
122
+ new Playing(),
123
+ new Ending()
124
+ };
125
+
126
+ private int currentState = START_WAITING;
127
+ private int bestScore = 0;
128
+ private int score = 0;
129
+ private boolean overBest = false; // ハイスコアをとったらtrue
130
+ private long startTime = 0L;
131
+ private int selectedLocation = 0; // ランダムで選択した出現位置
132
+ private int selectedObject = 0; // ランダムで選択した出現オブジェクト
133
+ private int callCounter = 0;
134
+ private boolean hitObject = false;
135
+
136
+ private Random random = new Random(System.currentTimeMillis());
137
+
138
+ private Timer timer = new Timer(TIMER_INTERVAL, new ActionListener() {
139
+ @Override
140
+ public void actionPerformed(ActionEvent e) {
141
+ callCounter++;
142
+ long pastTime = System.currentTimeMillis() - startTime;
143
+ if (pastTime >= TIMEUP) {
144
+ timer.stop();
145
+ currentState = ENDING;
146
+ if (score > bestScore) {
147
+ bestScore = score;
148
+ overBest = true;
149
+ }
150
+ } else if (pastTime <= TIMEUP * 0.2) {
151
+ if (callCounter % SPEED_LOW != 0) return;
152
+ } else if (pastTime <= TIMEUP * 0.85) {
153
+ if (callCounter % SPEED_MIDDLE != 0) return;
154
+ }
155
+
156
+ int loc = 0;
157
+ while ((loc = selectLocation()) == selectedLocation);
158
+
159
+ selectedLocation = loc;
160
+ selectedObject = selectObject();
161
+
162
+ WaniPaniCanvas.this.repaint();
163
+ }
164
+
165
+ private int selectLocation() {
166
+ return Math.abs(random.nextInt()) % LOCATION.length;
167
+ }
168
+
169
+ private int selectObject() {
170
+ int n = Math.abs(random.nextInt()) % 10;
171
+ if (n == 0) return BOMB_SELECTED;
172
+ else return WANI_SELECTED;
173
+ }
174
+ });
175
+
176
+ public WaniPaniCanvas() {
177
+ setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
178
+ addMouseListener(new MouseAdapter() {
179
+ @Override
180
+ public void mouseClicked(MouseEvent e) {
181
+ gameStates[currentState].mouseClicked(e);
182
+ }
183
+ });
184
+ }
185
+
186
+ public void paint(Graphics g) {
187
+ gameStates[currentState].paint(g);
188
+ }
189
+
190
+ interface GameState {
191
+ public void paint(Graphics g);
192
+ public void mouseClicked(MouseEvent e);
193
+ }
194
+
195
+ class StartWaiting implements GameState {
196
+ public void paint(Graphics g) {
197
+ g.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
198
+ Image img = images.get(IMG_TITLE);
199
+ g.drawImage(img, 0, 0, WaniPaniCanvas.this);
200
+ }
201
+
202
+ public void mouseClicked(MouseEvent e) {
203
+ // タイトル画面をクリックしたらゲームスタート
204
+ score = 0;
205
+ overBest = false;
206
+ selectedLocation = 0;
207
+ selectedObject = 0;
208
+ callCounter = 0;
209
+ hitObject = false;
210
+ startTime = System.currentTimeMillis();
211
+ currentState = PLAYING;
212
+ timer.start();
213
+ WaniPaniCanvas.this.repaint();
214
+ }
215
+ }
216
+
217
+ class Playing implements GameState {
218
+ public void paint(Graphics g) {
219
+ g.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
220
+ int index = IMG_WANI_NORMAL;
221
+ if (selectedObject == WANI_SELECTED && hitObject) {
222
+ index = IMG_WANI_DAMAGED;
223
+ } else if (selectedObject == BOMB_SELECTED) {
224
+ if (hitObject) index = IMG_BOMB_BOMB;
225
+ else index = IMG_BOMB_NORMAL;
226
+ }
227
+ Image img = images.get(index);
228
+ int x = LOCATION[selectedLocation].x;
229
+ int y = LOCATION[selectedLocation].y;
230
+ g.drawImage(img, x, y, WaniPaniCanvas.this);
231
+ g.drawString("得点: " + score, 10, 10);
232
+ }
233
+
234
+ public void mouseClicked(MouseEvent e) {
235
+ // 当たり判定
236
+ int x = LOCATION[selectedLocation].x;
237
+ int y = LOCATION[selectedLocation].y;
238
+ Rectangle rect = new Rectangle(x, y, OBJECT_WIDTH, OBJECT_HEIGHT);
239
+ if (rect.contains(e.getPoint())) score += 100;
240
+ WaniPaniCanvas.this.repaint();
241
+ }
242
+ }
243
+
244
+ class Ending implements GameState {
245
+ public void paint(Graphics g) {
246
+ g.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
247
+ Image img = images.get(IMG_ENDING);
248
+ g.drawImage(img, 0, 0, WaniPaniCanvas.this);
249
+ g.drawString("現在の最高得点: " + bestScore, 200, 200);
250
+ g.drawString("今回の得点: " + score, 200, 230);
251
+ if (overBest) g.drawString("ハイスコアです。おめでとう", 200, 260);
252
+ }
253
+
254
+ public void mouseClicked(MouseEvent e) {
255
+ currentState = START_WAITING;
256
+ WaniPaniCanvas.this.repaint();
257
+ }
258
+ }
259
+ }
260
+
261
+ ```