文章目录

  • ❤2023年3月,重新理解记录
  • 编译环境
  • 游戏界面
  • alien_invasion.py
  • alien.py
  • bullet.py
  • button.py
  • game_functions.py
  • game_stats.py
  • scoreboard.py
  • settings.py
  • ship.py

❤2023年3月,重新理解记录




编译环境

PyCharm

游戏界面


左上角的三个飞船,代表的是飞船个数,死亡一次减少一个

alien_invasion.py

import pygame
from pygame.sprite import Groupfrom settings import Settings
from game_stats import GameStats
from scoreboard import Scoreboard
from button import Button
from ship import Ship
import game_functions as gfdef run_game():# 初始化pygame、设置和屏幕对象pygame.init()ai_settings = Settings()screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))pygame.display.set_caption("Alien Invasion")# 创建Play按钮play_button = Button(ai_settings, screen, "Play")# 创建存储游戏统计信息的实例,并创建记分牌stats = GameStats(ai_settings)sb = Scoreboard(ai_settings, screen, stats)# 创建一艘飞船、一个子弹编组和一个外星人编组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, stats, sb, play_button, ship,aliens, bullets)if stats.game_active:ship.update()gf.update_bullets(ai_settings, screen, stats, sb, ship, aliens,bullets)gf.update_aliens(ai_settings, stats, screen, sb, ship, aliens, bullets)gf.update_screen(ai_settings, screen, stats, sb, ship, aliens,bullets, play_button)run_game()

alien.py

import pygame
from pygame.sprite import Spriteclass Alien(Sprite):"""表示单个外星人的类"""def __init__(self, ai_settings, screen):"""初始化外星人并设置其起始位置"""super(Alien, self).__init__()self.screen = screenself.ai_settings = ai_settings# 加载外星人图像,并设置其rect属性self.image = pygame.image.load('images/alien.bmp')self.rect = self.image.get_rect()# 每个外星人最初都在屏幕左上角附近self.rect.x = self.rect.widthself.rect.y = self.rect.height# 存储外星人的准确位置self.x = float(self.rect.x)def blitme(self):"""在指定位置绘制外星人"""self.screen.blit(self.image, self.rect)def check_edges(self):"""如果外星人位于屏幕边缘,就返回True"""screen_rect = self.screen.get_rect()if self.rect.right >= screen_rect.right:return Trueelif self.rect.left <= 0:return Truedef update(self):"""向左或右移动外星人"""self.x += (self.ai_settings.alien_speed_factor *self.ai_settings.fleet_direction)self.rect.x = self.x

bullet.py

import pygame
from pygame.sprite import Spriteclass Bullet(Sprite):"""一个对飞船发射的子弹进行管理的类"""def __init__(self, ai_settings, screen, ship):"""在飞船所处的位置创建一个子弹对象"""super(Bullet, self).__init__()self.screen = screen# 在(0,0)处创建一个表示子弹的矩形,再设置正确的位置self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,ai_settings.bullet_height)self.rect.centerx = ship.rect.centerxself.rect.top = ship.rect.top# 存储用小数表示的子弹位置self.y = float(self.rect.y)self.color = ai_settings.bullet_colorself.speed_factor = ai_settings.bullet_speed_factordef update(self):"""向上移动子弹"""# 更新表示子弹位置的小数值self.y -= self.speed_factor# 更新表示子弹的rect的位置self.rect.y = self.ydef draw_bullet(self):"""在屏幕上绘制子弹"""pygame.draw.rect(self.screen, self.color, self.rect)

button.py

import pygame.fontclass Button():def __init__(self, ai_settings, screen, msg):"""初始化按钮的属性"""self.screen = screenself.screen_rect = screen.get_rect()# 设置按钮的尺寸和其他属性self.width, self.height = 200, 50self.button_color = (0, 255, 0)self.text_color = (255, 255, 255)self.font = pygame.font.SysFont('arial', 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.centerdef draw_button(self):# 绘制一个用颜色填充的按钮,再绘制文本self.screen.fill(self.button_color, self.rect)self.screen.blit(self.msg_image, self.msg_image_rect)

game_functions.py

