zoukankan      html  css  js  c++  java
  • Html5 Egret游戏开发 成语大挑战(七)游戏逻辑和数据处理

    本篇在前面的基础上,将进行逻辑的编码开发让游戏能够正式的玩起来,这里没有注重太多的体验细节,而是直接实现游戏的规则逻辑,将分成两个部分说明:数据处理和游戏逻辑。

    初始化游戏数据

    在前面的第五篇中,我们通过数据的构建已经读取了所有的关卡数据在关卡选择界面中,LevelDataManager负责管理所有的关卡数据,在SceneLevels类中,当onclick_level触发时,就会切换到Game界面中,所以改造代码如下:

    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方法:

    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,将来它将帮我们完成换关卡之类的操作。

    但是此时我们发现一个问题,就是关卡中的选择“字”是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):

    //当一个问题字被选择添加到回答的时,设置不可见,并保存到本对象中以后使用
    public SetSelectWord(word:Word){
        if(word != null){
            this.setWordText(word.getWordText());
            this.SelectWord = word;
            word.visible = false;
        }
        else{
            this.setWordText("");
            this.SelectWord = null;
        }
    }

    这个方法的作用就是,下面的问题字操作的时候,将其保存在回答字中,将来再操作时将其还原显示。

    字块操作处理逻辑

    打开Word类,本游戏的字块是独立的,几乎不会变化,所以我们将点击事件放入对象自身处理,通过访问Game类的单例来让代码看起来更好读一些,所以,直接修改onclick_tap方法如下:

    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资源方面请到第二篇的后面下载) 

  • 相关阅读:
    Adobe Reader XI 自动闪退问题
    NoSQL非关系型数据库Redis (键值对(key-value)数据库) 学习笔记
    MarkdownPad2报错: Html Rendering Error (An error occurred with the Html rendering component.)
    Thymeleaf学习笔记
    Elasticsearch学习笔记2--Spring Data
    Redis5.0学习笔记
    Xshell6 评估期已过——解决办法
    Windows版抓包工具Wireshark3.0
    PHP 判断数据是否为空 ‘0’判断为空可选
    python3 多线程,多进程 ,IO多路复用
  • 原文地址:https://www.cnblogs.com/nowpaper/p/5183916.html
Copyright © 2011-2022 走看看