• HTML5 App实战(7):连连看


    去年有段时间喜欢玩连连看,觉得它的实现不难,直到最近决定自己写一个时,才发现做起来并不容易,后来参考了《VC经典游戏》里的代码才搞定。基本功能可以用了,有些动画效果还没有实现 ,有兴趣的朋友可以去完善。这里还是用“画app吧”开发一个FirefoxOS App(既然是HTML5 App,在其它平台上都可以运行)。

    1.用支持HTML5的浏览器(Chrome/Firefox/Safari/IE9+)打开http://www.drawapp8.com/appedit.php。

    1

    选择”新建“创建一个新的app,缺省情况下的设备是iphone5(或者其它设备)。

    2.现在我们把设备切换成FirefoxOS的手机。双击设备打开设备的属性对话框,在设备列表中选择firefoxOS的手机。

    2

    3.选择“确定”之后,我们就可以看到iphone5变成了FirefoxOS手机了。我们不需要上面的toolbar,把它删除掉。

    3

    4.在窗口中放入三个按钮用来选择游戏的难度。

    main

    5.再向模拟器中插入一个窗口(菜单"插入"->"窗口"),用作游戏的主界面。上面是工具条,下面是一个网格控件,网格中放入一个图片控件。

    win_main

    6.打开图片控件的属性对话框,设置它的图片。把要用到的连连看图片放到图片控件的option_image_x中,图片自己整理好放到网站上,我从android app中偷了一些图片放到CSDN code里的。CSDN code不支持外链,所以还是通过getimage.php作为代理访问。

    image_option

    7.界面差不多了,现在开始写代码:

    选择难度的按钮,先设置难度,然后打开游戏主窗口。三个按钮代码类似,只是难度级别不同。

    window.gameDifficult = "easy";
    this.openWindow("win_llk", 	function (retCode) {console.log("window closed.");}, false);
    

    游戏主窗口的onOpen事件:为了偷懒,我把游戏规代码全部放在这里了。代码比较多,你自己开发app时,建议把代码放到独立的js文件中,这样调试起来比较方便。

    var grid = this.getWindow().findChildByName("ui-grid", true);
    var easyLevel = localStorage.easyLevel ? localStorage.easyLevel : 0;
    var mediumLevel = localStorage.mediumLevel ? localStorage.mediumLevel : 0;
    var hardLevel = localStorage.hardLevel ? localStorage.hardLevel : 0;
    
    var rows = grid.getRows();
    var cols = grid.getCols();
    var difficult = window.gameDifficult;
    
    var imageNr = rows * cols;
    var imageTypeNr = rows;
    
    if(difficult === "medium") {
        imageTypeNr = imageTypeNr - 2;
    }
    else if(difficult === "easy") {
    	imageNr = imageNr/2;
    }
    
    var children = grid.getChildren();
    
    var n = rows * cols;
    var m = n - children.length;
    
    for(var i = 0; i < m; i++) {
        grid.addChild(grid.dupTemplateChild());
    }
    children.length = n;
    
    grid.reset = function() {
    	var mapArr = [];
    	var imageNrOfEachType = imageNr/imageTypeNr;
    	imageNrOfEachType = imageNrOfEachType%2 ? imageNrOfEachType + 1 : imageNrOfEachType;
    	imageTypeNr = imageNr/imageNrOfEachType;
    
    	for(var i = 0; i < imageTypeNr; i++) {
    		for(var j = 0; j < imageNrOfEachType; j++) {
    			mapArr.push(i);
    		}
    	}
    
    	for(var i = 0; i < n; i++) {
    		var iter = children[i];
    		iter.setImageSrc(null);
    		iter.setClickable(false);
    		iter.setBorderStyle(null, 0);
    		iter.imageID = -1;
    	}
    
    	var randArr = makeUniqRandArray(0, n-1);
    	for(var i = 0; i < imageNr; i++) {
    		var index = randArr[i];
    		var iter = children[index];
    		var imageID = mapArr[i];
    
    		iter.imageID = imageID;
    		iter.setClickable(true);
    		iter.setClickedStyle(UIImage.CLICKED_STYLE_RECT_BORDER, 3);
    		iter.setImageSrc(iter.getImageSrc("option_image_" + imageID));
    	}
    
    	grid.firstImage = null;
    	grid.secondImage = null;
    	grid.relayout();
    }
    
    grid.replay = function() {
    	this.reset();
    }
    
    grid.reset();
    
    ////////////////////////////////////////////////////
    
    function X1_Link_X2(x, y1, y2) {
    	var y = 0;
    
    	if(y1>y2){
    		y  = y1;
    		y1 = y2;
    		y2 = y;
    	}
    
    	for(i=y1+1; i<=y2; i++)	{
    		if(i==y2) return true;
    
    		if(children[i*cols+x].imageID >= 0) break;
    	}
    
    	if(XThrough(x-1,y1,false)&&XThrough(x-1,y2,false)) return true;
    
    	if(XThrough(x+1,y1,true)&&XThrough(x+1,y2,true))	return true;
    
    	return false;
    }
    
    function Y1_Link_Y2(x1, x2, y) {
    	var x = 0;
    	if(x1 > x2) {
    		x=x1;
    		x1=x2;
    		x2=x;
    	}
    
    	for(i=x1+1;i<=x2;i++) {
    		if(i==x2) return true;
    
    		if(children[y*cols+i].imageID >= 0) break;
    	}
    
    	if(YThrough(x1,y-1,false)&&YThrough(x2,y-1,false)) return true;
    
    	if(YThrough(x1,y+1,true)&&YThrough(x2,y+1,true))	return true;
    
    	return false;
    }
    
    function LineX(x, y1, y2) {
    	var y = 0;
    
    	if(y1>y2)	{
    		y=y1;
    		y1=y2;
    		y2=y;
    	}
    
    	for(y=y1;y<=y2;y++) {
    		if(children[y*cols+x].imageID >= 0) return false;
    		if(y==y2) return true;
    	}
    
    	return false;
    }
    
    function LineY(x1, x2, y) {
    	var x = 0;
    	if(x1>x2) {
    		x=x1;
    		x1=x2;
    		x2=x;
    	}
    
    	for(x=x1;x<=x2;x++){
    		if(children[y*cols+x].imageID >= 0) return false;
    		if(x==x2) return true;
    	}
    
    	return false;
    }
    
    function OneCornerLink(x1, y1,x2, y2) {
    	var n = 0;
    
    	if(x1>x2) 	{
    		n=x1;
    		x1=x2;
    		x2=n;
    		n=y1;
    		y1=y2;
    		y2=n;
    	}
    
    	if(y2<y1) {
    		if(LineY(x1+1,x2,y1)&&LineX(x2,y1,y2+1)) return true;
    		if(LineY(x2-1,x1,y2)&&LineX(x1,y2,y1-1)) return true;
    		return false;
    	}	
    	else 	{
    		if(LineY(x1+1,x2,y1)&&LineX(x2,y1,y2-1)) return true;
    		if(LineY(x2-1,x1,y2)&&LineX(x1,y2,y1+1)) return true;		
    
    		return false;
    	}
    
    	return false;
    }
    
    function TwoCornerLink(x1, y1, x2, y2){
    	var n = 0;
    
    	if(x1>x2)
    	{
    		n=x1;
    		x1=x2;
    		x2=n;
    		n=y1;
    		y1=y2;
    		y2=n;
    	}
    
    	if(XThrough(x1+1,y1,true)&&XThrough(x2+1,y2,true)) return true;
    
    	if(XThrough(x1-1,y1,false)&&XThrough(x2-1,y2,false)) return true;
    
    	if(YThrough(x1,y1-1,false)&&YThrough(x2,y2-1,false)) return true;
    	
    	if(YThrough(x1,y1+1,true)&&YThrough(x2,y2+1,true)) return true;
    
    	for(x=x1+1;x<cols;x++)	{
    		if(children[y1*cols+x].imageID >= 0)
    			break;
    		if(OneCornerLink(x,y1,x2,y2))
    			return true;
    	}
    
    	for(x=x1-1;x>-1;x--) {
    		if(children[y1*cols+x].imageID >= 0)
    			break;
    		if(OneCornerLink(x,y1,x2,y2))
    			return true;
    	}
    
    	for(y=y1-1;y>-1;y--)
    	{
    		if(children[y*cols+x1].imageID >= 0)
    			break;
    		if(OneCornerLink(x1,y,x2,y2))
    			return true;
    	}
    
    	for(y=y1+1;y<rows;y++)
    	{
    		if(children[y*cols+x1].imageID >= 0)
    			break;
    		if(OneCornerLink(x1,y,x2,y2))
    			return true;
    	}
    	
    	return false;
    }
    
    function XThrough(x, y, bAdd)
    {
    	if(bAdd)
    	{
    		for(i=x;i<cols;i++)
    			if(children[y*cols+i].imageID >= 0)
    				return false;
    	}
    	else
    	{
    		for(i=0;i<=x;i++)
    			if(children[y*cols+i].imageID >= 0)
    				return false;
    	}
    	return true;
    }
    
    function YThrough(x, y, bAdd)
    {
    	if(bAdd)
    	{
    		for(i=y;i<rows;i++)
    			if(children[i*cols+x].imageID >= 0)
    				return false;
    	}
    	else
    	{
    		for(i=0;i<=y;i++)
    			if(children[i*cols+x].imageID >= 0)
    				return false;
    	}
    	return true;
    }
    
    grid.IsLinked = function () {
    	var indexOfFirst = children.indexOf(grid.firstImage);
    	var indexOfSecond = children.indexOf(grid.secondImage);
    	var y1 = Math.floor(indexOfFirst/cols);
    	var x1 = indexOfFirst%cols;
    	var y2 = Math.floor(indexOfSecond/cols);
    	var x2 = indexOfSecond%cols;
    
    	if(x1==x2)	{
    		if(X1_Link_X2(x1,y1,y2))	return true;
    	}
    	else if(y1==y2)	{
    		if(Y1_Link_Y2(x1,x2,y1))	return true;
    	}
    
    	if(OneCornerLink(x1,y1,x2,y2))	{
    		return true;
    	}
    	else if(TwoCornerLink(x1,y1,x2,y2))	{
    		return true;
    	}
    
    	return false;
    }
    
    function animateLinked(grid) {
    	var firstImage = grid.firstImage;
    	var secondImage = grid.secondImage;
    	
    	var config = {};
    
    	config.opacityStart = 0.6;
     	config.opacityEnd = 0;
    	config.delay = 10;
     	config.duration = 1000;
    	config.scaleStart = 0.6;
    	config.scaleEnd = 0.2;
    	config.onDone = function(el) {
    		el.imageID = -1;
    		el.setScale(1);
    		el.setOpacity(1);
    		el.setClickable(false);
    		el.setImageSrc(null);
    	}
    
    	firstImage.animate(config);
    	secondImage.animate(config);
    
    	var labelScore = grid.getWindow().findChildByName("ui-label-score", true);
    	var score = parseInt(labelScore.getText()) + 10;
    	labelScore.animSetText(score);
    
    	return;
    }
    
    grid.onChildClicked = function(child) {
    	if(child.imageID < 0) {
    		return;
    	}
    
    	if(!this.firstImage) {
    		this.firstImage = child;
    		child.setBorderStyle("blue", 1);
    	}
    	else if(child.imageID >= 0) {
    		if(this.firstImage === child) {
    			return;
    		}
    
    		if(this.firstImage.imageID != child.imageID) {
    			this.firstImage.setBorderStyle(null, 0);
    			this.firstImage = child;
    			child.setBorderStyle("blue", 1);
    			return;
    		}
    
    		this.secondImage = child;
    		if(this.IsLinked()) {
    			animateLinked(this);
    		}
    
    		this.firstImage.setBorderStyle(null, 0);
    		this.firstImage = null;	
    		this.secondImage.setBorderStyle(null, 0);
    		this.secondImage = null;
    	}
    }
    

    游戏主窗口上返回按钮点击事件:关闭当前窗口。

    var retCode = 0;
    this.closeWindow(retCode);
    

    游戏主窗口上Replay按钮点击事件:

    var grid = this.getWindow().findChildByName("ui-grid", true);
    grid.replay();
    

    游戏主窗口上网格中图片控件的点击事件:

    this.getParent().onChildClicked(this) 
    

    好了,基本功能完成了,点击模拟器上的“预览”就可以玩游戏了。

    11.我们通过菜单"文件“/”在设备上预览“生成一个URL,在实际的设备上看看效果如何。

    12.最后当然是生成安装包了,菜单“云编译”/"编译FirefoxOS安装包"。

    这里有我们做好的,你可以直接参考:

    在线编辑

    在线运行


  • 相关阅读:
    iOS动画(一)coreAnimation 教程(转)
    sdwebimage基本用法及原理
    iOS推送
    Objective-C中的Block
    loadView、viewDidLoad、initWithCoder、initWithNibName、awakeFromNib的调用时间及用法
    提纲挈领-我的博客内容架构(持续更新)
    读过的书籍及思考系列 (详细列表)-持续更新
    看过的影视及思考系列(详细列表)-持续更新
    自学笔记系列:《Python学习手册 第五版》 -写在开始之前
    《Python网络爬虫权威指南 第二版》 -第1章 软件及BeautifulSoup库准备
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6167366.html
Copyright © 2020-2023  润新知