一、项目准备
在开发游戏前,我们需要安装一个pygame模块
- pygame 就是一个 Python 模块,专为电子游戏设计
安装pygame
sudo pip3 install pygame
验证安装
python3 -m pygame.examples.aliens
二、文件职责
首先我们需要两个文件编写代码 plane_main 和 plane_sprites
- plane_main
- 封装 主游戏类
- 创建 游戏对象
- 启动游戏
- plane_sprites
1.封装游戏中 所有 需要使用的 精灵子类
2.提供游戏的 相关工具
三、搭建游戏框架
第一部分----游戏初始化
- 设置游戏窗口
- 创建游戏时钟
- 创建精灵、精灵组
第二部分----游戏循环
- 设置刷新帧率
- 事件监听
- 碰撞检测
- 更新精灵组
- 更新屏幕显示
四、代码整理1----在plane_main游戏主程序中
- 导入模块
#导入Python本身提供的pygame模块
import pygame
#导入精灵文件Plan_sprites模块
from PlanSprite import *
- 创建一个类
#运用面向对象思想创建主游戏类
class PlaneGame(object):
- 游戏初始化
#初始化方法
def __init__(self):
#创建游戏窗口
self.screen = pygame.display.set_mode(SCREEN_RECT.size)
#创建游戏时钟
self.clock = pygame.time.Clock()
#创建精灵组
self.__create_sprites()
#得分显示,(默认为0)
self.wanjia = 0
#定时器 毫秒 第一个参数是事件的名字 第二个参数是多长时间执行一次时间
pygame.time.set_timer(CREATE_ENEMY_EVENT,1000)
- 创建精灵组
def __create_sprites(self):
#背景精灵组
bg1 = Background()
bg2 = Background(True)
self.back_group = pygame.sprite.Group(bg1,bg2)
#敌机的精灵组
self.enemy_group = pygame.sprite.Group()
#英雄的精灵组
self.hero = Hero()
self.hero_group = pygame.sprite.Group(self.hero)
- 游戏循环部分
def start_game(self):
print("游戏开始...")
while True:
#设置帧率
self.clock.tick(FRAME_PER_SEC)
#事件监听
self.__event_handler()
#碰撞检测
self.__check_collide()
#更新精灵和精灵组
self.__update_sprites()
#分数
self.__print_score()
#更新显示
pygame.display.update()
- 事件监听
def __event_handler(self)
for event in pygame.event.get():
#判断是否退出游戏
if event.type == pygame.QUIT:
PlaneGame.__game_over()
elif event.type == CREATE_ENEMY_EVENT: #敌机定时器事件
enemy = Enemy()
self.enemy_group.add(enemy)
elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE: #子弹定时器事件
self.hero.fire()
- 碰撞检测
def __check_collide(self):
# 1. 子弹摧毁敌机
if pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True):
self.wanjia +=2
# 2. 敌机撞毁英雄
enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)
# 判断列表时候有内容
if len(enemies) > 0:
# 让英雄牺牲
self.hero.kill()
print("英雄牺牲")
# 结束游戏
PlaneGame.__game_over()
print("游戏结束")
- 更新精灵组
def __update_sprites(self):
#更新背景精灵组
self.back_group.update()
self.back_group.draw(self.screen)
#更新敌机精灵组
self.enemy_group.update()
self.enemy_group.draw(self.screen)
#更新玩家飞机精灵组
self.hero_group.update()
self.hero_group.draw(self.screen)
#更新子弹精灵组
self.hero.bullets.update()
self.hero.bullets.draw(self.screen)
- 打印分数
def __print_score(self):
pygame.font.init()
#位置
pos = (20,0)
#颜色
color = (255,255,255)
#显示内容
text = "score:" + str(self.wanjia)
#字体
cur_font = pygame.font.SysFont("楷体",30)
text_fort = cur_font.render(text,1,color)
self.screen.blit(text_fort,pos)
- 结束游戏
#退出游戏
@staticmethod
def __game_over():
#卸载所有 pygame 模块
pygame.quit
#python本身提供的退出脚本的功能
exit()
- 调用主函数
if __name__ == '__main__':
#创建游戏对象
game = PlaneGame()
#开始游戏
game.start_game()
五、代码整理2----在plane_sprites游戏精灵中
#导入随机包
import random
#导入pygame模块
import pygame
#设置游戏屏幕大小
SCREEN_RECT = pygame.Rect(0,0,480,700)
#刷新帧率
FRAME_PER_SEC = 60
#敌机事件的常量
CREATE_ENEMY_EVENT = pygame.USEREVENT
- 创建游戏精灵的基础类
class GameSprite(pygame.sprite.Sprite):
#给基础类的速度设置一个默认值为1
def __init__(self,image_name,speed=1):
#继承父类的初始化
super().__init__()
#pygame.image.load(pygame提供的方法) 加载图片
self.image = pygame.image.load(image_name)
#设置尺寸
self.rect = self.image.get_rect()
#记录速度
self.speed = speed
#每次更新屏幕时在游戏循环内调用
def update(self):
#默认在垂直方向移动
self.rect.y += self.speed
- 创建背景精灵类
class Background(GameSprite):
#is_alt判断是否为另外一张图像(False表示第一张图像 True表示另外一张图像)
def __init__(self,is_alt=False):
#传入背景图片
image_name = "./images/timg.jpeg"
super().__init__(image_name)
#如果是另一张图像,讲图片设置到屏幕顶部
if is_alt:
self.rect.y = -self.rect.height
def update(self):
#调用父类的方法实现
super().update()
#判断是否移出屏幕,如果移出屏幕,将图像设置到屏幕的上方
if self.rect.y > SCREEN_RECT.height:
self.rect.y = -self.rect.height
- 创建敌机精灵类
class Enemy(GameSprite):
def __init__(self):
#传入敌机图片
image_name = "./images/enemy-1.gif"
super().__init__(image_name)
#设置敌机的随机初始速度
self.speed = random.randint(1,3)
#敌机x轴最大值 需要用屏幕的宽度-敌机自身的宽度
max_x = SCREEN_RECT.width - self.rect.width
self.rect.x = random.randint(0,max_x)#随机位置
self.rect.bottom = 0 #敌机底部位置
def update(self):
super().update()
#判断是否飞出屏幕,如果是,需要将敌机从精灵组删除
if self.rect.y >= SCREEN_RECT.height:
self.kill()
print("敌机飞出屏幕...")
#删除敌机后打印(可忽略)
def __del__(self):
print("敌机挂了 %s" % self.rect)
- 创建英雄精灵类
class Hero(GameSprite):
def __init__(self):
#传入玩家飞机图片
image_name = "./images/plane.png"
super().__init__(image_name,0)
#设置初始位置
self.rect.centerx = SCREEN_RECT.centerx
self.rect.bottom = SCREEN_RECT.bottom - 80
#创建子弹精灵组
self.bullets = pygame.sprite.Group()
self.speed1 = 0
def update(self):
#key.get_pressed(pygame提供的方法)设置按键
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_RIGHT]:
self.rect.x += 10
elif keys_pressed[pygame.K_LEFT]:
self.rect.x -= 10
elif keys_pressed[pygame.K_UP]:
self.rect.y -= 10
elif keys_pressed[pygame.K_DOWN]:
self.rect.y += 10
if keys_pressed[pygame.K_c]:
self.fire()
# 判断屏幕边界
if self.rect.left < 0:
self.rect.left = 0
elif self.rect.right > SCREEN_RECT.right:
self.rect.right = SCREEN_RECT.right
elif self.rect.top < 0:
self.rect.top = 0
elif self.rect.bottom > SCREEN_RECT.bottom:
self.rect.bottom = SCREEN_RECT.bottom
#发射子弹
def fire(self):
bullet = Bullet()
bullet1 = Bullet()
bullet2 = Bullet()
#子弹发射位置
bullet.rect.bottom = self.rect.y -30
bullet.rect.centerx = self.rect.centerx
bullet1.rect.bottom = self.rect.y -20
bullet1.rect.centerx = self.rect.centerx + 15
bullet2.rect.bottom = self.rect.y -20
bullet2.rect.centerx = self.rect.centerx - 15
#将子弹添加到精灵组
self.bullets.add(bullet,bullet1,bullet2)
- 创建子弹精灵
class Bullet(GameSprite):
def __init__(self):
#传入子弹图片
image_name = './images/bullet1.png'
super().__init__(image_name,-10)
#判断子弹超出屏幕后删除
def update(self):
super().update()
if self.rect.bottom < 0:
self.kill()