org 100h
jmp start
s_size equ 7
snake dw s_size dup(0)
tail dw ?
left equ 4bh
right equ 4dh
up equ 48h
down equ 50h
cur_dir db right
wait_time dw 0
msg1 db " Snake game", 0dh,0ah,0ah
db " Yilani on oklari ile kontrol et.", 0dh,0ah,0ah
db " Duvarlara degersen yanarsin!!!", 0dh,0ah, 0ah
db " Esc programi sonlandirir.", 0dh,0ah,0ah,0ah
db " Baslamak icin bir tusa bas.$"
msg3 db "", 0dh,0ah, 0ah,0ah, 0ah,0ah,0ah, 0ah,0ah,0ah, 0ah,0ah,0ah, 0ah,0ah, 0ah, 0ah, 0ah,
db " !!GAME OVER!!", 0dh,0ah,0ah, 0ah, 0ah, 0ah,0ah, 0ah,0ah,
db " $"
start:
; print welcome message:
mov dx, offset msg1
mov ah, 9
int 21h
; wait for any key:
mov ah, 00h
int 16h
mov ax, 0xB800 ; Video memory segment
mov es, ax ; Set ES segment to video memory
es: mov [09b4h],'?'
es: mov [0848h],'0'
es: mov [06b0h],'0'
es: mov [01E8h],'0'
; hide text cursor:
mov ah, 1
mov ch, 2bh
mov cl, 0bh
int 10h
game_loop:
; === select first video page
mov al, 0
mov ah, 05h
int 10h
mov dx, snake[0]
; set cursor at dl,dh
mov ah, 02h
int 10h
; print 'o' at the location:
mov al, 'o'
mov ah, 09h
mov bl, 0eh
mov cx, 1
int 10h
; === keep the tail:
mov ax, snake[s_size * 2 - 2]
mov tail, ax
call move_snake
; === hide old tail:
mov dx, tail
; set cursor at dl,dh
mov ah, 02h
int 10h
; print '.' at the old location:
mov al, ' '
mov ah, 09h
mov bl, 0eh
mov cx, 1
int 10h
check_for_key:
; === check for player commands:
mov ah, 01h
int 16h
jz no_key
mov ah, 00h
int 16h
cmp al, 1bh ; esc - key?
je stop_game ;
mov cur_dir, ah
no_key:
; === wait a few moments here:
; get number of clock ticks
; (about 18 per second)
; since midnight into cx:dx
mov ah, 00h
int 1ah
cmp dx, wait_time
jb check_for_key
add dx, 4
mov wait_time, dx
; === eternal game loop:
jmp game_loop
stop_game:
; show cursor back:
mov ah, 1
mov ch, 0bh
mov cl, 0bh
int 10h
ret
move_snake proc near
; set es to bios info segment:
mov ax, 40h
mov es, ax
; point di to tail
mov di, s_size * 2 - 2
; move all body parts
; (last one simply goes away)
mov cx, s_size-1
move_array:
mov ax, snake[di-2]
mov snake[di], ax
sub di, 2
loop move_array
cmp cur_dir, left
je move_left
cmp cur_dir, right
je move_right
cmp cur_dir, up
je move_up
cmp cur_dir, down
je move_down
jmp stop_move ; no direction.
move_left:
mov al, b.snake[0]
dec al
mov b.snake[0], al
cmp al, -1
jne stop_move
mov al, es:[4ah] ; col number.
dec al
call game_over ; return to right.
jmp stop_move
move_right:
mov al, b.snake[0]
inc al
mov b.snake[0], al
cmp al, es:[09b4h]
cmp al, es:[4ah] ; col number.
jb stop_move
call game_over ; return to left.
jmp stop_move
move_up:
mov al, b.snake[1]
dec al
mov b.snake[1], al
cmp al, -1
jne stop_move
mov al, es:[84h] ; row number -1.
call game_over ; return to bottom.
jmp stop_move
move_down:
mov al, b.snake[1]
inc al
mov b.snake[1], al
cmp al, es:[84h] ; row number -1.
jbe stop_move
call game_over ; return to top.
jmp stop_move
stop_move:
ret
grow_snake:
ret
game_over:
mov dx, offset msg3
mov ah, 9
int 21h
; wait for any key:
mov ah, 00h
int 16h
move_snake endp
我尝试在snake到达这些内存位置时将其增长:
es: mov [09b4h],'?'
es: mov [0848h],'0'
es: mov [06b0h],'0'
es: mov [01E8h],'0'
但是我做不到。我的第一个计划是在stop_game中检查它,并在那里调用grow_snake,但无论我如何尝试,我都没有工作。但是不能对grow_snake部分triend到inc_size做任何事情,但是它也不工作。
我该如何检查snake是否到达了我打印的东西的内存位置并相应地增长?
谢谢你。
1条答案
按热度按时间zour9fqk1#
更新
如果你不介意的话,我在屏幕上打印了蛇的头后写了
CheckFood proc
。它将head的XY坐标转换为内存中的偏移量,并搜索数组targetInMem
中是否存在相同的地址。我不知道这是否是你的答案。这仅仅是一个例子。屏幕坐标转换为视频内存偏移。
下面的例子