python实现大战外星人小游戏实例代码


Posted in Python onDecember 26, 2019

主程序

import pygame
from pygame.sprite import Group
from settings import Settings
from game_stats import gameStats
from ship import Ship
from button import Button
import game_functions as gf
def run_game():
  #初始化背景设置
  pygame.init()
  #创建一个Settings实例,并将其储存在变量ai_settings中
  ai_settings = Settings()
  #创建一个名为screen的显示窗口,游戏的所有图形元素都在其中绘制
  screen = pygame.display.set_mode((ai_settings.screen_heigth,
                   ai_settings.screen_width))
  pygame.display.set_caption("Aline invasion")
  #创建play按钮
  play_button = Button(ai_settings,screen,"play")
  #创建一个用于存储游戏统计数据的实例
  stats = gameStats(ai_settings)
  #创建一艘飞船,一个子弹编组,和一个外星人编组
  ship =Ship(ai_settings,screen)
  bullets = Group()
  aliens = Group()
  #创建外星人群
  gf.create_fleet(ai_settings, screen, ship, aliens)
  #开始游戏主循环
  while True:
    #监视鼠标和键盘事件
    gf.check_events(ai_settings,screen,ship,bullets)
    if stats.game_active:
      # 飞船移动
      ship.update()
      #子弹移动
      gf.update_bullets(ai_settings, screen, ship, aliens,bullets)
      gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets)
    #重绘屏幕
    gf.update_screen(ai_settings, screen, stats, ship, bullets, aliens, play_button)
run_game()

game_functions.py

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleep
def check_keydown_events(event,ai_settings,screen, ship, bullets):
  '''响应按下'''
  if event.key == pygame.K_RIGHT:
    ship.moving_right = True
  elif event.key == pygame.K_LEFT:
    ship.moving_left = True
  elif event.key == pygame.K_UP:
    ship.moving_up = True
  elif event.key == pygame.K_DOWN:
    ship.moving_down = True
  elif event.key == pygame.K_q:
    sys.exit()
  #当飞船移动时也能发射子弹
  if event.key == pygame.K_SPACE:
    fire_bullet(ai_settings, screen, ship, bullets)
def check_keyup_events(event, ship):
  if event.key == pygame.K_RIGHT:
    ship.moving_right = False
  elif event.key == pygame.K_LEFT:
    ship.moving_left = False
  elif event.key == pygame.K_UP:
    ship.moving_up = False
  elif event.key == pygame.K_DOWN:
    ship.moving_down = False
def check_events(ai_settings,screen,ship, bullets):
  '''响应鼠标键盘事件'''
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      sys.exit()
    elif event.type == pygame.KEYDOWN:
      check_keydown_events(event, ai_settings, screen, ship, bullets)
    elif event.type == pygame.KEYUP:
      check_keyup_events(event,ship)
def update_screen(ai_settings, screen, stats, ship, bullets, aliens, play_button):
  # 每次循环时都会重绘屏幕
  # 调用方法screen_fill()——用背景色填充屏幕
  screen.fill(ai_settings.screen_bg_color)
  #在飞船和外星人后面重绘所有子弹
  for bullet in bullets.sprites():
    bullet.draw_bullet()
  ship.blitme()
  aliens.draw(screen)
  #aline.blitme()
  #如果游戏处于非活动状态,就绘制play按钮
  if not stats.game_active:
    play_button.draw_button()
  # 让最近绘制的屏幕可见
  pygame.display.flip()
def update_bullets(ai_settings, screen, ship, aliens, bullets):
  bullets.update()
  # 删除已消失的子弹
  for bullet in bullets.copy():
    if bullet.rect.bottom <= 0:
      bullets.remove(bullet)
  #print(len(bullets)) # 显示当前在屏幕上有多少个子弹,从而核实子弹确实被删除了
  check_bullet_alien_collide(ai_settings, screen, ship, aliens, bullets)
