07.绘制卡通头像

#include #include #define PI 3.14int main(){initgraph(1024, 1024);//设置背景色为白色setbkcolor(WHITE);//使用当前背景色清空窗体cleardevice();//设置描边颜色为黑色,描边线形为实线,粗细为10setlinecolor(BLACK);setlinestyle(PS_SOLID, 10);//绘制头部//设置填充颜色为蓝色setfillcolor(BLUE);fillellipse(118, 125, 990, 931);Sleep(1000);//绘制脸//设置填充颜色为白色setfillcolor(WHITE);fillellipse(189, 271, 919, 931);Sleep(1000);//绘制一对眼睛fillellipse(375, 170, 555, 420);fillellipse(555, 170, 735, 420);Sleep(1000);//绘制一对瞳孔setfillcolor(BLACK);solidcircle(484, 333, 25);solidcircle(617, 333, 25);Sleep(1000);//绘制一对高光setfillcolor(WHITE);solidcircle(484, 333, 10);solidcircle(617, 333, 10);Sleep(1000);//绘制鼻子及竖线setfillcolor(RED);fillcircle(554, 420, 35);line(554, 460, 554, 828);Sleep(1000);//嘴巴arc(320, 510, 789, 827, PI, 2 * PI);Sleep(1000);//胡须line(125, 313, 296, 410);line(83, 444, 270, 474);line(83, 595, 262, 527);line(819, 414, 990, 320);line(845, 478, 1029, 448);line(853, 542, 1029, 660);getchar();closegraph();return 0;}

09.绘制显示器

#include #include int main(){initgraph(800, 600);setbkcolor(WHITE);cleardevice();//1.银色圆角矩形setfillcolor(RGB(232, 235, 240));solidroundrect(100, 50, 700, 450, 20, 20);//2.蓝黑色矩形setfillcolor(RGB(71, 78, 94));solidrectangle(100, 390, 700, 410);//3.蓝黑色圆角矩形solidroundrect(100, 50, 700, 410, 20, 20);//4.天蓝色矩形屏幕setfillcolor(RGB(115, 199, 235));solidrectangle(120, 70, 680, 390);//5.银色圆形摄像头setfillcolor(RGB(232, 235, 240));solidcircle(400, 60, 5);//6.蓝黑色圆形开机键setfillcolor(RGB(71, 78, 94));solidcircle(400, 430, 12);//7.深灰色椭圆底座setfillcolor(RGB(218, 219, 224));solidellipse(275, 515, 525, 545);//8.银色梯形支架setfillcolor(RGB(232, 235, 240));POINT bigTrapezoid[4] = { {345, 450}, {455, 450}, {475, 530}, {325, 530} };solidpolygon(bigTrapezoid, 4);//9.深灰色梯形阴影setfillcolor(RGB(218, 219, 224));POINT smallTrapezoid[4] = { {345, 450}, {455, 450}, {460, 470}, {340, 470} };solidpolygon(smallTrapezoid, 4);getchar();closegraph();return 0;}

11.绘制卡通熊

#include #include 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;}

14.直线运动

#include #include #include void LinearMotion(int x1, int y1, int x2, int y2, int v){//速度分量double vy;double vx;//根据运动类型,计算速度分量大小if (y2 == y1){//水平运动vx = v;vy = 0;}else if (x2 == x1){//垂直运动vx = 0;vy = v;}else{//其他运动//计算角度θ的正切tanThetadouble tanTheta = (double)abs(y2 - y1) / (double)abs(x2 - x1);//已知tanTheta,根据反三角函数计算角度θdouble theta = atan(tanTheta);//计算速度分量vy = sin(theta) * v;vx = cos(theta) * v;}//根据速度方向的正负,求得速度分量的符号int vxFlag = 0;int vyFlag = 0;if (x2 - x1 > 0)vxFlag = 1;else if (x2 - x1  0)vyFlag = 1;else if (y2 - y1 = x2)break;}else if (vxFlag == -1){//符号为负,直到小于等于终止点x2坐标为止if (x = y2)break;}else if (vyFlag == -1){//符号为负,直到小于等于终止点y2坐标为止if (y P2(200, -200)->P3(-200, -200)->P1(0, 200)LinearMotion(0, 200, 200, -200, 5);LinearMotion(200, -200, -200, -200, 5);LinearMotion(-200, -200, 0, 200, 5);//三角形(P4, P5, P6)//P4(0, -200)->P5(-200, 200)->P6(200, 200)->P4(0, -200)LinearMotion(0, -200, -200, 200, 5);LinearMotion(-200, 200, 200, 200, 5);LinearMotion(200, 200, 0, -200, 5);//矩形(P5, P6, P2, P3)//P5(-200, 200)->P6(200, 200)->P2(200, -200)->P3(-200, -200)->P5(-200, 200)LinearMotion(-200, 200, 200, 200, 5);LinearMotion(200, 200, 200, -200, 5);LinearMotion(200, -200, -200, -200, 5);LinearMotion(-200, -200, -200, 200, 5);getchar();closegraph();return 0;}

