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

news2024/11/29 2:52:54

开发环境配置

安装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.direction
      if self.border_width >= self.threshold:
        self.direction = -1
        self.toggle()

      if self.border_width < 0:
        self.active = False
        self.border_width = 0
        self.direction = 1
      pygame.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 = surf
    self.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_type
      print(f'碰撞1:{collided_coins1[0].coin_type}')
      if coin_type == 'silver':
        print(self.score)
        self.score += 1
      elif coin_type == 'gold':
        print(self.score)
        self.score += 2
      else:
        self.player.life += 1
        print(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):

    # update
    self.event_loop()
    life = self.player.life

    self.all_sprites.score = self.score
    self.all_sprites.life = life
    self.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.5
      self.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.coloradmin.cn/o/967823.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Lesson5-2:OpenCV视频操作---视频追踪

学习目标 理解meanshift的原理知道camshift算法能够使用meanshift和Camshift进行目标追踪 1.meanshift 1.1原理 m e a n s h i f t meanshift meanshift算法的原理很简单。假设你有一堆点集&#xff0c;还有一个小的窗口&#xff0c;这个窗口可能是圆形的&#xff0c;现在你可…

CocosCreator3.8研究笔记(四)CocosCreator 脚本说明及使用(上)

在Cocos Creator中&#xff0c;脚本代码文件分为模块和插件两种方式&#xff1a; 模块一般就是项目的脚本&#xff0c;包含项目中创建的代码、引擎模块、第三方模块。 插件脚本&#xff0c;是指从 Cocos Creator 属性检查器中导入的插件&#xff0c;一般是引入第三方引入库文件…

PixelSNAIL论文代码学习(3)——自注意力机制的实现

文章目录 引言正文介绍自注意力机制的简单实现样例本文中的自注意力机制具体实现代码分析nn.nin函数的具体实现nn.causal_attention模块实现注意力模块实现代码完整实现代码使用pytorch实现因果注意力模块causal_atttention模块 问题 总结引用 引言 阅读了pixelSNAIL,很简短&a…

java八股文面试[多线程]——线程的状态

5种状态一般是针对传统的线程状态来说&#xff08;操作系统层面&#xff09; 6种状态&#xff1a;Java中给线程准备的 NEW&#xff1a;Thread对象被创建出来了&#xff0c;但是还没有执行start方法。 RUNNABLE&#xff1a;Thread对象调用了start方法&#xff0c;就为RUNNABLE状…

已解决“SyntaxError: invalid character in identifier“报错问题

本文摘要&#xff1a;本文已解决 Python FileNotFoundError 的相关报错问题&#xff0c;并总结提出了几种可用解决方案。同时结合人工智能GPT排除可能得隐患及错误。 &#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领…

Oracle数据库分页查询

方法一 方法二 方法一要比方法二效率要高很多&#xff0c;查询效率提高主要体现在WHERE ROWNUM < 40这个语句上。 这是由于CBO优化模式下&#xff0c;Oracle可以将外层的查询条件推到内层查询中&#xff0c;以提高内层查询的执行效率。方法一中&#xff0c;第二层的查询条件…

完善开发工具箱:免费开源社区版软件推荐

一、背景 工欲善其事必先利其器&#xff0c;在日常的IT工作中&#xff0c;好的工具软件是开发者日常工作中最重要的工具之一。然而&#xff0c;专业版的软件价格昂贵&#xff0c;对于小团队或个人开发者来说可能是一大负担。当然国内大家会普遍推荐使用破解版&#xff0c;小公…

Java【手撕滑动窗口】LeetCode 438. “字符串中所有异位词“, 图文详解思路分析 + 代码

文章目录 前言一、字符串中所有异位词1, 题目2, 思路分析2.1, 引入哈希表找出异位词2.2, 引入变量记录"有效字符的个数"2.3, left 右移维护窗口2.4, 总结核心步骤 3, 代码 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: &#x1f4d5; Ja…

bazel工程介绍和demo构建

参考官方示例项目&#xff1a;git clone https://github.com/bazelbuild/examples 项目结构 使用Bazel管理的项目一般包含以下几种Bazel相关的文件&#xff1a;WORKSPACE(同WORKSPACE.bazel)&#xff0c;BUILD(同BUILD.bazel)&#xff0c;.bzl 和 .bazelrc 等。 具体结构如下…

