这是《Python编程:从入门到实践》的第一个实践项目,对应第12-14章,开发了一个简单的小游戏Alien Invasion。虽然对生物狗来说开发游戏这个技能并没有什么用,但初学者用来熟悉Python基础也是不错的。
没用的技能增加了
开始学Python有两个星期了,事实上也只是因为现在Python的流行,并没有实际需求。因此要求不高,只是解读一下书上的代码,我自己绝对写不出这样的代码。按照书上的顺序一步步实现整个游戏的过程还算比较有趣。
下面是游戏的介绍:
在这个游戏中,玩家控制一艘最初出现在屏幕底端中央的飞船。玩家可以使用箭头键左右移动飞船,还可以使用空格键射击。游戏开始时,一群外星人出现在天空中,并向屏幕下方移动。玩家的任务是射杀这些外星人。玩家将所有外星人都消灭干净后,将出现一群新的外星人,其移动速度更快。只要有外星人撞到玩家的飞船或到达屏幕底部,玩家就损失一艘飞船。玩家损失三艘飞船后,游戏结束。
创建了8个.py文件,和一个放了两张图片的文件夹。
里面用到的飞船和外星人的图像是我自己画的。
自己画的
最终效果如下。
游戏截屏
alien_invasion.py (1)
最主要的程序是alien_invasion.py,下面看一看这个文件。
首先导入需要的模块,包含了其它7个.py文件。
import sys #包含退出游戏的函数
from time import sleep
import pygame #包含开发游戏所需功能
from settings import Settings #导入这个类
from game_stats import GameStats
from scoreboard import Scoreboard
from button import Button
from ship import Ship
from bullet import Bullet
from alien import Alien
然后创建表示这个游戏的类。
创建一个表示游戏的类
class AlienInvasion:
“””管理游戏资源和行为的类”””
def init(self):
“””初始化游戏并创建游戏资源”””
init()是一个特殊的方法,创建AlienInvasion实例时会自动运行它
调用pygame里面的函数init(),初始化游戏设置
pygame.init()
创建的AlienInvasion类的实例的一个属性self.settings,变量的内容是Settings类
self.settings = Settings()
self的属性screen,内容是pygame模块的display的set_mode()函数产生的
创建一个显示窗口,元组内为宽高的像素。将这个窗口surface赋给属性self.screen
self.screen = pygame.display.set_mode(
(self.settings.screen_width,self.settings.screen_height))
设置标题
pygame.display.set_caption(“Alien Invasion”)
self的属性stats,游戏统计信息
self.stats = GameStats(self)
创建记分牌
self.sb = Scoreboard(self)
self的属性ship,内容是新创建的类Ship(self),同时需要把AlienInvasion传入Ship类
self.ship = Ship(self)
子弹,pygame.sprite.Group类,是一个编组,存储所有有效子弹,类似于列表
self.bullets = pygame.sprite.Group()
一群外星人,用于存储外星人的编组
self.aliens = pygame.sprite.Group()
self._create_fleet()
创建play按钮
self.play_button = Button(self, “Play”)
接下来定义了运行游戏的主要方法run_game(),其中包含了很多辅助方法。
def run_game(self): #定义方法run_game()
“””开始游戏的主循环”””
while True:
self._check_events() #辅助方法
if self.stats.game_active:
self.ship.update() #更新Ship的属性rect的坐标
self._update_bullets()
self._update_aliens()
self._update_screen()
先跳过这些辅助方法,看文档的最后,创建游戏实例和运行游戏。
创建游戏实例并运行游戏
if name == ‘main‘:
python模块包含内置的变量__name__
当该模块被直接执行的时候,__name__等于文件名(包含后缀.py )
如果该模块import到其他模块中,则该模块的__name__等于模块名称(不包含后缀.py)
__main__始终指当前执行模块的名称(包含后缀.py)
当模块被直接执行时,name == ‘main‘结果为真,才能运行if下的代码块
当模块被import 到其他脚本中,则不能执行if下的代码块
ai = AlienInvasion() #创建AlienInvasion
ai.run_game() #对这个对象执行run_game()方法
settings.py
这个文件里包含了游戏的设置。
class Settings:
“””存储游戏外星人入侵中所有设置的类”””
创建这个类的实例时,运行Settings()
def init(self): #创建新实例时,会自动运行__init__()这个方法
“””初始化游戏的静态设置”””
屏幕设置
self.screen_width = 1000 #以self为前缀的变量是这个实例的属性
self.screen_height = 700
self.bg_color = (230,230,230)
飞船设置
self.ship_limit = 3
子弹设置
self.bullet_width = 3
self.bullet_height = 15
self.bullet_color = (60, 60, 60)
self.bullets_allowed = 3
外星人设置
self.fleet_drop_speed = 19
加快游戏节奏速度
self.speedup_scale = 1.2
self.initialize_dynamic_settings()
外星人分数提高速度
self.score_scale = 1.5
def initialize_dynamic_settings(self):
“””初始化随游戏进行而变化的设置”””
self.ship_speed = 0.4
self.bullet_speed = 0.8
self.alien_speed = 0.1
self.fleet_direction = 1 #1表示右移,-1表示左移
self.alien_points = 50
def increase_speed(self):
“””提高速度设置和外星人分数”””
self.ship_speed *= self.speedup_scale
self.bullet_speed *= self.speedup_scale
self.alien_speed *= self.speedup_scale
self.alien_points = int(self.alien_points * self.score_scale)
game_stats.py
这是游戏的统计信息。
class GameStats:
“””跟踪游戏的统计信息”””
def init(self, ai_game): #需要传入一个AlienInvasion对象
“””初始化统计信息”””
self.settings = ai_game.settings
self.reset_stats()
游戏刚启动时处于非活跃状态
self.game_active = False
任何情况下都不重置的最高得分
self.high_score = 0
def reset_stats(self):
“””初始化游戏在运行期间可能发生变化的统计信息”””
self.ships_left = self.settings.ship_limit
self.score = 0
self.level = 1
ship.py
表示飞船的类,是游戏中的主要元素。
import pygame
from pygame.sprite import Sprite
class Ship(Sprite):
“””管理飞船的类”””
def init(self,ai_game): #需要传入一个AlienInvasion类的实例ai_game
“””初始化飞船并设置其初始位置”””
super().init()
ai_game.screen是pygame.display.set_mode()创建的一个surface
self.screen = ai_game.screen
self.screen_rect = ai_game.screen.get_rect()
ai_game.settings是Settings()
self.settings = ai_game.settings
加载飞船图像并获取其外接矩形
self.image = pygame.image.load(‘images/ship.bmp’)
self.rect = self.image.get_rect() #self.rect确定了飞船的位置
对于每艘新飞船,都将其放在屏幕底部的中央
self.rect.midbottom = self.screen_rect.midbottom
在飞船的属性x中存储小数值
self.x = float(self.rect.x)
移动标志
self.moving_right = False
self.moving_left = False
def update(self):
“””根据移动标志调整飞船的位置”””
更新飞船self.x而不是rect对象的x值
if self.moving_right and self.rect.right < self.screen_rect.right:
self.x += self.settings.ship_speed
if self.moving_left and self.rect.left > 0:
self.x -= self.settings.ship_speed
根据self.x更新rect对象
self.rect.x = self.x #rect只存储整数,self.rect确定了飞船的位置
def blitme(self):
“””在指定位置绘制飞船”””
self.screen.blit(self.image,self.rect) #在总窗口surface中绘制这个image的矩形
def center_ship(self):
“””让飞船在屏幕底部居中”””
self.rect.midbottom = self.screen_rect.midbottom
self.x = float(self.rect.x)
alien.py
表示外星人的类,是游戏中的另一个主要元素。
import pygame
from pygame.sprite import Sprite
class Alien(Sprite):
“””表示单个外星人的类”””
Alien类继承了从模块pygame.sprite中导入的类Sprite
通过Sprite可将游戏中相关的元素编组,进而同时操作编组中的所有元素
def init(self, ai_game):
“””初始化外星人并设置其起始位置”””
super().init()
self.screen = ai_game.screen
self.settings = ai_game.settings
加载外星人图像并设置其rect属性
self.image = pygame.image.load(‘images/alien.bmp’)
self.rect = self.image.get_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 or self.rect.left
Original: https://blog.csdn.net/weixin_35632603/article/details/113713192
Author: 小欣酱不小心
Title: 外星人入侵游戏python学习_外星人入侵:使用Python开发游戏
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/782489/
转载文章受原作者版权保护。转载请注明原作者出处!