- 2048游戏(C语言LINUX环境下,键盘读取实例)
- 一、Linux键盘值的调用 “get_keyboard.h”
- 二、代码基本思路
- 三、源代码
- 四、运行结果
在Linux下是没有自带的调取键盘的库的,所以我们得自己写一个头文件“get_keyborad.h”来获取键盘的值。当然如果在Windows环境下,直接调用“conio.h”头文件中就可以了。
// get_keyboard.h在linux下没有直接的get_ch()读取键盘,所以要自己写一个。 #ifndef GETCH_H #define GETCH_H #include二、代码基本思路#include #include #include typedef enum KEYBOARD { KEY_UP = 183, KEY_DOWN = 184, KEY_RIGHT = 185, KEY_LEFT = 186, KEY_BACKSPACE = 127, KEY_ENTER = 10, KEY_0 = 48, KEY_1 = 49, KEY_2 = 50, KEY_3 = 51, KEY_4 = 52, KEY_5 = 53, KEY_6 = 54, KEY_7 = 55, KEY_8 = 56, KEY_9 = 57, KEY_A = 65, KEY_B = 66, KEY_C = 67, KEY_D = 68, KEY_E = 69, KEY_F = 70, KEY_G = 71, KEY_H = 72, KEY_I = 73, KEY_J = 74, KEY_K = 75, KEY_L = 76, KEY_M = 77, KEY_N = 78, KEY_O = 79, KEY_P = 80, KEY_Q = 81, KEY_R = 82, KEY_S = 83, KEY_T = 84, KEY_U = 85, KEY_V = 86, KEY_W = 87, KEY_X = 88, KEY_Y = 89, KEY_Z = 90, KEY_a = 97, KEY_b = 98, KEY_c = 99, KEY_d = 100, KEY_e = 101, KEY_f = 102, KEY_g = 103, KEY_h = 104, KEY_i = 105, KEY_j = 106, KEY_k = 107, KEY_l = 108, KEY_m = 109, KEY_n = 110, KEY_o = 111, KEY_p = 112, KEY_q = 113, KEY_r = 114, KEY_s = 115, KEY_t = 116, KEY_u = 117, KEY_v = 118, KEY_w = 119, KEY_x = 120, KEY_y = 121, KEY_z = 122 }KEYBOARD; //此函数能立即从键盘不回显的接收数据 static int get_keyboard(void) { //接收系统调用的执行结果 int ret = 0; //存储终端设备的配置信息 struct termios old; //通过系统调用获取终端的配置信息 ret=tcgetattr(STDIN_FILENO,&old); if(0 > ret) { perror("tcgetattr"); return -1; } //初始化新的终端配置信息 struct termios new = old; //取消回显并立即获取 new.c_lflag &= ~(ICANON|ECHO); //设置新的终端配置信息 ret= tcsetattr(STDIN_FILENO,TCSANOW,&new); if(0 > ret) { perror("tcsetattr"); return -2; } //在新的模式下从终端获取数据 int key_value = 0; do { key_value += getchar(); //由于和系统对FILE结构体的实现各不相同 //linux系统 while(stdin->_IO_read_end - stdin->_IO_read_ptr); //OS系统 while(stdin->_r); }while(stdin->_IO_read_end - stdin->_IO_read_ptr); //还原终端的配置信息 ret = tcsetattr(STDIN_FILENO,TCSANOW,&old); if(0 > ret) { perror("tcsetattr"); return -3; } //返回获取到的数据 return key_value; } #endif//GETCH_H
-
先初始化加载游戏界面,用二维char类型数组(char map [row1] [col1])来储存交互界面。
-
再建一个数值的二维数组(int nmap [row2] [col2])来储存每个格子的数值。
-
将数值数组和界面数组建立映射关系,就可以把数值直接反应到交互界面。
-
生成随机数,存放到nmap中,刚开始生成3个,之后一次生成一个随机数(2、4、8)。
-
方向键的调用与游戏运行的函数设计
-
key = get_keyboard();获取方向值
-
调用函数判断,对是否能进行移动进行判断。
-
此处,我采取的是==将每一个方向重新抽离出来==,这样就可以四个方向进行一起判断,再重新写回
-
如果能移动,那么是否存在两个相邻或者其中间隔若干个空格的两数相同,如果存在则合并
-
先合并完成再进行移动。
-
顺便计算一下得分情况。
-
#include#include #include #include #include"get_keyboard.h" //#include windows下通过这个头文件获取键盘值。 #define MAX_ROW 6 //规格MAX_ROW*MAX_ROW #define EACH_ROW 3 //每个格子的高度 #define EACH_COL 7 //每个格子的宽度 #define TOTAL_ROW MAX_ROW*(1+EACH_ROW)+1 //总共需要的行数 #define TOTAL_COL MAX_ROW*(1+EACH_COL)+1 //总共需要的列数 #define EACH_TIME_NUM 3 //初始化数字个数 0){ num/=10; ++cnt; } return cnt; } int can_arr_move(int arr[]){ int i=0; int cnt = 0; for(i=0;i 0 && arr[i]!=0 && i 0){ arr[temp-1] = arr[temp]; arr[temp] = 0; --temp; } } } int can_move(int (*nmap)[MAX_ROW],int dirc,int mod,int *pscore){ int i,j; int x,y; int arr[MAX_ROW]={0}; int res = 0; int cnt=0; // 把所有序列转存到新的数组arr for(i=0;i 别忘了头文件 #include switch(key){ case KEY_UP: case KEY_DOWN: case KEY_LEFT: case KEY_RIGHT: system("clear"); //windows system("cls") r = move(map,nmap,key,pscore); break; case KEY_R: case KEY_r: system("clear"); //windows system("cls") load(); break; case KEY_Q: case KEY_q: exit(0); } if(r==-1) { printf("Game over ~n"); key = get_keyboard(); //windows 用getch() ->别忘了头文件 #include if(key == KEY_R || key == KEY_r) load(); else exit(0); } } } void load(){ int i,j; int m,p; int m2; int score = 0; char map[TOTAL_ROW][TOTAL_COL]; system("clear"); //windows system("cls") printf("小游戏1024n"); printf("press 'r' to restart , press 'q' to quit."); printf("nAre you ready? Press any key to start ...n"); get_keyboard(); //windows 用getch() ->别忘了头文件 #include system("clear"); //windows system("cls") printf(" SCORE: %dn",score); //初始化 游戏界面设计 for(i=0;i 四、运行结果
hexo_blog



