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

x86汇编实现双人Tron游戏双玩家同步移动的问题

解决双人Tron游戏双玩家同时移动的问题

当前代码的核心问题是单次仅处理一个按键输入:使用int 16h 00h读取按键时会清空缓冲区的单个按键,导致同时按住两个键时,后读取的按键会覆盖前一个的处理逻辑,无法同时跟踪两个玩家的输入状态。

解决方案

改为跟踪玩家的移动方向状态,先一次性读取键盘缓冲区中所有待处理的按键,更新两个玩家的当前方向变量,再统一处理两个玩家的移动逻辑,确保两者的输入都被正确响应。


具体实现步骤

  1. 定义方向状态变量
    新增两个字节变量,记录每个玩家的当前移动方向:

    ; 方向定义:0=停止,1=左,2=右,3=上,4=下
    plyr1_dir db 0
    plyr2_dir db 0
    
  2. 重写move_players过程
    分两步执行:

    • 第一步:遍历键盘缓冲区所有按键,更新玩家方向(支持按键按下/抬起的状态切换)
    • 第二步:根据方向变量分别处理两个玩家的移动、碰撞检测与绘制

修改后的完整代码:

move_players proc
    ; 第一步:读取所有键盘输入,更新玩家方向状态
    read_keys:
        mov ah, 01h ; 检查缓冲区是否有按键
        int 16h
        jz process_movement ; 无按键则进入移动处理

        mov ah, 00h ; 读取按键(AH=扫描码,AL=ASCII码)
        int 16h

        ; 玩家1 WASD按键处理(按下)
        cmp ah, 1Eh ; 'A'键扫描码
        je set_plyr1_left
        cmp ah, 20h ; 'S'键扫描码
        je set_plyr1_down
        cmp ah, 11h ; 'W'键扫描码
        je set_plyr1_up
        cmp ah, 21h ; 'D'键扫描码
        je set_plyr1_right

        ; 玩家1 WASD按键处理(抬起)
        cmp ah, 1Eh+80h ; 'A'键抬起扫描码
        je reset_plyr1_move
        cmp ah, 20h+80h ; 'S'键抬起扫描码
        je reset_plyr1_move
        cmp ah, 11h+80h ; 'W'键抬起扫描码
        je reset_plyr1_move
        cmp ah, 21h+80h ; 'D'键抬起扫描码
        je reset_plyr1_move

        ; 玩家2 方向键处理(按下)
        cmp ah, 75h ; 左方向键扫描码
        je set_plyr2_left
        cmp ah, 72h ; 上方向键扫描码
        je set_plyr2_up
        cmp ah, 77h ; 右方向键扫描码
        je set_plyr2_right
        cmp ah, 70h ; 下方向键扫描码
        je set_plyr2_down

        ; 玩家2 方向键处理(抬起)
        cmp ah, 75h+80h ; 左方向键抬起扫描码
        je reset_plyr2_move
        cmp ah, 72h+80h ; 上方向键抬起扫描码
        je reset_plyr2_move
        cmp ah, 77h+80h ; 右方向键抬起扫描码
        je reset_plyr2_move
        cmp ah, 70h+80h ; 下方向键抬起扫描码
        je reset_plyr2_move

        ; 其他按键忽略,继续读取下一个
        jmp read_keys

    ; 设置玩家1方向的分支
    set_plyr1_left:
        mov byte ptr [plyr1_dir], 1
        jmp read_keys
    set_plyr1_right:
        mov byte ptr [plyr1_dir], 2
        jmp read_keys
    set_plyr1_up:
        mov byte ptr [plyr1_dir], 3
        jmp read_keys
    set_plyr1_down:
        mov byte ptr [plyr1_dir], 4
        jmp read_keys
    reset_plyr1_move:
        mov byte ptr [plyr1_dir], 0
        jmp read_keys

    ; 设置玩家2方向的分支
    set_plyr2_left:
        mov byte ptr [plyr2_dir], 1
        jmp read_keys
    set_plyr2_right:
        mov byte ptr [plyr2_dir], 2
        jmp read_keys
    set_plyr2_up:
        mov byte ptr [plyr2_dir], 3
        jmp read_keys
    set_plyr2_down:
        mov byte ptr [plyr2_dir], 4
        jmp read_keys
    reset_plyr2_move:
        mov byte ptr [plyr2_dir], 0
        jmp read_keys

    ; 第二步:根据方向状态处理玩家1移动
    process_movement:
        mov al, [plyr1_dir]
        cmp al, 1
        je move_plyr1_left
        cmp al, 2
        je move_plyr1_right
        cmp al, 3
        je move_plyr1_up
        cmp al, 4
        je move_plyr1_down
        jmp process_plyr2

    move_plyr1_left:
        call plyr1_trace
        mov ax, [plyr1X]
        dec ax
        mov [plyr1X], ax
        call plyr1_check
        call plyr1_draw
        jmp process_plyr2
    move_plyr1_right:
        call plyr1_trace
        mov ax, [plyr1X]
        inc ax
        mov [plyr1X], ax
        call plyr1_check
        call plyr1_draw
        jmp process_plyr2
    move_plyr1_up:
        call plyr1_trace
        mov ax, [plyr1Y]
        dec ax
        mov [plyr1Y], ax
        call plyr1_check
        call plyr1_draw
        jmp process_plyr2
    move_plyr1_down:
        call plyr1_trace
        mov ax, [plyr1Y]
        inc ax
        mov [plyr1Y], ax
        call plyr1_check
        call plyr1_draw
        jmp process_plyr2

    ; 第三步:根据方向状态处理玩家2移动
    process_plyr2:
        mov al, [plyr2_dir]
        cmp al, 1
        je move_plyr2_left
        cmp al, 2
        je move_plyr2_right
        cmp al, 3
        je move_plyr2_up
        cmp al, 4
        je move_plyr2_down
        jmp move_end

    move_plyr2_left:
        call plyr2_trace
        mov ax, [plyr2X]
        dec ax
        mov [plyr2X], ax
        call plyr2_check
        call plyr2_draw
        jmp move_end
    move_plyr2_right:
        call plyr2_trace
        mov ax, [plyr2X]
        inc ax
        mov [plyr2X], ax
        call plyr2_check
        call plyr2_draw
        jmp move_end
    move_plyr2_up:
        call plyr2_trace
        mov ax, [plyr2Y]
        dec ax
        mov [plyr2Y], ax
        call plyr2_check
        call plyr2_draw
        jmp move_end
    move_plyr2_down:
        call plyr2_trace
        mov ax, [plyr2Y]
        inc ax
        mov [plyr2Y], ax
        call plyr2_check
        call plyr2_draw
        jmp move_end

    move_end:
        ret
move_players ENDP

关键改进点

  • 一次性读取键盘缓冲区所有按键,确保两个玩家的输入都被捕获,不会互相覆盖
  • 用方向变量持久化玩家的移动状态,支持按住按键持续移动、松开停止的逻辑
  • 分离输入处理与移动逻辑,先统一更新状态,再执行移动,保证双玩家同时响应

内容的提问来源于stack exchange,提问作者Jeszenői Bálint

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 09:17:06