⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1.asm

📁 汇编语言windows32位编程
💻 ASM
📖 第 1 页 / 共 2 页
字号:
    pop  g_pTail
    
    push 0
    pop  g_NodeCount
    
    mov ecx,8
   
    L5:  
     push ecx
    L4:
    invoke Random,50 
    mov   x2,eax
    invoke Random,50
    mov y2,eax
    mov edx,50
    mul edx
    add eax,x2
    mov ebx,OFFSET g_Map
    add ebx,eax
    mov al,BYTE PTR [ebx]
    cmp al,  MAP_NONE
     jne L4
    mov BYTE PTR[ebx],MAP_WALL
    pop ecx
    loop L5
    
    invoke DrawMap
    invoke Flip
    
    push DR_RIGHT
    pop  g_Direct    
    push GS_PLAY
    pop  g_GameState
    invoke SetTimer,g_hWnd,TIMER1_ID,TIMER1_INTERVAL,addr TimeProc     ;创建定时器1 :120ms
    invoke SetTimer,g_hWnd,TIMER2_ID,TIMER2_INTERVAL,addr TimeProc2    ;创建定时器2 :3s
    
    ret

NewGame endp


DrawMap proc                                 ;画地图的子程序
LOCAL x,y :DWORD                             ;注意地图的底,其实已经画好了
LOCAL i,j :DWORD                             ;这个子程序就是在底上画上“豆子”和“蛇”
LOCAL Pos:DWORD
LOCAL pNode :DWORD

    invoke Rectangle,g_hBackDc,0,0,400,400
  
    mov j, 0             ;j是行,先=0
    mov Pos, 0           ;相对的坐标
@@1:
    mov i, 0             ;i是列,=0
@@2:   
    mov ebx ,offset g_Map 
    add ebx,Pos
    mov al,byte ptr [ebx]
    
    .if al == MAP_WOOD         ;画豆'
        
        mov eax, i
        shl eax,3 ; i*8
        mov x , eax
        mov eax ,j
        shl eax ,3 ; j*8
        mov y,eax
       
        invoke BitBlt,g_hBackDc,x,y,8,8,g_hImgDc,8,0,SRCCOPY
        
    .elseif al==MAP_WALL
   
        mov eax, i
        shl eax,3 ; i*8
        mov x , eax
        mov eax ,j
        shl eax ,3 ; j*8
        mov y,eax
        invoke BitBlt,g_hBackDc,x,y,8,8,g_hImgwallDc,0,0,SRCCOPY
    .endif
    inc i
    inc Pos
    cmp i,50            ;不足一列,继续循环
    jnz @@2           
    
    inc j               ;一列完,行加1
    cmp j,50            ;行没到50,继续循环
    jnz @@1
      
    ;-- Draw Snake      画蛇
    mov ebx , g_pHead                      
@@3:
    cmp ebx , NULL
    jz  @@Break
    mov pNode ,ebx      ;保存蛇头的值  ???问题蛇头是怎么处理的,是不是4个字节4个字节的数据结构
    mov eax ,[ebx+4]    ;x
    shl eax , 3         ;x*8
    mov x,eax
    mov eax, [ebx+8]    ;y*8
    shl eax,3
    mov y,eax
    mov eax ,[ebx+12]   ;next
    mov pNode ,eax      ;
    invoke BitBlt,g_hBackDc,x,y,8,8,g_hImgDc,0,0,SRCCOPY
    
    mov ebx,pNode
    
    jmp @@3   

@@Break:
  
    ret

DrawMap endp

