先看源码:
.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
(最好是好的源代码,当然是问题也可以)。
下面就程序了
- 标 题:许源华游戏之俄罗斯方块
- 作 者:huagame
- 时 间:2009-08-23 16:50
- 链 接:http://bbs.pediy.com/showthread.php?t=96348