Python游戏开发-超级海盗!!!

开发环境配置

安装python环境后,下载pygame模块,使用如下命令

pip install pygame

注:该项目使用了一些新特性,使用3.10以上的版本

游戏项目介绍

游戏分为两个模块,分别是编辑模块和关卡模块,在编辑模块下,玩家可拖动地图菜单中的不同地图元素,对游戏界面进行地图的布局,在关卡模式下,玩家可控制角色对自己布局的地图关卡进行闯关

该游戏是一款类似于马里奥的闯关游戏,不同的是,玩家可自己设计游戏关卡进行闯关

游戏项目演示

项目源码获取在下面文章末尾获取 

游戏部分功能介绍

游戏模式切换

main.py为该程序的入口文件,editor.py为编辑模式的功能实现,level.py为关卡模式的功能实现,三者的关系如下

图片

在main.py中定义了一个标识符(self.editor_active)用于游戏两种模式的切换,默认该值为True,即运行程序,先进入编辑模式,编辑完成后,按下Enter键,则调用toggle()函数,将该值改为False,在main程序的循环体执行中,进入关卡模式

  #main.py中的Main类def run(self):while True:dt = self.clock.tick() / 1000# 通过检查self.editor_active的值,决定是运行编辑器还是关卡if self.editor_active:self.editor.run(dt)else:self.level.run(dt)self.transition.display(dt)pygame.display.update
 #main.py中的Main类def toggle(self):print('进入toggle,切换游戏的模式状态')self.editor_active = not self.editor_active# 通过检查self.editor_active的值,判断是否需要启动编辑器音乐if self.editor_active:self.editor.editor_music.play()

toggle函数的调用过程是较复杂的,程序运行后,首先调用了editor.run(dt),进入编辑模式,后调用Editor类中的event_loop()函数,该函数会及时响应玩家的事件操作(鼠标和键盘),当玩家在键盘中输入Enter键时,调用switch函数改变游戏模式状态

图片

Translation类作为main类的一个属性,在执行display()方法时,若属性transition.ative的值为True时(默认为False),进入if分支内,调用了main中的toggle()函数,改变了editor_active属性的值

 #Translation类#用于在游戏窗口中绘制过渡效果def display(self, dt):if self.active:self.border_width += 1000 * dt * self.directionif self.border_width >= self.threshold:self.direction = -1self.toggle()if self.border_width < 0:self.active = Falseself.border_width = 0self.direction = 1pygame.draw.circle(self.display_surface, 'black',self.center, self.radius, int(self.border_width))

游戏分数显示

为了提升游戏的体验感,增加游戏分数显示的功能,当玩家对关卡设计完成后,进行关卡挑战,玩家控制的角色只要接触到硬币,则右上角的游戏分数增加,按金币增加两分,银币增加一分进行计算

在level.py中的Level类的__init__()方法中添加属性score,用于记录游戏分数

# 游戏分数
self.score = 0

Player(玩家角色Sprite)类,在创建Level类时,作为level对象中的一个类属性被创建,同时地图上的其它(Sprite)类也被创建,这些精灵类都继承了通用的角色类Generic,而Generic继承Sprite

"""
通用的角色类,包含了角色的基本属性和方法
"""
class Generic(pygam,ere.sprite.Sprite):def __init__(self, pos, surf, group, z = LEVEL_LAYERS['main']):super().__init__(group)self.image = surfself.rect = self.image.get_rect(topleft = pos)self.z = z

这些精灵类都交给pygame.sprite.Group进行管理,它是一个可以容纳多个精灵对象的容器,作为Level类的一个属性,方便进行对象的获取

self.coin_sprites = pygame.sprite.Group()   # 硬币
self.shell_sprites = pygame.sprite.Group()  # 敌人

