实例介绍
【实例简介】
【实例截图】
【核心代码】
;************************************************************************
; 移动蛇
;------------------------------------------------------------------------
_movesnake proc
local @x, @y,@r,@pi
local @szBuffer[30] : byte
local @temp:DWORD
pushad
.if TimeFlag==0 ;游戏还没准备好,禁止移动
ret
.endif
mov ecx, snake.bodyLength
dec ecx
.if (ecx>0)
mov esi, offset snake.body ;
mov eax,ecx
shl eax,2 ;al*4
add esi,eax
mov edi, esi
sub esi, 4 ;减4
std ; 设置内存地址位增加方式 cld,清方向标志,即(DF)=0,地址从低到高 std,置方向标志1,DF=1,地址从高到低
rep movsd
xor ecx,ecx
cld ;必须改成系统默认方式 否则会出现莫名其妙的错误
.endif
;移动蛇头
finit
fld pi1_4
fimul DWORD ptr snake.Direction
fst @temp ;保存 方向角
fsin ;求正弦
fimul DWORD ptr snake.step
fadd snake.Y
fst snake.Y
FISTP snake.body.y
fld DWORD ptr @temp
fcos ;求余弦
fimul DWORD ptr snake.step
fadd snake.X
fst snake.X
FISTP snake.body.x
;--------------------在状态栏上刷新玩家的可退步数-----------------------
;invoke wsprintf, addr @szBuffer, addr BackLengthinfo,BackLength
;invoke SendMessage, hWinStatus, SB_SETTEXT, 2, addr @szBuffer
popad
ret
_movesnake endp
;************************************************************************
; 将Map中的元素以二维数组的形势表示,即由行号和列号表示,但注意行号、列号
; 是以Windows图形中的坐标为标准,X表示列;Y表示行
;************************************************************************
_ChangeDirection proc @KeyDown
local s1,s2, @szBuffer
pushad
mov ebx,@KeyDown
.if ebx == VK_RIGHT
inc snake.Direction
cmp snake.Direction,8
Jb @f
push 0
pop snake.Direction
@@:
mov eax,1
mov TimeFlag ,eax
.elseif ebx == VK_LEFT
dec snake.Direction
cmp snake.Direction,0
Jge @f
push 7
pop snake.Direction
@@:
mov eax,1
mov TimeFlag ,eax
.else
.endif
;invoke wsprintf, addr @szBuffer, addr szStep, snake.Direction
;invoke SendMessage, hWinStatus, SB_SETTEXT, 2, addr @szBuffer ;状态栏显示文本蛇身长度
popad
ret
_ChangeDirection endp
;************************************************************************
;
;************************************************************************
;------------------------------------------------------------------------
_Check proc ;检测 苹果和墙
local @w ,@h
local @x0:WORD,@y0:WORD,@tl
mov eax,widths
sub eax,snake.danyuange
mov @w,eax
mov eax,heights
sub eax,snake.danyuange
mov @h,eax
movzx eax, WORD ptr snake.body.x
movzx ebx, WORD ptr snake.body.y
.if eax >=@w || eax <=0 || ebx >=@h || ebx<=0 ;检测墙
mov ecx,1
mov BYTE ptr snake.die,cl ;蛇死亡
.endif
;------------检测蛇的身体
; for i= 1 to 20
; x= body(i).x-body(0).y
; y= body(i).y-body(0).y
; if abs(x) < 单元格x and abs(y)< 单元格y then
;蛇头与身体产生碰撞
; end if
;next
mov eax,snake.danyuange
shl eax,1
mov ebx,snake.step
xor edx,edx
div ebx
mov @tl,eax
mov ecx,snake.bodyLength
dec ecx;*******
.while ecx >@tl
mov eax, ecx
shl eax,2 ;eax*4
mov ebx, offset snake.body
add ebx,eax;求出蛇尾地址
mov ax,snake.body.x
sub ax,(Snake_body_class PTR [ebx]).x
jns @f
neg ax
@@:
mov @x0,ax
mov ax,snake.body.y
sub ax,(Snake_body_class PTR [ebx]).y
jns @f
neg ax
@@:
mov @y0,ax
mov eax,snake.danyuange
shl eax,1 ;ax*2
xor edx,edx
mov ebx,3 ;ax/3
div ebx
.if @x0< ax && @y0 < ax
mov ecx,1
mov BYTE ptr snake.die,cl ;蛇死亡
jmp ck2
.endif
dec ecx
sub ebx,4
.endw
;检查是否吃到苹果
mov ax,snake.body.x
sub ax,snake.egg_x
jns @f
neg ax
@@:
mov @x0,ax
mov ax,snake.body.y
sub ax,snake.egg_y
jns @f
neg ax
@@:
mov @y0,ax
mov eax,snake.danyuange;单元格
shl eax,1
xor edx,edx
mov ebx,3
div ebx
.if @x0< ax && @y0 < ax
;吃到苹果
mov ebx, offset snake.body
mov eax, snake.bodyLength
shl eax,2 ;eax*4
sub eax,4 ;eax-4
add ebx,eax
mov ecx,5
.while ecx >0
inc snake.bodyLength
push [ebx]
add ebx,4
pop [ebx];蛇尾的坐标
dec ecx
.endw
invoke place_apple
invoke sndPlaySoundA, _eat, SND_MEMORY Or SND_ASYNC Or SND_NODEFAULT
.endif
ck2:
mov eax, snake.bodyLength
mul snake.step
.if eax>=800d
mov eax,1
mov snake.win,al
invoke sndPlaySoundA, _win, SND_MEMORY Or SND_ASYNC Or SND_NODEFAULT
.endif
mov al, snake.die ;死亡
.if al==1
push 1d
pop snake.dietime;复活等待时间
invoke sndPlaySoundA, _die, SND_MEMORY Or SND_ASYNC Or SND_NODEFAULT
.endif
;----------------------检测蛇头与苹果
;----------------------检测蛇的长度看是否已过关 如果已过关 则select gate 初始化下一关
ret
_Check endp
;************************************************************************
snake_loop proc uses ebx esi edi ;游戏主线程
local @szTmp1[20]:BYTE ,@szTmp2[20]:BYTE
invoke GetTickCount
mov ebx,eax
sub eax, snake.oldtime
.if eax > snake.speed
mov snake.oldtime,ebx
.if snake.die==1
mov eax,snake.speed
add eax, snake.t1
.if eax >=500
push 0
pop snake.t1
dec snake.dietime
jns @f
xor eax,eax
mov snake.die,al ;复活
invoke init_game
@@:
.else
mov snake.t1,eax
.endif
.elseif snake.win==1
;选择关卡
.if CurrentGate==3
.else
inc CurrentGate
.endif
invoke _SelectGate,CurrentGate
invoke init_game
.else
invoke _movesnake
invoke _Check
.endif
invoke _Repaint ;刷新屏幕
.if snake.bodyLength==1
mov eax,snake.danyuange
.else
mov eax, snake.bodyLength
dec eax
mul snake.step
add eax,snake.danyuange
.endif
invoke wsprintf, addr @szTmp2, addr szStep, eax
invoke SendMessage, hWinStatus, SB_SETTEXT, 1, addr @szTmp2 ;状态栏显示文本蛇身长度
.endif
ret
snake_loop endp
;************************************************************************
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论