2017-08-17 23:21:39 yongh701 阅读数 7626
  • Unity3D棋盘游戏实战入门——2D智力拼图

    本课程使用Unity3d开发软件和C#编程语言,从零开始逐步完成一个2D拼图游戏项目。在本课程中,你可以了解并学习到游戏工程的创建和文件结构的维护、Unity3D的射线检测机制、插值插件Itween的使用、游戏数据的离线保存,并初步了解Unity3D的粒子系统和动画系统。

    766 人正在学习 去看看 伍晓波

回合制游戏一直在游戏史,至少是在中国的游戏历史上扮演很重要的角色。从仙剑到梦幻,这类游戏深受玩家喜爱。那么在Unity3D中怎么实现呢?下面用一个比较简单Unity3D的一对一回合制游戏来说明这个问题。其实也不难,关键是理清各个处理关系。

如下图所示,绿色代表玩家操控的主角,蓝色代表遇到的敌人,分别赋予大家100HP,然后玩家打敌方一下,敌方就-40HP,玩家被敌方摸一下就-30HP。下面是玩家成功战胜敌人的情况。


当然,玩家也可以防御的,此时敌方摸玩家一下仅15HP。下图是展示玩家HP变成0,游戏失败的情况。


当然,这个例子一点不好玩,毕竟又没有药品,招式只有1个,还是1对1的对打。甚至连MP都没有。也没有根据速度计算谁先出手的问题,还有Buff与Debuff之类的。不过,为了说明在Unity3D如何制作回合制游戏。我尽可能将一些能简化的东西先简化,主要突出回合制游戏的制作核心。

一、场景布置

首先是简单的场景布置,在3D部分很简单。就几个简单的基本组件,在一个Plane上面放2个Cube。并且上不同颜色的纯色Material。不赘述了,不懂可以参考《【Unity3D】物体、材质的设置、物体位移与旋转》(点击打开链接)。唯一需要大家注意的是,请将两个Cube改好名,以免到时候编程不知道哪个跟哪个。


其次是UGUI的布置。左下角是一个名为ActionPanel的Panel,旗下有两个按钮Attack Button和Defend Button,一会儿ActionPanel将被控制,而按钮Attack Button和Defend Button则将赋予点击事件。UGUI的按钮点击事件可以参考《【Unity3D】场景切换、UGUI组件事件、开始游戏与关闭游戏》(点击打开链接)。在这个ActionPanel的下方则是一个名为PlayerHPinfo的Text,同样会被脚本控制,用于显示血量等信息。

至于右上角是个动态文本的滚动区域WarinfoPanel,里面放置的一个WarinfoText用于显示战斗信息的文本,具体的制作可以参考《【Unity3D】动态文本的滚动条》(点击打开链接),这里需要注意上Mask组件的时候去除Show Mask Graphic,不然WarinfoText显示不出来。而在其下方,则是一个退出战斗的按钮ExitButton,当然这个东西,在实际游戏里面完全可以不要,自动切换回战斗前的场景。


并同时新建一个空物体WarControl,赋予脚本WarControl.cs。

以下是各个对象的从属关系,请注意改好名字。因为基本上上面提到的组件,都将被WarControl.cs控制。


二、脚本编写

WarControl.cs设置的变量,并且要控制的物体如下所示:


这段代码的思想如下:

由于Update()在每一帧的刷新都被执行的,在1秒就30帧的瞬间,Update()里面的代码不读完,这游戏就被卡死,所以Update()这个可视为主线程的函数,只承担以下简单任务,时刻在判断HP是否见底。


而攻击表演这些要交代给玩家看的东西,至少要占用1s的技能表演,我们则通过协程Coroutine完成,协程的详细说明具体可以看《【Unity3D】协程Coroutine的运用》(点击打开链接)。协程,其实也就是Unity3D的子线程,将通过按钮点击时间来创建。各个按钮点击之后,具体的思想如下图表示,其中实线表示玩家点击了“攻击按钮”,虚线则表示玩家点击了“防御按钮”。上例子的动画,我采用了Unity3D中极其简单的动画组件iTween来做,具体可以见《【iTween】单点移动和旋转》(点击打开链接)。

这里涉及到挂起0.5s~0.9s的东西,因此,只能写在协程里面完成的,不可能写在Update()里面,不然这游戏绝对卡死。