在Level类中声明get_coin()方法,用于检测角色是否触碰到硬币,pygame.sprite.spritecollide用于检测两个精灵对象是否发生碰撞,并返回碰撞列表,之所以调用两次,第一次用于获取碰撞的硬币对象信息,第二次设置为为True用于将碰撞的精灵删除

  def get_coins(self):# pygame.sprite.spritecollide:检测玩家和硬币的碰撞# 返回和玩家发生碰撞的硬币精灵的列表,同时将这些硬币精灵从 self.coin_sprites 精灵组中移除(设置碰撞为 True)collided_coins1 = pygame.sprite.spritecollide(self.player, self.coin_sprites, False)len = collided_coins1.__len__()if(len > 0):coin_type = collided_coins1[0].coin_typeprint(f'碰撞1:{collided_coins1[0].coin_type}')if coin_type == 'silver':print(self.score)self.score += 1elif coin_type == 'gold':print(self.score)self.score += 2else:self.player.life += 1print(f'生命数:{self.player.life}')collided_coins = pygame.sprite.spritecollide(self.player, self.coin_sprites, True)for sprite in collided_coins:print('碰撞')self.coin_sound.play()Particle(self.particle_surfs, sprite.rect.center, self.all_sprites)

此时游戏分数功能的记录已经完善,但还需要在游戏窗口中展示,在level.py中定义了CameraGroup类,继承自pygame.sprite.Group用于管理精灵对象,并在游戏窗口中进行精灵对象的绘制

游戏关卡模式运行时,会调用level.run方法,而run方法中,则调用了CameraGroup类中的update方法,对游戏窗口进行了更新,在调用该方法时,应将游戏分数score传给cameraGroup对象

 #level.run def run(self, dt):# updateself.event_loop()life = self.player.lifeself.all_sprites.score = self.scoreself.all_sprites.life = lifeself.all_sprites.update(dt)self.get_coins()self.get_damage()

故可在CameraGroup类的draw_horizon()添加游戏分数的显示

# 绘制游戏分数
text = pygame.font.Font("../font/LycheeSoda.ttf", 36).render(f'SCORE:{self.score}', True, (255, 255, 255))
self.display_surface.blit(text, (20, 20))

运行结果

图片

游戏生命显示

这里设计为红色宝石为角色的生命数,当触碰到敌人或者被敌人攻击击中后,生命数量减少1,当在游戏地图中触碰到红色宝石,则生命数量增加1

判断用户是否接触到红宝石,在上面的get_coin方法中已经完成,在Player类的属性中添加life属性,设置游戏角色的血量,同时将该属性值传给cameraGroup对象,与上面游戏分数的做法一样

#sprite.py中的Player类
# 设置血条
self.life = 2

在Player类中声明damage方法,用于减少角色生命数量,而真正角色碰撞受伤的逻辑在level中实现

  """Player类受到伤害时的操作,使玩家向上移动并启动无敌计时器"""def damage(self):if not self.invul_timer.active:print('受伤')self.invul_timer.activate()self.direction.y -= 1.5self.life -= 1
  #Level类def get_damage(self):# 检测角色是否与敌人发生碰撞collision_sprites = pygame.sprite.spritecollide(self.player, self.damage_sprites, False, pygame.sprite.collide_mask)if collision_sprites:self.hit_sound.play()self.player.damage()

运行结果如上图所示

游戏结束

当玩家生命数量为0时,则游戏结束,同时在游戏窗口中显示GAME OVER字体提示,在CameraGroup类中判断life的值即可

      # 绘制生命(用宝石数量代表生命数量)image = pygame.image.load("../graphics/items/diamond/0.png")image_rect = image.get_rect()image_rect.center = (30,80)text2 = pygame.font.Font("../font/LycheeSoda.ttf", 36).render(f':× {self.life}', True, (255, 255, 255))self.display_surface.blit(text2, (50, 65))self.display_surface.blit(image, image_rect)if self.life <= 0:text = pygame.font.Font('../font/LycheeSoda.ttf', 120).render('GAME  OVER', True, (215, 55, 74))self.display_surface.blit(text, (400, 250))

图片

项目源码获取在下面文章末尾获取

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/96183.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【个人博客系统网站】框架升级 · 工程目录 · 数据库设计

【JavaEE】进阶 个人博客系统&#xff08;1&#xff09; 文章目录 【JavaEE】进阶 个人博客系统&#xff08;1&#xff09;1. 使用Spring全家桶 MyBatis框架进行开发2. 页面2.1 登录页2.2 注册页2.3 详情页2.4 我的博客列表页3.5 所有人的博客列表页3.6 添加博客页3.7 修改文…

Redis与Mysql区别

