搜尋此網誌

2012年8月26日 星期日

ActionScript3.0 簡單寫個配對遊戲

有了 CAnimSprite 跟 CSimpleButton 這2個 class 之後
我們就可以簡單得來寫個配對遊戲

private function resInit():void {
    var i:int, j:int, k:int, sx:int, sy:int;
    var bmp:Bitmap = new CResources.imgCards();
   
    for ( i = 0; i < 2; i ++ ) m_spSel.push(null);
    for ( j = 0, sy = 50, k = 0; j < ROW_USED; j ++, sy += 52 ) {
        for ( i = 0, sx = 50; i < COL_USED; i ++, sx += 52, k ++ ) {
            var sp:CAnimSprite = new CAnimSprite(bmp, 50, 50);
            sp.x = sx;
            sp.y = sy;
            addChild(sp);
            sp.Value = k / 2 + 2;
            m_spCards.push(sp);
        }
    }
   

    m_btnStart = new CSimpleButton(new CResources.Menu_NewGame(), 80);
    m_btnStart.x = 300;
    m_btnStart.y = 260;
    addChild(m_btnStart);
    m_btnStart.addEventListener(MouseEvent.CLICK, clickGameStart);
   
    var format:TextFormat = new TextFormat();
    format.font = "Verdana";
    format.color = 0xFF0000;
    format.size = 24;
    m_txtTime.width = 200;
    m_txtTime.height = 30;
    m_txtTime.defaultTextFormat = format;
    m_txtTime.x = 280;
    m_txtTime.y = 20;
    addChild(m_txtTime);
}
一開始的初始化,主要是在舞台上擺上24張牌一個按鍵跟顯示時間用的TextField
其中的 sp.Value = k / 2 + 2; 是用來指定牌的內容
這是所使用的圖形,第一個frame是蓋牌,第二個frame之後就是開牌後所要顯示的內容


private function clickGameStart(event:MouseEvent):void {
    var btn:CSimpleButton = event.target as CSimpleButton;
    var i:int, rnd:int, v:int;
   
    btn.visible = false;
    for ( i = 0; i < ROW_USED * COL_USED; i ++ ) {
        rnd = RandNumber(0, ROW_USED * COL_USED - 1);
        v = m_spCards[i].Value;
        m_spCards[i].Value = m_spCards[rnd].Value;
        m_spCards[rnd].Value = v;
    }
    for ( i = 0; i < ROW_USED * COL_USED; i ++ ) {
        m_spCards[i].gotoAndStop(m_spCards[i].Value);
        m_spCards[i].useHandCursor = true;
    }
    m_selCount = 0;
    m_viewTime = VIEW_SECONDS;
    m_Timer.addEventListener(TimerEvent.TIMER, timerHandler);
    m_Timer.addEventListener(TimerEvent.TIMER_COMPLETE, completeHandler);
    m_Timer.reset();
    m_txtTime.text = m_viewTime.toString();
    m_Timer.start();
}
按了開始遊戲的按鍵,在事件處理函式做的是用亂數交換牌的內容(洗牌)
顯示所有牌的內容,再用一個Timer倒數計時讓玩家有5秒的看牌時間