因此,WarControl.cs如下,赋予给空物体WarControl。

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class WarControl : MonoBehaviour
{

    public GameObject Player;//代表玩家的绿色立方体
    private int Player_HP;//玩家的HP
    public GameObject Enemy;//代表玩家的蓝色立方体
    private int Enemy_HP;//敌人的HP
    public GameObject ActionPlane;//左下角玩家操作面板,旗下有两个按钮
    public GameObject PlayerHPinfo;//左下角的玩家的HP信息文本Text
    public GameObject WarinfoText;//右上角的战斗信息文本Text
    public GameObject ExitButton;//退出按钮
    private int Player_Max_HP;//玩家最大血量,这个其实可以视为一个常量const

    /*场景初始化过程,数据初始化过程我也写在这里了*/
    void Start()
    {

        Time.timeScale = 1;//打破时间结界,主要是配合下面update()中结算时的布置的时间结界Time.timeScale = 0;玩家点击“退出”重新进入场景

        /*定义玩家和敌人的血量和玩家的最大血量,这部分在实际中,可以从记载游戏状态的xml等地方取,这里粗暴定义为100*/
        Player_HP = 100;
        Enemy_HP = 100;
        Player_Max_HP = Player_HP;

        /*更新UI*/
        PlayerHPinfo.GetComponent<Text>().text = "HP:" + Player_HP + "/" + Player_Max_HP;//玩家HP信息文本的更新
        WarinfoText.GetComponent<Text>().text = "战斗开始!\n";//战斗信息更新

        ExitButton.SetActive(false);//隐藏“退出战斗”这个按钮

    }

    /*主线程,时刻在读取,这段由于大量代码是相同的,因此还可以优化下这个条件结构的写作*/
    void Update()
    {

        if (Player_HP < 0)
        {
            PlayerHPinfo.GetComponent<Text>().text = "HP:" + Player_HP + "/" + Player_Max_HP;//由于战斗结算在下面的子线程完成,在最终的战斗结算需要再次更新UI,以免有显示BUG
            Time.timeScale = 0;//布置一个时间结界
            ExitButton.SetActive(true);//打开“退出游戏”按钮
            Player.SetActive(false);//将代表玩家这个立方体消失,实际上还可以播放下玩家死亡动画什么的
            ActionPlane.SetActive(false);//关闭操作UI
            /*更新战斗信息*/
            WarinfoText.GetComponent<Text>().fontSize = 30;
            WarinfoText.GetComponent<Text>().text = "玩家死亡!战斗失败!\n";
        }

        if (Enemy_HP < 0)//同上,不赘述了
        {
            PlayerHPinfo.GetComponent<Text>().text = "HP:" + Player_HP + "/" + Player_Max_HP;
            Time.timeScale = 0;
            ExitButton.SetActive(true);
            Enemy.SetActive(false);
            ActionPlane.SetActive(false);
            WarinfoText.GetComponent<Text>().fontSize = 30;
            WarinfoText.GetComponent<Text>().text = "敌人死亡!胜利战斗!\n";
        }

    }

    /*按钮点击事件*/
    public void AttackButtonOnclick()
    {
        StartCoroutine(Attack());
    }
    public void DefendButtonOnclick()
    {
        StartCoroutine(Defend());
    }
    public void ExitButtonOnclick()
    {
        Application.LoadLevel("Turnbase_Single");
    }

    /*攻击协程*/
    IEnumerator Attack()
    {
        ActionPlane.SetActive(false);//先关闭操作UI
        StartCoroutine(Player_Attack());//新建一条玩家攻击协程
        yield return new WaitForSeconds(0.9f);//等待0.9s再读下面的代码,也就是等待玩家攻击技能表演完,一共0.9s
        yield return new WaitForSeconds(0.5f);//再等待0.5s,让玩家喘口气,表示上述动作交代完了,开始交代下述敌人攻击的技能
        StartCoroutine(Enemy_Attack(false));//再新建一条敌人攻击的协程,这里的false代表玩家没有防御
        yield return new WaitForSeconds(0.9f);//等待0.9s再读下面的代码,也就是等待敌人攻击技能表演完,一共0.9s
        PlayerHPinfo.GetComponent<Text>().text = "HP:" + Player_HP + "/" + Player_Max_HP;//更新UI
        ActionPlane.SetActive(true);//再打开操作UI,让玩家进行下一个回合的指令
        yield return null;
    }

    /*防御协程*/
    IEnumerator Defend()
    {
        ActionPlane.SetActive(false);//先关闭操作UI
        StartCoroutine(Enemy_Attack(true));//新建一条敌人攻击的协程,这里的true代表玩家没有防御
        yield return new WaitForSeconds(0.9f);//等待0.9s再读下面的代码,也就是等待敌人攻击技能表演完,一共0.9s
        PlayerHPinfo.GetComponent<Text>().text = "HP:" + Player_HP + "/" + Player_Max_HP;//更新UI
        ActionPlane.SetActive(true);//再打开操作UI,让玩家进行下一个回合的指令
        yield return null;
    }

    /*玩家攻击技能的表演,用iTween实现*/
    IEnumerator Player_Attack()
    {
        iTween.MoveTo(Player, iTween.Hash("position", new Vector3(0, 0.5f, 2), "easeType", "easeInCubic", "time", 0.3f, "loolType", "none"));
        yield return new WaitForSeconds(0.3f);
        iTween.RotateTo(Player, iTween.Hash("rotation", new Vector3(0, 180, 0), "easeType", "easeInCubic", "time", 0.3f, "loolType", "none"));
        iTween.RotateTo(Enemy, iTween.Hash("rotation", new Vector3(30, 0, 0), "easeType", "easeInCubic", "time", 0.3f, "loolType", "none"));
        yield return new WaitForSeconds(0.3f);
        iTween.MoveTo(Player, iTween.Hash("position", new Vector3(0, 0.5f, -4), "easeType", "easeInCubic", "time", 0.3f, "loolType", "none"));
        iTween.RotateTo(Enemy, iTween.Hash("rotation", new Vector3(0, 0, 0), "easeType", "easeInCubic", "time", 0.3f, "loolType", "none"));
        iTween.RotateTo(Player, iTween.Hash("rotation", new Vector3(0, 0, 0), "easeType", "easeInCubic", "time", 0f, "loolType", "none"));
        yield return new WaitForSeconds(0.3f);

        /*攻击结算*/
        WarinfoText.GetComponent<Text>().text += "玩家攻击,敌人-40HP\n";
        this.Enemy_HP -= 40;

    }

    /*敌人攻击技能的表演,用iTween实现*/
    IEnumerator Enemy_Attack(bool isPlayerDefend)
    {
        iTween.RotateTo(Enemy, iTween.Hash("rotation", new Vector3(0, 180, 0), "easeType", "easeInCubic", "time", 0.3f, "loolType", "none"));
        iTween.RotateTo(Player, iTween.Hash("rotation", new Vector3(-30, 0, 0), "easeType", "easeInCubic", "time", 0.3f, "loolType", "none"));
        yield return new WaitForSeconds(0.3f);
        iTween.RotateTo(Enemy, iTween.Hash("rotation", new Vector3(0, 0, 0), "easeType", "easeInCubic", "time", 0f, "loolType", "none"));
        iTween.RotateTo(Player, iTween.Hash("rotation", new Vector3(0, 0, 0), "easeType", "easeInCubic", "time", 0.3f, "loolType", "none"));
        /*攻击结算*/
        if (!isPlayerDefend)
        {
            WarinfoText.GetComponent<Text>().text += "敌人攻击,玩家-30HP\n";
            this.Player_HP -= 30;
        }
        else
        {
            WarinfoText.GetComponent<Text>().text += "敌人攻击,玩家-15HP\n";
            this.Player_HP -= 15;
        }
        yield return null;
    }

}

