先看源码:
   .386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include gdi32.inc
includelib kernel32.lib
includelib gdi32.lib
includelib user32.lib
 
_init proto
_choose proto
_brush proto :dword
_check proto :dword,:dword,:dword
.data
 number0 dd 0
 basexy dd 8 dup (0)
 basedirection dd 0
 basex dd 0
 basey dd 0
 base1 dd 0
 base2 dd 0
 baseaddr dd 0
 baseaddr1 dd 0
 baseaddr2 dd 0
 xline dd 0
 timecount dd 0
 control dd 0
 handle dd 0
 hwnd dd 0
 wBrush dd 0
 bBrush dd 0
 hdc dd 0
 msg MSG <0>
 x1 dd 0
 x2 dd 0
 x3 dd 0
 x4 dd 0
 y1 dd 0
 y2 dd 0
 y3 dd 0
 y4 dd 0
 
 
 xx dd 21 dup (0)
.const
 up1 dd 0,0,0,0,-32,0,32,64
     dd -32,0,32,64,0,0,0,0
     dd 0,0,0,0,-32,0,32,64
     dd -32,0,32,64,0,0,0,0
 up2 dd 0,-32,0,32,-32,0,0,0
     dd 32,0,0,0,0,-32,0,32
     dd 0,32,0,-32,32,0,0,0
     dd -32,0,0,0,0,32,0,-32
 up3 dd -32,-32,-32,0,-64,-32,0,0
     dd 32,0,-32,-32,-32,-32,-32,0
     dd 0,0,0,-32,32,0,-32,-32
     dd -64,-32,0,0,0,0,0,-32
 up4 dd 0,0,0,-32,-64,-32,0,0
     dd 32,0,-32,-32,0,0,0,-32
     dd -32,-32,-32,0,32,0,-32,-32
     dd -64,-32,0,0,-32,-32,-32,0
 wcname db 'wc',0
 equwallx equ 320
 equwally equ 512
 equwallsize equ 31
 equfull equ 0
.code
start proc
 local wc:WNDCLASSEX
 invoke GetModuleHandle,0
 mov handle,eax

 mov wc.hInstance,eax
 mov wc.cbSize,sizeof WNDCLASSEX
 mov wc.style,0
 mov wc.lpfnWndProc,offset DefWindowProc
 mov wc.cbClsExtra,0
 mov wc.cbWndExtra,0
 invoke LoadIcon,0,IDI_APPLICATION
 push eax
 mov wc.hIcon,eax
 pop eax
 mov wc.hIconSm,eax
 invoke LoadCursor,0,IDC_ARROW
 mov wc.hCursor,eax
 mov wc.hbrBackground ,COLOR_WINDOW
 mov wc.lpszMenuName,0
 mov wc.lpszClassName,offset wcname
 invoke RegisterClassEx,addr wc

 invoke GetSystemMetrics,SM_CYSCREEN
 push eax
 invoke GetSystemMetrics,SM_CXSCREEN
 sub eax,equwallx
 shr eax,1
 pop ebx
 sub ebx,equwally
 shr ebx,1
 invoke CreateWindowEx,0,offset wcname,offset wcname,WS_POPUPWINDOW,eax,ebx,equwallx,equwally,0,0,handle,0
 mov hwnd,eax
 invoke ShowWindow,hwnd,SW_NORMAL
 invoke GetStockObject,NULL_PEN
 invoke SelectObject,hdc,eax
 invoke GetStockObject,WHITE_BRUSH
 mov wBrush,eax
 invoke GetStockObject,BLACK_BRUSH
 mov bBrush,eax
 invoke ShowCursor,FALSE
 invoke _init
 invoke SetTimer,hwnd,0,50,0
main:
 invoke GetMessage,addr msg,hwnd,0,0
 mov eax, msg.message

 cmp eax, WM_KEYDOWN
 jnz nokeydown
 mov eax,msg.wParam
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;left;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 cmp eax,VK_LEFT
 jnz keydown1
 mov timecount,6
 ;;;;;;;;;;;;;;;;;;can go to left?
 mov eax,x1
 sub eax,32
 invoke _check,eax,y1,0
 cmp eax,0
 jz main
 mov eax,x2
 sub eax,32
 invoke _check,eax,y2,0
 cmp eax,0
 jz main
 mov eax,x3
 sub eax,32
 invoke _check,eax,y3,0
 cmp eax,0
 jz main
 mov eax,x4
 sub eax,32
 invoke _check,eax,y4,0
 cmp eax,0
 jz main
 invoke _brush,bBrush
 sub x1,32
 sub x2,32
 sub x3,32
 sub x4,32
 sub basex,32
 invoke _brush,wBrush