import sys
from time import sleepimport pygamefrom bullet import Bullet
from alien import Aliendef check_keydown_events(event, ai_settings, screen, ship, bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_UP:ship.moving_up = Trueelif event.key == pygame.K_DOWN:ship.moving_down = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings, screen, ship, bullets)elif event.key == pygame.K_q:sys.exit()def fire_bullet(ai_settings, screen, ship, bullets):"""如果还没有到达限制,就发射一颗子弹"""# 创建一颗子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings, screen, ship)bullets.add(new_bullet)def check_keyup_events(event, ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseelif event.key == pygame.K_LEFT:ship.moving_left = Falseelif event.key == pygame.K_UP:ship.moving_up = Falseelif event.key == pygame.K_DOWN:ship.moving_down = Falsedef check_events(ai_settings, screen, stats, sb, play_button, ship, aliens,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)elif event.type == pygame.MOUSEBUTTONDOWN:mouse_x, mouse_y = pygame.mouse.get_pos()check_play_button(ai_settings, screen, stats, sb, play_button, ship,aliens, bullets, mouse_x, mouse_y)def check_play_button(ai_settings, screen, stats, sb, play_button, ship, aliens,bullets, mouse_x, mouse_y):"""在玩家单击Play按钮时开始新游戏"""button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)if button_clicked and not stats.game_active:# 重置游戏设置ai_settings.initialize_dynamic_settings()# 隐藏光标pygame.mouse.set_visible(False)# 重置游戏统计信息stats.reset_stats()stats.game_active = True# 重置记分牌图像sb.prep_score()sb.prep_high_score()sb.prep_level()sb.prep_ships()# 清空外星人列表和子弹列表aliens.empty()bullets.empty()# 创建一群新的外星人,并让飞船居中create_fleet(ai_settings, screen, ship, aliens)ship.center_ship()def update_bullets(ai_settings, screen, stats, sb, ship, aliens, bullets):"""更新子弹的位置,并删除已消失的子弹"""# 更新子弹的位置bullets.update()# 删除已消失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship,aliens, bullets)def check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship,aliens, bullets):"""响应子弹和外星人的碰撞"""# 删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)if collisions:for aliens in collisions.values():stats.score += ai_settings.alien_points * len(aliens)sb.prep_score()check_high_score(stats, sb)if len(aliens) == 0:# 如果整群外星人都被消灭,就提高一个等级bullets.empty()ai_settings.increase_speed()# 提高等级stats.level += 1sb.prep_level()create_fleet(ai_settings, screen, ship, aliens)def update_screen(ai_settings, screen, stats, sb, ship, aliens, bullets,play_button):"""更新屏幕上的图像,并切换到新屏幕"""# 每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)# 在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()aliens.draw(screen)# 显示得分sb.show_score()# 如果游戏处于非活动状态,就绘制Play按钮if not stats.game_active:play_button.draw_button()# 让最近绘制的屏幕可见pygame.display.flip()def get_number_aliens_x(ai_settings, alien_width):"""计算每行可容纳多少个外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_aliens_x = int(available_space_x / (2 * alien_width))return number_aliens_xdef get_number_rows(ai_settings, ship_height, alien_height):"""计算屏幕可容纳多少行外星人"""available_space_y = (ai_settings.screen_height -(3 * alien_height) - ship_height)number_rows = int(available_space_y / (3 * alien_height))return number_rowsdef create_alien(ai_settings, screen, aliens, alien_number, row_number):"""创建一个外星人并将其放在当前行"""alien = Alien(ai_settings, screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberalien.rect.x = alien.xaliens.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):create_alien(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)breakdef change_fleet_direction(ai_settings, aliens):"""将整群外星人下移,并改变它们的方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def ship_hit(ai_settings, stats, screen, sb, ship, aliens, bullets):"""响应被外星人撞到的飞船"""if stats.ships_left > 0:# 将ships_left减1stats.ships_left -= 1# 更新记分牌sb.prep_ships()# 清空外星人列表和子弹列表aliens.empty()bullets.empty()# 创建一群新的外星人,并将飞船放到屏幕底端中央create_fleet(ai_settings, screen, ship, aliens)ship.center_ship()# 暂停sleep(0.5)else:stats.game_active = Falsepygame.mouse.set_visible(True)def check_aliens_bottom(ai_settings, stats, screen, sb, ship, aliens, bullets):"""检查是否有外星人到达了屏幕底端"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:# 像飞船被撞到一样进行处理ship_hit(ai_settings, stats, screen, sb, ship, aliens, bullets)breakdef check_high_score(stats, sb):"""检查是否诞生了新的最高得分"""if stats.score > stats.high_score:stats.high_score = stats.scoresb.prep_high_score()def update_aliens(ai_settings, stats, screen, sb, ship, aliens, bullets):"""检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""check_fleet_edges(ai_settings, aliens)aliens.update()# 检测外星人和飞船之间的碰撞if pygame.sprite.spritecollideany(ship, aliens):ship_hit(ai_settings, stats, screen, sb, ship, aliens, bullets)# 检查是否有外星人到达屏幕底端check_aliens_bottom(ai_settings, stats, screen, sb, ship, aliens, bullets)