也就一百多行代码而已!这里的攻击动画,用到了iTween实现,具体可以看《【iTween】利用协程完成多个动作、iTween的动作序列》(点击打开链接),不赘述了。同时,这里的玩家死亡和敌人死亡其实也可以加入一个立方体碎裂的动画,让游戏更加生动,具体可以参考《【Fracturing & Destruction】点破小球——Unity3D中达到条件才触发的物体爆裂、炸裂、碎裂效果》(点击打开链接),这里为了说明问题,我就不搞这么复杂,拉这么多无关重要的插件进来,降低代码的可读性。

同时赋予Attack_Button、Defend_Button和ExitButton,三个按钮点击事件分别为WarControl.cs的AttackButtonOnclick()、DefendButtonOnclick()和ExitButtonOnclick()则大功告成!


2018-02-27 17:53:22 qq_39710961 阅读数 972
  • Unity3D棋盘游戏实战入门——2D智力拼图

    本课程使用Unity3d开发软件和C#编程语言,从零开始逐步完成一个2D拼图游戏项目。在本课程中,你可以了解并学习到游戏工程的创建和文件结构的维护、Unity3D的射线检测机制、插值插件Itween的使用、游戏数据的离线保存,并初步了解Unity3D的粒子系统和动画系统。

    766 人正在学习 去看看 伍晓波

