Python+Pygame开发太空大战/飞机大战完整游戏项目(附源代码)

项目名称:太空大战

开发环境:Python3.6.4

第三方库:Pygame1.9.6

代码编辑器:Sublime Text

先来看一下游戏画面吧!  游戏画面动态且丰富哦!

 

需求分析

  • 利用Python开发一个太空大战,提供UIBgm,丰富的游戏图片素材,左上角拥有玩家的生命进度条且能够动态变化,右上角拥有玩家的生命条数
  • 游戏精灵能够动态交互,打败敌人能够有动态的爆炸效果(用静态图片循环播放可实现),且打败敌人能够随机的掉落火箭增加生命进度甚至增加生命条数(有一个所获几率的控制)的游戏精灵,打败敌人能够获得分数
  • 算法设计:能够根据玩家的生命进度及生命条数调整游戏难度和获得火箭,生命数等精灵的概率
  • 设计动态地图,使游戏更加动态化以及游戏化

     

功能模块

  • 库的导入
    1 import pygame
    2 import random
    3 from os import path
    4 import sys
    5 from pygame.locals import *
    6 import math
    7 from datetime import datetime, date, time

 

  • 图片导入
     1 img_dir = path.join(path.dirname(__file__),'img')
     2 background_dir = path.join(img_dir,'space.png')
     3 background_img1 = pygame.image.load(background_dir).convert()
     4 background_img2 = pygame.image.load(background_dir).convert()
     5 background_img3 = pygame.image.load('img/space.png').convert()
     6 background_rect = background_img1.get_rect()
     7 player_dir = path.join(img_dir,'spaceShips_005.png')
     8 player_img = pygame.image.load(player_dir).convert()
     9 player_img_small = pygame.transform.scale(player_img,(26,20))
    10 player_img_small.set_colorkey((0,0,0))
    11 enemy_dir = path.join(img_dir,'spaceMeteors_004.png')
    12 enemy_img = pygame.image.load(enemy_dir).convert()
    13 bullet_dir = path.join(img_dir,'bullet.png')
    14 bullet_img = pygame.image.load(bullet_dir).convert_alpha()
    15 missile_dir = path.join(img_dir,'spaceMissiles_040.png')
    16 missile_img = pygame.image.load(missile_dir).convert()
    17 spaceship_dir = path.join(img_dir,'spaceShips_007.png')
    18 spaceship_img = pygame.image.load(spaceship_dir).convert()
    19 spaceship_bullet_dir = path.join(img_dir,'spaceMissiles_001.png')
    20 spaceship_bullet_img = pygame.image.load(spaceship_bullet_dir).convert()

 

  • Bgm及音效文件的导入
    1 sound_dir = path.join(path.dirname(__file__),'sound')
    2 shoot_sound = pygame.mixer.Sound(path.join(sound_dir,'Laser_Shoot14.wav'))
    3 explosion_sound = pygame.mixer.Sound(path.join(sound_dir,'Explosion7.wav'))
    4 missile_sound = pygame.mixer.Sound(path.join(sound_dir,'Laser_Shoot5.wav'))
    5 pygame.mixer.music.load(path.join(sound_dir,'background_01.wav'))

 

  • 游戏精灵类的创建
     1 class Player(pygame.sprite.Sprite):
     2 
     3     def __init__(self):
     4         pygame.sprite.Sprite.__init__(self)
     5 #        self.image = pygame.Surface((50,50))
     6         self.image = pygame.transform.flip(player_img,False,True)
     7         self.image = pygame.transform.scale(self.image,(53,40))
     8         self.image.set_colorkey((0,0,0))
     9 #        self.image.fill((0,255,0))
    10         self.rect = self.image.get_rect()
    11         self.rect.centerx = WIDTH/2
    12         self.rect.bottom = HEIGHT
    13         self.radius = 20
    14         self.score = 0
    15 
    16 
    17         self.hp = 100
    18         self.lives =3
    19         self.hidden = False
    20         self.hide_time = 0
    21 
    22         self.is_missile_firing = False
    23         self.start_missile_time = 0
    24         self.last_missile_time = 0
    25 
    26 
    27 
    28 
    29     def update(self):
    30         key_state = pygame.key.get_pressed()
    31         if key_state[pygame.K_LEFT] or key_state[pygame.K_a]:
    32             self.rect.x -= 5
    33         if key_state[pygame.K_RIGHT] or key_state[pygame.K_d]:
    34             self.rect.x += 5
    35         if key_state[pygame.K_UP] or key_state[pygame.K_w]:
    36             self.rect.y -= 5
    37         if key_state[pygame.K_DOWN] or key_state[pygame.K_s]:
    38             self.rect.y += 5
    39         if self.rect.right > WIDTH:
    40             self.rect.right = WIDTH
    41         if self.rect.left < 0:
    42             self.rect.left = 0
    43         if self.rect.y < 0:
    44             self.rect.y = 0
    45         if self.rect.y > HEIGHT:
    46             self.rect.y = HEIGHT
    47 
    48     
    49         now = pygame.time.get_ticks()
    50         if self.hidden and now - self.hide_time > 1000:
    51             self.hidden = False
    52             self.rect.bottom = HEIGHT
    53             self.hp = 100
    54 
    55         if self.is_missile_firing:
    56             if now - self.start_missile_time <= MISSILE_LIFETIME:
    57                 if now - self.last_missile_time > MISSILE_INTERVAL:
    58                     missile = Missile(self.rect.center)
    59                     missiles.add(missile)
    60                     self.last_missile_time = now
    61             else:
    62                 self.is_missile_firing = False
    63 
    64 
    65 
    66     def shoot(self):
    67         bullet = Bullet(self.rect.centerx,self.rect.centery)
    68         bullets.add(bullet)
    69         shoot_sound.play()
    70 
    71     def fire_missile(self):
    72         self.is_missile_firing = True
    73         self.start_missile_time = pygame.time.get_ticks()
    74 
    75     def hide(self):
    76         self.hidden = True
    77         self.rect.y = HEIGHT
    78         self.hide_time = pygame.time.get_ticks()

 

  • 动态地图的实现
     1 class Dynamic_Background1(pygame.sprite.Sprite):
     2 
     3     def __init__(self):
     4         pygame.sprite.Sprite.__init__(self)
     5         self.image = pygame.transform.flip(background_img1,False,False)
     6         self.rect = self.image.get_rect()
     7         self.speed = 3
     8         self.last_time = pygame.time.get_ticks()
     9 
    10     def update(self):
    11         now = pygame.time.get_ticks()
    12         if now - self.last_time > 5:
    13             self.rect.y += self.speed
    14             self.last_time = now
    15             while self.rect.y >= HEIGHT:
    16                 self.rect.y = -self.rect.height
    17                 dynamic_background2.update()
    18 
    19 
    20         for event in pygame.event.get():
    21             if event.type == pygame.QUIT:
    22                 game_over == True
    23             if event.type == pygame.KEYDOWN:
    24                 if event.type == pygame.K_ESCAPE:
    25                     game_over == True
    26 
    27 
    28 class Dynamic_Background2(pygame.sprite.Sprite):
    29 
    30     def __init__(self):
    31         pygame.sprite.Sprite.__init__(self)
    32         self.image = pygame.transform.flip(background_img2,False,False)
    33         self.rect = self.image.get_rect()
    34         self.rect.y = -self.rect.height
    35         self.speed = 3
    36         self.last_time = pygame.time.get_ticks()
    37 
    38     def update(self):
    39         now = pygame.time.get_ticks()
    40         if now - self.last_time > 5:
    41             self.rect.y += self.speed
    42             self.last_time = now
    43             while self.rect.y >= HEIGHT:
    44                 self.rect.y = -self.rect.height
    45                 dynamic_background1.update()
    46 
    47         for event in pygame.event.get():
    48             if event.type == pygame.QUIT:
    49                 game_over == True
    50             if event.type == pygame.KEYDOWN:
    51                 if event.type == pygame.K_ESCAPE:
    52                     game_over == True

 

  • UI界面的实现
     1 def show_menu():
     2     global game_state,screen
     3     font_name = pygame.font.match_font('arial')
     4     font = pygame.font.Font(font_name,40)
     5     screen.blit(background_img3,background_rect)
     6 
     7     # rect1 = pygame.draw.rect(screen,(255,255,255),(WIDTH/20,80, 550, 100), 10)
     8     # screen.blit(font.render('SPACE SHOOTER',True,(0,255,0)), (150, 100))
     9     draw_text('SPACE SHOOTER',screen,(0,255,0),70,WIDTH/2,100)
    10     rect2 = pygame.draw.rect(screen,(0,255,0),(WIDTH/7 + 80,350, 400, 50), 10)
    11     screen.blit(font.render('Press Space key to start',True,(255,255,0)), (220, 350))
    12     rect3 = pygame.draw.rect(screen,(0,255,0),(WIDTH/7 + 80,450, 400, 50), 10)
    13     screen.blit(font.render('Press Esc key to quit',True,(255,255,0)), (220, 450))

 

  • 爆炸,太空站等动态效果的实现
     1 explosion_animation = []
     2 for i in range(9):
     3     explosion_dir = path.join(img_dir,'regularExplosion0{}.png'.format(i))
     4     explosion_img = pygame.image.load(explosion_dir).convert()
     5     explosion_animation.append(explosion_img)
     6 
     7 spaceship_zhan_animation = []
     8 for i in range(14,16):
     9     spaceship_zhan_dir = path.join(img_dir,'spaceBuilding_0{}.png'.format(i))
    10     spaceship_zhan_img = pygame.image.load(spaceship_zhan_dir).convert()
    11     spaceship_zhan_animation.append(spaceship_zhan_img)
    12 
    13 
    14 space_plant_animation = []
    15 for i in range(6,10):
    16     space_plant_dir = path.join(img_dir,'spaceBuilding_00{}.png'.format(i))
    17     space_plant_img = pygame.image.load(space_plant_dir).convert()
    18     space_plant_animation.append(space_plant_img)
    19 
    20 powerup_imgs = {}
    21 powerup_add_hp_dir = path.join(img_dir,'gem_red.png')
    22 powerup_imgs['add_hp'] = pygame.image.load(powerup_add_hp_dir).convert()
    23 powerup_add_life_dir = path.join(img_dir,'heartFull.png')
    24 powerup_imgs['add_life'] = pygame.image.load(powerup_add_life_dir).convert()
    25 powerup_add_missile_dir = path.join(img_dir,'gem_yellow.png')
    26 powerup_imgs['add_missile'] = pygame.image.load(powerup_add_missile_dir).convert()

 

  • 游戏精灵对象实例化
     1 dynamic_background1 = Dynamic_Background1()
     2 dynamic_background2 = Dynamic_Background2()
     3 space_plant_entity = Space_plant_entity()
     4 # spaceship_boss_one =Spaceship_Boss_One()
     5 player = Player()
     6 spaceship_zhan_shiwu = Spaceship_zhan_shiwu()
     7 enemys = pygame.sprite.Group()
     8 for i in range(7):
     9     enemy = Enemy()
    10     enemys.add(enemy)
    11 spaceships = pygame.sprite.Group()
    12 for i in range(5):
    13     spaceship = Spaceship()
    14     spaceships.add(spaceship)
    15 bullets = pygame.sprite.Group()
    16 spaceship_bullets = pygame.sprite.Group()
    17 missiles = pygame.sprite.Group()
    18 explosions = pygame.sprite.Group()
    19 powerups = pygame.sprite.Group()

 

  • 游戏画面的动态更新
     1                 dynamic_background1.update()
     2                 dynamic_background2.update()
     3                 player.update()
     4                 enemys.update()
     5                 bullets.update()
     6                 missiles.update()
     7                 explosions.update()
     8                 powerups.update()
     9                 spaceships.update()
    10                 spaceship_bullets.update()
    11                 # spaceship_boss_one_bullets.update()
    12                 spaceship_zhan_shiwu.update()
    13                 space_plant_entity.update()

 

  • 游戏精灵之间的碰撞检测
     1                 hits = pygame.sprite.spritecollide(player,enemys,True,pygame.sprite.collide_circle)
     2                 for hit in hits:
     3                     player.hp -= 30
     4                     if player.hp<0:
     5                         player.lives -= 1
     6                         player.hp = 100 
     7                         player.hide()
     8                         if player.lives == 0:
     9                             game_over = True
    10                 hits = pygame.sprite.spritecollide(player,spaceships,True,pygame.sprite.collide_circle)
    11                 for hit in hits:
    12                     player.hp -= 40
    13                     if player.hp<0:
    14                         player.lives -= 1
    15                         player.hp = 100
    16                         player.hide()
    17                         if player.lives == 0:
    18                             game_over = True
    19                 hits = pygame.sprite.spritecollide(player,spaceship_bullets,True,pygame.sprite.collide_circle)
    20                 for hit in hits:
    21                     player.hp -= 10  
    22                     if player.hp<0:
    23                         player.lives -= 1
    24                         player.hp = 100
    25                         player.hide()
    26                         if player.lives == 0:
    27                             game_over = True

 

  • 游戏精灵组之间的碰撞检测
     1                 hits_bullets = pygame.sprite.groupcollide(enemys,bullets,True,True)
     2                 hits_missiles = pygame.sprite.groupcollide(enemys,missiles,True,True)
     3                 hits_spaceships = pygame.sprite.groupcollide(spaceships,bullets,True,True)
     4                 hits_spaceships_and_missiles = pygame.sprite.groupcollide(spaceships,missiles,True,False)  
     5                 hits = {}
     6                 hits.update(hits_bullets)
     7                 hits.update(hits_missiles)
     8                 hits.update(hits_spaceships)
     9                 hits.update(hits_spaceships_and_missiles)
    10                 for hit in hits:
    11                     enemy = Enemy()    
    12                     enemys.add(enemy)
    13                     explosion = Explosion(hit.rect.center)
    14                     explosions.add(explosion)
    15                     player.score += (100 - hit.radius)
    16                     if random.random() > 0.9:
    17                         powerup = Powerup(hit.rect.center)
    18                         powerups.add(powerup)
    19 
    20 
    21                 hits = pygame.sprite.spritecollide(player,powerups,True)
    22                 for hit in hits:
    23                     if hit.type == 'add_hp':
    24                         player.hp += 50
    25                         if player.hp > 100:
    26                             player.hp = 100
    27                     elif hit.type == 'add_life':
    28                         player.lives += 1
    29                         if player.lives > 3:
    30                             player.lives = 3
    31                     else:
    32                         player.fire_missile()

 

  • 玩家生命进度UI的实现
     1 def draw_ui():
     2     pygame.draw.rect(screen,(0,255,0),(10,10,player.hp,15))
     3     pygame.draw.rect(screen,(255,255,255),(10,10,100,15),2)
     4 
     5     draw_text(str(player.score),screen,(255,255,255),20,WIDTH/2,10)
     6 
     7     img_rect = player_img_small.get_rect()
     8     img_rect.right = WIDTH - 10
     9     img_rect.top = 10
    10     for _ in range(player.lives):
    11         screen.blit(player_img_small,img_rect)
    12         img_rect.x -= img_rect.width + 10

 

  • 游戏初始化
    1 pygame.mixer.pre_init(44100,-16,2,2048)
    2 pygame.mixer.init()
    3 pygame.init()
    4 screen = pygame.display.set_mode((WIDTH,HEIGHT))
    5 pygame.display.set_caption("My Game")
    6 clock = pygame.time.Clock()

 

  • 游戏主程序的运行
     1 if __name__ == '__main__':
     2         while not game_over:
     3             clock.tick(60)
     4             if game_state == 0:
     5                 show_menu()
     6             else:
     7                 event_list = pygame.event.get()
     8                 for event in event_list:
     9                     if event.type == pygame.QUIT:
    10                         game_over = True
    11                     if event.type == pygame.KEYDOWN:
    12                         if event.key == pygame.K_ESCAPE:
    13                             game_over = True 
    14                         if event.key == pygame.K_SPACE:
    15                             player.shoot()
    16 
    17                 now = pygame.time.get_ticks()
    18                 if now - last_enemy_generate_time > NEW_ENEMY_GENERATE_INTERVAL:
    19                     enemy = Enemy()
    20                     enemys.add(enemy)
    21                     last_enemy_generate_time = now    
    22 
    23                 if now - last_spaceship_generate_time > NEW_SPACESHIP_GENERATE_INTERVAL:
    24                     spaceship = Spaceship()
    25                     spaceships.add(spaceship)
    26                     last_spaceship_generate_time = now

     注意bgm及音效的路径,我的是相对路径,路径一定要对,否则程序无法读取图片及音乐哦!

 

