首页
社区
课程
招聘
初学WIN32,写了一个俄罗斯方块程序练练手
发表于: 2006-5-9 20:47 19333

初学WIN32,写了一个俄罗斯方块程序练练手

2006-5-9 20:47
19333

最近学习WIn32程序,所以写了这个,写的比较乱,希望大家不要骂我啊!!!

毕竟花了时间写的,所以贴出来给大家批评。。。

我注释了一下,把注释了的asm文件传上来在18楼


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (57)
雪    币: 196
活跃值: (135)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
2
支持开源!!
2006-5-9 20:54
0
雪    币: 122
活跃值: (45)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
不错,收拉!!!!
2006-5-9 20:58
0
雪    币: 235
活跃值: (41)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
4
支持!
我也才刚学,看的恨不得撞墙,共勉!
2006-5-9 22:12
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
5
不错,开源支持。
2006-5-9 22:50
0
雪    币: 216
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
里面的注释我没有写太多,如果谁想要的话,我下次注释清楚了再发上来。
2006-5-9 22:55
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
下来看看,我这样的新手也要从这个学起呢
2006-5-10 00:56
0
雪    币: 179
活跃值: (131)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
8
BUG:堆死之后再重新开始游戏,暂停就用不了了
2006-5-10 08:26
0
雪    币: 603
活跃值: (617)
能力值: ( LV12,RANK:660 )
在线值:
发帖
回帖
粉丝
9
不错, 支持加注释, 呵呵~
2006-5-10 09:17
0
雪    币: 237
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
强烈的顶一下!
2006-5-10 12:56
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
支持开源。。。。。。。。。。。
2006-5-10 18:02
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
谢谢,收藏了
2006-5-10 22:34
0
雪    币: 110
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
刚想学 WIN32 ASM 下来看看,支持开源

注译最好详细点
2006-5-10 22:47
0
雪    币: 50
活跃值: (145)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
14
就是,注释详细点有助于我学习
2006-5-10 23:17
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
支持开源
2006-5-11 11:13
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
16
玩了下,挺不错的
2006-5-11 17:58
0
雪    币: 268
活跃值: (40)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
17
好东西,支持,收下了,我也在学win32拿来学习学习,希望多加注释
2006-5-12 11:31
0
雪    币: 216
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
加了一些注释的asm文件
上传的附件:
2006-5-12 13:23
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
想看一看,学一学
2006-5-13 01:07
0
雪    币: 268
活跃值: (40)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
20
不过好像还有一些bug,多玩一会然后重新开始试试看
2006-5-13 10:28
0
雪    币: 216
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
21
是有很多Bug,我这个程序的结构很乱,不过现在没时间改了,等以后有时间做个界面,到时候再一起改一下
2006-5-13 11:18
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
下载来看看.
2006-5-13 21:02
0
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
为什么编译后没有开始游戏选项呢,怎么回事,图标也没编译进去
2006-5-20 23:13
0
雪    币: 216
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
24
在我的机子上可以啊
2006-5-21 15:49
0
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
25
我曾写过一个DOS版的,代码经过高度优化,只有471字节.
有加速/立即下落,积分(100/300/600/1000制),逐渐加速.

;471 bytes GAME! By Dwing 
;Only for DOS/Win9x/WinME/DosBox(注意不能直接在Win2000以上系统运行) 
.model tiny 
.386 
.code 
$shape  equ 008h 
$backg  equ 0dbh 
$up     equ 72 
$left   equ 75 
$right  equ 77 
$down   equ 80 

        org 100h 
start:  int 10h                 ;设置显示模式0(40*25*16色字符模式) 
        push 0b800h             ;字符缓冲区段=b800h 
        pop ds                  ;ds=b800h 
        push ds 
        pop es                  ;es=b800h 
        xchg ax,di              ;di=0000h 
        mov ax,0700h+$backg     ;开始画边框,ax=字符(0dbh)及属性(灰色) 
        mov cx,ax               ;cx=数量 
        rep stosw               ;覆盖全屏 
        mov ax,0e30h            ;开始画数码框,ax=字符('0')及属性(黄色) 
        mov cl,6                ;cl=数字个数(6) 
        mov di,2*(40*23+17)     ;di=数字显示屏幕偏移位置 
        rep stosw               ;显示数码 
        xor ax,ax               ;开始画中间空框,ax=空字符 
        mov di,2*(40*2+15)      ;di=空框第一行屏幕偏移位置 
@nextbl:mov cl,10               ;cl=每行块数(10) 
        rep stosw               ;画一行空格 
        add di,2*(15+15)        ;计算下一行屏幕偏移位置 
        cmp di,2*(40*22+15)     ;判断是否画完最后一行(共20行) 
        jb  short @nextbl       ;没画完则循环 

