使用DOSBox-0.74运行的俄罗斯方块游戏

基于x86汇编语言实现的俄罗斯方块游戏
运行截图
游戏开始界面游戏中的界面游戏结束的界面
ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
START: MOV AX,DATA
MOV DS,AX
PUSH DS ;保存DS的值
MOV AL,1CH ;设置AL = 中断号
MOV AH,35H ;ES:BX为入口
INT 21H
MOV SEGMENT1C,ES ;将ES的值给1C中断段
MOV OFF1C,BX ;设置关中断的地址
MOV DX,OFFSET INT1C ;调用子函数INT1C取偏移地址
MOV AX,SEG INT1C ;SEG标号段地址
MOV DS,AX
MOV AL,1CH
MOV AH,25H ;设置新的中断向量,DS:DX为入口
INT 21H
POP DS
GAMEOVER:
MOV AH,00H ;设置显示模式3(802516色)
MOV AL,03H
INT 10H
SELECTSPEED:
MOV AH,09H ;显示字符串
MOV DX,OFFSET STARTMSG1 ;Select speed.
INT 21H
MOV DX,OFFSET STARTMSG2 ;1. Fast模式
INT 21H
MOV DX,OFFSET STARTMSG3 ;2. Middle模式
INT 21H
MOV DX,OFFSET STARTMSG4 ;3. Slow模式
INT 21H
MOV DX,OFFSET STARTMSG5 ;4. Exit模式
INT 21H
MOV AH,08H ;输入一个字符
INT 21H ;让玩家选择游戏模式(速度)
SUB AL,‘0’
MOV CL,AL
AND AL,3
CMP AL,CL
JNE SELECTSPEED ;没有选0-3 输入错了
INC AL
INC CL
MUL CL
CMP CL,1H ;如果是0则结束
JZ EXIT
MOV SPEED,AL ;设置游戏速度
MOV AH,00H
MOV AL,12H
INT 10H ;设置显示模式(64048016色)
MOV AH,0BH ;设置调色板、背景色或边框
MOV BH,01 ;选择调色板
MOV BL,00H ;选择调色板0(RGB)
INT 10H ;开始游戏
CALL INITGAME
CALL BEGIN
CALL DELAY
MOV TIM,0H
LOOP1: STI ;开中断
MOV AL,TIM
CMP AL,SPEED
JG TIME
MOV AH,1
INT 16H ;读键盘
JZ LOOP1
MOV AH,0
INT 16H ;读键盘
CMP AL,1BH ;如果是Esc键则退出
JZ EXIT
CMP AL,‘a’ ;按键a跳转
JZ KA
CMP AL,‘w’ ;按键w跳转
JZ KW
CMP AL,‘d’ ;按键d跳转
JZ KD
CMP AL,‘s’ ;按键s跳转
JNZ TIME
KS: CALL DELAY ;如果是s键则一直下落
CALL DOWN
CMP CON,1 ;如果还能下落则继续下落
JNE KS
CALL BEGIN
JMP LOOP1
KA: CALL LEFT ;调用向左移动
JMP LOOP1
KW: CALL ROTATE ;调用换向
JMP LOOP1
KD: CALL RIGHT ;调用向右移动
JMP LOOP1
TIME: MOV TIM,0H
CALL DOWN ;让方块自然下落
CMP CON,0 ;
JE LOOP1
CALL BEGIN
JMP LOOP1
EXIT:
MOV AX,0003H ;设置显示模式(802516色)
INT 10H
MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET ENDMSG
MOV AH,09H ;显示字符串
INT 21H
MOV DX,OFF1C
MOV AX,SEGMENT1C
MOV DS,AX
MOV AL,1CH
MOV AH,25H
INT 21H
MOV AX,4C00H
INT 21H ;返回dos
INT1C PROC
STI ;开中断
PUSH AX ;保存游戏数据
PUSH DX
MOV AX,DATA ;将数据段DATA存入DS中
MOV DS,AX
INC TIM
POP DX
POP AX ;恢复游戏数据
IRET ;中断返回
INT1C ENDP
DELAY PROC NEAR ;等待
PUSH CX
MOV CX,00FFH
LOOP20: LOOP LOOP20
POP CX
RET
DELAY ENDP
ROTATE PROC NEAR
MOV SI,OFFSET PAD ;取方块地址
MOV AL,NOW ;取方块类型
MOV AH,0H
MOV CL,32 ;左移5位
MUL CL
ADD SI,AX ;把类型号给si(占前3位)
MOV AL,DIRE ;取方向
INC AL
AND AL,03H
MOV AH,0H
MOV CL,8 ;左移3位
MUL CL
ADD SI,AX ;把方向给si
MOV DI,OFFSET P2 ;将P2的地址给DI
MOV CX,04H
CLD
LOOP12: PUSH CX
LODSW ;将SI的游戏数据内容加载到AX
MOV CL,XR ;将XR给CL
SHR AX,CL ;方块逻辑右移
MOV CL,XL
SHL AX,CL ;方块逻辑左移
STOSW ;把AX中的游戏数据内容复制到di所以内存
POP CX
LOOP LOOP12
CALL CHECK
CMP AL,0H
JNE SKIP10
MOV BX,0000H
CALL DISPPAD ;清空原来的方块
CALL COPY21
INC DIRE
AND DIRE,3H
MOV BH,00H
MOV BL,NCOLOR
CALL DISPPAD ;画新的方块
SKIP10: RET
ROTATE ENDP
RIGHT PROC NEAR
CALL COPY12
MOV SI,OFFSET P2
MOV CX,04H ;
LOOP7: MOV AX,[SI]
SHR AX,1
MOV [SI],AX
INC SI
INC SI
LOOP LOOP7
CALL CHECK
CMP AL,0H
JNE SKIP6
MOV BX,0000H
CALL DISPPAD
CALL COPY21
CMP XL,0
JE SKIP7
DEC XL
DEC XR
SKIP7: INC XR
MOV BH,00H
MOV BL,NCOLOR
CALL DISPPAD
SKIP6: RET
RIGHT ENDP
LEFT PROC NEAR
CALL COPY12
MOV SI,OFFSET P2
MOV CX,04H
LOOP10: MOV AX,[SI]
SHL AX,1
MOV [SI],AX
INC SI
INC SI
LOOP LOOP10
CALL CHECK
CMP AL,0H
JNE SKIP8
MOV BX,0000H
CALL DISPPAD
CALL COPY21
CMP XR,0
JE SKIP9
DEC XR
DEC XL
SKIP9: INC XL
MOV BH,00H
MOV BL,NCOLOR
CALL DISPPAD
SKIP8: RET
LEFT ENDP
DOWN PROC NEAR
CALL COPY12
INC TY
CALL CHECK
CMP AL,0H
JNE SKIP5
MOV BX,0000H
CALL DISPPAD
CALL COPY21
MOV BH,00H
MOV BL,NCOLOR
CALL DISPPAD
MOV CON,00H
RET
SKIP5: CALL PUT
MOV CON,01H
RET
DOWN ENDP
PUT PROC NEAR ;满了消除该行方块
MOV BH,0H
MOV BL,0h
CALL DISPPAD ;清除原有方块
MOV BH,0H
MOV BL,01011001b ;设置各方块的颜色
CALL DISPPAD ;显示新的方块
MOV DV,01H
MOV AH,0H
MOV AL,Y
ADD AL,Y
MOV SI,OFFSET BOARD
ADD SI,AX
MOV DI,00H
MOV CX,04H
CLD ;si自增
LOOP15: LODSW ;将si所指内容加载到ax
OR AX,P1[DI] ;
MOV [SI-2],AX
INC DI
INC DI
LOOP LOOP15 ;将P1中的内容弄到游戏区
MOV SI,OFFSET BOARD ; 进入整行消除
ADD SI,23*2 ;从最后一行开始
MOV DI,SI
MOV CX,20 ;循环次数
MOV BH,00H ;0页
MOV FLG,00H ;标志清零
STD ;SI自减
LOOP13: LODSW ;将si的内容加载到ax
CMP AX,0FFFFH ;
JNE SKIP12 ;不是整行跳转
MOV FLG,0FFH
MOV AL,DV
SAL AL,1
MOV DV,AL ;得分加++
JMP LOOP13
SKIP12: STOSW ;ax的内容返回di(即消除整行,非整行下落)
CMP FLG,0H
JE SKIP70 ;如果没有消除则跳转
PUSH CX
MOV DH,CL
ADD DH,03H ;
MOV DL,0AH ;游戏方块中的行列属性
MOV BX,0000H ;颜色属性
MOV BP,OFFSET PADMSG
MOV CX,20
PUSH AX
MOV AX,1300H
INT 10H ;将bp所指内容在指定行列输出,循环20次(清空消除整行)
POP AX
MOV CL,03H
SHL AX,CL ;清除前导3个1
MOV CX,0AH ;游戏区10个格
MOV DL,08H ;显示游戏的列号
LOOP14: INC DL
INC DL
MOV BL,0H
SHL AX,1
JNC SKIP11 ;无进位跳转
MOV BL,01011001b ;落定块以特定颜色显示
SKIP11: CALL DISPCELL
LOOP LOOP14 ;循环清除所有整行行
POP CX
SKIP70: LOOP LOOP13
MOV AL,DV
SAR AL,1
ADD SCORE[3],AL ;一个方块下落完成后总得分
MOV CX,05H
MOV SI,04H
LOOP16: CMP SCORE[SI],‘9’ ;转换对应的得分
JNG SKIP13
INC SCORE[SI-1]
SUB SCORE[SI],0AH
SKIP13: DEC SI
LOOP LOOP16
RET
PUT ENDP
DISPSCORE PROC NEAR ;显示分数
MOV AX,DATA
MOV ES,AX
MOV BP,OFFSET SCORE ;将Score的地址给BP
MOV CX,05H ;记录字符串长度备用
MOV DX,0635H ;起始位置
MOV BH,0H ;页码
MOV AL,0H ;逐个字符输出,光标返回起始位置
MOV BL,00110100B ;字符属性
MOV AH,13H
INT 10H ;显示出是否得分
RET
DISPSCORE ENDP

完整代码加报告下载地址

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值