def fire_bullet(ai_settings, screen, ship, bullets):
  if len(bullets) < ai_settings.bullet_num:
    # 创建一颗子弹,并将其加入到编组bullets中
    new_bullet = Bullet(ai_settings, screen, ship)
    bullets.add(new_bullet)
def check_bullet_alien_collide(ai_settings, screen, ship, aliens, bullets):
  '''检查是否有子弹击中了外星人
    如果有,就删除相应的外星人和子弹
    遍历编组bullets中所有子弹,再遍历编组aliens中的每个外星人。
    每当子弹与外星人重叠时,groupcllid()就在它返回的字典中添加一个键值对。
    两个实参True告诉pygame删除发生碰撞的子弹和外星人
  '''
  collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
  if len(aliens) == 0:
    # 删除现有所有子弹
    bullets.empty()
    # 当前外星人群消灭干净后,将会立刻出现一个新的外星人群
    create_fleet(ai_settings, screen, ship, aliens)
def get_number_aliens_x(ai_settings, alien_width):
  available_space_x = ai_settings.screen_heigth - 2 * alien_width
  number_aliens_x = int(available_space_x / (2 * alien_width))
  return number_aliens_x
def get_number_rows(ai_settings,ship_height,alien_height):
  '''计算屏幕可以容纳多少行外星人'''
  #以外星人的高度来记长,减去飞船的高度和空出的外星人与飞船间的距离
  available_space_y = (ai_settings.screen_heigth - (10*alien_height) - ship_height)
  number_rows = int(available_space_y/(2*alien_height))    #number_rows为外星人的行数
  return number_rows
def crate_aline(ai_settings, screen, aliens, alien_number, rows_number):
  # 创建一个外星人并将其加入当前行
  alien = Alien(ai_settings, screen)
  alien_width = alien.rect.width
  alien.x = alien_width + 2 * alien_width * alien_number
  alien.rect.x = alien.x
  alien.rect.y = alien.rect.height + 2*alien.rect.height*rows_number
  aliens.add(alien)
def create_fleet(ai_settings, screen, ship, aliens):
  '''创建一个外星人群'''
  #创建一个外星人,并计算一行可容纳多少个外星人'''
  #外星人的间距为外星人的宽度'''
  alien = Alien(ai_settings, screen)
  number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width )
  number_rows = get_number_rows(ai_settings, ship.rect.height, alien.rect.height)
  #穿件外星人群
  for row_number in range(number_rows):
    #创建一个外星人
    for alien_number in range(number_aliens_x):
      crate_aline(ai_settings, screen, aliens, alien_number, row_number)
def check_fleet_edges(ai_settings, aliens):
  '''当外星人到达屏幕边缘时的应对措施'''
  for alien in aliens.sprites():
    if alien.check_edges():
      change_fleet_direction(ai_settings, aliens)
      break
def change_fleet_direction(ai_settings, aliens):
  '''将整群外星人下移,并改变他们的方向'''
  for alien in aliens.sprites():
    alien.rect.y +=ai_settings.fleet_drop_speed
  ai_settings.fleet_direction *= -1
def ship_hit(ai_settings, stats, screen, ship, aliens, bullets):
  '''响应被外星人撞到的飞船'''
  if stats.ships_left > 0:
    # 将ship_left减1
    stats.ships_left -= 1
    # 清空外星人列表和子弹列表
    aliens.empty()
    bullets.empty()
    # 创建一群新的外星人,并将飞船放到屏幕地端中央
    create_fleet(ai_settings, screen, ship, aliens)
    ship.center_ship()
    #暂停
    sleep(0.5)
  else:
    stats.game_active = False
def check_aliens_bottom(ai_setting, stats, screen, ship, aliens, bullets):
  '''检查是否有外星人到达了屏幕底部'''
  screen_rect = screen.get_rect()
  for alien in aliens.sprites():
    if alien.rect.bottom >= screen_rect.bottom:
      #像飞船被撞到一样处理
      ship_hit(ai_setting, stats, screen, ship, aliens, bullets)
      break
