本篇在前面的基础上,将进行逻辑的编码开发让游戏可以正式的玩起来,这里没有注重太多的体验细节,而是直接实现游戏的规则逻辑,将分红两个部分说明:数据处理和游戏逻辑。html
初始化游戏数据数组
在前面的第五篇中,咱们经过数据的构建已经读取了全部的关卡数据在关卡选择界面中,LevelDataManager负责管理全部的关卡数据,在SceneLevels类中,当onclick_level触发时,就会切换到Game界面中,因此改造代码以下:dom
private onclick_level(e:egret.TouchEvent){ var icon = <LevelIcon>e.currentTarget; if(this.sel_level != icon.Level){ this.img_arrow.x = icon.x; this.img_arrow.y = icon.y; this.sel_level = icon.Level; }else{ //进入并开始游戏 this.parent.addChild(SceneGame.Shared()); SceneGame.Shared().InitLevel(icon.Level); this.parent.removeChild(this); } }
还记得单例吗?不明的能够去看一下前面第五篇,此时InitLevel方法尚未实现,实现SceneGame类,并添加InitLevel方法:ui
class SceneGame extends eui.Component { //单例 private static shared: SceneGame; public static Shared() { if(SceneGame.shared == null) { SceneGame.shared = new SceneGame(); } return SceneGame.shared; } public constructor() { super(); this.skinName = "src/Game/SceneGameSkin.exml"; this.btn_back.addEventListener(egret.TouchEvent.TOUCH_TAP,this.onclick_back,this); } //对象变量 private group_answer:eui.Group; private group_words: eui.Group; private img_question: eui.Image; private btn_back: eui.Group; private levelIndex:number; //初始化关卡 public InitLevel(level:number){ this.levelIndex = level; var leveldata = LevelDataManager.Shared().GetLevel(level); } private onclick_back(){ this.parent.addChild(SceneLevels.Shared()); this.parent.removeChild(this); } }
参数传入的是关卡数值,由于咱们已经有了数据管理类,不须要去从外部得到,如今有了对应的关卡数据,就能够构建游戏了,为了后面的设计操做,咱们将如今正在进行的关卡保存到一个自定义变量中就是 this.levelIndex,未来它将帮咱们完成换关卡之类的操做。this
可是此时咱们发现一个问题,就是关卡中的选择“字”是20个,而关卡数据中是10个(4+6),这样不够咱们放置的怎么办呢?有一个很简单的办法,随机另一个题目将问题答案和本题组合,而后打乱字符顺序,就能够了,固然若是为了减小难度,也能够将问题设计成为10个“问题字”,这里采用的是20个“问题字”来保证难度的一致,下面改造InitLevel方法:编码
//初始化关卡 public InitLevel(level:number){ this.levelIndex = level; var leveldata = LevelDataManager.Shared().GetLevel(level); //将字段接起来 var words = leveldata.answer + leveldata.word; //随机一个其它题目的字段混合进本题目 while(words.length==10){ var i = Math.floor(Math.random() * 400); if(i!=level){ var temp = LevelDataManager.Shared().GetLevel(i); words += temp.word + temp.answer; } } //对字段重排 var wordlist:string[]=[]; for(var i =0 ;i<words.length;i++){ wordlist.push(words.charAt(i)); } wordlist = this.randomlist(wordlist); //赋值 for(var i = 0;i<this.group_words.numChildren;i++){ var wordrect = <Word>this.group_words.getChildAt(i); wordrect.setWordText(wordlist[i]); wordrect.visible = true; } //重置一些状态 for(var i = 0;i<this.group_answer.numChildren;i++){ var answerrect = <AnswerWord>this.group_answer.getChildAt(i); answerrect.SetSelectWord(null); answerrect.visible = true; answerrect.SelectWord = null; } //显示图像 this.img_question.source = "resource/assets/"+leveldata.img; } //将一个数列随机 private randomlist(arr: any[]): any[] { var array = []; while(arr.length > 0) { var i = Math.floor(Math.random() * arr.length); array.push(arr[i]); arr.splice(i,1); } return array; }
在最后增长了一个本身写的randomlist方法,是将一个数组打乱顺序,上面的注释基本上已经将代码讲完,须要注意的是AnswerWord的SetSelectWord方法,在以前的代码中,没有对null进行处理,因此还得修改AnswerWord.SetSelectWord(word:Word):spa
//当一个问题字被选择添加到回答的时,设置不可见,并保存到本对象中之后使用 public SetSelectWord(word:Word){ if(word != null){ this.setWordText(word.getWordText()); this.SelectWord = word; word.visible = false; } else{ this.setWordText(""); this.SelectWord = null; } }
这个方法的做用就是,下面的问题字操做的时候,将其保存在回答字中,未来再操做时将其还原显示。设计
字块操做处理逻辑code
打开Word类,本游戏的字块是独立的,几乎不会变化,因此咱们将点击事件放入对象自身处理,经过访问Game类的单例来让代码看起来更好读一些,因此,直接修改onclick_tap方法以下:xml
protected onclick_tap(){ SceneGame.Shared().onclick_word(this); }
而后在SceneGame实现onclick_word方法,传入参数是word:
//当字点击的时候,由word类抛出 public onclick_word(word: Word){ //找到一个合适的位置添加进答案内容 var sel:AnswerWord = null; for(var i = 0;i<this.group_answer.numChildren;i++){ var answer = <AnswerWord>this.group_answer.getChildAt(i); if(answer.SelectWord == null){ sel = answer; break; } } //当有一个合适的位置的时候就会将字填充,并判断是否胜利 if(sel != null){ sel.SetSelectWord(word); //判断是否胜利 var check_str:string = ""; for(var i = 0;i < this.group_answer.numChildren;i++) { var answer = <AnswerWord>this.group_answer.getChildAt(i); check_str += answer.getWordText(); } if(check_str == LevelDataManager.Shared().GetLevel(this.levelIndex).answer){ //胜利 console.log("win"); } } }
若是没有找到合适添加位置的话,就没有任何操做,这个逻辑已经基本完成,能够运行起来看看效果,将开始界面加到Main中:
protected startCreateScene(): void { //this.addChild(SceneBegin.Shared()); this.addChild(SceneLevels.Shared()); }
而后一路点进游戏界面,就能够达到你想要效果了。
本篇已经结束,使用了点击事件和互相调用的方式来实现基本的规则处理,因为篇幅问题,还有不少东西没有实现,所以在此以后增长一篇二级页面的讲解。
本篇项目源码:ChengyuTiaozhan4.zip(因为博客园的文件大小限制,resource资源方面请到第二篇的后面下载)