简明的拼图游戏教程

想来想去,还是稍微写点东西吧,一来是想把自己的一些制作的思路与大家分享,二来也想请高手们点评一下。在这里把一些重点的部分详细说明一下,相信有点基础的朋友都能很快理解,心急点的朋友呢就直接跳到最后去看源码吧,呵呵。观看演示。

大体思路:载入图片、把图片分割、随机排列图片、鼠标点击事件、序列的比较判断是否结束。在这里只把一些关键的代码帖出来了,但不影响理解。
首先是加载图片,我们这里用的是外部载入,当然你也可以扩展一下做成可以多张图片选择的:

1
2
3
4
5
private function loadpic() {
	_loader = new Loader();
	_loader.load(new URLRequest("myphoto.jpg"));
	_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoad);
}

接下来到了一个重点了,分割图片,这里应该会有很多种处理方法,我这里用的是Matrix控制背景图填充的方法来实现的。有更好的方法还望大家指出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
private function onImageLoad(event:Event):void {
	var bitmap:BitmapData = new BitmapData(_loader.width, _loader.height);
	var x_num:int=480/x_p;//每小块的宽
	var y_num:int=360/y_p;//每小块的高
	bitmap.draw(_loader);
	pic_box=new box_bg();
	pic_box.x=10;
	pic_box.y=10;
	addChild(pic_box);
	d_arr=new Array();//初始数组
	for (var i:int=0; i<x_p; i++) {
		for (var j:int=0; j<y_p; j++) {
		var matrix:Matrix = new Matrix();
		matrix.translate(-x_num * i,-y_num * j);//背景定位
		var block:Sprite = new Sprite();
		block.x=x_num * i;
		block.y=y_num * j;
		var temp_obj:Object={obj:block,b_x:block.x,b_y:block.y};
		d_arr.push(temp_obj);//存入初始数组,在这里把obj也存入,方便后面的比较。
		block.buttonMode=true;
		block.graphics.lineStyle();
		block.graphics.beginBitmapFill(bitmap, matrix);
		block.graphics.drawRect(0,0,x_num-1, y_num-1);//通过背景图填充的方式分割图片
		block.graphics.endFill();
		pic_box.addChild(block);
		}
	}
}

图片分割好了,接下来就是要把它打散,也就是随机排列。我们刚才已经把正确的顺序存入了d_arr数组,那么现在要做的就是把这个数组复制一个出来,然后随机排列,用sort()加一个比较函数就可以实现。d_arr是初始的数组,c_arr是随机化了的数组,都包含了[obj,x,y],把d_arr中的obj取值c_arr中的x,y,那么就实现了图片的随机排列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private function block_pic(e:MouseEvent) {
	var fooba:ByteArray=new ByteArray();//深度复制数组。
	fooba.writeObject(d_arr);
	fooba.position=0;
	c_arr=fooba.readObject() as Array;
	c_arr.sort(randomsort);//随机排列
	for (var i=0; i<c_arr.length; i++) {
		d_arr[i].obj.addEventListener(MouseEvent.CLICK,block_click)//在这里加上鼠标点击事件。
		d_arr[i].obj.x=c_arr[i].b_x;
		d_arr[i].obj.y=c_arr[i].b_y;
	}
}
//随机排列比较函数
private function randomsort(obj_A:String,obg_B:String):int {
	return Math.floor(Math.random() * 3 - 1);//这里只能产生-1、0、1三种值。
}

接下来是鼠标点击事件,我们这里要的效果是点击两个不同的图片使之互换,这一步比较简单,给个变量来判断是第一次还是第二次点击,记录下坐标然后互换就可以了。当然还得记得把点击的对象深度置顶,不然移动的时候会被其它图片挡住的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private function block_click(e:MouseEvent) {
//第一次点击
	if (d_choose) {
		click_x1=e.target.x;
		click_y1=e.target.y;
		var v_obj=e.target;
		c_obj=v_obj;
		pic_box.setChildIndex(v_obj,pic_box.numChildren-1);
		c_obj.alpha=0.7;
		d_choose=!d_choose;
	} else {
//第二次点击
		v_obj=e.target;
		pic_box.setChildIndex(v_obj,pic_box.numChildren-1);
		c_obj.alpha=1;
		TweenLite.to(c_obj,0.3,{x:e.target.x,y:e.target.y,onComplete:check_end});
		TweenLite.to(e.target,0.3,{x:click_x1,y:click_y1,onComplete:check_end});//两个都要写onComplete,要不然就让其中一个运动时间长一点。
		d_choose=!d_choose;
		step+=1;
		move_num_mc.m_num.text=step;
	}
}

最后是判断是否拼成功,这里没有用到两个数组是否相等的比较,因为两个数组的顺序不一样。这里是通过判断obj在两个数组中的x,y是否相同来判定的。

1
2
3
4
5
6
7
8
9
10
private function check_end() {
	end_test=0;//位置正确的个数,正确个数为数组长度时,拼图成功。
	for (var i=0; i<d_arr.length; i++) {
	(Math.floor(d_arr[i].obj.x)==d_arr[i].b_x)&&(Math.floor(d_arr[i].obj.y)==d_arr[i].b_y) ? end_test=end_test+1 : 0;
	}
	isend();
}
private function isend() {
	end_test==d_arr.length ? win() : 0;
}

源文件:puzzles.rar

相关文章

Moondy 发表于 2009-6-15 8,958 Views | 类别: Flash/AS3

26条留言 立即发表评论

  1. #1jack @ 2009-6-30 15:54 回复

    学习中,这个博客很不错….

    • Moondy @ 2009-6-30 16:15 回复

      欢迎常来呀!大家交个朋友,共同学习提高了!

  2. #2Michael @ 2009-7-3 14:52 回复

    博主学习和共享的精神值得学习。希望这个博客越来越好!

    • Moondy @ 2009-7-3 16:04 回复

      说得我都不好意思了。欢迎常来呀,我也会常去你那逛逛的。

  3. #3匿名 @ 2009-7-8 12:26 回复

    您那个拼图里面的类似box_bg之类的函数,在那里定义的阿?说找不到……
    多谢~

    • Moondy @ 2009-7-8 15:28 回复

      那只是创建对像的名称呀。没有定义元件绑定类,会默认继承MovieClip类的。
      如果还有哪里不明白的,就加我QQ吧。

  4. #4匿名 @ 2009-7-18 10:10 回复

    :icon38 :icon35 :icon38

  5. #5匿名 @ 2009-7-26 12:04 回复

    一个flash初学者对你顶礼膜拜。再请教一个问题,最近被安排了一个任务,要做一个成语的游戏,规则是一个4*4的格子,比如说4个的第一个字都是马,其他的12个字被随意的打散到四周,随便拖动第一个字只要它的横坐标对了,就可以放到那里,然后就是这样,我想用数组做,不过自己对编程真的没什么信心,而且要考虑的问题也实在有点多,不知道flash能不能实现呀。而且还要导一个库进去,随机抽成语。

    • Moondy @ 2009-7-26 16:31 回复

      实现是没有问题的,但有些时候最好在设计的时候就把某些难点给绕过去。比如说你这个如果说4个成语的开头都是马,那么这里就必须判断第二个字放在任意一个马的后面都能成立,这相对说来就是一个比较复杂的判断了。还有就是你这个库的问题,自行编辑一个类似XML文件随机动态生成是没有问题的,但是默认的宋体用在这样的游戏里不美观,嵌入字库会让文件的体积增大很多。总之我感觉这个游戏对于一个初学者来说可能是难了一点。

      • 匿名 @ 2009-7-26 23:45 回复

        真实太感谢了,我还是要在专研一下,判断的那些,我想用三个数组来完成,流程图画了很多遍了,只不过还是恨自己当时学编程的时候没有用心,还是要恶补一下。虽然对自己信息不是太足,但是看到那个论坛上写的,never give up!

        • Moondy @ 2009-7-27 09:44 回复

          回头想了下,其实不难。把抽出的成语放在一个数组,每拖动一次就判断一次,比如说拖到第二个字那就判断这数组的每个元素中是否有前两个字符相同的情况,以此类推。相信你可以的

  6. #6qwe @ 2009-7-27 02:09 回复

    flash8打不开怎么办?

    • Moondy @ 2009-7-27 09:35 回复

      这是AS3写的,只有FLASH9以上的能打开。

  7. #7石头 @ 2009-9-7 21:40 回复

    :icon05
    楼主,您好!
    我是一个FLASH AS3的初学者,希望你能指导下,代码部分能看懂,只是不熟悉FLASH外部导入类的做法,我看了你的教程,里面没任何代码,你那种写法不熟悉,所以搞不懂,我所熟悉的大多是写在FLA里面的,你的原文件我导不出SWF,也看不到代码所在,所以不能完全研究出。见笑了,一个初学者,希望能加QQ:173616374 请抽空点化下

    • Moondy @ 2009-9-8 00:21 回复

      首先,我不是高手,我也只是个爱好者罢了。另外希望你不要向着想还原成写在元件上的代码去研究,应该慢慢吸取一些面向对象的思想。一开始可能会很不习惯,我也是这样过来的。

  8. #8匿名 @ 2009-10-10 12:53 回复

    :icon37

  9. #9匿名 @ 2010-5-24 17:35 回复

    :icon23

  10. #10sunrisedance @ 2010-6-24 18:05 回复

    这个方法确实挺好的,我想问问楼主,假如类似你这样的游戏改用电脑自动实现拼图怎么样?

    • moondy @ 2010-6-24 23:19 回复

      其实也可以的,因为每小块的当前位置以及正确位置都在两个数组里,一个个还原就可以了。理论上是行的

      • sunrisedance @ 2010-6-25 09:53 回复

        原来是你使用鼠标点击进行交换图片,现在要实现自动拼图,我可以定义一个时间函数,在时间事件里实现碎片的交换,我是这样想的,不知道行不行?

      • moondy @ 2010-6-25 21:41 回复

        其实我都很久没有弄AS了,都有点忘了。
        理论上当然是可行的,只要循环读正确的那个数组就可以了,查找第N个obj的当前坐标是否跟正确数组里的一样,不一样的话就跟当前正确坐标的那个obj交换,如此循环下去就可以了。

        • sunrisedance @ 2010-6-28 12:34 回复

          谢谢,我也想过了,正准备开始做呢!

        • moondy @ 2010-6-28 21:02 回复

          欢迎探讨 :icon43

          • sunrisedance @ 2010-6-28 22:19

            在吗

  11. #11Ben @ 2011-9-18 14:53 回复

    我想做flash小游戏,但是除了平常上课,自学了也有半年了,还是菜鸟阶段,想问博主怎样快速提高学习效率啊

  12. #12Kelly @ 2011-10-20 16:35 回复

    博主太有才了!我学习了

评论

:icon07 :icon02 :icon16 :icon23 :icon37 :icon05 :icon38 :icon35 more »
(Ctrl + Enter)