def update_aliens(ai_settings, stats, screen, ship, aliens, bullets):
  '''检查是否有外星人位于屏幕边缘,并更新外星人的位置'''
  check_fleet_edges(ai_settings, aliens)
  #更新外星人群中所有外星人的位置'''
  aliens.update()
  #检测外星人和飞船之间的碰撞
  if pygame.sprite.spritecollideany(ship,aliens):
    ship_hit(ai_settings, stats, screen, ship, aliens, bullets)
  #检查是否有外星人到达屏幕底端
  check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets)

ship.py

import pygame
class Ship(object):
  def __init__(self,ai_settings,screen):   #参数screen指定了要将飞船绘制到什么地方
    self.screen = screen
    self.ai_settings = ai_settings
    #加载飞船图像并获取其外接矩形
    self.image = pygame.image.load(r'E:\pycharm project\飞机大战\images\ship.bmp')   #加载图像,这个函数返回一个表示飞船的surface存储到self.image中
    self.rect = self.image.get_rect()    #使用get_rect()获取相应的surface的属性rect
    self.screen_rect = screen.get_rect()
    #将每艘新飞船放在屏幕底部中央
    self.rect.centerx = self.screen_rect.centerx #将self.rect.centerx(飞船中心的x坐标)设置为表示屏幕的矩形属性centerx
    self.rect.bottom = self.screen_rect.bottom #将self.rect.bottom(飞船下边缘的y坐标)设置为表示屏幕的矩形的属性bottom
    #在飞船的属性center中存储小数值
    self.center = float(self.rect.centerx)
    #移动标志
    self.moving_right = False    #添加属性:moving_right
    self.moving_left = False
    self.moving_up = False
    self.moving_down = False
  def update(self):
    '''根据移动标志调整飞船的位置'''
    if self.moving_right and self.rect.right<self.screen_rect.right: #self.rect.right:返回飞船外接矩形右端的x坐标
      self.rect.centerx += self.ai_settings.ship_speed_factor                  #self.screen_rect.right:返回屏幕右侧的坐标
    if self.moving_left and self.rect.left>0:    #与上同理
      self.rect.centerx -= self.ai_settings.ship_speed_factor
    if self.moving_up and self.rect.top>self.screen_rect.top:
      self.rect.bottom -= self.ai_settings.ship_speed_factor
    if self.moving_down and self.rect.bottom<self.screen_rect.bottom:
      self.rect.bottom += self.ai_settings.ship_speed_factor
  def blitme(self):
    '''在指定位置绘制飞船'''
    self.screen.blit(self.image,self.rect)   #根据self.rect指定的位置将图像绘制到屏幕上
  def center_ship(self):
    '''将飞船放在屏幕上居中'''
    self.center = self.screen_rect.centerx

alien.py

import pygame
from pygame.sprite import Sprite
import os
class Alien(Sprite):
  '''代表单个外星人类'''
  def __init__(self, ai_settings, screen):
    '''初始化外星人并设置其初始位置'''
    super(Alien,self).__init__()
    self.ai_settings = ai_settings
    self.screen = screen
    #加载外星人图像,并设置七rect属性
    self.image = pygame.image.load(r'E:\pycharm project\飞机大战\images\alien.bmp')
    self.rect = self.image.get_rect() # 使用get_rect()获取相应的surface的属性rect
    #设置外星飞船的初始位置
    self.rect.x = self.rect.width
    self.rect.y= self.rect.height
    #储存外星人的准确位置
    self.x= float(self.rect.x)
  def check_edges(self):
    '''如果外星人位于屏幕边缘就返回True'''
    screen_rect = self.screen.get_rect()
    if self.rect.right > screen_rect.right:
      return True
    elif self.rect.left < screen_rect.left:
      return True
  def update(self):
    '''向右移动外星人'''
    self.x += (self.ai_settings.alien_speed_factor*self.ai_settings.fleet_direction)
    self.rect.x = self.x
  def blitme(self):
    '''在指定位置绘制外星人'''
    self.screen.blit(self.image,self.rect)

