在VC 6.0上用C语言写的简单的微信打飞机程序,实现了基本的我机上下左右移动,发射子弹的功能。实现了敌机(目前只能下一个)下落功能,并实现了子弹撞机敌机,敌机从新下落的功能。
未实现多个敌机下落的功能。
VC 6.0用C写的界面非常不友好,不过我写的代码基本的框架思路已经建立。本人正在学习python,后面试图用python实现了一个更加友好的微信打飞机。
程序截图:
源代码:
/***************************************************************/ /*微信经典打飞机 * 基于VC 6.0 编译链接即可运行 * 已实现的功能: * 1、AWSD控制我方飞机上下左右移动 * 2、我方飞机撞墙检测(四面的墙都要检测) * 3、添加我方飞机发弹功能(子弹发射函数,应单独建立一个线程) * 4、添加一个敌机下落函数 * 5、将敌机下落与我方飞机控制运动抽象为一个线程 * 6、添加我方飞机发射子弹线程 * 7、添加子弹与敌机碰撞检测功能 * 8、添加敌机与我机碰撞游戏结束功能 * 9、添加多个敌机 * 10、增加击落敌机计分功能 * 版权:通渭县西关小学四年级一班田刚 */ /***************************************************************/ #include<stdio.h> #include<windows.h> #include<conio.h> #include<string.h> #define BACK 176//背景图案 #define BACK_INT -80//背景的整数表示 #define FRAME 178//分割框图案 #define NODE 219//我机方块图案,敌机也用这个方块 #define NODE_INT -37//我机方块的整数表示 #define BOOM 30//飞机子弹图案 #define BOOM_INT -226//飞机子弹的整数表示 //#define ENEMY 8//敌机方块图案 #define ERROR -1 #define OK 0 #define DISPLAY 1//显示 #define CLEAR 0//消除 #define MY_PLANE_BLOCK 0//我方飞机方块 #define BOOM_BLOCK 1//子弹方块 #define ENEMY_BLOCK 2//敌人飞机 int my_plane_x = -1, my_plane_y = -1; int enemy_plane_x = 0, enemy_plane_y = 0; char back[20][30] = {0};//竖直为x轴,横轴为y轴,原点在右上角 HANDLE g_mutex; void backgroud_init(void);//画面背景的初始化 void set_windows_pos(int i, int j);//指定光标位置 void block_display(int block_type, int coor_x, int coor_y, int color_type);//显示或者消除飞机方块 void block_legal_check(int *coor_x, int *coor_y);//飞机方块越界检测 void boom_display(int coor_x, int coor_y);//我方飞机子弹发射函数 int enemy_boom_check(int coor_x, int coor_y);//敌机与子弹碰撞检测函数 int enemy_plane_move(int coor_x, int coor_y);//敌机运动函数 DWORD WINAPI MY_PLANE_Thread(LPVOID pM);//我方飞机控制函数 DWORD WINAPI ENEMY_PLANE_Thread(LPVOID pM);//敌机控制函数 int main(void) { HANDLE my_plane_handle; HANDLE enemy_plane_handle; g_mutex = CreateMutex(NULL, false, NULL);//创建互斥量 backgroud_init();//背景的显示 block_display(MY_PLANE_BLOCK, 19, 11, DISPLAY);//我方飞机的初始化显示 //建立我放飞机运动控制线程 my_plane_handle = CreateThread(NULL, 0, MY_PLANE_Thread, NULL, 0, NULL); //建立敌人飞机运行控制线程 enemy_plane_handle = CreateThread(NULL, 0, ENEMY_PLANE_Thread, NULL, 0, NULL); /* 判断敌机与我机是否相撞,只判断某几个点 */ while(1) { //头结点不能相撞 if((my_plane_x - 1) == enemy_plane_x) { if((my_plane_y - 1) == (enemy_plane_y - 1)) { break; } } //我机右翼不能与敌机左翼相撞 if(my_plane_x == enemy_plane_x - 1) { if(my_plane_y == (enemy_plane_y - 2)) { break; } } //我机左翼不能与右翼相撞 if(my_plane_x == (enemy_plane_x - 1)) { if((my_plane_y - 2) == enemy_plane_y) { break; } } //我机尾部不能与敌机尾部相撞 if(my_plane_x == (enemy_plane_x - 1)) { if((my_plane_y - 1) == (enemy_plane_y - 1)) { break; } } //其他情况敌机会被子弹击落 } //游戏结束 printf("gameover\n"); //关闭相应线程 CloseHandle(my_plane_handle); CloseHandle(enemy_plane_handle); WaitForSingleObject(my_plane_handle, INFINITE); WaitForSingleObject(enemy_plane_handle, INFINITE); return 0; } /***************************************************************/ /*** 画面背景的初始化 ***/ /***其中原点在右上角,竖轴为x轴,横轴为y轴。y(0 - 19)为方块区***/ /***域,y = 20为切割边 ***/ /***************************************************************/ void backgroud_init(void) { int x = 0, y = 0; for(x = 0; x <= 20; x++) { for(y = 0; y <= 20; y++) { back[x][y] = BACK; if(20 == y) { back[x][y] = FRAME; } if(20 == x) { back[x][y] = FRAME; } } } //背景图案的显示 for(x = 0; x <= 20; x++) { for(y = 0; y <= 20; y++) { printf("%c", back[x][y]); } printf("\n"); } } /***************************************************************/ /*** 设置windows光标,类似于TC中的gotoxy ***/ /***i,j 为要传入的x,y坐标 ***/ /***************************************************************/ void set_windows_pos(int i, int j)//设置windows光标,类似于TC中的gotoxy { /*if((0 > i) || (0 > j)) { return ERROR; }*/ /*windows的横轴是x轴,而本程序设计的是竖轴是X轴 这里做个转换*/ COORD pos={j,i}; HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hOut,pos); } /***************************************************************/ /***********************消除/填上*******************************/ /***输入:block_type 方块类型:我方飞机方块MY_PLANE_BLOCK、 /***子弹方块BOOM_BLOCK 敌人飞机 ENEMY_BLOCK***/ /***输入:coor_x coor_y 方块当前头的坐标 ***/ /***初始coor_x,coor_y为一个方块的最右下的一个方块的坐标 ***/ /***color_type DISPLAY 方块显示 CLEAR 方块消除 ***/ /***************************************************************/ void block_display(int block_type, int coor_x, int coor_y, int color_type) { int x = 0, y = 0; int color = 0; if(DISPLAY == color_type)//显示方块 { if(MY_PLANE_BLOCK == block_type)//飞机方块类型 { color = NODE; } else if(BOOM_BLOCK == block_type)//子弹飞机类型 { color = BOOM; } else if(ENEMY_BLOCK == block_type)//敌人飞机方块类型 { color = NODE; } else { printf("block_type is error.\n"); return; } } else if(CLEAR == color_type)//消除方块 { color = BACK; } else { printf("color_type error!\n"); return; } switch(block_type) { case MY_PLANE_BLOCK: for(y = coor_y; y >= coor_y - 2; y--) { back[coor_x][y] = color;//方块色 set_windows_pos(coor_x, y);//移动windows的光标 printf("%c", back[coor_x][y]); } coor_x--; coor_y--; back[coor_x][coor_y] = color;//方块色 set_windows_pos(coor_x, coor_y);//移动windows的光标 printf("%c", back[coor_x][coor_y]); break; case BOOM_BLOCK: back[coor_x][coor_y] = color;//方块色 set_windows_pos(coor_x, coor_y);//移动windows的光标 printf("%c", back[coor_x][coor_y]); break; case ENEMY_BLOCK: coor_y--; back[coor_x][coor_y] = color;//方块色 set_windows_pos(coor_x, coor_y);//移动windows的光标 printf("%c", back[coor_x][coor_y]); coor_x--; coor_y++; if(coor_x < 0 || coor_y < 0) { return; } for(y = coor_y; y >= coor_y - 2; y--) { back[coor_x][y] = color;//方块色 set_windows_pos(coor_x, y);//移动windows的光标 printf("%c", back[coor_x][y]); } break; default: printf("block_type is error.\n"); break; } } void block_legal_check(int *coor_x, int *coor_y)//飞机方块越界检测 { if((NULL == coor_x) || (NULL == coor_y)) { printf("x,y of plane is error\n"); return; } if(*coor_x > 19) { *coor_x = 19; } if(*coor_x < 1) { *coor_x = 1; } if(*coor_y < 2) { *coor_y = 2; } if(*coor_y > 19) { *coor_y = 19; } } void boom_display(int coor_x, int coor_y)//我方飞机子弹发射函数 { int x = 0, y = 0; block_display(BOOM_BLOCK, coor_x, coor_y, DISPLAY); for(x = coor_x - 1; x >= 0; x--) { Sleep(20); block_display(BOOM_BLOCK, x + 1, coor_y, CLEAR);//消除上一次的子弹印迹 block_display(BOOM_BLOCK, x, coor_y, DISPLAY);//画上下一次的子弹印迹 } block_display(BOOM_BLOCK, 0, coor_y, CLEAR);//消除上一次的子弹印迹 } DWORD WINAPI MY_PLANE_Thread(LPVOID pM) { int c = 0; int new_back_x = 19;//新的方块头坐标x int new_back_y = 11;//新的方块头坐标y int befor_back_x = 0;//旧的方块头坐标x int befor_back_y = -1;//旧的方块头坐标y while(1) { //怎样在这里清除键盘输入,flush不起作用 befor_back_x = new_back_x; befor_back_y = new_back_y; if(kbhit())//检测有输入 { c = getch(); if(c > 0) { switch(c) { case 119://上 new_back_x--; break; case 97://左 new_back_y--; break; case 100://右 new_back_y++; break; case 115://下 new_back_x++; break; default://ESC break; } } } block_legal_check(&new_back_x, &new_back_y);//飞机x,y坐标检测,防止撞墙 WaitForSingleObject(g_mutex, INFINITE); if((befor_back_x != new_back_x) || (befor_back_y != new_back_y))//当飞机不移动的话不去处理这个流程 { block_display(MY_PLANE_BLOCK,befor_back_x, befor_back_y, CLEAR);//原来的飞机方块位置清除掉 block_display(MY_PLANE_BLOCK,new_back_x, new_back_y, DISPLAY);//画下一个飞机方块位置 } my_plane_x = new_back_x; my_plane_y = new_back_y; //子弹发射函数 boom_display(new_back_x - 2, new_back_y - 1); ReleaseMutex(g_mutex); } return 0; } //敌机运动函数 DWORD WINAPI ENEMY_PLANE_Thread(LPVOID pM) { (void)enemy_plane_move(0, 4); //(void)enemy_plane_move(0, 11); //(void)enemy_plane_move(0, 19); return 0; } //敌机运动函数,传入初始x,y坐标 int enemy_plane_move(int coor_x, int coor_y) { int new_back_x = coor_x;//新的方块头坐标x int new_back_y = coor_y;//新的方块头坐标y int befor_back_x = coor_x;//旧的方块头坐标x int befor_back_y = coor_y;//旧的方块头坐标y while(1) { for(new_back_x = 0; new_back_x < 20; new_back_x++) { WaitForSingleObject(g_mutex, INFINITE); block_display(ENEMY_BLOCK, befor_back_x, befor_back_y, CLEAR);//消除上一次的敌机印迹 block_display(ENEMY_BLOCK, new_back_x, new_back_y, DISPLAY);//画上下一次的敌机印迹 ReleaseMutex(g_mutex); befor_back_y = new_back_y; befor_back_x = new_back_x; enemy_plane_x = new_back_x; enemy_plane_y = new_back_y; Sleep(500); //敌机是否被子弹击中检测函数 if(1 == enemy_boom_check(new_back_x, new_back_y)) { break; } } } return 0; } /* 敌机与子弹碰撞检测函数,传入当前敌机初始坐标 当敌机与子弹碰撞后,返回1 当敌机与子弹没有碰撞,返回0 */ int enemy_boom_check(int coor_x, int coor_y) { int y = 0; coor_y--; if(NODE_INT != back[coor_x][coor_y]) { return 1; } coor_x--; coor_y++; if(coor_x < 0 || coor_y < 0) { return 0; } for(y = coor_y; y >= coor_y - 2; y--) { if(NODE_INT != back[coor_x][y]) { return 1; } } return 0; }