KeyDownProc proc dwKey :DWORD

   .if g_GameState != GS_PLAY 
       ret
   .endif 
   
   mov eax,dwKey
   .if eax == VK_UP                  ;如果按下的是上
       .if g_Direct != DR_DOWN       ;蛇头不是向后的,才行
           push DR_UP
           pop  g_Direct             ;蛇头改为朝上
       .endif
   .elseif eax == VK_DOWN            ;如果按下的是下
       .if g_Direct != DR_UP         ;蛇头不是向上的,才行
           push DR_DOWN
           pop  g_Direct             ;蛇头改为朝下
       .endif   
   .elseif eax == VK_LEFT            ;如果按下的是左
       .if g_Direct != DR_RIGHT      ;蛇头不是向右的,才行
           push DR_LEFT
           pop  g_Direct             ;蛇头改为朝左
       .endif
   .elseif eax == VK_RIGHT           ;如果按下的是右
       .if g_Direct != DR_LEFT       ;蛇头不是向左的,才行
           push DR_RIGHT
           pop  g_Direct             ;蛇头改为朝右
       .endif    
   .endif 
   ret
   
KeyDownProc endp


FreeGame proc                                  ;释放程序中创建的一些资源
LOCAL pNode :DWORD
    .if g_pHead == NULL
        ret
    .endif
    
    ;Kill Timer
    invoke KillTimer,g_hWnd,TIMER1_ID          ;释放定时器1
    invoke KillTimer,g_hWnd,TIMER2_ID          ;释放定时器2
     
    ; Clear Map
    invoke RtlZeroMemory,addr g_Map,50*50
    ; Free The Snake
    mov ebx , g_pHead
    mov eax ,[ebx+12] ;pNext
    mov pNode ,eax
    
@@1:    
    invoke LocalFree, ebx  ; free mem
    mov ebx,pNode
    cmp ebx,NULL
    jz @@Break
    mov eax,[ebx+12]; pNext
    mov pNode ,eax
    jmp @@1

@@Break:
    
    mov eax, NULL
    mov g_pHead ,eax
    mov g_pTail ,eax
    push 0
    pop  g_NodeCount
    push GS_STOP
    pop  g_GameState    
    ret

FreeGame endp


MsgBox proc
    
    invoke MessageBox,g_hWnd,addr AppName,addr AppName,MB_OK
    ret

MsgBox endp

Random proc Range:DWORD               ;生成随数的子程序

    mov eax, g_RandomSeed
    mov ecx, 23
    mul ecx
    add eax, 7
    and eax, 0FFFFFFFFh
    ror eax, 1
    xor eax, g_RandomSeed
    mov g_RandomSeed, eax
    mov ecx, Range
    xor edx, edx
    div ecx
    mov eax, edx
    ret

Random endp

TimeProc proc hWnd:HWND,uMsg:UINT,idEvent :UINT,dwTime:DWORD  
LOCAL pNode:DWORD ;                                  ;功能是叫蛇向前移动
LOCAL Pos:DWORD
LOCAL x1,y1:DWORD
   
   pushad                                                            ;保存所有寄存器
   invoke KillTimer,g_hWnd,TIMER1_ID                                 ;关定时器
  
