如何利用int 16h/1和int 16h/0实现同PC双人双盒同步移动?
用int 16h/1和int 16h/0实现双玩家同步按键操作
核心逻辑
int 16h/1(功能号1)是非阻塞式键盘检查,调用后通过ZF标志位反馈状态:ZF=1代表键盘缓冲区无按键,ZF=0代表有按键等待读取。int 16h/0(功能号0)是阻塞式按键读取,但配合int 16h/1的前置检查,就能在游戏主循环里轮询处理所有待触发的按键,避免单个按键阻塞整个程序,从而实现双玩家同步操作。
实现步骤
分配独立按键组:给两名玩家设置互不冲突的操作按键,比如:
- 玩家1:W(上)、S(下)、A(左)、D(右)
- 玩家2:方向键↑、↓、←、→
主循环轮询按键:在游戏主循环中重复执行以下流程:
- 调用
int 16h/1检查是否有按键待读取 - 若有按键(ZF=0),调用
int 16h/0读取按键的ASCII码与扫描码 - 根据按键类型,更新对应玩家盒子的坐标
- 若无按键(ZF=1),直接执行屏幕刷新逻辑
- 调用
处理扩展按键:方向键、功能键属于扩展按键,调用
int 16h/0时会先返回0E0h(扩展前缀),需再次调用int 16h/0才能获取实际扫描码,要单独处理这种情况。
汇编代码示例
; 假设已通过int 10h/0初始化320x200 256色视频模式 ; 玩家1盒子坐标:bx(X轴)、cx(Y轴) ; 玩家2盒子坐标:dx(X轴)、si(Y轴) MAIN_LOOP: ; 检查键盘缓冲区是否有按键 mov ah, 1 int 16h jz REFRESH_SCREEN ; ZF=1,无按键,跳转到屏幕刷新 ; 读取按键(AH=扫描码,AL=ASCII码) mov ah, 0 int 16h ; 处理玩家1的WASD按键 cmp al, 'W' je PLAYER1_UP cmp al, 'S' je PLAYER1_DOWN cmp al, 'A' je PLAYER1_LEFT cmp al, 'D' je PLAYER1_RIGHT ; 处理玩家2的方向键(扩展按键) cmp ah, 0E0h jne CHECK_NEXT_KEY ; 不是扩展前缀,跳过 ; 读取方向键实际扫描码 mov ah, 0 int 16h cmp ah, 48h ; 方向键↑ je PLAYER2_UP cmp ah, 50h ; 方向键↓ je PLAYER2_DOWN cmp ah, 4Bh ; 方向键← je PLAYER2_LEFT cmp ah, 4Dh ; 方向键→ je PLAYER2_RIGHT CHECK_NEXT_KEY: jmp MAIN_LOOP ; 继续检查下一个按键 ; 玩家1移动逻辑 PLAYER1_UP: dec cx jmp MAIN_LOOP PLAYER1_DOWN: inc cx jmp MAIN_LOOP PLAYER1_LEFT: dec bx jmp MAIN_LOOP PLAYER1_RIGHT: inc bx jmp MAIN_LOOP ; 玩家2移动逻辑 PLAYER2_UP: dec si jmp MAIN_LOOP PLAYER2_DOWN: inc si jmp MAIN_LOOP PLAYER2_LEFT: dec dx jmp MAIN_LOOP PLAYER2_RIGHT: inc dx jmp MAIN_LOOP REFRESH_SCREEN: ; 此处编写清除旧盒子、绘制新盒子的屏幕更新代码 ; ... jmp MAIN_LOOP
关键注意点
- 持续轮询:主循环要反复检查按键,确保所有待处理的按键都被读取,避免按键丢失。
- 扩展按键处理:必须处理扩展前缀
0E0h,否则无法正确识别方向键等扩展按键。 - 同步刷新:屏幕刷新要在按键处理完成后执行,保证两名玩家的盒子位置同步更新。
内容的提问来源于stack exchange,提问作者zizo
相关产品推荐
相关产品推荐

