用cocos2d-x做一個簡單的windows phone 7遊戲:旋轉炮塔(二)用cocos2d-x做一個簡單的windows phone 7遊戲:更猛的怪獸和更多的關卡(三)

來源:互聯網
上載者:User

本教程基於子龍山人翻譯的cocos2d的IPHONE教程,用cocos2d-x for XNA引擎重寫,加上我一些加工製作。教程中大多數文字圖片都是原作者和翻譯作者子龍山人,還有不少是我自己的理解和加工。感謝原作者的教程和子龍山人的翻譯。本教程僅供學習交流之用,切勿進行商業傳播。

子龍山人翻譯的Iphone教程地址:http://www.cnblogs.com/andyque/articles/1997820.html

Iphone教程原文地址:http://www.raywenderlich.com/692/rotating-turrets

 

旋轉炮塔來改變射擊的方向。許多遊戲都有這個功能,

 

在這個教程中,將會詳細地講解如何?這個功能,即如何把旋轉炮塔的功能添加到一個遊戲當中去。

準備工作

  如果你看完並實踐了上一個教程,你可以繼續使用那個工程。如果沒有的話,那麼下載這個連結的代碼吧。

  接下來,下載新的 player sprite 和 projectile sprite圖片,然後把它們加到Content工程的images目錄裡面。並修改原來的精靈初始化代碼。

// In the init methodCCSprite player = CCSprite.spriteWithFile(@"images/player2");// In the ccTouchesEnded methodCCSprite projectile = CCSprite.spriteWithFile(@"images/Projectile2");

 

編譯並運行你的工程,如果一切順利的話,你將會看到一個炮塔正在發射子彈。然後,這並不是很好,因為炮塔在射擊的時候並沒有面朝那個方向。因此,接下來讓我們來解決這個問題。

 

 

 

旋轉並射擊

 

  在我們旋轉炮塔之前,首先,我們需要儲存Player精靈的引用,以便後面旋轉它的時候使用。把Player精靈的聲明提到類當中去:

CCSprite player;


修改init中的代碼為:

player = CCSprite.spriteWithFile(@"images/player2");

 

好了,現在讓我們取出player對象的引用並且旋轉它吧!為了旋轉它,我們首先需要計算出旋轉的角度。為瞭解決這個問題,想想我們在高中時候學過的三角代數吧。還記得sin cos tan嗎?為了便於理解,下面使用一張圖來解釋一下:tan = 對面/鄰邊。

 

 

  如上所示,我們想要旋轉的角度是arctangent(angle),即對offY/offX求arctangent運算。

  然而,這裡還有兩件事情,我們需要放在心上。首先,當我們計算actangent(offY/offX)的時候,這個結果是弧度,但是cocos2d使用的卻是角度。還好,cocosd2d提供了一個非常方便的宏,可以使得角度和弧度之間方便轉化。

  第二點,我們假定上面的圖中angle的偏轉是正20度,但是,cocos2d裡面順時針方向為正(而不是所示的逆時針為正)。讓我們看到下面這個圖:

 

 

 

  因此,為了得到正確的方向,我們把運算結果乘以一個-1就可以了。比如,如果我們把上面那幅圖片裡的角度乘以-1的話,我們就得夠得到-20度,這個角度其實就是逆時針方向的20度。(感覺老外說話好囉嗦啊,聰明的讀者恐怕早就明白了吧!:)

  好了,講得夠多了!讓我們來寫一點代碼吧。在ccTouchesEnded裡面加入以下代碼,添加位置在你的projectile runAction之前。

            //Determine angle to face            float angleRadians = (float)Math.Atan(offRealY / offRealX);            float angleDegrees = MathHelper.ToDegrees(angleRadians);            float cocosAngle = -1 * angleDegrees;            player.rotation = cocosAngle;

 

 

  編譯並運行工程,現在我們的炮塔在射擊的時候可以改變方向了。

旋轉之後再射擊

  目前來說還不錯,但是有一點點怪。因為,這個炮塔好像突然一下跳到一個方向射擊,有點不夠流暢。我們可以解決這個問題,但是在這之前,我們需要重構一下代碼。

  首先,開啟GamePlayLayer類,然後在你的類裡添加如下成員變數:

