飞机大战游戏

Pygame模块下载及导入创建

在电脑中用pip install pygame命令安装pygame模块并导入pycharm中

先创建一个飞机大战项目文件,所有代码都写在这个文件里,创建好后将游戏的图片文件拷贝到项目文件下

pip install pygame

创建游戏窗口

创建窗口

在上面创建的飞机大战文件中创建py文件,在里面写以下所有代码。

首先导入pygame包,利用import pygame命令实现导入;再创建游戏窗口设置元组set_mode,在元组中设置其宽高。

import pygame

pygame.init()  # 初始化

# 创建游戏窗口

pygame.display.set_mode((480,650)) # 元组中480表示宽度, 650表示高度

pygame.quit() # 卸载模块,释放资源【】

使游戏循环

通过语句While True实现游戏循环,位置写在pygame.quit()上方

# 游戏循环

while True:

   pass

修改游戏名称和图标

主要修改游戏的名称和图标,使其变成飞机大战游戏专有

Set_caption修改游戏名称,image.load导入图片set.icon修改图标为导入的图片

# 修改游戏名称

pygame.display.set_caption("飞机大战")

# 修改游戏图标

icon = pygame.image.load("img/icon72x72.png")

pygame.display.set_icon(icon)

绘制游戏背景和英雄机精灵

绘制游戏背景

首先image.load加载图片,screen.blit将背景图片加载到窗口中,并将其设置到原点位置(0,0)

#加载背景图片

bg_img = pygame.image.load("img/background.png")

#将背景图片加载到窗口中,(0,0)表示背景图片放到原点位置

screen.blit(bg_img,(0,0))

绘制英雄机

image.load加载图片,用.....if...else....绘制英雄精灵图片将英雄飞机绘制到游戏窗口上,要设计heroIndexShif = 0 作为切换图片索引,rect定义英雄机。

其中,飞机位置的确认是这样的,窗口的大小都是 480*650,飞机大小是100*124,由于飞机初始化的时候在窗口的正下方,所以英雄机的坐标为(190,526)

heroIndexShif = 0 #作为切换图片索引

hero_rect = pygame.rect.Rect(190,526,66,80) # 定义英雄机rect

# 将英雄的飞机绘制到窗口上

   if heroIndexShift == 0:

       screen.blit(hero_img1,(hero_rect.x,hero_rect.y))

       heroIndexShift +=1

   else:

       screen.blit(hero_img2,(hero_rect.x,hero_rect.y))

       heroIndexShift = 0

设置游戏时钟

主要是为了设置游戏的刷新次数,创建游戏时钟,在游戏循环中设置时钟为每秒钟刷新60次

# 创建游戏时钟

clock = pygame.time.Clock()

clock.tick(60) # 60表示每秒钟刷新60

更改英雄机坐标位置

主要是为了英雄精灵实现上下自动移动首先rect.y修改英雄飞机的y轴值,让飞机从底部飞进

  # 修改英雄飞机的y轴值

   hero_rect.y -= 1

   # 让飞机从底部飞进

   if hero_rect.bottom <=0:

       hero_rect.y = 650

事件监听和控制英雄机移动

游戏事件监听

通过事件监听来接收鼠标和键盘对英雄机的控制,一定要增添事件监听,否则游戏将不能实现正常关闭。

  1. 首先获取所有事件

 event_list = pygame.event.get()

  1. 获取窗口退出事件

 for event in event_list:

if event.type == pygame.QUIT:# 加上这个模块就不卡了

   print("游戏结束了.......")

   pygame.quit() # 卸载模块

   exit(0)

终止Python程序, exit(0)表示正常退出 exit(1)表示异常退出。

控制英雄机移动

通过if elif实现对英雄机的上下左右移动控制,一定要计算好英雄机移动数值,要设置定义按键动作重复执行。

   if  event.type == pygame.KEYDOWN:

           if event.key == pygame.K_LEFT:# 向左移动

               heroPlaneX = heroPlaneX - 5 if heroPlaneX >= 5 else 0

           elif event.key == pygame.K_RIGHT:# 向右移动

               heroPlaneX = heroPlaneX +5 if heroPlaneX <= 375 else 380

           elif event.key == pygame.K_DOWN: # 向下移动

               heroPlaneY = heroPlaneY + 5 if heroPlaneY <= 521 else 526

           elif event.key == pygame.K_UP: # 向上移动

               heroPlaneY = heroPlaneY -5 if heroPlaneY >= 5 else 0

