Html5 Egret游戲開發 成語大挑戰(六)游戲界面構建和設計


本篇將主要講解游戲界面的構建和設計,會應用到egret.eui的自定義組件,可以很直觀的構建一個游戲整體,這里我們仍然只需要使用EgretWing就可以達到目的,本篇可能是篇幅最少的一個,但是涉及自定義組件和類繼承,希望能夠讀者能夠看明白,這對將來的游戲開發的思維幫助非常大。

自定義控件布局

首先先創建一個名為SceneGameSkin的exml皮膚,直接在這里面拖拖拽拽拼出初步的界面:

上面是題目區,下面是回答區,此時,找了了一下資源,發現字的方塊沒有放進資源文件,沒關系,我們可以直接使用eui.Rect這個基本空間創造一個字塊出來,exml描述如下:

<e:Rect ellipseWidth="20" fillColor="0xFFFFFF" strokeColor="0x0276D0" strokeWeight="4" ellipseHeight="20" right="0" left="0" bottom="0" top="0"/>

看看是不是和圖片上的很像,在編輯器里的基本面板屬性中是沒有ellipseWidth、ellipseHeight等等這些屬性的,需要點屬性欄右上角的所有屬性標簽才能顯示,然后微調即可。

可是,只有這個字塊背景是沒用的,還需要增加Label來顯示文字,但如果一個一個的匹配就很麻煩了,能不能使用skin來自己做一個自定組件自己管理並處理邏輯呢?這個很簡單,先構造一個skin然后配上一個自定義組件的代碼就可以實現了。

新建一個基於eui.Component的皮膚,大小設置為80x80:

<?xml version='1.0' encoding='utf-8'?>
<e:Skin class="WordSkin" width="80" height="80" xmlns:e="http://ns.egret.com/eui" xmlns:w="http://ns.egret.com/wing">
    <e:Rect ellipseWidth="20" fillColor="0xFFFFFF" strokeColor="0x0276D0" strokeWeight="4" ellipseHeight="20" right="0" left="0" bottom="0" top="0"/>
    <e:Label id="lb_text" text="字" horizontalCenter="0" verticalCenter="0" textColor="0x000000" size="60"/>
</e:Skin>

新建一個typescript類,這里的名字就叫Word,繼承自eui.Component,處理代碼如下:

//普通的一個字,用來做問題的字塊使用
class Word extends eui.Component {
    protected lb_text:eui.Label;
    public constructor() {
          super();
          this.addEventListener(egret.TouchEvent.TOUCH_TAP,this.onclick_tap,this);
    }
    protected onclick_tap(){
        console.log(this.lb_text.text);
    }
    //這里沒有做成屬性的原因是因為當應用到eui的時候,Skin還未指定,運行時候會出現報錯,如果指定了SkinName,那么就會產生兩次eui的構建浪費內存
    public setWordText(value:string){
        this.lb_text.text = value;
    }
    public getWordText():string{
        return this.lb_text.text;
    }
}

保存編譯一下,然后在UI設計器的組件里就能看到一個Word自定義組件,然后將它拖進SceneGameSkin里,奇怪,怎么什么都沒有呢,因為還沒有指定皮膚:

 

指定好皮膚后,就會顯示正確了,下面開始進行布局操作,拖放擺好Group到SceneGameSkin的界面中,這里就可以用上Group的布局特性,比如下面的回答字里一共是20個漢字,可以使用Tile的方式排列成一個有序的陣列:

同樣上面的問題欄中,可以使用Group的橫向排列,調整你的界面直到滿意。

繼承的方式擴展自定義組件

那么好了,自此基本上已經完成,一般來說,后面就可以完全靠代碼控制來實現字塊的顯示和處理了,但這還不夠,因為下面的字和上面的字雖然樣子一樣,但處理的邏輯不一樣,比如說,下面的字是一點就自己消失,同時將文本放置到上面的答案中,而上面的字點擊就會移除自己的文本顯示,同時將下面的對應字塊顯示出來,如果用比較笨的方法,就是在代碼中加一個字典對應起來,然后增加一大堆,看起來很繞圈的代碼,其實這里的游戲邏輯很簡單,一個答案字只會對應一個回答字,如果在組件上帶上回答字塊的對象,不就好處理了嗎?如果每個Word控件都增加一個變量保存選定太顯得暴力,這里可以使用繼承增加一個SelectWord變量,而其他的邏輯可以通過重載方法來保持代碼的簡潔性,下面就是實現了一個繼承自Word的AnswerWord類,這個類同樣在保存編譯后,也會出現在自定義組件中,

