4 玛丽冒险 - pygame+itertools+random

#### 4.1 需求分析

特点:

1、播放与停止背景音乐

2、随机生成管道与导弹障碍

3、显示积分

4、跳跃躲避障碍

5、碰撞障碍

6、游戏音效

#### 4.2 系统设计

##### 4.2.1 系统功能结构

音效

- 背景音乐的播放与停止

- 动作音效(跳跃,加分。碰撞)

主窗体:

- 移动的玛丽
- 滚动的地图
- 碰撞
- 积分

随机障碍

- 飞行的导弹
- 管道

##### 4.2.2 系统业务流程

用户 --> 主窗体 --> 随机出现障碍 -->躲避障碍 --> 验证 --> (是) 添加积分

验证--> (否) 碰撞 ---> 结束 ---> 主窗体

#### 4.3 系统开发必备

##### 4.3.1 开发工具必备

开发运行环境:     

​    操作系统:win7,win10

​    python版本:3.7

​    内置模块:itertools,random

​    第三方模块:pygame

##### 4.3.2 文件夹组织架构

marie_adventure -- 项目包

- audio  --- 保存音效文件
- image --- 保存图片
- marie.py -- 游戏文件

#### 4.4 实现

##### 4.4.1 游戏窗体的实现

开始 →     1、定义窗体大小/2、定义更新画面的时间 --> 

​        --->   初始化:应用 init()函数 

​        ---> 循环更新窗体 (应用:pygame.display.update()方法)

​        ---> 是否关闭窗体 ---> 是 ---> 关闭 ---> 结束

​                                     -----> 否  ---> 循环更新窗体 

具体步骤:

(1) 创建文件夹

(2) 导入pygame库和pygame中的常量库,定义窗体的宽度和高度

```python
import pygame
from pygame.locals import *        # 导入pygame中的常量
import sys            # 系统模块

SCREENWIDTH = 822        # 窗口宽度
SCREENHEIGHT = 199        # 窗口高度
FPS = 30                # 更新画面的时间
```

(3) 创建mainGame()方法。在该方法中首先进行pygame的初始化工作,然后创建时间对象用于更新窗体中的画面,再创建窗体实例并设置窗体的标题文字,最后通过循环实现窗体的显示与刷新

```
def mainGame():
    score = 0
    over = False
    global SCREEN, FPSCLOCK    
    pygame.init()            # 初始化pygame
    # 使用python时钟控制每个循环多长时间运行一次,
```

##### 4.4.2 地图加载

```

```

##### 4.4.3 跳跃功能

1、指定玛丽的固定坐标(默认显示在地图上的固定位置),

2、判断是否按下<space>键,按下了就开启跳跃开关,以5个像素的距离向上移动

3、当玛丽到达窗体顶部的边缘时,再让其以5个像素的距离向下移动,回到地面后关闭跳跃的开关

开始 --- > 创建Marie类(加载图片)<应用:init()函数> ---> 是否按下空格键 --- 是 ---> 玛丽是否在地面 ---是--> 实现玛丽跳跃 应用:marie.jump_audio.play()方法, jump()函数 ,move()函数 , draw_marie()函数。

具体步骤:

(1)导入迭代工具,创建一个名称为Marie的玛丽类,然后在该类的初始化方法中,首先定义玛丽跳跃时所需要的变量,然后加载玛丽跑动的三张照片,最后加载玛丽跳跃时的音效并设置玛丽默认显示的坐标位置,

```python
from itertools import cycle        # 导入迭代工具

class Marie():
    def __init__(self):
        # 初始化玛丽矩形
        self.rect = pygame.Rect(0,0,0,0)
        self.jumpState = False        # 跳跃的状态
        self.jumpHeight = 130        # 跳跃的高度
        self.lowest_y = 140            # 最低坐标
        self.jumpValue = 0            # 跳跃增变量
        
        # 玛丽动图索引
        self.marieIndex = 0
        self.marieIndexGen = cycle([0,1,2])
        
        # 加载玛丽图片
        self.adventure_img = (
            pygame.image.load('image/adventure1.png').convert_alpha(),
            pygame.image.load('image/adventure2.png').convert_alpha(),
            pygame.image.load('image/adventure3.png').convert_alpha(),
        )
        self.jump_audio = pygame.mixer.Sound('audio/jump.wav')        # 跳音效
        self.recv.size = self.adventure_img[0].get_size()
        self.x = 50;        # 绘制玛丽的x坐标
        self.y = self.lowest_y            # 绘制玛丽的y坐标
        self.rect.topleft =(self.x, self.y)
```

