文章目录
- 一、EasyX的安装
- 二、C++_EasyX 项目
- 1. 樱花
- 2. 雪花
- 3. 小熊
- 4. 跳动爱心
- 5. 橘子钟表
- 6. 红玫瑰
- 7. 奥特曼
- 三、更多项目资源
EasyX提取链接
网盘链接:https://pan.baidu.com/s/1gPtRVZub_008jwcK11Bb-g?pwd=9ol9
提取码:9ol9
什么是EasyX?
EasyX 是针对 C++ 的图形库,可以帮助 C 语言初学者快速上手图形和游戏编程。 比如,可以用 VC + EasyX 很快的用几何图形画一个房子,或者一辆移动的小车,可以编写俄罗斯方块、贪吃蛇、黑白棋等小游戏可以练习图形学的各种算法等等。
一、EasyX的安装
-
- 提取并下载上述网盘链接,得到一个EasyX_20220116.exe文件
-
- 双击exe文件,点击下一步
- 双击exe文件,点击下一步
-
- 找到最新VC版本,选择安装
- 找到最新VC版本,选择安装
-
- 弹出安装成功界面
- 弹出安装成功界面
-
- 进入VS2022,新建一个空项目cpp工程
- 进入VS2022,新建一个空项目cpp工程
-
- 添加源文件,输入以下代码进行安装测试
#include<graphics.h>//引用图形库头文件
#include <conio.h>
int main()
{
initgraph(400, 400); //创建窗口大小为640x480像素
circle(200, 200, 100); //画圆,圆心(200,200),半径100
outtextxy(170, 200, _T("比特冬哥"));
_getch(); //按任意键继续,防止闪退
closegraph(); //关闭绘图窗口
return 0;
}
-
- 按下F5运行,出现如下样式表示安装成功
- 按下F5运行,出现如下样式表示安装成功
二、C++_EasyX 项目
1. 樱花
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#define PI 3.1415926
#define WIDTH 800 // 画面宽度
#define HEIGHT 600 // 画面高度度
float offsetAngle = PI / 6; // 左右枝干和父枝干偏离的角度
float shortenRate = 0.65; // 子枝干比父枝干变短的倍数
int isShowAnimation = 1; // 是否显示树生成的过程动画
// 把[inputMin,inputMax]范围的input变量,映射为[outputMin,outputMax]范围的output变量
float mapValue(float input, float inputMin, float inputMax, float outputMin, float outputMax)
{
float output;
if ((input - inputMin) < 0.000001) // 防止除以零的bug
output = outputMin;
else
output = (input - inputMin) * (outputMax - outputMin) / (inputMax - inputMin) + outputMin;
return output;
}
// 生成[min,max]之间的随机小数
float randBetween(float min, float max)
{
float t = rand() / double(RAND_MAX); // 生成[0,1]的随机小数
// 调用mapValue函数,把值范围从[0,1]映射到[min,max]
float r = mapValue(t, 0, 1, min, max);
return r;
}
// 枝干生成和绘制递归函数
// 输入参数:枝干起始x y坐标,枝干长度,枝干角度,枝干绘图线条宽度,第几代
void brunch(float x_start, float y_start, float length, float angle, float thickness, int generation)
{
// 利用三角函数求出当前枝干的终点x,y坐标
float x_end, y_end;
x_end = x_start + length * cos(angle);
y_end = y_start + length * sin(angle);
// 画线条枝干
setlinestyle(PS_SOLID, thickness); // 设定当前枝干线宽
// 设置枝干为灰褐色,主树干最黑,子枝干逐渐变亮
COLORREF color = HSVtoRGB(15, 0.75, 0.4 + generation * 0.05);
setlinecolor(color); // 设定当前枝干颜色
line(x_start, y_start, x_end, y_end); // 画出当前枝干(画线)
// 求出子枝干的代数
int childGeneration = generation + 1;
// 生成左、右、中间三个子枝干的长度,逐渐变短,并有一定随机性
float childLength = shortenRate * length;
float leftChildLength = childLength * randBetween(0.9, 1.1);
float rightChildLength = childLength * randBetween(0.9, 1.1);
float centerChildLength = childLength * randBetween(0.8, 1.1);
// 当子枝干长度大于2,并且代数小于等于10,递归调用产生子枝干
if (childLength >= 2 && childGeneration <= 9)
{
// 生成子枝干的粗细,逐渐变细
float childThickness = thickness * 0.8;
if (childThickness < 2) // 枝干绘图最细的线宽为2
childThickness = 2;
// 一定概率产生左、右、中子枝干
if (randBetween(0, 1) < 0.95)
brunch(x_end, y_end, leftChildLength, angle + offsetAngle * randBetween(0.5, 1), childThickness, childGeneration);
if (randBetween(0, 1) < 0.95)
brunch(x_end, y_end, rightChildLength, angle - offsetAngle * randBetween(0.5, 1), childThickness, childGeneration);
if (randBetween(0, 1) < 0.85)
brunch(x_end, y_end, centerChildLength, angle + offsetAngle / 5 * randBetween(-1, 1), childThickness, childGeneration);
}
else // 最末端绘制樱花,画一个粉色填充圆
{
setlinestyle(PS_SOLID, 1); // 线宽
// 樱花粉色HSVtoRGB(325,0.3,1),有一定随机性
COLORREF color = HSVtoRGB(randBetween(300, 350), randBetween(0.2, 0.3), 1);
setlinecolor(color); // 设定线条颜色
setfillcolor(color); // 设定填充颜色
if (childLength <= 4) // 如果子枝干长度小于等于4
fillcircle(x_end, y_end, 2); // 圆的半径为2(再小就看不清了)
else
fillcircle(x_end, y_end, childLength / 2); // 画一个圆,半径为子枝干长度的一半
}
if (isShowAnimation) // 如果为1,绘制樱花树生成的过程动画
{
FlushBatchDraw(); // 批量绘制
Sleep(1); // 暂停
}
}
void startup() // 初始化
{
srand(time(0)); // 随机初始化
initgraph(WIDTH, HEIGHT); // 新开一个画面
setbkcolor(RGB(255, 255, 255)); // 白色背景
cleardevice(); // 清屏
BeginBatchDraw(); // 开始批量绘制
brunch(WIDTH / 2, HEIGHT, 0.45 * HEIGHT * shortenRate, -PI / 2, 15 * shortenRate, 1); // 递归函数调用
FlushBatchDraw(); // 批量绘制
}
void update() // 每帧更新
{
MOUSEMSG m;
if (MouseHit())
{
m = GetMouseMsg();
if (m.uMsg == WM_MOUSEMOVE) // 当鼠标移动时,设定递归函数的参数
{
// 鼠标从左到右,左右子枝干偏离父枝干的角度逐渐变大
offsetAngle = mapValue(m.x, 0, WIDTH, PI / 10, PI / 4);
// 鼠标从上到下,子枝干比父枝干的长度缩短的更快
shortenRate = mapValue(m.y, 0, HEIGHT, 0.7, 0.3);
}
if (m.uMsg == WM_LBUTTONDOWN) // 当鼠标左键点击时,以当前参数开始绘制一棵新数
{
cleardevice(); // 清屏
brunch(WIDTH / 2, HEIGHT, 0.45 * HEIGHT * shortenRate, -PI / 2, 15 * shortenRate, 1); // 递归调用
FlushBatchDraw(); // 批量绘制
}
if (m.uMsg == WM_RBUTTONDOWN) // 当鼠标右键点击时,切换是否显示过程动画
{
if (isShowAnimation == 1)
isShowAnimation = 0;
else if (isShowAnimation == 0)
isShowAnimation = 1;
}
}
}
int main() // 主函数
{
startup(); // 初始化
while (1) // 重复循环
update(); // 每帧更新
return 0;
}
2. 雪花
/* *************************
* 程序名称: LoveSnow - 表白程序
* ********* 说明 **********
* 需要自己提供一张大小为 640×480 的图片(img.jpg)在项目根目录下
* 大小可以在程序内更改,图片名字也可以。
* *************************/
#include <graphics.h>
#define MAX_STAR 500 // 雪花数量上限
#define SCREEN_WIDTH 640 // 屏幕宽度
#define SCREEN_HEIGHT 480 // 屏幕高度
#define MAX_STEP 3 // 雪花每次移动最高步长
#define MAX_RADIUS 3 // 雪花最大半径
#define IMGNAME _T("XXXX.jpg") // 图片名字
using namespace std;
// 图片转数组(这个有很大优化空间的,需要识别彩色照片可以看这)
int imgList[SCREEN_HEIGHT][SCREEN_WIDTH] = { 0 };
// 雪花状态
enum STATUS
{
STOP = 0, // 不动
UP, // 向上
DOWN, // 向下
LEFT, // 向左
RIGHT, // 向右
RANDOM, // 随机
ALL_STATUS // 记录状态总数
};
struct STAR
{
int x; // 雪花的 x 坐标
int y; // 雪花的 y 坐标
enum STATUS stat; // 雪花状态
unsigned radius; // 雪花的半径
int step; // 雪花每次移动的步长
int color; // 雪花的颜色
};
struct SqList
{
struct STAR* elems; // 顺序表的基地址
int length; // 顺序表的长度
int size; // 顺序表的空间
};
// 顺序表的接口
bool initList(SqList& L);
bool listAppend(SqList& L, struct STAR e);
bool listDelete(SqList& L, int i);
void destroyList(SqList& L);
bool initList(SqList& L)
{
L.elems = new struct STAR[MAX_STAR];
if (!L.elems) return false;
L.length = 0;
L.size = MAX_STAR;
return true;
}
bool listAppend(SqList& L, struct STAR e)
{
if (L.length == L.size) return false; // 存储空间已满
L.elems[L.length] = e;
L.length++; // 表长加 1
return true;
}
bool listDelete(SqList& L, int i)
{
if (i < 0 || i >= L.length) return false;
if (i == L.length - 1)
{ // 删除最后一个元素
L.length--;
return true;
}
for (int j = i; j < L.length - 1; j++)
{
L.elems[j] = L.elems[j + 1]; // 删除位置的后续元素一次往前移
}
L.length--;
return true;
}
void destroyList(SqList& L)
{
if (L.elems) delete[]L.elems; // 释放存储空间
L.length = 0;
L.size = 0;
}
/************************************
* 功能:移动雪花,并在指定区域留下雪痕
* 输入参数:
* L - 雪花对象
* i - 雪花在全局数组中的下标
* 返回值:无
************************************/
void MoveStar(SqList& L, int i)
{
// 留下雪痕
if (L.elems[i].stat == DOWN)
{
if (imgList[L.elems[i].y][L.elems[i].x] == 1)
{
L.elems[i].y += L.elems[i].step;
L.elems[i].x -= 2;
}
}
if (L.elems[i].stat == UP)
{
if (imgList[L.elems[i].y][L.elems[i].x] == 1)
{
L.elems[i].y -= L.elems[i].step;
L.elems[i].x -= 2;
}
}
if (L.elems[i].stat == LEFT)
{
if (imgList[L.elems[i].y][L.elems[i].x] == 1) L.elems[i].x -= L.elems[i].step;
}
if (L.elems[i].stat == RIGHT)
{
if (imgList[L.elems[i].y][L.elems[i].x] == 1) L.elems[i].x += L.elems[i].step;
}
if (L.elems[i].stat == STOP) return;
// 擦除原来的雪花
setfillcolor(BLACK);
solidcircle(L.elems[i].x, L.elems[i].y, L.elems[i].radius);
if (L.elems[i].stat == DOWN)
{
L.elems[i].y += L.elems[i].step;
L.elems[i].x -= 2;
if (L.elems[i].x < 0) L.elems[i].x = SCREEN_WIDTH;
if (L.elems[i].y > SCREEN_HEIGHT) L.elems[i].y = 0;
//if(L.elems[i].y>SCREEN_HEIGHT) listDelete(L, i); // 这段代码可以让飘出屏幕外的雪花消亡
}
else if (L.elems[i].stat == UP)
{
L.elems[i].y -= L.elems[i].step;
L.elems[i].x -= 2;
if (L.elems[i].x < 0) L.elems[i].x = SCREEN_WIDTH;
if (L.elems[i].y < 0) L.elems[i].y = SCREEN_HEIGHT;
//if(L.elems[i].y<0) listDelete(L, i);
}
else if (L.elems[i].stat == LEFT)
{
L.elems[i].x -= L.elems[i].step;
if (L.elems[i].x > 0) L.elems[i].x = SCREEN_WIDTH;
//if(L.elems[i].x<0) listDelete(L, i);
}
else if (L.elems[i].stat == RIGHT)
{
L.elems[i].x += L.elems[i].step;
if (L.elems[i].x > SCREEN_HEIGHT) L.elems[i].x = 0;
//if(L.elems[i].x>SCREEN_WIDTH) listDelete(L, i);
}
setfillcolor(L.elems[i].color);
solidcircle(L.elems[i].x, L.elems[i].y, L.elems[i].radius);
}
/************************************
* 功能:初始化雪花
* 输入参数:
* i - 雪花在全局数组中的下标
* 返回值:无
************************************/
void initStar(struct STAR& _star)
{
int rgb = 0;
//rand() 得到随机数范围 0 - 32767 RAND_MAX
_star.x = rand() % SCREEN_WIDTH; // x 范围 0 - SCREEN_WIDTH
_star.y = rand() % SCREEN_HEIGHT; // y 范围 0 - SCREEN_HEIGHT
//_star.stat = STATUS(rand() % 6); // 雪花状态:随机
_star.stat = DOWN; // 雪花状态:向下
_star.radius = 1 + rand() % MAX_RADIUS; // 半径控制 1 - MAX_RADIUS
_star.step = rand() % MAX_STEP + 1; // 步长 1 - MAX_STEP
rgb = 255 * _star.step / MAX_STEP; // RGB:0 - 255
_star.color = RGB(rgb, rgb, rgb);
}
int main()
{
bool quit = false;
struct STAR star;
SqList starList;
// 初始化屏幕
initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);
// 初始化图片
IMAGE img(SCREEN_WIDTH, SCREEN_HEIGHT);
//loadimage(&img, IMGNAME);
SetWorkingImage(&img); // 设置 img为绘制设备
setbkcolor(WHITE);
cleardevice();
settextcolor(BLACK);
settextstyle(120, 55, _T("黑体"));
outtextxy(100, 150, _T("比特冬哥"));
//outtextxy(100, 250, _T("有一个家"));
COLORREF color; // 记录像素颜色
BYTE r, b, g; // 记录像素RGB
for (int y = 0; y < SCREEN_HEIGHT; y++)
{
for (int x = 0; x < SCREEN_WIDTH; x++)
{
color = getpixel(x, y); // 获取像素颜色
r = GetRValue(color);
b = GetBValue(color);
g = GetGValue(color);
if (r < 200 && b < 200 && g < 200)
{ // 判断需留下“雪痕”的数组位置
imgList[y][x] = 1;
}
}
}
SetWorkingImage(); // 设置回默认绘制设备
cleardevice();
// 初始化保存雪花状态的顺序表
initList(starList);
for (int i = 0; i < MAX_STAR; i++)
{
initStar(star);
listAppend(starList, star);
}
for (int i = 0; i < starList.length; i++)
{
setfillcolor(starList.elems[i].color);
solidcircle(starList.elems[i].x, starList.elems[i].y,
starList.elems[i].radius);
}
while (quit == false)
{
for (int i = 0; i < starList.length; i++)
{
MoveStar(starList, i);
}
if (starList.length == 0)
{ // 若设置雪花离开屏幕后消亡,则会触发此退出
quit = true;
}
Sleep(50);
}
system("pause");
closegraph();
return 0;
}
3. 小熊
#include <stdio.h>
#include <easyx.h>
int main()
{
initgraph(800, 600);
// 背景
setbkcolor(RGB(169, 92, 10));
cleardevice();
// 耳朵阴影
setfillcolor(RGB(130, 69, 4));
solidcircle(200, 130, 90);
solidcircle(600, 130, 90);
// 留出月牙状阴影
setfillcolor(RGB(255, 178, 50));
solidcircle(200, 120, 90);
solidcircle(600, 120, 90);
// 耳朵剪切区域
HRGN leftEarClip = CreateEllipticRgn(110, 30, 290, 210);
HRGN rightEarClip = CreateEllipticRgn(510, 30, 690, 210);
HRGN earsClip = CreateRectRgn(0, 0, 0, 0);
CombineRgn(earsClip, leftEarClip, rightEarClip, RGN_OR);
setcliprgn(earsClip);
// 留出耳朵高光
setfillcolor(RGB(243, 154, 2));
solidcircle(200, 130, 90);
solidcircle(600, 130, 90);
// 耳朵里面
setfillcolor(RGB(255, 178, 50));
solidcircle(200, 210, 90);
solidcircle(600, 210, 90);
// 释放区域
DeleteObject(leftEarClip);
DeleteObject(rightEarClip);
DeleteObject(earsClip);
// 禁用剪切区域
setcliprgn(NULL);
// 头
setfillcolor(RGB(255, 178, 50));
solidcircle(400, 300, 250);
// 头剪切区域
HRGN headClip = CreateEllipticRgn(150, 50, 650, 550);
setcliprgn(headClip);
// 留出头高光
setfillcolor(RGB(243, 154, 2));
solidcircle(400, 320, 250);
// 释放区域
DeleteObject(headClip);
// 禁用剪切区域
setcliprgn(NULL);
// 眼睛
setfillcolor(RGB(51, 34, 8));
solidcircle(275, 300, 25);
solidcircle(525, 300, 25);
// 白色椭圆阴影
setfillcolor(RGB(130, 69, 4));
solidellipse(310, 385, 490, 485);
// 白色椭圆
setfillcolor(WHITE);
solidellipse(310, 380, 490, 480);
// 鼻子
setfillcolor(RGB(51, 34, 8));
solidcircle(400, 420, 15);
// 胡须
setlinestyle(PS_SOLID, 5);
setlinecolor(RGB(51, 34, 8));
line(400, 420, 370, 450);
line(400, 420, 430, 450);
getchar();
closegraph();
return 0;
}
4. 跳动爱心
#include<graphics.h> //需安装easyx图形库插件
#include<conio.h>
#include<time.h>
#include<math.h>
#include<sys/timeb.h>
struct MyLove
{
int NUMS; // 编号
double m;
double n;
double size;
bool Is_show;
int x;
int y;
};
MyLove mylove[400];
int CenterX = 320;
int CenterY = 180;
double Size = 60;
void initdata(); // 初始化数据
void updata(); // 更新
void movedata(); // 平移
void showdata(); // 显示
int* GetRand(int* buf, int count, int range); // 随机数的生成
void heart(int x0, int y0, int size, COLORREF C);
void HpSleep(int ms);
int main()
{
initgraph(640, 480);
initdata();
BeginBatchDraw();
while (true)
{
updata();
showdata();
HpSleep(30); // 改为精确延时
FlushBatchDraw();
cleardevice();
}
EndBatchDraw();
_getch();
return 0;
}
void updata()
{
int* buf = (int*)malloc(sizeof(int) * 20);
buf = GetRand(buf, 20, (int)(2 * Size / 0.01));
movedata();
for (int i = 0; i < 20; i++)
{
mylove[i].m = buf[i] * 0.01;
mylove[i].n = (((sin(buf[(int)i] * 0.01) * sqrt(fabs(cos(buf[(int)i] * 0.01)))) / (sin(buf[(int)i] * 0.01) + 1.4142)) - 2 * sin(buf[(int)i] * 0.01) + 2);
mylove[i].size = Size;
mylove[i].NUMS = i / 20;
mylove[i].Is_show = true;
mylove[i].x = (int)(-Size * mylove[i].n * cos(mylove[i].m) + CenterX);
mylove[i].y = (int)(-Size * mylove[i].n * sin(mylove[i].m) + CenterY - mylove[i].size);
}
for (int i = 20; i < 400; i++)
{
mylove[i].size = mylove[i].size + 1;
if (mylove[i].size > 80)
{
mylove[i].size = 80;
}
mylove[i].NUMS = i / 20;
mylove[i].x = (int)(-mylove[i].size * mylove[i].n * cos(mylove[i].m) + CenterX);
mylove[i].y = (int)(-mylove[i].size * mylove[i].n * sin(mylove[i].m) + CenterY - mylove[i].size);
}
}
void movedata()
{
for (int i = 399; i > 19; i--)
{
mylove[i] = mylove[i - 20];
}
}
void showdata()
{
settextcolor(RED);
wchar_t c = 0x59; // 0x28 是电话机在 Wingdings 字体中的对应编码
for (int i = 0; i < 400; i++)
{
settextstyle(mylove[i].NUMS + 10, 0, _T("Webdings"));
setbkmode(TRANSPARENT);
outtextxy(mylove[i].x + 20, mylove[i].y + 20, c);
}
}
int* GetRand(int* buf, int count, int range)
{
struct timeb timeSeed;
ftime(&timeSeed);
srand(timeSeed.time * 1000 + timeSeed.millitm); // milli time
for (int i = 0; i < count; i++)
{
int randTmp = rand() % range;
for (int j = 0; j < i; j++)
{
if (buf[j] == randTmp)
{
break;//检查重复。
}
}
buf[i] = randTmp;
}
return buf;
}
void initdata()
{
for (int i = 0; i < 400; i++)
{
mylove[i].NUMS = 0;
mylove[i].m = 0;
mylove[i].n = 0;
mylove[i].size = 0;
mylove[i].Is_show = false;
mylove[i].x = 0;
mylove[i].y = 0;
}
}
// 精确延时函数(可以精确到 1ms,精度 ±1ms)
// by yangw80<yw80@qq.com>, 2011-5-4
void HpSleep(int ms)
{
static clock_t oldclock = clock(); // 静态变量,记录上一次 tick
oldclock += ms * CLOCKS_PER_SEC / 1000; // 更新 tick
if (clock() > oldclock) // 如果已经超时,无需延时
oldclock = clock();
else
while (clock() < oldclock) // 延时
Sleep(1); // 释放 CPU 控制权,降低 CPU 占用率,精度 10~16ms
// Sleep(0); // 更高精度、更高 CPU 占用率,精度 1ms
}
5. 橘子钟表
#include <stdio.h>
#include <conio.h>
#include <graphics.h>
#include <math.h>
const double PI = 3.141592654; // 定义圆周率
// 画表盘
void dial()
{
// 画蓝色背景
setbkcolor(0xe6cdb4); // 设置背景色
cleardevice(); // 清屏
// 画黄色外圆
setlinestyle(PS_SOLID, 10); // 设置线宽为十个像素
setlinecolor(YELLOW); // 设置画线颜色为黄色
setfillcolor(WHITE); // 设置填充颜色为白色
fillcircle(0, 0, 170); // 画圆
// 填充扇形颜色
int r = 150; // 定义半径为 150
setlinestyle(PS_SOLID, 2); // 设置线宽为两像素
for (int n = 0; n < 10; n++)
{
// 画橘子瓣的三次贝塞尔曲线
POINT pts[13]; // 定义数组,起始点、控制点 1、控制点 2、终点(起点)、控制点 1、控制点 2、终点(起点)……
double a = 2 * PI * n / 10; // 橘子瓣弧度
pts[0].x = int(r / 8 * cos(a + 2 * PI / 22));
pts[0].y = int(r / 8 * sin(a + 2 * PI / 22)); pts[12] = pts[11] = pts[0];
pts[1].x = int(r / 12 * cos(a + 2 * PI / 22)); pts[2].x = int(r / 12 * cos(a - 2 * PI / 22));
pts[1].y = int(r / 12 * sin(a + 2 * PI / 22)); pts[2].y = int(r / 12 * sin(a - 2 * PI / 22));
pts[3].x = int(r / 8 * cos(a - 2 * PI / 22));
pts[3].y = int(r / 8 * sin(a - 2 * PI / 22)); pts[4] = pts[3];
pts[5].x = int(r * cos(a - 2 * PI / 22));
pts[5].y = int(r * sin(a - 2 * PI / 22)); pts[6] = pts[5];
pts[9].x = int(r * cos(a + 2 * PI / 22));
pts[9].y = int(r * sin(a + 2 * PI / 22)); pts[10] = pts[9];
pts[7].x = int(r * 1.1 * cos(a - 2 * PI / 30)); pts[8].x = int(r * 1.1 * cos(a + 2 * PI / 30));
pts[7].y = int(r * 1.1 * sin(a - 2 * PI / 30)); pts[8].y = int(r * 1.1 * sin(a + 2 * PI / 30));
int c = HSLtoRGB(36.0f * n, 0.8f, 0.8f); // 设置彩虹色
setlinecolor(c); // 设置画线颜色为彩虹色
polybezier(pts, 13); // 画三次贝塞尔曲线
setfillcolor(c); // 设置填充色为彩虹色
floodfill(int(r / 2 * cos(a)), int(r / 2 * sin(a)), c); // 填充橘子瓣
}
// 显示表盘细节
settextcolor(BLACK); // 设置字体颜色
setbkmode(TRANSPARENT); // 设置背景色为透明
for (int n = 0; n < 12; n++)
{
// 整点刻度
setfillcolor(BLACK);
solidcircle(int(145 * cos(n * 2 * PI / 12)), -int(145 * sin(n * 2 * PI / 12)), 2);
solidcircle(int(145 * cos(n * 2 * PI / 4)), -int(145 * sin(n * 2 * PI / 4)), 4);
// 显示数字
wchar_t s[10];
swprintf_s(s, 10, L"%d", 12 - n); // int 类型转换成 char 类型
// 设置字体、大小及输出
if ((12 - n) % 3 == 0) settextstyle(48, 0, L"Broadway");
else settextstyle(24, 0, L"Broadway");
// 定义字符串长和宽,居中
int w, h;
w = textwidth(s);
h = textheight(s);
outtextxy(int(125 * cos(n * 2 * PI / 12 + PI / 2) - w / 2),
-int(125 * sin(n * 2 * PI / 12 + PI / 2) - h / 2),
s);
}
}
// 显示数字时钟
void digital(int h, int m, int s)
{
// 画显示当前时间的三个小矩形
setlinecolor(LIGHTGRAY); // 设置边框颜色为浅灰色
setfillcolor(WHITE); // 设置填充颜色为白色
fillrectangle(-40 - 13, 50, -40 + 13, 50 + 26);
fillrectangle(-13, 50, 13, 50 + 26);
fillrectangle(40 - 13, 50, 40 + 13, 50 + 26);
// 显示当前时间
settextstyle(24, 0, L"Consolas");
wchar_t a[10];
int w;
swprintf_s(a, 10, L"%d", h); w = textwidth(a); outtextxy(-40 - w / 2, 50, a);
swprintf_s(a, 10, L"%d", m); w = textwidth(a); outtextxy(-w / 2, 50, a);
swprintf_s(a, 10, L"%d", s); w = textwidth(a); outtextxy(40 - w / 2, 50, a);
}
// 画表针
void needles(int h, int m, int s)
{
double a = PI / 2 - (2 * PI * h / 12 + 2 * PI * 1 / 12 * m / 60); // 时针所走弧度
double b = PI / 2 - (2 * PI * m / 60 + 2 * PI * 1 / 60 * s / 60); // 分针所走弧度
double c = PI / 2 - 2 * PI * s / 60; // 秒针所走弧度
setlinecolor(BLACK); // 设置画线颜色为黑色
setlinestyle(PS_SOLID, 9); // 设置线宽为九像素
line(0, 0, int(50 * cos(a)), int(-50 * sin(a))); // 画时针
setlinestyle(PS_SOLID, 6); // 设置线宽为六像素
line(0, 0, int(100 * cos(b)), int(-100 * sin(b))); // 画分针
setlinecolor(RED); // 设置画线颜色为红色
setlinestyle(PS_SOLID, 3); // 设置线宽为三像素
line(int(20 * cos(c + PI)), -int(20 * sin(c + PI)), int(130 * cos(c)), -int(130 * sin(c))); // 画秒针
}
// 主函数
int main()
{
// 创建绘图窗口
initgraph(640, 480);
BeginBatchDraw(); // 开启批量绘图
setorigin(320, 240); // 设置原点
while (true)
{
// 计算
SYSTEMTIME ti; // 定义变量保存当前时间
GetLocalTime(&ti); // 获取当前时间
// 绘画
cleardevice();
dial(); // 画表盘
digital(ti.wHour, ti.wMinute, ti.wSecond); // 画数字时钟
needles(ti.wHour, ti.wMinute, ti.wSecond); // 画表针
// 延时
FlushBatchDraw();
Sleep(1000);
}
_getch();
EndBatchDraw();
closegraph();
return 0;
}
6. 红玫瑰
#include <graphics.h>
#include <conio.h>
#include <math.h>
// 定义全局变量
int rosesize = 500;
int h = -250;
// 定义结构体
struct DOT
{
double x;
double y;
double z;
double r; // 红色
double g; // 绿色
// b(蓝色) 通过 r 计算
};
// 计算点
bool calc(double a, double b, double c, DOT& d)
{
double j, n, o, w, z;
if (c > 60) // 花柄
{
d.x = sin(a * 7) * (13 + 5 / (0.2 + pow(b * 4, 4))) - sin(b) * 50;
d.y = b * rosesize + 50;
d.z = 625 + cos(a * 7) * (13 + 5 / (0.2 + pow(b * 4, 4))) + b * 400;
d.r = a * 1 - b / 2;
d.g = a;
return true;
}
double A = a * 2 - 1;
double B = b * 2 - 1;
if (A * A + B * B < 1)
{
if (c > 37) // 叶
{
j = (int(c) & 1);
n = j ? 6 : 4;
o = 0.5 / (a + 0.01) + cos(b * 125) * 3 - a * 300;
w = b * h;
d.x = o * cos(n) + w * sin(n) + j * 610 - 390;
d.y = o * sin(n) - w * cos(n) + 550 - j * 350;
d.z = 1180 + cos(B + A) * 99 - j * 300;
d.r = 0.4 - a * 0.1 + pow(1 - B * B, -h * 6) * 0.15 - a * b * 0.4 + cos(a + b) / 5 + pow(cos((o * (a + 1) + (B > 0 ? w : -w)) / 25), 30) * 0.1 * (1 - B * B);
d.g = o / 1000 + 0.7 - o * w * 0.000003;
return true;
}
if (c > 32) // 花萼
{
c = c * 1.16 - 0.15;
o = a * 45 - 20;
w = b * b * h;
z = o * sin(c) + w * cos(c) + 620;
d.x = o * cos(c) - w * sin(c);
d.y = 28 + cos(B * 0.5) * 99 - b * b * b * 60 - z / 2 - h;
d.z = z;
d.r = (b * b * 0.3 + pow((1 - (A * A)), 7) * 0.15 + 0.3) * b;
d.g = b * 0.7;
return true;
}
// 花
o = A * (2 - b) * (80 - c * 2);
w = 99 - cos(A) * 120 - cos(b) * (-h - c * 4.9) + cos(pow(1 - b, 7)) * 50 + c * 2;
z = o * sin(c) + w * cos(c) + 700;
d.x = o * cos(c) - w * sin(c);
d.y = B * 99 - cos(pow(b, 7)) * 50 - c / 3 - z / 1.35 + 450;
d.z = z;
d.r = (1 - b / 1.2) * 0.9 + a * 0.1;
d.g = pow((1 - b), 20) / 4 + 0.05;
return true;
}
return false;
}
// 主函数
void main()
{
// 定义变量
short* zBuffer;
int x, y, z, zBufferIndex;
DOT dot;
// 初始化
initgraph(640, 480); // 创建绘图窗口
setbkcolor(WHITE); // 设置背景色为白色
cleardevice(); // 清屏
// 初始化 z-buffer
zBuffer = new short[rosesize * rosesize];
memset(zBuffer, 0, sizeof(short) * rosesize * rosesize);
for (int j = 0; j < 2000 && !_kbhit(); j++) // 按任意键退出
{
for (int i = 0; i < 10000; i++) // 减少是否有按键的判断
if (calc(double(rand()) / RAND_MAX, double(rand()) / RAND_MAX, rand() % 46 / 0.74, dot))
{
z = int(dot.z + 0.5);
x = int(dot.x * rosesize / z - h + 0.5);
y = int(dot.y * rosesize / z - h + 0.5);
if (y >= rosesize) continue;
zBufferIndex = y * rosesize + x;
if (!zBuffer[zBufferIndex] || zBuffer[zBufferIndex] > z)
{
zBuffer[zBufferIndex] = z;
// 画点
int r = ~int((dot.r * h)); if (r < 0) r = 0; if (r > 255) r = 255;
int g = ~int((dot.g * h)); if (g < 0) g = 0; if (g > 255) g = 255;
int b = ~int((dot.r * dot.r * -80)); if (b < 0) b = 0; if (b > 255) b = 255;
putpixel(x + 50, y - 20, RGB(r, g, b));
}
}
Sleep(1);
}
// 退出
delete[]zBuffer;
_getch();
closegraph();
}
7. 奥特曼
#include<conio.h>
#include<graphics.h>
#include<math.h>
#define PI acos(-1.0)
double th = PI / 180;
// 绘制斜的椭圆
void DrawEllipse(int x0, int y0, int a, int b, int k, int color);
// 绘制心形
void heart(int x0, int y0, int size, COLORREF C);
int main()
{
initgraph(640, 640);
setbkcolor(WHITE);
cleardevice();
// 设置线的宽度
setlinestyle(PS_SOLID, 5);
setlinecolor(BLACK);
setfillcolor(RGB(238, 238, 238));
// 左耳朵
fillrectangle(175, 266, 190, 325);
fillrectangle(159, 281, 175, 315);
// 右耳朵
fillrectangle(393, 268, 410, 324);
fillrectangle(410, 286, 423, 311);
fillellipse(187, 196, 397, 402);
setfillcolor(WHITE);
fillroundrect(288, 146, 302, 242, 10, 20);
// 绘制左右眼睛
DrawEllipse(243, 297, 38, 30, -30, BLACK);
DrawEllipse(350, 297, 38, 30, 30, BLACK);
setfillcolor(RGB(248, 245, 143));
floodfill(243, 297, BLACK);
floodfill(350, 297, BLACK);
line(296, 422, 249, 394);
line(296, 422, 336, 394);
setfillcolor(RGB(235, 110, 69));
floodfill(295, 410, BLACK);
setfillcolor(RGB(137, 211, 211));
fillcircle(294, 432, 10);
// 绘制身体
arc(222, 399, 286, 591, 145.0 / 180 * PI, PI + 145.0 / 180 * PI);
arc(305, 413, 364, 591, PI + 35.0 / 180 * PI, 55.0 / 180 * PI);
line(224, 485, 359, 485);
line(224, 511, 278, 549);
line(278, 549, 312, 549);
line(312, 549, 360, 515);
setfillcolor(RGB(235, 110, 69));
floodfill(294, 517, BLACK);
setfillcolor(RGB(238, 238, 238));
floodfill(252, 554, BLACK);
floodfill(334, 559, BLACK);
// 绘制左边胳膊
arc(189, 387, 353, 647, 109.0 / 180 * PI, PI);
arc(189, 480, 223, 537, 10.0 / 180.0 * PI + PI, 0);
line(196, 471, 222, 491);
setfillcolor(RGB(235, 110, 69));
floodfill(207, 501, BLACK);
// 绘制右胳膊
arc(230, 319, 424, 455, 110.0 / 180 * PI + PI, 5.0 / 180 * PI);
arc(392, 360, 424, 395, -5.0 / 180 * PI, PI + PI / 2);
arc(310, 286, 402, 394, 70.0 / 180 * PI + PI, 150.0 / 180 * PI + PI);
line(372, 390, 394, 431);
setfillcolor(RGB(235, 110, 69));
floodfill(399, 402, BLACK);
// 给身体颜色
setfillcolor(RGB(238, 238, 238));
floodfill(296, 458, BLACK);
// 连接气球
line(463, 187, 422, 365);
heart(464, 67, 30, BLACK);
setfillcolor(RGB(235, 110, 69));
floodfill(464, 70, BLACK);
setfillcolor(RGB(255, 232, 201));
solidcircle(508, 70, 6);
_getch();
return 0;
}
void heart(int x0, int y0, int size, COLORREF C)
{
double m, n, x, y;
double i;
for (i = 0; i <= 2 * size; i = i + 0.01)
{
// 产生极坐标点
m = i;
n = -size * (((sin(i) * sqrt(fabs(cos(i)))) / (sin(i) + 1.4142)) - 2 * sin(i) + 2);
// 转换为笛卡尔坐标
x = n * cos(m) + x0;
y = n * sin(m) + y0;
setfillcolor(C);
solidcircle((int)x, (int)y, 2);
}
}
void DrawEllipse(int x0, int y0, int a, int b, int k, int color)
{
double i;
double x, y, tx, ty;
for (i = -180; i <= 180; i = i + 0.5)
{
x = a * cos(i * th);
y = b * sin(i * th);
tx = x;
ty = y;
x = tx * cos(k * th) - ty * sin(k * th) + x0;
y = y0 - (ty * cos(k * th) + tx * sin(k * th));
setfillcolor(color);
solidcircle((int)x, (int)y, 2);
}
}
三、更多项目资源
若大家有什么有趣的想法或设计 可留言评论区 或 私信即可