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資源方面請到第二篇的后面下載) 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM