C/C++基于easyX库实现三星环绕小项目(C/C++)
1,项目描述
功能1:使用图形化的方式描述地球围绕着太阳转动,月球围绕着地球转动
功能2:在转动的过程中当用户按下1,2,3,4,5,6,7时它可以变换出7种不同的颜色,当用户按下8时它可以变换从1-7的颜色依次变换当用户再次按下8键时停止变换颜色
功能3:当用户按下上键时,地球会围绕太阳反转,当再次按下上键时地球会恢复到正转
功能4:当用户按下空格键的时候,所有动画暂停,当再次按下空格键的时候所有动画继续进行。
2,解决思路
其实纵观整个项目需求,在不考虑真实的星体运算下,它的实现原理就像是时钟转动的实现原理是一致的
对于地球围绕着太阳进行转动来说,可以将太阳作为中心点,地球围绕着这个中心点进行转动,对于月球围绕着地球进行转动来说,可以将地球作为一个中心点,月球围绕着地球进行转动,这样就实现了基本的地球,太阳和月球的三星环绕
需要考虑的是整个项目是在转动中获取按键信息做出相应的画面更新,所以按键更新画面应该是放在一个非阻塞的函数下进行,也就是使用_kbhit()来实现,将这个条件放在运行中的死循环之中,可以随时通过按键信息更新画面基本元素
当考虑到8键,空格键和上键时,它们三个键位就相当于开关,按下就开,再按就关,我可以使用开关算法完成这样的操作。
3,关键代码
开发使用IDE:Visual Studio2019
注意:
easyX库不是C++的自带库需要下载和安装,很简单
easyX库是基于C++的,所以文件的后缀名需要改为.cpp才能正常运行
首先为了方便程序的可维护性,所以最开始,使用了枚举定义了地球,月球和太阳的半径。
typedef enum RADIES {//星球半径sunradies = 150,//太阳earthradies = 30,//地球moonradies = 5,//月亮
}radies;
然后为了能实现色彩的变化,也可以先定义一个颜色的枚举,颜色是基于easyX库中的。
typedef enum COLOR {//颜色black = 0,//黑色blue = 0xAA0000,//蓝色green = 0x00AA00,//绿色cyan = 0xAAAA00,//青色red = 0x0000AA,//红色magenta = 0xAA00AA,//紫色brown = 0x0055AA,//棕色lightgray = 0xAAAAAA,//浅灰yellow = 0x55FFFF,//黄色
}color;
3.1,实现基本的地球,太阳和月球三星环绕关键代码
可以看作是三个中心点之间的不断的运算关系,最核心的是通过不断更新中心坐标的位置实现,对于太阳来说,它的中心坐标是位于窗口的中心,并且对于太阳来说它是不动的,对于地球来说,它的中心坐标是根据以太阳为中心基点,围绕着太阳进行转动的,对于月球来说,亦然,地球和月球都是行星,它们的运动是依靠着坐标点的位置变化实现,所以可以定义一个行星结构体,包含行星的半径和行星中心x和y坐标
typedef struct Plant {//行星int radies;//行星半径int center_x;//行星中心X坐标int center_y;//行星中心Y坐标
}plant;
在程序中先创建行星,也就是为行星赋予基本的中心点和半径作初始化,然后,通过绘制行星,传入行星实时更新的坐标点在死循环中更新图像。
//通过传入结构体指针首先给指针所指向的内存地址中的相关属性赋初值void creatplant(plant* p, int x, int y, int radies) {p->center_x = x;//行星中心的初始x坐标p->center_y = y;//行星中心的初始y坐标p->radies = radies;//行星的半径}
通过传入中心行星和环绕行星,使用指针来访问内存空间,通过修改内存中的数值实现实时改变终点坐标
void drawplant(plant* p1, plant* p2, double angle, int a, color c, radies r) {p1->center_x = p2->center_x + (WIDTH / a) * sin(angle);//以p2为中心,实时改变角度改变内存的x值p1->center_y = p2->center_y - (WIDTH / a) * cos(angle);//以p2为中心,实时改变角度改变内存的y值setfillcolor(c);solidcircle(p1->center_x, p1->center_y, p1->radies);//根据改变的值绘制图形}
直接绘制太阳,因为太阳就是一个静止的状态:
//因为太阳它是固定的就是一个静态图片void drawsun(color c, int x, int y, radies r) {setfillcolor(c);solidcircle(x, y, r);}
接下来就可在主方法中进行绘制的实验了
int main(){plant s, e, m;color c1=red;creatplant(&s, WIDTH / 2, HEIGHT / 2, sunradies);//创建太阳属性creatplant(&e, WIDTH / 8, HEIGHT / 8, earthradies);//创建地球属性creatplant(&m, WIDTH / 10, HEIGHT / 10, moonradies);//创建月球属性while (1) {drawsun(c1, s.center_x, s.center_y, sunradies);//画太阳BeginBatchDraw();在内存中绘画,避免频闪drawplant(&e, &s, eangle, 3, blue, earthradies);//传入地球,更新角度并且绘制drawplant(&m, &e, mangle, 13, yellow, moonradies);//传入月球,更新角度并且绘制eangle = eangle + 2 * PI / 60;//地球的角度实时变化mangle = mangle + 2 * PI / 30;//月球的角度实时变化,分的分数应该更小如果等于60一起转动Sleep(50); //便于看出轨迹的运动FlushBatchDraw();//将画出的内容从内存调出clearcircle(e.center_x, e.center_y, earthradies);//清除clearcircle(m.center_x, m.center_y, moonradies);//清除,再画下一次的更新}return 0;
}
实验截图:
3.2,开关算法思想关键代码
该代码用于主方法中控制整个程序的流程,其关键部分如下,56,32,72是键值,也就是在键盘中它都有对应的值
int i = 1;//作为闪烁颜色的开关int m1 = 1;//作为暂停的开关int n1 = 1;//作为逆时针转动的开关while (key != 27) {if (_kbhit()) {//使用的非阻塞方法,也就是它不会等待事件的发生而阻塞是一直接收事件switch (key = _getch()) {case 56:i = i * -1; break;//当按下8键时,i=-1<0,进行颜色变换,当再按下8键时,i>0,不变case 32:m1 = m1 * -1; break;//按下空格时<0,再按下时>0case 72:n1 = n1 * -1; break;//按下上时<0,再按下时>0}}if (i < 0) {//进行颜色的变换color c[8] = { black,blue,red,blue,yellow,cyan,magenta,blue };srand((unsigned)time(NULL));int n = rand() % 8;Sleep(1);drawsun(c[n], s.center_x, s.center_y, sunradies);}if (m1 > 0) {//只有当m1>0时才会改变角度,当m1<0时不再改变if (n1 > 0) {//当n1>0时才会正转,<0时走反转eangle = eangle + 2 * PI / 60;mangle = mangle + 2 * PI / 30;}else {eangle = eangle - 2 * PI / 60;mangle = mangle - 2 * PI / 30;}}}
4,项目运行截图
5,具体代码实现
#include<graphics.h>
#include<conio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#define WIDTH 800//窗口的宽
#define HEIGHT 800//窗口的高
#define PI 3.14159//PI
typedef enum RADIES {//星球半径sunradies = 150,//太阳earthradies = 30,//地球moonradies = 5,//月亮
}radies;
typedef enum COLOR {//颜色black = 0,//黑色blue = 0xAA0000,//蓝色green = 0x00AA00,//绿色cyan = 0xAAAA00,//青色red = 0x0000AA,//红色magenta = 0xAA00AA,//紫色brown = 0x0055AA,//棕色lightgray = 0xAAAAAA,//浅灰yellow = 0x55FFFF,//黄色
}color;
typedef struct Plant {//行星int radies;//行星半径int center_x;//行星中心X坐标int center_y;//行星中心Y坐标
}plant;
void drawsun(color c, int x, int y, radies r);//绘制太阳
void creatplant(plant* p, int x, int y, int radies);//创建星球
void drawplant(plant* p1, plant* p2, double angle, int a, color c, radies r);//绘制星球
int main()
{plant s, e, m;creatplant(&s, WIDTH / 2, HEIGHT / 2, sunradies);//创建太阳属性creatplant(&e, WIDTH / 8, HEIGHT / 8, earthradies);//创建地球属性creatplant(&m, WIDTH / 10, HEIGHT / 10, moonradies);//创建月球属性color c1 = red;initgraph(WIDTH, HEIGHT);double eangle = 0;double mangle = 0;char key = 0;int i = 1;//作为闪烁颜色的开关int m1 = 1;//作为暂停的开关int n1 = 1;//作为逆时针转动的开关while (key != 27) {if (_kbhit()) {switch (key = _getch()) {case 49:c1 = blue; break;case 50:c1 = yellow; break;case 52:c1 = brown; break;case 53:c1 = magenta; break;case 54:c1 = red; break;case 55:c1 = lightgray; break;case 56:i = i * -1; break;case 32:m1 = m1 * -1; break;case 27:break;case 72:n1 = n1 * -1; break;}drawsun(c1, s.center_x, s.center_y, sunradies);}drawsun(c1, s.center_x, s.center_y, sunradies);if (i < 0) {color c[8] = { black,blue,red,blue,yellow,cyan,magenta,blue };srand((unsigned)time(NULL));int n = rand() % 8;Sleep(1);drawsun(c[n], s.center_x, s.center_y, sunradies);}BeginBatchDraw();drawplant(&e, &s, eangle, 3, blue, earthradies);drawplant(&m, &e, mangle, 13, yellow, moonradies);if (m1 > 0) {if (n1 > 0) {eangle = eangle + 2 * PI / 60;mangle = mangle + 2 * PI / 30;}else {eangle = eangle - 2 * PI / 60;mangle = mangle - 2 * PI / 30;}}Sleep(50);FlushBatchDraw();clearcircle(e.center_x, e.center_y, earthradies);clearcircle(m.center_x, m.center_y, moonradies);}EndBatchDraw();_getch();closegraph();return 0;
}
void drawsun(color c, int x, int y, radies r) {setfillcolor(c);solidcircle(x, y, r);
}
void creatplant(plant* p, int x, int y, int radies) {p->center_x = x;p->center_y = y;p->radies = radies;
}
void drawplant(plant* p1, plant* p2, double angle, int a, color c, radies r) {p1->center_x = p2->center_x + (WIDTH / a) * sin(angle);p1->center_y = p2->center_y - (WIDTH / a) * cos(angle);setfillcolor(c);solidcircle(p1->center_x, p1->center_y, p1->radies);
}
/*
地球要围绕着太阳转动
月球要围绕着地球转动
按下1-7的按键时,太阳会变色
按下8的时候太阳会依次的变色
当按下空格键的时候,太阳会停止转动
当按下上键的时候地球和月亮会逆向的转动,再按下上键的时候,地球和月亮会顺时针转动
*/
C/C++基于easyX库实现三星环绕小项目(C/C++)相关推荐
- 基于c语言Easyx库的捕鱼达人小游戏
基于c语言Easyx库的捕鱼达人小游戏(一) 文章目录 基于c语言Easyx库的捕鱼达人小游戏(一) 主菜单 游戏实现 捕鱼计分 下一阶段 主菜单 (写在前面的话:使用EASY-X库一定要命名为.cp ...
- 基于easyx库的GUI扫雷项目
基于easyx库的GUI扫雷项目 文章目录 基于easyx库的GUI扫雷项目 0.观前提醒 1.扫雷游戏项目效果展示 2.扫雷游戏项目基本信息 3.扫雷游戏项目设计思路 4.扫雷游戏实现原理 4.1 ...
- 基于easyX制作的C语言小游戏
目录 游戏内容 开始界面 加载界面 游戏界面 游戏胜利界面 选择难度界面 游戏介绍界面 上代码! 头文件 定义数据 自定义函数 全局变量 窗口类函数 开始界面 加载窗口 游戏界面 难度选择窗口 游戏介 ...
- 用C++和easyx库完成一个数独小游戏
按我之前产生数独的思路使用matlab产生数独和使用python产生数独游戏python数独游戏的思路,改写成了C++语言的数独游戏,并结合easyx库进行游戏界面输出和交互.(在我之前的博客里都有写 ...
- c语言/c++大作业基于easyx图形库自制RPG类型小游戏代码(附源码)
目录 一.游戏玩法 二.完整代码 三.部分细节 透明化人物背景 关于easyx库中怎样贴出透明图片 地图的链表实现 移动检测 碰撞检测 总结 前言: 花两天边看easyx文档边学边写的期末小作业. 学 ...
- 矩阵键盘基于51(UcosII)计算器小项目
矩阵键盘 最近要给学弟学妹(应该没有)培训矩阵键盘,正好写一写我写矩阵键盘的思路,顺便分享一个之前做的基于ucosii的计算器小项目 原理 原理就不介绍了,CSDN有很多分享的,推荐两篇参考一下: 参 ...
- 绘制樱花树特效(基于EasyX库实现)
1.程序运行环境(必读) Visual C++ 6.0.Visual Studio 2010 ~ Visual Studio 2022 等支持EasyX图形库的软件均可以使用,实现相应功能. ---- ...
- c语言基于easyx库的 飞机大战游戏(鼠标控制飞机移动,武器升级,boss发射散弹,boss血条等功能)
课设题目 实现功能: 飞机鼠标控制–飞机武器升级–敌机发射子弹–boss发射散弹–boss血条记录–我方多条生命 图片资源和源码在下面 链接:https://pan.baidu.com/s/1uTQV ...
- 基于EasyX图形库的C/C++实战项目——西南大学大一C语言程序设计|课程设计《多功能应用平台》
目录 一.扫雷 二.迷宫 三.通讯录 四.核心代码 一.扫雷 功能简介:1. 棋盘设置 2. 设置模式 3. 红旗标志 4. 递归展开(DFS) 扫雷 二.迷宫 功能介绍: 1. ...
最新文章
- Java图形化:布局方式
- 如何在Kubernetes集群动态使用 NAS 持久卷
- cache 的设计与实现--转载
- javaweb使用 数据库连接池 DBCP,实现对数据库驱动使用优化,多个 action共用一个数据库连接
- iOS开发 - Swift实现清除缓存功能
- 计算机网络——分层结构,协议,接口和服务
- 最快15分钟,完成高精度AI模型定制开发
- 水果手绘插画素材|一眼就想吃了!
- [设计模式-创建型]原型(Prototype)
- Github Trending被中文项目“占领”,国外开发者不开心了!
- ProE常用曲线方程式
- php openoffice,php实现openoffice转pdf的方法
- SQL 数据库语句练习
- MATLAB经纬度转化
- 用php写后端怎么使用模板_用PHP保守秘密
- flash崩溃未保存!
- 读书笔记:《好团队激活个人--猫鼬教你如何带团队》
- 世界各国城镇人口占比数据(1960-2018年)
- Cocoa公历和中国农历直接的转换
- 【硬见小百科】看完这篇,请不要再说不懂MOSFET!