game_stats.py

class GameStats():"""跟踪游戏的统计信息"""def __init__(self, ai_settings):"""初始化统计信息"""self.ai_settings = ai_settingsself.reset_stats()# 游戏刚启动时处于活动状态self.game_active = False# 在任何情况下都不应重置最高得分self.high_score = 0def reset_stats(self):"""初始化在游戏运行期间可能变化的统计信息"""self.ships_left = self.ai_settings.ship_limitself.score = 0self.level = 1

scoreboard.py

import pygame.font
from pygame.sprite import Groupfrom ship import Shipclass Scoreboard():"""显示得分信息的类"""def __init__(self, ai_settings, screen, stats):"""初始化显示得分涉及的属性"""self.screen = screenself.screen_rect = screen.get_rect()self.ai_settings = ai_settingsself.stats = stats# 显示得分信息时使用的字体设置self.text_color = (30, 30, 30)self.font = pygame.font.SysFont(None, 48)# 准备包含最高得分和当前得分的图像self.prep_score()self.prep_high_score()self.prep_level()self.prep_ships()def prep_score(self):"""将得分转换为一幅渲染的图像"""rounded_score = int(round(self.stats.score, -1))score_str = "{:,}".format(rounded_score)self.score_image = self.font.render(score_str, True, self.text_color,self.ai_settings.bg_color)# 将得分放在屏幕右上角self.score_rect = self.score_image.get_rect()self.score_rect.right = self.screen_rect.right - 20self.score_rect.top = 20def prep_high_score(self):"""将最高得分转换为渲染的图像"""high_score = int(round(self.stats.high_score, -1))high_score_str = "{:,}".format(high_score)self.high_score_image = self.font.render(high_score_str, True,self.text_color, self.ai_settings.bg_color)# 将最高得分放在屏幕顶部中央self.high_score_rect = self.high_score_image.get_rect()self.high_score_rect.centerx = self.screen_rect.centerxself.high_score_rect.top = self.score_rect.topdef prep_level(self):"""将等级转换为渲染的图像"""self.level_image = self.font.render(str(self.stats.level), True,self.text_color, self.ai_settings.bg_color)# 将等级放在得分下方self.level_rect = self.level_image.get_rect()self.level_rect.right = self.score_rect.rightself.level_rect.top = self.score_rect.bottom + 10def prep_ships(self):"""显示还余下多少艘飞船"""self.ships = Group()for ship_number in range(self.stats.ships_left):ship = Ship(self.ai_settings, self.screen)ship.rect.x = 10 + ship_number * ship.rect.widthship.rect.y = 10self.ships.add(ship)def show_score(self):"""在屏幕上显示飞船和得分"""self.screen.blit(self.score_image, self.score_rect)self.screen.blit(self.high_score_image, self.high_score_rect)self.screen.blit(self.level_image, self.level_rect)# 绘制飞船self.ships.draw(self.screen)

settings.py

