首先要下载pygame
代码类
(1)游戏初始化
image.png(2)创建英雄
image.png(3)创建游戏窗口
image.png
(4)创建图像
image.png
(5)创建飞机
(6)调用update方法
image.png
(7)创建时钟对象
image.png
(8)让英雄动起来
image.png
(9)监听退出 image.png
(10)飞机循环飞行
image.png image.png
总的代码
import pygame
from gws import *
class PlaneGame(object):
"""飞机大战主游戏类"""
def __init__(self):
print("游戏初始化")
"""在开始游戏我们做这么几件事
1 创建游戏窗口
2 创建游戏时钟
3 调用创建精灵和精灵组的方法 (私有方法)
"""
self.screen = pygame.display.set_mode(SCREEN_RECT.size)
self.clock = pygame.time.Clock(self.__create_sprites()
pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000)
def start_game(self):
"""在开始游戏这里我们需要做下面几件事"""
while True:
# 1 设置帧率
self.clock.tick(60)
# 2 事件监听 主要是要监听我们鼠标 键盘的一些事件
self.__event_handler()
# 3 碰撞检测 碰撞检测的内容比较 在这里我还没有定义 现在需要补上
self.__check_collide()
# 4 更新精灵和精灵组
self.__update_sprites()
# 5 更新显示
pygame.display.update()
# 在上面 我们调用类方法 并且关于帧率的设置
# 更新精灵组 碰撞检测 刷新屏幕这些事情 是要实时检测的
# 所以我写在游戏循环里面
# 没1/60秒 就会调用一次
# 创建精灵和精灵组
def __create_sprites(self):
bg1 = Background()
# True 就表示是第二张图片
bg2 = Background(True)
# 首先你要知道 你需要先 创建背景精灵 需要把精灵的修改一下
# bg1 = Background('images/background.png')
# bg2 = Background('images/background.png')
# # 我们发现 两张图片的位置我们需要设置一下
# bg2.rect.y = -bg2.rect.height
# 我们已经创建了背景精灵 我们接下来可以创建一个背景精灵组
# 背景组 把我们的背景扔进 背景精灵组
#------------------------------------------
# 英雄
self.hero = Hero(60)
self.hero1 = Hero(-60)
self.back_group = pygame.sprite.Group(bg1, bg2)
# 敌机组
self.enemy_group = pygame.sprite.Group()
# 英雄组
self.hero_group = pygame.sprite.Group(self.hero,self.hero1)
# 事件监听
def __event_handler(self):
# 在这里我先写 事件监听 为啥呢?在调试过程中我好关闭窗口呀
for event in pygame.event.get():
# 另外一个方案 返回按键元组 这个我们观察一下就知道了
# 如果 某个按键按下 对应的值应该会是
key_pressed = pygame.key.get_pressed()
key_pressed1 = pygame.key.get_pressed()
if key_pressed[pygame.K_KP1]:
self.hero.fire()
if key_pressed[pygame.K_RIGHT]:
print("向右边移动")
# 给英雄一个移动速度
self.hero.speed = 8
elif key_pressed[pygame.K_LEFT]:
self.hero.speed = -8
print("向左边移动")
elif key_pressed[pygame.K_UP]:
print("向上边移动")
self.hero.speed1 = -8
elif key_pressed[pygame.K_DOWN]:
print("想下边移动")
self.hero.speed1 = 8
else:
self.hero.speed = 0
self.hero.speed1 = 0
# pygame.event.get():这是 获取到我们所有的事件
if event.type == pygame.QUIT:
# 哈哈 我调用方法 是不是相当于可以关闭我们的窗口啦!!!
# 在开发的过程中需要 有这种思想 专门的事情由专门的方法去做
self.__game_over()
# event.type 相当于说之前 是通过我们按键盘或者
# 移动鼠标 产生事件
# 那么现在呢 是我们自己创造一个事件 每秒执行一次
# 然后我们去监听我们自己 让 系统去每秒调用的事件
# 如果调到 那就说明监听成功
# 那么既然监听监听成功 我需要在监听成功后
# 去创建敌机 因为我的目的 就是每秒创建一家敌机
elif event.type == CREATE_ENEMY_EVENT:
# 因为我的敌机精灵类还没有写
# 我这里就先输出一下
# 其实这一步 我们完全可以先运行一下
# 看看有没有出错 看看是不是每秒调用一次
print("新的敌机产生")
# 我们添加了敌机 但是但是但是
# 没有刷新呀!
self.enemy_group.add(Enemy())
#elif event.type == HERO_FIRE_EVENT:
#self.hero.fire()
#self.hero1.fire()
if key_pressed1[pygame.K_SPACE]:
self.hero1.fire()
if key_pressed1[pygame.K_d]:
print("向右边移动")
# 给英雄一个移动速度
self.hero1.speed = 8
elif key_pressed1[pygame.K_a]:
self.hero1.speed = -8
print("向左边移动")
elif key_pressed1[pygame.K_w]:
print("向上边移动")
self.hero1.speed1 = -8
elif key_pressed1[pygame.K_s]:
print("想下边移动")
self.hero1.speed1 = 8
else:
self.hero1.speed = 0
self.hero1.speed1 = 0
# 更新精灵和精灵组
def __update_sprites(self):
"""更新精灵组"""
# 我们这一步 先更新背景组
# 刷新位置
# self.back_group.update()
# # 绘制到屏幕上 类似blit
# self.back_group.draw(self.screen)
# self.enemy_group.update()
# self.enemy_group.draw(self.screen)
# self.hero_group.update()
# self.enemy_group.draw(self.screen)
# 到这里我们就可以简写代码了 改造 看了比较清爽
for xxx in [self.back_group, self.enemy_group, self.hero_group, self.hero.bullets, self.hero1.bullets]:
xxx.update()
xxx.draw(self.screen)
def __check_collide(self):
"""接下来我们就需要完成碰撞检测"""
# 1 子弹摧毁飞机
# 子弹炸毁敌机 的情况:
# 地一个参数和第二个参数是要参与碰撞检测的精灵
# 地三个参数为 Ture的时候 就是当碰撞的时候 被碰撞的精灵从精灵组移出
pygame.sprite.groupcollide(
self.enemy_group, self.hero.bullets,True, True)
# 2 敌机撞毁飞机
enemies = pygame.sprite.spritecollide(
self.hero, self.enemy_group, True)
pygame.sprite.groupcollide(
self.enemy_group, self.hero1.bullets, True, True)
enemies1 = pygame.sprite.spritecollide(
self.hero1, self.enemy_group, True)
# 判断列表时候有内容
if len(enemies) == 1:
# 让英雄牺牲
self.hero.kill()
self.hero.rect.x = -SCREEN_RECT.width
if len(enemies1) == 1:
self.hero1.kill()
self.hero1.rect.x = -SCREEN_RECT.width
if self.hero.rect.x == -SCREEN_RECT.width and self.hero1.rect.x == -SCREEN_RECT.width:
# 结束游戏
self.__game_over()
def __game_over(self):
"""游戏结束"""
print("游戏结束")
# 这是pygame提供的卸载模块的功能
pygame.quit()
# 这是python本身提供的退出脚本的功能
exit()
# 总结 :我们需要先卸载我们的pygame模块 然后退出我们的脚本
# 这个方法就是在我当前方法内生效 在其他模块调不到
if __name__ == "__main__":
# 创建游戏对象
game = PlaneGame()
# 开始游戏
game.start_game()
"""
来讲讲类的设计吧! 这个游戏类 我们主要就是考虑逻辑性 当然 你按照之前的学习快速入门的内容 也能搞出
一个打飞机 但是我们需要把我们的代码写的逻辑清晰 并且
分工明确
关于 planeGame类 我们内部是这么设计的
PlaneGame为我们的主游戏类
包含这些属性 screen--->游戏屏幕 clock--->游戏时钟
设计了几个方法 分别做不同的事情
1 初始化方法:设置我们的初始化属性
2 创建精灵 __create_sprites(self): 这里我设置成私有方法
3 start_game(self): 是开始游戏的方法
4 事件监听 event_handler
5 碰撞检测 check_collider
6 更新精灵和精灵组(主要是为了实时去改变和绘制我们精灵
游戏精灵(背景 飞机 敌机 子弹 的位置
7 结束游戏 game_over
大致我们就分析完了 现在来开始写我们的代码
"""
另一个代码
"""
这是我们刚刚说的 另外一个需要设计的模块
在这个模块 放一些常用工具和 基础类 和精灵类
在其他模块调用
"""
import pygame
import random
# 设置游戏屏幕小大 这是一个常量
# 常量见名知意 就是不需要猜测的数字的含义 就是一个固定的数值
# 通过一处修改 其他地方也能生效 统一控制
SCREEN_RECT = pygame.Rect(0, 0, 480,700)
# 我们的父类需要考虑这几个问题
# 1 通用性 2 属性有哪些 方法有哪些 将来谁要用
# 我们自己去定制的精灵类 需要继承 pygame提供的精灵类
"""
我们需要定义的属性有:
image-->图片
rect--->坐标
speed -->速度
"""
# 接下来我们就开始写我们敌机方面的内容 (产生敌机)
# 我先定义一个事件常量
CREATE_ENEMY_EVENT = pygame.USEREVENT
# 我们还可以定义一个事件常量 (发射子弹)
HERO_FIRE_EVENT = pygame.USEREVENT + 1
GameSprite(pygame.sprite.Sprite):
"""游戏精灵的基础类"""
# 我们其实可以给我们的基础类的速度 设置一个默认值
def __init__(self,new_image,new_speed=1):
super().__init__()
# 我们需要以下3个属性
# 考虑到通用性 我们需要改造一下代码
# pygame.image.load pygame提供的方法 主要是加载图片
self.image = pygame.image.load(new_image)
# self.image.get_rect() 获取图片的宽高 get_rect() 是pygame提供
self.rect = self.image.get_rect()
# 这是将来精灵的移动速度 精灵有:英雄精灵 背景精灵 敌机精灵 子弹精灵
self.speed = new_speed
def update(self):
# 默认垂直方向移动 (这个时候我就要有一个概念 坐标系的y轴控制垂直
self.rect.y += self.speed
# 那么以上就是我们游戏的基础类 接下来我们需要设置我们的 背景类
# 首先我们需要先明确我们的背景类 继承自我们的游戏精灵类
class Background(GameSprite):
"""背景精灵类"""
def __init__(self,is_alt=False):
"""is_alt 判断是否为另外一张图像
False表示第一张图像
True表示另外一张图像 我们最开始说了 我们是2张图像交替
在这里我先设置一下 vim快捷键
"""
# 因为背景图片是固定的 所以我们可以在背景精灵类直接传图片
super().__init__('./images/background.png')
if is_alt:
# 如果是地二张图片 我们让他的初始位置为 -self.rect.height
self.rect.y = -self.rect.height
def update(self):
# 1 调用父类的方法实现 这是实现父类方法
super().update()
# 2 判断是否移除屏幕 如果移出屏幕 我们就要将图像设置到屏幕到上方
# SCREEN_RECT.height 这是我们自己设置的常量 我们可以往上看
# 其实到这一步 我们就已经把我们的背景类设计完了 接下来我们就去我们的主程序模块调用就行了
if self.rect.y >= SCREEN_RECT.height:
self.rect.y = -self.rect.height
# 接下来我们就要设置我们的敌机类
# 我们的敌机类 同样也是继承自我们的精灵基类
class Enemy(GameSprite):
"""敌机精灵类"""
def __init__(self):
# 1 调用父类方法 创建敌机精灵类 并且指定敌机图像
super().__init__('./images/enemy1.png')
# 2 设置敌机初始速度 稍后设置 (随机数)
# 我的sublime 没有花事件去调 老是跟我发脾气
self.speed = random.randint(1, 3)
# 3 设置敌机的随机初始位置 稍后设置
# self.rect.y = self.rect.bottom - self.rect.height
self.rect.bottom = 0
# 敌机x轴最大值 需要用屏幕的宽度-敌机自身的宽度
max_x = SCREEN_RECT.width - self.rect.width
# 随机一个位置
self.rect.x = random.randint(0, max_x)
# 我们发现。。。。。敌机出来的位置在 一条线上
# 说明 x轴的位置一直没有变
def update(self):
# 1 调用父类方法
super().update()
# 2 判断是否飞出屏幕 如果是 需要敌机从精灵组删除
if self.rect.y >= SCREEN_RECT.height:
print("敌机飞出屏幕")
# 移出屏幕 就销毁
self.kill()
# 接下来我们就设计英雄类和子弹类
# 英雄精灵类
class Hero(GameSprite):
"""英雄精灵类"""
def __init__(self,a):
# 英雄的初始速度我设置为0
super().__init__('./images/me1.png',0)
# 设置初始位置 这是是让我英雄X轴的中心点等于屏幕X轴中心点
self.rect.centerx = SCREEN_RECT.centerx + a
# 这里是设置我飞机的y轴
self.rect.bottom = SCREEN_RECT.bottom
# 子弹组
self.bullets = pygame.sprite.Group()
# 这样 我们的子弹精灵组 就创建完毕了 我们就要去fire里面修改我们的
# 方法
self.speed1 = 0
def update(self):
# 飞机水平移动
self.rect.x += self.speed
self.rect.y += self.speed1
# 控制英雄边界 屏幕边界
if self.rect.left < 0:
self.rect.left = 0
if self.rect.right >SCREEN_RECT.right:
self.rect.right = SCREEN_RECT.right
if self.rect.bottom > SCREEN_RECT.height:
self.rect.bottom = SCREEN_RECT.height
if self.rect.top < 0:
self.rect.top = 0
def fire(self):
# 英雄的方法。。。发射子弹 是一个动作 是一个行为 。。。
print("发射子弹....")
for i in (1,2,3):
# 子弹精灵 我们在 英雄的这个fire()方法里面去创建
#1 创建 子弹精灵
bullet = Bullet()
gws = Bullet()
sst = Bullet()
#2 设置精灵位置
bullet.rect.bottom = self.rect.y -20
bullet.rect.centerx = self.rect.centerx
gws.rect.bottom = self.rect.y -20
gws.rect.centerx = self.rect.centerx +15
sst.rect.bottom = self.rect.y -20
sst.rect.centerx = self.rect.centerx -15
#3 将精灵添加到精灵组
self.bullets.add(bullet,gws,sst)
class Bullet(GameSprite):
"""子弹精灵"""
def __init__(self):
super().__init__('./images/bullet1.png',-10)
def update(self):
super().update()
# 判断是否超出屏幕
if self.rect.bottom < 0:
self.kill()
这就是基本的飞机大战
网友评论