论文部分内容阅读
【摘 要】滑动拼接游戏是一款深受大众喜爱的益智小游戏,文章详细介绍了在Flash平台下,使用ActionScript 3.0角本语言来实现滑动拼接游戏中几个关键问题的核心算法。
【关键词】ActionScript3.0 滑动拼接游戏 核心算法
引言
滑动拼接游戏是一款深受大众喜爱的益智小游戏,早在电脑出现之前就以实体的形式存在。随着计算机技术的发展和人们在生活中对益智小游戏的需求,促进了游戏开发行业的迅猛发展。ActionScript是一种基于Flash、Flex等多种开发环境、面向对象编程的脚本语言。随着ActionScript 3.0(以下简称AS3)的出现,使Flash开发游戏变得更加强大,Flash结合AS3能够迅速而灵活的制作出更加细腻、交互娱乐性强的小游戏。
1 游戏设计的几个关键问题
滑动拼接游戏是一个由n个格子组成的长方形盒子,在盒子中将n-1个拼图小块锁在里面,玩家可以单击拼图小块滑入唯一一个没有小块的格子里,接着可以继续滑动新的小块到空的格子,如此反复,直到拼图小块构成一个完整的图形。在游戏的设计中最为关键的几个问题是:(1)如何导入与分割图片;(2)如何随机排列图片小块;(3)如何实现单击图片小块其向空格滑动;(4)如何测试游戏结束。
2 图片的导入与分割算法研究
滑动拼接游戏的制作首先要考虑的是如何将位图导入并将导入的图片分割成n个小块,n的个数由二维数组的行数和列数决定,如3行4列就是3×4共12个小块,4行6列就是4×6共24个小块,小块的个数越多,游戏的难度就越大。最后还应去掉最右下角的图片小块,让该位置形成一个空位即产生一个空的格子。
2.1 位图的导入
要导入位图,需创建一个Loader对象和一个URLRequest实例,然后使用load命令将它们配对。导入图像函数loadBitmap()代码如下。
private function loadBitmap(bitmapFile:String):void //导入图像函数
{//创建URLRequest变量,表示外部图像文件的位置
var tplj:URLRequest = new URLRequest(bitmapFile);
var tpzr:Loader=new Loader(); //创建一个图像Loader对象
tpzr.load(tplj); //使用load()方法告诉Loader对象装入URLRequest所代表的图像文件
tpzr.contentLoaderInfo.addEventListener(Event.COMPLETE,fengetp);// 当图像导入完成后,fengetp函数被调用
}
2.2 图片的分割
当Loader对象帧听到图像导入完成后,会调用分割图片函数fengetp()来实现图片的分割。函数中创建一个Bitmap对象tp接收导入的位图,分割图片使用二维数组来完成,在行数与列数的双重循环中,将其按分割的块数把相应区域的像素拷贝到一个个小Bitmap对象上,并生成相应的Sprit对象,最后在场景中按对应位置显示拷贝后的小图片Sprit对象,同时将它们存储在一个数组中。需要注意的是要产生一个空的格子,可定义一个blankPoint,它是一个Point对象,代表拼图中的空白区域,初始值为最右下角的图片位置,即blankPoint = new Point(hangshu - 1,lieshu - 1);在循环中,当前小块的位置依次与blankPoint比较,若相同即最右下角小块,则不进行像素拷贝等操作,从而形成空格。分割图片函数fengetp()代码如下:
private function fengetp(cs:Event)
{var tp:Bitmap = Bitmap(cs.target.loader.content);
xiaotpdxsz=new Array();
for (var i:uint=0; i {for (var j:uint=0; j {if (blankPoint.equals(new Point(i,j)))
{continue; } //形成空格
var xiaotp:Bitmap = new Bitmap(new BitmapData(onewidth,oneheight)); //创建新的小块
xiaotp.bitmapData.copyPixels(tp.bitmapData,new Rectangle(j*onewidth,i*oneheight,onewidth,oneheight),new Point(0,0)); //对新建小块复制图像
var xiaotpjl:Sprite = new Sprite ?; //创建新的Sprite,小块位图数据赋给它
xiaotpjl.addChild(xiaotp);
addChild(xiaotpjl); //按对应位置显示拷贝后的小图片Sprit对象
xiaotpjl.x=j*(onewidth+jianju)+xcz;
xiaotpjl.y=i*(oneheight+jianju)+ycz;
var xiaotpdx:Object=new Object();
//创建小图片Object,包含当前位置、原始位置和小图片Sprit xiaotpdx.dqwz = new Point(i,j);
xiaotpdx.ywz = new Point(i,j);
xiaotpdx.piece = xiaotpjl;
xiaotpjl.addEventListener(MouseEvent.CLICK,clickyd);//单击小图片调用clickyd函数
xiaotpdxsz.push(xiaotpdx);//将小图片Object存入数组中}}}
3 随机排列图片小块算法研究
当图片小块的位置放好了之后,需要将拼图打乱,但并不能将所有的小块放置在随机的位置上,因为这样做很有可能在游戏时再也不能将它们还原为原来的位置,即游戏无法结束也就是无解。为了防止出现这样的情况,可以采取逆序的方法,从最后完成的拼图开始,随机移动拼图小块200次,直到拼图板看起来已经完全被打乱。为了让移动随机化,将所有可以移动的小块放进一个数组,然后从数组中随机挑选出一个移动,并执行它。随机排列图片小块代码如下:
private function paileitp()
{for (var n:uint=0; n<200; n++) //随机移动拼图小块200次
{ var hfydxiaotpdxsz:Array=new Array(); //创建数组对象用来存放所有可以移动的小块
for (var i:uint=0; i {if (youxiaoyd(xiaotpdxsz[i]) != "none")
{hfydxiaotpdxsz.push(xiaotpdxsz[i]); }
}
var sjxb:uint = Math.floor(Math.random() * hfydxiaotpdxsz.length);
// 在可合法移动小块数组中随机挑选出一个移动
yidongtp(hfydxiaotpdxsz[sjxb],false); //调用移动图片函数进行移动
}
}
通过youxiaoyd()函数来判断小块是否为合法的移动小块。即小块的位置如果在空格的上、下、左、右四个位置时能够合法的移动,否则不能移动。代码如下:
private function youxiaoyd(cs:Object):String
{
if ((cs.dqwz.x==blankPoint.x )&& (cs.dqwz.y==blankPoint.y+1))
{ return "left";}
if ((cs.dqwz.x==blankPoint.x )&& (cs.dqwz.y==blankPoint.y-1))
{return "right";}
if ((cs.dqwz.y==blankPoint.y )&& (cs.dqwz.x==blankPoint.x+1))
{return "up";}
if ((cs.dqwz.y==blankPoint.y )&& (cs.dqwz.x==blankPoint.x-1))
{return "down";}
return "none";
}
4 单击图片小块开始滑动算法研究
在游戏开始前随机排列图片小块和游戏中玩家单击图片小块时都会对图片小块进行移动,我们可通过移动图片函数yidongtp()的第二个布尔参数yidongxg来进行区分。参数设置为false,为随机排列图片小块时的移动;参数设置为true,为玩家单击图片小块时的移动,这时会添加一个滑动过程的动画。yidongtp()函数代码如下:
private function yidongtp(cs:Object,yidongxg:Boolean)//将一个小块移动到空白区域
{switch (youxiaoyd(cs)) //得到空白区域的方向
{ case "up" :
yidongtpfx(cs,-1,0,yidongxg); break;
case "down" :
yidongtpfx(cs,1,0,yidongxg); break;
case "left" :
yidongtpfx(cs,0,-1,yidongxg); break;
case "right" :
yidongtpfx(cs,0,1,yidongxg); break;
}
}
private function yidongtpfx(cs:Object,dx:int,dy:int,yidongxg:Boolean)
{ //将小块移入空白区域
cs.dqwz.x += dx;
cs.dqwz.y += dy;
blankPoint.x -= dx;
blankPoint.y -= dy;
if (yidongxg) //是否需要移动的动画
{kshuadong(cs,dy*(oneheight+jianju),dx*(onewidth+jianju)); } //添加滑动动画效果
else
{ cs.piece.x=cs.dqwz.y*(oneheight+jianju)+xcz;
cs.piece.y=cs.dqwz.x*(onewidth+jianju)+ycz;
}
}
5 判断游戏是否结束算法研究
判断游戏是否结束,只需比较每个小块的当前位置与初始位置是否相同,如果全部相同,则游戏结束。游戏完成函数youxiwancheng()代码如下:
private function youxiwancheng()
{var iscomplete:Boolean
for (var i:uint=0; i {if (! xiaotpdxsz[i].dqwz.equals(xiaotpdxsz[i].ywz))
{ iscomplete=false; }
}
iscomplete= true;
if (iscomplete ())//检测拼图游戏是否完成
{clearhs(); //游戏结束时的清理
gotoAndStop(“gameover”); //跳转到游戏结束帧
}
}
结语
至此通过算法已解决了滑动拼接游戏中的几个关键问题,我们还可以在此基础上通过形参来控制二维数组的行数和列数,从而改变游戏的难度;也可以通过AS代码来为游戏添加背景音乐和显示原图提示。
参考文献
[1](美)Gary Rosenzweig,胡蓉,张东宁,朱栗华译.ActionScrip3.0游戏编程(第2版)[M].北京:人民邮电出版社,2013.
[2]孙颖.Flash Action 3殿堂之路[M].北京:电子工业出版社,2007.
[3](美)Todd Perkins,张猛译.Flash ActionScript3.0实训课堂[M].北京:人民邮电出版社,2008.
【关键词】ActionScript3.0 滑动拼接游戏 核心算法
引言
滑动拼接游戏是一款深受大众喜爱的益智小游戏,早在电脑出现之前就以实体的形式存在。随着计算机技术的发展和人们在生活中对益智小游戏的需求,促进了游戏开发行业的迅猛发展。ActionScript是一种基于Flash、Flex等多种开发环境、面向对象编程的脚本语言。随着ActionScript 3.0(以下简称AS3)的出现,使Flash开发游戏变得更加强大,Flash结合AS3能够迅速而灵活的制作出更加细腻、交互娱乐性强的小游戏。
1 游戏设计的几个关键问题
滑动拼接游戏是一个由n个格子组成的长方形盒子,在盒子中将n-1个拼图小块锁在里面,玩家可以单击拼图小块滑入唯一一个没有小块的格子里,接着可以继续滑动新的小块到空的格子,如此反复,直到拼图小块构成一个完整的图形。在游戏的设计中最为关键的几个问题是:(1)如何导入与分割图片;(2)如何随机排列图片小块;(3)如何实现单击图片小块其向空格滑动;(4)如何测试游戏结束。
2 图片的导入与分割算法研究
滑动拼接游戏的制作首先要考虑的是如何将位图导入并将导入的图片分割成n个小块,n的个数由二维数组的行数和列数决定,如3行4列就是3×4共12个小块,4行6列就是4×6共24个小块,小块的个数越多,游戏的难度就越大。最后还应去掉最右下角的图片小块,让该位置形成一个空位即产生一个空的格子。
2.1 位图的导入
要导入位图,需创建一个Loader对象和一个URLRequest实例,然后使用load命令将它们配对。导入图像函数loadBitmap()代码如下。
private function loadBitmap(bitmapFile:String):void //导入图像函数
{//创建URLRequest变量,表示外部图像文件的位置
var tplj:URLRequest = new URLRequest(bitmapFile);
var tpzr:Loader=new Loader(); //创建一个图像Loader对象
tpzr.load(tplj); //使用load()方法告诉Loader对象装入URLRequest所代表的图像文件
tpzr.contentLoaderInfo.addEventListener(Event.COMPLETE,fengetp);// 当图像导入完成后,fengetp函数被调用
}
2.2 图片的分割
当Loader对象帧听到图像导入完成后,会调用分割图片函数fengetp()来实现图片的分割。函数中创建一个Bitmap对象tp接收导入的位图,分割图片使用二维数组来完成,在行数与列数的双重循环中,将其按分割的块数把相应区域的像素拷贝到一个个小Bitmap对象上,并生成相应的Sprit对象,最后在场景中按对应位置显示拷贝后的小图片Sprit对象,同时将它们存储在一个数组中。需要注意的是要产生一个空的格子,可定义一个blankPoint,它是一个Point对象,代表拼图中的空白区域,初始值为最右下角的图片位置,即blankPoint = new Point(hangshu - 1,lieshu - 1);在循环中,当前小块的位置依次与blankPoint比较,若相同即最右下角小块,则不进行像素拷贝等操作,从而形成空格。分割图片函数fengetp()代码如下:
private function fengetp(cs:Event)
{var tp:Bitmap = Bitmap(cs.target.loader.content);
xiaotpdxsz=new Array();
for (var i:uint=0; i
{continue; } //形成空格
var xiaotp:Bitmap = new Bitmap(new BitmapData(onewidth,oneheight)); //创建新的小块
xiaotp.bitmapData.copyPixels(tp.bitmapData,new Rectangle(j*onewidth,i*oneheight,onewidth,oneheight),new Point(0,0)); //对新建小块复制图像
var xiaotpjl:Sprite = new Sprite ?; //创建新的Sprite,小块位图数据赋给它
xiaotpjl.addChild(xiaotp);
addChild(xiaotpjl); //按对应位置显示拷贝后的小图片Sprit对象
xiaotpjl.x=j*(onewidth+jianju)+xcz;
xiaotpjl.y=i*(oneheight+jianju)+ycz;
var xiaotpdx:Object=new Object();
//创建小图片Object,包含当前位置、原始位置和小图片Sprit xiaotpdx.dqwz = new Point(i,j);
xiaotpdx.ywz = new Point(i,j);
xiaotpdx.piece = xiaotpjl;
xiaotpjl.addEventListener(MouseEvent.CLICK,clickyd);//单击小图片调用clickyd函数
xiaotpdxsz.push(xiaotpdx);//将小图片Object存入数组中}}}
3 随机排列图片小块算法研究
当图片小块的位置放好了之后,需要将拼图打乱,但并不能将所有的小块放置在随机的位置上,因为这样做很有可能在游戏时再也不能将它们还原为原来的位置,即游戏无法结束也就是无解。为了防止出现这样的情况,可以采取逆序的方法,从最后完成的拼图开始,随机移动拼图小块200次,直到拼图板看起来已经完全被打乱。为了让移动随机化,将所有可以移动的小块放进一个数组,然后从数组中随机挑选出一个移动,并执行它。随机排列图片小块代码如下:
private function paileitp()
{for (var n:uint=0; n<200; n++) //随机移动拼图小块200次
{ var hfydxiaotpdxsz:Array=new Array(); //创建数组对象用来存放所有可以移动的小块
for (var i:uint=0; i
{hfydxiaotpdxsz.push(xiaotpdxsz[i]); }
}
var sjxb:uint = Math.floor(Math.random() * hfydxiaotpdxsz.length);
// 在可合法移动小块数组中随机挑选出一个移动
yidongtp(hfydxiaotpdxsz[sjxb],false); //调用移动图片函数进行移动
}
}
通过youxiaoyd()函数来判断小块是否为合法的移动小块。即小块的位置如果在空格的上、下、左、右四个位置时能够合法的移动,否则不能移动。代码如下:
private function youxiaoyd(cs:Object):String
{
if ((cs.dqwz.x==blankPoint.x )&& (cs.dqwz.y==blankPoint.y+1))
{ return "left";}
if ((cs.dqwz.x==blankPoint.x )&& (cs.dqwz.y==blankPoint.y-1))
{return "right";}
if ((cs.dqwz.y==blankPoint.y )&& (cs.dqwz.x==blankPoint.x+1))
{return "up";}
if ((cs.dqwz.y==blankPoint.y )&& (cs.dqwz.x==blankPoint.x-1))
{return "down";}
return "none";
}
4 单击图片小块开始滑动算法研究
在游戏开始前随机排列图片小块和游戏中玩家单击图片小块时都会对图片小块进行移动,我们可通过移动图片函数yidongtp()的第二个布尔参数yidongxg来进行区分。参数设置为false,为随机排列图片小块时的移动;参数设置为true,为玩家单击图片小块时的移动,这时会添加一个滑动过程的动画。yidongtp()函数代码如下:
private function yidongtp(cs:Object,yidongxg:Boolean)//将一个小块移动到空白区域
{switch (youxiaoyd(cs)) //得到空白区域的方向
{ case "up" :
yidongtpfx(cs,-1,0,yidongxg); break;
case "down" :
yidongtpfx(cs,1,0,yidongxg); break;
case "left" :
yidongtpfx(cs,0,-1,yidongxg); break;
case "right" :
yidongtpfx(cs,0,1,yidongxg); break;
}
}
private function yidongtpfx(cs:Object,dx:int,dy:int,yidongxg:Boolean)
{ //将小块移入空白区域
cs.dqwz.x += dx;
cs.dqwz.y += dy;
blankPoint.x -= dx;
blankPoint.y -= dy;
if (yidongxg) //是否需要移动的动画
{kshuadong(cs,dy*(oneheight+jianju),dx*(onewidth+jianju)); } //添加滑动动画效果
else
{ cs.piece.x=cs.dqwz.y*(oneheight+jianju)+xcz;
cs.piece.y=cs.dqwz.x*(onewidth+jianju)+ycz;
}
}
5 判断游戏是否结束算法研究
判断游戏是否结束,只需比较每个小块的当前位置与初始位置是否相同,如果全部相同,则游戏结束。游戏完成函数youxiwancheng()代码如下:
private function youxiwancheng()
{var iscomplete:Boolean
for (var i:uint=0; i
{ iscomplete=false; }
}
iscomplete= true;
if (iscomplete ())//检测拼图游戏是否完成
{clearhs(); //游戏结束时的清理
gotoAndStop(“gameover”); //跳转到游戏结束帧
}
}
结语
至此通过算法已解决了滑动拼接游戏中的几个关键问题,我们还可以在此基础上通过形参来控制二维数组的行数和列数,从而改变游戏的难度;也可以通过AS代码来为游戏添加背景音乐和显示原图提示。
参考文献
[1](美)Gary Rosenzweig,胡蓉,张东宁,朱栗华译.ActionScrip3.0游戏编程(第2版)[M].北京:人民邮电出版社,2013.
[2]孙颖.Flash Action 3殿堂之路[M].北京:电子工业出版社,2007.
[3](美)Todd Perkins,张猛译.Flash ActionScript3.0实训课堂[M].北京:人民邮电出版社,2008.