//繼承自“問題字”,“答案字”是放在上面回答區域,
//由於當答案字點擊的時候,答案字會消失並將對應的問題字還原顯示
class AnswerWord extends Word{
    public SelectWord:Word = null;
    public constructor() {
        super();
    }
    protected onclick_tap() {
        if(this.SelectWord != null){
            this.SelectWord.visible = true;
            this.SelectWord = null;
            this.setWordText("");
        }
        console.log("AnswerWord");
    }
    //當一個問題字被選擇添加到回答的時,設置不可見,並保存到本對象中以后使用
    public SetSelectWord(word:Word){
        word.visible = false;
        this.setWordText(word.getWordText());
        this.SelectWord = word;
    }
}

那么我們將上面的四個漢字都給替換成AnswerWord,點擊一下試試看看命令欄里的輸出,不明白的可以參看上面的注釋。

最終的SceneGameSkin.exml代碼如下:

<?xml version='1.0' encoding='utf-8'?>
<e:Skin class="SceneGameSkin" width="720" height="1136" xmlns:e="http://ns.egret.com/eui" xmlns:w="http://ns.egret.com/wing" xmlns:ns1="*">
    <e:Image source="GameBG3_jpg" left="0" top="0" bottom="0" right="0"/>
    <e:Image source="WordFrame_png" x="39" y="120"/>
    <e:Group id="group_words" width="538" height="417" x="108" y="637">
        <ns1:Word x="80" y="106" skinName="WordSkin"/>
        <ns1:Word skinName="WordSkin" y="116" x="90"/>
        <ns1:Word skinName="WordSkin" y="126" x="100"/>
        <ns1:Word skinName="WordSkin" y="136" x="110"/>
        <ns1:Word skinName="WordSkin" y="146" x="120"/>
        <ns1:Word skinName="WordSkin" y="156" x="130"/>
        <ns1:Word skinName="WordSkin" y="166" x="140"/>
        <ns1:Word skinName="WordSkin" y="176" x="150"/>
        <ns1:Word skinName="WordSkin" y="186" x="160"/>
        <ns1:Word skinName="WordSkin" y="196" x="170"/>
        <ns1:Word skinName="WordSkin" y="206" x="180"/>
        <ns1:Word skinName="WordSkin" y="216" x="190"/>
        <ns1:Word skinName="WordSkin" y="226" x="200"/>
        <ns1:Word skinName="WordSkin" y="236" x="210"/>
        <ns1:Word skinName="WordSkin" y="246" x="220"/>
        <ns1:Word skinName="WordSkin" y="256" x="230"/>
        <ns1:Word skinName="WordSkin" y="266" x="240"/>
        <ns1:Word skinName="WordSkin" y="276" x="250"/>
        <ns1:Word skinName="WordSkin" y="286" x="260"/>
        <ns1:Word skinName="WordSkin" y="296" x="270"/>
        <e:layout>
            <e:TileLayout horizontalGap="30" verticalGap="30"/>
        </e:layout>
    </e:Group>
    <e:Button id="btn_back" x="11" y="8">
        <e:skinName>
            <e:Skin states="up,down,disabled">
                <e:Image width="100%" height="100%" source="BackBtn_png" source.down="BackBtn1_png"/>
                <e:Label id="labelDisplay" horizontalCenter="0" verticalCenter="0"/>
            </e:Skin>
        </e:skinName>
    </e:Button>
    <e:Image id="img_question" width="390" height="260" y="179" horizontalCenter="0"/>
    <e:Group id="group_answer" width="373" height="95" x="177" y="464">
        <ns1:AnswerWord skinName="WordSkin" y="478" x="185"/>
        <ns1:AnswerWord skinName="WordSkin" y="478" x="284"/>
        <ns1:AnswerWord skinName="WordSkin" y="478" x="378"/>
        <ns1:AnswerWord skinName="WordSkin" y="478" x="475"/>
        <e:layout>
            <e:HorizontalLayout gap="15"/>
        </e:layout>
    </e:Group>
</e:Skin>
SceneGameSkin.exml

本篇已經結束,這里學習使用了自定義組件、類繼承(或說組件繼承),來搭建和設計游戲的主界面,將基礎做好,后面的開發工作就容易很多了。

本篇項目源碼:ChengyuTiaozhan3.zip(由於博客園的文件大小限制,resource資源方面請到第二篇的后面下載) 


免責聲明!

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



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