【C/C++】使用类和对象 练习EasyX图形库

news2025/1/14 1:20:27

创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c++系列专栏:C/C++零基础到精通 🔥

给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ

在这里插入图片描述

c语言内容💖:

专栏:c语言之路重点知识整合

【c语言】全部知识点总结


目录

  • 一、创建类
  • 二、构造、析构函数
  • 三、基本功能
  • 四、运行结果
  • 图片资源
  • 全部完整代码

在之前的文章中使用C语言完成过几个基于EasyX图形库的小项目

【c语言】游戏项目——贪吃蛇、俄罗斯方块等

介绍过类和对象后,本文将通过类和对象的角度再次使用EasyX图形库,进行简单的练习,封装一个游戏人物—属性、行为等

一、创建类

将游戏人物—超级玛丽封装成类,定义人物的横纵坐标和面朝方向,代表人物在画面中的位置和状态

class CMary
{
public:
	int m_x;
	int m_y;
	int m_direct;	//四个方向
	//表示图片的变量
	IMAGE m_up;
	IMAGE m_down;
	IMAGE m_left;
	IMAGE m_right;
};

二、构造、析构函数

使用构造函数将程序窗口、窗口背景、人物坐标进行初始化

	CMary()		//构造函数用于初始化
	{
		//创建窗口 大小600*600
		::initgraph(600, 600);		// ::取全局作用域,最好加上:: 防止同名函数的混淆

		//设定窗口背景色为 白色
		::setbkcolor(RGB(255, 255, 255));
		::cleardevice();

		//初始化最初位置为 中间
		m_x = 300;
		m_y = 300;

		m_direct = DIRECT_RIGHT;
	}

加载图片资源也写到构造函数中(图片资源放在文末)

需要在工程文件目录下创建pic文件夹,将图片资源保存其中

		//加载图片(表示图片的变量和具体的图片资源绑定)
		::loadimage(&m_up, L"./pic/mary-up.bmp");		//相对路径		L:转码
		::loadimage(&m_down, L"./pic/mary-down.bmp");
		::loadimage(&m_left, L"./pic/mary-left.bmp");
		::loadimage(&m_right, L"./pic/mary-right.bmp");

析构函数用来回收额外的内存空间,关闭窗口

	~CMary()	//析构函数 回收
	{
		::closegraph();	//关闭窗口
	}

三、基本功能

基本功能包括显示人物、人物移动、运行程序的函数

通过EasyX图形库提供的函数进行绘图,定义Show()函数用来显示人物

	//显示人物
	void Show()
	{
		//每次改变位置前,清空窗口
		::BeginBatchDraw();	//开始批量绘图
		::cleardevice();

		m_direct == DIRECT_UP ? ::putimage(m_x, m_y, &m_up) : void(0);
		m_direct == DIRECT_DOWN ? ::putimage(m_x, m_y, &m_down) : void(0);
		m_direct == DIRECT_LEFT ? ::putimage(m_x, m_y, &m_left) : void(0);
		m_direct == DIRECT_RIGHT ? ::putimage(m_x, m_y, &m_right) : void(0);

		settextstyle(20, 0, _T("宋体"));
		settextcolor(RGB(0, 0, 255));
		outtextxy(40, 390, L"天喜Studio");
		::EndBatchDraw();	//结束批量绘图
	}

定义Move()函数用来控制人物的移动,并且根据选择的方向不同进行不同方向的移动

在移动时根据窗口大小限制人物,防止任务移动到窗口外

	//人物移动
	void Move(int direct)
	{
		switch (direct)
		{
		case DIRECT_UP:
		{
			/*if (m_y - MOVE_STEP >= 0)
			{
				m_y -= MOVE_STEP;
			}
			else
			{
				m_y = 0;
			}*/
			m_y - MOVE_STEP >= 0 ? m_y -= MOVE_STEP : m_y = 0;
			m_direct = DIRECT_UP;
			break;
		}
		case DIRECT_DOWN:
		{
			//下边界: 图片尺寸大小 60	600-60=540
			m_y - MOVE_STEP <= 540 ? m_y += MOVE_STEP : m_y = 540;
			m_direct = DIRECT_DOWN;
			break;
		}
		case DIRECT_LEFT:
		{
			m_x - MOVE_STEP >= 0 ? m_x -= MOVE_STEP : m_x = 0;
			m_direct = DIRECT_LEFT;
			break;
		}

		case DIRECT_RIGHT:
		{
			//右边界: 图片尺寸大小 60	600-60=540
			m_x - MOVE_STEP <= 540 ? m_x += MOVE_STEP : m_x = 540;
			m_direct = DIRECT_RIGHT;
			break;
		}
		}
	}

定义Run()运行函数,用于获取用户按下的键盘信息(通过控制台)

并根据方向键进行人物的移动,不断进行刷新显示,实现动态画面


	//运行
	void Run()
	{
		Show();		//初始显示
		while (1)
		{
			//不断获取键盘信息:按下的方向键
			int key = _getch();
			if (key == ESC_KEY)
			{
				::MessageBox(nullptr, L"退出游戏?", L"提示", MB_OK);
				break;
			}
			Move(key);	//根据方向键移动人物
			Show();//更新显示

			Sleep(10);
		}
	}

主函数

主函数中只需要使用CMary人物类创建一个对象m,通过调用类中的Run()函数开始执行程序

int main()
{
	CMary m;
	m.Run();	//运行

	return 0;
}

四、运行结果

在这里插入图片描述

图片资源

mary-down.bmp

在这里插入图片描述

mary-left.bmp

在这里插入图片描述

mary-right.bmp

在这里插入图片描述

mary-up.bmp

在这里插入图片描述

全部完整代码

直接复制代码并配置图片路径就能执行:

#include <conio.h>

#include <easyx.h>
#include <windows.h>
//宏定义四个方向:
#define DIRECT_UP   72
#define DIRECT_DOWN 80
#define DIRECT_LEFT 75
#define DIRECT_RIGHT 77

#define MOVE_STEP 5
#define ESC_KEY 27

class CMary
{
public:
	int m_x;
	int m_y;

	int m_direct;	//方向
	IMAGE m_up;
	IMAGE m_down;
	IMAGE m_left;
	IMAGE m_right;

public:
	CMary()		//构造函数用于初始化
	{
		//创建窗口 大小600*600
		::initgraph(600, 600);		// ::取全局作用域,最好加上:: 防止同名函数的混淆

		//设定窗口背景色为 白色
		::setbkcolor(RGB(255, 255, 255));
		::cleardevice();

		//初始化最初位置为 中间
		m_x = 300;
		m_y = 300;

		m_direct = DIRECT_RIGHT;

		//加载图片(表示图片的变量和具体的图片资源绑定)
		::loadimage(&m_up, L"./pic/mary-up.bmp");	//相对路径		L:转码
		::loadimage(&m_down, L"./pic/mary-down.bmp");
		::loadimage(&m_left, L"./pic/mary-left.bmp");
		::loadimage(&m_right, L"./pic/mary-right.bmp");


	}
	~CMary()	//析构函数 回收
	{
		::closegraph();	//关闭窗口
	}

	//显示人物
	void Show()
	{
		//每次改变位置前,清空窗口
		::BeginBatchDraw();	//开始批量绘图
		::cleardevice();

		m_direct == DIRECT_UP ? ::putimage(m_x, m_y, &m_up) : void(0);
		m_direct == DIRECT_DOWN ? ::putimage(m_x, m_y, &m_down) : void(0);
		m_direct == DIRECT_LEFT ? ::putimage(m_x, m_y, &m_left) : void(0);
		m_direct == DIRECT_RIGHT ? ::putimage(m_x, m_y, &m_right) : void(0);

		settextstyle(20, 0, _T("宋体"));
		settextcolor(RGB(0, 0, 255));
		outtextxy(500, 570, L"天喜Studio");
		::EndBatchDraw();	//结束批量绘图
	}
	//人物移动
	void Move(int direct)
	{
		switch (direct)
		{
		case DIRECT_UP:
		{
			/*if (m_y - MOVE_STEP >= 0)
			{
				m_y -= MOVE_STEP;
			}
			else
			{
				m_y = 0;
			}*/
			m_y - MOVE_STEP >= 0 ? m_y -= MOVE_STEP : m_y = 0;
			m_direct = DIRECT_UP;
			break;
		}
		case DIRECT_DOWN:
		{
			//下边界: 图片尺寸大小 60	600-60=540
			m_y - MOVE_STEP <= 540 ? m_y += MOVE_STEP : m_y = 540;
			m_direct = DIRECT_DOWN;
			break;
		}
		case DIRECT_LEFT:
		{
			m_x - MOVE_STEP >= 0 ? m_x -= MOVE_STEP : m_x = 0;
			m_direct = DIRECT_LEFT;
			break;
		}

		case DIRECT_RIGHT:
		{
			//右边界: 图片尺寸大小 60	600-60=540
			m_x - MOVE_STEP <= 540 ? m_x += MOVE_STEP : m_x = 540;
			m_direct = DIRECT_RIGHT;
			break;
		}
		}
	}


	//运行
	void Run()
	{
		Show();		//初始显示
		while (1)
		{
			//不断获取键盘信息:按下的方向键
			int key = _getch();
			if (key == ESC_KEY)
			{
				::MessageBox(nullptr, L"退出游戏?", L"提示", MB_OK);
				break;
			}
			Move(key);	//根据方向键移动人物
			Show();//更新显示

			Sleep(10);
		}
	}

};

int main()
{
	CMary m;
	m.Run();	//运行

	return 0;
}

在这里插入图片描述

大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●)

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

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

相关文章

【关联式容器】之map和set

【关联式容器】之map和set 容器类型树形结构的关联式容器mapset&#xff0c;multiset&#xff0c;multimap的区别与联系 容器类型 在STL中&#xff0c;我们接触过许多容器&#xff0c;例如&#xff1a;vector&#xff0c;list&#xff0c;stack&#xff0c;queue&#xff0c;m…

conll2003数据集下载与预处理

CoNLL-2003 数据集包括 1,393 篇英文新闻文章和 909 篇德文新闻文章。我们将查看英文数据。 1. 下载CoNLL-2003数据集 https://data.deepai.org/conll2003.zip 下载后解压你会发现有如下文件。 打开train.txt文件&#xff0c; 你会发现如下内容。 CoNLL-2003 数据文件包含由单…

逍遥自在学C语言 | 指针陷阱-空指针与野指针

前言 在C语言中&#xff0c;指针是一种非常强大和灵活的工具&#xff0c;但同时也容易引发一些问题&#xff0c;其中包括空指针和野指针。 本文将带你了解这两个概念的含义、产生原因以及如何避免它们所导致的问题。 一、人物简介 第一位闪亮登场&#xff0c;有请今后会一直…

【玩转Docker小鲸鱼叭】理解DockerFile如此简单

DockerFile构建过程 DockerFile 是Docker的一个配置文件&#xff0c;本质上来说它只是一个文本文件&#xff0c;它是用来构建Docker镜像的。DockerFile配置文件中包含了一系列的指令和配置信息&#xff0c;用于描述如何构建镜像以及如何运行容器。通过编写 Dockerfile&#xf…

RISC-V处理器的设计与实现(二)—— CPU框架设计

前面我们选好了要实现的指令集&#xff0c;并且了解了每个指令的功能&#xff08;传送门&#xff1a;RISC-V处理器的设计与实现&#xff08;一&#xff09;—— 基本指令集_Patarw_Li的博客-CSDN博客&#xff09;&#xff0c;接下来我们就可以开始设计cpu了。当然我们不可能一上…

ChatGPT更新的使用指南,与其他类似的人工智能的软件和服务-更新版(2023-6-25)

文章目录 一、什么是ChatGPT二、如何使用三、如何使用ChatGPT帮助我们的工作和生活四、高阶用法1、角色扮演2、英语口语老师3、在搜索引擎中集成ChatGPT 五、常见问题五、其他类似的软件和服务 如果你还不知道如何注册和使用&#xff0c;可看末尾&#xff0c;手把手教你。 一、…

Linux线程同步

同步的几种方式&#xff1a;信号量&#xff0c;互斥锁&#xff0c;条件变量&#xff0c;读写锁 同步&#xff1a;对程序的执行过程进行控制&#xff0c;保证对临界资源的访问同一时刻只能有一个进程或线程访问。 2.1信号量 存在P操作&#xff1a;获取资源&#xff0c;信号量…

58.最后一个单词的长度

LeetCode-58.最后一个单词的长度 1、题目描述2、解题思路3、代码实现4、解题记录 1、题目描述 题目描述&#xff1a; 给你一个字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任…

通讯录获取APP程序分析

前言 APP非法获取用户通讯录等隐私信息 我用技术分析APP是如何获取信息的 如果你不幸中招了&#xff0c;可以参考下方链接(有偿) 我的方法是替换掉通讯录数据&#xff0c;替换不成功包退&#xff01; 每日16:00-06:00在线&#xff0c;5分钟受理&#xff0c;2~3小时完成 点下面…

下载安装mysql与设置密码详细步骤(压缩包版本)