CCSprite nextProjectile = null;

然後,修改你的ccTouchesEnded方法,並且添加一個新的方法,叫做finishShoot,如下所示:

        public override void ccTouchesEnded(List<CCTouch> touches, CCEvent event_)        {            if (nextProjectile != null)                return;            CCTouch touch = touches.FirstOrDefault();            CCPoint location = touch.locationInView(touch.view());            location = CCDirector.sharedDirector().convertToGL(location);            //set up initial location of projectile            CCSize winSize = CCDirector.sharedDirector().getWinSize();            //CCSprite projectile = CCSprite.spriteWithFile(@"images/Projectile");            nextProjectile = CCSprite.spriteWithFile(@"images/Projectile2");            nextProjectile.position = new CCPoint(20, winSize.height / 2);            //Determine offset of location to projectile            float offX = location.x - nextProjectile.position.x;            float offY = location.y - nextProjectile.position.y;            //Bail out if we are shooting or backwards            if (offX <= 0)            {                return;            }            //Determine where we wish to shoot the projectile to            float realX = winSize.width + nextProjectile.contentSize.width / 2;            float ratio = offY / offX;            float realY = realX * ratio + nextProjectile.position.y;            CCPoint realDest = new CCPoint(realX, realY);            //Determine the length of how far we're shooting            float offRealX = realX - nextProjectile.position.x;            float offRealY = realY - nextProjectile.position.y;            float length = (float)Math.Sqrt(offRealX * offRealX + offRealY * offRealY);            float velocity = 480 / 1;//480pixls/lsec            float realMoveDuration = length / velocity;            //Determine angle to face            float angleRadians = (float)Math.Atan(offRealY / offRealX);            float angleDegrees = MathHelper.ToDegrees(angleRadians);            float cocosAngle = -1 * angleDegrees;            float rotateSpeed = (float)(0.5 / Math.PI);//Would take 0.5 seconds to rotate 0.5 radians ,or half a circle            float rotateDuration = Math.Abs(angleRadians * rotateSpeed);            player.runAction(CCSequence.actions(CCRotateTo.actionWithDuration(rotateDuration,cocosAngle), CCCallFunc.actionWithTarget(this, finishShoot)));            //Move projectile to actual endpoint            nextProjectile.runAction(CCSequence.actions(CCMoveTo.actionWithDuration(realMoveDuration, realDest),                CCCallFuncN.actionWithTarget(this,spriteMoveFinished)));            nextProjectile.tag = 2;                        //SimpleAudioEngine.sharedEngine().playEffect(@"resource/pew-pew-lei");        }        void finishShoot()        {             // Ok to add now , we are finished rotation            this.addChild(nextProjectile);            _projectiles.Add(nextProjectile);            nextProjectile = null;        }

看上去好像有許多代碼,但是,實際上我們改動的並不多--大部分只是做一些小小的重構。下面是我們所修改的內容的一個列表:

  1.在函數開頭檢查nextProjectile的值是否為nil。這意味著我們當前的touch事件正發生在射擊過程之中。也就是說,炮塔已經發射出一個子彈了。

  2.之前,我們使用一個projectile的局部變數,並把它加入到了當前的情境中。在這個版本中,我們增加了一個nextProjectile的成員變數,但是並沒有馬上加到當前情境中。因為後要還要使用。

  3.定義炮塔旋轉的角度,半秒鐘旋轉半個圓。記住,一個圓有2 PI個弧度。

  4.計算旋轉特定的角度需要多長時間,這裡是拿弧度乘以速度。

  5.接下來,我們使用一個sequence action來旋轉我們的炮塔。最後,調用一個函數,把projectile加入到當前情境當中去。

  好,大功告成!編譯並運行工程,現在炮塔可以旋轉,並且很流暢地射擊了!

 

本次工程下載:http://dl.dbank.com/c0cvo9f1gc

 繼續學習:用cocos2d-x做一個簡單的windows phone 7遊戲:更猛的怪獸和更多的關卡(三)

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.