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

📄 block.asm

📁 俄罗斯方块
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;*******************************************************************
; author:qinjie  date:2008-04-03
;
; descript :
;          :全部使用80x86的简单汇编指令
;
;          :本程序很多东西都可以在数据段配置
;          ;可配置方块大小,颜色,界面位置,使用的按键,每个方块模型形状
;          ;可配置每个方块模型变化后的形状,每个方块模型出现的概率
;          ;可配置自动下落的触发间隔,都是在数据段里面配出来的.
;
;*******************************************************************

;*******************************************************************
; finish:
;         下次应该考虑将墙设置为空心
;         应该考虑将移动和变形用统一的方法
;         应该考虑配置概率的限制,该版本有限制概率和不能超过db的长度
;         下次应该考虑将墙的厚度增加,免得配置新模型的时候出来bug
;         下次应该考虑如何将分数在屏幕上面更新
;         下次应该友好的用户交互,不能游戏结束就弹出去
;         下次应该考虑随着得分增加然后速度自动增加
;         不足之处不再做修改
;         qinjie 08-04-05
;*******************************************************************
data segment
     ;配置游戏框架左上角的象素坐标,以及每个方块的边长象素长
     leftpx dw 124
     toppx dw  22
     l db 5
     
     ;初试话显示器模式INT10H的参数:模式,调色盘前景色,调色盘背景色
     ctrmod db 5
     bgcolor db 15
     frontcolor db 10

     ;俄罗思方块的颜色,以及背景色int 10h的0ch功能,的al参数
     blockcolor db 5
     blockbgcolor db 12
     framecolor db 7
     currnetcolor db ?

     ; 2 为墙
	 ; 1 为下落好的
	 ;-1 为正在下落的
	 ; 0 为空着没有东西的

     ;定义数组矩阵
     i db  8
     j db  3
     matrix db 2,2,2,2,2,2,2,2,2,2,2,2
            db 2,0,0,0,0,0,2,0,0,0,0,2
            db 2,0,0,0,0,0,2,0,0,0,0,2
            db 2,0,0,0,0,0,2,0,0,0,0,2
            db 2,0,0,0,0,0,2,0,0,0,0,2
            db 2,2,2,2,2,2,2,2,2,2,2,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,0,0,0,0,0,0,0,0,0,0,2
            db 2,2,2,2,2,2,2,2,2,2,2,2

    oldmatrix db 312 dup(0);辅助矩阵,为打印屏幕次数更少设置
 
    borni    db  7 ;新模型生成位置,x方向第7格
	bornj    db  5 ;新模型生成位置,y方向第5格

	gameover db  0  ;   1为游戏结束
	turnover db  0  ;   1为一轮下落结束
	movsign  db  'd';   程序只认:'r'向右 | 'l'向左 |'d'向下|其他不移动

    ;temp四乘四矩阵,粘贴到matrix(i,j)的模型id
	temp4x4 db 16 dup(0)

    pasteid db ?


    ;用于保存检测冲突的结果,1为冲突,0为不冲突
	;在变形和生成新模型中需要用这个结果
    chkclash db 0

	;几个变形的按键,配置在这里,方便改变
    rtkey db 'd'  ;右
	ltkey db 'a'  ;左
	dnkey db 's'  ;下
	cgkey db 'w'  ;变形

    ;当前模型编号,当前后继模型编号
    mdnow db 100
	mdnext db 100

	;配置模型变化编号
	;配置模型出现概率
	;配置模型的样子(数组)
	          ; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14
	mdchange db 1, 0, 2, 4, 5, 6, 3, 8, 9,10, 7,12,13,14,11;变化指针
        mdchance db 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1;出现机会的权值,注权值总和不要超过127
	mdcount  db 15 ;模型总数

         ;0号模型
	mode db 0,9,0,0
	     db 0,9,0,0
	     db 0,9,0,0
	     db 0,9,0,0
         ;1号模型
	     db 0,0,0,0
	     db 9,9,9,9
	     db 0,0,0,0
	     db 0,0,0,0
         ;2号模型
	     db 0,0,0,0
	     db 0,9,9,0
	     db 0,9,9,0
	     db 0,0,0,0
         ;3号模型
	     db 0,9,0,0
	     db 9,9,9,0
	     db 0,0,0,0
	     db 0,0,0,0
         ;4号模型
	     db 0,9,0,0
	     db 0,9,9,0
	     db 0,9,0,0
	     db 0,0,0,0
         ;5号模型
	     db 0,0,0,0
	     db 9,9,9,0
	     db 0,9,0,0
	     db 0,0,0,0
         ;6号模型
	     db 0,9,0,0
	     db 9,9,0,0
	     db 0,9,0,0
	     db 0,0,0,0
		 ;7号模型
	     db 0,9,0,0
	     db 0,9,0,0
	     db 0,9,9,0
	     db 0,0,0,0
		 ;8号模型
	     db 0,0,0,0
	     db 9,9,9,0
	     db 9,0,0,0
	     db 0,0,0,0
		 ;9号模型
	     db 9,9,0,0
	     db 0,9,0,0
	     db 0,9,0,0
	     db 0,0,0,0
		 ;10号模型
	     db 0,0,9,0
	     db 9,9,9,0
	     db 0,0,0,0
	     db 0,0,0,0
		 ;11号模型
	     db 0,0,9,0
	     db 0,0,9,0
	     db 0,9,9,0
	     db 0,0,0,0
		 ;12号模型
	     db 0,9,0,0
	     db 0,9,9,9
	     db 0,0,0,0
	     db 0,0,0,0
		 ;13号模型
	     db 0,9,9,0
	     db 0,9,0,0
	     db 0,9,0,0
	     db 0,0,0,0
		 ;14号模型
	     db 0,0,0,0
	     db 0,9,9,9
	     db 0,0,0,9
	     db 0,0,0,0

        ;触发下落的模块的参数
		;触发等待时间为 basicwait * mulnum

        sec db ?          ; 下落秒的历史纪录
		persec db ?       ; 下落百分之一秒的历史纪录
		basicwait db 22   ; 基本间隔,单位为百分之一秒,最好大点,30以上
        mulnum db 2       ; 延迟触发基本间隔的倍数
        trigger db 0      ; 1触发/0不触发       