回合制是一种游戏打怪形式,所有游戏内玩家轮流自己的回合,只有轮到自己的回合,才能够进行操纵。早期战略由于硬件运算能力有限,在考量游戏乐趣与操作简易得情况下,多半采取这种型式。目前常见的回合制手游有《梦幻西游》、《梦幻诛仙》、《修仙物语》等。

发展历程
相关历史
回合制游戏得流行起源于桌面游戏,特别是兵棋。特点包括剧情较少,单人模式很多基于历史战役;其他如名著系列,文明系列,战岛(游戏系列),BattleTech;网络游戏则有《梦幻西游》、《全民大冒险》、《少年三国志》等。

特点
回合制网游介绍:
回合制网游,就是指在游戏中遇到怪物时转到战斗界面,敌人在屏幕的一端,己方在屏幕的另一端,论回合依次行动,直至战斗结束,回到正常的游戏界面的游戏方式.
回合制这一模式来源于桌面游戏,电脑游戏的雏形即来自于此。于是,即使在几十年后,仍然有大量的游戏固执地坚守回合制的阵地,包括战略类游戏“文明”系列、桌面类游戏“大富翁”系列,剧情类——也就是我们所说的RPG类游戏采用回合制的更是不胜枚举。
回合制游戏节奏较慢,玩家可以有大把的时间用来聊天;回合制游戏操作简单,可以加入包括宠物、召唤兽等复杂的系统,玩家可以同时操作数个角色;回合制游戏的PK较为轻松,玩家把战斗当作是一种娱乐,而不是发泄。

回合制游戏的特点:
一、回合制游戏一般都采用2D的形式,不会过分强调战斗,这决定了这类游戏不会给人强烈的直观感受,这也意味着玩家很难通过截图或者第一眼就喜欢上这类游戏。
二、回合制游戏强调社区、交流,这两者都不是直观感受,也是需要通过一段时间体会,才能适应,才能喜爱的。
三、因为强调社区和交流,所有回合制游戏一般都依靠口碑传播和群体效应来吸引更多玩家的,简单的市场炒作和广告投放短时间内拉动效果不明显。
四、回合制因为节奏较慢,升级较慢,诸如家园系统、帮派系统、宠物系统、坐骑系统等等,都需要玩家在较长时间内才能体会到这类游戏的乐趣,口碑效应也较慢。
五.回合制通常带有一定的故事性(相对与韩国泡菜而言是相当有内涵),故事性也是回合制吸引玩家的必杀之一,因此回合制通常比即时制更有故事性.
六.回合制无法提供紧张刺激的战斗,因此为了提高游戏的趣味通常会设计许多好玩的系统来吸引玩家,这就使得回合制的游戏性与即时制相比略胜一筹.(通常情况下)
七.综合5和6,回合制游戏游戏比即时制游戏更有内涵,更适合老玩家游戏.

以上大概就是对以往的回合制游戏的讲解和点评,本人呢也是基于这些来进行代码的编写:
总体逻辑设计为 生成对象并复制,战斗逻辑

未完!

2017-06-09 00:12:07 zys91011_muse 阅读数 1107
  • Unity3D棋盘游戏实战入门——2D智力拼图

    本课程使用Unity3d开发软件和C#编程语言,从零开始逐步完成一个2D拼图游戏项目。在本课程中,你可以了解并学习到游戏工程的创建和文件结构的维护、Unity3D的射线检测机制、插值插件Itween的使用、游戏数据的离线保存,并初步了解Unity3D的粒子系统和动画系统。

    766 人正在学习 去看看 伍晓波