@rernd: in  al,40h              ;开始随机选择方块类型,al=时间随机值 
        and al,0111b            ;al只取0-7 
        jz  short @rernd        ;如果是0则重新选择(只选1-7,共7种) 
        dec ax                  ;1-7变为0-6 
        mov bx,2*(40*2+15+4)    ;方块起始屏幕偏移位置 
        jnz short @t            ;如果不是0(长条形方块需特殊处理)则跳转 
        mov bx,2*(40+15+4)      ;长条形方块的起始屏幕偏移位置上移一行 
@t:     xchg ax,bp              ;bp=方块起始屏幕偏移位置 

        call @isok              ;判断新产生的方块能否放置 
        jz  short @goon         ;能放置则跳转 
@end:   call @dispb             ;不能放置情况:先显示方块 
        push cs 
        pop ds                  ;ds=当前程序段 
        lea dx,msg1             ;dx="GAMEOVER"信息地址 
        mov ah,9                ;ah=9(显示字符串) 
        int 21h                 ;显示"GAMEOVER" 
@esc:   in  al,60h              ;读键盘 
        dec al                  ;"ESC"扫描码=1 
        jnz short @esc          ;如果没有按"ESC"则跳回继续读键盘 
        mov ax,3                ;ax=DOS默认显示模式(3) 
        int 10h                 ;设置显示模式3(80*25*16色字符模式) 
        retn                    ;退出 

@goon:  mov cl,0ffh             ;新方块能放置情况:先进入延时状态 
        cmp cl,40h              ;cl=循环等待次数 
        jae short @wait         ;确认cl不小于40 
        mov cl,40h 
@wait:  call @dispb             ;显示当前新方块 
        push cx                 ;进入等待状态 
        xor cx,cx               ;cx=等待时间(微秒)低字 
        mov dx,1000             ;dx=等待时间(微秒)高字 
        mov ah,86h 
        int 15h                 ;等待 
        pop cx                  ;退出等待状态 

@t4:    mov ah,1 
        int 16h                 ;判断键盘缓冲区是否有字符 
        jz  short @loop         ;没有按键则跳出键盘处理部分 
        xor ax,ax 
        call @disp              ;清除新方块的显示 
        int 16h                 ;读取键盘缓冲区字符=>ah 
        mov al,ah               ;al=ah 
        cmp al,$up              ;判断是否是上方向键 
        jnz short @k1           ;不是则跳转 
        push bp                 ;保存当前新方块的摆放形状 
        movzx bp,cs:[bp+bkv]    ;改变新方块的摆放形状 
        call @isok              ;判断是否能放置 
        jz  short @loop_        ;能放置则跳出键盘处理部分 
        pop bp                  ;不能放置则恢复新方块原来形状 
        loop @wait              ;继续下一次等待 
@k1:    push bx                 ;保存当前新方块的位置 
        cmp al,$left            ;判断是否是左方向键 
        jnz short @k2           ;不是则跳转 
        dec bx                  ;新方块左移一个位置(2个字节) 
        dec bx 
@test:  call @isok              ;判断是否能放置 
        jz  short @loop_        ;能放置则跳出键盘处理部分 
        pop bx                  ;不能放置则恢复新方块原来位置 
        loop @wait              ;继续下一次等待 
@k2:    cmp al,$right           ;判断是否是右方向键 
        jnz short @k3           ;不是则跳转 
        inc bx                  ;新方块右移一个位置(2个字节) 
        inc bx 
        jmp short @test         ;剩下的处理同"左方向键" 
@k3:    pop bx                  ;恢复新方块原来位置 
        cmp al,1                ;判断是否是ESC键 
        jz  short @end          ;如果是则跳转到退出程序段 
        jmp short @ok           ;如果是其他按键则跳出延时状态 
@loop_: pop ax                  ;清除保存的新方块位置 
@loop:  loop @wait              ;继续下一次等待 

@ok:    push ax                 ;保存按键扫描码 
        xor ax,ax               ;延时过后进入方块下落部分 
        call @disp              ;清除新方块的显示 
        add bx,2*40             ;新方块下移一个位置(2个字节) 
        call @isok              ;判断是否能放置 
        pop ax                  ;恢复按键扫描码 
        jnz short @down         ;如果不能放置新方块则跳转 
        cmp al,$down            ;判断是否是下方向键 
        jz  short @ok           ;如果是则继续下落 
        jmp short @goon         ;不是则进入下一次延时 
@down:  sub bx,2*40             ;恢复新方块原来位置 
        call @dispb             ;显示新方块 

        xor ax,ax               ;进入判断是否有一行已满 
        mov dx,ax               ;ax=dx=0 
        mov si,2*(40*2+15)      ;si=中间空框的起始屏幕偏移位置 
@nextl: mov di,si               ;di=当前判断的屏幕偏移位置 
        mov cl,11               ;判断10次(10+1) 
        repnz scasw             ;扫描一行 
        jz  short @skip         ;如果有空位则跳出 
        pusha                   ;进入消除一行部分 
        mov si,di 
        sub si,2*40             ;si=上一行屏幕偏移位置 
        mov cx,si               ;cx=移动字符个数 
        std 
        rep movsb               ;移下一行 
        cld 
        mov di,2*(40*2+15)      ;di=中间空框最上一行的屏幕偏移位置 
        mov cl,10               ;一行10个方块 
        rep stosw               ;清除最上一行 
        popa                    ;退出消除一行部分 
        inc dx                  ;分数基值+1 
        add dh,dl               ;累计当前分数 
