登录

选择主题

请选择一种主题

检测到您希望减少动画效果,该主题包含大量动画,是否继续?

PicoLoop

项目概述

玩家人物图像

PicoLoop 是一款像素风格闯关类练手小游戏,使用 C++ 面向对象开发。

项目不仅拥有经典人物闯关玩法,还在此基础上创新出了自制模式。

项目经过优化,让人物能够流畅移动,让人物与物体相互作用稳定。

项目将玩家产生的数据持久化存储到文件中,关闭游戏不会丢失数据。

效果展示

技术栈

  • C++ 面向对象
  • Easyx 图形库

特点

本项目运用了 C++ 面向对象特性,例如继承、派生、多态与封装, Page基类是页面的基类,能够监听与处理用户交互事件的,所有子页面都派生于它; Element是所有游戏元素的基类,各类具体元素重写相应功能的虚函数,让元素有不同功能。

项目没有使用智能指针,内存均为手动管理,使用了堆内存手动申请与释放, 解决了浅拷贝、重复释放、空指针等内存管理问题。

如果您对游戏或源代码感兴趣,可点击 下载源码 ,导航到底部下载标题进行下载。

游戏玩法

核心玩法

核心玩法很简单:玩家使用键盘操纵人物到达终点旗帜,这是唯一的胜利方式。

玩法分类

  • 闯关模式(play):玩家通过按键盘的方向键,使人物移动或跳跃; 控制人物穿过预设的重重障碍,收集所有钥匙,躲避致命元素,合理利用道具, 抵达终点即可通过关卡。关卡采用自选模式,无需担心卡关问题;
  • 自制模式(make):玩家放置控制人物和元素并控制人物抵达终点。 内置 84 个可编辑关卡,数据持久化存档。玩家可发挥自己的创意, 放置玩家以及各种元素,创建属于自己的关卡并预览游玩。

元素介绍

要想胜利就不可避免与元素产生交互,不同元素会对玩家产生不同影响:

  • 砖块元素:阻挡玩家的移动路线,是游戏的主要障碍;
  • 钥匙元素:玩家需要收集全部钥匙才能解锁终点旗帜并过关;
  • 跑鞋元素:玩家拾取后,跳跃高度有显著增加,能跳得更高;
  • 火元素:当人物触碰到火元素时,会立即被击杀,游戏自动重玩;
  • ……

游戏里有对游戏操作和元素功能的详细介绍, 大家可以下载后,在关卡页点击 help 按钮查看图鉴。

因篇幅限制,元素介绍在这里不一一列出。

设计思路

整体架构设计

本项目采用模块化架构,基于 EasyX 图形库搭建完整游戏运行框架, 游戏开发流程是:初始化 → 游戏循环 → 资源释放。 这样按功能拆分独立模块,有利于降低耦合度,便于维护与扩展。

  1. 全局以 Game 游戏类为主类, 统一调度生命周期、全局状态与逻辑流转,作为程序入口;
  2. 依托 Window 窗口类、Page 页面类、 PicoElement 元素类三层拆分,分别负责窗口事件、 页面切换、游戏元素管理,这样明确了职责,便于维护和添加新元素;
  3. 采用基类派生的继承设计,设计了 PageButtonPicoElement 抽象基类及其子类。

像素视觉设计

游戏的所有绘图都是使用图形库内置函数绘制的,未使用任何图片文件。 绘图始终保持简约的像素风格,并开启了动画流畅性优化。

当窗口最小化或失去焦点时,动画播放会自动暂停,以节省资源。

碰撞检测设计

游戏采用了最经典的矩形碰撞检测方法,根据玩家与元素的四个顶点的相对位置来判断, 分为以下几种情况:

  • 触碰元素任何地方,即“碰到”元素
  • 触碰元素上、下、左、右外表面
  • 触碰元素上、下、左、右内表面
  • 触碰元素中心点,即“通过”元素
  • 触碰元素上、下、左、右外表面或内表面,但未对齐

例如触碰元素上表面代码:

// Touch element top surface
return this->y > player.y + player.size &&
this->y <= player.y + player.size + player.MOVE_STEP &&
this->x <= player.x + player.size &&
this->x + this->size >= player.x;

游戏少量元素拥有动画,通过实现时钟计时方法来播放,可在图鉴中看到。

关卡功能设计

在游戏广场中,玩家通过按键盘控制人物移动和跳跃,暂停游戏,重玩,退出。具体操作:

  • 方向 键使人物移动或跳跃;
  • 空格 键暂停游戏;
  • R 键或退格键重玩当前关卡;
  • Esc 键或点击右上角关闭按钮退出游戏。

玩家如果想具体了解一个元素的功能,可以点击 help 按钮查看图鉴。

问题解决

问题描述

编写项目的过程中遇到了许多问题:

  1. 碰撞检测不够准确、角色运动不够流畅的各类异常问题;
  2. 主循环执行逻辑与元素管理方式不当,导致画面闪烁与交互卡顿;
  3. 数据读写容错性差,用户不慎修改文件导致读取失败、存档异常丢失问题;
  4. 按钮对象创建时文字对象指针的浅拷贝、资源重复释放的内存管理问题;
  5. 元素编辑器读取空指针或已释放对象导致程序崩溃的问题。

解决方案

针对以上问题,项目开发者分别进行了以下优化:

  1. 统一采用基于 Element 基类的矩形碰撞判定算法,明确了“小于”和“小于或等于”的边界情况,使穿模概率大幅下降。
  2. 优化 Game 类主循环流程,采用 “更新 → 计算 → 渲染” 顺序;使用 BeginBatchDrawEndBatchDraw批量绘制来消除闪烁; 优化元素及人物绘制策略,移动时只更新人物区域背景,避免全屏重绘; 使用基类Page统一事件监听的形式,避免组件跨页面响应。
  3. 增加文件格式校验与字段合法性判断,异常时自动将所有数据置零;采用安全写入机制, 类型、数据范围错误时直接抛异常,避免因文件数据损坏导致存档丢失。
  4. 明确 _tcsdup 宏底层会申请 LPTSTR 类型(开发时环境)的动态指针,在按钮实体析构函数中使用 free 释放资源,实现拷贝构造函数、 拷贝赋值运算符,手动实现深拷贝逻辑,避免成员指针共用内存隐患以及内存泄漏问题。
  5. 在编辑器模块访问 Element 对象前增加空指针校验, 确保仅对有效实例进行操作,避免释放后使用对象。

下载源码

本项目开放源码下载功能,可点击下方链接在 GitHub 上免费下载源码。

注意源码为个人编写,仅供参考,还存在不足的方面,不保证代码的质量和准确性。 大家可以在源码的基础上修改,以新增更多元素、更多关卡,创造出更好的游戏体验。

备注

免责声明
  • 本项目为个人学习练手项目,仅代表个人创意,不对代码的正确性、完整性、 有效性、及时性做出任何保证。请勿将源代码用于正式开发环境中或其它非法用途。
  • 项目的所有源代码仅供学习交流使用,不得用于任何商业用途。 若因复制源代码用于生产环境等行为造成的损失,项目设计者及开发者不承担任何责任。
  • 若项目名称和第三方商标名称发生局部命名冲突,纯属命名巧合, 项目设计者及开发者无任何侵权目的。

所有评论 (...)

登录后才能发表评论
字数:0 / 1000 行数:1 / 25 点击上方“发表评论”提交

    删除评论

    确定要删除该评论吗?

    举报评论

    举报该评论

    请填写举报理由,我们将尽快处理。 请谨慎使用此功能,确保真实反映评论问题。