开发者社区> 吞吞吐吐的> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

键盘、游戏、ASCII码引出的一系列问题

简介:
+关注继续查看

初学者就爱开发点小游戏,比如贪吃蛇、俄罗斯方块等,开发这种小游戏就必须有按键控制,一般情况下我们是直接用getch()函数接收按键,然后转换成对应的ASCII码,再通过与ASCII码比较判断用户到底是按了什么键,然后根据按键去执行相应的操作,比如移动、旋转。

但是最近实践我发现这其实没那么简单,举个例子:比如贪吃蛇,当用户按下“向上的方向键”时,要控制蛇往上走,为了说明问题,简化一点,如果按了向上的方向键则输出“up”,其他方向键类似。一般我们会去查ASCII码表(下面有),

 

 如图,向上的方向键是38,然后我们就会写出这么一个小程序:

 

复制代码
#include<stdio.h>
#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<stdio.h>
#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<stdio.h>
#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)
Home键: VK_HOME (36)
Page Up: VK_PRIOR (33)
PageDown: VK_NEXT (34)
End键: VK_END (35)
Delete键: VK_DELETE (46)

方向键(←): VK_LEFT (37)
方向键(↑): VK_UP (38)
方向键(→): VK_RIGHT (39)
方向键(↓): VK_DOWN (40)

F1键: VK_F1 (112)
F2键: VK_F2 (113)
F3键: VK_F3 (114)
F4键: VK_F4 (115)
F5键: VK_F5 (116)
F6键: VK_F6 (117)
F7键: VK_F7 (118)
F8键: VK_F8 (119)
F9键: VK_F9 (120)
F10键: VK_F10 (121)
F11键: VK_F11 (122)
F12键: VK_F12 (123)

Num Lock键: VK_NUMLOCK (144)
小键盘0: VK_NUMPAD0 (96)
小键盘1: VK_NUMPAD0 (97)
小键盘2: VK_NUMPAD0 (98)
小键盘3: VK_NUMPAD0 (99)
小键盘4: VK_NUMPAD0 (100)
小键盘5: VK_NUMPAD0 (101)
小键盘6: VK_NUMPAD0 (102)
小键盘7: VK_NUMPAD0 (103)
小键盘8: VK_NUMPAD0 (104)
小键盘9: VK_NUMPAD0 (105)
小键盘.: VK_DECIMAL (110)
小键盘*: VK_MULTIPLY (106)
小键盘+: VK_MULTIPLY (107)
小键盘-: VK_SUBTRACT (109)
小键盘/: VK_DIVIDE (111)

Pause Break键: VK_PAUSE (19)
Scroll Lock键: VK_SCROLL (145)

 

 


博主ma6174对本博客文章(除转载的)享有版权,未经许可不得用于商业用途。转载请注明出处http://www.cnblogs.com/ma6174/

对文章有啥看法或建议,可以评论或发电子邮件到ma6174@163.com


本文转自ma6174博客园博客,原文链接:http://www.cnblogs.com/ma6174/archive/2011/12/18/2291759.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
C语言——函数的综合运用。自定义函数,gotoxy清屏函数与HideCursor隐藏光标,防闪屏,共同制作打飞机游戏。
①在变量中,我们必须进行定义赋值初始化后,才能在程序中使用,所以需要一个“地方”,整理好这些变量,在程序中整洁一些void startup() //数据初始化②打出画面中所显示的所需代码,也给一个函数void show() //显示画面③在游戏运行中,飞机的移动,发射等操作必须使用键盘,此时就要进行输入判断,给出相应的函数,实行不同的命令 ,其中分为两种,一种是程序运行时对输入做出变化,另一种是不变化void updateWithoutInput() //与用户输入无关的更新。
0 0
复习单片机:矩阵按键(内含1 矩阵按键介绍+2 硬件设计+3 软件设计+4原始代码+5 实验现象)
复习单片机:矩阵按键(内含1 矩阵按键介绍+2 硬件设计+3 软件设计+4原始代码+5 实验现象)
0 0
复习单片机:流水灯(内含2种方法(左移操作符法+crol法)+设计思路+原始代码)
复习单片机:流水灯(内含2种方法(左移操作符法+crol法)+设计思路+原始代码)
0 0
【Python 百炼成钢】错位键盘、单词的长度、字母重排
【Python 百炼成钢】错位键盘、单词的长度、字母重排
0 0
c++【键盘读入操作】,两种方法做小游戏的控制摇杆
c++【键盘读入操作】,两种方法做小游戏的控制摇杆
0 0
如何在小游戏使用键盘进行输入
本文主要内容是在微信小游戏制作工具中使用“键盘”插件,来实现玩家在小游戏中通过键盘进行输入操作的功能。
0 0
C语言 - 实现字符从两端移动,向中间汇聚(动态效果)
C语言 - 实现字符从两端移动,向中间汇聚(动态效果)
0 0
C语言中的‘‘\0“对应键盘上哪一个按键
C语言中的‘‘\0“对应键盘上哪一个按键
0 0
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载