<cocos2d-x for window phone>一個簡單的打地鼠遊戲

免責聲明:本文章由fengyun1989創作,採用知識共享署名-非商業性使用-相同方式共享 2.5 中國大陸許可協議進行許可。

寫在前面:最近兩個月比較忙,很久沒更新教程了。這麼些日子,發生了不少事,WP8發佈了。我的T8788也被徹底拋棄了。。。win8也RP版了。前景未卜啊。肯定不少人在迷茫了吧。我覺得呢,都是浮雲,語言只是工具,能夠一通百通才是王道,微軟不行大不了換IOS,Android。接下來的一段時間,估計會寫些win8的教程。我感覺win8和WP8有種莫名的聯繫,不過也道不清說不明。反正就順着感覺來了。

本次教程寫一個簡單的打地鼠遊戲。如果你對cocos2d-x編程不瞭解,可以先閱讀cocos2d-x做一個簡單的windows phone 7遊戲》系列文章。不過,如果你有相關的經驗就另當別論了。

程序截圖:

思路簡介:

  打地鼠主要是問題就在於地鼠出頭和打地鼠的點擊處理。地鼠出頭有兩種方法,一種是用動畫,一種是用Z軸的縱向效果。動畫效果的方法Nowpaper前段時間就寫了這麼一篇《Cocos2d-x for WindowsPhone:開發一個打地鼠遊戲》,我想就不在這裏囉嗦了。懶得再將這些重複的內容在做一遍。這裏就介紹下Z軸的方法。

    

    只要把前景分爲3塊。分爲上中下三塊,在洞的中心分開。添加到層的時候設置Z軸,最下的最前,最上的最後。最後後的設置一塊黑色的背景。兩塊圖之間留着空間來讓地鼠Sprite進行move動作。這樣就能產生地鼠從洞中鑽出的視覺效果了。

    現在來下載需要的圖片;http://dl.dbank.com/c0tayrr384

開始吧:

  新建一個工程cocos2d的工程,命名爲cocos2dWhacAMoleDemo。當然,因爲是練習項目,所以OpenXLive沒有用到。就去掉那個勾。然後修復引用。這些操作做了很多次了。不懂的建議看下以前的文章。

   然後再Classes文件夾添加一個類。命名爲AttackMoleScene.cs,使之繼承於CCScene。修改代碼如下:

namespace cocos2dWhacAMoleDemo.Classes
{
    class AttackMoleScene:CCScene
    {
        public AttackMoleScene()
        {
            this.addChild(AttackMoleLayer.node());
        }
    }

    class AttackMoleLayer : CCLayer
    {
        public override bool init()
        {
            if (!base.init())
                return false;
            CCSize winSize = CCDirector.sharedDirector().getWinSize();
            CCSprite background = CCSprite.spriteWithFile(@"images/background");
            background.position = new CCPoint(winSize.width / 2, winSize.height / 2);
            this.addChild(background, -3);
            CCSprite grassUpper = CCSprite.spriteWithFile(@"images/grass_upper");
            grassUpper.position = new CCPoint(winSize.width / 2, winSize.height - grassUpper.contentSize.height / 2);
            this.addChild(grassUpper, -2);
            CCSprite grassMid = CCSprite.spriteWithFile(@"images/grass_mid");
            grassMid.position = new CCPoint(winSize.width / 2,
                winSize.height - grassUpper.contentSize.height - grassMid.contentSize.height / 2);
            this.addChild(grassMid, 0);
            CCSprite grassLower = CCSprite.spriteWithFile(@"images/grass_lower");
            grassLower.position = new CCPoint(winSize.width / 2, grassLower.contentSize.height / 2);
            this.addChild(grassLower, 2);
            return true;
        }

        public new static AttackMoleLayer node()
        {
            AttackMoleLayer layer = new AttackMoleLayer();
            if (layer.init())
                return layer;
            return null;
        }
    }
}

上面做了些什麼呢,在層裏面添加了前景。三塊,細心的朋友注意到了。我addChild的時候,Z軸的參數都不一樣。背景在最後,所以Z軸的值最小。每兩塊間留一個位置給地鼠冒頭。前景的位置也是設置成上中下三個位置。這樣,從Z軸的上頭看下就能正好成一整塊前景。

  現在修改AppDelegate的applicationDidFinishLaunching方法:

            //CCScene pScene = cocos2dWhacAMoleDemoScene.scene();
            AttackMoleScene pScene = new AttackMoleScene();
            //run
            pDirector.runWithScene(pScene);

現在可以執行了。就可以看到不錯的前景了。

那麼現在來添加一個地鼠來冒一下頭試試吧。

在層的init方法上面添加:

            CCSprite mole = CCSprite.spriteWithFile(@"images/mole_1");
            mole.position = new CCPoint(155,30);
            var move = CCMoveBy.actionWithDuration(2, new CCPoint(0, 100));
            var action = CCRepeat.actionWithAction(CCSequence.actions(move, move.reverse()), 5);
            mole.runAction(action);
            this.addChild(mole, 1);