15.弹球小游戏

#include #include #include #include typedef struct {//圆心坐标int x, y;//速度分量int vx, vy;//小球半径int r;//挡板左边、顶边、右边、底边坐标int barLeft, barTop, barRight, barBottom;}GameData;void reset(GameData* gdata){gdata->x = rand() % (400 + 1) - 200;gdata->y = rand() % (300 + 1) - 150;gdata->vx = 5;gdata->vy = 5;if (rand() % 2 == 0){gdata->vy = -gdata->vy;}if (rand() % 2 == 0){gdata->vx = -gdata->vx;}gdata->r = 40;gdata->barLeft = -150;gdata->barRight = 150;gdata->barTop = -280;gdata->barBottom = -300;}int main(){initgraph(800, 600);//坐标系原点在窗体中心,X轴正方向向右,Y轴正方向向上setorigin(400, 300);setaspectratio(1, -1);//设置背景色setbkcolor(RGB(164, 225, 202));//使用背景色清空窗体cleardevice();//当前时间作为随机数种子srand((unsigned int)time(NULL));//游戏数据GameData gdata;//初始化游戏数据reset(&gdata);while (1){cleardevice();//绘制小球solidcircle(gdata.x, gdata.y, gdata.r);//绘制挡板solidrectangle(gdata.barLeft, gdata.barTop, gdata.barRight, gdata.barBottom);//每帧之间休眠40msSleep(40);//撞击或越过顶边反弹if (gdata.y >= 300 - gdata.r){gdata.vy = -gdata.vy;}//撞击或越过左、右边反弹if (gdata.x = 400 - gdata.r){gdata.vx = -gdata.vx;}//撞击或越过挡板后反弹if (gdata.barLeft <= gdata.x && gdata.x <= gdata.barRight && gdata.y  -400){gdata.barLeft -= 20;gdata.barRight -= 20;}}else if (c == 'd'){if (gdata.barRight < 400){gdata.barLeft += 20;gdata.barRight += 20;}}}if (gdata.y <= -300){//重置游戏初始数据reset(&gdata);}}closegraph();return 0;}

16.贪吃蛇

