最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Unity程序猿勇闖茶杯之魂(二)

2018-09-18 16:55 作者:皮皮關(guān)做游戲  | 我要投稿

作者:Yukine


大家好。

之前驚聞ios上出現(xiàn)了假的茶杯頭手游(已被蘋果商店移除),就很好奇的去找了找視頻看看效果如何…… 好吧,更加堅(jiān)定了我填坑的信心。

還是我自己搞吧……

那么廢話不多說(shuō),讓我們書接上回:

在上一期中,主要介紹了主角的一些基本操作。在本期中,將先補(bǔ)充一些主角的其他操作(填坑)并制作一個(gè)Boss并能與玩家產(chǎn)生交互(再挖一個(gè)大坑)。


角色操作補(bǔ)充

上一期涉及的基本操作包括移動(dòng),跳躍,下蹲,沖刺和普通射擊。本期將補(bǔ)充EX射擊(也就是開大)和Parry(消除)兩個(gè)操作。

1.EX射擊

EX射擊和普通射擊的原理類似,但需要注意的是,EX射擊的子彈的射擊方向?yàn)榘朔较颍源a中要考慮到各種方向鍵輸入的情況;而且在地面上和在空中釋放EX射擊的動(dòng)畫是有一點(diǎn)差別的(前幾幀動(dòng)畫稍有不同),在不同狀態(tài)下要出發(fā)進(jìn)入不同的動(dòng)畫;此外,還有一個(gè)細(xì)節(jié)需要留意,EX射擊會(huì)產(chǎn)生很微弱的反沖力從而得到更好的視覺(jué)效果。

private void _Explosion()

{

    _isExplosion = true;

 

    _rigidbody.velocity = new Vector2(0, 0);

    _rigidbody.gravityScale = 0;

 

    //根據(jù)是否在地面觸發(fā)對(duì)應(yīng)動(dòng)畫

    if (_isGrounded)

    {

        _explosionDustBornEffectPos = _explosionDustBornEffectGroundPoint;

        _animator.SetTrigger("GroundExplosion");

    }

    else

    {

        _explosionDustBornEffectPos = _explosionDustBornEffectAirPoint;

        _animator.SetTrigger("AirExplosion");

    }

 

    //根據(jù)輸入的方向鍵改變射擊方向

    if(Input.GetKeyDown(KeyCode.W) || Input.GetKey(KeyCode.W))

    {

        if (Input.GetKeyDown(KeyCode.A) || Input.GetKey(KeyCode.A) || Input.GetKeyDown(KeyCode.D) || Input.GetKey(KeyCode.D))

        {

            _explosionDustPos = _explosionDustBornPointRightUp;

            _shootDic = new Vector2(_faceDic, 1);

            _animator.SetFloat("ExplosionState", 0.5f);

        }

        else

        {

            _explosionDustPos = _explosionDustBornPointUp;

            _shootDic = new Vector2(0, 1);

            _animator.SetFloat("ExplosionState", 0.25f);

        }

    }

    else if (Input.GetKeyDown(KeyCode.S) || Input.GetKey(KeyCode.S))

    {

        if (Input.GetKeyDown(KeyCode.A) || Input.GetKey(KeyCode.A) || Input.GetKeyDown(KeyCode.D) || Input.GetKey(KeyCode.D))

        {

            _explosionDustPos = _explosionDustBornPointRightDown;

            _shootDic = new Vector2(_faceDic, -1);

            _animator.SetFloat("ExplosionState", 0.75f);

        }

        else

        {

            _explosionDustPos = _explosionDustBornPointDown;

            _shootDic = new Vector2(0, -1);

            _animator.SetFloat("ExplosionState", 1f);

        }

    }

    else

    {

        _explosionDustPos = _explosionDustBornPointRight;

        _shootDic = new Vector2(_faceDic, 0);

        _animator.SetFloat("ExplosionState", 0);

    }

}

 


再將對(duì)應(yīng)的灰塵特效和子彈運(yùn)動(dòng)的腳本掛載到事先做好的預(yù)制體上,得到的效果如下(可以無(wú)限EX射擊的感覺(jué)真的是爽):

2.Parry消除