添加一個地鼠到層中,並且設置它在左下角的洞裏進行Move來回運動。關於這個座標(155,30)是怎麼算出來的,我用畫圖工具打開grass.png這個文件,用鼠標來大概獲取座標,然後用筆算下座標。需要注意的是,cocos2d-x裏面的座標原點在左下角。而window的是在左上角。

現在編譯運行,就能看到一個地鼠來回冒頭了。

讓地鼠隨機冒頭

  我們先來思考下接下來的怎麼做,怎麼保存所以的地鼠精靈,怎麼確定初始化座標,怎麼判斷地鼠被打,然後讓他消失,怎麼確定洞裏面有地鼠而不至於重複添加。

   我的方法是全部用數組來解決。比較簡單。

   添加以下的聲明到層:

        int[,] moleValue = new int[2, 3] { { 0, 0, 0 }, { 0, 0, 0 } };
        CCSprite[,] moles = new CCSprite[2, 3];
        int[] initPositionX = new int[3] { 155, 400, 640 };
        int[] initPositionY = new int[2] {30, 260};

上面的moleValue記錄的是當前洞裏有沒有地鼠,1就是有,0就是沒有。moles記錄當前所有冒頭地鼠的引用。最後兩個是初始化座標,3*2=6. 這些座標都是我通過畫圖工具來計算出來的。

現在註釋到上面的單個地鼠冒頭的代碼。往層裏面添加方法:

       void addMole(float dt)
        {
            Random r = new Random();
            int i = r.Next() % 3;
            int j = r.Next() % 2;
            if (moleValue[j, i] == 0)
            {
                moles[j, i] = CCSprite.spriteWithFile(@"images/mole_1");
                moles[j, i].position = new CCPoint(initPositionX[i], initPositionY[j]);
                var move = CCMoveBy.actionWithDuration(2, new CCPoint(0, 100));
                var action = CCSequence.actions(move, move.reverse()
                    , CCCallFuncN.actionWithTarget(this, spriteMoveDone));
                moles[j, i].runAction(action);
                moleValue[j, i] = 1;
                if (j == 0)
                    this.addChild(moles[j, i], 1);
                else
                    this.addChild(moles[j, i], -1);
            }
        }

        void spriteMoveDone(object sender)
        {
            CCSprite sprite = sender as CCSprite;
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    if (moles[j, i] == sprite)
                    {
                        moleValue[j, i] = 0;
                        break;
                    }
                }
            }
            this.removeChild(sprite, true);
        }

並且添加一行到init方法

this.schedule(addMole, 1.0f);

我們修改地鼠變爲只是上下Move一次。並且在退回後調用回調函數移除該sprite。設置該位置的moleValue值爲0.現在就能看見地鼠不怕死的不斷冒頭了。

打地鼠

  既然地鼠都不怕死的冒出來了。不打貌似很不爽的樣子,但是,現在點擊屏幕,沒人任何反應。。。因爲我們還沒有對點擊進行註冊和處理。

   那麼怎麼判斷是點擊了地鼠呢。我設定這麼一個範圍算是點擊了地鼠。

  由於地鼠初始化在框的下面,其座標的X和在這個黑色框下邊的中點座標X一樣。Y值+70纔算和這個黑色框下邊的中點的座標Y值一樣。

現在添加一個方法來處理觸點座標:

        private void handleTouchPosition(CCPoint touch)
        {
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    float tempX = initPositionX[i] - touch.x;
                    if ((tempX < 80 && tempX > -80) && (initPositionY[j] + 150 - touch.y > 0 && initPositionY[j] + 70 < touch.y))
                    {
                        if (moleValue[j, i] == 1)
                        {
                            if (moles[j, i] != null)
                            {
                                this.removeChild(moles[j, i], true);
                            }
                            moleValue[j, i] = 0;
                            moles[j, i] = null;
                        }
                        return;
                    }
                }
            }
        }

這樣,遍歷所有的洞,判斷點擊是否是這個洞。然後判斷現在是否有地鼠,有地鼠就把地鼠移除。

現在在init方法中註冊觸摸事件:

this.isTouchEnabled = true;

然後重載ccTouchesEnded方法:
        public override void ccTouchesEnded(List<CCTouch> touches, CCEvent event_)
        {
            foreach (var touch in touches)
            {
                CCPoint touchLocation = touch.locationInView(touch.view());
                touchLocation = CCDirector.sharedDirector().convertToGL(touchLocation);
                touchLocation = this.convertToNodeSpace(touchLocation);
                handleTouchPosition(touchLocation);
            }
        }

這個方法先把座標轉換,再處理座標。現在運行,可以看到地鼠被打死了。

何去何從

  現在,我們已經擁有了一個不錯的打地鼠遊戲。是不是覺得少了點什麼呢。。

  •     考慮拓展地鼠被打的動作,加個錘子或者什麼的。另外,可以添加地鼠被打後的表情,這都可以用Action可以實現
  •     把硬編碼的地鼠重構出來,添加多個關卡
  •     去試試用動畫來製作地鼠冒頭
  •     增加更多種類的地鼠,比如說有些地鼠可以捱打2下
  •     添加很棒的音效

本次工程代碼下載:http://dl.dbank.com/c0bgua6l79


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章