#include #include #include #include #define NODE_WIDTH 40//节点typedef struct {int x;int y;}node;//绘制网格//横线(0, y), (800, y) 0 <= y <= 600//竖线(x, 0),(x, 600)0 <= x <= 800void paintGrid(){//横线for (int y = 0; y < 600; y += NODE_WIDTH){line(0, y, 800, y);}//竖线for (int x = 0; x < 800; x += NODE_WIDTH){line(x, 0, x, 600);}}void paintSnake(node* snake, int n){int left, top, right, bottom;for (int i = 0; i < n; i++){//左上角:【网格x坐标 * 网格宽度, 网格y坐标 * 网格宽度】left = snake[i].x * NODE_WIDTH;top = snake[i].y * NODE_WIDTH;//右下角:【(网格x坐标 + 1) * 网格宽度, (网格y坐标 + 1) * 网格宽度】right = (snake[i].x + 1) * NODE_WIDTH;bottom = (snake[i].y + 1) * NODE_WIDTH;//通过左上角与右下角坐标绘制矩形solidrectangle(left, top, right, bottom);}}//方向枚举enum direction{eUp,eDown,eLeft,eRight};//蛇身体移动node snakeMove(node* snake, int length, int direction){//for (int i = 0; i  E E D C Bfor (int i = length - 1; i > 0; i--){snake[i] = snake[i - 1];}//下一个头节点node newHead;newHead = snake[0];if (direction == eUp){newHead.y--;}else if (direction == eDown){newHead.y++;}else if (direction == eLeft){newHead.x--;}else //right{newHead.x++;}//更新头节点//E D C B A ---> F E D C Bsnake[0] = newHead;//for (int i = 0; i < length; i++)//printf("(%d, %d)\n", snake[i].x, snake[i].y);//返回尾节点return tail;}//键盘输入改变directionvoid changeDirection(enum direction* pD){//检查输入缓存区中是否有数据if (_kbhit() != 0){//_getch函数获取输入缓存区中的数据char c = _getch();//判断输入并转向switch (c){case 'w'://向上移动if (*pD != eDown)*pD = eUp;break;case 's'://向下移动if (*pD != eUp)*pD = eDown;break;case 'a'://向左移动if (*pD != eRight)*pD = eLeft;break;case 'd'://向右移动if (*pD != eLeft)*pD = eRight;break;}}}//绘制食物/*(x * NODE_WIDTH, y * NODE_WIDTH)@-----------||||||||||-----------@ ((x + 1) * NODE_WIDTH, (y + 1) * NODE_WIDTH)*/void paintFood(node food){int left, top, right, bottom;left = food.x * NODE_WIDTH;top = food.y * NODE_WIDTH;right = (food.x + 1) * NODE_WIDTH;bottom = (food.y + 1) * NODE_WIDTH;setfillcolor(YELLOW);solidrectangle(left, top, right, bottom);setfillcolor(WHITE);}//随机创建食物node createFood(node* snake, int length){node food;while (1){food.x = rand() % (800 / NODE_WIDTH);food.y = rand() % (600 / NODE_WIDTH);int i;for (i = 0; i < length; i++){if (snake[i].x == food.x && snake[i].y == food.y){break;}}if (i < length)continue;elsebreak;}return food;}bool isGameOver(node* snake, int length){//是否撞墙if (snake[0].x  800 / NODE_WIDTH)return true;if (snake[0].y  600 / NODE_WIDTH)return true;//是否吃到蛇身for (int i = 1; i < length; i++){if (snake[0].x == snake[i].x && snake[0].y == snake[i].y)return true;}return false;}void reset(node* snake, int* pLength, enum direction* d){snake[0] = node{ 5, 7 };snake[1] = node{ 4, 7 };snake[2] = node{ 3, 7 };snake[3] = node{ 2, 7 };snake[4] = node{ 1, 7 };*pLength = 5;*d = eRight;}int main(){initgraph(800, 600);//设置背景色setbkcolor(RGB(164, 225, 202));//使用背景色清空窗体cleardevice();//蛇节点坐标node snake[100] = { {5, 7}, {4, 7}, {3, 7}, {2, 7}, {1, 7} };//蛇节点长度int length = 5;enum direction d = eRight;//食物srand(unsigned int(time(NULL)));node food = createFood(snake, length);while (1){//清空整个窗体cleardevice();//绘制网格paintGrid();//绘制蛇节点paintSnake(snake, length);//绘制食物paintFood(food);//休眠500msSleep(500);//获取键盘输入并将方向存储到变量dchangeDirection(&d);node lastTail = snakeMove(snake, length, d);//新的蛇头节点是否与食物节点重合if (snake[0].x == food.x && snake[0].y == food.y){//限制snake节点最大长度if (length < 100){//已经吃到食物, 长度+1snake[length] = lastTail;length++;}//重新生成新的食物food = createFood(snake, length);}//游戏是否结束if (isGameOver(snake, length) == true){//游戏结束,复位设置,重新生成食物reset(snake, &length, &d);food = createFood(snake, length);}}getchar();closegraph();return 0;}

17.多物体运动