class Settings():"""存储《外星人入侵》的所有设置的类"""def __init__(self):"""初始化游戏的静态设置"""# 屏幕设置self.screen_width = 1200self.screen_height = 800self.bg_color = (230, 230, 230)# 飞船的设置self.ship_speed_factor = 0.3# 子弹设置self.bullet_speed_factor = 1self.ship_limit = 3self.bullet_width = 3self.bullet_height = 15self.bullet_color = 60, 60, 60self.bullets_allowed = 3# 外星人设置self.alien_speed_factor = 0.1self.fleet_drop_speed = 10# 以什么样的速度加快游戏节奏self.speedup_scale = 1.01# 外星人点数的提高速度self.score_scale = 1.1self.initialize_dynamic_settings()# fleet_direction为1表示向右移,为-1表示向左移self.fleet_direction = 1def initialize_dynamic_settings(self):"""初始化随游戏进行而变化的设置"""self.ship_speed_factor = 0.3self.bullet_speed_factor = 1self.alien_speed_factor = 0.1# fleet_direction为1表示向右;为-1表示向左self.fleet_direction = 1# 记分self.alien_points = 50def increase_speed(self):"""提高速度设置和外星人点数"""self.ship_speed_factor *= self.speedup_scaleself.bullet_speed_factor *= self.speedup_scaleself.alien_speed_factor *= self.speedup_scaleself.alien_points = int(self.alien_points * self.score_scale)

ship.py

import pygame
from pygame.sprite import Spriteclass Ship(Sprite):def __init__(self, ai_settings, screen):"""初始化飞船并设置其初始位置"""super(Ship, self).__init__()self.screen = screenself.ai_settings = ai_settings# 加载飞船图像并获取其外接矩形self.image = pygame.image.load('images/ship.bmp')self.rect = self.image.get_rect()self.screen_rect = screen.get_rect()# 将每艘新飞船放在屏幕底部中央self.rect.centerx = self.screen_rect.centerxself.rect.bottom = self.screen_rect.bottom# 在飞船的属性center中存储小数值self.center = float(self.rect.centerx)self.centery = float(self.rect.centery)# 移动标志self.moving_right = Falseself.moving_left = Falseself.moving_up = Falseself.moving_down = Falsedef update(self):"""根据移动标志调整飞船的位置"""# 更新飞船的center值,而不是rectif self.moving_right and self.rect.right < self.screen_rect.right:self.center += self.ai_settings.ship_speed_factorif self.moving_left and self.rect.left > 0:self.center -= self.ai_settings.ship_speed_factorif self.moving_up and self.rect.top > 0:self.centery -= self.ai_settings.ship_speed_factorif self.moving_down and self.rect.bottom < self.screen_rect.bottom:self.centery += self.ai_settings.ship_speed_factor# 根据self.center更新rect对象self.rect.centerx = self.centerself.rect.centery = self.centerydef center_ship(self):"""让飞船在屏幕上居中"""self.center = self.screen_rect.centerxself.centery = self.screen_rect.bottomdef blitme(self):"""在指定位置绘制飞船"""self.screen.blit(self.image, self.rect)

