用VFP编写“贪食蛇”游戏
软件世界
“贪食蛇”游戏是手机上流行的一个小游戏,觉得很好玩,春节无事,将其移植至电脑,不敢独享,遂与大家分享。
“贪食蛇”的游戏规则:设法引导贪食蛇吞掉食物,用方向键控制蛇向上、向下、向左、向右移动。开始后,蛇不能停下或向后退,不要碰墙或接触蛇尾,否则游戏结束。
编程思路
1.建立蛇身:在手机上,蛇是由小块的方形组合起来的,笔者决定用形状控件(shape)组成蛇身。当蛇吃掉一个青蛙时,蛇的身体就会增长一截,蛇尾就会多出一个形状控件。
2.建立青蛙:笔者抽象的用一个“*”号代表。
3.蛇的移动:首先要考虑蛇头的移动,有两个情况:①蛇按原来的方向移动②蛇头转弯
要实现移动只需将组成蛇的各部分按要求变更位置即可。
对于第①种情况,只需将蛇头向原方向移动一格,后面的部分继承上一状态前面部分的位置即可。
对于第②种情况,移动蛇头时要向玩者按方向键的方向移动,其他跟第①种一样。
而要实现蛇不停的移动则需利用一个计时器(timer)控件,让蛇在一个时间间隔内产生一次移动。
4.设置级别:即设置游戏中蛇移动的快慢,要改变蛇移动的快慢,只需将计时器(timer)的interval(间隔时间)属性改变即可。
编程步骤
第一步:建立工程
新建一个工程取名为:贪食蛇.prj
第二步:建立窗体,取名为main.sct
在窗体main中加入如图所示控件:
命令按纽:(1)command1、 (2)command3
设置command1的caption属性为:“开始”;
设置command3的caption属性为:“退出”。
这两个按纽分别控制游戏开始及退出。
组合框:(4)jb
组合框jb将控制游戏的级别。将组合框jb的rowsourcetype属性设为“1-值”,将rowsource属性设为“一级,二级,三级,四级,五级,六级,七级,八级,九级”。
计时器:(5)timer1
计时器timer1将控制蛇体在一间隔时间的运动。由timer1的interval属性控制蛇运动的快慢,设置interval的初始值为”0”
标签:(3)dian、(7)fs、(8)gs
标签dian在游戏中代表蛇的食物青蛙,设置caption属性为:“*”,height属性为:“10” ,width属性为“10”,backcolor属性为“0,0,255”,forecolor属性为“255,0,0”。
标签fs在游戏中显示游戏者当前所得的分数;
标签gs在游戏中显示游戏者当前所吃的青蛙数;
为表示强调将fs和gs的forecolor属性设为“255,0,0”。
(图1)中(9)(10)(11)为辅助标签,caption属性分别为:“请选择级别”、“分数”、“青蛙数”。

