質問編集履歴
3
ソースコードの追加
test
CHANGED
File without changes
|
test
CHANGED
@@ -105,3 +105,280 @@
|
|
105
105
|
何分このような場所で質問することは初めてなので、
|
106
106
|
足りない点至らない点あるとは思いますが
|
107
107
|
何卒よろしくお願いいたします。
|
108
|
+
|
109
|
+
### コメントを受けての使用したソースコード全体
|
110
|
+
```Python
|
111
|
+
import tkinter as tk
|
112
|
+
import random
|
113
|
+
import time
|
114
|
+
|
115
|
+
value = 0
|
116
|
+
|
117
|
+
#ウィンドウの横幅
|
118
|
+
Window_Width = 600
|
119
|
+
#ウィンドウの縦幅
|
120
|
+
Window_Height = 600
|
121
|
+
|
122
|
+
Cannon_Y = 550
|
123
|
+
|
124
|
+
Enemy_Space_X = 100
|
125
|
+
Enemy_Space_Y = 60
|
126
|
+
Enemy_Move_Space_X = 20
|
127
|
+
Enemy_Move_Speed = 2000
|
128
|
+
Number_Of_Enemy = 18
|
129
|
+
Enemy_Shoot_Interval = 200
|
130
|
+
|
131
|
+
Collision_Detection = 300
|
132
|
+
|
133
|
+
Bullet_Height = 10
|
134
|
+
Bullet_Width = 2
|
135
|
+
Bullet_Speed = 10
|
136
|
+
|
137
|
+
Text_Good_Size = 10
|
138
|
+
Text_Congratulations_Size = 50
|
139
|
+
Text_GameClear_Size = 60
|
140
|
+
Text_GameOver_Size = 90
|
141
|
+
|
142
|
+
#砲台を設定するクラスの定義
|
143
|
+
class Cannon:
|
144
|
+
#__init__=クラスのインスタンスの生成時自動呼出しされるメソッド
|
145
|
+
def __init__(self, x, y=Cannon_Y): #self=インスタンスを指し示す
|
146
|
+
#
|
147
|
+
self.x = x
|
148
|
+
self.y = y
|
149
|
+
#self.=Class Cannonの中のメソッドを使う
|
150
|
+
self.draw()
|
151
|
+
self.bind()
|
152
|
+
|
153
|
+
#画像の設置
|
154
|
+
def draw(self):
|
155
|
+
#tag=設置したイラストに名前を付ける
|
156
|
+
self.id = cv.create_image(self.x,self.y,image=cannon_Image,tag="cannon")
|
157
|
+
|
158
|
+
#画像にイベントを作成
|
159
|
+
def bind(self):
|
160
|
+
#ButtonPress-3=右クリック
|
161
|
+
cv.tag_bind(self.id, "<ButtonPress-3>", self.pressed)
|
162
|
+
#Button1-Motion=ウィジェット内でカーソルが動いたとき
|
163
|
+
cv.tag_bind(self.id, "<Motion>", self.dragged)
|
164
|
+
|
165
|
+
#キャンバス上で右クリックを押したときのイベントメソッド
|
166
|
+
def pressed(self, event):
|
167
|
+
#クラスMyBulletのインスタンスを作成
|
168
|
+
mybullet = MyBullet(event.x, self.y)
|
169
|
+
#クラスMyBulletのdrawメソッド
|
170
|
+
mybullet.draw()
|
171
|
+
#クラスMyBulletのshootメソッド
|
172
|
+
mybullet.shoot()
|
173
|
+
|
174
|
+
#キャンバス上でカーソルが動いた時のイベントメソッド
|
175
|
+
def dragged(self, event):
|
176
|
+
#event=イベントの
|
177
|
+
dx = event.x - self.x
|
178
|
+
#coords=指定した画像の座標の変更や情報の取得
|
179
|
+
self.x, self.y = cv.coords(self.id)
|
180
|
+
#coords(画像の指定, x座標, y座標)
|
181
|
+
cv.coords(self.id, self.x+dx, self.y)
|
182
|
+
self.x = event.x
|
183
|
+
|
184
|
+
def destroy(self):
|
185
|
+
#delete=指定した画像の消去
|
186
|
+
cv.delete(self.id)
|
187
|
+
|
188
|
+
#発射する弾のクラス
|
189
|
+
class MyBullet:
|
190
|
+
#最初に読み込まれるメソッドは__init__とするルールがある
|
191
|
+
def __init__(self, x, y):
|
192
|
+
self.x = x
|
193
|
+
self.y = y
|
194
|
+
|
195
|
+
#画像の設置
|
196
|
+
def draw(self):
|
197
|
+
#rectangle=長方形の設置(左上の座標,右下の座標,色の指定)
|
198
|
+
self.id = cv.create_rectangle(self.x-Bullet_Width, self.y+Bullet_Height, self.x+Bullet_Width, self.y-Bullet_Height, fill="blue")
|
199
|
+
|
200
|
+
def shoot(self):
|
201
|
+
if self.y >= 0:
|
202
|
+
#move=画像の移動(画像の指定,移動するx座標,移動するy座標)
|
203
|
+
cv.move(self.id, 0, -Bullet_Height)
|
204
|
+
self.y -= Bullet_Height
|
205
|
+
#同じクラスのメソッドdefeatを使用
|
206
|
+
self.defeat()
|
207
|
+
#after=処理を遅らせる(遅らせる秒数,経過後に実行するメソッド)
|
208
|
+
root.after(Bullet_Speed, self.shoot)
|
209
|
+
|
210
|
+
def defeat(self):
|
211
|
+
for enemy in enemies:
|
212
|
+
if ((self.x-enemy.x)**2+(self.y-enemy.y)**2) < Collision_Detection:
|
213
|
+
#existをFalseに
|
214
|
+
enemy.exist = False
|
215
|
+
#クラスenemyのメソッドdestroy
|
216
|
+
enemy.destroy()
|
217
|
+
#create_text=テキストの作成
|
218
|
+
cv.create_text(enemy.x, enemy.y, text="good!", fill="cyan", font=("System", Text_Good_Size), tag="good")
|
219
|
+
|
220
|
+
def destroy(self):
|
221
|
+
#画像の消去
|
222
|
+
cv.delete(self.id)
|
223
|
+
|
224
|
+
|
225
|
+
#敵のクラス
|
226
|
+
class Enemy:
|
227
|
+
#クラスのインスタンス生成時に起動
|
228
|
+
def __init__(self, x, y):
|
229
|
+
self.x = x % Window_Width
|
230
|
+
self.y = y+x//Window_Width*Enemy_Space_X
|
231
|
+
#existをtrueに
|
232
|
+
self.exist = True
|
233
|
+
#同じクラスのメソッドdraw
|
234
|
+
self.draw()
|
235
|
+
#同じクラスのメソッドmove
|
236
|
+
self.move()
|
237
|
+
|
238
|
+
def draw(self):
|
239
|
+
#画像の設置
|
240
|
+
self.id = cv.create_image(self.x, self.y, image=crab_Image, tag="enemy")
|
241
|
+
|
242
|
+
def enemy_shoot(self):
|
243
|
+
if self.exist:
|
244
|
+
#クラスEnemyBulletのインスタンス生成
|
245
|
+
enemybullet = EnemyBullet(self.x, self.y)
|
246
|
+
#クラスEnemyBulletのメソッドdraw
|
247
|
+
enemybullet.draw()
|
248
|
+
#クラスEnemyBulletのメソッドshoot
|
249
|
+
enemybullet.shoot()
|
250
|
+
|
251
|
+
def move(self):
|
252
|
+
global value
|
253
|
+
|
254
|
+
if self.exist:
|
255
|
+
if value % 2 == 0:
|
256
|
+
#self.x += Enemy_Move_Space_X
|
257
|
+
print('0')
|
258
|
+
#time.sleep(1)
|
259
|
+
value += 1
|
260
|
+
else:
|
261
|
+
#self.x -= Enemy_Move_Space_X
|
262
|
+
print('1')
|
263
|
+
#time.sleep(1)
|
264
|
+
value += 1
|
265
|
+
|
266
|
+
#画像位置の変更
|
267
|
+
cv.coords(self.id, self.x, self.y)
|
268
|
+
#処理を遅らせる
|
269
|
+
root.after(1000, Enemy.move)
|
270
|
+
|
271
|
+
def destroy(self):
|
272
|
+
#画像の消去
|
273
|
+
cv.delete(self.id)
|
274
|
+
|
275
|
+
#敵の弾のクラス
|
276
|
+
class EnemyBullet:
|
277
|
+
#クラスのインスタンス作成時に起動するメソッド
|
278
|
+
def __init__(self, x, y):
|
279
|
+
self.x = x
|
280
|
+
self.y = y
|
281
|
+
|
282
|
+
def draw(self):
|
283
|
+
#長方形の生成
|
284
|
+
self.id = cv.create_rectangle(self.x-Bullet_Width, self.y+Bullet_Height, self.x+Bullet_Width, self.y-Bullet_Height,fill="red")
|
285
|
+
|
286
|
+
def shoot(self):
|
287
|
+
if self.y <= Window_Height:
|
288
|
+
#画像の移動
|
289
|
+
cv.move(self.id, 0, Bullet_Height)
|
290
|
+
self.y += Bullet_Height
|
291
|
+
#同じクラスのメソッドcollision
|
292
|
+
self.collision()
|
293
|
+
#処理を遅らせる
|
294
|
+
root.after(Bullet_Speed, self.shoot)
|
295
|
+
|
296
|
+
def collision(self):
|
297
|
+
if ((self.x-cannon.x)**2+(self.y-cannon.y)**2) < Collision_Detection:
|
298
|
+
#gameoverメソッド
|
299
|
+
gameover()
|
300
|
+
|
301
|
+
def destroy(self):
|
302
|
+
#画像の消去
|
303
|
+
cv.delete(self.id)
|
304
|
+
|
305
|
+
def gameclear():
|
306
|
+
winflag = 0
|
307
|
+
for enemy in enemies:
|
308
|
+
#敵を倒すたびに数が+1される
|
309
|
+
if enemy.exist == False:
|
310
|
+
winflag += 1
|
311
|
+
|
312
|
+
#倒した敵の数が敵の総数と同じ場合
|
313
|
+
if winflag == Number_Of_Enemy:
|
314
|
+
#good!のテキストを削除
|
315
|
+
cv.delete("good")
|
316
|
+
#Congratulation!テキストの作成
|
317
|
+
cv.create_text(Window_Width//2, Window_Height//2-80, text="Congratulation!",fill="lime", font=("System", Text_Congratulations_Size))
|
318
|
+
#GameClear!テキストの作成
|
319
|
+
cv.create_text(Window_Width//2, Window_Height//2+20, text="GAME CREAR!", fill="lime", font=("System", Text_GameClear_Size))
|
320
|
+
|
321
|
+
def gameover():
|
322
|
+
#画像cannon, goodの削除
|
323
|
+
cv.delete("cannon", "good")
|
324
|
+
#GameOverテキストの作成
|
325
|
+
cv.create_text(Window_Width//2, Window_Height//2, text="GAME OVER", fill="red", font=("System", Text_GameOver_Size))
|
326
|
+
|
327
|
+
def enemy_randomshoot():
|
328
|
+
#ランダムに配列enemiesから選ぶ
|
329
|
+
enemy = random.choice(enemies)
|
330
|
+
#メソッドenemy_shoot
|
331
|
+
enemy.enemy_shoot()
|
332
|
+
#処理を遅らせる
|
333
|
+
root.after(Enemy_Shoot_Interval, enemy_randomshoot)
|
334
|
+
|
335
|
+
def numberplus():
|
336
|
+
global value
|
337
|
+
value = value + 1
|
338
|
+
|
339
|
+
if __name__ == '__main__':
|
340
|
+
#初期画面の作成
|
341
|
+
root = tk.Tk()
|
342
|
+
#タイトルの設定
|
343
|
+
root.title('shootingNeo')
|
344
|
+
#キャンバスの作成
|
345
|
+
cv = tk.Canvas(root, width=Window_Width, height=Window_Height, bg='black')
|
346
|
+
#キャンバスの設置
|
347
|
+
cv.pack()
|
348
|
+
|
349
|
+
#砲台の画像の読み込み
|
350
|
+
cannon_Image = tk.PhotoImage(file="canon.png")
|
351
|
+
#敵の画像の読み込み
|
352
|
+
crab_Image = tk.PhotoImage(file="crab.png")
|
353
|
+
|
354
|
+
#メニューバーの作成
|
355
|
+
menubar = tk.Menu(root)
|
356
|
+
#ウィンドウの属性を変更
|
357
|
+
root.configure(menu=menubar)
|
358
|
+
#ウィンドウに子メニューを追加・設定
|
359
|
+
menubar.add_command(label="Quit", underline=0, command=root.quit)
|
360
|
+
|
361
|
+
#クラスCannonのインスタンスを生成
|
362
|
+
cannon = Cannon(Window_Width//2, Cannon_Y)
|
363
|
+
|
364
|
+
#enemy = Enemy()
|
365
|
+
#root.after(1000, enemy.move)
|
366
|
+
|
367
|
+
#for文の中を回すための配列
|
368
|
+
enemies = []
|
369
|
+
|
370
|
+
for i in range(Number_Of_Enemy):
|
371
|
+
enemy_i = Enemy(i*Enemy_Space_X+50, Enemy_Space_Y)
|
372
|
+
enemies.append(enemy_i)
|
373
|
+
|
374
|
+
#root.after(1000, Enemy.move)
|
375
|
+
|
376
|
+
#GUIアプリの表示
|
377
|
+
root.mainloop()
|
378
|
+
```
|
379
|
+
となります。問題のRoopメソッドが名前は変わりますが141行目のEnemyクラスのmoveメソッドです。
|
380
|
+
メソッドを呼び出している行が126行目、159行目となります。
|
381
|
+
※こちらのソースコードはサイト様(https://qiita.com/ell/items/f0f74865c07710f1eab8
|
382
|
+
)を参考にしていろいろと改変して練習しているものです。
|
383
|
+
※コメントアウトされているコードは試行錯誤したものが残っているものです。重要性は低いです。
|
384
|
+
|
2
コメントを受けての補足を追加
test
CHANGED
File without changes
|
test
CHANGED
@@ -77,3 +77,31 @@
|
|
77
77
|
皆皆様に比べればまだまだ若輩者ではありますが、
|
78
78
|
どうかお力添えをお願い申し上げます。
|
79
79
|
|
80
|
+
### コメントを受けての補足
|
81
|
+
TakaiY さん
|
82
|
+
コメントありがとうございます。
|
83
|
+
確かにどこで呼び出しているかわかりづらかったですよね。
|
84
|
+
思慮が足りず申し訳ないです。
|
85
|
+
実際に呼び出しているのは下記のような形です。
|
86
|
+
```Python
|
87
|
+
class OtamesiRoop:
|
88
|
+
def __init__(self):
|
89
|
+
self.Roop()
|
90
|
+
|
91
|
+
def Roop():
|
92
|
+
global value
|
93
|
+
if value % 2 == 0:
|
94
|
+
print('0') #処理A
|
95
|
+
value += 1
|
96
|
+
else:
|
97
|
+
print('1') #処理B
|
98
|
+
value += 1
|
99
|
+
root.after(1000, Roop)
|
100
|
+
```
|
101
|
+
のような形です。
|
102
|
+
使用したクラス自体はroot.mainloop()の1行上で
|
103
|
+
otamesi = OtamesiRoop()
|
104
|
+
とインスタンス化してます。
|
105
|
+
何分このような場所で質問することは初めてなので、
|
106
|
+
足りない点至らない点あるとは思いますが
|
107
|
+
何卒よろしくお願いいたします。
|
1
街頭のソースコードという文言がわかりにくかったので修正しました
test
CHANGED
File without changes
|
test
CHANGED
@@ -25,7 +25,7 @@
|
|
25
25
|
※ただコードがどういう動きをしているか確かめている間は実際したかった処理A・Bをコメントアウトした後、
|
26
26
|
処理A・Bにprintを追記して動かしています
|
27
27
|
|
28
|
-
### 該当のソースコード
|
28
|
+
### 該当のソースコード※この中にやってみたことが書いてあります
|
29
29
|
|
30
30
|
```Python
|
31
31
|
#パターン1
|