马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 孤星8 于 2024-6-7 16:42 编辑
在命令行窗口下,执行我的程序可以用左键和右键移动太空船(其实只是^符号),暂时不能发射武器。
我是用汇编写的,用的GetKeyState来读取键盘。
- format PE console
- entry start
- include 'win32a.inc'
- MOST_LEFT equ 1
- MOST_RIGHT equ 70
- START_COL equ 35
- ;START_ROW equ 20
- section '.data' data readable writeable
- _newpos dd START_COL
- _oldpos dd START_COL
- _spaceship db '^'
- _bullet db '|'
- _blank db ' '
- _ansi_cls db 27,'[H',27,'[J'
- _ansi_cls_len = $ - _ansi_cls
- _ansi_reset db 27,'[0m' ; ANSI escape code (reset color)
- _ansi_reset_len = $ - _ansi_reset
- _instruction db 'Press Left and Right arrow to move; ESC to quit'
- _instruction_len = $ - _instruction
- _stdout dd ?
- _mode dd ?
- _number rb 10
- _ansi_goto_new rb 9 ; 27,'[00;00H'
- _ansi_goto_old rb 9
- _count dd ?
- ;CSI n ; m H
- ;Moves the cursor to row n, column m. The values are 1-based, and default to 1 (top left corner) if omitted.
- ;VK_ESCAPE 0x1B ESC key
- ;VK_LEFT 0x25 LEFT ARROW key
- ;VK_UP 0x26 UP ARROW key
- ;VK_RIGHT 0x27 RIGHT ARROW key
- ;VK_DOWN 0x28 DOWN ARROW key
- section '.code' code readable executable
- start:
- push -11
- call [GetStdHandle]
- mov dword [_stdout], eax
- push _mode
- push [_stdout]
- call [GetConsoleMode]
- or [_mode], 4 ;ENABLE_VIRTUAL_TERMINAL_PROCESSING
- push [_mode]
- push [_stdout]
- call [SetConsoleMode]
- push 0
- push 0
- push _ansi_cls_len
- push _ansi_cls
- push dword [_stdout]
- call [WriteConsole] ;Clear entire screen
- push 0
- push 0
- push _instruction_len
- push _instruction
- push dword [_stdout]
- call [WriteConsole] ;Print keyboard instruction
- mov eax, dword [_newpos]
- call itoa
- mov [_count], ebx
- call DrawSpaceship
- .loop:
- push 100
- call [Sleep]
- push 0x1B ;ESC key
- call [GetKeyState]
- bt eax, 15 ; If the high-order bit is 1, the key is down; otherwise, it is up
- jc .done
- push 0x25 ;LEFT ARROW key
- call [GetKeyState]
- bt eax, 15
- jc .left
- push 0x27 ;RIGHT ARROW key
- call [GetKeyState]
- bt eax, 15
- jc .right
- jmp .loop
- .left:
- call SaveValue
- sub [_newpos], 1
- cmp [_newpos], MOST_LEFT
- jl .keepleft
- mov eax, dword [_newpos]
- call itoa
- mov [_count], ebx
- ;push 0
- ;push 0
- ;push ebx
- ;push _number
- ;push dword [_stdout]
- ;call [WriteConsole]
- call DrawSpaceship
- jmp .loop
- .keepleft:
- mov [_newpos], MOST_LEFT
- jmp .loop
- .right:
- call SaveValue
- add [_newpos], 1
- cmp [_newpos], MOST_RIGHT
- jg .keepright
- mov eax, dword [_newpos]
- call itoa
- mov [_count], ebx
- ;push 0
- ;push 0
- ;push ebx
- ;push _number
- ;push dword [_stdout]
- ;call [WriteConsole]
- call DrawSpaceship
- jmp .loop
- .keepright:
- mov [_newpos], MOST_RIGHT
- jmp .loop
- .done:
- push 0
- call [ExitProcess]
- itoa: ;-) Nice code snippet by Pauli Lindgren (https://pkl.paldex.fi/)
- ; INPUT: EAX
- ; OUTPUT: _number
- ; LEN OF OUTPUT: EBX
- mov ecx, 10
- xor ebx, ebx
- .divide:
- xor edx, edx
- div ecx
- push edx
- inc ebx
- test eax, eax
- jnz .divide
- mov ecx, ebx
- lea esi, [_number]
- .next:
- pop eax
- add al, '0'
- mov [esi], al
- inc esi
- loop .next
- ret
- SaveValue: ;Save old spaceship position
- mov eax, [_newpos]
- mov [_oldpos], eax
- mov ecx, 8
- lea edi, [_ansi_goto_old]
- lea esi, [_ansi_goto_new]
- rep movsb
- ret
- DrawSpaceship:
- mov ecx, [_count]
- lea edi, [_ansi_goto_new]
- mov byte [edi], 27
- mov byte [edi+1], '['
- mov byte [edi+2], '2' ;START_ROW = 20
- mov byte [edi+3], '0'
- mov byte [edi+4], ';'
- add edi,5
- lea esi, [_number]
- rep movsb
- mov byte [edi], 'H'
- mov byte [edi+1], 0
- push 0
- push 0
- push 8
- push _ansi_goto_new ;New position
- push dword [_stdout]
- call [WriteConsole]
- push 0
- push 0
- push 1
- push _spaceship
- push dword [_stdout]
- call [WriteConsole] ;Draw new spaceship
- push 0
- push 0
- push 8
- push _ansi_goto_old ;Old position
- push dword [_stdout]
- call [WriteConsole]
- push 0
- push 0
- push 1
- push _blank
- push dword [_stdout]
- call [WriteConsole] ;Delete old spaceship
- ret
- section '.idata' import readable writeable
- library kernel32, 'KERNEL32.DLL', \
- user32, 'USER32.DLL'
- import kernel32,\
- GetStdHandle, 'GetStdHandle', \
- WriteConsole, 'WriteConsoleA', \
- ExitProcess,'ExitProcess', \
- GetConsoleMode, 'GetConsoleMode',\
- SetConsoleMode, 'SetConsoleMode',\
- Sleep, 'Sleep'
- import user32,\
- GetKeyState, 'GetKeyState'
复制代码
|
|