質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2427閲覧

シューティングゲームにおける弾の実装について

ka-kosya19212

総合スコア2

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2021/08/29 13:37

編集2021/08/29 13:39

前提・実現したいこと

シューティングゲームで、円上を動く自機から垂直方向にまっすぐに発射される弾を作りたいのですが、自機の円の中心からの回転角度を利用して記述しているため、弾をうったあと、機体が動くと同時に弾をまっすぐとぶのではなく、回転してしまいます。どのように解消すればいいのか教えてほしいです。

発生している問題・エラーメッセージ

該当のソースコード

python

1import pygame 2import sys 3import math 4import random 5 6img_galaxy = pygame.image.load("galaxy.png") 7img_ship = [ 8 pygame.image.load("starship1.png"), 9 pygame.image.load("starship_l1.png"), 10 pygame.image.load("starship_r1.png"), 11 pygame.image.load("starship_burner.png") 12] 13img_weapon = pygame.image.load("bullet.png") 14img_center = pygame.image.load("center.png") 15img_enemy = [ 16 pygame.image.load("enemy0.png"), 17 pygame.image.load("enemy1.png") 18] 19tmr = 0 20r = 0 21s_x = 0 22s_y = 0 23s_d = 0 24key_spc = 0 25 26msl_f = False 27msl_x = 0 28msl_y = 0 29 30MISSILE_MAX = 200 31msl_no = 0 32msl_f = [False]*MISSILE_MAX 33msl_x = [0]*MISSILE_MAX 34msl_y = [0]*MISSILE_MAX 35 36ENEMY_MAX = 100 37emy_no = 0 38emy_f = [False]*ENEMY_MAX 39emy_x = [0]*ENEMY_MAX 40emy_y = [0]*ENEMY_MAX 41emy_a = [0]*ENEMY_MAX 42emy_type = [0]*ENEMY_MAX 43emy_speed = [0]*ENEMY_MAX 44 45EMY_BULLET = 0 46LINE_T = -80 47LINE_B = 800 48LINE_L = -80 49LINE_R = 1040 50 51zx =0 52zy =0 53 54def center(scrn): 55 scrn.blit(img_center,[380,260]) 56 57def get_dis(x1,x2,y1,y2): 58 return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) 59 60def move_starship(scrn,key): 61 global s_x,s_y,s_d,key_spc,r 62 s_d = 0 63 if key[pygame.K_LEFT] == 1: 64 s_d = 1 65 r = r - 8 66 if key[pygame.K_RIGHT] == 1: 67 s_d = 2 68 r = r + 8 69 key_spc = (key_spc+1)*key[pygame.K_SPACE] 70 if key_spc%5 ==1: 71 set_missile() 72 73 img_rz = pygame.transform.rotate(img_ship[s_d],-1*r) 74 75 s_x = 120*math.cos(math.radians(r-90))+480-25-5 76 s_y = 120*math.sin(math.radians(r-90))+360-25-5 77 78 scrn.blit(img_rz,[s_x,s_y]) 79 80def set_missile(): 81 global msl_no,r,s_x,s_y,zx,zy 82 msl_f[msl_no] = True 83 msl_x[msl_no] = (120+25)*math.cos(math.radians(r-90))+480-25-5 84 msl_y[msl_no] = (120+25)*math.sin(math.radians(r-90))+360-25-5 85 zx = msl_x[msl_no]-s_x 86 zy = msl_y[msl_no]-s_y 87 88 msl_no = (msl_no+1)%MISSILE_MAX 89 90def move_missiele(scrn): 91 global r,zx,zy 92 for i in range(MISSILE_MAX): 93 if msl_f[i] == True: 94 msl_x[i] = msl_x[i] + zx 95 msl_y[i] = msl_y[i] + zy 96 img_r = pygame.transform.rotate(img_weapon, -1 * r) 97 scrn.blit(img_r,[msl_x[i]-10,msl_y[i]-32]) 98 if msl_y[i]<0: 99 msl_f[i] = False 100 101def bring_enemy(): 102 if tmr%30 == 0: 103 set_enemy(random.randint(20,940),LINE_T,90,1,6) 104 105def set_enemy(x,y,a,ty,sp): 106 global emy_no 107 while True: 108 if emy_f[emy_no] ==False: 109 emy_f[emy_no] = True 110 emy_x[emy_no] = x 111 emy_y[emy_no] = y 112 emy_a[emy_no] = a 113 emy_type[emy_no] = ty 114 emy_speed[emy_no] = sp 115 break 116 emy_no = (emy_no+1)%ENEMY_MAX 117 118def move_enemy(scrn): # 敵機の移動 119 for i in range(ENEMY_MAX): 120 if emy_f[i] == True: 121 ang = -90-emy_a[i] 122 png = emy_type[i] 123 emy_x[i] = emy_x[i] + emy_speed[i]*math.cos(math.radians(emy_a[i])) 124 emy_y[i] = emy_y[i] + emy_speed[i]*math.sin(math.radians(emy_a[i])) 125 if emy_type[i] == 1 and emy_y[i] > 360: 126 set_enemy(emy_x[i], emy_y[i], 90, 0, 8) 127 emy_a[i] = -45 128 emy_speed[i] = 16 129 if emy_x[i] < LINE_L or LINE_R < emy_x[i] or emy_y[i] < LINE_T or LINE_B < emy_y[i]: 130 emy_f[i] = False 131 if emy_type[i] != EMY_BULLET: 132 for n in range(MISSILE_MAX): 133 if msl_f[n]== True and math.dist((emy_x[i],emy_y[i]),(msl_x[n],msl_y[n]))< 7+25: 134 msl_f[n] = False 135 emy_f[i] = False 136 img_rz = pygame.transform.rotozoom(img_enemy[png], ang, 1.0) 137 scrn.blit(img_rz, [emy_x[i]-img_rz.get_width()/2, emy_y[i]-img_rz.get_height()/2]) 138 139def main(): 140 global tmr 141 pygame.init() 142 pygame.display.set_caption("地球防衛軍") 143 screen = pygame.display.set_mode((960,720)) 144 clock = pygame.time.Clock() 145 while True: 146 tmr = tmr + 1 147 for event in pygame.event.get(): 148 if event.type == pygame.QUIT: 149 pygame.quit() 150 sys.exit() 151 if event.type == pygame.KEYDOWN: 152 if event.key == pygame.K_F1: 153 screen = pygame.display.set_mode((960,720),pygame.FULLSCREEN) 154 if event.key == pygame.K_F2 or event.key == pygame.K_ESCAPE: 155 screen = pygame.display.set_mode((960,720)) 156 screen.blit(img_galaxy,[0,0]) 157 center(screen) 158 159 key = pygame.key.get_pressed() 160 move_starship(screen,key) 161 move_missiele(screen) 162 bring_enemy() 163 move_enemy(screen) 164 165 pygame.display.update() 166 clock.tick(30) 167 168if __name__ == '__main__': 169 main()

