You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TASM 8086汇编Pong游戏:左玩家按键松开后 paddle持续移动

解决TASM 8086 Pong游戏左玩家Paddle按键松开后持续移动的问题

问题根源

你的左玩家按键处理逻辑使用了int 16h ah=1h调用,这个指令存在两个核心问题:

  • 该调用是非阻塞查询键盘缓冲区是否有按键,按住按键时系统会自动向缓冲区重复填充该按键的ASCII码,哪怕松开按键,缓冲区残留的未处理数据会让代码持续执行移动逻辑。
  • 它只能检测按键是否被按下,无法获取按键释放的信号,因此无法判断用户已松开按键来停止移动。

右玩家逻辑正常,大概率是因为其采用了正确的按键读取方式(比如int 16h ah=0h)或处理了按键释放状态。

修复方案

根据需求不同,有两种常用修复方式:

方式1:改进按键读取逻辑(适合简单场景)

先查询是否有按键,再用int 16h ah=0h读取按键并清空缓冲区,无按键时不修改Paddle位置:

; Left Player's Paddle Movement
proc keys_p2
pusha
    mov [x_surface_p2],40

    ; 非阻塞查询是否有按键
    mov ah,1h
    int 16h
    jz no_key_p2 ; 无按键则跳过移动逻辑

    ; 读取按键并清空缓冲区(确保取出唯一按键)
    mov ah,0h
    int 16h
    
    cmp al,27 ; ESC键
    je endGame 

    cmp al,77h ; W键(Up)
    jne skip3_p2
        sub [y0_p2],2
        call the_cleaner_buffer
        jmp skip4_p2
        
skip3_p2:
    cmp al,73h ; S键(Down)
    jne skip4_p2
        add [y0_p2],2
        call the_cleaner_buffer
        jmp skip4_p2
        
skip4_p2:
    push [y0_p2]
    pop  [y_surface_p2] 

no_key_p2:
    CALL printPakman_p2

    popa
    ret
endp keys_p2

方式2:使用键盘中断检测按键按下/释放(适合按住持续移动场景)

如果要支持按住按键时Paddle持续移动、松开即停,需要通过键盘中断(INT 9)记录按键状态:

步骤1:定义按键状态变量(在数据段添加)

p2_up_pressed db 0   ; W键按下状态:1=按下,0=松开
p2_down_pressed db 0 ; S键按下状态:1=按下,0=松开

步骤2:替换键盘中断处理程序

; 键盘INT9中断处理程序
proc keyboard_int
pusha
    in al,60h ; 读取键盘扫描码
    test al,80h ; 检查是否为按键释放扫描码(最高位为1)
    jnz key_release

    ; 处理按键按下
    cmp al,11h ; W键扫描码
    je set_up_pressed
    cmp al,1Fh ; S键扫描码
    je set_down_pressed
    jmp end_key_int

set_up_pressed:
    mov [p2_up_pressed],1
    jmp end_key_int

set_down_pressed:
    mov [p2_down_pressed],1
    jmp end_key_int

key_release:
    and al,7Fh ; 清除释放标记,得到原始扫描码
    cmp al,11h
    je clear_up_pressed
    cmp al,1Fh
    je clear_down_pressed
    jmp end_key_int

clear_up_pressed:
    mov [p2_up_pressed],0
    jmp end_key_int

clear_down_pressed:
    mov [p2_down_pressed],0

end_key_int:
    mov al,20h ; 发送EOI信号给PIC,结束中断
    out 20h,al
    popa
    iret
endp keyboard_int

步骤3:修改左玩家移动逻辑

proc keys_p2
pusha
    mov [x_surface_p2],40

    ; 根据按键状态移动Paddle
    cmp byte [p2_up_pressed],1
    jne check_down
        sub [y0_p2],2
        call the_cleaner_buffer

check_down:
    cmp byte [p2_down_pressed],1
    jne skip_move
        add [y0_p2],2
        call the_cleaner_buffer
        
skip_move:
    push [y0_p2]
    pop  [y_surface_p2] 
    CALL printPakman_p2

    popa
    ret
endp keys_p2

内容的提问来源于stack exchange,提问作者ChickenRei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 03:01:00