この記事の例では、参考のためにPython航空機戦争プロジェクトを共有しています。具体的な内容は次のとおりです。
import gc
import random
import pygame
# プレイヤー飛行機スプライト
import Constants
classHeroPlane(pygame.sprite.Sprite):
def __init__(self, screen):
# 親クラス初期化メソッドを呼び出す
# pygame.sprite.Sprite.__init__(self)super().__init__()
# 窓
self.screen = screen
# プレイヤーの飛行機の写真
self.image = pygame.image.load('./feiji/feiji.png')
# 航空機長方形エリアオブジェクト
self.rect = self.image.get_rect()
# 左上隅の座標
self.rect.topleft =[512/2-116/2,600]
# 飛行機の速度
self.speed =15
# スプライトグループは、すべての弾丸スプライトを格納します
self.bullets = pygame.sprite.Group()
# 初期HP100
self.blood_value =100
# プレイヤーの飛行機が終わったかどうかをマークします
self.is_remove = False
# 分解された画像のインデックスは0から始まります
self.mIndex =0
# 爆発写真のリスト
self.bomb_mImages =[]for v inrange(1,15):
# リスト内のすべての写真を保存し、各写真を2回保存します
self.bomb_mImages.append(pygame.image.load('./feiji/image '+str(v)+'.png'))
self.bomb_mImages.append(pygame.image.load('./feiji/image '+str(v)+'.png'))
def kill_blood(self, kill_value=10):"""血液量の減少"""
self.blood_value -= kill_value
print('打たれた、まだ血が残っている%s'% self.blood_value)if self.blood_value <=0:
# 負の血液量を避ける
self.blood_value =0
# 血液量<=0セットは_削除はTrueです
self.is_remove = True
def key_control(self):"""ボタンを押して航空機を監視および操作します"""
# キーボードイベントを聞く
key_pressed = pygame.key.get_pressed() #この方法では、押されて離されていないキーボードを検出できることに注意してください。
if key_pressed[pygame.K_w] or key_pressed[pygame.K_UP]:
# 最上位の値が0未満の場合、最上位に到達し、それ以上移動しません。
if self.rect.top 3:
self.rect.top -= self.speed
if key_pressed[pygame.K_s] or key_pressed[pygame.K_DOWN]:if self.rect.bottom <=768:
self.rect.bottom += self.speed
if key_pressed[pygame.K_a] or key_pressed[pygame.K_LEFT]:if self.rect.left 0:
self.rect.left -= self.speed
if key_pressed[pygame.K_d] or key_pressed[pygame.K_RIGHT]:if self.rect.right <520:
self.rect.right += self.speed
if key_pressed[pygame.K_SPACE]:
# print("space")
# 3つの弾丸を作成する
bullet1 =Bullet(self.screen, self.rect.left, self.rect.top,1)
bullet2 =Bullet(self.screen, self.rect.left, self.rect.top,2)
bullet3 =Bullet(self.screen, self.rect.left, self.rect.top,3)
# スプライトグループに追加
self.bullets.add(bullet1, bullet2, bullet3)
def bomb(self):print('プレイヤーの飛行機が爆発する')"""爆発の写真を表示"""
self.screen.blit(self.bomb_mImages[self.mIndex], self.rect)
self.mIndex +=1print('mIndex', self.mIndex)if self.mIndex =len(self.bomb_mImages):
# 最後までプレイすると、爆発が終了してTrueに戻ります
return True
def update(self):if self.is_remove:print('プレーヤーの飛行機が電話を切る')
# プレーヤーが電話を切った場合
if self.bomb():
# 爆発の終わり
print('爆発の終わり')
self.rect.topleft =[-200,-200]
# カウントダウンを開始
pygame.time.set_timer(Constants.game_over_id,1000)
# プレーヤープレーンを[なし]にポイントして、更新を停止します
manager.hero = None
else:
self.key_control()
self.display()
def display(self):
# if self.blood_value <=0:
# # HPが0未満の場合は、ウィンドウの外に移動します
# self.rect.topleft =[-200,-200]
# ウィンドウ116に航空機を表示します*100
self.screen.blit(self.image, self.rect)
# ウィザードグループの箇条書きの位置を更新します
self.bullets.update()
# スプライトグループのすべての弾丸をウィンドウに表示する
self.bullets.draw(self.screen)classBullet(pygame.sprite.Sprite):
# path_numは、ショットに含まれる弾丸を示します
def __init__(self, screen, planex, planey, path_num):
# 親クラス初期化メソッドを呼び出す
# pygame.sprite.Sprite.__init__(self)super().__init__()
# 窓
self.screen = screen
# 弾丸の写真
self.image = pygame.image.load('./feiji/bullet_12.png')
# 弾丸長方形エリアオブジェクト
self.rect = self.image.get_rect()
# 弾丸の左上隅の座標
self.rect.topleft =[planex +48, planey -20]
# 弾丸の速度
self.speed =15
# path_numは、ショットに含まれる弾丸を示します
self.path_num = path_num
def update(self):"""弾丸座標を変更する"""
self.rect.top -= self.speed
if self.rect.bottom <0:
# 弾丸が画面の上部から移動され、ウィザードグループから弾丸が削除されるようになりました
self.kill()if self.path_num ==1:
pass
elif self.path_num ==2:
# 2に等しい場合は、左側のショットです
self.rect.left -=10
elif self.path_num ==3:
# 3に等しい場合は、右側のショットです
self.rect.right +=10
# 盗賊の精神
classEnemyPlane(pygame.sprite.Sprite):
# クラス属性を作成して、すべての航空機のすべての弾丸を保存します
all_bullets = pygame.sprite.Group()
def __init__(self, screen):
# 親クラス初期化メソッドを呼び出す
# pygame.sprite.Sprite.__init__(self)super().__init__()
# 窓
self.screen = screen
# プレイヤーの飛行機の写真
self.image = pygame.image.load('./feiji/img-plane_5.png')
# 航空機長方形エリアオブジェクト
self.rect = self.image.get_rect()
# 左上隅のx座標はランダムです
self.rect.topleft =[random.randint(0,412),0]
# 飛行機の速度
self.speed =3
# スプライトグループは、すべての弾丸スプライトを格納します
self.bullets = pygame.sprite.Group()
# 盗賊の左右の方向は、デフォルトでは最初は右です
self.direction ='right'
# Bullet's Elf Group
self.bullets = pygame.sprite.Group()
# 敵機が攻撃されたかどうかをマークして削除する
self.is_remove = False
# 分解された画像のインデックスは0から始まります
self.mIndex =0
# 爆発写真のリスト
self.bomb_mImages =[]for v inrange(1,14):
# リスト内のすべての写真を保存し、各写真を2回保存します
self.bomb_mImages.append(pygame.image.load('./feiji/image '+str(v)+'.png'))
self.bomb_mImages.append(pygame.image.load('./feiji/image '+str(v)+'.png'))
# 爆発場所を記録する
self.x =0
self.y =0
def auto_move(self):"""自動移動"""
# 下に移動
self.rect.bottom += self.speed
# 航空機が境界の外に移動した場合は削除します
if self.rect.top Manager.height:
self.kill()
# 左右に異なる方向に移動します
if self.direction =='right':
self.rect.right +=6
elif self.direction =='left':
self.rect.right -=6
# 左右の境界を越えて移動方向を変える
if self.rect.right = Manager.width:
self.direction ='left'if self.rect.left <=0:
self.direction ='right'
def auto_fire(self):
# ランダムな番号を使用する
num = random.randint(1,40)
# 1に等しいかどうかを判断し、弾丸を発射します。これにより、確率が低下します。
if num ==5:
# 盗賊の弾丸を生成する
bullet =EnemyBullet(self.screen, self.rect.left, self.rect.top)
# スプライトグループに追加
self.bullets.add(bullet)
# クラス全員に弾丸を追加する_弾丸の衝突検出に使用されます
EnemyPlane.all_bullets.add(bullet)
def bomb(self):"""爆発の写真を表示"""if self.mIndex =len(self.bomb_mImages):
# 最後までプレイすると、爆発が終了してTrueに戻ります
return True
self.screen.blit(self.bomb_mImages[self.mIndex],(self.x, self.y))
self.mIndex +=1
def update(self):if self.is_remove:if self.rect.left !=-200:
# 爆発の場所を記録する
self.x = self.rect.left
self.y = self.rect.top
# 衝突した場合は、衝突検出を防ぐために窓から航空機を取り外します
self.rect.left =-200
self.rect.top =-200
# 爆発効果を表示
if self.bomb() and not self.bullets:
# 爆発が終了した場合は、ウィザードグループから自分を削除します
self.kill()else:
# モバイル
self.auto_move()
# 火
self.auto_fire()
# 表示
self.display()
self.bullet_show()
def display(self):
# ウィンドウ116に航空機を表示します*100
self.screen.blit(self.image, self.rect)
def bullet_show(self):if self.bullets:
# 盗賊の弾丸の更新
self.bullets.update()
# 敵の航空機の弾丸表示
self.bullets.draw(self.screen)classEnemyBullet(pygame.sprite.Sprite):
# path_numは、ショットに含まれる弾丸を示します
def __init__(self, screen, x, y):
# 親クラス初期化メソッドを呼び出す
# pygame.sprite.Sprite.__init__(self)super().__init__()
# 窓
self.screen = screen
# 弾丸の写真
self.image = pygame.image.load('./feiji/bullet_6.png')
# 弾丸長方形エリアオブジェクト
self.rect = self.image.get_rect()
# 弾丸の左上隅の座標
self.rect.topleft =[x +40, y +60]
# 弾丸の速度
self.speed =10
def update(self):"""弾丸座標を変更する"""
self.rect.bottom += self.speed
# 弾丸が下に移動して境界から外れた場合は削除します
if self.rect.top Manager.height:
self.kill()
# ゲームミュージック
classGameSound(object):
def __init__(self):
pygame.mixer.init() #音楽モジュールの初期化
pygame.mixer.music.load("./feiji/Jamesketed.mp3")
pygame.mixer.music.set_volume(0.5) #半分の音
self.__bomb = pygame.mixer.Sound("./feiji/bomb.wav")
def playBackgroundMusic(self):
# バックグラウンドミュージックの再生を開始します-1は常に繰り返すことを意味します
pygame.mixer.music.play(-1)
def playBombSound(self):
pygame.mixer.Sound.play(self.__bomb) #爆発音楽
classGameBackground(object):
# マップを初期化します
def __init__(self, screen):
self.mImage1 = pygame.image.load("./feiji/img_bg_level_4.jpg")
self.mImage2 = pygame.image.load("./feiji/img_bg_level_4.jpg")
# 窓
self.screen = screen
# 補助モバイルマップ
self.y1 =0
self.y2 =-Manager.height # -768
def update(self):
self.move()
self.draw()
# マップを移動する
def move(self):
self.y1 +=2
self.y2 +=2if self.y1 = Manager.height:
self.y1 =0if self.y2 =0:
self.y2 =-Manager.height
# 地図を描く
def draw(self):
self.screen.blit(self.mImage1,(0, self.y1))
self.screen.blit(self.mImage2,(0, self.y2))classManager:
hero: HeroPlane
# 幅と高さを作成する
width =512
height =768
def __init__(self):
# pygameが初期化されます。そうでない場合、フォントファイルが見つかりません。
pygame.init()
# 1 ウィンドウの作成パラメータ1は幅と高さ、パラメータ2追加のパラメータパラメータ3は色の深さです
self.screen = pygame.display.set_mode((self.width, self.height),0,32)
# 2 背景画像オブジェクトを作成する
# self.background = pygame.image.load('./feiji/img_bg_level_5.jpg')
self.background =GameBackground(self.screen)
# 飛行機オブジェクトを作成する
self.hero =HeroPlane(self.screen)
# 時計オブジェクトを作成する
self.clock = pygame.time.Clock()
# 盗賊のエルフ
self.enemys = pygame.sprite.Group()
# サウンドエフェクトオブジェクトを初期化します
self.sound =GameSound()
# スコア属性を定義する
self.score =0
# カウントダウン時間
self.over_time =3
def exit(self):
# 終了コードを実行する
pygame.quit()
# プログラムの終了
exit()
def new_enemy(self):
# 盗賊オブジェクトを作成する
enemy =EnemyPlane(self.screen)
# スプライトグループに追加
self.enemys.add(enemy)
def drawText(self, text, x, y, textHeight=30, fontColor=(255,255,255), backgroudColor=None):
# フォントファイルからフォントオブジェクトパラメータを取得する1フォントファイルパラメータ2フォントサイズ
font_obj = pygame.font.Font('./feiji/baddf.ttf', textHeight)
# 1 テキスト2がアンチエイリアシングであるかどうか3テキストの色4背景の色
text_obj = font_obj.render(text, True, fontColor, backgroudColor) #表示するテキストを構成します
# 表示するオブジェクトの長方形を取得します
text_rect = text_obj.get_rect()
# 表示オブジェクトの座標を設定します
text_rect.topleft =(x, y)
# 指定した領域に単語を描画します。パラメータ1はテキストオブジェクトです。パラメータ2は長方形オブジェクトです。
self.screen.blit(text_obj, text_rect)
def game_over_timer(self):"""カウントダウンを実行する"""
self.over_time -=1if self.over_time ==0:
# カウントダウンを停止します
pygame.time.set_timer(Constants.game_over_id,0)
# ゲームを再開します
self.start_game()
def show_over_text(self):print('self.over_time', self.over_time)
# カウントダウン時間はゲーム終了時に表示されます
self.drawText('gameover %d'% self.over_time,0, Manager.height /2, textHeight=50,
fontColor=[0,0,0])
def start_game(self):
global manager
# シチュエーションバンディットブレットエルフグループ
EnemyPlane.all_bullets.empty()
manager =Manager()
# ガベージコレクションは、Pythonインタープリターにリサイクルを促します
gc.collect()
manager.main()
def main(self):
# バックグラウンドミュージックを再生する
self.sound.playBackgroundMusic()
# Ref。1eventidは、自分で定義したイベントIDです(0-32)使用されているpygameの他のイベントIDと競合しないでください。
# パラメータ2は、タイミングイベントの間隔時間(ミリ秒単位)です。
pygame.time.set_timer(Constants.new_enemy,500)while True:
# 1秒あたりの実行回数を制御する
self.clock.tick(60)
# イベントを取得して処理する
for event in pygame.event.get():
# イベントのタイプが終了であるかどうかを判別します
if event.type == pygame.QUIT:
# 脱落
self.exit()
elif event.type == Constants.new_enemy:
# 20に等しいということは、タイマーが有効になって敵の航空機を追加することを意味します
# print('敵機を追加する')
self.new_enemy()
elif event.type == Constants.game_over_id:print('カウントダウン33333')
# カウントダウン時間を表示する
self.game_over_timer()
# 3 ウィンドウに背景画像を表示する
# self.screen.blit(self.background,(0,0))
self.background.update()
self.drawText('割合:%s'% self.score,0,0)if self.hero:
self.drawText('HP:%s'% self.hero.blood_value,0,30)
# 航空機を更新する
self.hero.update()
# if self.hero.blood_value <=0 and not self.hero.bullets.sprites():
# # プレーヤーの航空機の参照を[なし]にポイントし、できるだけ早くリリースします
# self.hero = None
else:
self.drawText('HP:0',0,30)
# 盗賊を更新する
self.enemys.update()
# 飛行機がハングアップした場合、カウントダウンは常に表示されます
if not self.hero:
# カウントダウンを表示
self.show_over_text()
# プレーヤーの航空機と敵の航空機の両方が自己であるかどうかを判断します.enemys.sprites()スプライトグループに対応するスプライトのリストを返します
if self.hero and self.enemys.sprites():
# 衝突検出で返された衝突した敵機のリスト
collide_enemys = pygame.sprite.spritecollide(self.hero, self.enemys, False, pygame.sprite.collide_mask)if collide_enemys:
# リストが空でない場合は、敵の航空機に遭遇したことを意味します
print('敵機に遭遇')
# 爆発音
self.sound.playBombSound()
self.hero.kill_blood(100)for enemy_item in collide_enemys:
# 敵の飛行機が攻撃されたことをマークします
enemy_item.is_remove = True
# プレイヤーの航空機とプレイヤーの航空機の弾丸と敵の航空機が存在するかどうかを確認します
if self.hero and self.hero.bullets and self.enemys:
# プレイヤーの航空機と敵の航空機の間の衝突を検出します
# 返品は辞書形式です{<Bullet sprite(in0 groups):[<EnemyPlane sprite(in0 groups)]}
# { 衝突する弾丸1:[敵機が1ヒット、敵機が2ヒット]、衝突する弾丸2:[敵機が1ヒット、敵機が5ヒット]}
collode_dict = pygame.sprite.groupcollide(self.hero.bullets, self.enemys, True, False,
pygame.sprite.collide_mask)
# 1 複数の弾丸が同じ平面に当たる#2異なる弾丸が異なる飛行機に当たる#すべてのボーナスポイントで重複する敵の航空機を削除します
# print(collode_dict)if collode_dict:
# 爆発音
self.sound.playBombSound()print(self.score)
# セットを使用して敵の航空機を追加し、重複を削除します
enemyset =set()
# ヒットしたすべての敵機のリストを取得し、トラバースします
for v_enemys in collode_dict.values():
# 敵の航空機のリストをトラバースします
for enemy_item in v_enemys:
# print(id(enemy_item))
enemyset.add(enemy_item)
# 敵の飛行機が攻撃されたことをマークします
enemy_item.is_remove = True
# 衝突後+10点*セット内の敵機の数
self.score +=10*len(enemyset)
# プレイヤーの航空機と敵の航空機の弾丸を決定する
if self.hero and EnemyPlane.all_bullets:
# プレイヤーと敵の航空機との衝突を検出する
collide_bullets = pygame.sprite.spritecollide(self.hero, EnemyPlane.all_bullets, True,
pygame.sprite.collide_mask)if collide_bullets:
# ヒットした場合は10を減らします*弾丸の数
self.hero.kill_blood(10*len(collide_bullets))
# 2 表示ウィンドウ
pygame.display.update()if __name__ =='__main__':
manager =Manager()
manager.main()
以上が本稿の内容ですので、皆様のご勉強に役立てていただければ幸いです。
Recommended Posts