button.py

import pygame.ftfont
class Button():
  def __init__(self,ai_settings, screen, msg):
    '''初始化按钮的属性'''
    self.screen = screen
    self.screen_rect = screen.get_rect()
    #设置按钮的尺寸和其他属性
    self.width, self.height = 200,50
    self.button_color = (0,255,255)
    self.text_color = (255,255,255)
    self.font = pygame.font.SysFont(None,48)
    #创建按钮的rect对象,并使其居中
    self.rect = pygame.Rect(0,0,self.width,self.height)
    self.rect.center = self.screen_rect.center
    #按钮的标签只需创建一次
    self.prep_msg(msg)
  def prep_msg(self,msg):
    '''将msg渲染为图像,并使其在按钮上居中'''
    self.msg_image = self.font.render(msg,True,self.text_color,self.button_color)
    self.msg_image_rect = self.msg_image.get_rect()
    self.msg_image_rect.center = self.rect.center
  def draw_button(self):
    '''绘制一个用颜色填充的按钮,在绘制文本'''
    self.screen.fill(self.button_color,self.rect)
    self.screen.blit(self.msg_image,self.msg_image_rect)

bullet.py

import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):    #Bullet类继承从模块pygame.sprite中导入的Sprite类
  '''一个对飞船发射的子弹进行管理'''    #通过使用精灵,可将游戏中相关的元素编组,进而同时操作编组中的所有元素
  def __init__(self,ai_settings, screen, ship):
    '''在飞船所处的位置创建一个子弹对象'''
    super(Bullet,self).__init__()    #调用super()来继承Sprite
    self.screen = screen

    #在(0,0)处创建一个表是子弹的矩形,在设置正确的位置
    self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,ai_settings.bullet_height)  #子弹并非基于图像,则必须使用pygame.Rect()从空白创建一个矩形
    self.rect.centerx = ship.rect.centerx
    self.rect.top = ship.rect.top

    #存储用小数表示的子弹位置
    self.y = float(self.rect.y)   #将子弹的y坐标存储为小数值

    #设置子弹颜色和速度
    self.color = ai_settings.bullet_color
    self.speed_factor = ai_settings.bullet_speed_factor

  def update(self):
    '''更新表示子弹位置的小数值'''
    self.y -= self.speed_factor
    #更新表示子弹的rect的位置
    self.rect.y = self.y

  def draw_bullet(self):
    '''在屏幕上绘制子弹'''
    pygame.draw.rect(self.screen,self.color,self.rect)   #函数draw.rect()使用存储在self.color中
                                # 的颜色填充表示子弹的rect占据的屏幕

game_stats.py

'''跟踪游戏统计数据'''
class gameStats():
  def __init__(self, ai_settings):
    self.ai_settings = ai_settings
    self.reset_stats()
    #游戏刚启动时处于非活动状态
    self.game_active = False

  def reset_stats(self):
    '''初始化在游戏运行期间可能变化的统计信息'''
    self.ships_left = self.ai_settings.ship_limit

settings.py

class Settings():
  def __init__(self):
    #屏幕设置
    self.screen_heigth = 1000
    self.screen_width = 700
    self.screen_bg_color = (230,230,230)  #设置背景色
    self.ship_speed_factor = 1.5
    self.ship_limit = 3

    self.bullet_speed_factor = 1
    self.bullet_width = 3
    self.bullet_height = 15
    self.bullet_color = 60,60,60
    self.bullet_num = 6

    #外星人设置
    self.alien_speed_factor = 1
    #fleet_drop_speed为有外星人撞到屏幕边缘时下降的速度
    self.fleet_drop_speed = 10
    #当fleet_direction为1时向右,为-1时向左
    self.fleet_direction = 1

总结

