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 相关文章推荐
Python查看多台服务器进程的脚本分享
Jun 11 Python
深入解析Python中的WSGI接口
May 11 Python
Django入门使用示例
Dec 12 Python
Python+matplotlib实现填充螺旋实例
Jan 15 Python
django文档学习之applications使用详解
Jan 29 Python
Matplotlib 生成不同大小的subplots实例
May 25 Python
python xpath获取页面注释的方法
Jan 14 Python
python如何获取列表中每个元素的下标位置
Jul 01 Python
Django实现发送邮件找回密码功能
Aug 12 Python
pytorch查看torch.Tensor和model是否在CUDA上的实例
Jan 03 Python
python设置环境变量的作用整理
Feb 17 Python
详解Python生成器和基于生成器的协程
Jun 03 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
ThinkPHP中实例Model方法的区别说明
2010/08/21 PHP
php比较多维数组中值的大小排序实现代码
2012/09/08 PHP
TopList标签和JavaScript结合两例
2007/08/12 Javascript
javascript 文档的编码问题解决
2009/03/01 Javascript
IE6中使用position导致页面变形的解决方案(js代码)
2011/01/09 Javascript
js截取字符串的两种方法及区别详解
2013/11/05 Javascript
使用jQuery快速解决input中placeholder值在ie中无法支持的问题
2014/01/02 Javascript
JavaScript中this关键词的使用技巧、工作原理以及注意事项
2014/05/20 Javascript
jQuery插件kinMaxShow扩展效果用法实例
2015/05/04 Javascript
基于jquery实现人物头像跟随鼠标转动
2015/08/23 Javascript
javascript html5移动端轻松实现文件上传
2020/03/27 Javascript
js 获取站点应用名的简单实例
2016/08/18 Javascript
js学习总结_基于数据类型检测的四种方式(必看)
2017/07/04 Javascript
详解Vue单元测试Karma+Mocha学习笔记
2018/01/31 Javascript
[52:07]完美世界DOTA2联赛PWL S3 LBZS vs access 第二场 12.10
2020/12/13 DOTA
Python删除空文件和空文件夹的方法
2015/07/14 Python
通过数据库向Django模型添加字段的示例
2015/07/21 Python
python thrift搭建服务端和客户端测试程序
2018/01/17 Python
python numpy和list查询其中某个数的个数及定位方法
2018/06/27 Python
使用python接受tgam的脑波数据实例
2020/04/09 Python
Django返回HTML文件的实现方法
2020/09/17 Python
Python3.9.1中使用split()的处理方法(推荐)
2021/02/07 Python
纯CSS3单页切换导航菜单界面设计的简单实现
2016/08/16 HTML / CSS
Helly Hansen工作服美国官方网上商店:为最恶劣的环境
2019/09/04 全球购物
英国标志性生活方式品牌:Skinnydip London
2019/12/15 全球购物
雷蛇美国官网:Razer
2020/04/03 全球购物
你经历的项目中的SCM配置项主要有哪些?什么是配置项?
2013/11/04 面试题
XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?
2016/01/12 面试题
施工安全协议书
2013/12/11 职场文书
办公室文书岗位职责
2013/12/16 职场文书
高职教师岗位职责
2013/12/24 职场文书
合伙协议书
2014/04/23 职场文书
校本培训个人总结
2015/02/28 职场文书
2015年卫生院健康教育工作总结
2015/07/24 职场文书
利用javaScript处理常用事件详解
2021/04/14 Javascript
Flutter集成高德地图并添加自定义Maker的实践
2022/04/07 Java/Android