Parry可以說(shuō)是茶杯頭中一個(gè)很重要的操作,不僅影響最終的評(píng)分,關(guān)鍵時(shí)刻還能通過(guò)Parry躲過(guò)敵人攻擊。那么在實(shí)現(xiàn)這項(xiàng)功能時(shí)要注意:一是Parry僅能在跳躍狀態(tài)下出發(fā),所以要在跳躍狀態(tài)中才能相應(yīng)Parry的輸入指令;另一點(diǎn)是在Parry成功時(shí),會(huì)有一個(gè)很短暫的玩家停在空中的效果,這里需要在Parry成功的同時(shí)將Animator的速度變?yōu)?,在暫停時(shí)間過(guò)后恢復(fù)為1,同時(shí)在暫停時(shí)要將玩家的速度和重力影響都改為0,就可以基本表現(xiàn)出暫停的效果啦。

private void _Parry()

{

    _isParry = true;

    _isAlreadyParry = true;

 

    if (OnParry != null)

    {

        OnParry(true);

    }

 

    _animator.SetTrigger("Parry");

}

 

public void EnterPause(Vector2 parryHitPos) //進(jìn)入暫停狀態(tài)

{

    _isInParryState = true;

    _rigidbody.velocity = new Vector2(0, 0);

    _rigidbody.gravityScale = 0; //暫停無(wú)速度無(wú)重力

 

    _curAnimatorSpeed = _animator.speed;

    _animator.speed = 0f;

    _isOnPause = true;

 

    if(OnEnableParryEffect != null)

    {

        OnEnableParryEffect(_parryEffectPos.position, parryHitPos);

    }

}

 

那么將相應(yīng)的效果預(yù)制體之類的準(zhǔn)備好,來(lái)試驗(yàn)一下吧:

玩家的操作就介紹到這里了,玩家的其他狀態(tài)例如被擊中和死亡會(huì)放到后面再說(shuō),接下來(lái)就要開始制作Boss了。


Boss的制作

茶杯頭中的Boss眾多,各有特色,這里僅選取菜園關(guān)卡中的土豆Boss做個(gè)示范(其實(shí)是沒(méi)來(lái)得及做那么多(lll¬ω¬))。


1.場(chǎng)景搭建

既然是菜園關(guān)的Boss,那么就先把場(chǎng)景搭建好:

挺還原的!

好了,又到了扣細(xì)節(jié)的時(shí)間,沒(méi)錯(cuò),這個(gè)場(chǎng)景中也是有很多細(xì)節(jié)的!樹上的輪胎是在不斷播放動(dòng)畫的,而且天空中的云朵是在運(yùn)動(dòng)的,這里需要對(duì)云朵資源進(jìn)行回收與復(fù)用來(lái)避免頻繁的實(shí)例化,那么就需要用到在上一期提及的對(duì)象池,對(duì)象池的基本原理就是將要多次使用的物體存放于一個(gè)設(shè)定好的池內(nèi)(在代碼中通常是列表或字典),需要時(shí)從池內(nèi)取出對(duì)應(yīng)物體,在使用完畢后放回池內(nèi)來(lái)實(shí)現(xiàn)循環(huán)利用。

public void GetCloudInstance(int num, GameObject go)

{

    var startPos = _GetStartPos(num);

    var instanceToPool = _instancePool.GetInstance(go).GetComponent<Cloud>();

 

    Vector3 newStartPos = new Vector3(startPos.x, startPos.y, go.transform.position.z);

    instanceToPool.ResetPos(newStartPos, instanceToPool.CurrentType, this);

}

 

public void ReturnInstance(GameObject go)

{

    _instancePool.ReturnInstance(go);

}

 


該段代碼中的_instancePool即為設(shè)定好的對(duì)象池類,來(lái)實(shí)現(xiàn)出池和入池。這個(gè)類的具體代碼可以參考已上傳至GitHub上的SimpleGameObjectPool.cs腳本。

那么,設(shè)定好云朵的速度,產(chǎn)生位置和消失位置后,整個(gè)場(chǎng)景的效果就是下面這樣了:

2.Boss狀態(tài)分析