#游戏unity-音之国度#战斗系统中的回合制

转载需标明出处

在上一篇博客中,我们介绍了实现回合制的代码中的新内容——协程,这篇博客我们就真正的来实现一个回合制游戏;首先,一般的回合制游戏都是自己与敌人接连出招,然后当一方血量为0是终止战斗,而我们的音符兽(主角)有不同的类型,相对应的就有不同的种类特点——例如,有的就会在受到攻击后,自动进行反击,而反击的血量在一个较低的数值范围内随机产生,基于这样的思想,我们可以增加一定几率的敌人的反击算法。
主要的运行流程就是在对战开始后,几秒后自动进入己方出战,出来技能框,选择技能,然后主要的一点就是交换攻击权限,由对方攻击;而这个攻击权限就由一个布尔值来控制,如下:
这里写图片描述
我用的是Animation组件
这里写图片描述

好了废话少说上绑在主角身上的脚本Player

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour
{

    public int HP = 100;

    //等待玩家操作  
    public bool isWaitPlayer = true;
    public bool ifUIshow = true;

    //动画组件  
    private Animation mAnim;

    // Use this for initialization  
    void Start()
    {
        mAnim = this.GetComponent<Animation>();
        mAnim.Play("Walk");

    }

    //伤害  
    void OnDamage(int mValue)
    {
        HP -= mValue;
    }


    public void OnGUI()
    {
        //如果处于等待状态,则显示操作窗口  
        if (isWaitPlayer && ifUIshow)
        {
            GUI.Window(0, new Rect(Screen.width / 2 + 150, Screen.height / 2 + 150, 200, 200), InitWindow, "请选择技能");
            //  mAnim.Play("skill");
            mAnim.Play("Walk");
        }
    }


    void InitWindow(int ID)
    {
        if (GUI.Button(new Rect(0, 20, 200, 30), "攻击"))
        {

            mAnim.Play("Run");
            OnDamage(10);
            //交换操作权  
            isWaitPlayer = false;
            ifUIshow = false;
        }
        if (GUI.Button(new Rect(0, 50, 200, 30), "法术"))
        {
            OnDamage(10);
            mAnim.Play("Dying");
            //交换操作权  
            isWaitPlayer = false;
            ifUIshow = false;
        }
    }

    // Update is called once per frame  
    void Update()
    {

    }
}

绑在敌人身上的脚本

using UnityEngine;
using System.Collections;

public class Monster : MonoBehaviour
{

    public int HP = 100;
    public bool isWaitPlayer = true;

    //动画组件  

    private Animation mAnim;

    // Use this for initialization  
    void Start()
    {
        mAnim = this.GetComponent<Animation>();
        mAnim.Play("Walk");
    }


    void OnDamage(int mValue)
    {
        HP -= mValue;
    }

    //敌人AI算法  
    public void StartAI()
    {
        if (!isWaitPlayer)
        {
            if (HP > 20)
            {
                //80%  
                if (Random.Range(1, 5) % 5 != 1)
                {
                    mAnim.Play("Dying");
                    // mAnim.SetBool("enemyAttack", true);
                    //ondamage  
                    isWaitPlayer = true;
                }
                //20%  
                else
                {
                    mAnim.Play("Dying");
                    isWaitPlayer = true;
                }
            }
            else
            {
                switch (Random.Range(1, 5) % 5)
                {
                    case 0:
                        mAnim.Play("Dying");
                        isWaitPlayer = true;
                        break;
                }
            }
        }
    }

    // Update is called once per frame  
    void Update()
    {
        if (isWaitPlayer)
        {
            mAnim.Play("Walk");
        }
    }
}

后台控制的总脚本control——其中就有上一篇所讲到的协程函数的运用



using UnityEngine;
using System.Collections;


public class control : MonoBehaviour
{

    //动画组件  
    private Animation mAnim;

    //定义玩家及敌人  
    public Transform mPlayer;
    public Transform mEnemy;

    //定义玩家及敌人脚本类  
    private Player playerScript;
    private Monster enemyScript;

    //默认操作状态为玩家操作  
    private OperatorState mState = OperatorState.Player;