keydown1:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;right;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 cmp eax,VK_RIGHT
 jnz keydown2
 ;;;;;;;;;;;;;;;;;;can go to right?
 mov timecount,6
 mov eax,x1
 add eax,32
 invoke _check,eax,y1,0
 cmp eax,0
 jz main
 mov eax,x2
 add eax,32
 invoke _check,eax,y2,0
 cmp eax,0
 jz main
 mov eax,x3
 add eax,32
 invoke _check,eax,y3,0
 cmp eax,0
 jz main
 mov eax,x4
 add eax,32
 invoke _check,eax,y4,0
 cmp eax,0
 jz main
 invoke _brush,bBrush
 add x1,32
 add x2,32
 add x3,32
 add x4,32
 add basex,32
 invoke _brush,wBrush
keydown2:
 cmp eax,VK_DOWN
 jnz keydown3
 jmp lfall
keydown3:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;up;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 cmp eax,VK_UP
 jnz keydown4
 cmp control,1
 jnz main
 mov timecount,6
 mov eax,baseaddr
 mov baseaddr2,eax
 add baseaddr2,32 
 mov eax,baseaddr1
 cmp eax,baseaddr2
 jnz @f
 sub baseaddr2,128
@@:
 mov edx,baseaddr2
 lea ecx,basexy
 mov edi,0
 
lup3:
 cmp edi,16
 jz lup2
 mov eax,[edx+edi]
 add eax,basex
 mov [ecx+edi],eax
 add edi,4
 jmp lup3
lup2:
 
 cmp edi,32
 jz lup1
 mov eax,[edx+edi]
 add eax,basey
 mov [ecx+edi],eax
 add edi,4
 jmp lup2
lup1: 
 lea ebx,basexy
 mov base1,ebx
 mov base2,0
lup5:
 cmp base2,4
 jz lup4
 mov ebx,base1
 add base1,4
 inc base2
 invoke _check,[ebx],[ebx+16],0
 cmp eax,0
 jz main
 jmp lup5
lup4:
 
 invoke _brush,bBrush

 pushf
 lea edi,x1
 lea esi,basexy
 mov ecx,8
 cld 
 rep movsd
 popf 
 invoke _brush,wBrush
 mov eax,baseaddr2
 mov baseaddr,eax
 jmp main
keydown4:
 cmp eax,VK_ESCAPE
 jnz main
 invoke ExitProcess,0
nokeydown:
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;timer;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 cmp eax,WM_TIMER
 jnz notimer
 cmp timecount,0
 jz @f
 dec timecount
 jmp main
@@:
 mov timecount,6
 ;;;;;;;;;;;;;;;can fall?
lfall:
 mov eax,y1
 add eax,32
 invoke _check,x1,eax,0
 cmp eax,0
 jz nofall
 mov eax,y2
 add eax,32
 invoke _check,x2,eax,0
 cmp eax,0
 jz nofall
 mov eax,y3
 add eax,32
 invoke _check,x3,eax,0
 cmp eax,0
 jz nofall
 mov eax,y4
 add eax,32
 invoke _check,x4,eax,0
 cmp eax,0
 jz nofall
 invoke _brush,bBrush
 add y1,32
 add y2,32
 add y3,32
 add y4,32
 add basey,32
 invoke _brush,wBrush
 jmp notimer
nofall:
 cmp y1,0
 jns @f
 invoke ExitProcess,0
@@: 
 cmp y2,0
 jns @f
 invoke ExitProcess,0
@@:
 cmp y3,0
 jns @f
 invoke ExitProcess,0
@@:
 cmp y4,0
 jns @f
 invoke ExitProcess,0
@@:
 mov number0,0
 mov base1,0
 invoke _check,x1,y1,1
 invoke _check,x2,y2,1
 invoke _check,x3,y3,1
 invoke _check,x4,y4,1
 lea ebx,xx
 mov ecx,0
 cmp number0,0
 jz ll1
l3:
 cmp number0,0
 jz l1
 cmp dword ptr [ebx],0
 jnz l2
 mov base2,ebx
 dec number0
 pushf
 pushad
 mov edi,ebx
 mov esi,ebx
 sub esi,4
 std
 rep movsd
 popad
 popf
l2:
 inc ecx
 add ebx,4
 jmp l3
l1:
 invoke GetDC,hwnd
 mov hdc,eax
 invoke SelectObject,hdc,bBrush
 add base1,32
 invoke Rectangle,hdc,0,0,320,base1
 invoke SelectObject,hdc,wBrush
 
 mov eax,base1
 sub eax,32
 mov y1,eax