data ends

code segment
assume ds:data,cs:code
start:
    mov ax,data
    mov ds,ax



	;&&&&&&&&&&&&&&&&&
    ;设置显示器模式
    mov ah,00h
    mov al,ctrmod
    int 10h
    mov ah,0bh
    mov bh,0
    mov bl,bgcolor
    int 10h
    mov bh,1
    mov bl, frontcolor
    int 10h
    ;&&&&&&&&&&&&&&&&&


	call set_next;设置next
	call set_next;设置now

	call mainloop;主循环

	;停一下
	mov ah,8
	int 21h

    ;&&&&&&&&&&&&&&&&
	;设置字符显示模式
    mov ah,00h
    mov al,3
    int 10h
    ;&&&&&&&&&&&&&&&&&
    ;退出
    mov ah,4ch
    int 21h

draw_a_block proc near
;函数功能,打印一个方块
     push ax
     push bx
     push cx
     push dx
     push di
     ;寻找dx的初值,y坐标
     mov al,i
     dec al
     mov ah,l
     mul ah
     add ax,toppx
     mov dx,ax
     ;用di保存cx的初值,x坐标
     mov al,j
     dec al
     mov ah,l
     mul ah
     add ax,leftpx
     mov di,ax
     
     ;fix**************为格子之间有空格打补丁**
     cmp l,byte ptr 3
     jc s2_1
     inc dx
     inc ax
     dec l
     s2_1:
     ;fix**************************************
     
     ;开始打印(i,j)方块        
     mov ah,0ch
     mov al,currnetcolor
     mov bh,l

 s2: mov bl,l
     mov cx,di
 s1: int 10h
     inc cx
     dec  bl
     jnz s1
     inc dx
     dec bh
     jnz s2
     ;fix**************为格子之间有空格打补丁
     cmp l,byte ptr 3
     jc s2_2
     inc l
     s2_2:
     ;fix************************************ 
     pop di
     pop dx
     pop cx
     pop bx
     pop ax
     ret
draw_a_block endp

scan_board proc near
;函数功能,打印全屏幕
     push ax
     push bx
     push cx
     push dx
     mov ch,i
     mov cl,j
     mov bx,311;12 X 26

     mov i,26
s4:  mov j,12
s3:
;**********************************************
;循环体,扫描每个数组
;打印全屏幕
     ;判断是否需要打印,如果需要打印则走case分支
     mov al,matrix[bx] 
     cmp al,oldmatrix[bx]
     jz s8

     mov oldmatrix[bx],al 

     ;CASE1: 数组元素为2,是边界
     cmp matrix[bx],byte ptr 2
     jnz s5
     mov al,framecolor
     mov currnetcolor,al
     call draw_a_block
s5:
     ;Case2: 数组元素为-1,是正在下落的方块
     cmp matrix[bx],byte ptr -1
     jnz s6
     mov al,blockcolor 
     mov currnetcolor,al
     call draw_a_block
s6:
     ;Case3:数组元素为1,是下落完毕的方块
     cmp matrix[bx],byte ptr 1
     jnz s7
     mov al,blockcolor 
     mov currnetcolor,al
     call draw_a_block
s7:
    ;Case4:数组元素为0,没有东西,用背景色填充
     cmp matrix[bx],byte ptr 0
     jnz s8
     mov al,blockbgcolor 
     mov currnetcolor,al
     call draw_a_block
s8:
;**********************************************
     dec bx
     dec j
     jnz s3
     dec i
     jnz s4

     mov i,ch
     mov j,cl
     
     pop dx
     pop cx      
     pop bx
     pop ax
     ret