#include #include #include #define NUM_OF_BALLS 1000#define PI 3.14typedef struct {int x;int y;int vx;int vy;COLORREF color;}ball;int main(){initgraph(800, 600);//坐标系原点在窗体中心,X轴正方向向右,Y轴正方向向上setorigin(400, 300);setaspectratio(1, -1);//设置背景色setbkcolor(WHITE);//设置描边颜色setlinecolor(BLACK);//使用背景色清空窗体cleardevice();int r = 10;ball* balls = (ball*)malloc(sizeof(ball) * NUM_OF_BALLS);if (balls == NULL){return -1;}for (int i = 0; i < NUM_OF_BALLS; i++){int m, n;//圆心x坐标区间:[-400 + r, 400 - r]m = -400 + r;n = 400 - r;balls[i].x = rand() % (n - m + 1) + m;//圆心y坐标区间:[-300 + r, 300 - r]m = -300 + r;n = 300 - r;balls[i].y = rand() % (n - m + 1) + m;//随机颜色,色相随机,饱和度为80%,明度为90%balls[i].color = HSVtoRGB((float)(rand() % 360), 0.8f, 0.9f);//随机速度大小[3, 8],速度方向与x方向夹角[0, 359]m = 3;n = 8;int v = rand() % (n - m + 1) + m;double theta;theta = rand() % 360;balls[i].vx = v * cos(theta * PI / 180);balls[i].vy = v * sin(theta * PI / 180);}while (1){//清空画面cleardevice();//绘制多个小球for (int i = 0; i < NUM_OF_BALLS; i++){setfillcolor(balls[i].color);fillcircle(balls[i].x, balls[i].y, r);}Sleep(40);//遍历所有小球,若碰到或越过边界,则反弹for (int i = 0; i = 300 - r || balls[i].y <= -300 + r){balls[i].vy = -balls[i].vy;}//碰到或越过左右边界反弹if (balls[i].x = 400 - r){balls[i].vx = -balls[i].vx;}//小球移动位置balls[i].x += balls[i].vx;balls[i].y += balls[i].vy;}}closegraph();return 0;}

18.批量绘图

#include #include #include #define NUM_OF_BALLS 1000#define PI 3.14typedef struct {int x;int y;int vx;int vy;COLORREF color;}ball;int main(){initgraph(800, 600);//坐标系原点在窗体中心,X轴正方向向右,Y轴正方向向上setorigin(400, 300);setaspectratio(1, -1);//设置背景色setbkcolor(WHITE);//设置描边颜色setlinecolor(BLACK);//使用背景色清空窗体cleardevice();int r = 10;ball* balls = (ball*)malloc(sizeof(ball) * NUM_OF_BALLS);if (balls == NULL){return -1;}for (int i = 0; i < NUM_OF_BALLS; i++){int m, n;//圆心x坐标区间:[-400 + r, 400 - r]m = -400 + r;n = 400 - r;balls[i].x = rand() % (n - m + 1) + m;//圆心y坐标区间:[-300 + r, 300 - r]m = -300 + r;n = 300 - r;balls[i].y = rand() % (n - m + 1) + m;//随机颜色,色相随机,饱和度为80%,明度为90%balls[i].color = HSVtoRGB((float)(rand() % 360), 0.8f, 0.9f);//随机速度大小[3, 8],速度方向与x方向夹角[0, 359]m = 3;n = 8;int v = rand() % (n - m + 1) + m;double theta;theta = rand() % 360;balls[i].vx = v * cos(theta * PI / 180);balls[i].vy = v * sin(theta * PI / 180);}//开始批量绘图BeginBatchDraw();while (1){//清空画面cleardevice();//绘制多个小球for (int i = 0; i < NUM_OF_BALLS; i++){setfillcolor(balls[i].color);fillcircle(balls[i].x, balls[i].y, r);}//显示累积的1000个小球,为一帧画面FlushBatchDraw();Sleep(40);//遍历所有小球,若碰到或越过边界,则反弹for (int i = 0; i = 300 - r || balls[i].y <= -300 + r){balls[i].vy = -balls[i].vy;}//碰到或越过左右边界反弹if (balls[i].x = 400 - r){balls[i].vx = -balls[i].vx;}//小球移动位置balls[i].x += balls[i].vx;balls[i].y += balls[i].vy;}}//结束批量绘图EndBatchDraw();closegraph();return 0;}

19.图片

#include #include int main(){initgraph(1200, 480);IMAGE img;loadimage(&img, "background.jpg");putimage(0, 0, &img);IMAGE imgBear;loadimage(&imgBear, "bear.png");putimage(530, 180, &imgBear);getchar();closegraph();}

20.透明图片

#include #include int main(){initgraph(1200, 480);//背景图片IMAGE imgBackground;loadimage(&imgBackground, "./background.jpg");//白背景的黑剪影IMAGE imgMask;loadimage(&imgMask, "./mask.jpg");//黑背景的熊本体IMAGE imgBear;loadimage(&imgBear, "./bear.jpg");//背景图片绘制到窗体上putimage(0, 0, &imgBackground);//mask.jpg与窗体中图像进行与运算putimage(530, 180, &imgMask, SRCAND);//bear.jpg与窗体中图像进行与运算putimage(530, 180, &imgBear, SRCPAINT);getchar();closegraph();}