目录 一、前言 二、操作步骤 &#xff08;一&#xff09;下载与解压缩 &#xff08;二&#xff09;配置环境变量 &#xff08;三&#xff09;安装MySQL服务 &#xff08;四&#xff09;设置ini文件和data文件 &#xff08;五&#xff09;启动MySQL服务和设置密码 三、…

【C++ 程序设计】第 5 章:类的继承与派生

目录 一、类的继承与类的派生 &#xff08;1&#xff09;继承的概念 &#xff08;2&#xff09;派生类的定义与大小 ① 派生类的定义 ② 派生类的大小 &#xff08;3&#xff09;继承关系的特殊性 &#xff08;4&#xff09;有继承关系的类之间的访问 &#xff08;5&am…

多线程单例模式

1、单例模式 顾名思义&#xff0c;单例模式能保证某个类在程序中只存在唯一一份示例&#xff0c;而不会创建出多个实例。就像java的JDBC编程只需要创建一个单例类DataSourece从这个DataSorce中获取数据库连接。没必要创建多个对象。 单例模式具体实现方式分为“饿汉”和“懒汉…

java编译与反编译

参考&#xff1a; Idea 使用技巧记录_source code recreated from a .class file by intell_hresh的博客-CSDN博客 深入理解Java Class文件格式&#xff08;一&#xff09;_昨夜星辰_zhangjg的博客-CSDN博客 实践详解javap命令&#xff08;反编译字节码&#xff09;_天然玩家…

【运筹优化】元启发式算法详解:迭代局部搜索算法(Iterated Local Search,ILS)+ 案例讲解代码实现

文章目录 一、介绍二、迭代局部搜索2.1 总体框架2.2 随机重启2.3 在 S* 中搜索2.4 ILS 三、获得高性能3.1 初始解决方案3.2 Perturbation3.2.1 扰动强度3.2.2 自适应扰动3.2.3 更复杂的扰动方案3.2.4 Speed 3.3 接受准则3.4 Local Search3.5 ILS 的全局优化 四、ILS 的精选应用…

Windows PE怎么修复系统?使用轻松备份解决!

​什么是Windows PE? Windows预先安装环境&#xff08;英语&#xff1a;Microsoft Windows Preinstallation Environment&#xff09;&#xff0c;简称Windows PE或WinPE&#xff0c;是Microsoft Windows的轻量版本&#xff0c;主要提供个人电脑开发商&#xff08;主要为OEM厂…

electron+vue3全家桶+vite项目搭建【20】窗口事件广播,通用事件封装

引入 electron中的渲染进程与主进程之间的数据交互需要利用ipc通信&#xff0c;互相订阅/通知来实现&#xff0c;我们不妨封装一个通用事件广播&#xff0c;利用自定义的事件名称来让主进程遍历窗口挨个推送对应内容&#xff0c;来实现事件的广播。 demo项目地址 实现思路 …

【计算机视觉】MaskFormer:将语义分割和实例分割作为同一任务进行训练

文章目录 一、导读二、逐像素分类和掩码分类的区别2.1 逐像素分类2.2 掩码分类2.3 区别 三、DETR四、MaskFormer五、MaskFormer用于语义和实例分割六、总结 一、导读 目标检测和实例分割是计算机视觉的基本任务&#xff0c;在从自动驾驶到医学成像的无数应用中发挥着关键作用。…

模拟电路系列分享-运放的关键参数5

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 提示&#xff1a;这里可以添加技术概要 例如&#xff1a; 实际运放与理想运放具有很多差别。理想运放就像一个十全十美的人&#xff0c;他学习100 分&#xff0c;寿命无限长&#xff0c;长得没挑剔&#xff0c;而实…

【c++11】移动构造的性质 和 与拷贝构造的比较(详解)

文章目录 定义性质移动构造的定义实例代码分析移动构造 与 拷贝构造的比较移动赋值 和 拷贝赋值 应用场景 定义 移动构造&#xff08;Move Constructor&#xff09;是一种特殊的构造函数&#xff0c;它通过接收一个右值引用参数来创建新对象&#xff0c;并从传入的对象中“移动…

操作系统——Windows 线程的互斥与同步

一、实验题目 Windows 线程的互斥与同步 二、实验目的 (1) 回顾操作系统进程、线程的有关概念&#xff0c;加深对 Windows 线程的理解。 (2) 了解互斥体对象&#xff0c;利用互斥与同步操作编写生产者-消费者问题的并发程序&#xff0c;加深对 P (即 semWait)、V(即 semSig…