200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 学习记录_C语言打砖块小游戏

学习记录_C语言打砖块小游戏

时间:2020-01-27 05:21:15

相关推荐

学习记录_C语言打砖块小游戏

第一次体验到了写代码一上午,修BUG修一天的感觉。但还有一个BUG始终不知道如何解决,那便是如果额外产生的小球触碰到礼盒砖块(会产生额外球),便会在左上角出现隐形球。无奈只好将礼盒砖块改为一个,并将存放小球信息的数组改为2。若有大佬给出建议,不胜感激。

玩法如下:

游戏有四种颜色砖块随机刷新在地图上:分别是深灰色(三血)、灰色(二血)、棕褐色(一血)、绿色(赠送额外小球);

使用鼠标控制球板移动,当所有砖块被击碎时胜利,否则失败。

1.效果展示:

2.编程思路:

构造二维数组来存储砖块,数组内容分别为0、1、2、3、4来表示不同种类的砖块。当小球进入砖块时触发碰撞检测,并对砖块生命值减一。同时用画墙函数根据当前数组中存储的内容来绘制砖块。

3.核心程序:

已知打砖块下游戏需要用小球实现对球板、砖块、窗口的碰撞。那么,程序的核心内容就是碰撞函数。由于知识有限,在写对砖块的碰撞函数时,先将一个砖块碰撞检测范围分为8部分,本别是四个顶角,以及上下左右两侧,当小球进入砖块时,便根据小球当前坐标在砖块内部范围进行检测。并根据检测内容给与小球不同方向的速度。

4.代码展示:

#define _CRT_SECUURE_NO_WARNINGS#include <stdio.h>#include <easyx.h>#include <time.h>/*碰撞思路:首先定义一组二维数组表示,存放1表示砖块,0表示砖块被打碎每个砖块都有自己的坐标x、y进行碰撞检测时,若一个砖块对应的数组值为1,则触发检测碰撞检测:根据二维数组为砖块提高的x、y值,可以得打一块砖块的下、左、右三条边以及下方两个顶点当小球碰到下边时,只需将y轴速度取反即可完成弹射效果当小球碰到两侧时,只需将x轴速度取反即可完成弹射效果但是当小球碰到顶点时,需要将x轴与y轴速度均取反*/#define block_w 85//砖块宽度#define block_h 45//砖块高度#define space 2//砖块间距#define num_w 10//砖块横向数量#define num_h 10//砖块纵向数量/*在像素坐标中,以水平方向为x轴,铅垂方向为y轴,但对应的数组中,以y表示行数,x表示列数*/int num = 1;//当前小球数量int flag = 0;//是否需要产生额外小球标志int flag_1 = 0;//是否开始发射标志int flag_2 = 0;//是否发生第一次弹射标志int flag_3 = 0;//产生第n个额外小球标志int tmpx = 0;int tmpy = 0;float decide = 4;//碰撞判定范围追加值int arr[num_h][num_w];enum speed//定义小球移动速度{ none,slowly = 2,medium,fastly };typedef struct Ball//定义小球参数{int x;int y;int r;int speedx;int speedy;}Ball;void Wall()//墙体函数:根据每个砖块对应的二维数组的值来绘制不同颜色,若0值则不绘制砖块{int x = 0, y = 0;for (y = 0; y < num_h; y++){for (x = 0; x < num_w; x++){if (arr[y][x]){if (arr[y][x] == 1){setfillcolor(RGB(128, 128, 0));}else if (arr[y][x] == 2){setfillcolor(RGB(128, 128, 128));}else if (arr[y][x] == 3){setfillcolor(RGB(104, 104, 104));}else{setfillcolor(RGB(0, 128, 64));}solidrectangle(block_w * x, block_h * y, block_w * (x + 1) - space, block_h * (y + 1) - space);}}}}void Extra(Ball ball[]);void Check_crash(int* x, int* y, Ball* ball)//检测碰撞位置函数:进入一个砖块碰撞范围内,检测碰撞的位置{if (arr[*y][*x] == 1)//撞到一血砖块直接撞碎{arr[*y][*x] = 0;}else if (arr[*y][*x] == 4)//撞到礼盒砖块得到一个额外球{arr[*y][*x] = 0;if (num < 3){num++;flag_3++;}flag = 1;tmpx = ball->x;tmpy = ball->y;printf("%d\n", num);Extra(ball);}else{arr[*y][*x] -= 1;}//一个砖块的右边,截取宽度为两个像素,再去掉上边两个像素的矩形和下边两个像素的矩形,剩余的面积判定为右侧/*___|______________|___* | |右* ___|______________|侧_| | */if (ball->x <= block_w * (*x + 1) - space && ball->x >= block_w * (*x + 1) - space - decide &&ball->y <= block_h * (*y + 1) - space - decide && ball->y >= block_h * (*y) + decide)//碰到砖块右侧{printf("右侧:%d\n", ball->speedx);ball->speedx = medium;}else if (ball->x>= block_w * (*x) && ball->x <= block_w * (*x) + decide &&ball->y <= block_h * (*y + 1) - space - decide && ball->y >= block_h * (*y) + decide)//碰到砖块左侧{printf("左侧:%d\n", ball->speedx);ball->speedx = -medium;}else{//一个砖块的下边,截取宽度为两个像素,再去掉左边两个像素的矩形和右边两个像素的矩形,剩余的面积判定为下侧/*___|______________|___* | |* ___|______________|___|下 侧 | */if (ball->y <= block_h * (*y + 1) - space && ball->y >= block_h * (*y + 1) - space - decide &&ball->x <= block_w * (*x + 1) - space - decide && ball->x >= block_w * (*x) + decide)//碰到砖块底边{ball->speedy = -fastly;printf("底边:%d\n", ball->speedy);}else if (ball->y >= block_h * (*y) && ball->y <= block_h * (*y) + decide &&ball->x <= block_w * (*x + 1) - space - decide && ball->x >= block_w * (*x) + decide)//碰到砖块顶边{printf("顶边:%d\n", ball->speedy);ball->speedy = fastly;}}if (ball->x > block_w * (*x + 1) - space - decide && ball->x < block_w * (*x + 1) &&ball->y > block_h * (*y + 1) - space - decide && ball->y < block_h * (*y + 1)){printf("右下角:%d\t%d\n", ball->speedx, ball->speedy);ball->speedx = medium;ball->speedy = -fastly;}else if (ball->x > block_w * (*x) && ball->x < block_w * (*x) + decide &&ball->y > block_h * (*y + 1) - space - decide && ball->y < block_h * (*y + 1)){printf("左下角:%d\t%d\n", ball->speedx, ball->speedy);ball->speedx = -medium;ball->speedy = -fastly;}else if (ball->x > block_w * (*x + 1) - space - decide && ball->x < block_w * (*x + 1) &&ball->y > block_h * (*y) + decide && ball->y < block_h * (*y)){printf("右上角:%d\t%d\n", ball->speedx, ball->speedy);ball->speedx = -medium;ball->speedy = fastly;}else if (ball->speedx > block_w * (*x) && ball->speedx < block_w * (*x) + decide &&ball->speedy > block_h * (*y) + decide && ball->speedy < block_h * (*y)){printf("左上角:%d\t%d\n", ball->speedx, ball->speedy);ball->speedx = medium;ball->speedy = fastly;}}void Check_edge(Ball* ball)//窗口边缘碰撞检测{if (ball->x <= ball->r){ball->speedx = medium;}else if (ball->x >= block_w * 10 - ball->r){ball->speedx = -medium;}else if (ball->y <= ball->r){ball->speedy = -fastly;}}void Crash(Ball ball[])//碰撞函数{int x = 0, y = 0, i = 0;for (y = 0; y < num_h; y++){for (x = 0; x < num_w; x++){for (i = 0; i < num; i++){if (arr[y][x] >= 1 &&//遍历所有小球,检测各个小球是否进入砖块碰撞范围,若进入,则对该小球调用碰撞检测函数实现该小球的碰撞(ball[i].x <= block_w * (x + 1) - space &&ball[i].x >= block_w * x &&ball[i].y <= block_h * (y + 1) - space &&ball[i].y >= block_h * y)){flag_2 = 1;Check_crash(&x, &y, &ball[i]);}else//若没有则检测是否与窗口碰撞{Check_edge(&ball[i]);}}}}}void Check_board(int* site, Ball* ball)//检测板子碰撞函数{if (ball->x <= *site + 100 + ball->r && ball->x >= *site + 90 && ball->y >= block_h * num_h + 400 - ball->r)//碰到板子右角{ball->speedx = medium;ball->speedy = fastly;}else if (ball->x >= *site - ball->r && ball->x <= *site + 10 && ball->y >= block_h * num_h + 400 - ball->r)//碰到板子左角{ball->speedx = -medium;ball->speedy = fastly;}else{if (ball->y >= block_h * num_h + 400)//碰到板子顶边{ball->speedy = fastly;}}}void Board(ExMessage* msg, Ball ball[])//球板函数{static int site = block_w * 5 + 10;if (peekmessage(msg, EM_MOUSE)){site = msg->x;//球板位置if (msg->lbutton){flag_1 = 1;}}if (!flag_1)//若没有按下左键,则球的位置跟随球板位置{ball[0].x = site + 50;ball[0].y = block_h * num_h + 400;}setfillcolor(BLUE);fillrectangle(site, block_h * num_h + 400, site + 100, block_h * num_h + 410);for (int i = 0; i < num; i++){if (ball[i].x <= site + 100 + ball[i].r && ball[i].x >= site - ball[i].r &&ball[i].y <= block_h * num_h + 410 && ball[i].y >= block_h * num_h + 400 - ball[i].r && flag_2){Check_board(&site, &ball[i]);}}}void Extra(Ball ball[])//产生额外小球{if (flag_3 && flag){ball[flag_3].x = tmpx;//额外小球初始位置和起始小球初始位置相同ball[flag_3].y = tmpy;ball[flag_3].r = ball[0].r;ball[flag_3].speedx = none;ball[flag_3].speedy = fastly;printf("最新的小球的x速度:%d和y速度%d位置为%d %d\n", ball[flag_3].speedx, ball[flag_3].speedy, ball[flag_3].x, ball[flag_3].y);flag = 0;}}void Ball_move(Ball ball[])//小球移动函数{if (flag_1){ball[0].y -= ball[0].speedy;ball[0].x += ball[0].speedx;}if (flag_3){for (int i = 0; i < flag_3; i++){ball[i + 1].y -= ball[i + 1].speedy;ball[i + 1].x += ball[i + 1].speedx;setfillcolor(RGB(128, 128, 64));fillcircle(ball[i + 1].x, ball[i + 1].y - ball[i + 1].r, ball[i + 1].r);printf("球的位置x:%d,y:%d\n", ball[i + 1].x, ball[i + 1].y);}}setfillcolor(RGB(0, 128, 64));fillcircle(ball[0].x, ball[0].y - ball[0].r, ball[0].r);Sleep(1);}void Random()//对墙体砖块随机化,其中有4个礼盒砖块,15个三血砖块,30个二血砖块,20个空位,剩余的均为一血砖块{int x = 0, y = 0;for (x = 0; x < num_w; x++)//先将砖块全部初始化为一血{for (y = 0; y < num_h; y++){arr[y][x] = 1;}}int gift = 1;int empty = 20;int life_3 = 15;int life_2 = 30;while (life_2){int i = rand() % num_w;int j = rand() % num_h;if (arr[j][i] == 1){arr[j][i] = 2;life_2--;}}while (life_3){int i = rand() % num_w;int j = rand() % num_h;if (arr[j][i] == 1){arr[j][i] = 3;life_3--;}}while (gift){int i = rand() % num_w;int j = rand() % num_h;if (arr[j][i] == 1){arr[j][i] = 4;gift--;}}while (empty){int i = rand() % num_w;int j = rand() % num_h;if (arr[j][i] == 1){arr[j][i] = 0;empty--;}}}int Judge(Ball ball[])//判断小球是否都掉落,若全部掉落则游戏失败{int count1 = 0;int count2 = 0;int x = 0, y = 0;for (x = 0; x < num_h; x++){for (y = 0; y < num_w; y++){if (arr[x][y] == 0){count2++;if (count2 == num_w * num_h){return 2;}}}}for (int i = 0; i < num; i++){if (ball[i].y >= block_h * num_h + 500){count1++;}}if (count1 == num){return 0;}return 1;}int Menu(ExMessage* msg)//菜单函数{BeginBatchDraw();setbkcolor(WHITE);cleardevice();char str[] = "按Enter开始游戏";settextcolor(RED);setbkmode(TRANSPARENT);settextstyle(100, 0, "楷体");int wid = textwidth(str);int hei = textheight(str);setfillcolor(BLUE);fillrectangle((block_w * num_w - wid) / 2, (block_h * num_h + 500 - hei) / 2, block_w * num_w - (block_w * num_w - wid) / 2, block_h * num_h + 500 - (block_h * num_h + 500 - hei) / 2);outtextxy((block_w * num_w - wid) / 2, (block_h * num_h + 500 - hei) / 2, str);FlushBatchDraw();if (peekmessage(msg, EM_KEY))//按键检测{if (msg->vkcode == 13){return 0;}}return 1;}int main(){int play = 1;int start = 1;int i = 0, j = 0;Ball ball[10] = { { 0, 450, 10, none, fastly } ,{ 0, 0, 0, none, none }};ExMessage msg;srand((unsigned int)time(NULL));Random();initgraph(block_w * num_w, block_h * num_h + 500, EW_SHOWCONSOLE);while (start){start = Menu(&msg);}while (play == 1){BeginBatchDraw();setbkcolor(RGB(170, 170, 255));cleardevice();Wall();Board(&msg, ball);Crash(ball);Ball_move(ball);EndBatchDraw();play = Judge(ball);}while (1){BeginBatchDraw();setbkcolor(WHITE);cleardevice();char str1[] = "菜逼快去学习";char str2[] = "666";settextcolor(RED);setbkmode(TRANSPARENT);settextstyle(50, 0, "楷体");int wid1 = textwidth(str1);int hei1 = textheight(str1);int wid2 = textwidth(str2);int hei2 = textheight(str2);if (play == 0){outtextxy((block_w * num_w - wid1) / 2, (block_h * num_h + 500 - hei1) / 2, str1);}else{outtextxy((block_w * num_w - wid2) / 2, (block_h * num_h + 500 - hei2) / 2, str2);}FlushBatchDraw();}getchar();closegraph();return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。