(图1)中(12)(13)(14)为线条,用于标出蛇移动的范围。
1.设置主窗体init事件,用于初始化蛇身及青蛙。
** 设置全局变量*
** num:蛇节数,sewidth:屏幕宽,seheight:屏幕高,ss:分数的系数(一级为1,二级为2)
** jb:级别,numbeg:初始蛇数,fensu:分数,minci:名次,sebeg:蛇头的状态
public num,sewidth,seheight,ss,numbeg,jb,fensu,minci,sebeg
LOCAL tmp
**以下为设置初始值**
fensu=0 &&初始化分数为0
jb="一级" &&设置初始级别为一级
minci=11
sewidth=500
seheight=350
sebeg='1'
num=10 &&设置蛇的初始长度
numbeg=10 &&设置蛇尾
thisform.width=650 &&设置窗体宽度
thisform.height=362 &&设置窗体高度
thisform.caption="☆☆☆☆☆ 快乐贪食蛇 ☆☆☆☆☆" &&设置窗体标题
ThisForm.jb.value=jb
ThisForm.fs.caption=''
ThisForm.gs.caption=''
thisform.timer1.interval=0
**设置初始值完 **
**初始化蛇身 **
for i=1 to num
tmp="cmd"+alltrim(str(i,3))
thisform.addobject(tmp,'shape')
fh="thisform."+tmp+".height=10"
fw="thisform."+tmp+".width=10"
ft="thisform."+tmp+".top=100"
fd="thisform."+tmp+".bordercolor=128"
fb="thisform."+tmp+".backcolor=52"
fl="thisform."+tmp+".left="+str(300+10*(i-1),3)
fv="thisform."+tmp+".visible=.t."
&fh
&fw
&ft
&fl
&fb
&fd
&fv
endfor
**初始化蛇身完成**
** 设置青蛙**
thisform.adddian
thisform.command1.setfocus
application.visible=.F.
2.设置主窗体main的keypress事件,用于控制蛇移动时蛇头移动的方向。
** sebeg:蛇头的方向:1向左移;2向上移;3向右移;4向下移
LPARAMETERS nKeyCode, nShiftAltCtrl
do case
case nKeyCode=19.and.sebeg!='3'
sebeg='1'
case nKeyCode=5.and.sebeg!='4'
sebeg='2'
case nKeyCode=4.and.sebeg!='1'
sebeg='3'
case nKeyCode=24.and.sebeg!='2'
sebeg='4'
endcase
3.设置主窗体main自定义事件adddian,用于随机产生一个青蛙,且该青蛙的位置与蛇不一样。
local a1,a2,i,b1,b2,fb1,fb2
a1=rand()*1000
a2=rand()*1000
do while a1>=sewidth-20
a1=a1-(sewidth-20)
enddo
do while a2>=seheight-20
a2=a2-(seheight-20)
enddo
a1=int(a1/10)*10
a2=int(a2/10)*10
if a1<20
a1=a1+10
endif
if a2<20
a2=a2+10
endif
for i=1 to num
tmp="cmd"+alltrim(str(i,3))
fb2="a1=thisform."+tmp+".top"+".and.a2=thisform."+tmp+".left"
if &fb2
if a1>20
a1=a1-10
else
a1=a1+10
endif
if a2>20
a2=a2-10
else
a2=a2+10
endif
endif
endfor
ThisForm.doin.left=a1
ThisForm.doin.top=a2
4.设置主窗体main自定义事件ad
done,用于蛇吞掉青蛙时,蛇增加一截。
local tmp1,tmp2,fh,hw,ft,fd,fb,fl,fv,x,y,xx,yy
tmp1="cmd"+alltrim(str(num,3))
num=num+1
tmp2="cmd"+alltrim(str(num,3))
thisform.addobject(tmp2,'shape')
fh="thisform."+tmp2+".height=10"
fw="thisform."+tmp2+".width=10"
ft="thisform."+tmp2+".top=thisform."+tmp1+".top"
fd="thisform."+tmp2+".bordercolor=128"
fb="thisform."+tmp2+".backcolor=52"
fl="thisform."+tmp2+".left=thisform."+tmp1+".left"
fv="thisform."+tmp2+".visible=.t."
seend='1'
&fh
&fw
&ft
&fl
&fb
&fd
&fv
5.设置主窗体main自定义事件sedele,用于游戏重新开始时删掉多余的蛇身。
local ft,fl,i
for i=11 to num
tmp="cmd"+alltrim(str(i,3))
thisform.removeobject(tmp)
endfor
num=10
sebeg='1'
for i=1 to num
tmp="cmd"+alltrim(str(i,3))
ft="thisform."+tmp+".top=100"
fl="thisform."+tmp+".left="+str(300+10*(i-1),3)
&ft
&fl
endfor
thisform.refresh
return
6.设置窗体main中command1(开始)的click事件
local tmp1,tmp2
fensu=0
ThisForm.gs.caption=""
ThisForm.fs.caption=""
tmp1=ThisForm.jb.value
jb=alltrim(tmp1)
**ss为计分系数
do case
case tmp1="一级"
tmp2=400
ss=1
case tmp1="二级"
tmp2=300
ss=2
case tmp1="三级"
tmp2=200
ss=3
case tmp1="四级"
tmp2=100
ss=4
case tmp1="五级"
tmp2=90
ss=5
case tmp1="六级"
tmp2=80
ss=6
case tmp1="七级"
tmp2=60
ss=7
case tmp1="八级"
tmp2=40
ss=8
case tmp1="九级"
tmp2=30
ss=9
endcase
*用Timer1控制游戏速度
ThisForm.Timer1.interval=tmp2
thisform.sedele
num=numbeg
ThisForm.jb.enabled=.F.
thisform.command1.setfocus
7.设置窗体main中timer1的timer事件,该事件控制蛇不断移动
local tmp1,tmp2,ft,fl,kk,fv,bb,cc,flag2,fb
bb=thisform.cmd1.left
cc=thisform.cmd1.top
flag2=.F.
for i=1 to num
kk=num-i+1
tmp1='cmd'+alltrim(str(kk,3))
if kk=1
do case
case sebeg='1'
fl="thisform."+tmp1+".left="+"thisform."+tmp1+".left-10"
case sebeg='2'
fl="thisform."+tmp1+".top="+"thisform."+tmp1+".top-10"
case sebeg='3'
fl="thisform."+tmp1+".left="+"thisform."+tmp1+".left+10"
case sebeg='4'
fl="thisform."+tmp1+".top="+"thisform."+tmp1+".top+10"
endcase
&fl
else
tmp2='cmd'+alltrim(str(kk-1,3))
ft="thisform."+tmp1+".top="+"thisform."+tmp2+".top"
fl="thisform."+tmp1+".left="+"thisform."+tmp2+".left"
&ft
&fl
endif
**判断是否蛇撞墙或蛇头接触蛇尾**
if thisform.cmd1.left>=sewidth .or.thisform.cmd1.left<=0.or.thisform.cmd1.top>=seheight.or.
thisform.cmd1.top<=0
flag2=.T.
endif
if kk>2
fcmp="thisform."+tmp1+".left=bb .and."+"thisform."+tmp1+".top=cc"
if &fcmp
flag2=.T.
endif
endif
endfor
if flag2
ThisForm.Timer1.interval=0
ThisForm.jb.enabled=.T.
wait windows "你输了!重新玩请按开始!"
thisform.timer1.interval=0
ThisForm.jb.enabled=.T.
ThisForm.command1.setfocus
return
else
if ThisForm.doin.left=thisform.cmd1.left .and.thisform.doin.top=thisform.cmd1.top
fensu=(num-numbeg+1)*ss
ThisForm.fs.caption=alltrim(str(fensu))
ThisForm.gs.caption=alltrim(str(num-numbeg+1))
thisform.addone &&增加蛇的长度
thisform.adddian &&增加青蛙
endif
endif
8.设置窗体main中command3(退出)事件
application.visible=.T.
quit
第三步:将工程“贪食蛇.prj”编译成可执行文件。
注:以上程序在Windows98+VFP6.0下测试通过。