Pythonでタンクバトルゲームを実現|ドライポスト

著者| Li Qiujian

プロデュース| AIテクノロジーベースキャンプ(rgznai100)

「タンクバトル」は、1985年に日本のナムコゲームカンパニーがニンテンドーFCプラットフォームで立ち上げた多面的な飛行機射撃ゲームです。このゲームは、戦略的なオンラインカテゴリである戦車戦と基地の防衛をテーマにしています。同時に、FCプラットフォームでは珍しいレベルエディターを内蔵した数少ないゲームの1つでもあり、プレイヤーはいくつかの小道具を入手することで、独自のレベルを作成し、タンクとベースを強化できます。今日は、pythonを使用して、次の戦車戦の生産を復元します。

実験前の準備

まず、使用するPythonのバージョンは3.6.5です。使用するモジュールは次のとおりです。

魔神プログラム

その中で、ウィザードクラスは、弾丸プログラム、食べ物、家、レンガの壁、木やその他の障害物、タンクなどの主要な機能を呼び出すための基本的なプログラムフレームワークとして使用されます。具体的なプログラムのレイアウトは次のとおりです。

弾丸プログラムの中で、弾丸の位置、方向、画像の読み込み、弾丸の速度などの基本情報を含むbullet.pyプログラムを最初に確立する必要があります。具体的なコードは次のとおりです。

''' 弾丸'''classBullet(pygame.sprite.Sprite):
 def __init__(self, bullet_image_paths, screensize, direction, position, border_len, is_stronger=False, speed=8,**kwargs):
 pygame.sprite.Sprite.__init__(self)
 self.bullet_image_paths = bullet_image_paths
 self.width, self.height = screensize
 self.direction = direction
 self.position = position
 self.image = pygame.image.load(self.bullet_image_paths.get(direction))
 self.rect = self.image.get_rect()
 self.rect.center = position
 # マップのエッジ幅
 self.border_len = border_len
 # それは強化された弾丸ですか(壊れた鉄の壁の強化版)
 self.is_stronger = is_stronger
 # 弾丸の速度
 self.speed = speed
 ''' 弾丸を動かす,弾丸が範囲外になった場合,次にTrueを返します,それ以外の場合はFalse'''
 def move(self):if self.direction =='up':
  self.rect = self.rect.move(0,-self.speed)
 elif self.direction =='down':
  self.rect = self.rect.move(0, self.speed)
 elif self.direction =='left':
  self.rect = self.rect.move(-self.speed,0)
 elif self.direction =='right':
  self.rect = self.rect.move(self.speed,0)if(self.rect.top < self.border_len)or(self.rect.bottom > self.height)or(self.rect.left < self.border_len)or(self.rect.right > self.width):return True
 return False

食品報酬カテゴリ、タンクが食品を食べるときの寿命を延ばすなどの基本的な報酬としてfood.pyを確立します。

''' 食物.報酬を得るために使用されます'''classFoods(pygame.sprite.Sprite):
 def __init__(self, food_image_paths, screensize,**kwargs):
 pygame.sprite.Sprite.__init__(self)
 self.name = random.choice(list(food_image_paths.keys()))
 self.image = pygame.image.load(food_image_paths.get(self.name))
 self.rect = self.image.get_rect()
 self.rect.left, self.rect.top = random.randint(100, screensize[0]-100), random.randint(100, screensize[1]-100)
 self.exist_time =1000
 def update(self):
 self.exist_time -=1return True if self.exist_time <0else False

タンクファミリの場合、home.pyを作成して、基本情報(生きているかどうか、画像の読み込み、場所のサイズなど)を保存します。

''' ベースキャンプ'''classHome(pygame.sprite.Sprite):
 def __init__(self, position, imagepaths,**kwargs):
 pygame.sprite.Sprite.__init__(self)
 self.imagepaths = imagepaths
 self.image = pygame.image.load(self.imagepaths[0])
 self.rect = self.image.get_rect()
 self.rect.left, self.rect.top = position
 self.alive = True
 ''' 破壊されました'''
 def setDead(self):
 self.image = pygame.image.load(self.imagepaths[1])
 self.alive = False
 ''' 画面に描く'''
 def draw(self, screen):
 screen.blit(self.image, self.rect)