@skip:  add si,2*40             ;下一行偏移位置 
        cmp si,2*(40*22)        ;判断是否判断完所有行 
        jb  short @nextl        ;没有则继续下一行判断 
        and dx,dx               ;判断是否有得到当前的分数 
        jz  short @t_           ;没有则跳过 
@t00:   mov di,2*(40*23+21)     ;数码位屏幕偏移位置(第2位) 
@t0:    mov byte ptr[di],30h    ;置0 
        dec di                  ;进一位(倒退2个字节长度) 
        dec di 
        cmp di,2*(40*23+20)     ;判断是否进入第3位 
        jnz short @t000         ;如果不是则跳过 
        dec byte ptr cs:[@goon+1];每100分等待次数减1(加速) 
@t000:  inc byte ptr[di]        ;当前数码位+1 
        cmp byte ptr[di],3ah    ;判断数码位是否超过9 
        jz  short @t0           ;如果是则跳转(进位) 
        dec dh                  ;当前分数累计值-1 
        jnz short @t00          ;如果分数没加完则继续累加 
@t_:    jmp @rernd              ;继续产生下一个新方块 

@isok:  mov si,bp               ;判断是否能放置方块子模块 
        shl si,2                ;si=方块形状标号*4(占4个字节) 
        xor ax,ax 
        mov dx,ax               ;ax=dx=0 
        add si,offset bks       ;si=方块形状位置描述指针 
        push cx                 ;保存cx 
        mov cl,4                ;cl=方块数(4) 
@nextb: db 2eh                  ;lodsb cs: (al<=cs:[si]) 
        lodsb                   ;载入方块位置描述(位置偏移) 
        mov di,ax 
        or  dx,[di+bx]          ;判断小方块是否冲突 
        loop @nextb             ;继续判断下一个位置描述 
        pop cx                  ;恢复cx 
        retn                    ;返回 

@dispb: mov al,$shape           ;显示方块子模块,al=方块形状标号 
        mov ah,cs:[bp+bkc]      ;ah=方块颜色值 
@disp:  mov si,bp 
        shl si,2                ;si=方块形状标号*4(占4个字节) 
        push cx                 ;保存cx 
        mov cl,4                ;cl=方块数(4) 
@nextb_:movzx di,cs:[si+bks]    ;取方块描述 
        mov [di+bx],ax          ;显示一个小方块 
        inc si                  ;si=下一个位置描述 
        loop @nextb_            ;继续画下一个小方块 
        pop cx                  ;恢复cx 
        retn                    ;返回 

bkc     db  2                   ;方块颜色值 
        db  9,12,13,14, 11,10 
        db  9,9,9,      12,13 
        db  11,11,11,   10,10,10 
        db  2 
bkv     db  18                  ;方块形状链表 
        db  7,10,11,4,  12,15 
        db  8,9,1,      2,3 
        db  13,14,5,    16,17,6 
        db  0                   ;下面是方块形状描述 
bks     db 40*2,41*2,42*2,43*2  ;  ****                 0 
        db  1*2,40*2,41*2,42*2  ;   *     **   **    ** 基本形状*7 
        db  1*2, 2*2,40*2,41*2  ;  ***   **     **   ** 1-4 
        db  0*2, 1*2,41*2,42*2  ; 
        db  0*2, 1*2,40*2,41*2  ; 
        db  0*2,40*2,41*2,42*2  ;    *       *       
        db  2*2,40*2,41*2,42*2  ;    ***   ***          5-6 
        db  1*2,40*2,41*2,81*2  ;   *         *         扩展形状*12 
        db 40*2,41*2,42*2,81*2  ;  **   ***   ** 
        db  1*2,41*2,42*2,81*2  ;   * *  *  * *         7-9 
        db  0*2,40*2,41*2,81*2  ;     **   ** 
        db  1*2,40*2,41*2,80*2  ;      *   *            10-11 
        db  1*2,41*2,80*2,81*2  ;    *        **   
        db 40*2,41*2,42*2,82*2  ;    *   ***  * 
        db  1*2, 2*2,41*2,81*2  ;   **     *  *         12-14 
        db  0*2, 1*2,41*2,81*2  ;*  **        * 
        db 40*2,41*2,42*2,80*2  ;*   *   ***  * 
        db  1*2,41*2,81*2,82*2  ;*   *   *    **        15-17 
        db  2*2,42*2,82*2,122*2 ;*                      18 
msg1    db 9,9,'GAMEOVER',9,9,'$' 
end start

编译命令行:
TASM els.asm
TLINK els.obj /t

WinNT/2000/XP/2003运行需要DOSBox模拟器,下载地址:
http://www.skycn.com/soft/24049.html
上传的附件:
2006-5-21 16:25
0
游客
登录 | 注册 方可回帖
返回
//