private function completeHandler(e:TimerEvent):void {
    m_txtTime.text = "0";
    m_Timer.removeEventListener(TimerEvent.TIMER, timerHandler);
    m_Timer.removeEventListener(TimerEvent.TIMER_COMPLETE, completeHandler);
    m_cardLeft = ROW_USED * COL_USED;
    for ( var i:int = 0; i < m_cardLeft; i ++ ) {
        m_spCards[i].gotoAndStop(1);
        m_spCards[i].buttonMode = true;
        m_spCards[i].addEventListener(MouseEvent.CLICK, clickOnCards);
    }
    m_tmStart = getTimer();
    addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
倒數時間到事件處理函式:
先移除一些有關Timer的偵聽事件
所有的牌改顯示為蓋牌,並為每張牌加滑鼠按鍵的偵聽動作
addEventListener(Event.ENTER_FRAME, onEnterFrame); 則主要是用來計算顯示使用的時間

private function clickOnCards(event:MouseEvent):void {
    var sp:CAnimSprite = event.currentTarget as CAnimSprite;

    //trace(event.currentTarget);
    if( m_selCount < 2 ) {
        m_spSel[m_selCount++] = sp;
        sp.gotoAndStop(sp.Value);
        sp.buttonMode = false;
        sp.removeEventListener(MouseEvent.CLICK, clickOnCards);
        if ( m_selCount == 2 ) setTimeout(CheckCardMatch, 100);
    }
}
每選一張牌,就將該張牌放入一個陣列
當選了兩張牌時,就做檢查的動作
用 setTimeout(CheckCardMatch, 100); 主要是讓第二張牌有足夠的時間來顯示

private function CheckCardMatch():void {
    m_selCount = 0;
    if ( m_spSel[0].Value != m_spSel[1].Value ) {
        for ( var i:int = 0; i < 2; i ++ ) {
            m_spSel[i].gotoAndStop(1);
            m_spSel[i].buttonMode = true;
            m_spSel[i].addEventListener(MouseEvent.CLICK, clickOnCards);
        }
    }
    else {
        m_cardLeft -= 2;
        if ( m_cardLeft == 0 ) {
            removeEventListener(Event.ENTER_FRAME, onEnterFrame);
            m_btnStart.visible = true;
        }
    }
}
檢查動作很簡單,只要比較兩張牌的Value是不是一樣即可
不一樣則恢復蓋牌及偵聽的動作
一樣則將剩餘牌數減2,當剩餘牌數為0時,表示完成遊戲
移除ENTER_FRAME的偵聽停止計時
重新顯示開始遊戲的按鍵

完整的程式碼(FlashDevelop的專案)

程式結果:


4 則留言:

大俠HowRU 提到...

玩了三次,成績是:102、58、77



請問一下~美化圖片工具的中文化&簡單邊框有加入2.7.3 PORTABLE了嗎?想把第一版中的圖樣放到中文版來用,要怎樣做?謝謝
[版主回覆09/01/2012 13:36:14]之前文中不是已經有說明了

此版經過縮減,所附的樣板較少,但開放自訂可以讀取外在的圖檔來當樣板
您可在此下載額外的材質 https://github.com/hejiann/beautify/wiki/Textures-Download
將下載的圖檔或您自己自訂的圖檔放在
\Documents and Settings\"使用者的名稱"\.gimp-2.8/rip-border
\Documents and Settings\"使用者的名稱"\.gimp-2.8/texture-border
資料夾底下即可
上面是安裝版,如果是可攜式版本,以 portable 2.8 來說,則是
\Data\.gimp\rip-border
\Data\.gimp\texture-border

大俠HowRU 提到...

我現在用的版本是2.7.3 PORTABLE第一版,2.7.3 PORTABLE好像有更新過,是不是?PORTABLE 2.7.4還是一樣嗎?想更新版本,不知道下載哪個好。應該採用哪個當基礎,然後把另一個版本不同的地方放進來?再加上美化圖片工具的中文化&簡單邊框。簡單說就是更新時也做一個集大成,把新東西都加進來成為最完整的。之前用的時候,2.7.3比2.7.4跑得順,所以留2.7.3,而且也跟2.8一樣。
不然就是用portable 2.8,把2.7.3跟2.7.4的資料夾移進來,好處可能是少了顯示BUG的黑畫面??

大俠HowRU 提到...

請問~這個Adobe Pixel Bender Plug-In,GIMP可以用嗎?要放在哪兒?謝謝(BY前面的小方格打勾,會出現載點)

大俠HowRU 提到...

Adobe Pixel Bender Plug-In
http://labs.adobe.com/downloads/pixelbenderplugin.html
[版主回覆09/09/2012 20:23:20]也許你可以寫信給adobe
建議它如果要出plugin
順便也出gimp版