C语言数组实现打砖块游戏
作者:无限的菜鸟
这篇文章主要为大家详细介绍了C语言数组实现打砖块游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文实例为大家分享了C语言数组实现打砖块游戏的具体代码,供大家参考,具体内容如下
这次我们使用数组来改进打砖块游戏。
反弹的球
首先我们实现一个可以在荧幕上反弹的小球。使用二维数组 int canvas[High][Width] ( 和js的canvas没有一毛钱关系)来储存画布上的所有元素,值为0时输出空格,值为1时输出小球。
设小球坐标为(ball_x, ball_y),则有canvas[ball_x][ball_y] = 1 ,且暂时将其他元素的值设为0。
每次更新小球位置时将原位置元素设为0,将新位置元素设为1即可。
注意:gotoxy函数用于清屏重画,很久以前讲过的。
#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <cwindow.h> // 画面尺寸设定 #define High 15 #define Width 20 //全局变量 int ball_x,ball_y; //小球坐标 int ball_vx,ball_vy;//小球速度 int canvas[High][Width] = [0]; void gotoxy(int x, int y) //移动光标便于清屏重画 { HANDLE handle = GetStdHandle(STD_UOTPUT_HANDLE); CROOD pos; pos.X = x; pos.Y = y; SetConsoleCursorPosition(handle, pos); } void startup() //数据初始化 { ball_x = 0; ball_y = Width/2; ball_vx = 1; ball_vy = 1; canvas[ball_x][ball_y] = 1; } void show() { gotoxy(0, 0); int i,j; for(i=0; i<High; i++) { for(j=0; j<Width; j++) { if (canvas[i][j] == 0) printf(" ");//输出空格 else if (canvas[i][j] == 1) printf("O");//输出小球 } printf("|\n");//每画完一行显示边界并换行 } for(j=0; j<Width; j++) printf("-");//最后画下边界 } void updateWithoutInput() //无关输入的更新 { //小球移动 canvas[ball_x][ball_y] = 0; ball_x = ball_x + ball_vx; ball_y = ball_y + ball_vy; //反弹判断 if ((ball_x == 0)||(ball_x == High - 1)) ball_vx = -ball_vx; if ((ball_y == 0)||(ball_y == Width - 1)) ball_vy = -ball_vy; canvas[ball_x][ball_y] = 1; //休眠时间,避免刷新过快 sleep(50); } void updateWithInput() {} int main() { startup(); while(1) { show(); updateWithoutInput(); updateWithInput(); } return 0; }
这里要注意的是:
- updateWithInput留空,因为现在还没有用户操作的功能实现。
- main是死循环,所以测试时要注意,当然也可以改进。
增加挡板
现在我们可以新定义,当数组中某一元素值为2时,输出挡板“ * ”。
并且为updateWithInput增加移动挡板的功能,每次移动一个单位作为其速度(当然可以改成别的数)。
挡板的刷新方式和小球一样,先将原位置清零然后把新位置元素改为2。
需要增加的内容如下:
//全局变量 int position_x,position_y; //挡板中心坐标 int ridus; //挡板半径,就是延伸的长度 int left,right; //挡板左右位置 //初始化 ridus = 5; position_x = High - 1; position_y = Width/2; left = position_y - ridus; right = position_x + ridus; int k; for(k=left; k<=right; k++) canvas[position_x][k] = 2; //输出部分 ... else if (canvas[i][j] == 2) printf("*"); ... //更新部分(与输入无关) if (ball_x == High - 2) { //判断是否挡住 if ((ball_y >= left)&&(ball_y <= right)) { printf("\a"); } else //未挡住 { printf("游戏失败\n"); printf("pause"); exit(0); } } //与输入有关的更新 void updateWithInput() { char input; if (kbhit()) //判断是否有输入 input = getch(); if ((input == 'a')&&(left > 0))//左移 { canvas[position_x][right] = 0; position_y --; left = position_y - ridus; right = position_x + ridus; canvas[position_x][left] = 2; } if ((input == 'd')&&(right < Width -1))//右移 { canvas[position_x][left] = 0; position_y ++; left = position_y - ridus; right = position_x + ridus; canvas[position_x][right] = 2; } }
打砖块
这部分内容就和之前的内容一样了。
需要增加的内容有:
1. 初始砖块
2. 小球碰到砖块的判定
3. 碰到砖块后的更新(砖块消失、小球反弹)
具体代码如下:
//初始化 int k,i; for(k=0; k<Width; k++) for(i=0; i<high/4; i++) //这里是画砖块,可以根据修改 i 的范围改变砖块的排数 canvas[i][k] = 3; //输出 ... else if (canvas[i][j] == 3) printf("#"); ... //碰到砖块后 if (canvas[ball_x + ball_vx][ball_y + ball_vy] == 3) { canvas[ball_x + ball_vx][ball_y + ball_vy] = 0; ball_vx = -ball_vx; ball_vy = -ball_vy; printf("\a"); }
最后
1. 坐标系是x轴向下,y 轴向右。
2. 实际对碰撞的判定是在斜方向上,当然可以改进判定内容。
3. 游戏胜利条件还没有完善。
全代码:
#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <cwindow.h> // 画面尺寸设定 #define High 15 #define Width 20 //全局变量 int ball_x,ball_y; //小球坐标 int ball_vx,ball_vy;//小球速度 int canvas[High][Width] = [0]; int position_x,position_y; //挡板中心坐标 int ridus; //挡板半径,就是延伸的长度 int left,right; //挡板左右位置 void gotoxy(int x, int y) //移动光标便于清屏重画 { HANDLE handle = GetStdHandle(STD_UOTPUT_HANDLE); CROOD pos; pos.X = x; pos.Y = y; SetConsoleCursorPosition(handle, pos); } void startup() //数据初始化 { ball_x = 0; ball_y = Width/2; ball_vx = 1; ball_vy = 1; canvas[ball_x][ball_y] = 1; ridus = 5; position_x = High - 1; position_y = Width/2; left = position_y - ridus; right = position_x + ridus; int k,i; for(k=left; k<=right; k++) canvas[position_x][k] = 2; for(k=0; k<Width; k++) for(i=0; i<high/4; i++) //这里是画砖块,可以根据修改 i 的范围改变砖块的排数 canvas[i][k] = 3; } void show() { gotoxy(0, 0); int i,j; for(i=0; i<High; i++) { for(j=0; j<Width; j++) { if (canvas[i][j] == 0) printf(" ");//输出空格 else if (canvas[i][j] == 1) printf("O");//输出小球 else if (canvas[i][j] == 2) printf("*"); else if (canvas[i][j] == 3) printf("#"); } printf("|\n");//每画完一行显示边界并换行 } for(j=0; j<Width; j++) printf("-");//最后画下边界 } void updateWithoutInput() //无关输入的更新 { if (canvas[ball_x + ball_vx][ball_y + ball_vy] == 3) { canvas[ball_x + ball_vx][ball_y + ball_vy] = 0; ball_vx = -ball_vx; ball_vy = -ball_vy; printf("\a"); } if (ball_x == High - 2) { //判断是否挡住 if ((ball_y >= left)&&(ball_y <= right)) { printf("\a"); } else //未挡住 { printf("游戏失败\n"); printf("pause"); exit(0); } } //小球移动 canvas[ball_x][ball_y] = 0; ball_x = ball_x + ball_vx; ball_y = ball_y + ball_vy; //反弹判断 if ((ball_x == 0)||(ball_x == High - 1)) ball_vx = -ball_vx; if ((ball_y == 0)||(ball_y == Width - 1)) ball_vy = -ball_vy; canvas[ball_x][ball_y] = 1; //休眠时间,避免刷新过快 sleep(50); } void updateWithInput() { char input; if (kbhit()) //判断是否有输入 input = getch(); if ((input == 'a')&&(left > 0))//左移 { canvas[position_x][right] = 0; position_y --; left = position_y - ridus; right = position_x + ridus; canvas[position_x][left] = 2; } if ((input == 'd')&&(right < Width -1))//右移 { canvas[position_x][left] = 0; position_y ++; left = position_y - ridus; right = position_x + ridus; canvas[position_x][right] = 2; } } int main() { startup(); while(1) { show(); updateWithoutInput(); updateWithInput(); } return 0; }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。