21.让熊跑起来

#define _CRT_SECURE_NO_WARNINGS#include #include #include #define BEAR_FRAMES 11void putTransparentImage(int x, int y, const IMAGE* mask, const IMAGE* img){putimage(x, y, mask, SRCAND);putimage(x, y, img, SRCPAINT);}int main(){initgraph(1200, 480);//设置背景色setbkcolor(WHITE);//使用背景色清空窗体cleardevice();IMAGE imgBackground;loadimage(&imgBackground, "background.jpg");// load imagesIMAGE imgArrBearFrames[BEAR_FRAMES];for (int i = 0; i < BEAR_FRAMES; i++){char strImgPath[100];sprintf(strImgPath, "bear/frames/bear%d.png", i);loadimage(&imgArrBearFrames[i], strImgPath);}// load masksIMAGE imgArrBearMasks[BEAR_FRAMES];for (int i = 0; i = BEAR_FRAMES)frame = 0;if (x >= 1200 + 150)x = -150;Sleep(50);}EndBatchDraw();getchar();closegraph();return 0;}

23.精确帧率控制

#include #include int main(){//提高系统定时器时钟分辨率为1毫秒timeBeginPeriod(1);initgraph(800, 600);setbkcolor(RGB(164, 225, 202));cleardevice();setfillcolor(WHITE);//开始时间、结束时间、频率FLARGE_INTEGER startCount, endCount, F;//获取频率FQueryPerformanceFrequency(&F);int x = 0, y = 300;int vx = 5;BeginBatchDraw();while (1){//获取起始计数QueryPerformanceCounter(&startCount);//准备画面cleardevice();solidcircle(x, y, 50);x = x + vx;if (x = 800)vx = -vx;//获取结束计数QueryPerformanceCounter(&endCount);//计算时差long long elapse = (endCount.QuadPart - startCount.QuadPart)/ F.QuadPart * 1000000;//时差若小于40000,则一直循环,直到时差大于等于40000//注意这里的单位是微秒while (elapse < 40000){//先休眠一小会,再检查是否超时Sleep(1);//重新获取结束时间QueryPerformanceCounter(&endCount);//更新时差elapse = (endCount.QuadPart - startCount.QuadPart)* 1000000 / F.QuadPart;}//绘制画面FlushBatchDraw();}EndBatchDraw();closegraph();//timeBeginPeriod与timeEndPeriod必须成对存在,并且传一样的值timeEndPeriod(1);return 0;}

25.打气球