scan_board endp

i_j_move proc near
;函数功能,该函数没有判断是否能移动
;只负责移动
;所以不能直接调用,需要先判断
    push ax
    push bx
    push cx
    push dx
    push di
    mov ah,i
    mov al,j
    push ax

    ;上面的那个地址di
    mov ah,0
    dec al
    mov di,ax
    mov ah,i
    dec ah
    mov al,12
    mul ah
    add di,ax

    ;下面的那个地址bx
    mov bx,di
    add bx,52;48+4

	;根据移动方向选择
	;替换-1的相对地址si
	;和循环中的稍描方向cx
	mov al,movsign

	cmp al,byte ptr 'r'
	jnz s9
	mov si,1
	mov cx,-1
	jmp s12
s9:
    cmp al,byte ptr 'l'
	jnz s10
	mov si,-1
	mov cx,1
	jmp s12
s10:
    cmp al ,byte ptr 'd'
	jnz s18exit
	mov si,12
	mov cx,-1
	jmp s12
s12:

    ;让两个地址不越界
    cmp bx,298;最右下角的空白格为298
    jc s13
    mov bx,298
s13:
    cmp dx,72;最左上角的空白格子为72
    jnc s14
    mov dx,72
s14:
    
    ;到这里 
	;si为于等待修改的元素的地址偏移量
	;di为稍描上面界限的那个地址
	;bx为稍描上面界限的那个地址

	;如果si等于-1(左移动)就从上往下扫描,否则从下往上扫描

	cmp si, -1
	jnz s15
    mov ax,bx
	mov bx,di
	mov di,ax

s15:
    ;until循环,di移动到结束的下一个位置,当哨兵
    add di,cx

	;循环,如果是-1则进行移动
s16:
    cmp matrix[bx],byte ptr -1
    jnz s17
    mov matrix[bx],0
    mov matrix[bx+si],-1
s17:
    add bx,cx
    cmp bx,di
    jnz s16

s18exit:
    pop ax
    mov j,al
    mov i,ah
    pop di
    pop dx
    pop cx
    pop bx
    pop ax
    ret
i_j_move endp

block_move proc near
    push ax
	push bx
	push cx
	push dx
	push si
	push di

    ;dh用做标记,1为block_move 成功,0为block_move失败
    mov dh,0

    ;先判断(i,j)位置的正在下落的方块是否能移动
    mov ch,i
	mov cl,j

    ;bx中放数组上部那个界限
	mov ah,ch
	dec ah
	mov al,12
	mul ah
	mov bx,ax
	mov ah,0
	mov al,cl
	dec ax
	add bx,ax
    ;di放数组下部分那个界限
    mov di,bx
	add di,52;48+4
	;让两个界限不越界[72, 298]
	cmp bx,72
	jnc s19
	mov bx,72
s19:
    cmp di,298
	jc s20
    mov di,298
s20:
    ;di当哨兵,until型循环
    inc di
    ;先取相对偏移量si,等一下从bx稍描到di
	mov al,movsign

	cmp al,byte ptr 'd'
	jnz s21
	mov si,12
	jmp s23judge
s21:cmp al,byte ptr 'l'
    jnz s22
	mov si,-1
	jmp s23judge
s22:cmp al,byte ptr 'r'
    jnz s31exit
	mov si,1
	jmp s23judge
s23judge:
    ;如果执行到这里,表示movsign里面是有数据的
	;开始判断
	cmp matrix[bx],byte ptr -1
	jnz s24
	cmp matrix[bx+si],byte ptr 1
	jz  s31exit
	cmp matrix[bx+si],byte ptr 2
	jz  s31exit
s24:
    inc bx
	cmp bx,di
	jnz s23judge

	;如果执行到这里,表示可以移动,马上处理移动,然后设置标记
    call i_j_move
	mov dh,1

	;移动完毕,改变i和j的值,然后结束
	mov al,movsign
    mov ch,i
	mov cl,j

	cmp al,byte ptr 'd'
	jnz s25
	inc ch
	jmp s27
s25:
    cmp al,byte ptr 'l'
	jnz s26
	dec cl
	jmp s27
s26:
    inc cl
s27:

    mov i,ch
	mov j,cl

s31exit:
    ;如果下落失败,则设置turnover标记1
	mov al,movsign
	cmp al,'d'
	jnz s34
	cmp dh,0
	jnz s34
	mov turnover,1
	;将(i,j)附近-1的元素全部变成1的元素
    mov bx,di
	sub bx,53;48+4
s32:
    cmp matrix[bx],byte ptr -1
	jnz s33
	mov matrix[bx],1
s33:
    inc bx
	cmp bx,di
	jnz s32
s34:
    ;清除下落标记
    mov movsign,0

    pop di
	pop si
	pop dx
	pop cx
	pop bx
	pop ax
	ret
block_move endp

i_j_clear proc near
    push ax
	push bx

⌨️ 快捷键说明

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