适合刚入门C语言的编程学习小白的十个练手项目,每个都很经典且实用,让你学完C语言不再迷茫!
一、多关卡推箱子主要考察知识点:数组
开发工具:Visual Studio2019、EasyX图形库
效果图:
完整代码:
#include二、扫雷#include #include #include #include #pragma comment(lib,"winmm.lib") //静态库资源 //用三维数组特定的数字描绘出这个地图 int cas = 0; int map[4][8][8] = { 1,1,1,1,1,1,1,1, 1,3,4,0,0,4,3,1, 1,0,1,3,0,1,0,1, 1,0,1,4,0,1,0,1, 1,0,0,5,0,0,0,1, 1,0,1,0,0,1,0,1, 1,3,4,0,0,4,3,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,3,4,0,0,4,3,1, 1,0,1,3,0,1,0,1, 1,0,1,4,0,1,0,1, 1,3,4,5,0,0,0,1, 1,0,1,0,0,1,0,1, 1,3,4,0,0,4,3,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,3,4,0,0,4,3,1, 1,0,1,3,0,1,0,1, 1,0,1,4,0,1,0,1, 1,3,4,0,0,4,3,1, 1,0,1,0,0,1,0,1, 1,3,4,5,0,4,3,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,3,4,0,0,4,3,1, 1,0,1,3,0,1,3,1, 1,3,1,4,0,1,4,1, 1,4,0,0,0,5,0,1, 1,0,0,0,0,1,0,1, 1,3,4,0,0,4,3,1, 1,1,1,1,1,1,1,1, }; IMAGE img[6]; //6张图片,6个名字 void loadResource() { loadimage(img + 0, "0.bmp", 50, 50); loadimage(img + 1, "1.bmp", 50, 50); loadimage(img + 2, "3.bmp", 50, 50); loadimage(img + 3, "4.bmp", 50, 50); loadimage(img + 4, "5.bmp", 50, 50); loadimage(img + 5, "7.bmp", 50, 50); } //绘制地图 void drawGraph() { for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { //算贴图的坐标 int x = 50 * j; int y = 50 * i; switch (map[cas][i][j]) { case 0: //一个汉字符号占用两个位置 //printf(" "); putimage(x, y, img + 0); break; case 1: putimage(x, y, img + 1); //printf("■"); break; case 3: putimage(x, y, img + 2); //printf("☆"); break; case 4: putimage(x, y, img + 3); //printf("★"); break; case 5: case 8: putimage(x, y, img + 4); //printf("人"); break; case 7: putimage(x, y, img + 5); //printf("●"); break; } } //printf("n"); } } //玩游戏 void keyDown() { int userKey = _getch(); //不可见输入 //定位:找到人的位置 int i = 0; int j = 0; for (i = 1; i < 8; i++) { for (j = 1; j < 8; j++) { if (map[cas][i][j] == 5 || map[cas][i][j] == 8) { goto NEXT; } } } NEXT: //我们这个游戏用什么按键去玩 switch (userKey) { case 'W': case 'w': case 72: if (map[cas][i - 1][j] == 0 || map[cas][i - 1][j] == 3) { map[cas][i][j] -= 5; map[cas][i - 1][j] += 5; } if (map[cas][i - 1][j] == 4 || map[cas][i - 1][j] == 7) { if (map[cas][i - 2][j] == 0 || map[cas][i - 2][j] == 3) { map[cas][i][j] -= 5; map[cas][i - 1][j] += 1; map[cas][i - 2][j] += 4; } } break; case 's': case 'S': case 80: if (map[cas][i + 1][j] == 0 || map[cas][i + 1][j] == 3) { map[cas][i][j] -= 5; map[cas][i + 1][j] += 5; } if (map[cas][i + 1][j] == 4 || map[cas][i + 1][j] == 7) { if (map[cas][i + 2][j] == 0 || map[cas][i + 2][j] == 3) { map[cas][i][j] -= 5; map[cas][i + 1][j] += 1; map[cas][i + 2][j] += 4; } } break; case 'a': case 'A': case 75: if (map[cas][i][j - 1] == 0 || map[cas][i][j - 1] == 3) { //a+=1 a=a+1 复合赋值运算符 map[cas][i][j] -= 5; map[cas][i][j - 1] += 5; } if (map[cas][i][j - 1] == 4 || map[cas][i][j - 1] == 7) { if (map[cas][i][j - 2] == 0 || map[cas][i][j - 2] == 3) { map[cas][i][j] -= 5; map[cas][i][j - 1] += 1; map[cas][i][j - 2] += 4; } } break; case 'd': case 'D': case 77: if (map[cas][i][j + 1] == 0 || map[cas][i][j + 1] == 3) { map[cas][i][j] -= 5; map[cas][i][j + 1] += 5; } if (map[cas][i][j + 1] == 4 || map[cas][i][j + 1] == 7) { if (map[cas][i][j + 2] == 0 || map[cas][i][j + 2] == 3) { map[cas][i][j] -= 5; map[cas][i][j + 1] += 1; map[cas][i][j + 2] += 4; } } break; } } //胜负的判断: int gameOver() { //地图上没有箱子就可以结束 for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { if (map[cas][i][j] == 4) { return 0; } } } return 1; } int main() { loadResource();//定义加载资源函数 mciSendString("open 1.mp3", 0, 0, 0);//加载音乐 mciSendString("play 1.mp3 repeat", 0, 0, 0);//循环播放音乐资源 initgraph(50 * 8, 50 * 8); while (1) { drawGraph(); if (gameOver()) { cas++; //变换关卡 if (cas == 4) break; } keyDown();//循环按下按键 //system("cls"); } closegraph();//关闭窗口 return 0; }
主要考察知识点:数组
开发工具:Visual Studio2019、EasyX图形库
效果图:
完整代码:
#include三、贪吃蛇#include #include #include #include #pragma comment(lib, "winmm.lib") #define ROW 10 //定义行列的常量 #define COL 10 #define MineNum 10 //雷的数量 #define ImgSize 40 //图片的尺寸 //定义图片资源 IMAGE imgs[12]; void loadResource() { for (int i = 0; i < 12; i++) { char imgPath[50] = { 0 }; sprintf_s(imgPath, "./images/%d.jpg", i); loadimage(&imgs[i], imgPath, ImgSize, ImgSize); } } bool isfirst = true; //是不是第一次进来 //函数声明 void show(int map[][COL]); void init(int map[][COL]); void draw(int map[][COL]); void mouseMsg(ExMessage* msg, int map[][COL]); void boomBlank(int map[][COL], int row, int col); int judge(int map[][COL], int row, int col); int main() { //创建窗口 initgraph(400, 400); //播放开始音乐 mciSendString("open ./images/start.mp3 alias bgm", NULL, 0, NULL); mciSendString("play bgm", NULL, 0, NULL); //扫雷地图 int map[ROW][COL] = {0}; init(map); //游戏主循环 while (true) { //处理消息 ExMessage msg; while (peekmessage(&msg, EM_MOUSE)) { switch (msg.message) { case WM_LBUTTONDOWN: //鼠标左键和右键点击 case WM_RBUTTONDOWN: mouseMsg(&msg, map); int ret = judge(map,msg.y/ImgSize, msg.x / ImgSize); //点击之后判断 if (ret == -1) { draw(map); int select = MessageBox(GetHWnd(), "你这么牛,怎么输了呢?敢再来一把吗?", "low B!", MB_OKCANCEL); if (select == IDOK) //再来一把 { //重新初始化 init(map); } else //退出 { exit(0); } } else if(ret == 1) { } system("cls"); printf("judege:%dn", ret); show(map); break; } } draw(map); } //show(map); getchar(); return 0; } void show(int map[][COL]) { for (int i = 0; i < ROW; i++) { for (int k = 0; k < COL; k++) { printf("%2d ", map[i][k]); } printf("n"); } } //初始化数据 void init(int map[][COL]) { loadResource(); //设置随机数种子 srand((unsigned)time(NULL)); //把map全部初始化为0 memset(map, 0, sizeof(int) * ROW * COL); //随机设置十个雷 用-1表示 for (int i = 0; i < MineNum; ) { //数组的有效下标 [0,9] int r = rand() % ROW; int c = rand() % COL; if (map[r][c] == 0) { map[r][c] = -1; //只有执行了这里的代码,才成功设置了雷 -1 i++; } } //把以雷为中心的九宫格数据都+1,雷除外 for (int i = 0; i < ROW; i++) { for (int k = 0; k < COL; k++) { //找到雷,并遍历雷所在的九宫格 if (map[i][k] == -1) { for (int r = i-1; r <= i+1; r++) { for (int c = k-1; c <= k+1; c++) { //对周围的数据加1,会有一个bug if ((r >= 0 && r < ROW && c >= 0 && c < COL) && map[r][c] != -1) { ++map[r][c]; } } } } } } //加密格子 for (int i = 0; i < ROW; i++) { for (int k = 0; k < COL; k++) { map[i][k] += 20; } } } //绘制 void draw(int map[][COL]) { //贴图,根据map里面的数据,贴对应的图片 for (int i = 0; i < ROW; i++) { for (int k = 0; k < COL; k++) { if (map[i][k]>=0 && map[i][k]<=8) //[0,8] { int index = map[i][k]; //0 1 2 3 4 5 6 7 8 putimage(k * ImgSize, i * ImgSize, &imgs[index]); // } else if (map[i][k] == -1) { putimage(k * ImgSize, i * ImgSize, &imgs[9]); } else if (map[i][k] >= 19 && map[i][k] <= 28) { putimage(k * ImgSize, i * ImgSize, &imgs[10]); } else if(map[i][k] >= 39) //-1 + 20 +20 { putimage(k * ImgSize, i * ImgSize, &imgs[11]); } } } } //鼠标操作数据 void mouseMsg(ExMessage* msg,int map[][COL]) { //先根据鼠标点击的坐标求出对应的数组的下标 int r = msg->y / ImgSize; int c = msg->x / ImgSize; //左键打开格子 if (msg->message == WM_LBUTTONDOWN) { //什么时候能够打开,没有打开的时候就打开 if (map[r][c]>=19 && map[r][c]<=28) { //这个函数只能播放wav格式 PlaySound("./images/click.wav", NULL, SND_ASYNC | SND_FILENAME); map[r][c] -= 20; boomBlank(map, r, c); //检测一下是不是空白格子,是,炸开 isfirst = true; } } //右键标记格子 else if (msg->message == WM_RBUTTONDOWN) { PlaySound("./images/rightClick.wav", NULL, SND_ASYNC | SND_FILENAME); //是否能够标记:如果没有打开就能标记 if (map[r][c] >= 19 && map[r][c] <= 28) { map[r][c] += 20; } else if(map[r][c]>=39) { map[r][c] -= 20; } } } //点击空白格子,连环爆开周围的所有空白格子还有数字 row col 是当前点击的格子 void boomBlank(int map[][COL],int row,int col) { //判断row col位置是不是空白格子 if (map[row][col] == 0) { for (int r = row-1; r <= row+1; r++) { for (int c = col-1; c <= col+1; c++) { if ((r>=0&&r =0&&c
=19 && map[r][c]<=28) //没有打开 { //每一次调用都会播放一下 if (isfirst) { PlaySound("./images/search.wav", NULL, SND_ASYNC | SND_FILENAME); isfirst = false; } map[r][c] -= 20; boomBlank(map, r, c); } } } } return; } //游戏结束条件 输了返回-1 没结束返回0 赢了返回 1 int judge(int map[][COL],int row ,int col) { //点到了雷,结束 输了 if (map[row][col] == -1 || map[row][col] == 19) { return -1; } //点完了格子,结束 赢了 点开了100 - 10 = 90 个格子 int cnt = 0; for (int i = 0; i < ROW; i++) { for (int k = 0; k < COL; k++) { //统计打开的格子的数量 if (map[i][k] >= 0 && map[i][k] <= 8) { ++cnt; } } } if (ROW*COL - MineNum == cnt) { return 1; } return 0; }
主要考察知识点:结构体
开发工具:Visual Studio2019、EasyX图形库
效果图:
完整代码:
#include#include #include #include #include #pragma comment(lib,"winmm.lib") #define WIDTH 800 //窗口的宽高 #define HEIGHT 600 #define SNAKE_NUM 500//蛇的最大节数 enum DIR//蛇的方向 { UP, //上 DOWN, LEFT, RIGHT, }; struct Snake //蛇的结构 { int size; //有多少节 POINT coor[SNAKE_NUM];//每一节蛇的坐标数组 int dir;//蛇的方向 int speed;//速度 int score;//分数 }snake; struct Food//食物 { int x; int y; int r; int flag;//是否被吃掉 COLORREF color; }food; //初始化数据 void GameInit() { //播放背景音乐 mciSendString(L"open ./ress/snake_bgm.mp3 alias BGM", 0, 0, 0); mciSendString(L"play BGM repeat", 0, 0, 0); //设置随机数种子 srand(GetTickCount()); //初始化蛇 snake.dir = DIR::RIGHT;//思考:怎么表示蛇的方向? ::域运算符 snake.score = 0; snake.size = 3; snake.speed = 10; snake.coor[2].x = 10; snake.coor[2].y = 10; snake.coor[1].x = 20; snake.coor[1].y = 10; snake.coor[0].x = 30; snake.coor[0].y = 10; //初始化食物 food.color = RGB(rand() % 256, rand() % 256, rand() % 256); food.flag = 1; food.r = rand() % 10 + 5; food.x = rand() % WIDTH; food.y = rand() % HEIGHT; } void GameDraw() { BeginBatchDraw();//防止闪屏 //设置背景颜色 setbkcolor(RGB(151, 203, 208)); cleardevice(); //绘制蛇 for (int i = 0; i < snake.size; i++) { setfillcolor(BLACK); solidcircle(snake.coor[i].x, snake.coor[i].y, 5); } //绘制食物 if (food.flag) { setfillcolor(food.color); solidcircle(food.x, food.y, food.r); } EndBatchDraw(); } //蛇的移动 void SnakeMove() { //移动蛇身体,每一节蛇(处舌头外),都等于前一节的上一次坐标 for (int i = snake.size - 1; i>0; i--)//从蛇尾遍历到蛇头 { snake.coor[i] = snake.coor[i - 1];//结构体可以直接赋值 //snake.coor[i].x = snake.coor[i - 1].x; //snake.coor[i].y = snake.coor[i - 1].y; } //移动蛇头 switch (snake.dir) { case UP: snake.coor[0].y -= snake.speed; if (snake.coor[0].y <= 0) { snake.coor[0].y = HEIGHT; } break; case DOWN: snake.coor[0].y += snake.speed; if (snake.coor[0].y >= HEIGHT) { snake.coor[0].y = 0; } break; case LEFT: snake.coor[0].x -= snake.speed; if (snake.coor[0].x <= 0) { snake.coor[0].x = WIDTH; } break; case RIGHT: snake.coor[0].x += snake.speed; if (snake.coor[0].x >= WIDTH) { snake.coor[0].x = 0; } break; } } //改变蛇的方向 void keyControl() { if ((GetAsyncKeyState('W') || GetAsyncKeyState(VK_UP)) && snake.dir!=DOWN) { snake.dir = UP; } if ((GetAsyncKeyState('S') || GetAsyncKeyState(VK_DOWN)) && snake.dir != UP) { snake.dir = DOWN; } if ((GetAsyncKeyState('A') || GetAsyncKeyState(VK_LEFT)) && snake.dir != RIGHT) { snake.dir = LEFT; } if ((GetAsyncKeyState('D') || GetAsyncKeyState(VK_RIGHT)) && snake.dir != LEFT) { snake.dir = RIGHT; } } void EatFood() { if (snake.coor[0].x >= food.x - food.r && snake.coor[0].x <= food.x + food.r && snake.coor[0].y >= food.y - food.r && snake.coor[0].y <= food.y + food.r && food.flag) { mciSendString(L"close eat", 0, 0, 0); mciSendString(L"open ./ress/eatfood.mp3 alias eat", 0, 0, 0); mciSendString(L"play eat", 0, 0, 0); snake.size++; food.flag = 0; } //如果食物被吃了,就重新生成一个食物 if (!food.flag) { food.color = RGB(rand() % 256, rand() % 256, rand() % 256); food.flag = 1; food.r = rand() % 10 + 5; food.x = rand() % WIDTH; food.y = rand() % HEIGHT; } } //使程序暂停 void stop() { if (_kbhit())//检测是否有按键 { if (_getch() == ' ') { while (_getch() != ' '); } } } void die() { for (int i = 4; i < snake.size; i++) { if (snake.coor[0].x == snake.coor[i].x && snake.coor[0].y == snake.coor[i].y) { MessageBox(GetHWnd(), L"you die!low B!", L"warnning~",MB_OK); exit(666); } } } int main() { initgraph(WIDTH, HEIGHT); GameInit(); DWORD t1, t2;//typedef unsigned long DWORD; t1 = t2 = GetTickCount();//获取系统开机到现在,所经过的毫秒数 while (1) { GameDraw(); if (t2 - t1 > 200) { SnakeMove(); t1 = t2; } t2 = GetTickCount(); keyControl(); EatFood(); stop(); die(); //Sleep(500);//使整个程序,延迟,而我要的是移动延迟 } return 0; }
由于文章篇幅原因,下面程序都只放效果图,所有项目完整源码及资源包可以进群领取哦!还有更多学习资料、电子书籍、案例源码,欢迎大家一起学习交流,共同进步!点击下方链接进群领取
点击链接加入群聊【C语言/C++交流彗星二群】
四、连连看效果图:
五、拼图游戏效果图:
六、飞机大战效果图:
七、流星雨表白(单身程序员必备)效果图:
八、烟花表白(单身程序员必备) 九、中国象棋效果图:
十、数字雨效果图:
今天就先给大家分享这十个最基础的入门项目!后续会更新更多高级案例和项目实战,有需要的小伙伴可以点赞收藏加关注~
需要C语言入门大礼包、各种C语言C++学习资料的小伙伴可以加入小编的学习群,里面聚集了一些正在学习C语言的小伙伴,在学习C语言的过程中遇到任何的问题,大家都可以一起交流,希望大家都能够实现自己的梦想,加油!资料领取点击下面链接加群哦!
点击链接加入群聊【C语言/C++交流群】



