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获取远程图片大小和尺寸的方法
Mar 26 Python
对python中的logger模块全面讲解
Apr 28 Python
python 利用栈和队列模拟递归的过程
May 29 Python
Django跨域请求问题的解决方法示例
Jun 16 Python
Python饼状图的绘制实例
Jan 15 Python
Python 利用切片从列表中取出一部分使用的方法
Feb 01 Python
【python】matplotlib动态显示详解
Apr 11 Python
Python3 JSON编码解码方法详解
Sep 06 Python
python中有关时间日期格式转换问题
Dec 25 Python
基于Python脚本实现邮件报警功能
May 20 Python
python opencv通过按键采集图片源码
May 20 Python
python函数的两种嵌套方法使用
Apr 02 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
在线短消息收发的程序,不用数据库
2006/10/09 PHP
php入门小知识
2008/03/24 PHP
php从数组中随机抽取一些元素的代码
2012/11/05 PHP
PHP输出缓冲控制Output Control系列函数详解
2015/07/02 PHP
php使用pclzip类实现文件压缩的方法(附pclzip类下载地址)
2016/04/30 PHP
PHP正则判断一个变量是否为正整数的方法
2019/02/27 PHP
基于php解决json_encode中文UNICODE转码问题
2020/11/10 PHP
javascript写的简单的计算器,内容很多,方法实用,推荐
2011/12/29 Javascript
基于jquery创建的一个图片、视频缓冲的效果样式插件
2012/08/28 Javascript
Checbox的操作含已选、未选及判断代码
2013/11/07 Javascript
JavaScript中通过prototype属性共享属性和方法的技巧实例
2015/03/13 Javascript
jquery实现倒计时功能
2015/12/28 Javascript
jquery实现左右无缝轮播图
2020/07/31 Javascript
Bootstrap实现渐变顶部固定自适应导航栏
2020/08/27 Javascript
将angular.js项目整合到.net mvc中的方法详解
2017/06/29 Javascript
jQuery列表检索功能实现代码
2017/07/17 jQuery
ReactNative踩坑之配置调试端口的解决方法
2017/07/28 Javascript
swiper自定义分页器使用方法详解
2020/09/14 Javascript
[07:48]DOTA2上海特级锦标赛主赛事首日RECAP
2016/03/04 DOTA
Python中的一些陷阱与技巧小结
2015/07/10 Python
浅谈python字典多键值及重复键值的使用
2016/11/04 Python
Python入门必须知道的11个知识点
2018/03/21 Python
python数字图像处理实现直方图与均衡化
2018/05/04 Python
Python并发:多线程与多进程的详解
2019/01/24 Python
Python使用微信接入图灵机器人过程解析
2019/11/04 Python
python编写实现抽奖器
2020/09/10 Python
CSS3动画animation实现云彩向左滚动
2014/05/09 HTML / CSS
英国最大的汽车配件在线商店:Euro Car Parts
2019/09/30 全球购物
英国男女豪华配饰和礼品网站:Black.co.uk
2020/02/28 全球购物
一些PHP的面试题
2015/05/06 面试题
一分钟演讲稿
2014/04/30 职场文书
2014年销售工作总结与计划
2014/12/01 职场文书
雷锋的故事观后感
2015/06/10 职场文书
旅游投诉信范文
2015/07/02 职场文书
2016七夕情人节寄语
2015/12/04 职场文书
Python first-order-model实现让照片动起来
2022/06/25 Python