#include #include #include #define WINDOW_WIDTH 800#define WINDOW_HEIGHT 600#define MAX_IN_WINDOW 5#define BALLOON_RADIUS 30typedef struct {int x;int y;int r;int v;COLORREF color;}balloon;balloon generateBalloon(){balloon b;//x坐标在区间[100, 700]之间int m, n;m = 100;n = 700;b.x = rand() % (n - m + 1) + m;//y坐标在窗口底部b.y = WINDOW_HEIGHT;//半径为符号常量BALLOON_RADIUSb.r = BALLOON_RADIUS;//速度在区间[1, 3]之间m = 1;n = 3;b.v = rand() % (n - m + 1) + m;//颜色RGB值随机b.color = RGB(rand() % 256, rand() % 256, rand() % 256);return b;}int main(){//创建一个宽度为WINDOW_WIDTH、高度为WINDOW_HEIGHT的窗体,并用白色背景色刷新窗体。initgraph(WINDOW_WIDTH, WINDOW_HEIGHT);setbkcolor(WHITE);cleardevice();//气球数组balloon arrBalloons[MAX_IN_WINDOW];//给气球数组赋值for (int i = 0; i < MAX_IN_WINDOW; i++)arrBalloons[i] = generateBalloon();//当前出现的气球数int current = MAX_IN_WINDOW;//鼠标位置int mouseX = 0, mouseY = 0;timeBeginPeriod(1);LARGE_INTEGER startCount, endCount, F;QueryPerformanceFrequency(&F);BeginBatchDraw();while (1){QueryPerformanceCounter(&startCount);//清空窗体cleardevice();//绘制并移动气球for (int i = 0; i < MAX_IN_WINDOW; i++){//绘制气球setfillcolor(arrBalloons[i].color);solidcircle(arrBalloons[i].x, arrBalloons[i].y, arrBalloons[i].r);}//移动气球for (int i = 0; i < MAX_IN_WINDOW; i++)arrBalloons[i].y -= arrBalloons[i].v;//删除已飞出窗体外的气球int i = 0;while (i < current){int y = arrBalloons[i].y;//是否已飞出窗体外if (y < -BALLOON_RADIUS){//依次使用后续元素覆盖前驱元素,直到最后一个有效元素为止for (int j = i; j < current - 1; j++)arrBalloons[j] = arrBalloons[j + 1];//当前气球数减1current--;}else{//数组元素未被删除,i才能自增1i++;}}//增加新气球if (current < MAX_IN_WINDOW){//气球数组中追加一个气球arrBalloons[current] = generateBalloon();//当前气球数加1current++;}//绘制准心//设置描边颜色为RGB(237, 178, 29)setlinecolor(RGB(237, 178, 29));//线段样式为实线、线段宽度为3setlinestyle(PS_SOLID, 3);//绘制半径为20的描边圆circle(mouseX, mouseY, 20);//绘制十字line(mouseX - 20, mouseY, mouseX + 20, mouseY);line(mouseX, mouseY - 20, mouseX, mouseY + 20);QueryPerformanceCounter(&endCount);long long elapse = (endCount.QuadPart - startCount.QuadPart)* 1000000 / F.QuadPart;//每秒帧率设置为60,因此最长等待时间为1000000 / 60while (elapse < 1000000 / 60){Sleep(1);//获取鼠标消息ExMessage msg;bool isOk = peekmessage(&msg, EX_MOUSE);//是否有新消息,没有则无需处理消息if (isOk == true){//如果是鼠标移动消息,则更新鼠标位置if (msg.message == WM_MOUSEMOVE){mouseX = msg.x;mouseY = msg.y;}//如果是鼠标点击消息,则判断是否点击到气球,点击到将气球删除else if (msg.message == WM_LBUTTONDOWN){//检查哪个气球被点击到int i = 0;while (i < current){int ballX = arrBalloons[i].x;int ballY = arrBalloons[i].y;int distance = (int)sqrt(pow(ballY - msg.y, 2) + pow(ballX - msg.x, 2));//是否鼠标与气球的圆心距离小于半径if (distance < BALLOON_RADIUS){//依次使用后续元素覆盖前驱元素,直到移动完最后一个有效元素为止for (int j = i; j < current - 1; j++)arrBalloons[j] = arrBalloons[j + 1];//当前气球数减1current--;}else{//数组元素未被删除,i才能自增1i++;}}}}QueryPerformanceCounter(&endCount);elapse = (endCount.QuadPart - startCount.QuadPart)* 1000000 / F.QuadPart;}//批量显示FlushBatchDraw();}EndBatchDraw();timeEndPeriod(1);closegraph();return 0;}

26.音频

#include #include int main(){// 打开音乐mciSendString("open 起床歌.mp3", NULL, 0, NULL);printf("打开音乐");getchar();// 开始播放mciSendString("play 起床歌.mp3", NULL, 0, NULL);printf("开始播放");getchar();// 暂停播放mciSendString("pause 起床歌.mp3", NULL, 0, NULL);printf("暂停播放");getchar();// 继续播放mciSendString("resume 起床歌.mp3", NULL, 0, NULL);printf("继续播放");getchar();// 停止播放mciSendString("stop 起床歌.mp3", NULL, 0, NULL);printf("停止播放");getchar();// 关闭音乐mciSendString("close 起床歌.mp3", NULL, 0, NULL);printf("关闭音乐");getchar();}

27

(1)封装