游戏画面

  • UI界面

         

 

  • 玩家生命条数及生命数UI画面

     

 

  • 游戏画面

     

                       

由于博客园不能上传视频,在此我提供游戏视频观看连接:https://mp.weixin.qq.com/s/j7PhvAJKzrN0ntLgpowcqA

 

更进一步设计:你可以添加boss,关卡,游戏动态特效等等

Sublime Text 官网:https://www.sublimetext.com

Pygame官网:https://www.pygame.org/news

Python官网:https://www.python.org

 

原创不易,如果觉得有点用,希望可以随手点个赞,拜谢各位老铁!

 


 

 

作者Info

作者:南柯树下,Goal:让编程更有趣!

原创微信公众号:『小鸿星空科技』,专注于算法、爬虫,网站,游戏开发,数据分析、自然语言处理,AI等,期待你的关注,让我们一起成长、一起Coding!

版权声明:本文禁止抄袭、转载 ,侵权必究!

 


扫码关注我的公众号,回复 “太空大战” 获取完整项目,包括源码游戏图片素材音乐和音效,我们一起成长,一起Coding,让编程更有趣!


  

——  ——  ——  ——  —  END  ——  ——  ——  ——  ———— 

         欢迎扫码关注我的公众号

          小鸿星空科技

    

posted @ 2020-11-25 00:34  南柯树下  阅读(1633)  评论(0编辑  收藏  举报