    //定义操作状态枚举  
    public enum OperatorState
    {
        Quit,
        EnemyAI,
        Player
    }

    // Use this for initialization  
    void Start()
    {

        mAnim = mPlayer.GetComponent<Animation>();

        //获取玩家及敌人脚本类  
        playerScript = mPlayer.GetComponent<Player>();
        enemyScript = mEnemy.GetComponent<Monster>();
        playerScript.OnGUI();
    }

    //UI延迟4.5秒调出  
    IEnumerator WaitUI()
    {
        yield return new WaitForSeconds(1F);
        enemyScript.isWaitPlayer = true;
        playerScript.ifUIshow = true;

    }

    //  
    IEnumerator WaitAI()
    {
        yield return new WaitForSeconds(2.0F);
        enemyScript.isWaitPlayer = false;
    }

    //为怪物AI延迟3秒  
    IEnumerator UpdateLater()
    {
        yield return new WaitForSeconds(3.0F);
        //敌人停止等待  
        enemyScript.isWaitPlayer = false;
        //敌人执行AI  
        enemyScript.StartAI();
    }

    // Update is called once per frame  
    void Update()
    {
        //如果敌我双方有一方生命值为0,则游戏结束  
        if (playerScript.HP == 0)
        {
            mState = OperatorState.Quit;
            Debug.Log("游戏失败");
        }
        else if (enemyScript.HP == 0)
        {
            mState = OperatorState.Quit;
            Debug.Log("游戏胜利");
        }
        else
        {
            switch (mState)
            {
                case OperatorState.Player:
                    {
                        if (!playerScript.isWaitPlayer)
                        {
                            StartCoroutine("UpdateLater");
                            StartCoroutine("WaitUI");
                            mState = OperatorState.EnemyAI;
                        }
                        break;
                    }
                case OperatorState.EnemyAI:
                    {
                        if (enemyScript.isWaitPlayer)
                        {
                            StartCoroutine("WaitAI");
                            playerScript.isWaitPlayer = true;
                            mState = OperatorState.Player;


                            mAnim.Play("Walk");
                        }
                        break;
                    }
            }
        }
    }
}

这里写图片描述
至此,回合制对战的基本代码书写完成。

2019-03-06 16:55:50 weixin_34389926 阅读数 48
  • Unity3D棋盘游戏实战入门——2D智力拼图

    本课程使用Unity3d开发软件和C#编程语言,从零开始逐步完成一个2D拼图游戏项目。在本课程中,你可以了解并学习到游戏工程的创建和文件结构的维护、Unity3D的射线检测机制、插值插件Itween的使用、游戏数据的离线保存,并初步了解Unity3D的粒子系统和动画系统。

    766 人正在学习 去看看 伍晓波

一、场景布置

首先是简单的场景布置,在3D部分很简单。就几个简单的基本组件,在一个Plane上面放2个Cube,并且上不同颜色的纯色Material。唯一需要大家注意的是,请将两个Cube改好名,以免到时候编程不知道哪个跟哪个。

其次是UGUI的布置。左下角是一个名为ActionPanel的Panel,旗下有两个按钮Attack Button和Defend Button,一会儿ActionPanel将被控制,而按钮Attack Button和Defend Button则将赋予点击事件。在这个ActionPanel的下方则是一个名为PlayerHPinfo的Text,同样会被脚本控制,用于显示血量等信息。

至于右上角是个动态文本的滚动区域WarinfoPanel,里面放置的一个WarinfoText用于显示战斗信息的文本,这里需要注意上Mask组件的时候去除Show Mask Graphic,不然WarinfoText显示不出来。而在其下方,则是一个退出战斗的按钮ExitButton,当然这个东西,在实际游戏里面完全可以不要,自动切换回战斗前的场景。

并同时新建一个空物体WarControl,赋予脚本WarControl.cs。

二、脚本编写

由于Update()在每一帧的刷新都被执行的,在1秒就30帧的瞬间,Update()里面的代码不读完,这游戏就被卡死,所以Update()这个可视为主线程的函数,只承担以下简单任务,时刻在判断HP是否见底。