場(chǎng)景搭建完畢,接下來(lái)讓Boss動(dòng)起來(lái)。這個(gè)土豆Boss大體分為四種狀態(tài):跳出地面,閑置狀態(tài),攻擊狀態(tài)和被擊敗狀態(tài)。跳出地面及被擊敗只需要運(yùn)用Animator就足夠,這個(gè)Boss的攻擊模式也很簡(jiǎn)單:每輪攻擊會(huì)發(fā)射四顆子彈(前三顆為普通子彈,最后一顆為可Parry子彈),攻擊的動(dòng)畫速度會(huì)隨著輪數(shù)的增加而變快,并以三輪為一個(gè)循環(huán),每輪攻擊之間都有固定的時(shí)間間隔。那么在代碼中可以使用一個(gè)儲(chǔ)存了三個(gè)速度值的數(shù)組來(lái)控制每一輪攻擊時(shí)攻擊動(dòng)畫的播放速度,每當(dāng)一輪攻擊的四個(gè)子彈發(fā)射完畢后,馬上切換至下一個(gè)速度,并在設(shè)定的時(shí)間間隔后進(jìn)入下一輪攻擊。

//update中與攻擊相關(guān)的部分代碼

if (_isTimerWorking) //每一輪攻擊結(jié)束后開始計(jì)時(shí),超過(guò)設(shè)定的時(shí)間間隔就進(jìn)入下一輪攻擊

{

    _ChangeLocalPos(-0.2f);

    _animator.speed = 1;

    _timer += Time.deltaTime;

}

 

if(_timer < _intervalTime)

{

     return;

}

 

if(!_isInAttackState)

{

     _isTimerWorking = false

     _animator.speed = _curSpeed;

     _animator.SetTrigger("Attack");

     _isInAttackState = true;

}

//end update

 

//每一輪攻擊結(jié)束后切換至下一個(gè)動(dòng)畫播放速度

private void _OnNextSpeed(int stage)

{

    if (stage != 2)

    {

        stage = stage + 1;

        _curAttackStage = (AttackStage)stage;

    }

    else

    {

        stage = 0;

        _curAttackStage = AttackStage.StageOne;

    }

 

    _curSpeed = _fireSpeed[stage];

}

 

Boss發(fā)射子彈和玩家類似,在動(dòng)畫某一特定幀調(diào)用幀事件,并運(yùn)用事件機(jī)制將發(fā)射子彈的消息通知給相應(yīng)的管理腳本,并在管理腳本中獲取對(duì)應(yīng)的類型子彈實(shí)例。

private void _ShootBullet()

{

    _bulletCount += 1;

 

    //已發(fā)射子彈數(shù)小于4時(shí)發(fā)射普通子彈,等于4時(shí)發(fā)射可Parry子彈

    if (_bulletCount < 4)

    {

        if(OnShoot != null)

        {

            OnShoot(0);

        }

    }

    else

    {

        if (OnShoot != null)

        {

            OnShoot(1);

        }

    }

}


那么,Boss的初步效果就是這樣的了:


3.玩家與Boss的交互

到了最激動(dòng)人心的時(shí)刻了,玩家和Boss終于可以開始互毆了!為了有更好的表現(xiàn)效果,我們需要在玩家和Boss發(fā)射的子彈上添加腳本來(lái)判斷是否擊中了對(duì)方,這里玩家和Boss子彈都運(yùn)用了OnTriggerEnter的物理觸發(fā)模式,若檢測(cè)到接觸到的物體是要造成傷害的對(duì)象,則會(huì)使其出發(fā)受到傷害的函數(shù)。無(wú)論是玩家還是Boss,受到傷害后均要有視覺(jué)上的反饋:

  • 對(duì)于玩家來(lái)說(shuō),接觸到Boss的子彈會(huì)觸發(fā)被擊中動(dòng)畫,進(jìn)入被擊中狀態(tài),進(jìn)入被擊中狀態(tài)時(shí)不會(huì)響應(yīng)玩家的任何輸入;并且在被擊中動(dòng)畫播放完畢后進(jìn)入一段時(shí)間的無(wú)敵狀態(tài),在無(wú)敵狀態(tài)下,玩家會(huì)有規(guī)律的閃爍效果,這里只需要按照一定時(shí)間間隔改變Sprite Renderer的透明度即可,并且在此期間不會(huì)觸發(fā)被攻擊判定。

private void _EnterInvincibleState() //進(jìn)入無(wú)敵狀態(tài)