ll3:
 mov ebx,base2
 mov eax,[ebx]
 mov y2,eax
 cmp y1,0
 js ll2
 mov x1,0
 mov x2,1
ll5:
 mov edx,x2
 bt y2,edx
 jc ll4
 mov ecx,x1
 add ecx,equwallsize
 mov edx,y1
 add edx,equwallsize
 invoke Rectangle,hdc,x1,y1,ecx,edx
ll4:
 inc x2
 add x1,32
 cmp x2,11
 js ll5
 
 sub base2,4
 sub y1,32
 jmp ll3
 
ll2:
 invoke ReleaseDC,hwnd,hdc
 ll1:
 invoke _choose
 invoke _brush,wBrush
notimer:
 invoke DispatchMessage,addr msg
 jmp main
 ret
start endp

;-----------------------------------------_init---------------------------------
_init proc
 mov timecount,6
 invoke GetDC,hwnd
 mov hdc,eax
 invoke SelectObject,hdc,bBrush
 invoke Rectangle,hdc,0,0,equwallx,equwally
 invoke ReleaseDC,hwnd,hdc
 pushf
 mov eax,2046
 mov ecx,20
 lea edi,xx
 cld
 rep stosd
 mov dword ptr [edi],0
 popf
 invoke _choose
 invoke _brush,wBrush
 ret 
_init endp

 ;-------------------------------------_choose--------------------------------
_choose proc
 mov basedirection,0
 mov control,1
 invoke GetTickCount
 mov ebx,5
 xor edx ,edx 
 div ebx 
 cmp edx,0
 jnz @f
 mov control,0
 mov x1,128
 mov x3,128
 mov x2,160
 mov x4,160
 mov y1,-64
 mov y2,-64
 mov y3,-32
 mov y4,-32
 ret
@@:
 cmp edx,1
 jnz @f
 lea eax,up1
 mov baseaddr ,eax
 add eax,128
 mov baseaddr1,eax
 mov basex,128
 mov basey,-96
 mov x1,128
 mov x3,128
 mov x2,128
 mov x4,128
 mov y1,-128
 mov y2,-96
 mov y3,-64
 mov y4,-32
 ret
@@:
 cmp edx,2
 jnz @f
 lea eax,up2
 mov baseaddr,eax
 add eax,128
 mov baseaddr1,eax
 mov basex,160
 mov basey,-32
 mov x1,160
 mov x3,160
 mov x2,128
 mov x4,192
 mov y1,-64
 mov y2,-32
 mov y3,-32
 mov y4,-32
 ret
@@:
 cmp edx,3
 jnz @f
 lea eax, up3
 mov baseaddr ,eax
 add eax,128
 mov baseaddr1,eax
 mov basex,160
 mov basey,-32
 mov x1,128
 mov x3,128
 mov x2,128
 mov x4,160
 mov y1,-96
 mov y2,-64
 mov y3,-32
 mov y4,-32
 ret
@@:
 lea eax,up4
 mov baseaddr ,eax
 add eax,128
 mov baseaddr1,eax
 mov basex,160
 mov basey,-32
 mov x1,160
 mov x3,160
 mov x2,160
 mov x4,128
 mov y1,-96
 mov y2,-64
 mov y3,-32
 mov y4,-32
 ret
_choose endp
 ;;----------------------------------------_brush----------------------------------
_brush proc p1
 
 invoke GetDC,hwnd
 mov hdc,eax 
 invoke SelectObject,hdc,p1
 mov eax,x1
 add eax,equwallsize
 mov ebx,y1
 add ebx,equwallsize
 invoke Rectangle,hdc,x1,y1,eax,ebx
 
 mov eax,x2
 add eax,equwallsize
 mov ebx,y2
 add ebx,equwallsize
 invoke Rectangle,hdc,x2,y2,eax,ebx
 
 mov eax,x3
 add eax,equwallsize
 mov ebx,y3
 add ebx,equwallsize
 invoke Rectangle,hdc,x3,y3,eax,ebx
 
 mov eax,x4
 add eax,equwallsize
 mov ebx,y4
 add ebx,equwallsize
 invoke Rectangle,hdc,x4,y4,eax,ebx
 invoke ReleaseDC,hwnd,hdc
 ret
_brush endp
 ;;;;;------------------------------_check-----------------------------------
_check proc p1,p2,p3
 
 mov eax,p2
 add eax,128
 shr eax,5
 mov xline,eax
 shl eax,2
 lea ebx,xx
 add ebx,eax
 mov eax,p1
 add eax,32
 shr eax,5
 cmp p3,0
 jnz nocheck
 bt dword ptr [ebx],eax
 jc @f
 mov eax,0
 ret