pygame.key.set_repeat(20,30)

在使按键动作重复执行时,set_repeat(20,30)中20,30都是毫秒级的,20代表按下键盘20 ms后反应,30代表当在30 ms内还没有抬起键盘,就会再给一个20 ms按键反应。

绘制敌机和控制敌机移动

绘制敌机精灵

加载敌机精灵图片到游戏中,定义敌机精灵的rect以及xy坐标,绘制出的敌机精灵要和英雄机大小相似,且要使敌机精灵在游戏显示窗口上方位置。

# 加载敌机图片

enemy_img = pygame.image.load("img/enemy1.png")

# 定义敌机的rect

enemy_rect = pygame.rect.Rect(206,0,69,89) # x= 480//2-69//2

# 英雄机的x,y轴坐标

enemyPlaneX = enemy_rect.x

enemyPlaneY = enemy_rect.y

# 绘制敌机精灵

screen.blit(enemy_img,(enemyPlaneX,enemyPlaneY))

控制敌机移动

通过if elif实现对敌机的上下左右移动控制,一定要计算好英雄机移动数值,要在游戏循环代码外进行设置。

   if direct == "":

       enemyPlaneX -= 5

       if enemyPlaneX <= 0:

           direct = ""

   elif direct == "":

       enemyPlaneX += 5

       if enemyPlaneX >= 480-69:

           direct = ""

绘制敌机子弹和英雄机子弹

绘制英雄机与敌机子弹时我们采取类方法来进行定义,draw用来画子弹,然后定义xy坐标和窗口对象,elif设置英雄机控制发射子弹,实例化子弹对象并将子弹添加到列表中。要画出每一个子弹,在画敌机子弹时要产生随机性。实例化每一个子弹并让子弹到最下面的时候消失。

class HeroBullet():

   """

  英雄精灵子弹的类

  """

   def __init__(self, x, y, screen):

       """

      :param x: x坐标

      :param y: y 坐标

      :param screen: 窗口对象

      """

       self.x = x

       self.y = y

       self.screen = screen

       self.pic = pygame.image.load("img/bullet.png")

   def draw(self):

       """用来画子弹"""

       self.screen.blit(self.pic, (self.x, self.y))

       self.move()

   def move(self):

       self.y -= 5

class EnemyBullet():

   """敌机精灵子弹类"""

   def __init__(self, x, y, screen):

       self.x = x

       self.y = y

       self.screen = screen

       self.pic = pygame.image.load("img/bullet1.png")

   def draw(self):

       """用来画子弹"""

       self.screen.blit(self.pic, (self.x, self.y))

       self.move()

   def move(self):

       self.y -= 5

画出英雄机子弹

   elif event.key == pygame.K_SPACE:  # 英雄机控制发射子弹

               # 实例化子弹对象

               hero_bullet = HeroBullet(heroPlaneX + 50 - 11, heroPlaneY - 22, screen)         # 把子弹添加到列表里

               HeroBiulist.append(hero_bullet)

# 画出英雄战机的子弹每一个子弹

   for bullet in HeroBiulist:

       bullet.draw()

       # 让子弹到最上边的时候消失

       HeroBiulist.remove(bullet) if bullet.y < 0 else ""