#define _CRT_SECURE_NO_WARNINGS#include #include #include struct student {void (*setStudentId)(struct student* s, int year, int classNum, int serialNum);const char* (*getGender)(struct student* s);void (*setGender)(struct student* s, const char* strGender);int id; //学号char name[20];//姓名int gender; //性别int mark; //分数};void setStudentId(struct student* s, int year, int classNum, int serialNum){char buffer[20];sprintf(buffer, "%d%d%d", year, classNum, serialNum);int id = atoi(buffer);s->id = id;}const char* getGender(struct student* s){if (s->gender == 0){return "女";}else if (s->gender == 1){return "男";}return "未知";}void setGender(struct student* s, const char* strGender){int numGender;if (strcmp("男", strGender) == 0){numGender = 1;}else if (strcmp("女", strGender) == 0){numGender = 0;}else{numGender = -1;}s->gender = numGender;}void initStudent(struct student* s){s->setStudentId = setStudentId;s->getGender = getGender;s->setGender = setGender;}int main(){struct student stu;//初始化studentinitStudent(&stu);//学号:202212326//姓名:小明//性别: 男//分数:98stu.setStudentId(&stu, 2022, 123, 26);strcpy(stu.name, "小明");stu.setGender(&stu, "男");stu.mark = 98;//打印这些数值printf("学号:%d\n", stu.id);printf("姓名:%s\n", stu.name);const char* gender = stu.getGender(&stu);printf("性别:%s\n", gender);printf("分数:%d\n", stu.mark);return 0;}

(2)继承

#define _CRT_SECURE_NO_WARNINGS#include #include #include struct person {int id; //编号char name[20];//姓名int gender; //性别//设置性别void (*setGender)(struct person* s, const char* strGender);//获取性别const char* (*getGender)(struct person* s);};struct teacher {struct person super;char subject[20]; //任课科目};struct student {struct person super;int mark; //分数//设置学号void (*setStudentId)(struct student* s, int year, int classNum, int serialNum);};const char* getGender(struct person* p){if (p->gender == 0){return "女";}else if (p->gender == 1){return "男";}return "未知";}void setGender(struct person* p, const char* strGender){int numGender;if (strcmp("男", strGender) == 0){numGender = 1;}else if (strcmp("女", strGender) == 0){numGender = 0;}else{numGender = -1;}p->gender = numGender;}void setStudentId(struct student* s, int year, int classNum, int serialNum){char buffer[20];sprintf(buffer, "%d%d%d", year, classNum, serialNum);int id = atoi(buffer);s->super.id = id; //由s->id = id 修改为 s->super.id = id}void initPerson(struct person* p){p->getGender = getGender;p->setGender = setGender;}void initStudent(struct student* s){initPerson(&(s->super));s->setStudentId = setStudentId;}void initTeacher(struct teacher* t){initPerson(&(t->super));}int main(){struct student stu;//初始化studentinitStudent(&stu);//学号:202212326//姓名:小明//性别: 男//分数:98stu.setStudentId(&stu, 2022, 123, 26);strcpy(stu.super.name, "小明");stu.super.setGender(&stu.super, "男");stu.mark = 98;//打印这些数值printf("学号:%d\n", stu.super.id);printf("姓名:%s\n", stu.super.name);const char* gender = stu.super.getGender(&stu.super);printf("性别:%s\n", gender);printf("分数:%d\n", stu.mark);putchar('\n');struct teacher t;//初始化teacherinitTeacher(&t);//工号:12345//姓名:林老师//性别: 男//科目:C语言t.super.id = 12345;strcpy(t.super.name, "林老师");t.super.setGender(&t.super, "男");strcpy(t.subject, "C语言");//打印这些数值printf("学号:%d\n", t.super.id);printf("姓名:%s\n", t.super.name);gender = t.super.getGender(&t.super);printf("性别:%s\n", gender);printf("科目:%s\n", t.subject);return 0;}

28.多态

#include #include struct Shape {void (*draw)(struct Shape*);};struct Rect {struct Shape super;int left;int top;int right;int bottom;};struct Circle {struct Shape super;int x;int y;int r;};struct Triangle {struct Shape super;POINT p1;POINT p2;POINT p3;};void drawRect(struct Rect* r){rectangle(r->left, r->top, r->right, r->bottom);}void drawCircle(struct Circle* c){circle(c->x, c->y, c->r);}void drawTriangle(struct Triangle* t){line(t->p1.x, t->p1.y, t->p2.x, t->p2.y);line(t->p2.x, t->p2.y, t->p3.x, t->p3.y);line(t->p3.x, t->p3.y, t->p1.x, t->p1.y);}void initRect(struct Rect* r){r->super.draw = (void (*)(struct Shape*))drawRect;}void initCircle(struct Circle* c){c->super.draw = (void (*)(struct Shape*))drawCircle;}void initTriangle(struct Triangle* t){t->super.draw = (void (*)(struct Shape*))drawTriangle;}int main(){initgraph(800, 600);setaspectratio(1, -1);setorigin(400, 300);setbkcolor(WHITE);setlinecolor(BLACK);cleardevice();struct Rect r = { {}, -200, 200, 200, 0 };struct Circle c = { {}, 0, 0, 100 };struct Triangle t = { {},{0, 200}, {-200, 0}, {200, 0} };initRect(&r);initCircle(&c);initTriangle(&t);struct Shape* arrShape[3] = {(struct Shape*)&r, (struct Shape*)&c, (struct Shape*)&t };for (int i = 0; i draw(arrShape[i]);}getchar();closegraph();return 0;}

