初学者就爱开发点小游戏,比如贪吃蛇、俄罗斯方块等,开发这种小游戏就必须有按键控制,一般情况下我们是直接用getch()函数接收按键,然后转换成对应的ASCII码,再通过与ASCII码比较判断用户到底是按了什么键,然后根据按键去执行相应的操作,比如移动、旋转。
但是最近实践我发现这其实没那么简单,举个例子:比如贪吃蛇,当用户按下“向上的方向键”时,要控制蛇往上走,为了说明问题,简化一点,如果按了向上的方向键则输出“up”,其他方向键类似。一般我们会去查ASCII码表(下面有),
如图,向上的方向键是38,然后我们就会写出这么一个小程序:
#include<conio.h>
int main()
{
char ch;
while(true)
{
ch=getch();
if(ch == 38)//向上键
printf("up");
if(ch == 27)//ESC键
printf("ESC");
}
}
感兴趣的朋友可以试试编译运行一下,你就会发现问题:如果按“ESC”键,则输出“ESC”,但是无论怎么按向上的方向键,始终不输出“up”!这是问什么呢?我也不知道。当然通过查ASCII码表,我们会发现,其实ASCII38对应的是'&',如果输入'&',就会输出‘up’!晕.........哪位大神知道为什么?回复一下,小弟不胜感激。
但问题还是要解决的,键盘上的向上方向键到底怎么接收呢?后来查了很多资料,看了很多实例,我发现,如果将38改为72就能输出‘up’!太神奇了,我们查ASCII码72对应的字符,就会发现那其实是‘H’,也就是说,如果我们输入‘H’,也能输出‘up’,事实确实如此!太奇怪了!键盘上的‘H’和向上方向键终归是不一样吧,一样的话不久麻烦了吗,平常打字的时候按向上方向键也没见输出‘H’,哈,开个玩笑。这个问题看着小,如果仅仅在贪吃蛇这种小游戏里还没什么,用户一般不会想到去按‘H’的,但是如果在大型软件或大型游戏中呢?说不定这个小bug会让整个系统崩溃!说不定黑客通过这个bug就入侵了!
一个问题刚解决,又一个问题来了,那么我们到底怎样才能避免上面的问题呢?冥思苦想了良久,坐立不安,心神恍惚,茶饭不思,精神萎靡,头晕脑胀..........终于,在今天,突发灵感,想到方案啦!哈哈,下面让我慢慢道来:
我是这样想的,既然查ASCII码表那么麻烦,查出来还不能用,那么为什么不自己开发一个小程序呢,用户按一个键,然后输出对应的ASCII码,代码很简单,学过C的都会写,我把代码贴出来:
#include<conio.h>
int main()
{
char c;
while(1)
{
c=getch();
printf("%d %x %c\n",c,c,c);
}
}
代码就是这么个意思:接收一个键盘按键,然后输出对应的十进制ASCII码,然后输出对应的16进制的ASCII码,最后输出按键对应的字符(如果能显示就会在屏幕上显示)。运行一下,你就会发现问题,一个惊天动地的问题,一个难以置信的问题,当按下向上的方向键后,竟然出现这个(檫亮眼,看截图)
怎么回事?看清楚了吗?再擦擦眼,仔细看,没错,就是这样,下面那一行还好理解,就是72嘛,刚才我们已经做过实验了,但是,上面一行怎么回事?我们不是就按了一个键吗,怎么会显示两行?再看源代码,不对啊,应该只输出一行才对,我们预期的应该是只输出下面以后那个的,上面一行到底是什么?输出的-32又对应着什么?为什么会有上面一行?小弟我是真晕了,还是请教各位大仙大神大牛,Orz.........
我是这样想的,也不知到对不对,或许,当你按下向上的方向键后,实际按的是两个键,啊!?不懂,我也不懂,只是猜测,然后第一个键就是上面显示的-32,第二个键才是真正得到的ASCII码。我也不知道对不对,反正如果按我的想法的话,那个相同按键的问题就能解决了,看代码:
#include<conio.h>
int main()
{
char ch;
while(true)
{
ch=getch();
if(ch == -32)
{
ch=getch();
if(ch==72)//向上键
printf("up");
}
if(ch==27)//ESC键
printf("ESC");
}
}
这样的话,只有在按下向上的方向键后才输出‘up’输入‘H’就不会输出‘up’,当然,在开发中,我们就可以这样做了,最起码能保证不会出问题,但是到底为什么是这样,我也不明白,还请高人指点。
另外,关于按键转换成ASCII码的小程序我感觉还是比较有用的,最起码能快速得到你想要的按键或字符的ASCII,不用整天抱着个ASCII码表查,我已经做成一个小软件,在我网盘里,如果需要的话可以到我的网盘下载:http://ma6174.ys168.com/
另,附上ASCII码表,虽然查了也不会用,看看吧,或许能用着
ASCII值 | 控制字符 | ASCII值 | 控制字符 | ASCII值 | 控制字符 | ASCII值 | 控制字符 |
0 | NUT | 32 | (space) | 64 | @ | 96 | 、 |
1 | SOH | 33 | ! | 65 | A | 97 | a |
2 | STX | 34 | ” | 66 | B | 98 | b |
3 | ETX | 35 | # | 67 | C | 99 | c |
4 | EOT | 36 | $ | 68 | D | 100 | d |
5 | ENQ | 37 | % | 69 | E | 101 | e |
6 | ACK | 38 | & | 70 | F | 102 | f |
7 | BEL | 39 | , | 71 | G | 103 | g |
8 | BS | 40 | ( | 72 | H | 104 | h |
9 | HT | 41 | ) | 73 | I | 105 | i |
10 | LF | 42 | * | 74 | J | 106 | j |
11 | VT | 43 | + | 75 | K | 107 | k |
12 | FF | 44 | , | 76 | L | 108 | l |
13 | CR | 45 | - | 77 | M | 109 | m |
14 | SO | 46 | . | 78 | N | 110 | n |
15 | SI | 47 | / | 79 | O | 111 | o |
16 | DLE | 48 | 0 | 80 | P | 112 | p |
17 | DCI | 49 | 1 | 81 | Q | 113 | q |
18 | DC2 | 50 | 2 | 82 | R | 114 | r |
19 | DC3 | 51 | 3 | 83 | X | 115 | s |
20 | DC4 | 52 | 4 | 84 | T | 116 | t |
21 | NAK | 53 | 5 | 85 | U | 117 | u |
22 | SYN | 54 | 6 | 86 | V | 118 | v |
23 | TB | 55 | 7 | 87 | W | 119 | w |
24 | CAN | 56 | 8 | 88 | X | 120 | x |
25 | EM | 57 | 9 | 89 | Y | 121 | y |
26 | SUB | 58 | : | 90 | Z | 122 | z |
27 | ESC | 59 | ; | 91 | [ | 123 | { |
28 | FS | 60 | < | 92 | \ | 124 | | |
29 | GS | 61 | = | 93 | ] | 125 | } |
30 | RS | 62 | > | 94 | ^ | 126 | ~ |
31 | US | 63 | ? | 95 | — | 127 | DEL |
NUL | VT 垂直制表 | SYN 空转同步 |
SOH 标题开始 | FF 走纸控制 | ETB 信息组传送结束 |
STX 正文开始 | CR 回车 | CAN 作废 |
ETX 正文结束 | SO 移位输出 | EM 纸尽 |
EOY 传输结束 | SI 移位输入 | SUB 换置 |
ENQ 询问字符 | DLE 空格 | ESC 换码 |
ACK 承认 | DC1 设备控制1 | FS 文字分隔符 |
BEL 报警 | DC2 设备控制2 | GS 组分隔符 |
BS 退一格 | DC3 设备控制3 | RS 记录分隔符 |
HT 横向列表 | DC4 设备控制4 | US 单元分隔符 |
LF 换行 | NAK 否定 | DEL 删除 |
键盘常用ASCII码 |
ESC键 VK_ESCAPE (27) 回车键: VK_RETURN (13) TAB键: VK_TAB (9) Caps Lock键: VK_CAPITAL (20) Shift键: VK_SHIFT ($10) Ctrl键: VK_CONTROL (17) Alt键: VK_MENU (18) 空格键: VK_SPACE ($20/32) 退格键: VK_BACK (8) 左徽标键: VK_LWIN (91) 右徽标键: VK_LWIN (92) 鼠标右键快捷键:VK_APPS (93) Insert键: VK_INSERT (45) 方向键(←): VK_LEFT (37) F1键: VK_F1 (112) Num Lock键: VK_NUMLOCK (144) Pause Break键: VK_PAUSE (19) |
博主ma6174对本博客文章(除转载的)享有版权,未经许可不得用于商业用途。转载请注明出处http://www.cnblogs.com/ma6174/
对文章有啥看法或建议,可以评论或发电子邮件到ma6174@163.com