【洛谷】P3853 路标设置

原题链接&#xff1a;https://www.luogu.com.cn/problem/P3853 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 整体思路&#xff1a;二分答案 由题意知&#xff0c;公路上相邻路标的最大距离定义为该公路的“空旷指数”。在公路上增设一些路标&…

6. series对象及DataFrame对象知识总结

【目录】 文章目录 6. series对象及DataFrame对象知识总结1. 导入pandas库2. pd.Series创建Series对象2.1 data 列表2.2 data 字典 3. s1.index获取索引4. s1.value获取值5. pd.DataFrame()-创建DataFrame 对象5.1 data 列表5.2 data 嵌套列表5.3 data 字典 6. df[列索引]…

Linux安装MySQL5.7.26教程图解

0、准备工作 下载MySQL软件包 ①、官网下载&#xff1a;https://www.cnblogs.com/linu-x/p/15701479.html#_label6 ②、百度网盘下载&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;chao ③、文件说明 主机名 CentOS版本 MySQL版本 IP地址 test CentOS Linux …

AtCoder Beginner Contest 318

目录 A - Full Moon B - Overlapping sheets C - Blue Spring D - General Weighted Max Matching E - Sandwiches F - Octopus A - Full Moon #include<bits/stdc.h> using namespace std; const int N1e65; typedef long long ll ; const int maxv4e65; typedef …

nsq中diskqueue详解 - 第二篇

上一篇博客 nsq中diskqueue详解 - 第一篇_YZF_Kevin的博客-CSDN博客 中我们讲了diskqueue是什么&#xff0c;为什么需要它&#xff0c;它的整体架构流程&#xff0c;以及对外接口等等&#xff0c;如果你还没了解过&#xff0c;强烈建议先看一下&#xff0c;不然直接看这篇博客的…

AVR128单片机 USART通信控制发光二极管显示

一、系统方案 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 void port_init(void) { PORTA 0xFF; DDRA 0x00;//输入 PORTB 0xFF;//低电平 DDRB 0x00;//输入 PORTC 0xFF;//低电平 DDRC 0xFF;//输出 PORTE 0xFF; DDRE 0xfE;//输出 PO…

Leetcode Top 100 Liked Questions(序号236~347)

236. Lowest Common Ancestor of a Binary Tree 题意&#xff1a;二叉树&#xff0c;求最近公共祖先&#xff0c;All Node.val are unique. 我的思路 首先把每个节点的深度得到&#xff0c;之后不停向上&#xff0c;直到val相同&#xff0c;存深度就用map存吧 但是它没有向…

Lesson4-2:OpenCV图像特征提取与描述---Harris和Shi-Tomas算法

学习目标 理解Harris和Shi-Tomasi算法的原理能够利用Harris和Shi-Tomasi进行角点检测 1 Harris角点检测 1.1 原理 H a r r i s Harris Harris角点检测的思想是通过图像的局部的小窗口观察图像&#xff0c;角点的特征是窗口沿任意方向移动都会导致图像灰度的明显变化&#xff…

【多线程】线程间通信及状态

文章目录 1. 线程间的通信1.1 wait和notify1.2 notify随机唤醒1.3 notifyAll()1.4 join() 2. 线程间的状态3. 验证线程的状态3.1 验证NEW、RUNNABLE、TERMINATED3.2 验证WAITING3.3 验证TIMED-WAITING3.4 验证BLOCKED 4. 面试题&#xff1a;wait和sleep对比 1. 线程间的通信 1…

人工智能轨道交通行业周刊-第58期(2023.8.28-9.3)

本期关键词&#xff1a;成都智慧工厂、机务段、站台地标、备案大模型、AIGC报告 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通RailMetro轨道世界铁路…

Redis 缓存穿透击穿和雪崩

一、说明 Redis 缓存的使用&#xff0c;极大的提升了应用程序的性能和效率&#xff0c;特别是数据查询方面。但同时&#xff0c;它也带来了一些问题。其中&#xff0c;最要害的问题&#xff0c;就是数据的一致性问题&#xff0c;从严格意义上讲&#xff0c;这个问题无解。如果对…