試したこと

ゲーム画像↓(前にうった弾が自機が移動しているため画面にのこって回転している様子)
イメージ説明

def set_missile とdef move_missileのところの話です。
機体が移動したあと、円に対して法線ベクトルの方向?にそのまま弾がまっすぐ飛ぶようにしたいです

補足情報(FW/ツールのバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TakaiY

2021/08/29 15:05

[円上を動く自機から垂直方向にまっすぐに発射される弾を作りたい」とのことですが、「弾をまっすぐとぶのではなく、回転してしまいます」とはどのような状況なのかよくわかりません。 現状と希望の弾の軌跡を図示するなど、明示していただけませんか?
TakaiY

2021/08/30 02:13

質問への回答は、ここではなくて、質問そのものを編集して載せると、見に来た人に見てもらいやすくなりますよ。 なるほど、そういうことですか。 参照している変数が捕捉されていておかしな動きをさせているようですが、よく見てみないとわからないですね。
guest

回答1

0

ベストアンサー

ミサイルの動く方向がただ1組のzx,zy変数で定義されていて全ての弾がそれを見ています。その値は、最後の弾を打つときに再計算されているため、全ての弾が最後に打った弾と同じ方向に進むようになっているのが原因です。

弾それぞれが初期の進行方向を持つことができるようにする必要があります。
たとえば、弾情報として、弾のidと進行方向を持つdictを保持するなど。

投稿2021/08/30 02:20

TakaiY

総合スコア13687

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ka-kosya19212

2021/08/30 03:49

なるほど!初期情報を保持できるように辞書を利用すればいいのですね。なんとなくはイメージできたのですが、自分のコードのどこをどう書き換えればいいのかわからなくなったしまったので、簡易的なコードを教えてほしいです。時間があればお願いします。
ka-kosya19212

2021/08/30 04:04

解決いたしました。回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問