广告位联系
返回顶部
分享到

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

C语言 来源:互联网 作者:佚名 发布时间:2022-10-31 22:13:05 人浏览
摘要

功能1:使用图形化的方式描述地球围绕着太阳转动,月球围绕着地球转动 功能2:在转动的过程中当用户按下1,2,3,4,5,6,7时它可以变换出7种不同的颜色,当用户按下8时它可以变换从1-7的

功能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才能正常运行

首先为了方便程序的可维护性,所以最开始,使用了枚举定义了地球,月球和太阳的半径。

1

2

3

4

5

typedef enum RADIES {//星球半径

    sunradies = 150,//太阳

    earthradies = 30,//地球

    moonradies = 5,//月亮

}radies;

然后为了能实现色彩的变化,也可以先定义一个颜色的枚举,颜色是基于easyX库中的。

1

2

3

4

5

6

7

8

9

10

11

typedef enum COLOR {//颜色

    black = 0,//黑色

    blue = 0xAA0000,//蓝色

    green = 0x00AA00,//绿色

    cyan = 0xAAAA00,//青色

    red = 0x0000AA,//红色

    magenta = 0xAA00AA,//紫色

    brown = 0x0055AA,//棕色

    lightgray = 0xAAAAAA,//浅灰

    yellow = 0x55FFFF,//黄色

}color;

  • 实现基本的地球,太阳和月球三星环绕关键代码

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

1

2

3

4

5

typedef struct Plant {//行星

    int radies;//行星半径

    int center_x;//行星中心X坐标

    int center_y;//行星中心Y坐标

}plant;

在程序中先创建行星,也就是为行星赋予基本的中心点和半径作初始化,然后,通过绘制行星,传入行星实时更新的坐标点在死循环中更新图像。

1

2

3

4

5

6

//通过传入结构体指针首先给指针所指向的内存地址中的相关属性赋初值

void creatplant(plant* p, int x, int y, int radies) {

p->center_x = x;//行星中心的初始x坐标

p->center_y = y;//行星中心的初始y坐标

p->radies = radies;//行星的半径

}

通过传入中心行星和环绕行星,使用指针来访问内存空间,通过修改内存中的数值实现实时改变终点坐标

1

2

3

4

5

6

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);//根据改变的值绘制图形

}

直接绘制太阳,因为太阳就是一个静止的状态:

1

2

3

4

5

//因为太阳它是固定的就是一个静态图片

void drawsun(color c, int x, int y, radies r) {

setfillcolor(c);

solidcircle(x, y, r);

}

接下来就可在主方法中进行绘制的实验了

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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是键值,也就是在键盘中它都有对应的值

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

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,具体代码实现

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

#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的时候太阳会依次的变色

当按下空格键的时候,太阳会停止转动

当按下上键的时候地球和月亮会逆向的转动,再按下上键的时候,地球和月亮会顺时针转动

*/


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://blog.csdn.net/EMCred/article/details/127546317
相关文章
  • C++11, 14, 17对tuple元素的访问介绍
    C++11, 14, 17对tuple元素的访问 std::tuple 作为可以存放任意个数,任意类型的元祖被我个人经常使用。 记得以前看侯捷谈到这个数据结构的时候
  • C++使用easyX库实现三星环绕效果流程介绍

    C++使用easyX库实现三星环绕效果流程介绍
    功能1:使用图形化的方式描述地球围绕着太阳转动,月球围绕着地球转动 功能2:在转动的过程中当用户按下1,2,3,4,5,6,7时它可以变换出7种不
  • C++时间函数整理介绍
    一、 时间概念 格林威治时间GMT(Greenwich Mean Time) 格林威治皇家天文台为了海上霸权的扩张计划,在十七世纪就开始进行天体观测。为了天
  • C++中类的六大默认成员函数的介绍

    C++中类的六大默认成员函数的介绍
    一、类的默认成员函数 二、构造函数Date(形参列表) 构造函数主要完成初始化对象,相当于C语言阶段写的Init函数。 默认构造函数:无参的构
  • C/C++实现遍历文件夹最全方法总结介绍

    C/C++实现遍历文件夹最全方法总结介绍
    一、filesystem(推荐) 在c++17中,引入了文件系统,使用起来非常方便 在VS中,可以直接在项目属性中调整: 只要是C++17即以上都可 然后头文件
  • C语言实现手写Map(数组+链表+红黑树)的代码

    C语言实现手写Map(数组+链表+红黑树)的代码
    要求 需要准备数组集合(List) 数据结构 需要准备单向链表(Linked) 数据结构 需要准备红黑树(Rbtree)数据结构 需要准备红黑树和链表适配策略
  • MySQL系列教程之使用C语言来连接数据库

    MySQL系列教程之使用C语言来连接数据库
    写在前面 知道了 Java中使用 JDBC编程 来连接数据库了,但是使用 C语言 来连接数据库却总是连接不上去~ 立即安排一波使用 C语言连接 MySQL数
  • 基于C语言实现简单学生成绩管理系统

    基于C语言实现简单学生成绩管理系统
    一、系统主要功能 1、密码登录 2、输入数据 3、查询成绩 4、修改成绩 5、输出所有学生成绩 6、退出系统 二、代码实现 1 2 3 4 5 6 7 8 9 10 11
  • C语言实现共享单车管理系统

    C语言实现共享单车管理系统
    1.功能模块图; 2.各个模块详细的功能描述。 1.登陆:登陆分为用户登陆,管理员登陆以及维修员登录,登陆后不同的用户所执行的操作
  • C++继承与菱形继承的介绍

    C++继承与菱形继承的介绍
    继承的概念和定义 继承机制是面向对象程序设计的一种实现代码复用的重要手段,它允许程序员在保持原有类特性的基础上进行拓展,增加
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计