一、关系型数据库 mysql&#xff0c;pgsql,oracle ,sqlserver 支持连表关联查询&#xff08;会有一些特定的语法特特性&#xff09; 二、非关系型数据库 redis,mongodb,memcache &#xff08;key-value&#xff09; 三、关系型数据库与非关系型数据库的区别&#xff1a; 1&am…

java八股文面试[多线程]——synchronized锁升级过程

速记&#xff1a;偏向-轻量-重量 锁膨胀 上面讲到锁有四种状态&#xff0c;并且会因实际情况进行膨胀升级&#xff0c;其膨胀方向是&#xff1a;无锁——>偏向锁——>轻量级锁——>重量级锁&#xff0c;并且膨胀方向不可逆 一.锁升级理论. 在synchronized锁升级过程…

【UE 材质】实现角度渐变材质、棋盘纹理材质

目标 步骤 一、角度渐变材质 1. 首先通过“Mask”节点将"Texture Coordinate" 节点的R、G通道分离 2. 通过“RemapValueRange”节点将0~1范围映射到-1~1 可以看到此时R通道效果&#xff1a; G通道效果&#xff1a; 继续补充如下节点 二、棋盘纹理材质 原视频链接&…

python调用git出错:ImportError: Failed to initialize: Bad git executable.

报错信息 #报错信息 Traceback (most recent call last): File “”, line 1, in File “C:\Python27\lib\site-packages\git_init_.py”, line 85, in raise ImportError(‘Failed to initialize: {0}’.format(exc)) ImportError: Failed to initialize: Bad git executab…

在windows下安装配置skywalking

1.下载地址 Downloads | Apache SkyWalkinghttp://skywalking.apache.org/downloads/ 2.文件目录说明 将文件解压后&#xff0c;可看到agent和bin目录&#xff1a; Agent&#xff1a;作为探针&#xff0c;安装在服务器端&#xff0c;进行数据采集和上报。 Config&#xff1a…

[国产MCU]-W801开发实例-用户报文协议(UDP)数据接收和发送

用户报文协议(UDP)数据接收和发送 文章目录 用户报文协议(UDP)数据接收和发送1、UDP简单介绍2、W801的UDP创建逻辑2.1 UDP使用步骤2.2 代码实现1、UDP简单介绍 用户数据报协议 (UDP) 是一种跨互联网使用的通信协议,用于对时间敏感的传输,例如视频播放或 DNS查找。它通过在数…

Leetcode54螺旋矩阵

思路&#xff1a;用set记录走过的地方&#xff0c;记下走的方向&#xff0c;根据方向碰壁变换 class Solution:def spiralOrder(self, matrix: list[list[int]]) -> list[int]:max_rows len(matrix)max_cols len(matrix[0])block_nums max_cols * max_rowscount 1i 0j…

DB-GPT使用

一、源码安装 安装 请按照以下步骤安装DB-GPT 1. Hardware Requirements 如果你的显存不够&#xff0c;DB-GPT支持8-bit和4-bit量化版本 2. Install git clone https://github.com/eosphoros-ai/DB-GPT.git目前使用Sqlite作为默认数据库&#xff0c;因此DB-GPT快速部署不…

windows环境搭建ELK

目录 资源下载&#xff08;8.9.1&#xff09; ES安装、注册、使用 Kibana安装、注册、使用 Logstash安装、注册、使用 Filebeat安装、使用&#xff08;如果只有一个数据流&#xff0c;则不需要使用filebeat&#xff0c;直接上logstash即可&#xff09; 资源下载&#xff0…

java对象的组成部分

在 HotSpot 虚拟机里&#xff0c;对象在堆内存中的存储布局可以划分为三个部分&#xff1a;对象头&#xff08;Header&#xff09;、实例数据&#xff08;Instance Data&#xff09;和对齐填充&#xff08;Padding&#xff09; 对象头主要由两部分组成&#xff1a; 第一部分存…

如何中mac上安装多版本python并配置PATH

摘要 mac 默认安装的python是 python3&#xff0c;但是如果我们需要其他python版本时&#xff0c;该怎么办呢&#xff1f; 例如&#xff1a;需要python2 版本&#xff0c;如果使用homebrew安装会提示没有python2。同时使用python --version 会发现commond not found。 所以本…