mov ebx , g_pHead   
mov eax,[ebx+4]
mov x1,eax
mov eax,[ebx+8]
mov y1,eax
mov eax, g_Direct 

 .if eax == DR_LEFT                   ;方向是左,就把头的列-1
       dec x1
       cmp x1,0
       jge @@1
       invoke GameOver                  ;看看到了地图边上没有,到边上就死了
       popad
       ret
 .elseif (eax==DR_RIGHT)
       inc x1
       cmp x1,50
       jle @@1
       invoke GameOver
       popad
       ret
 .elseif(eax==DR_UP)
      dec y1
      cmp y1,0
      jge @@1
      invoke GameOver
      popad
      ret
 .elseif(eax==DR_DOWN)
      inc y1
      cmp y1,50
      jle @@1
      invoke GameOver
      popad
      ret
 .endif
 @@1:
    mov eax,y1
    mov ecx,50
    mul ecx
    add eax,x1
    mov ebx,OFFSET g_Map
    add ebx,eax
    mov Pos,ebx
    mov al, BYTE PTR[ebx]
   .if(al==MAP_WOOD)                         ;加一个身长
      inc g_NodeCount 
       invoke wsprintf,addr g_szBuffer, addr FmtStrNodeCount,g_NodeCount    ;输出为g_szBuffer,输入为FmtStrNodeCount,g_NodeCount 
       invoke SendDlgItemMessage,g_hWnd,IDC_SBR1,SB_SETTEXT,2,addr g_szBuffer ;工具栏的显示
      mov esi,g_pHead
      invoke LocalAlloc ,LPTR,sizeof(SNode)
      mov g_pHead,eax
      mov edi,eax
      mov pNode,eax
      mov [esi],eax
      mov eax,esi
      mov [edi+12],eax                      ;后一个和前一个链接好
      mov eax,NULL
      mov [edi],eax 
      mov al,MAP_NODE                        ;更改地图里的值
      mov eax,Pos
      mov BYTE PTR[eax],al 
     invoke SetTimer,g_hWnd,TIMER2_ID,TIMER2_INTERVAL,addr TimeProc2 
      jmp L
   .elseif(al==MAP_NONE)
   jmp L3
   .elseif(al==MAP_NODE)
    invoke GameOver
    popad
   .elseif(al==MAP_WALL)
    invoke GameOver
    popad
   .endif 
    
 L3:       
    mov eax,g_pTail
    mov pNode,eax
   
    mov ebx,[eax+4]
    mov eax,[eax+8]
    mov ecx ,50
    mul ecx
    add eax,ebx
    mov ebx,OFFSET g_Map
    add eax,ebx
    mov BYTE PTR[eax],MAP_NONE
   .while(1)
    mov eax,pNode
    mov esi,[eax]
    .if(esi==NULL)
    jmp L
    .endif
    mov ebx,[esi+4]
    mov [eax+4],ebx
    mov ebx,[esi+8]
    mov [eax+8],ebx
    mov edx,[eax+8]
    mov pNode,esi
   .endw 
  
L:  
    mov ebx,x1
    mov eax,pNode
    mov [eax+4],ebx
    mov ebx,y1
    mov [eax+8],ebx
    mov eax,y1
    mov ecx,50
    mul ecx
    add eax,x1
    mov ebx,OFFSET g_Map
    add ebx,eax
    mov al,MAP_NODE
    mov byte PTR[ebx],al
      invoke DrawMap
       invoke Flip 
      invoke SetTimer,g_hWnd,TIMER1_ID,TIMER1_INTERVAL,addr TimeProc    ;又再创建定时器1
      mov eax,food
     .if(eax==g_NodeCount)
       push GS_STOP
       pop  g_GameState
      invoke KillTimer,g_hWnd,TIMER2_ID       ;关定时器2
      invoke KillTimer,g_hWnd,TIMER1_ID       ;关定时器1
      invoke MessageBox,g_hWnd,addr success,addr AppName,MB_ICONINFORMATION
      .endif 
      popad                                                             ;恢复所有寄存器
   
      ret 
       
TimeProc endp


TimeProc2 proc hWnd:HWND,uMsg:UINT,idEvent:UINT,dwTime:DWORD   ;每三秒在地图上放一个豆
LOCAL x,y:DWORD
LOCAL Pos:DWORD
pushad
L1:
invoke Random, 50
mov x,eax
invoke Random,50
mov y,eax
mov ecx,50
mul ecx
add eax,x
mov Pos,eax
mov ebx,OFFSET g_Map
add eax,ebx
mov al,byte ptr [eax]
.if(al!=0)
jmp L1
.else
jmp L2
.endif
L2:

mov ebx,offset g_Map         ;如果不是0的话,就可以放豆
    add ebx,Pos                  ;下面的代码就是放豆
    mov al ,MAP_WOOD             ;wood就是豆,呵呵,是不是应该取名为food更好些呢?
    mov byte ptr [ebx],al
 invoke KillTimer,g_hWnd,TIMER2_ID  
 invoke DrawMap               
    invoke Flip
    popad
    
    ret
TimeProc2 endp
end start 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -