# 基于 Python 制作接金币小游戏
Python 版本:3.6.4
**相关模块:**
pygame 模块;
以及一些 python 自带的模块。
#### 环境搭建
安装 Python 并添加到环境变量,pip 安装需要的相关模块即可。
**原理简介**
首先先声明一下,这个小游戏主要是依赖 pygame 写的,不会 pygame 的小伙伴请先阅读相关的开发文档了解一下这是啥
首先,我们来进行一下游戏的初始化操作(比如初始化游戏窗口,加载一些必要的游戏素材等等),代码实现如下:
```python
'''游戏初始化'''
def initGame():
# 初始化pygame, 设置展示窗口
pygame.init()
screen = pygame.display.set_mode(cfg.SCREENSIZE)
pygame.display.set_caption('catch coins —— 微信公众号: Charles的皮卡丘')
# 加载必要的游戏素材
game_images = {}
for key, value in cfg.IMAGE_PATHS.items():
if isinstance(value, list):
images = []
for item in value: images.append(pygame.image.load(item))
game_images[key] = images
else:
game_images[key] = pygame.image.load(value)
game_sounds = {}
for key, value in cfg.AUDIO_PATHS.items():
if key == 'bgm': continue
game_sounds[key] = pygame.mixer.Sound(value)
# 返回初始化数据
return screen, game_images, game_sounds
```
接着,为了让我们在写小游戏的过程中保持一个良好的心情,就先让自己喜欢的游戏背景音乐响起来吧
然后选一张好看的背景图片,这样才可以在它的基础上逐渐加入接金币这个小游戏涉及到的游戏元素嘛:
![](https://www.writebug.com/myres/static/uploads/2022/5/16/8cb9455258de19604e76b079edc9090e.writebug)
源代码如下:
```python
# 游戏主循环
clock = pygame.time.Clock()
while True:
# --填充背景
screen.fill(0)
screen.blit(game_images['background'], (0, 0))
# --按键检测
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# --更新屏幕
pygame.display.flip()
clock.tick(cfg.FPS)
```
小人的移动主要是通过我们自己定义的 Hero 类里的 move 函数实现的,具体而言代码实现如下:
```python
'''定义hero类'''
class Hero(pygame.sprite.Sprite):
def __init__(self, images, position=(375, 520), **kwargs):
pygame.sprite.Sprite.__init__(self)
self.images_right = images[:5]
self.images_left = images[5:]
self.images = self.images_right.copy()
self.image = self.images[0]
self.mask = pygame.mask.from_surface(self.image)
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = position
self.diretion = 'right'
self.speed = 8
self.switch_frame_count = 0
self.switch_frame_freq = 1
self.frame_index = 0
'''左右移动hero'''
def move(self, screensize, direction):
assert direction in ['left', 'right']
if direction != self.diretion:
self.images = self.images_left.copy() if direction == 'left' else self.images_right.copy()
self.image = self.images[0]
self.diretion = direction
self.switch_frame_count = 0
self.switch_frame_count += 1
if self.switch_frame_count % self.switch_frame_freq == 0:
self.switch_frame_count = 0
self.frame_index = (self.frame_index + 1) % len(self.images)
self.image = self.images[self.frame_index]
if direction == 'left':
self.rect.left = max(self.rect.left-self.speed, 0)
else:
self.rect.left = min(self.rect.left+self.speed, screensize[0])
'''画到屏幕上'''
def draw(self, screen):
screen.blit(self.image, self.rect)
```
实现小人左右走动这个效果的核心思路其实就是根据函数输入的方向来改变小人可以使用的图片组合(images_right/images_left)。然后对于正在往某个方向行动中的小人,每隔 switch_frame_freq 帧游戏画面就切换一次小人的图片,游戏中的小人图片一共十张:
![](https://www.writebug.com/myres/static/uploads/2022/5/16/51c6155e86b1bdfa68af63aecfe784d3.writebug)
前 5 张是向右走的图片组,后 5 张是向左走的图片组。
现在,我们开始实现掉金币的效果啦,就像这样:
![](https://www.writebug.com/myres/static/uploads/2022/5/16/2d46f8b772c52a4eece72307124c56b0.writebug)
核心代码实现如下:
```python
# 定义食物组
food_sprites_group = pygame.sprite.Group()
generate_food_freq = random.randint(10, 20)
generate_food_count = 0
while True:
...
# --随机生成食物
generate_food_count += 1
if generate_food_count > generate_food_freq:
generate_food_freq = random.randint(10, 20)
generate_food_count = 0
food = Food(game_images, random.choice(['gold',] * 10 + ['apple']), cfg.SCREENSIZE)
food_sprites_group.add(food)
# --更新食物
for food in food_sprites_group:
if food.update(): food_sprites_group.remove(food)
...
```
其中食物类的定义如下:
```python
'''定义食物类'''
class Food(pygame.sprite.Sprite):
def __init__(self, images_dict, selected_key, screensize, **kwargs):
pygame.sprite.Sprite.__init__(self)
self.screensize = screensize
self.image = images_dict[selected_key]
self.mask = pygame.mask.from_surface(self.image)
self.rect = self.image.get_rect()
self.rect.left, self.rect.bottom = random.randint(20, screensize[0]-20), -10
self.speed = random.randrange(5, 10)
self.score = 1 if selected_key == 'gold' else 5
'''更新食物位置'''
def update(self):
self.rect.bottom += self.speed
if self.rect.top > self.screensize[1]:
return True
return False
```
整个定义其实很简单,苹果 5 分,金币 1 分,update 函数用于实时更新食物的位置以实现食物下降的效果。
问题来了,我们该怎么实现接金币的效果呢,这金币一直往下掉接不住可咋办啊。别担心,只需要调用到 pygame 库里的碰撞检测功能就可以啦,具体而言代码实现如下:
```python
while True:
...
# --碰撞检测
for food in food_sprites_group:
if pygame.sprite.collide_mask(food, hero):
game_sounds['get'].play()
food_sprites_group.remove(food)
score += food.score
...
```
代码原理其实很简单,就是实时地检测小人有没有接触到金币,接触到的话就发出接到金币的声音,并移除对应的金币和获得一定的奖励得分。效果是这样子的:
![](https://www.writebug.com/myres/static/uploads/2022/5/16/17ea9f853eec4b29c1185164cb69e07b.writebug)
最后,我们来完善一下我们的小游戏,让它看起来更加"规范"一些:
(1) 加入倒计时(在规定的时间内获得尽量高的得分)
```python
while True:
...
# --倒计时信息
countdown_text = 'Count down: ' + str((90000 - pygame.time.get_ticks()) // 60000) + ":" + str((90000 - pygame.time.get_ticks()) // 1000 % 60).zfill(2)
countdown_text = font.render(countdown_text, True, (0, 0, 0))
countdown_rect = countdown_text.get_rect()
countdown_rect.topright = [cfg.SCREENSIZE[0]-30, 5]
screen.blit(countdown_text, countdown_rect)
...
```
(2) 显示得分(显示当前的得分和历史最高分)
```
while True:
...
# --显示得分
score_text = f'Score: {score}, Highest: {highest_score}'
score_text = font.render(score_text, True, (0, 0, 0))
score_rect = score_text.get_rect()
score_rect.topleft
基于 Python 制作接金币小游戏【100011851】
版权申诉
183 浏览量
2023-04-12
17:06:13
上传
评论
收藏 4.53MB ZIP 举报
神仙别闹
- 粉丝: 2687
- 资源: 7649
最新资源
- 教学内容及补充-cha7.rar
- 设计1.ms14
- vscode-1.64.1.tar源码文件
- vscode-1.64.0.tar源码文件
- vscode-1.52.0.tar源码文件
- Music-Player +PlayerActivity+ rockplayer+ SeeJoPlayer 播放器JAVA源码
- vscode-1.46.0.tar源码文件
- 最近很火植物大战僵尸杂交版2.08苹果+安卓+PC+防闪退工具V2+修改工具+高清工具+通关存档整合包更新
- 超级好用的截图工具PixPin,可录制Gif图
- Screenshot_2024-05-21-17-06-42-64_2332cb9b27b851b548ba47a91682926c.jpg
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