画出敌机子弹

 # 产生随机数

   x = random.randint(0,100)

   if x == 5 or x == 78:

       # 实例化一个子弹

       enemy_bullet = EnemyBullet(enemyPlaneX+69//2-9//2,enemyPlaneY+89,screen)

       # 产生的每一个子弹放到一个列表里

       EnemyBiulist.append(enemy_bullet)

   for bullet in EnemyBiulist:

       bullet.draw() # 绘制子弹

       # 让子弹到最下面的时候消失

       EnemyBiulist.remove(bullet) if bullet.y >650-89 -21//2  else ""

   pygame.display.update()

绘制敌机爆炸和英雄机爆炸

绘制敌机爆炸

绘制爆炸及碰撞检测,设置爆炸条件和图片索引,控制敌机爆炸条件,检测敌机和子弹的矩形是否相交,绘制敌机爆炸图片, 当敌机爆炸图片的下表和图片总数相同时,说明爆炸图片已经绘制结束。在这里要用到colliderect()函数,语法为rect1.colliderect(rect2)

 is_bomb = False  # 爆炸条件

  enemy_bomb_index = 0  # 爆炸图片索引

  # 控制敌机爆炸的条件

   for bullet in HeroBiulist:

 定义子弹的rect,检测敌机和子弹的矩形是否相交,并绘制敌机爆炸图片放入游戏,用if  else做循环检测是否为真,从而执行爆炸命令。

       hero_bullet_rect = pygame.rect.Rect(bullet.x, bullet.y,10,10)

       flag = pygame.Rect.colliderect(enemy_rect,hero_bullet_rect)# 检测敌机和子弹的矩形是否相交

       if flag:

           print("敌机爆炸了......")

           enemy_bomb = True # 爆炸条件为真

           HeroBiulist.remove(bullet)

   enemy_bomb_list = ["img/enemy1_down1.png", "img/enemy1_down2.png", "img/enemy1_down3.png", "img/enemy1_down4.png"]

   # 绘制敌机爆炸的图片

   if enemy_bomb == False:

       # 如果没有检测到爆炸,就绘制没有爆炸敌机的图片

       screen.blit(enemy_img, (enemyPlaneX, enemyPlaneY))

   else:# 绘制敌机爆炸

       if enemy_bomb_index == len(enemy_bomb_list):# 当敌机爆炸图片的下表和图片总数相同时,说明爆炸图片已经绘制结束

           time.sleep(0.2)

           exit(0)# 结束程序

       enemy_bomb_img = pygame.image.load(enemy_bomb_list[enemy_bomb_index])# 加载敌机爆炸图片

       screen.blit(enemy_bomb_img, (enemyPlaneX, enemyPlaneY))# 绘制敌机爆炸图片

       enemy_bomb_index +=1

       time.sleep(0.2)

绘制英雄机爆炸

设置英雄机爆炸条件及图片索引,定义子弹将英雄飞机绘制到窗口上,当爆炸图片加载结束后,加载并绘制英雄飞机爆炸的图片。我们只需要循环遍历每一颗已经发射的子弹,子弹和每一个敌人飞机的矩形是否相交,如果相交,说明子弹击中了敌机,我们对应做行为就可以了。

hero_is_bomb = False # 英雄机爆炸条件

hero_bomb_index = 0  # 英雄机爆炸图片索引

for bullet in EnemyBiulist:

       enemy_bullet_rect = pygame.rect.Rect(bullet.x, bullet.y, 9, 21)  # 定义敌机子弹rect

       flag = enemy_bullet_rect.colliderect(hero_rect)  # 英雄机爆炸的条件

       if flag:

           print("英雄爆炸了.....")

           hero_is_bomb = True  # 爆炸条件为真

           EnemyBiulist.remove(bullet)# 当战机爆炸的时候,移除子弹

   if hero_is_bomb == False:

       # 将英雄的飞机绘制到窗口上

       if heroIndexShift == 0:

           screen.blit(hero_img1, (heroPlaneX, heroPlaneY))

           heroIndexShift += 1

       else:

           screen.blit(hero_img2, (heroPlaneX, heroPlaneY))

           heroIndexShift = 0

   else:

       if hero_bomb_index == len(hero_bomb_list):# 当爆炸图片加载结束后

           time.sleep(0.3)

           exit()

       # 加载英雄机爆炸图片

       hero_bomb_img = pygame.image.load(hero_bomb_list[hero_bomb_index])

       # 绘制英雄机爆炸的图片

       screen.blit(hero_bomb_img,(heroPlaneX,heroPlaneY))

       hero_bomb_index += 1

       time.sleep(0.2)

飞机大战游戏项目完整代码

import random
import pygame
import time
pygame.init()

#创建窗口
screen=pygame.display.set_mode((480,650))#480为宽,500为高
#
修改游戏名称
pygame.display.set_caption('飞机大战')
#修改游戏图标
icon = pygame.image.load("img/icon.png")
pygame.display.set_icon(icon)

# 加载背景
bg_img = pygame.image.load('img/background.png')
#加载精灵图片
hero_img1 = pygame.image.load("img/me1.png")
hero_img2 = pygame.image.load(
"img/me2.png")
#加载战机战损
hero_bomb_imgs=["img/me_destroy_1.png",
                  
"img/me_destroy_2.png", "img/me_destroy_3.png", "img/me_destroy_4.png"]
#作为切换的索引值
shitindex=0
#定义英雄机位置
hero_rect=pygame.rect.Rect(190,525,100,124)
#设置精灵XY
hero_PlaneX=hero_rect.x
hero_PlaneY=hero_rect.y

#加载敌机图片
enemy_img=pygame.image.load('img/enemy2.png')
enemy_img2=pygame.image.load(
"img/enemy2_hit.png")
#加载敌机战损
enemy_bomb_imgs=["img/enemy2_down1.png",
                  
"img/enemy2_down2.png", "img/enemy2_down3.png", "img/enemy2_down4.png"]
#定义敌机位置
enemy_rect=pygame.rect.Rect(158,0,69,99#(480-69)/2
enemyPlaneX=enemy_rect.x
enemyPlaneY=enemy_rect.y

#设置灵敏度
pygame.key.set_repeat(20,30)
#定义时钟
clock=pygame.time.Clock()
#定义图片切换索引
hero_imgindex=0
#定义敌机初始移动方向
direct='left'
#定义英雄机子弹   子弹类
class HeroBullet:
   
def __init__(self,x,y,screen):
       
self.x=x
       
self.y=y
       
self.screen=screen
       
self.pic=pygame.image.load('img/bullet1.png')
   
#画子弹
   
def draw(self):
       
self.screen.blit(self.pic,(self.x,self.y))
       
self.move()
   
#子弹移动方法
   
def move(self):
       
self.y-=5
#英雄机子弹列表
hero_Bulletlist=[]
#定义敌机子弹
class EnemyBullet:
   
def __init__(self, x, y, screen):
       
self.x = x
       
self.y = y
       
self.screen = screen
       
self.pic = pygame.image.load('img/bullet2.png')
   
# 画子弹
   
def draw(self):
       
self.screen.blit(self.pic, (self.x, self.y))
       
self.move()
   
# 子弹移动方法
   
def move(self):
       
self.y+=5
#敌机子弹列表
enemy_list=[]
#英雄机爆炸
hero_bomb=False
#英雄机爆炸索引
hero_bomb_index=
#敌机爆炸条件
enemy_bomb=False
#敌机爆炸索引
enemy_bomb_index=0
#游戏循环
while True:
    clock.tick(
60)#60表示每秒刷新60
    #
图片背景
   
screen.blit(bg_img, (0, 0))
   
# 修改飞机y,实现自动飞行
   
hero_PlaneY -=1
   
# 飞机从底部飞出
   
if hero_PlaneY<0:
       hero_PlaneY=
650
   
#绘制敌机
   
screen.blit(enemy_img,(enemyPlaneX,enemyPlaneY))

   
# 控制敌机移动
   
if direct =='left':
        enemyPlaneX-=
5
       
if enemyPlaneX<=0:
            direct=
'right'
   
elif direct=='right':
        enemyPlaneX=enemyPlaneX + 
5
       
if enemyPlaneX >=480-165:
            direct=
'left'

   
x=random.randint(1,100)
   
if x==5 or x==78 :
       
#绘制敌机子弹
       
enemybullet=EnemyBullet(enemyPlaneX+69/2-5/2,enemyPlaneY+99,screen)
        enemy_list.append(enemybullet)
   
for bullet2 in enemy_list:
        bullet2.draw()
        enemy_bullet_rect = pygame.rect.Rect(bullet2.x, bullet2.y,
5, 11)
        flag2 = enemy_bullet_rect.colliderect(hero_rect)
       
if flag2:
           
print("战机爆炸")
            hero_bomb =
True
           
enemy_list.remove(bullet2)
   
if hero_bomb == False:
           
# 英雄机绘制到窗口
       
if shitindex == 0:
            screen.blit(hero_img1, (hero_PlaneX, hero_PlaneY))
            shitindex =
1
       
else:
            screen.blit(hero_img2, (hero_PlaneX, hero_PlaneY))
            shitindex =
0
   
else:
       
if hero_bomb_index == len(hero_bomb_imgs):
            time.sleep(
0.3)
           
exit()
        hero_bomb_img = pygame.image.load(hero_bomb_imgs[hero_bomb_index])
        screen.blit(hero_bomb_img, (hero_PlaneX, hero_PlaneY)) 
# 绘制爆炸图片
       
hero_bomb_index += 1
       
time.sleep(0.09)
   
# 对事件进行监听 获取所有事件
   
event_list = pygame.event.get()
   
#捕捉窗口退出事件
   
for event in event_list:
       
if event.type == pygame.QUIT:  # 加上这个模块就不卡了
           
print("游戏结束了.......")
            pygame.quit() 
# 卸载模块
           
exit(0# 终止Python程序, exit(0)表示正常退出 exit(1)表示异常退出
   
#
控制英雄精灵移动
       
if event.type == pygame.KEYDOWN:
           
if event.key == pygame.K_LEFT:
                hero_PlaneX = hero_PlaneX -
5 if hero_PlaneX >= 5 else 0
           
elif event.key == pygame.K_RIGHT:
                hero_PlaneX = hero_PlaneX +
5 if hero_PlaneX <= 375 else 380
           
elif event.key == pygame.K_DOWN:
                hero_PlaneY  = hero_PlaneY  +
5 if hero_PlaneY  <= 521 else 526
           
elif event.key == pygame.K_UP:
                hero_PlaneY  = hero_PlaneY  -
5 if hero_PlaneY >= 5 else 0
           
elif event.key == pygame.K_SPACE:
               
#调用子弹的方法属性
               
hero_bullet=HeroBullet(hero_PlaneX+50,hero_PlaneY-11,screen)
               
#把子弹放入列表中  子弹是多个 我们将多个实例化的子弹放表中
               
hero_Bulletlist.append(hero_bullet)
   
for bullet in hero_Bulletlist:
        bullet.draw()
       
#让子弹到最上面的时候消失
       
hero_Bulletlist.remove(bullet) if bullet.y < 0 else ''
       
# 定义英雄子弹rect
       
hero_bullet_rect = pygame.rect.Rect(bullet.x, bullet.y, 5, 11)
       
# 碰撞检测
       
flag = hero_bullet_rect.colliderect(enemy_rect)
       
if flag:
           
print("敌机爆炸")
            enemy_bomb =
True
           
hero_Bulletlist.remove(bullet)
   
if enemy_bomb == False:
           
#切换图片, # 绘制敌机图片
       
if enemy_bomb_index == 0:
            screen.blit(enemy_img, (enemyPlaneX, enemyPlaneY))
            enemy_bomb_index =
1
       
else:
            screen.blit(enemy_img2, (enemyPlaneX, enemyPlaneY))
            enemy_bomb_index =
0
   
else:
       
if enemy_bomb_index == len(enemy_bomb_imgs):
               
# 当敌机爆炸索引与图片总数相同时,退出游戏
           
time.sleep(0.2)
           
exit(0)
        enemy_bomb_img = pygame.image.load(enemy_bomb_imgs[enemy_bomb_index])
        screen.blit(enemy_bomb_img, (enemyPlaneX, enemyPlaneY)) 
# 绘制爆炸图片
       
enemy_bomb_index += 1
       
time.sleep(0.2)
# 图片更新
   
pygame.display.update()
# pygame.quit()

  • 40
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值