C++使用easyX库实现三星环绕效果流程详解

目录
  • 1,项目描述
  • 2,解决思路
  • 3,关键代码
  • 4,项目运行截图
  • 5,具体代码实现

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;
  • 实现基本的地球,太阳和月球三星环绕关键代码

可以看作是三个中心点之间的不断的运算关系,最核心的是通过不断更新中心坐标的位置实现,对于太阳来说,它的中心坐标是位于窗口的中心,并且对于太阳来说它是不动的,对于地球来说,它的中心坐标是根据以太阳为中心基点,围绕着太阳进行转动的,对于月球来说,亦然,地球和月球都是行星,它们的运动是依靠着坐标点的位置变化实现,所以可以定义一个行星结构体,包含行星的半径和行星中心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;
}

实验截图:

  • 开关算法思想关键代码

该代码用于主方法中控制整个程序的流程,其关键部分如下,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,再按下时>0
        case 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++使用easyX库实现三星环绕效果流程详解的文章就介绍到这了,更多相关C++三星环绕内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++基于EasyX库实现拼图小游戏

    用C++的EasyX库做的拼图小游戏,供大家参考,具体内容如下   记录一下自己做的第一个项目,还有一些改进空间QWQ,可以支持难度升级,但是通关判断似乎有点小问题肯定不是我菜通不了关 . #pragma once #include <iostream> #include <graphics.h> #include <Windows.h> #include <algorithm> #include <easyx.h> #include <c

  • C++实现基于EASYX库扫描线算法

    本文实例为大家分享了C++实现基于EASYX库扫描线算法的具体代码,供大家参考,具体内容如下 扫描线算法的基本原理 * 作者在扫描线算法的基础上自己设计的更易于理解的地物填充绘制算法 流程图 代码 #include<graphics.h> //#include<conio.h> #include<iostream> using namespace std; //-----------------------------草图形-----------------------

  • C++使用easyX库实现三星环绕效果流程详解

    目录 1,项目描述 2,解决思路 3,关键代码 4,项目运行截图 5,具体代码实现 1,项目描述 功能1:使用图形化的方式描述地球围绕着太阳转动,月球围绕着地球转动 功能2:在转动的过程中当用户按下1,2,3,4,5,6,7时它可以变换出7种不同的颜色,当用户按下8时它可以变换从1-7的颜色依次变换当用户再次按下8键时停止变换颜色 功能3:当用户按下上键时,地球会围绕太阳反转,当再次按下上键时地球会恢复到正转 功能4:当用户按下空格键的时候,所有动画暂停,当再次按下空格键的时候所有动画继续进行.

  • JavaScript制作楼层导航效果流程详解

    目录 本期目标 1. 功能实现 1.1 结构层 1.2 样式层 1.3 行为层 1.3.1 楼层跳转 1.3.2 楼层监听 2. 效果预览 3. 项目代码 本期目标 使用JavaScript制作楼层导航效果,实现两个功能: 楼层跳转 楼层监听 1. 功能实现 1.1 结构层 <div id="box" class="box"> <ul class="list"> <li class="content-par

  • React实现卡片拖拽效果流程详解

    前提摘要: 学习宋一玮 React 新版本 + 函数组件 &Hooks 优先 开篇就是函数组件+Hooks 实现的效果如下: 学到第11篇了 照葫芦画瓢,不过老师在讲解的过程中没有考虑拖拽目标项边界问题,我稍微处理了下这样就实现拖拽流畅了 下面就是主要的代码了,实现拖拽(src/App.js): 核心在于标记当前项,来源项,目标项,并且在拖拽完成时对数据处理,更新每一组数据(useState): /** @jsxImportSource @emotion/react */ // 上面代码是使用e

  • Jquery 效果使用详解

    jQuery是一款同prototype一样优秀js开发库类,特别是对css和XPath的支持,使我们写js变得更加方便!如果你不是个js高手又想写出优 秀的js效果,jQuery可以帮你达到目的! .hide() 隐藏匹配的元素. .hide() 这个方法不接受任何参数. .hide([duration][,complete]) duration 一个字符串或者数字决定动画将运行多久. complete 在动画执行完时执行的函数. .hide([duration][,easing][,compl

  • Python黑魔法库安装及操作字典示例详解

    目录 1. 安装方法 2. 简单示例 3. 兼容字典的所有操作 4. 设置返回默认值 5. 工厂函数自动创建key 6. 序列化的支持 7. 说说局限性 本篇文章收录于<Python黑魔法手册>v3.0 第七章,手册完整版在线阅读地址:Python黑魔法手册 3.0 文档 字典是 Python 中基础的数据结构之一,字典的使用,可以说是非常的简单粗暴,但即便是这样一个与世无争的数据结构,仍然有很多人 "用不惯它" . 也许你并不觉得,但我相信,你看了这篇文章后,一定会和我一

  • Python标准库之Math,Random模块使用详解

    目录 数学模块 ceil -- 上取整 floor -- 下取整 四舍五入 pow -- 幂运算 sqrt -- 开平方运算 fabs -- 绝对值 modf -- 拆分整数小数 copysign -- 正负拷贝 fsum -- 序列和 pi -- 圆周率常数 factorial -- 因数 随机模块 random -- 获取 0~~1 之间的小数 randrange -- 获取指定范围内的整数 randint -- 获取指定范围整数 uniform -- 获取指定范围内随机小数(左闭右开) c

  • Python Asyncio库之asyncio.task常用函数详解

    目录 前记 0.基础 1.休眠--asyncio.sleep 2.屏蔽取消--asyncio.shield 3.超时--asyncio.wait_for 4.简单的等待--wait 5.迭代可等待对象的完成--asyncio.as_completed 前记 Asyncio在经过一段时间的发展以及获取Curio等第三方库的经验来提供更多的功能,目前高级功能也基本完善,但是相对于其他语言,Python的Asyncio高级功能还是不够的,但好在Asyncio的低级API也比较完善,开发者可以通过参考A

  • BootStrap的JS插件之轮播效果案例详解

    Bootstrap 是一个用于快速开发 Web 应用程序和网站的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的. 案例 下面展示的就是此插件和相关组件制作的轮播案例. <div id="carousel-example-generic" class="carousel slide" data-ride="carousel"> <!-- Indicators --> <ol class

  • 微信小程序 利用css实现遮罩效果实例详解

    微信小程序 利用css实现遮罩效果实例详解 实现效果图: 如图所示,使用css实现小程序的遮罩效果,代码如下 js文件代码: //index.js //获取应用实例 var app = getApp() Page({ data: { flag: false }, a: function(){ this.setData({flag: false}) }, b: function(){ this.setData({flag: true}) } }) wxss文件代码: .b1{position:fi

  • JS库之Highlight.js的用法详解

    官网:https://highlightjs.org/ 下载地址:https://highlightjs.org/download/ 下载到本地后,新建个页面测试 1.在head中加入css和js的引用 <head> <title>highlight</title> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <link r

随机推荐