Assembly 在汇编中进行乒乓球游戏时,如何一次获得多个按键的输入?
我是初学者,所以这段代码可能不太好,我用了Assembly 在汇编中进行乒乓球游戏时,如何一次获得多个按键的输入?,assembly,keyboard,emu8086,pong,Assembly,Keyboard,Emu8086,Pong,我是初学者,所以这段代码可能不太好,我用了int16h来做这段代码,但我对这段int不太了解。我刚发现你不可能一次击多个键;有什么帮助吗? 这个代码的问题是一次只能移动一块板,我需要两块板。如何检查多个输入 以下是所有想要它的人的代码: 这个代码的问题是一次只能移动一块板,我需要两块板 同时性的感觉来自于快速,真正的快速。计算机中的大多数东西都是连续工作的,但我们认为许多事情是并行发生的 你的支票代码很好。一块板使用q键和s键,另一块板使用向上键和向下键。 一旦有键可用,键盘BIOS功能00h将
int16h
来做这段代码,但我对这段int
不太了解。我刚发现你不可能一次击多个键;有什么帮助吗?这个代码的问题是一次只能移动一块板,我需要两块板。如何检查多个输入 以下是所有想要它的人的代码: 这个代码的问题是一次只能移动一块板,我需要两块板 同时性的感觉来自于快速,真正的快速。计算机中的大多数东西都是连续工作的,但我们认为许多事情是并行发生的 你的支票代码很好。一块板使用q键和s键,另一块板使用向上键和向下键。
一旦有键可用,键盘BIOS功能00h将立即检索该键,您的程序将相应地更新图形。但是如果你的图形输出程序花费的时间太长,那么玩家就会开始认为键盘太慢了 查看您的图形例程,我看到您使用视频BIOS功能0Ch在屏幕上放置像素。这是缓慢的,尤其是痛苦的,因为你在最简单的图形屏幕上播放,你只需
MOV
一个字节就可以画出一个像素
在需要快速图形的程序中,将ES
段寄存器点永久地放在视频缓冲区是非常有利的
mov ax, 0A000h
mov es, ax
cld ; Because of the use of STOSB
这就是清除屏幕所需的全部内容:
ClearScreen:
xor di, di
mov cx, 64000
mov al, 0
rep stosb
ret
这是绘制水平线(160100)-(200100)的方式:
另一个答案是关于一个多人游戏,其中没有一个玩家一直按专用键,从而占据键盘。尽管这种情况非常合理,但您可能希望允许玩家长时间按住钥匙。为此,我们可以用自己的处理程序替代BIOS/DOS提供的键盘处理程序 键盘上的每个键都与一个唯一的8位数字相关联,我们称之为扫描码。
只要按下一个键,键盘就会在端口60h处提供相关键的扫描码。键盘还生成一个中断09h。此中断的处理程序可以检查扫描代码并以任何方式处理它。下面的演示程序就是这样做的。
当按下某个键时,扫描码是一个最高位关闭的字节。释放钥匙时,扫描码是一个最高位为on的字节。对于按压和释放,其他7位保持不变 应该注意的是,尽管对于你的乒乓球游戏来说很好,但是包含的替换处理程序是一个极简的处理程序。复杂的处理程序还将考虑前缀为E0h或E1h代码的扩展扫描代码 该程序有附加注释,因此您可以轻松了解正在发生的事情。代码使用FASM语法。演示在真实DOS环境和DOSBox(0.74)中运行正常
程序的键列表记录键盘上所有键的当前状态。如果字节为0,则未按下该键。如果一个字节是1,则该键当前正在被按下。这个问题应该被上千次投票,仅仅是为了在汇编中编写游戏的想法……学校项目:p无论如何,在汇编中打乒乓球真的是很有价值的回答你的问题吗?我想会的。也许老实说,我会试着学习港口主义!但问题是不能同时按下两个键来同时移动两块板,所以idk如果这样可以解决这个问题。谢谢,不过我会用你的代码让我的项目感觉好20倍。顺便问一下,我如何改变板的宽度?此外,我对es或rep stosb也不太了解,这会有问题吗?@orraz1如果您对
es
或rep stosb
不太了解,请了解8086的完整指令集。它不太复杂;它包含大约50条指令,与当前x86的指令集相比,这算不了什么。我相信我的第二个答案会解决你同时按下按键的问题!这是胡说八道,谢谢,我会试着把这段代码翻译成tasm,并把它放在我的项目tysm.Sry中来回答问题,但是“DOS.GetInterruptVector”和“DOS.GetInterruptVector”到底是什么?还有,你在这段代码中到底在做什么?Nvm我现在明白了omfg这是Genius你有关于如何使用int 21h 25中断的文章吗?我知道它是如何工作的,只是不知道你如何使用它。顺便问一下,我应该把机具中断代码放在哪里?
ClearScreen:
xor di, di
mov cx, 64000
mov al, 0
rep stosb
ret
mov dl, 15 ; BrightWhite
mov cx, 51 ; 51 pixels from 160 to 200
mov bx, 160 ; X
mov ax, 100 ; Y
call DrawLine
...
DrawLine:
push dx
mov di, 320 ; BytesPerScanline
mul di
add ax, bx
mov di, ax ; Address DI = (Y * BPS) + X
pop ax ; Color AL
rep stosb
ret
; Multi-player Keyboard Input (c) 2021 Sep Roland
ORG 256 ; Output will be a .COM program
mov ax, 3509h ; DOS.GetInterruptVector
int 21h ; -> ES:BX
push es bx ; (1)
mov dx, Int09
mov ax, 2509h ; DOS.SetInterruptVector
int 21h
mov ax, 0013h ; BIOS.SetVideoMode 320x200 (256 colors)
int 10h
mov ax, 0A000h ; Video buffer
mov es, ax
cld ; So we can use the string primitive STOSB
Cont:
mov si, 160 ; Width
mov di, 100 ; Height
mov al, 0 ; Black
cmp [KeyList+48h], al ; Up
je .a
mov al, 2 ; Green
.a: mov cx, 160 ; X
mov dx, 0 ; Y
call Paint
mov al, 0 ; Black
cmp [KeyList+50h], al ; Down
je .b
mov al, 14 ; Yellow
.b: mov cx, 160 ; X
mov dx, 100 ; Y
call Paint
mov al, 0 ; Black
cmp [KeyList+11h], al ; aZerty / qWerty
je .c
mov al, 4 ; Red
.c: mov cx, 0 ; X
mov dx, 0 ; Y
call Paint
mov al, 0 ; Black
cmp [KeyList+1Fh], al ; S
je .d
mov al, 1 ; Blue
.d: mov cx, 0 ; X
mov dx, 100 ; Y
call Paint
cmp byte [KeyList+1], 0 ; ESC
je Cont
pop dx ds ; (1)
mov ax, 2509h ; DOS.SetInterruptVector
int 21h
mov ax, 4C00h ; DOS.Terminate
int 21h
; --------------------------------------
Int09:
push ax bx
in al, 60h
mov ah, 0
mov bx, ax
and bx, 127 ; 7-bit scancode goes to BX
shl ax, 1 ; 1-bit press/release goes to AH
xor ah, 1 ; -> AH=1 Press, AH=0 Release
mov [cs:KeyList+bx], ah
mov al, 20h ; The non specific EOI (End Of Interrupt)
out 20h, al
pop bx ax
iret
; --------------------------------------
; IN (al,cx,dx,si,di)
Paint:
push cx dx di ; AL=Color CX=X DX=Y SI=Width DI=Height
push ax ; (1)
mov ax, 320 ; BytesPerScanline
mul dx
add ax, cx ; (Y * BPS) + X
mov dx, di
mov di, ax
pop ax ; (1)
.a: mov cx, si
rep stosb
sub di, si
add di, 320
dec dx
jnz .a
pop di dx cx
ret
; --------------------------------------
KeyList db 128 dup 0
KeyList db 128 dup 0