レンガの壁などの障害物の場合は、メインの位置サイズでもあるscenes.pyのレイアウトを作成します。

''' れんが壁'''classBrick(pygame.sprite.Sprite):
 def __init__(self, position, imagepath,**kwargs):
 pygame.sprite.Sprite.__init__(self)
 self.image = pygame.image.load(imagepath)
 self.rect = self.image.get_rect()
 self.rect.left, self.rect.top = position
''' 鉄の壁'''classIron(pygame.sprite.Sprite):
 def __init__(self, position, imagepath,**kwargs):
 pygame.sprite.Sprite.__init__(self)
 self.image = pygame.image.load(imagepath)
 self.rect = self.image.get_rect()
 self.rect.left, self.rect.top = position
''' 氷'''classIce(pygame.sprite.Sprite):
 def __init__(self, position, imagepath,**kwargs):
 pygame.sprite.Sprite.__init__(self)
 self.image = pygame.Surface((24,24))for i inrange(2):for j inrange(2):
  self.image.blit(pygame.image.load(imagepath),(12*i,12*j))
 self.rect = self.image.get_rect()
 self.rect.left, self.rect.top = position
''' 川'''classRiver(pygame.sprite.Sprite):
 def __init__(self, position, imagepath,**kwargs):
 pygame.sprite.Sprite.__init__(self)
 self.image = pygame.Surface((24,24))for i inrange(2):for j inrange(2):
  self.image.blit(pygame.image.load(imagepath),(12*i,12*j))
 self.rect = self.image.get_rect()
 self.rect.left, self.rect.top = position
''' 木'''classTree(pygame.sprite.Sprite):
 def __init__(self, position, imagepath,**kwargs):
 pygame.sprite.Sprite.__init__(self)
 self.image = pygame.Surface((24,24))for i inrange(2):for j inrange(2):
  self.image.blit(pygame.image.load(imagepath),(12*i,12*j))
 self.rect = self.image.get_rect()
 self.rect.left, self.rect.top = position

タンクの場合は、tanks.pyを作成して、タンクの数、初期位置などの情報を含めます。

''' プレイヤータンク'''classPlayerTank(pygame.sprite.Sprite):
 def __init__(self, name, player_tank_image_paths, position, border_len, screensize, direction='up', bullet_image_paths=None, protected_mask_path=None, boom_image_path=None,**kwargs):
 pygame.sprite.Sprite.__init__(self)
 # プレーヤー1/プレーヤー2
 self.name = name
 # タンクピクチャーパス
 self.player_tank_image_paths = player_tank_image_paths.get(name)
 # マップのエッジ幅
 self.border_len = border_len
 # 画面サイズ
 self.screensize = screensize
 # タンクの初期方向
 self.init_direction = direction
 # 初期位置
 self.init_position = position
 # 弾丸の写真
 self.bullet_image_paths = bullet_image_paths
 # 保護カバーの画像パス
 self.protected_mask = pygame.image.load(protected_mask_path)
 self.protected_mask_flash_time =25
 self.protected_mask_flash_count =0
 self.protected_mask_pointer = False
 # タンク爆発ビュー
 self.boom_image = pygame.image.load(boom_image_path)
 self.boom_last_time =5
 self.booming_flag = False
 self.boom_count =0
 # タンク寿命の数
 self.num_lifes =3
 # リセット
 self.reset()'''モバイル'''
 def move(self, direction, scene_elems, player_tanks_group, enemy_tanks_group, home):
 # 爆発時に動かない
 if self.booming_flag:return
 # 方向が一貫していない場合は、最初に方向を変更してください
 if self.direction != direction:
  self.setDirection(direction)
  self.switch_count = self.switch_time
  self.move_cache_count = self.move_cache_time
 # モバイル(バッファを使用する)
 self.move_cache_count +=1if self.move_cache_count < self.move_cache_time:return
 self.move_cache_count =0if self.direction =='up':
  speed =(0,-self.speed)
 elif self.direction =='down':
  speed =(0, self.speed)
 elif self.direction =='left':
  speed =(-self.speed,0)
 elif self.direction =='right':
  speed =(self.speed,0)
 rect_ori = self.rect
 self.rect = self.rect.move(speed)
 # - - 出会いのシーン要素
 for key, value in scene_elems.items():if key in['brick_group','iron_group','river_group']:if pygame.sprite.spritecollide(self, value, False, None):
   self.rect = rect_ori
  elif key in['ice_group']:if pygame.sprite.spritecollide(self, value, False, None):
   self.rect = self.rect.move(speed)
 # - - 他のプレイヤーの戦車に遭遇した
 if pygame.sprite.spritecollide(self, player_tanks_group, False, None):
  self.rect = rect_ori
 # - - 敵の戦車に遭遇
 if pygame.sprite.spritecollide(self, enemy_tanks_group, False, None):
  self.rect = rect_ori
 # - - プレイヤーベースキャンプに会う
 if pygame.sprite.collide_rect(self, home):
  self.rect = rect_ori
 # - - 境界を打つ
 if self.rect.left < self.border_len:
  self.rect.left = self.border_len
 elif self.rect.right > self.screensize[0]-self.border_len:
  self.rect.right = self.screensize[0]- self.border_len
 elif self.rect.top < self.border_len:
  self.rect.top = self.border_len
 elif self.rect.bottom > self.screensize[1]-self.border_len:
  self.rect.bottom = self.screensize[1]- self.border_len
 # タンクホイールモーションエフェクトの写真を切り替える
 self.switch_count +=1if self.switch_count > self.switch_time:
  self.switch_count =0
  self.switch_pointer = not self.switch_pointer
  self.image = self.tank_direction_image.subsurface((48*int(self.switch_pointer),0),(48,48))