{

    _invincibleTimer += Time.deltaTime; //記錄無(wú)敵時(shí)間

    if(_invincibleTimer >= HIT_INVINCIBLE_TIME) //超過(guò)無(wú)敵時(shí)間,退出無(wú)敵狀態(tài),停止閃爍

    {

        _isInvincible = false;

        _isFadeAway = false;

        _spriteRender.color = new Color(1, 1, 1, _maxAlpha);

        _invincibleTimer = 0;

    }

}

 

private void _FadeAway() //無(wú)敵時(shí)閃爍

{

    _fadeAwayTimer += Time.deltaTime;

    if(!_isInFade && _fadeAwayTimer >= _normalTime)

    {

        //通過(guò)改變透明度實(shí)現(xiàn)閃爍的效果

        _spriteRender.color = new Color(1, 1, 1, _fadeAlpha);

        _isInFade = true;

        _fadeAwayTimer = 0f;

    }

    else if(_isInFade && _fadeAwayTimer >= _fadeAwayTime)

    {

        _spriteRender.color = new Color(1, 1, 1, _maxAlpha);

        _isInFade = false;

        _fadeAwayTimer = 0f;

    }

}

  • 對(duì)于Boss來(lái)說(shuō),若接觸到玩家發(fā)射的子彈也會(huì)有類似的閃爍效果,但Boss的閃爍原理與玩家不同,是通過(guò)Sprite Mask并控制遮罩層的顯隱來(lái)實(shí)現(xiàn)的。


最后我們?cè)賮?lái)處理一下玩家和Boss的被擊敗/死亡狀態(tài)。這里要涉及到數(shù)據(jù)的交互,由于現(xiàn)在僅需要實(shí)現(xiàn)效果,所以還沒(méi)有用到專門的類去處理數(shù)據(jù)(正式項(xiàng)目中不僅需要專門的數(shù)據(jù)類,同時(shí)也需要用專門的手段來(lái)存儲(chǔ)和讀取關(guān)卡,傷害,Boss血量等各類數(shù)據(jù)信息)。這里用最簡(jiǎn)單的在玩家類中設(shè)置生命數(shù),每被擊中一次生命數(shù)減一,為0時(shí)觸發(fā)死亡動(dòng)畫,在玩家死亡時(shí)要注意使按鍵輸入無(wú)效,以免出現(xiàn)bug;Boss則是在Boss類中直接設(shè)定血量,被子彈擊中時(shí)扣除相應(yīng)的子彈傷害,血量為0時(shí)播放被擊敗動(dòng)畫。實(shí)現(xiàn)效果可以參考以下兩個(gè)短視頻:


首先是玩家被擊中三次后死亡的效果

再來(lái)看看Boss被擊敗后的效果


嗯,至少比那個(gè)ios上的假茶杯頭好多了(根本不是一個(gè)平臺(tái)的啊喂~)。那么至此,茶杯頭系列算是暫時(shí)告一段落了,至于還會(huì)不會(huì)有更新,我只想說(shuō):有夢(mèng)是好事,可惜不現(xiàn)實(shí),還是夢(mèng)里有緣再見吧~

目前涉及到的所有的代碼已經(jīng)傳至我的GitHub:https://github.com/Yukimine33/CupheadCodeByMyself  歡迎查閱。


想系統(tǒng)學(xué)習(xí)游戲開發(fā)的童鞋,歡迎訪問(wèn) http://levelpp.com/      

游戲開發(fā)攪基QQ群:869551769       

微信公眾號(hào):皮皮關(guān)

Unity程序猿勇闖茶杯之魂(二)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
丘北县| 景东| 竹北市| 察雅县| 社旗县| 信丰县| 兰州市| 工布江达县| 台前县| 乌什县| 越西县| 如东县| 灵寿县| 奉化市| 白沙| 兴海县| 博兴县| 新龙县| 永吉县| 汉寿县| 山东| 项城市| 蕉岭县| 西城区| 云龙县| 临城县| 鄢陵县| 巢湖市| 缙云县| 乐陵市| 长治县| 来安县| 秦皇岛市| 吴川市| 湾仔区| 嵊州市| 沙田区| 彭阳县| 科技| 屏南县| 中超|