以上所述是小编给大家介绍的python实现大战外星人小游戏,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
动态创建类实例代码
Oct 07 Python
python中字典dict常用操作方法实例总结
Apr 04 Python
python通过索引遍历列表的方法
May 04 Python
Python中将字典转换为列表的方法
Sep 21 Python
python爬虫面试宝典(常见问题)
Mar 02 Python
python表格存取的方法
Mar 07 Python
从请求到响应过程中django都做了哪些处理
Aug 01 Python
python实现旋转和水平翻转的方法
Oct 25 Python
解决Numpy中sum函数求和结果维度的问题
Dec 06 Python
Python进程的通信Queue、Pipe实例分析
Mar 30 Python
学会python自动收发邮件 代替你问候女友
May 20 Python
Django haystack实现全文搜索代码示例
Nov 28 Python
Python数据存储之 h5py详解
Dec 26 #Python
Python 使用 prettytable 库打印表格美化输出功能
Dec 26 #Python
Python实现图片识别加翻译功能
Dec 26 #Python
opencv resize图片为正方形尺寸的实现方法
Dec 26 #Python
opencv之为图像添加边界的方法示例
Dec 26 #Python
Python 过滤错误log并导出的实例
Dec 26 #Python
python3 pathlib库Path类方法总结
Dec 26 #Python
You might like
php中大括号作用介绍
2012/03/22 PHP
Linux中为php配置伪静态
2014/12/17 PHP
PHP仿微信多图片预览上传实例代码
2016/09/13 PHP
php文件包含目录配置open_basedir的使用与性能详解
2017/04/03 PHP
枚举JavaScript对象的函数
2006/12/22 Javascript
Web层改进II-用xmlhttp 无声息提交复杂表单
2007/01/22 Javascript
css图片自适应大小
2007/11/28 Javascript
jQueryPad 实用的jQuery测试工具(支持IE,chrome,FF)
2010/05/22 Javascript
jQuery 插件仿百度搜索框智能提示(带Value值)
2013/01/22 Javascript
js类式继承的具体实现方法
2013/12/31 Javascript
javascript制作的滑动图片菜单
2015/05/15 Javascript
Jquery 垂直多级手风琴菜单附源码下载
2015/11/17 Javascript
jQuery实现的省市县三级联动菜单效果完整实例
2016/08/01 Javascript
使用bootstrap validator的remote验证代码经验分享(推荐)
2016/09/21 Javascript
JavaScript Date 知识浅析
2017/01/29 Javascript
微信小程序页面间通信的5种方式
2017/03/31 Javascript
vue bootstrap小例子一枚
2017/06/09 Javascript
validationEngine 表单验证插件使用实例代码
2017/06/15 Javascript
在vue中添加Echarts图表的基本使用教程
2017/11/22 Javascript
jquery层次选择器的介绍
2019/01/18 jQuery
vue中img src 动态加载本地json的图片路径写法
2019/04/25 Javascript
详解vue中v-model和v-bind绑定数据的异同
2020/08/10 Javascript
python学习笔记之列表(list)与元组(tuple)详解
2017/11/23 Python
Python操作Oracle数据库的简单方法和封装类实例
2018/05/07 Python
Python列表解析配合if else的方法
2018/06/23 Python
基于tensorflow加载部分层的方法
2018/07/26 Python
python实现字典嵌套列表取值
2019/12/16 Python
Python基础之高级变量类型实例详解
2020/01/03 Python
Python如何生成xml文件
2020/06/04 Python
高级文秘工作总结的自我评价
2013/09/28 职场文书
仓库主管岗位职责
2014/03/02 职场文书
员工安全承诺书
2014/05/22 职场文书
党员应该树立反腐倡廉的坚定意识思想汇报
2014/09/12 职场文书
党委书记个人检查对照材料思想汇报
2014/10/11 职场文书
党的群众路线教育实践活动个人对照检查材料(四风)
2014/11/05 职场文书
2015年防汛工作总结
2015/05/15 职场文书