回答編集履歴

1

fix

2023/02/18 23:17

投稿

退会済みユーザー
test CHANGED
@@ -1,27 +1,298 @@
1
1
  ```
2
+ def move(self):
3
+ global value
4
+
5
+ if self.exist:
6
+ if value % 2 == 0:
7
+ self.x += Enemy_Move_Space_X
8
+ print('0')
9
+ #time.sleep(1)
10
+ value += 1
11
+ else:
12
+ self.x -= Enemy_Move_Space_X
13
+ print('1')
14
+ #time.sleep(1)
15
+ value += 1
16
+
17
+ #画像位置の変更
18
+ cv.coords(self.id, self.x, self.y)
19
+ #処理を遅らせる
20
+ root.after(1000, Enemy.move)
21
+ ```
22
+ ここの一番下の
23
+ 「root.after(1000, Enemy.move)」
24
+
25
+ 「root.after(1000, self.move)」
26
+ に変えてください。
27
+
28
+ 修正後の全部のコード
29
+ ```
30
+ import tkinter as tk
31
+ import random
2
- import tkinter
32
+ import time
3
-
4
-
33
+
5
- value=0
34
+ value = 0
35
+
6
-
36
+ #ウィンドウの横幅
7
-
37
+ Window_Width = 600
38
+ #ウィンドウの縦幅
39
+ Window_Height = 600
40
+
41
+ Cannon_Y = 550
42
+
43
+ Enemy_Space_X = 100
44
+ Enemy_Space_Y = 60
45
+ Enemy_Move_Space_X = 20
46
+ Enemy_Move_Speed = 2000
47
+ Number_Of_Enemy = 18
48
+ Enemy_Shoot_Interval = 200
49
+
50
+ Collision_Detection = 300
51
+
52
+ Bullet_Height = 10
53
+ Bullet_Width = 2
54
+ Bullet_Speed = 10
55
+
56
+ Text_Good_Size = 10
57
+ Text_Congratulations_Size = 50
58
+ Text_GameClear_Size = 60
59
+ Text_GameOver_Size = 90
60
+
61
+ #砲台を設定するクラスの定義
62
+ class Cannon:
63
+ #__init__=クラスのインスタンスの生成時自動呼出しされるメソッド
64
+ def __init__(self, x, y=Cannon_Y): #self=インスタンスを指し示す
65
+ #
66
+ self.x = x
67
+ self.y = y
68
+ #self.=Class Cannonの中のメソッドを使う
69
+ self.draw()
70
+ self.bind()
71
+
72
+ #画像の設置
73
+ def draw(self):
74
+ #tag=設置したイラストに名前を付ける
75
+ self.id = cv.create_image(self.x,self.y,image=cannon_Image,tag="cannon")
76
+
77
+ #画像にイベントを作成
78
+ def bind(self):
79
+ #ButtonPress-3=右クリック
80
+ cv.tag_bind(self.id, "<ButtonPress-3>", self.pressed)
81
+ #Button1-Motion=ウィジェット内でカーソルが動いたとき
82
+ cv.tag_bind(self.id, "<Motion>", self.dragged)
83
+
84
+ #キャンバス上で右クリックを押したときのイベントメソッド
85
+ def pressed(self, event):
86
+ #クラスMyBulletのインスタンスを作成
87
+ mybullet = MyBullet(event.x, self.y)
88
+ #クラスMyBulletのdrawメソッド
89
+ mybullet.draw()
90
+ #クラスMyBulletのshootメソッド
91
+ mybullet.shoot()
92
+
93
+ #キャンバス上でカーソルが動いた時のイベントメソッド
94
+ def dragged(self, event):
95
+ #event=イベントの
96
+ dx = event.x - self.x
97
+ #coords=指定した画像の座標の変更や情報の取得
98
+ self.x, self.y = cv.coords(self.id)
99
+ #coords(画像の指定, x座標, y座標)
100
+ cv.coords(self.id, self.x+dx, self.y)
101
+ self.x = event.x
102
+
103
+ def destroy(self):
104
+ #delete=指定した画像の消去
105
+ cv.delete(self.id)
106
+
107
+ #発射する弾のクラス
108
+ class MyBullet:
109
+ #最初に読み込まれるメソッドは__init__とするルールがある
110
+ def __init__(self, x, y):
111
+ self.x = x
112
+ self.y = y
113
+
114
+ #画像の設置
115
+ def draw(self):
116
+ #rectangle=長方形の設置(左上の座標,右下の座標,色の指定)
117
+ self.id = cv.create_rectangle(self.x-Bullet_Width, self.y+Bullet_Height, self.x+Bullet_Width, self.y-Bullet_Height, fill="blue")
118
+
8
- def Roop():
119
+ def shoot(self):
9
-
120
+ if self.y >= 0:
121
+ #move=画像の移動(画像の指定,移動するx座標,移動するy座標)
122
+ cv.move(self.id, 0, -Bullet_Height)
123
+ self.y -= Bullet_Height
124
+ #同じクラスのメソッドdefeatを使用
125
+ self.defeat()
126
+ #after=処理を遅らせる(遅らせる秒数,経過後に実行するメソッド)
127
+ root.after(Bullet_Speed, self.shoot)
128
+
129
+ def defeat(self):
130
+ for enemy in enemies:
131
+ if ((self.x-enemy.x)**2+(self.y-enemy.y)**2) < Collision_Detection:
132
+ #existをFalseに
133
+ enemy.exist = False
134
+ #クラスenemyのメソッドdestroy
135
+ enemy.destroy()
136
+ #create_text=テキストの作成
137
+ cv.create_text(enemy.x, enemy.y, text="good!", fill="cyan", font=("System", Text_Good_Size), tag="good")
138
+
139
+ def destroy(self):
140
+ #画像の消去
141
+ cv.delete(self.id)
142
+
143
+
144
+ #敵のクラス
145
+ class Enemy:
146
+ #クラスのインスタンス生成時に起動
147
+ def __init__(self, x, y):
148
+ self.x = x % Window_Width
149
+ self.y = y+x//Window_Width*Enemy_Space_X
150
+ #existをtrueに
151
+ self.exist = True
152
+ #同じクラスのメソッドdraw
153
+ self.draw()
154
+ #同じクラスのメソッドmove
155
+ self.move()
156
+
157
+ def draw(self):
158
+ #画像の設置
159
+ self.id = cv.create_image(self.x, self.y, image=crab_Image, tag="enemy")
160
+
161
+ def enemy_shoot(self):
162
+ if self.exist:
163
+ #クラスEnemyBulletのインスタンス生成
164
+ enemybullet = EnemyBullet(self.x, self.y)
165
+ #クラスEnemyBulletのメソッドdraw
166
+ enemybullet.draw()
167
+ #クラスEnemyBulletのメソッドshoot
168
+ enemybullet.shoot()
169
+
170
+ def move(self):
171
+ global value
172
+
173
+ if self.exist:
174
+ if value % 2 == 0:
175
+ self.x += Enemy_Move_Space_X
176
+ print('0')
177
+ #time.sleep(1)
178
+ value += 1
179
+ else:
180
+ self.x -= Enemy_Move_Space_X
181
+ print('1')
182
+ #time.sleep(1)
183
+ value += 1
184
+
185
+ #画像位置の変更
186
+ cv.coords(self.id, self.x, self.y)
187
+ #処理を遅らせる
188
+ # root.after(1000, Enemy.move)
189
+ root.after(1000, self.move)
190
+
191
+ def destroy(self):
192
+ #画像の消去
193
+ cv.delete(self.id)
194
+
195
+ #敵の弾のクラス
196
+ class EnemyBullet:
197
+ #クラスのインスタンス作成時に起動するメソッド
198
+ def __init__(self, x, y):
199
+ self.x = x
200
+ self.y = y
201
+
202
+ def draw(self):
203
+ #長方形の生成
204
+ self.id = cv.create_rectangle(self.x-Bullet_Width, self.y+Bullet_Height, self.x+Bullet_Width, self.y-Bullet_Height,fill="red")
205
+
206
+ def shoot(self):
207
+ if self.y <= Window_Height:
208
+ #画像の移動
209
+ cv.move(self.id, 0, Bullet_Height)
210
+ self.y += Bullet_Height
211
+ #同じクラスのメソッドcollision
212
+ self.collision()
213
+ #処理を遅らせる
214
+ root.after(Bullet_Speed, self.shoot)
215
+
216
+ def collision(self):
217
+ if ((self.x-cannon.x)**2+(self.y-cannon.y)**2) < Collision_Detection:
218
+ #gameoverメソッド
219
+ gameover()
220
+
221
+ def destroy(self):
222
+ #画像の消去
223
+ cv.delete(self.id)
224
+
225
+ def gameclear():
226
+ winflag = 0
227
+ for enemy in enemies:
228
+ #敵を倒すたびに数が+1される
229
+ if enemy.exist == False:
230
+ winflag += 1
231
+
232
+ #倒した敵の数が敵の総数と同じ場合
233
+ if winflag == Number_Of_Enemy:
234
+ #good!のテキストを削除
235
+ cv.delete("good")
236
+ #Congratulation!テキストの作成
237
+ cv.create_text(Window_Width//2, Window_Height//2-80, text="Congratulation!",fill="lime", font=("System", Text_Congratulations_Size))
238
+ #GameClear!テキストの作成
239
+ cv.create_text(Window_Width//2, Window_Height//2+20, text="GAME CREAR!", fill="lime", font=("System", Text_GameClear_Size))
240
+
241
+ def gameover():
242
+ #画像cannon, goodの削除
243
+ cv.delete("cannon", "good")
244
+ #GameOverテキストの作成
245
+ cv.create_text(Window_Width//2, Window_Height//2, text="GAME OVER", fill="red", font=("System", Text_GameOver_Size))
246
+
247
+ def enemy_randomshoot():
248
+ #ランダムに配列enemiesから選ぶ
249
+ enemy = random.choice(enemies)
250
+ #メソッドenemy_shoot
251
+ enemy.enemy_shoot()
252
+ #処理を遅らせる
253
+ root.after(Enemy_Shoot_Interval, enemy_randomshoot)
254
+
255
+ def numberplus():
10
256
  global value
11
- if value % 2 == 0:
12
- print('0') #処理A
13
- value += 1
257
+ value = value + 1
14
- else:
258
+
15
- print('1') #処理B
259
+ if __name__ == '__main__':
16
- value += 1
260
+ #初期画面の作成
17
- root.after(1000, Roop)
18
-
19
- root = tkinter.Tk()
261
+ root = tk.Tk()
262
+ #タイトルの設定
20
- root.geometry("300x200")
263
+ root.title('shootingNeo')
21
-
264
+ #キャンバスの作成
22
-
265
+ cv = tk.Canvas(root, width=Window_Width, height=Window_Height, bg='black')
266
+ #キャンバスの設置
267
+ cv.pack()
268
+
269
+ #砲台の画像の読み込み
270
+ cannon_Image = tk.PhotoImage(file="canon.png")
271
+ #敵の画像の読み込み
272
+ crab_Image = tk.PhotoImage(file="crab.png")
273
+
274
+ #メニューバーの作成
275
+ menubar = tk.Menu(root)
276
+ #ウィンドウの属性を変更
277
+ root.configure(menu=menubar)
278
+ #ウィンドウに子メニューを追加・設定
279
+ menubar.add_command(label="Quit", underline=0, command=root.quit)
280
+
281
+ #クラスCannonのインスタンスを生成
282
+ cannon = Cannon(Window_Width//2, Cannon_Y)
283
+
284
+ #enemy = Enemy()
23
- root.after(1000, Roop)
285
+ #root.after(1000, enemy.move)
286
+
24
-
287
+ #for文の中を回すための配列
25
-
288
+ enemies = []
289
+
290
+ for i in range(Number_Of_Enemy):
291
+ enemy_i = Enemy(i*Enemy_Space_X+50, Enemy_Space_Y)
292
+ enemies.append(enemy_i)
293
+
294
+ #root.after(1000, Enemy.move)
295
+
296
+ #GUIアプリの表示
26
- root.mainloop()
297
+ root.mainloop()
27
- ```
298
+ ```