30.动态数组

main.c

#define _CRT_SECURE_NO_WARNINGS#include "vector.h"#include #include #include struct student {int id; //学号char name[20];//姓名int gender; //性别int mark; //成绩};int main(){struct vector vec;vectorInit(&vec);//appendstruct student* s1 = (struct student*)malloc(sizeof(struct student));s1->id = 1;strcpy(s1->name, "小明");s1->gender = 1;s1->mark = 90;vec.append(&vec, s1);for (int i = 0; i id, s->name, s->gender, s->mark);}printf("size:%d\n", vec.size);printf("capacity:%d\n", vec.capacity);getchar();//append追加struct student* s2 = (struct student*)malloc(sizeof(struct student));s2->id = 2;strcpy(s2->name, "小红");s2->gender = 0;s2->mark = 95;vec.append(&vec, s2);for (int i = 0; i id, s->name, s->gender, s->mark);}printf("size:%d\n", vec.size);printf("capacity:%d\n", vec.capacity);getchar();//remove//别忘记销毁小明的数据free(vec.get(&vec, 0));vec.remove(&vec, 0);for (int i = 0; i id, s->name, s->gender, s->mark);}printf("size:%d\n", vec.size);printf("capacity:%d\n", vec.capacity);for (int i = 0; i < vec.size; i++){struct student* s = vec.get(&vec, i);free(s);}getchar();//clearvec.clear(&vec);for (int i = 0; i id, s->name, s->gender, s->mark);}printf("size:%d\n", vec.size);printf("capacity:%d\n", vec.capacity);getchar();//销毁数组vectorDestroy(&vec);return 0;}

vector.h

#pragma once#include #define VECTOR_INIT_CAPACITY 10struct vector {bool (*append)(struct vector* pVec, void* data);void* (*get)(struct vector* pVec, int index);void (*clear)(struct vector* pVec);void (*remove)(struct vector* pVec, int index);void** pData;int size;int capacity;};void vectorInit(struct vector*);void vectorDestroy(struct vector* pVec);

vector.c

#include "vector.h"#include bool vectorAppend(struct vector* pVec, void* data){if (pVec == NULL || data == NULL)return false;//是否超长if (pVec->size >= pVec->capacity){//加长到两倍void** newData = (void**)realloc(pVec->pData, pVec->capacity * sizeof(void*) * 2);if (newData == NULL){return false;}pVec->pData = newData;pVec->capacity = 2 * pVec->capacity;}pVec->pData[pVec->size] = data;pVec->size++;return true;}void* vectorGet(struct vector* pVec, int index){if (index >= pVec->size)return NULL;return pVec->pData[index];}void vectorRemove(struct vector* pVec, int index){for (int i = index; i size - 1; i++)pVec->pData[i] = pVec->pData[i + 1];pVec->size -= 1;}void vectorClear(struct vector* pVec){if (pVec->pData != NULL)free(pVec->pData);pVec->pData = (void**)malloc(sizeof(void*) * VECTOR_INIT_CAPACITY);pVec->capacity = VECTOR_INIT_CAPACITY;pVec->size = 0;}void vectorInit(struct vector* pVec){pVec->get = vectorGet;pVec->append = vectorAppend;pVec->remove = vectorRemove;pVec->clear = vectorClear;//初始情况下申请VECTOR_INIT_CAPACITY个elementpVec->pData = (void**)malloc(sizeof(void*) * VECTOR_INIT_CAPACITY);pVec->capacity = VECTOR_INIT_CAPACITY;pVec->size = 0;}void vectorDestroy(struct vector* pVec){if (pVec->pData == NULL)return;free(pVec->pData);pVec->pData = NULL;pVec->size = 0;pVec->capacity = 0;}