而攻击表演这些要交代给玩家看的东西,至少要占用1s的技能表演,我们则通过协程Coroutine完成。协程,其实也就是Unity3D的子线程,将通过按钮点击时间来创建。各个按钮点击之后,具体的思想如下图表示,其中实线表示玩家点击了“攻击按钮”,虚线则表示玩家点击了“防御按钮”。

这里涉及到挂起0.5s~0.9s的东西,因此,只能写在协程里面完成的,不可能写在Update()里面,不然这游戏绝对卡死。

这里的攻击动画,用到了iTween实现,具体可以参考《【iTween】利用协程完成多个动作、iTween的动作序列》。同时,这里的玩家死亡和敌人死亡其实也可以加入一个立方体碎裂的动画,让游戏更加生动。

同时赋予Attack_Button、Defend_Button和ExitButton,三个按钮点击事件分别为WarControl.cs的AttackButtonOnclick()、DefendButtonOnclick()和ExitButtonOnclick()则大功告成!

更多unity2018的功能介绍请到paws3d学习中心查找。

2014-09-25 17:44:54 caoyouxing 阅读数 4393
  • Unity3D棋盘游戏实战入门——2D智力拼图

    本课程使用Unity3d开发软件和C#编程语言,从零开始逐步完成一个2D拼图游戏项目。在本课程中,你可以了解并学习到游戏工程的创建和文件结构的维护、Unity3D的射线检测机制、插值插件Itween的使用、游戏数据的离线保存,并初步了解Unity3D的粒子系统和动画系统。

    766 人正在学习 去看看 伍晓波

现在手游火的一塌糊涂,引擎也是层出不穷除了引领3D市场的Unity3D,独霸2D市场的Cocos2D-X之外,还有虚幻、Sphinx等,甚至搜狐也开发了国产的Genesis-3D引擎。
其它的不多说,这里主要就对比Unity3D和Cocos2D-X,帮助大家选择。

如果你想开发一个2D游戏,有着C++/C/LUA之一的基础,那么Cocos2D-X也许比较适合你。他本身就为2D游戏设计,有着丰富的源码、实例和教程文档。你可以得到社区的大力支持。

如果你想开发一个3D或2D游戏,有着面向对象编程语言基础(比如Java、C#、AS等)。那么Unity3D会很适合你。虽然他主攻3D,但是assetstore有着丰富的插件,使得你想快速构建一个2D游戏也不是一件难事。

其实把这两个东西放在一起比,即使不严格说也是没有办法说的。Cocos2d-x是个渲染引擎,专注2D游戏(即使内部利用3D的很多技术)。而Unity是个解决方案,不单是渲染引擎,早先专注于3D应用的开发;最近因为它一个2D插件(用来帮助开发者制作2D游戏)在用户需求中还是比较强烈的,战略性的官方开始把这个插件的功能官方化(官方开始制作2D功能的模块),因此可以说由把Cocos2d-x的功能也在融合进来。这个是概念上的澄清。

基于概念回到问题,学习这两个东西,并不是两个技术的方向,而是两个游戏开发类型的方向。因为Unity如果弄得很通,Cocos2d-x就是个子集(仅负责渲染管理)。我只能说,对于刚入门的,如果你不是只想专注于2D游戏,那么,完全可以从Unity入手,理由:

1、完整的解决方案,学好一个,其他的东西上手非常快;
2、海量的学习资料;
3、没有C++的繁琐,完全可以专注于技术点的学习;

学习难度的话,我想C++如果好的话,Cocos2d-x相对小一点,涉及功能少很多,所以,相对简单;但是C++如果不会或者不好,则另当别论,而且相对入门的来说 js和c#更亲民。

那么我个人是怎么选择Unity3D和Cocos2D-X的?
我自然是选择Unity3D:
1、虽然你现在可能是做2D游戏,但如果你以后想做3D呢?用Unity3D的话从2D到3D的转换成本很低。
2、丰富的插件支持。
3、成熟的工具以及强大的编辑器拓展,让你可以很方便的定制适合自己项目需要的编辑器。
4、内置强大的性能分析工具。
5、几乎支持所有主流平台:WEB、Win、Mac、IOS、Android、XBox、PS3、Wii

6、Unity5还有更完善的光照系统、UI架构以及支持发布成Html5。可见该引擎的发展处于高速阶段。


没有更多推荐了,返回首页