(2)在Marie类中创建jump()方法,通过该方法实现开启跳跃的开关,

```python
# 跳状态
def jump(self):
    self.jumpState = True
```

(3)在Marie类中创建move()方法,在该方法中判断如果玛丽的跳跃开关开启时,再判断玛丽是否在地面上,如果满足这两个条件玛丽就以五个像素的距离向上移动,当玛丽到达窗体顶部时以5个像素的距离向下移动,当玛丽回到地面后关闭跳跃开关

```
# 玛丽移动
def move(self):
    if self.jumpState:
        if self.rect.y >= self.lowest_y:
            self.jumpValue = -5
        if self.rect.y <= self.lowest_y - self.jumpHeight:
            self.jumpValue = 5
        self.rect.y += self.jumpValue
        if self.rect.y >= self.lowest_y:
            self.jumpState = False
```

##### 4.4.4 随机出现的障碍

##### 4.4.5 背景音乐的播放与停止

##### 4.4.6 碰撞和积分的实现

开始 -- 循环执行游戏(障碍物与玛丽)  --> 是否发生碰撞 --> Y --> 游戏结束:应用:game_over函数 --> 结束

​                                                        ---> N --> 是否越过障碍 --> Y --> 加分,应用:getScore()函数 -->循环执行游戏..

实现碰撞和积分功能的具体步骤如下:

(1)Obstacle类中,draw_obstacle()方法的下面创建getScore()方法用于获取分数并播放加分音效,然后创建showScore()方法用于在窗体顶部右侧的位置显示分数。

```python
# 获取分数
def getScore(self):
    tmp = self.score
    if tmp == 1;
        self.score_audio.play()        # 播放加分音乐 ??
    self.score = 0
    return tmp
    
# 显示分数
def showScore(self,score):
    # 获取得分数字
    self.scoreDigits = [int(x) for x in list(str(score))]        
    totalWidth = 0            # 要显示的所有数字的总宽度
    for digit in self.scoreDigits:
        # 获取积分图片的宽度
        totalWidth += self.numbers[digit].get_width()
    # 分数横向位置
    Xoffset = (SCREENWIDTH - (totalWidth+30))
    for digit in self.scoreDigits:
        # 绘制分数
        SCREEN.blit(self.numbers[digit],(Xoffset,SCREENHEIGHT*0.1))
        # 随着数字增加改变位置
        Xoffset += self.numbers[digit].get_width()
```

(2) 在mainGame()方法的上面最外层创建game_over()方法,在该方法中首先需要加载与播放撞击的音效,然后获取窗体的宽度与高度,最后加载游戏结束的图片并将该图片显示在窗体的中间位置,代码如下:

```python
# 游戏结束的方法
def game_over():
    bump_audio = pygame.mixer.Sound('audio/bump.wav')        # 撞击
    bump_audio.play()                                        # 播放撞击音效
    # 获取窗体宽,高
    screen_w = pygame.display.Info().current_W
    screen_h = pygame.display.Info().current_h
    # 加载游戏结束的图片
    over_img = pygame.image.load('image/gameover.png').convert_alpha()
    
    # 将游戏结束的图片绘制在窗体的中间位置
    SCREEN.blit(over_img,((screen_w - over_img.get_width())/2,(screen_h - over_img.get_height())/2))
```

(3) 在mainGame()方法中,绘制障碍物代码的下面判断玛丽与障碍物是否发生碰撞,如果发生了碰撞则开启游戏结束的开关,并调用游戏结束的方法显示游戏结束的图片,否则判断玛丽是否越过了障碍物,越过就进行分数的增加并显示当前得分,代码如下

```python
# 判断玛丽与障碍物是否碰撞
if pygame.sprite.collide_rect(marie, list[i]):
    over = True        # 碰撞后开启结束开关
    game_over()        # 调用游戏结束的方法
    music_button.bg_music.stop()
else:
    # 判断玛丽是否越过障碍物
    if(list[i].rect.x + list[i].rect.width) < marie.rect.x:
        # 加分
        score += list[i].getScore()
# 显示分数
list[i].showScore(score)
```

(4) 为了实现游戏结束后再次按下键盘上的<space>(空格)键时,重新启动游戏。所以需要在mainGame()方法中开启玛丽跳的状态代码的下面判断游戏结束的开关是否开启,如果开启将重新调用mainGame()方法重新启动游戏,代码如下

```python
if over == True:        # 判断游戏结束的开关是否开启
    mainGame()            # 如果开启将调用mainGame方法重启游戏
```

#### 4.5 小结

pygame为核心模块

itertools实现动态图片的迭代

random产生随机数字,实现障碍物的随机出现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值