@@:
 mov eax,1
 ret
nocheck:
 btr dword ptr [ebx],eax
 cmp dword ptr [ebx],0
 jnz l1
 inc number0
 mov eax,p2
 cmp eax,base1
 js l1
 mov base1,eax
l1:
 ret
_check endp
end start
  (看到主题我连名字都打出来了,想必我是个爱炫耀的人。这,确实是事实。我心还想您在心里轻轻顶下我。哈哈)
   高手一般有源码就够了,如果你是的话,下面的分析,不妨先不看。
   先观察下游戏,也就是下面几个步骤:
   1.方块随机出现
   2.方块下滑,期间人顺时针转动;
   3,方块下滑到不到下滑了,也就停了
   4.到第1 个步骤了
   下面到开始写程序了:
   第一:设计界面,要作图的窗口,最好的就是风格WS_PUPOPWINDOW的窗口了。其它的也行。不过这个程序貌似没多实际价值。(有的话,我肯定不在多话了。早卖钱了,不过对拿来练习实在是个好程序),所以有些地方不是很完美,望见谅。
   代码就是这个了:
   这个实在说不多少;
 第二:方块随机出
  也就小段_init和小段_choose
   在纸上,画画那些方块也就出了这些代码。
  至于哪个取随机数那几句代码:
  invoke GetTickCount
 mov ebx,5
 xor edx ,edx 
 div ebx 
  。是常用的,最好记熟。
  pushf
 mov eax,2046
 mov ecx,20
 lea edi,xx
 cld
 rep stosd
 mov dword ptr [edi],0
 popf
   上面这段要说说:其中数列XX记录的是方块的位置
  2046 也就111,111,111,10(2)
  如此一来,我们玩游戏时能就看见的一行10个方格也就对应中间的十个‘1’了
  哪个还有第一位的’0‘是什么意思呢?
  其实第11位也是’0‘的。这样一来,一个数也就记录了12个位置,也就围墙也占一位
  当然也你也可以有10个数来记录。这要有方格下滑和变化时稍稍改下就是了
  回到我的程序,这样做,我就可以忽略边界了
  ’1‘表示没方格,’0‘,表示有方格,当一行满方块时,对应的那个数也就0了,这样好判断
  说实在我就看好亮点才用这数列。
  第三:到这,方块应该随机出来了,还有问题的话,就回头一步步检查,说实在我的程序都是修改出的。
  在方块出来后,在我的程序里也就有手动控制就先处理手动控制,再自动下滑:向左,向右,向下,写一二次,应该可以写出。就是按UP键时有些麻烦。
  首先看段数据:
  up1 dd 0,0,0,0,-32,0,32,64
     dd -32,0,32,64,0,0,0,0
     dd 0,0,0,0,-32,0,32,64
     dd -32,0,32,64,0,0,0,0
 up2 dd 0,-32,0,32,-32,0,0,0
     dd 32,0,0,0,0,-32,0,32
     dd 0,32,0,-32,32,0,0,0
     dd -32,0,0,0,0,32,0,-32
 up3 dd -32,-32,-32,0,-64,-32,0,0
     dd 32,0,-32,-32,-32,-32,-32,0
     dd 0,0,0,-32,32,0,-32,-32
     dd -64,-32,0,0,0,0,0,-32
 up4 dd 0,0,0,-32,-64,-32,0,0
     dd 32,0,-32,-32,0,0,0,-32
     dd -32,-32,-32,0,32,0,-32,-32
     dd -64,-32,0,0,-32,-32,-32,0
    这是除田字方块外的四种方块的四种状态数据,是对应方块中心点(BASEX,BASEY)来说,
   相加就可以了。
  (这个,我也办法,要统一来循环的话,也分来分去,实在是惭愧,哪位牛人能统一的话,欢迎向我’炫耀‘)
   每一行对应是X1,X2,X3,X4,Y1,Y2,Y3,Y4
    写代码时要注意下基址
  第四:到方块落定了,方法_CHECK有两个功能:一是检查位置有无方块,二是设置位置有广场
  由参数 P3 决定;
  最后也就一行满了,一面就向一下一行,数据XX用REP MOVSD就行了,接着描绘方块,又到新方块随机出来 完了
  哪个高人低人,只要是有想法的,可以发个邮件给我:522165473@qq.com 
   (最好是好的源代码,当然是问题也可以)。
   下面就程序了

上传的附件 w.rar