ゲームインターフェース設定

ゲームインターフェイス設定には、開始インターフェイス設定、終了インターフェイス設定、およびレベル切り替えインターフェイス設定が含まれます。

ゲーム開始インターフェースには、プレーヤー数の選択と写真と音楽のロードが含まれます。

''' ゲーム開始インターフェース'''
def gameStartInterface(screen, cfg):
 background_img = pygame.image.load(cfg.OTHER_IMAGE_PATHS.get('background'))
 color_white =(255,255,255)
 color_red =(255,0,0)
 font = pygame.font.Font(cfg.FONTPATH, cfg.WIDTH//12)
 logo_img = pygame.image.load(cfg.OTHER_IMAGE_PATHS.get('logo'))
 logo_img = pygame.transform.scale(logo_img,(446,70))
 logo_rect = logo_img.get_rect()
 logo_rect.centerx, logo_rect.centery = cfg.WIDTH/2, cfg.HEIGHT//4
 tank_cursor = pygame.image.load(cfg.PLAYER_TANK_IMAGE_PATHS.get('player1')[0]).convert_alpha().subsurface((0,144),(48,48))
 tank_rect = tank_cursor.get_rect()
 # プレイヤー選択数
 player_render_white = font.render('1 PLAYER', True, color_white)
 player_render_red = font.render('1 PLAYER', True, color_red)
 player_rect = player_render_white.get_rect()
 player_rect.left, player_rect.top = cfg.WIDTH/2.8, cfg.HEIGHT/2.5
 players_render_white = font.render('2 PLAYERS', True, color_white)
 players_render_red = font.render('2 PLAYERS', True, color_red)
 players_rect = players_render_white.get_rect()
 players_rect.left, players_rect.top = cfg.WIDTH/2.8, cfg.HEIGHT/2
 # ゲームのヒント
 game_tip = font.render('press <Enter> to start', True, color_white)
 game_tip_rect = game_tip.get_rect()
 game_tip_rect.centerx, game_tip_rect.top = cfg.WIDTH/2, cfg.HEIGHT/1.4
 game_tip_flash_time =25
 game_tip_flash_count =0
 game_tip_show_flag = True
 # メインループ
 clock = pygame.time.Clock()
 is_dual_mode = False
 while True:for event in pygame.event.get():if event.type == pygame.QUIT:
  pygame.quit()
  sys.exit()
  elif event.type == pygame.KEYDOWN:if event.key == pygame.K_RETURN:return is_dual_mode
  elif event.key == pygame.K_UP or event.key == pygame.K_DOWN or event.key == pygame.K_w or event.key == pygame.K_s:
   is_dual_mode = not is_dual_mode
 screen.blit(background_img,(0,0))
 screen.blit(logo_img, logo_rect)
 game_tip_flash_count +=1if game_tip_flash_count > game_tip_flash_time:
  game_tip_show_flag = not game_tip_show_flag
  game_tip_flash_count =0if game_tip_show_flag:
  screen.blit(game_tip, game_tip_rect)if not is_dual_mode:
  tank_rect.right, tank_rect.top = player_rect.left-10, player_rect.top
  screen.blit(tank_cursor, tank_rect)
  screen.blit(player_render_red, player_rect)
  screen.blit(players_render_white, players_rect)else:
  tank_rect.right, tank_rect.top = players_rect.left-10, players_rect.top
  screen.blit(tank_cursor, tank_rect)
  screen.blit(player_render_white, player_rect)
  screen.blit(players_render_red, players_rect)
 pygame.display.update()
 clock.tick(60)

ゲーム終了インターフェースには、ゲームの勝利と失敗の判断、およびゲームを終了するか設定を再開するかが含まれます。

''' ゲームオーバーインターフェース'''
def gameEndIterface(screen, cfg, is_win=True):
 background_img = pygame.image.load(cfg.OTHER_IMAGE_PATHS.get('background'))
 color_white =(255,255,255)
 color_red =(255,0,0)
 font = pygame.font.Font(cfg.FONTPATH, cfg.WIDTH//12)
 # ゲーム失敗グラフ
 gameover_img = pygame.image.load(cfg.OTHER_IMAGE_PATHS.get('gameover'))
 gameover_img = pygame.transform.scale(gameover_img,(150,75))
 gameover_img_rect = gameover_img.get_rect()
 gameover_img_rect.midtop = cfg.WIDTH/2, cfg.HEIGHT/8
 gameover_flash_time =25
 gameover_flash_count =0
 gameover_show_flag = True
 # ゲームに勝つためのヒント
 if is_win:
 font_render = font.render('Congratulations, You win!', True, color_white)else:
 font_render = font.render('Sorry, You fail!', True, color_white)
 font_rect = font_render.get_rect()
 font_rect.centerx, font_rect.centery = cfg.WIDTH/2, cfg.HEIGHT/3
 # オプトアウトまたは再起動に使用されます
 tank_cursor = pygame.image.load(cfg.PLAYER_TANK_IMAGE_PATHS.get('player1')[0]).convert_alpha().subsurface((0,144),(48,48))
 tank_rect = tank_cursor.get_rect()
 restart_render_white = font.render('RESTART', True, color_white)
 restart_render_red = font.render('RESTART', True, color_red)
 restart_rect = restart_render_white.get_rect()
 restart_rect.left, restart_rect.top = cfg.WIDTH/2.4, cfg.HEIGHT/2
 quit_render_white = font.render('QUIT', True, color_white)
 quit_render_red = font.render('QUIT', True, color_red)
 quit_rect = quit_render_white.get_rect()
 quit_rect.left, quit_rect.top = cfg.WIDTH/2.4, cfg.HEIGHT/1.6
 is_quit_game = False
 # メインループ
 clock = pygame.time.Clock()while True:for event in pygame.event.get():if event.type == pygame.QUIT:
  pygame.quit()
  sys.exit()
  elif event.type == pygame.KEYDOWN:if event.key == pygame.K_RETURN:return is_quit_game
  elif event.key == pygame.K_UP or event.key == pygame.K_DOWN or event.key == pygame.K_w or event.key == pygame.K_s:
   is_quit_game = not is_quit_game
 screen.blit(background_img,(0,0))
 gameover_flash_count +=1if gameover_flash_count > gameover_flash_time:
  gameover_show_flag = not gameover_show_flag
  gameover_flash_count =0if gameover_show_flag:
  screen.blit(gameover_img, gameover_img_rect)
 screen.blit(font_render, font_rect)if not is_quit_game:
  tank_rect.right, tank_rect.top = restart_rect.left-10, restart_rect.top
  screen.blit(tank_cursor, tank_rect)
  screen.blit(restart_render_red, restart_rect)
  screen.blit(quit_render_white, quit_rect)else:
  tank_rect.right, tank_rect.top = quit_rect.left-10, quit_rect.top
  screen.blit(tank_cursor, tank_rect)
  screen.blit(restart_render_white, restart_rect)
  screen.blit(quit_render_red, quit_rect)
 pygame.display.update()
 clock.tick(60)

ゲームインターフェイススイッチは、主に進行状況バーによって読み込まれます。

''' レベル切り替えインターフェース'''
def switchLevelIterface(screen, cfg, level_next=1):
 background_img = pygame.image.load(cfg.OTHER_IMAGE_PATHS.get('background'))
 color_white =(255,255,255)
 color_gray =(192,192,192)
 font = pygame.font.Font(cfg.FONTPATH, cfg.WIDTH//20)
 logo_img = pygame.image.load(cfg.OTHER_IMAGE_PATHS.get('logo'))
 logo_img = pygame.transform.scale(logo_img,(446,70))
 logo_rect = logo_img.get_rect()
 logo_rect.centerx, logo_rect.centery = cfg.WIDTH/2, cfg.HEIGHT//4
 # ゲームの読み込みのヒント
 font_render = font.render('Loading game data, You will enter Level-%s'% level_next, True, color_white)
 font_rect = font_render.get_rect()
 font_rect.centerx, font_rect.centery = cfg.WIDTH/2, cfg.HEIGHT/2
 # ゲームの読み込みの進行状況バー
 gamebar = pygame.image.load(cfg.OTHER_IMAGE_PATHS.get('gamebar')).convert_alpha()
 gamebar_rect = gamebar.get_rect()
 gamebar_rect.centerx, gamebar_rect.centery = cfg.WIDTH/2, cfg.HEIGHT/1.4
 tank_cursor = pygame.image.load(cfg.PLAYER_TANK_IMAGE_PATHS.get('player1')[0]).convert_alpha().subsurface((0,144),(48,48))
 tank_rect = tank_cursor.get_rect()
 tank_rect.left = gamebar_rect.left
 tank_rect.centery = gamebar_rect.centery
 # 読み込み時間
 load_time_left = gamebar_rect.right - tank_rect.right +8
 # メインループ
 clock = pygame.time.Clock()while True:for event in pygame.event.get():if event.type == pygame.QUIT:
  pygame.quit()
  sys.exit()if load_time_left <=0:return
 screen.blit(background_img,(0,0))
 screen.blit(logo_img, logo_rect)
 screen.blit(font_render, font_rect)
 screen.blit(gamebar, gamebar_rect)
 screen.blit(tank_cursor, tank_rect)
 pygame.draw.rect(screen, color_gray,(gamebar_rect.left+8, gamebar_rect.top+8, tank_rect.left-gamebar_rect.left-8, tank_rect.bottom-gamebar_rect.top-16))
 tank_rect.left +=1
 load_time_left -=1
 pygame.display.update()
 clock.tick(60)

完全なコード:

抽出コード:09bl

著者:Qiuキー

***CSDNブログの専門家、CSDNマスタークラスの作成者。中国鉱業技術大学の修士号、開発におけるタッパップコンペティションアワードなど。 ***

Recommended Posts

Pythonでタンクバトルゲームを実現|ドライポスト
Pythonでタンクバトルゲームを実現|ドライポスト
パイソンを使って航空機戦争ゲームを実現する
Pythonは戦車戦を実現
Pythonは単純なタンクバトルを実装します
pythonはゲームという言葉を推測します
Pythonは推測ゲームを実現します
Pythonは実店舗のゲームを実装しています
PythonはTowerofHanoiゲームを解決します
Pythonの基本的な実際の戦闘-年齢ゲームを推測する
Pythonは貪欲なヘビの二重の戦いを実現します
pythonに最初に精通した、pythonの文法規則
Pythonに付属しているIDEはどこにありますか