- 从三月开始看《python:从入门到实践》自学python,踏入编程的世界,已经过去两个多月了,学完基础知识之后开始学习游戏项目《外星人入侵》。
外星人入侵:在游戏《外星人入侵》中,玩家控制着一艘最初出现在屏幕底部中央的飞船。玩家可以使用箭头键左右移动飞船,还可使用空格键进行射击。游戏开始时,一群外星
人出现在天空中,他们在屏幕中向下移动。玩家的任务是射杀这些外星人。玩家将所有外星人都消灭干净后,将出现一群新的外星人,他们移动的速度更快。只要有
外星人撞到了玩家的飞船或到达了屏幕底部,玩家就损失一艘飞船。玩家损失三艘飞船后,游戏结束。
通过学习这样一个项目,我学到了pygame的运用,对之前学的类、函数、方法有了更深的认识,开始思考项目背后运行的原理。
项目分为10个文件,9个py文件和1个json文件。
py文件分别储存了游戏的各个要素,具体作用我会在代码的注释中详述。json文件会被 scorebroad.py 中的代码自动创建,用于储存游戏中出现的最高分。
作为新手,免不了要出错,在写这个项目的过程我也遇到了不少问题,也向很多大神求助过,在这里感谢帮助过我的前辈。我把几个遇到的问题都写在了之前在出错的地方。
总结一下教训:
1.写代码的时候一定要专注,不然很多时候怎么出错都不知道。
2.调用方法函数的时候记得加上括号,不然会报错,这是个细节问题。
3.一定要注意缩进问题,有时候不应该的缩进会导致一些莫名其妙的问题,找代码出错的时候记得看一看缩进是否正确。
游戏界面如图:
项目代码如下:
settings.py
#创建一个游戏设置的类
class Settings:
def __init__(self):
#储存游戏初始化数据
#初始化游戏的静态设置
self.screen_width = 1400
self.screen_height = 750
self.bg_color = (200,200,200)
#设置飞船数量
self.ship_limit = 3
#创建关于子弹的属性
self.bullet_width = 15
self.bullet_height = 30
self.bullet_bg_color = (60,0,0)
#设置限制子弹数量
self.bullets_allowed = 3
#设置外星人下降值
self.alien_drop_factor = 2
#设置速度提升倍数
self.speedup_scale = 1.1
#设置外星人点数的提高速度
self.score_scale = 1.5
#初始化速度值
self.initialize_dynamic_settings()
def initialize_dynamic_settings(self):
#初始化动态设置
# 设置外星人移动速度
self.alien_speed_factor = 0.5
# 设置外星人群移动值,向右为1,向左为-1
self.fleet_direction = 1
#设置外星人分数
self.alien_points = 50
#设置子弹移动速度
self.bullet_speed_factor = 5
# 设置飞船移动速度
self.ship_speed_factor = 3
def increase_speed(self):
#提升速度值
self.ship_speed_factor *= self.speedup_scale
self.bullet_speed_factor *= self.speedup_scale
self.alien_speed_factor*= self.speedup_scale
#提升分数
self.alien_points = int(self.alien_points * self.score_scale)
alien.py
#创建一个关于外星人的模块
import pygame
from pygame.sprite import Sprite
class Alien(Sprite):
'''表示单个外星人的类'''
def __init__(self,ai_settings,screen):
#继承精灵类
super().__init__()
self.ai_settings = ai_settings
self.screen = screen
#返回外星人图像并矩形化
self.image = pygame.image.load('image/humor.png')
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 blitme(self):
'''在指定位置绘制外星人'''
self.screen.blit(self.image,self.rect)
def update(self):
#外星人坐标为速度乘以方向值,当方向值为负时方向改变
self.x += (self.ai_settings.alien_speed_factor *
self.ai_settings.fleet_direction)
self.rect.x = self.x
'''当方向值为1时,x 坐标增加,向右移动。方向值为-1时,x 坐标减少,向左移动'''
def check_edges(self):
#检查外星人是否碰到了边缘
#矩形化屏幕
screen_rect = self.screen.get_rect()
#当外星人贴图右边缘大于或等于屏幕矩形右边缘,返回正确
if self.rect.right >= screen_rect.right:
return True
#当外星人贴图左边缘小于或等于屏幕矩形左边缘(小于等于0),返回正确
elif self.rect.left <= screen_rect.left:
return True
bullet.py
#创建子弹类
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
'''一个对飞船发射的子弹进行管理的类'''
def __init__(self,ai_settings,screen,ship):
#通过函数super()来继承sprite
super().__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.centerx
self.rect.top = ship.rect.top
#储存用小数表示的子弹位置
'''由于子弹是直线向下移动,所以我们只考虑在y轴上坐标的变化,
而x轴的坐标是固定的,这由发射子弹时飞船的x轴坐标决定,
因为我们在前面定义了self.rect.centerx = ship.rect.centerx'''
self.y = float(self.rect.y)
#储存子弹颜色
self.color = ai_settings.bullet_bg_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)
ship.py
import pygame
from pygame.sprite import Sprite
class Ship(Sprite):
def __init__(self,ai_settings,screen):
'''初始化飞船并设置其初始位置'''
#继承精灵
super().__init__()
self.screen = screen
self.ai_settings = ai_settings
#加载飞船图像,并获取其外接矩形
#load返回贴图所在文件
self.image = pygame.image.load('image/shot.PNG')
#矩形属性rect为贴图的矩形对象
#get_rect()是一个处理矩形图像的方法,返回值包含矩形的居中属性( center centerx centery )
#get_rect须加上(),否则后续程序在运行时会出现无法引用centerx和bottom的错误
self.rect = self.image.get_rect()
#先将表示屏幕的矩形储存在属性screen—rect中
self.screen_rect = screen.get_rect(</