# 基于 Python 设计的小恐龙小游戏
本来想带大家用遗传算法再训一波龙的,于是把自己之前写的仿谷歌浏览器小恐龙代码找了出来,就是这个:
Python 制作小游戏(七)
想在它基础上加 AI 控制的代码的,结果发现之前写的那个版本和原版还是有出入的,而且玩起来的体验也很差,于是就打算先重构一版这个游戏分享给大家,然后再带大家训龙。毕竟磨刀不误砍柴工嘛。
废话不多说,让我们愉快地开始吧
## 开发工具
Python 版本:**3.6.4
**相关模块:**
pygame 模块;
以及一些 python 自带的模块。
##### 环境搭建
安装 Python 并添加到环境变量,pip 安装需要的相关模块即可。
##### 先睹为快
在终端运行如下命令即可:
```
python Game7.py
```
效果如下:
![](https://www.writebug.com/myres/static/uploads/2022/5/16/65ecc8d97274f9acf8e1d051c09374c3.writebug)
#### 原理简介
这里介绍一下游戏的实现原理,先说明一下,为了后面方便训龙,我没有加入黑夜的场景效果,即游戏只有白天的场景。
首先,我们对游戏进行一些必要的初始化工作:
```
# 游戏初始化
pygame.init()
screen = pygame.display.set_mode(cfg.SCREENSIZE)
pygame.display.set_caption('T-Rex Rush —— Charles的皮卡丘')
# 导入所有声音文件
sounds = {}
for key, value in cfg.AUDIO_PATHS.items():
sounds[key] = pygame.mixer.Sound(value)
```
接着,我们来考虑一下,游戏中有哪些游戏元素:
- 小恐龙:由玩家控制以躲避路上的障碍物;
- 路面:游戏的背景;
- 云:游戏的背景;
- 飞龙:路上的障碍物之一,小恐龙碰上就会死掉;
- 仙人掌:路上的障碍物之一,小恐龙碰上就会死掉;
- 记分板:记录当前的分数和历史最高分。
让我们来依次定义一下这些游戏元素类。对于云,路面以及仙人掌来说,定义起来很简单,我们只需要加载对应的游戏元素图片:
![](https://www.writebug.com/myres/static/uploads/2022/5/16/9bee4fa92c79cd8d0356e7eb37f87514.writebug)
然后写两个类内部方法 update 和 draw 就 ok 了。两个方法分别用于将场景不断向左移动以实现小恐龙不断向前移动的动画效果和将场景显示在游戏界面的对应位置上。具体而言,代码实现如下:
```
'''地板'''
class Ground(pygame.sprite.Sprite):
def __init__(self, imagepath, position, **kwargs):
pygame.sprite.Sprite.__init__(self)
# 导入图片
self.image_0 = pygame.image.load(imagepath)
self.rect_0 = self.image_0.get_rect()
self.rect_0.left, self.rect_0.bottom = position
self.image_1 = pygame.image.load(imagepath)
self.rect_1 = self.image_1.get_rect()
self.rect_1.left, self.rect_1.bottom = self.rect_0.right, self.rect_0.bottom
# 定义一些必要的参数
self.speed = -10
'''更新地板'''
def update(self):
self.rect_0.left += self.speed
self.rect_1.left += self.speed
if self.rect_0.right < 0:
self.rect_0.left = self.rect_1.right
if self.rect_1.right < 0:
self.rect_1.left = self.rect_0.right
'''将地板画到屏幕'''
def draw(self, screen):
screen.blit(self.image_0, self.rect_0)
screen.blit(self.image_1, self.rect_1)
'''云'''
class Cloud(pygame.sprite.Sprite):
def __init__(self, imagepath, position, **kwargs):
pygame.sprite.Sprite.__init__(self)
# 导入图片
self.image = pygame.image.load(imagepath)
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = position
# 定义一些必要的参数
self.speed = -1
'''将云画到屏幕上'''
def draw(self, screen):
screen.blit(self.image, self.rect)
'''更新云'''
def update(self):
self.rect = self.rect.move([self.speed, 0])
if self.rect.right < 0:
self.kill()
'''仙人掌'''
class Cactus(pygame.sprite.Sprite):
def __init__(self, imagepaths, position=(600, 147), sizes=[(40, 40), (40, 40)], **kwargs):
pygame.sprite.Sprite.__init__(self)
# 导入图片
self.images = []
image = pygame.image.load(imagepaths[0])
for i in range(3):
self.images.append(pygame.transform.scale(image.subsurface((i*101, 0), (101, 101)), sizes[0]))
image = pygame.image.load(imagepaths[1])
for i in range(3):
self.images.append(pygame.transform.scale(image.subsurface((i*68, 0), (68, 70)), sizes[1]))
self.image = random.choice(self.images)
self.rect = self.image.get_rect()
self.rect.left, self.rect.bottom = position
self.mask = pygame.mask.from_surface(self.image)
# 定义一些必要的变量
self.speed = -10
'''画到屏幕上'''
def draw(self, screen):
screen.blit(self.image, self.rect)
'''更新'''
def update(self):
self.rect = self.rect.move([self.speed, 0])
if self.rect.right < 0:
self.kill()
```
记分板的定义也类似,只不过它不需要移动,但是需要实时地更新当前 的分数:
```
'''记分板'''
class Scoreboard(pygame.sprite.Sprite):
def __init__(self, imagepath, position, size=(11, 13), is_highest=False, bg_color=None, **kwargs):
pygame.sprite.Sprite.__init__(self)
# 导入图片
self.images = []
image = pygame.image.load(imagepath)
for i in range(12):
self.images.append(pygame.transform.scale(image.subsurface((i*20, 0), (20, 24)), size))
if is_highest:
self.image = pygame.Surface((size[0]*8, size[1]))
else:
self.image = pygame.Surface((size[0]*5, size[1]))
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = position
# 一些必要的变量
self.is_highest = is_highest
self.bg_color = bg_color
self.score = '00000'
'''设置得分'''
def set(self, score):
self.score = str(score).zfill(5)
'''画到屏幕上'''
def draw(self, screen):
self.image.fill(self.bg_color)
for idx, digital in enumerate(list(self.score)):
digital_image = self.images[int(digital)]
if self.is_highest:
self.image.blit(digital_image, ((idx+3)*digital_image.get_rect().width, 0))
else:
self.image.blit(digital_image, (idx*digital_image.get_rect().width, 0))
if self.is_highest:
self.image.blit(self.images[-2], (0, 0))
self.image.blit(self.images[-1], (digital_image.get_rect().width, 0))
screen.blit(self.image, self.rect)
```
上面代码用 is_highest 变量来区分该记分板是否用于记录游戏最高分,还是只是记录当前的分数,做该区分的原因是游戏最高分前面有 HI 标识,所以占的空间更大:
![](https://www.writebug.com/myres/static/uploads/2022/5/16/c357ab88099110c4243bbf8747d3130d.writebug)
飞龙的定义就稍微复杂一些了,因为它不仅需要向左移动,还需要做出不停扇动翅膀的效果。具体而言,飞龙有两张图:
![](https://www.writebug.com/myres/static/uploads/2022/5/16/3f254b648fbc5d9debed50b18ec95fbd.writebug)
你需要做的就是每隔一段时间就切换一次当前的飞龙图片,以实现飞龙扇动翅膀的效果:
```python
'''飞龙'''
class Ptera(pygame.sprite.Sprite):
def __init__(self, imagepath, position, size=(46, 40), **kwargs):
pygame.sprite.Sprite.__init__(self)
# 导入图片
self.images = []
image = pygame.image.load(imagepath)
for i in range(2):
self.images.append(pygame.transform.scale(image.subsurface((i*92, 0), (92, 81)), size))
self.image_idx = 0
self.image = self.images[self.image_idx]
self.rect = self.image.get_rect()
self.rect.left, self.rect.centery = position
self.mask = pygame.mask.from_surface(self.image)
# 定义一些必要的变量
self.speed = -10
self.ref
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
100011853-基于Python制作小恐龙游戏.zip (26个子文件)
cpgam
__init__.py 51B
resources
audios
die.wav 33KB
jump.wav 8KB
point.wav 57KB
images
cacti-big.png 1KB
ground.png 568B
numbers.png 459B
dino.png 1KB
ptera.png 594B
cloud.png 329B
gameover.png 408B
offline-sprite-2x-black.png 6KB
dino_ducking.png 714B
cacti-small.png 782B
replay.png 432B
LICENSE 1KB
modules
__init__.py 149B
interfaces
__init__.py 106B
endinterface.py 1KB
startinterface.py 1KB
sprites
__init__.py 128B
obstacle.py 3KB
dinosaur.py 3KB
scene.py 3KB
trexrush.py 7KB
README.md 17KB
共 26 条
- 1
资源评论
神仙别闹
- 粉丝: 2704
- 资源: 7645
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功