Python编程:从入门到实践,《外星人入侵》游戏代码【600行】【手敲原创】相关推荐

  1. Python编程从入门到实践——外星人入侵代码

    学习python的新人一枚,在学习的过程中遇到了很多问题,最后通过在CSDN等网站上查阅资料等都慢慢解决了,写一个帖子,一方面是记录自己的代码,另一方面和大家分享一下. 目录 alien.py ali ...

  2. python编程:从入门到实践 外星人入侵项目:武装飞船 代码运行不显示飞船

    我的飞船去哪了???!!! 照着书上的项目完整的代码运行一下,结果屏幕上没出现飞船,代码都是对的呀,这是咋回事? 屏幕高度问题 class Settings():"""A ...

  3. Python语法学习测试记录(Python编程从入门到实践——Eric Matthes著)

    注:工作之余,学习一门脚本语言,选择了当下火热的Python.2020-05-27日开始学习Python基础语法,期间参考<Python编程从入门到实践--Eric Matthes著>一书 ...

  4. 《Python编程从入门到实践》外星人入侵游戏——添加 飞船 图片和外星人 图片,素材

    <Python编程从入门到实践>在本书里学到的.本篇主要介绍该游戏中所需要的两个图片.分别为飞船和外星人图片. 1.首先去到 http://www.ituring.com.cn/book/ ...

  5. python编程从入门到实践之外星人入侵全代码

    好久没有更新了,最近寒假在家没事做,就想学点东西,在网上找到一本关于python的书籍<python编程从入门到实践>,经过大概一个多月的时间吧,也算是大致把本书浏览了一遍. 本人感觉这本 ...

  6. 《Python编程从入门到实践》,留言送5本

    你好,我是 zhenguo 我每次送书,一定必选经典.今天图灵出版社的这本<Python编程从入门到实践>,就很值得一读,强调入门学习Python的动手和实践,是一本经典好书.今天一共赠送 ...

  7. python开发之父亲自编写《python编程从入门到实践》中译版图书销量破百万册,完整版PDF开放下载

    为什么要学习python 主流编程语言 世界上的编程语言有600多种,但真正大家主流在使用的最多二三十种,不同的语言有自己的特点和擅长领域,随着计算机的不断发展,新语言在不断诞生,也同时有很多老旧的语 ...

  8. 《Python编程从入门到实践 第2版》 读后感

    <Python编程从入门到实践 第2版> 读后感 一直在想,一本好的Python书籍应该是怎样的?是将所有的基础知识点都讲解透彻?还是仅仅从方法上对读者授之以渔呢?我想这也是很多著书人在开 ...

  9. python编程 入门到实践-终于懂了python编程从入门到实践

    Python语言是一种典型的脚本语言,简洁,语法约束少,接近人类语言.有丰富的数据结构,例如列表.字典.集合等.具有可移植性,支持面向过程和面向对象编程,并且开源.以下是小编为你整理的python编程 ...

  10. python编程 从入门到实践豆瓣-三周刷完《Python编程从入门到实践》的感受

    本文将以对话采访的形式展现 为什么会选择学习Python 语法简洁,实用,和golang部分类似,学习性价比高: 应用范围广,涉及后端,机器学习,图像处理,游戏等: 好奇这是一门怎样的语言 计划如何学 ...

最新文章

  1. 数组中存储不定个数的元素
  2. php开发支持的文件类型整理
  3. 到底什么是面向对象,面试中怎么回答。面向过程和面向对象的区别是什么。java跨平台特性以及java和C++的区别。面向对象的三大特性——封装、继承和多态。面向对象的高拓展性以及低耦合度怎么体现?
  4. eclipse java jdk_设置Eclipse和Java JDK
  5. 智慧办公的AI博弈——看飞企互联如何接招!
  6. 常见Java面试题之静态变量和实例变量的区别
  7. 什么是 TCC分布式事务
  8. ENSP如何开启服务器的http_Centos\Liunx如何安装MySQL?
  9. BMVC-2021-DETR: End-to-End Object Detection with Transformers 阅读笔记
  10. linux内核网络队列,Linux 内核网络协议栈 ------ 清理重传队列中函数 tcp_clean_rtx_queue...
  11. 使用markdown-it插件
  12. 为何说 a16z 是一家通过 VC 获利的媒体公司?
  13. Codeforces Round #548 (Div. 2) C. Edgy Trees(思维+dfs)
  14. 安装EEGLAB以及创建电极位置
  15. 【Java】若依前后端分离,分页数据为null报错
  16. 微信开发者工具未绑定企业号开发者
  17. 鸿蒙手机系统论坛,对华为手机及“鸿蒙”系统(移动端)的一些期待
  18. 【它山之玉】在申请教职中“再造”自己-科学网马臻
  19. LInux安装 词典 软件星际译王安装、词库下载
  20. 电脑PDF阅读+谷歌翻译

热门文章

  1. ShareSDK Android端主流平台分享示例
  2. JS 数组中的 filter 方法
  3. R中排序函数总结:sort,order,rank,arrange,reorder
  4. 数据仓库笔记(高质量建模)——01
  5. java抓取并保存图片_【初学】java爬虫并抓取图片保存
  6. 微信小程序_25,自定义tabBar
  7. kicad最小布线宽度默认是多少_【HIWE艾维】家庭智能装修布线详解
  8. ZeroTier内网穿透部署
  9. ​新加坡国立大学癌症研究所,陈蕾蕾课题组招收生物信息学博士后
  10. 优秀的智慧展厅需要有哪些设计?