回答編集履歴
6
Nキーロールオーバーについて追記
answer
CHANGED
@@ -21,9 +21,15 @@
|
|
21
21
|
|
22
22
|
> 自機を左上に移動してるときだけ弾が発射されないのですが、これはなぜでしょうか?
|
23
23
|
|
24
|
+
■条件
|
25
|
+
・自機を左上方向に移動中
|
26
|
+
・ショットキーを押下
|
27
|
+
|
24
|
-
|
28
|
+
この時にショットキーを押下しても弾が発射されないという点ですね。
|
25
|
-
不具合ではないでしょうか、以下のprint文で正しい値が取れているのかdebugしてみてはどうでしょうか。
|
29
|
+
不具合ではないでしょうか、以下のprint文で各処理で正しい値が取れているのかdebugしてみてはどうでしょうか。
|
26
30
|
少し調査してみた限りでは、event.key == K_SPACE:のスペース押下イベントが発生してませんでした。
|
31
|
+
[キーボードの同時押しの制限(Nキーロールオーバー)に引っかかった可能性もあります](http://wikiwiki.jp/fpag/?%A5%AD%A1%BC%A5%DC%A1%BC%A5%C9%A4%CE%C6%B1%BB%FE%B2%A1%A4%B7%A4%CB%A4%C4%A4%A4%A4%C6)
|
32
|
+
|
27
33
|
あとはがんばってくださいな。
|
28
34
|
|
29
35
|
```Python
|
5
質問を読み違えていたので訂正。
answer
CHANGED
@@ -21,18 +21,16 @@
|
|
21
21
|
|
22
22
|
> 自機を左上に移動してるときだけ弾が発射されないのですが、これはなぜでしょうか?
|
23
23
|
|
24
|
-
こちらはバグですねご指摘ありがとうございます。
|
25
|
-
|
24
|
+
キーボードの左上キーを押下して移動時に弾が発射されないという点でしたね。
|
26
|
-
|
25
|
+
不具合ではないでしょうか、以下のprint文で正しい値が取れているのかdebugしてみてはどうでしょうか。
|
26
|
+
少し調査してみた限りでは、event.key == K_SPACE:のスペース押下イベントが発生してませんでした。
|
27
|
+
あとはがんばってくださいな。
|
27
28
|
|
29
|
+
```Python
|
28
|
-
|
30
|
+
import time
|
29
|
-
0. Player#moveにて自機の移動範囲を制限する。
|
30
|
-
|
31
|
+
print('Done' + str(time.perf_counter()))
|
32
|
+
```
|
31
33
|
|
32
|
-
案2で実装します。
|
33
|
-
質問文に自機の画像が無いため正確な自機のサイズはわかりませんが、
|
34
|
-
Player#moveを参考に30*30としておきます。
|
35
|
-
|
36
34
|
以下はサンプルコードです。
|
37
35
|
|
38
36
|
---
|
4
空白行を削除!
answer
CHANGED
@@ -132,7 +132,6 @@
|
|
132
132
|
enemy1.draw(screen)
|
133
133
|
# 5,bullet_listの内容をfor in ループで回す。
|
134
134
|
for bullet in bullet_list:
|
135
|
-
|
136
135
|
bullet.move()
|
137
136
|
bullet.draw()
|
138
137
|
#リストからスクリーン範囲外のbulletをクリーンアップ
|
3
Bullet#is_destroyを自機のサイズを計算するように変更、bullet説明変数を追加
answer
CHANGED
@@ -7,8 +7,36 @@
|
|
7
7
|
0. `class Bullet`を新規追加
|
8
8
|
0. 変数:`bullet_list` にて`Bullet`の生存管理をする。
|
9
9
|
|
10
|
+
---
|
10
|
-
|
11
|
+
2018/03/05 コメント欄の質問を受けて追記
|
11
12
|
|
13
|
+
> bullet = Bullet()
|
14
|
+
としていないのに
|
15
|
+
bullet.move()
|
16
|
+
bullet.draw()
|
17
|
+
が動くのはなぜですか?
|
18
|
+
|
19
|
+
これはしてますよ。処理の流れをコメント1~5で説明します。
|
20
|
+
動きが分かりづらい時は図でプログラムの動作を書いてみるといいかもです。
|
21
|
+
|
22
|
+
> 自機を左上に移動してるときだけ弾が発射されないのですが、これはなぜでしょうか?
|
23
|
+
|
24
|
+
こちらはバグですねご指摘ありがとうございます。
|
25
|
+
Bullet#is_destroyで弾の生存判定をしているのですが、
|
26
|
+
自機のサイズを計算するのを忘れてました。そのため、すぐに弾が削除対象になります。
|
27
|
+
|
28
|
+
対応方法は2案あって、
|
29
|
+
0. Player#moveにて自機の移動範囲を制限する。
|
30
|
+
0. Bullet#is_destroyで自機のサイズを計算に含める。
|
31
|
+
|
32
|
+
案2で実装します。
|
33
|
+
質問文に自機の画像が無いため正確な自機のサイズはわかりませんが、
|
34
|
+
Player#moveを参考に30*30としておきます。
|
35
|
+
|
36
|
+
以下はサンプルコードです。
|
37
|
+
|
38
|
+
---
|
39
|
+
|
12
40
|
```Python
|
13
41
|
# -*- coding: utf-8 -*-
|
14
42
|
import pygame
|
@@ -69,11 +97,12 @@
|
|
69
97
|
|
70
98
|
@property
|
71
99
|
def is_destroy(self) -> bool:
|
72
|
-
if self.bullet.x <
|
100
|
+
if self.bullet.x < -30 or self.bullet.y < - 30:
|
73
101
|
return True
|
74
102
|
return False
|
75
103
|
|
76
104
|
# 自機の位置が移動しても発射位置が追従するようにself.x/self.y ではなく self.rectを使用
|
105
|
+
# 3,Bulletクラスのインスタンス変数を生成してshoot関数の戻り値として返す
|
77
106
|
return Bullet(self.rect.x, self.rect.y)
|
78
107
|
|
79
108
|
|
@@ -90,6 +119,7 @@
|
|
90
119
|
player = Player("player.jpg", 350, 400, 5, 5)
|
91
120
|
enemy1 = Enemy("enemy.jpg", 100, 100, 5, 0)
|
92
121
|
clock = pygame.time.Clock()
|
122
|
+
# 1,リストでbulletの生存管理
|
93
123
|
bullet_list = []
|
94
124
|
|
95
125
|
while 1:
|
@@ -100,7 +130,9 @@
|
|
100
130
|
enemy1.move()
|
101
131
|
player.draw(screen)
|
102
132
|
enemy1.draw(screen)
|
133
|
+
# 5,bullet_listの内容をfor in ループで回す。
|
103
134
|
for bullet in bullet_list:
|
135
|
+
|
104
136
|
bullet.move()
|
105
137
|
bullet.draw()
|
106
138
|
#リストからスクリーン範囲外のbulletをクリーンアップ
|
@@ -113,9 +145,12 @@
|
|
113
145
|
pygame.quit()
|
114
146
|
sys.exit()
|
115
147
|
if event.type == KEYDOWN:
|
148
|
+
# 2,ショット:スペースキーを押下時に弾を発射
|
116
149
|
if event.key == K_SPACE:
|
117
150
|
# 発射時にbullet_listに追加
|
118
|
-
|
151
|
+
bullet = player.shoot(screen)
|
152
|
+
# 4,リストにplayer.shootの戻り値である変数:bulletを追加
|
153
|
+
bullet_list.append(bullet)
|
119
154
|
if event.key == K_ESCAPE:
|
120
155
|
pygame.quit()
|
121
156
|
sys.exit()
|
2
is_destroyをプロパティ化
answer
CHANGED
@@ -34,12 +34,15 @@
|
|
34
34
|
self.rect = Rect(x, y, w, h)
|
35
35
|
self.vx = vx
|
36
36
|
self.vy = vy
|
37
|
+
|
37
38
|
def draw(self, screen):
|
38
39
|
screen.blit(self.image, self.rect)
|
39
40
|
|
41
|
+
|
40
42
|
class Player(Flyer):
|
41
43
|
def __init__(self, filename, x, y, vx, vy):
|
42
44
|
super().__init__(filename, x, y, vx, vy)
|
45
|
+
|
43
46
|
def move(self):
|
44
47
|
pressed_key = pygame.key.get_pressed()
|
45
48
|
if pressed_key[K_LEFT]:
|
@@ -55,15 +58,16 @@
|
|
55
58
|
|
56
59
|
def shoot(self, screen): #弾発射
|
57
60
|
class Bullet(object):
|
58
|
-
def __init__(self, x:int, y:int):
|
61
|
+
def __init__(self, x: int, y: int):
|
59
62
|
self.bullet = Rect(x, y, 20, 20)
|
60
63
|
|
61
64
|
def draw(self):
|
62
65
|
pygame.draw.rect(screen, (255, 255, 255), self.bullet)
|
63
66
|
|
64
|
-
def move(self, x:int=0, y:int=-5):
|
67
|
+
def move(self, x: int=0, y: int=-5):
|
65
68
|
self.bullet.move_ip(x, y)
|
66
69
|
|
70
|
+
@property
|
67
71
|
def is_destroy(self) -> bool:
|
68
72
|
if self.bullet.x < 0 or self.bullet.y < 0:
|
69
73
|
return True
|
@@ -72,9 +76,11 @@
|
|
72
76
|
# 自機の位置が移動しても発射位置が追従するようにself.x/self.y ではなく self.rectを使用
|
73
77
|
return Bullet(self.rect.x, self.rect.y)
|
74
78
|
|
79
|
+
|
75
80
|
class Enemy(Flyer):
|
76
81
|
def __init__(self, filename, x, y, vx, vy):
|
77
82
|
super().__init__(filename, x, y, vx, vy)
|
83
|
+
|
78
84
|
def move(self):
|
79
85
|
self.rect.move_ip(self.vx, self.vy)
|
80
86
|
self.rect = self.rect.clamp(SCREEN)
|
@@ -97,8 +103,8 @@
|
|
97
103
|
for bullet in bullet_list:
|
98
104
|
bullet.move()
|
99
105
|
bullet.draw()
|
100
|
-
#リストからスクリーン範囲外のbulletを
|
106
|
+
#リストからスクリーン範囲外のbulletをクリーンアップ
|
101
|
-
bullet_list = list(filter(lambda x: not x.is_destroy
|
107
|
+
bullet_list = list(filter(lambda x: not x.is_destroy, bullet_list))
|
102
108
|
|
103
109
|
pygame.display.update()
|
104
110
|
|
@@ -117,4 +123,5 @@
|
|
117
123
|
|
118
124
|
if __name__ == "__main__":
|
119
125
|
main()
|
126
|
+
|
120
127
|
```
|
1
追記
answer
CHANGED
@@ -2,10 +2,8 @@
|
|
2
2
|
0. 移動処理である`bullet.move_ip`をショットキー押下時の一度しか行っていないため、一度しか移動されないからです。そのため質問文のような状態になります。
|
3
3
|
0. move_ipのパラメータは上に移動したいなら、x軸ではなくy軸の値を変更する必要があります。
|
4
4
|
|
5
|
-
|
6
5
|
それ以外に発射したbulletがスクリーンの描画範囲外かの`生存管理`を行う必要があります。
|
7
6
|
|
8
|
-
|
9
7
|
0. `class Bullet`を新規追加
|
10
8
|
0. 変数:`bullet_list` にて`Bullet`の生存管理をする。
|
11
9
|
|
@@ -110,7 +108,7 @@
|
|
110
108
|
sys.exit()
|
111
109
|
if event.type == KEYDOWN:
|
112
110
|
if event.key == K_SPACE:
|
113
|
-
#
|
111
|
+
# 発射時にbullet_listに追加
|
114
112
|
bullet_list.append(player.shoot(screen))
|
115
113
|
if event.key == K_ESCAPE:
|
116
114
|
pygame.quit()
|