• unity3d-游戏实战突出重围,整合游戏


    结构图:

       

    两个场景,一个是开始界面。一个是游戏界面:

    脚本说明:依次是:敌人脚本,主角游戏,主菜单,工具

    Enemy

      1 using UnityEngine;
      2 using System.Collections;
      3 
      4 public class Enemy : MonoBehaviour
      5 {
      6 
      7     /*===============================
      8      * 敌人脚本
      9      *==============================*/
     10 
     11     //敌人状态
     12 
     13     //敌人站立状态
     14     public const int STATE_STAND = 0;
     15     //敌人行走状态
     16     public const int STATE_WALK = 1;
     17     //敌人奔跑状态
     18     public const int STATE_RUN = 2;
     19     //敌人暂停状态
     20     public const int STATE_PAUSE = 3;
     21 
     22     //记录敌人当前状态
     23     private int enemState;
     24     //主角对象
     25     private GameObject hero;
     26 
     27     //备份上一次敌人的思考时间
     28     private float backUptime;
     29     //敌人思考下一次行为时间
     30     private const int AI_ATTACK_TIME = 2;
     31     //敌人的巡逻范围
     32     public const int AI_ATTACK_DISTANCE = 10;
     33 
     34     //是否绘制血条  当鼠标指向敌人则绘制。离开则不绘制
     35     bool showBlood = false;
     36 
     37     //血条资源贴图
     38     public Texture2D tex_red;
     39     public Texture2D tex_black;
     40 
     41     //生命值贴图
     42     public Texture2D tex_hp;
     43 
     44     //生命值
     45     private int HP = 100;
     46 
     47     //敌人仇恨
     48     private bool ishatred = false;
     49 
     50     //图片数字资源
     51     Object[] texmube;
     52 
     53 
     54     // Use this for initialization
     55     void Start()
     56     {
     57         //获取主角对象,这里前端赋值比较好
     58         hero = GameObject.Find("Hero");
     59 
     60         //读取图片资源
     61         texmube = Resources.LoadAll("number");
     62 
     63         //设置敌人默认状态为站立
     64         enemState = STATE_STAND;
     65     }
     66 
     67     // Update is called once per frame
     68     void Update()
     69     {
     70         //判断敌人与主角之间的距离
     71         if (Vector3.Distance(transform.position, hero.transform.position) < AI_ATTACK_DISTANCE || ishatred)
     72         {
     73             //敌人进入奔跑状态
     74             gameObject.animation.Play("run");
     75             enemState = STATE_RUN;
     76 
     77             //设置敌人面朝主角方向
     78             transform.LookAt(hero.transform);
     79 
     80             //随机攻击主角
     81             int rand = Random.Range(0, 20);
     82             if (rand == 0)
     83             {
     84                 //模拟攻击,
     85                 //向主角发送攻击消息,然后在主角对象脚本中实现HeroHrut方法,进行主角减血
     86                 hero.SendMessage("HeroHurt");
     87             }
     88         }
     89         //敌人进入巡逻状态
     90         else
     91         {
     92             //计算敌人的思考时间
     93             if (Time.time - backUptime >= AI_ATTACK_TIME)
     94             {
     95                 //敌人开始思考
     96                 //备份思考的时间
     97                 backUptime = Time.time;
     98 
     99                 //取得0~2之间的随机数
    100                 int rand = Random.Range(0, 2);
    101                 if (rand == 0)
    102                 {
    103                     //敌人进入站立状态
    104                     transform.animation.Play("idle");
    105                     //设置状态
    106                     enemState = STATE_STAND;
    107                 }
    108                 else if (rand == 1)
    109                 {
    110                     //敌人进入行走状态
    111                     //敌人随机旋转角度
    112                     Quaternion rotate = Quaternion.Euler(0, Random.Range(1, 5) * 90, 0);
    113                     //1秒内完成旋转
    114                     transform.rotation = Quaternion.Lerp(transform.rotation, rotate, Time.deltaTime * 1000);
    115                     //播放行走动画
    116                     transform.animation.Play("walk");
    117                     enemState = STATE_WALK;
    118                 }
    119 
    120             }
    121         }
    122         switch (enemState)
    123         {
    124             case STATE_STAND: break;
    125             case STATE_WALK:
    126                 //敌人行走
    127                 transform.Translate(Vector3.forward * Time.deltaTime);
    128                 //gameObject.animation.Play("walk");
    129                 break;
    130             case STATE_RUN:
    131                 //敌人朝向主角奔跑,当相距2时,就不向前跑了
    132                 if (Vector3.Distance(transform.position, hero.transform.position) > 3)
    133                 {
    134                     transform.Translate(Vector3.forward * Time.deltaTime * 3);
    135                 }
    136                 break;
    137         }
    138     }
    139     void OnGUI()
    140     {
    141         if (showBlood)//如果绘制血条
    142         {
    143             //绘制生命值贴图
    144             GUI.DrawTexture(new Rect(5, 0, tex_hp.width, tex_hp.height), tex_hp);
    145             //绘制主角生命值
    146             Tools.DrawImageNumber(200, 0, HP, texmube);
    147 
    148             //绘制敌人血条
    149             int blood_width = tex_red.width * HP / 100;
    150             //绘制黑色血条 即底色
    151             GUI.DrawTexture(new Rect(5, 50, tex_black.width, tex_black.height), tex_black);
    152             //绘制红色血条
    153             GUI.DrawTexture(new Rect(5, 50, blood_width, tex_red.height), tex_red);
    154         }
    155     }
    156 
    157     /// <summary>
    158     /// 当在敌人上单击鼠标左键
    159     /// </summary>
    160     void OnMouseDown()
    161     {
    162         //击中敌人目标
    163         if (HP > 0)
    164         {
    165             //减掉5点血
    166             HP -= 5;
    167             //被击打时,后退
    168             transform.Translate(Vector3.back * 1);
    169             //击中敌人后立即进入战斗状态
    170             ishatred = true;
    171         }
    172         else//敌人死亡
    173         {
    174             //敌人死亡
    175             Destroy(gameObject);
    176             //发送死亡消息
    177             hero.SendMessage("EnemyHurt");
    178         }
    179     }
    180     void OnMouseUp()
    181     {
    182         //击打后退还原
    183         transform.Translate(Vector3.forward * Time.deltaTime * 1);
    184     }
    185     void OnMouseOver()
    186     {
    187         //开始绘制血条
    188         showBlood = true;
    189     }
    190     void OnMouseExit()
    191     {
    192         //结束绘制血条
    193         showBlood = false;
    194     }
    195 }

    Game

      1 using UnityEngine;
      2 using System.Collections;
      3 
      4 public class Game : MonoBehaviour
      5 {
      6     /*===============================
      7      * 主角脚本
      8      *==============================*/
      9 
     10     //游戏状态机
     11 
     12     //游戏中状态
     13     public const int STATE_GAME = 0;
     14     //游戏胜利状态
     15     public const int STATE_WIN = 1;
     16     //游戏失败状态
     17     public const int STATE_LOSE = 2;
     18 
     19     //枚举角色鼠标位置
     20     public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
     21     public RotationAxes axes = RotationAxes.MouseXAndY;
     22     float rotationY = 0f;
     23 
     24     //鼠标准心
     25     public Texture2D tex_fire;
     26 
     27     //血条资源贴图
     28     public Texture2D tex_red;
     29     public Texture2D tex_black;
     30 
     31     //生命值贴图
     32     public Texture2D tex_hp;
     33 
     34     //战斗胜利资源贴图
     35     public Texture2D tex_win;
     36     //战斗失败资源贴图
     37     public Texture2D tex_lose;
     38     //游戏音乐资源
     39     public AudioSource music;
     40 
     41     //主角生命值
     42     public int HP = 100;
     43 
     44     //图片数字资源
     45     Object[] texmuber;
     46 
     47     //当前游戏状态
     48     int gameState;
     49 
     50 
     51 
     52     // Use this for initialization
     53     void Start()
     54     {
     55         //取消默认鼠标图标
     56         Screen.showCursor = false;
     57         //读取图片资源
     58         texmuber = Resources.LoadAll("number");
     59         //设置默认状态为游戏中
     60         gameState = STATE_GAME;
     61 
     62         if (rigidbody) //如果是刚体
     63             /*
     64              如果freezeRotation被启用,旋转不会被物体模拟修改。
     65              * 这对于创建第一人称射击游戏时是很有用的,因为玩家需要使用鼠标完全控制旋转。
     66              */
     67             rigidbody.freezeRotation = true;////冻结旋转
     68     }
     69 
     70     // Update is called once per frame
     71     void Update()
     72     {
     73         switch (gameState)
     74         {
     75             case STATE_GAME: UpdateGame(); break;
     76             case STATE_WIN:
     77             case STATE_LOSE:
     78                 if (Input.GetKey(KeyCode.Escape))
     79                 {
     80                     Application.LoadLevel("Menu");
     81                 }
     82                 break;
     83             default:
     84                 break;
     85         }
     86     }
     87 
     88 
     89     void OnGUI()
     90     {
     91         switch (gameState)
     92         {
     93             case STATE_GAME:
     94                 RenderGame();
     95                 break;
     96             case STATE_WIN:
     97                 GUI.DrawTexture(new Rect(0, 0, tex_win.width, tex_win.height), tex_win);
     98                 break;
     99             case STATE_LOSE:
    100                 GUI.DrawTexture(new Rect(0, 0, tex_lose.width, tex_lose.height), tex_lose);
    101                 break;
    102             default:
    103                 break;
    104         }
    105     }
    106 
    107     private void RenderGame()
    108     {
    109         if (tex_fire)
    110         {
    111             //绘制鼠标准心
    112             float x = Input.mousePosition.x - tex_fire.width / 2;
    113             float y = Screen.height - Input.mousePosition.y - tex_fire.width / 2;
    114 
    115             GUI.DrawTexture(new Rect(x, y, tex_fire.width, tex_fire.height), tex_fire);
    116         }
    117 
    118         //绘制主角血条
    119         int blood_width = tex_red.width * HP / 100;
    120         GUI.DrawTexture(new Rect(5, Screen.height - 50, tex_black.width, tex_black.height), tex_black);
    121         GUI.DrawTexture(new Rect(5, Screen.height - 50, blood_width, tex_red.height), tex_red);
    122 
    123         //绘制生命值贴图
    124         GUI.DrawTexture(new Rect(5, Screen.height - 80, tex_hp.width, tex_hp.height), tex_hp);
    125 
    126         //绘制主角生命值
    127         Tools.DrawImageNumber(200, Screen.height - 80, HP, texmuber);
    128     }
    129 
    130     /// <summary>
    131     /// 主角被攻击
    132     /// </summary>
    133     void HeroHurt()
    134     {
    135         HP--;
    136         if (HP <= 0)
    137         {
    138             HP = 0;
    139             gameState = STATE_LOSE; //游戏失败
    140         }
    141     }
    142 
    143     /// <summary>
    144     /// 碰到道具血条加血
    145     /// </summary>
    146     void HeroAddBlood()
    147     {
    148         HP += 50;
    149         if (HP >= 100)
    150         {
    151             HP = 100;
    152         }
    153     }
    154     /// <summary>
    155     /// 敌人被攻击
    156     /// </summary>
    157     void EnemyHurt()
    158     {
    159         //找到所有的NPC
    160         GameObject[] enemy = GameObject.FindGameObjectsWithTag("enemy");
    161         //Debug.Log(enemy.Length);
    162 
    163         //敌人对象数字长度为1表示敌人全部死亡
    164         if (enemy.Length == 1)
    165         {
    166 
    167             gameState = STATE_WIN;
    168         }
    169     }
    170     private void UpdateGame()
    171     {
    172         if (Input.GetKey(KeyCode.Escape))
    173         {
    174             Application.LoadLevel("Menu");
    175         }
    176         //计算摄像机旋转
    177         if (axes == RotationAxes.MouseX)
    178         {
    179             //旋转角色 
    180             transform.Rotate(0, Input.GetAxis("Mouse X"), 0);
    181         }
    182         else
    183         {
    184             //设置角色欧拉角
    185             transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0);
    186         }
    187     }
    188 
    189     /// <summary>
    190     /// 在移动的时,当controller碰撞到collider时OnControllerColliderHit被调用。
    191     /// </summary>
    192     /// <param name="hit"></param>
    193     void OnControllerColliderHit(ControllerColliderHit hit)
    194     {
    195         //获取角色控制器碰撞到的游戏对象
    196         GameObject collObj = hit.gameObject;
    197 
    198         //是否为加血的箱子对象
    199         if (collObj.name == "Cube")
    200         {
    201             //主角加血
    202             HeroAddBlood();
    203             //销毁箱子
    204             Destroy(collObj);
    205         }
    206     }
    207 
    208 }

    Menu

      1 using UnityEngine;
      2 using System.Collections;
      3 
      4 public class Menu : MonoBehaviour {
      5 
      6     /*===============================
      7      * 主菜单脚本
      8      *==============================*/
      9 
     10 
     11     //游戏界面状态机
     12 
     13     //主菜单界面
     14     public const int STATE_MAINMENU = 0;
     15     //游戏设置界面
     16     public const int STATE_OPTION = 1;
     17     //游戏帮助界面
     18     public const int STATE_HELP = 2;
     19     //游戏退出界面
     20     public const int STATE_EXIT = 3;
     21     //GUI皮肤
     22     public GUISkin mySkin;
     23 
     24     //游戏背景贴图
     25     public Texture textureBG;
     26     //开始菜单贴图
     27     public Texture tex_startInfo;
     28     //帮助菜单贴图
     29     public Texture tex_helpInfo;
     30 
     31     //游戏音乐资源
     32     public AudioSource music;
     33     //当前游戏状态
     34     private int gameState;
     35 
     36     // Use this for initialization
     37     void Start()
     38     {
     39         //初始化游戏状态为主菜单界面
     40         gameState = STATE_MAINMENU;
     41     }
     42 
     43     // Update is called once per frame
     44     void Update()
     45     {
     46 
     47     }
     48     void OnGUI()
     49     {
     50         switch (gameState)
     51         {
     52             case STATE_MAINMENU:
     53                 //绘制主菜单界面
     54                 RenderMainMenu();
     55                 break;
     56             case STATE_OPTION:
     57                 //绘制游戏设置界面
     58                 RenderOption();
     59                 break;
     60             case STATE_HELP:
     61                 //绘制游戏帮助界面
     62                 RenderHelp();
     63                 break;
     64             case STATE_EXIT:
     65                 //绘制游戏退出界面
     66                 //目前直接关闭并退出游戏
     67                 break;
     68             default:
     69                 break;
     70         }
     71     }
     72     /// <summary>
     73     /// 绘制游戏帮助界面
     74     /// </summary>
     75     private void RenderHelp()
     76     {
     77         GUI.skin = mySkin;
     78         GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), tex_helpInfo);
     79         //返回按钮
     80         if (GUI.Button(new Rect(0, 500, 403, 78), "", "back"))
     81         {
     82             gameState = STATE_MAINMENU;
     83         }
     84     }
     85     /// <summary>
     86     /// 绘制游戏设置界面
     87     /// </summary>
     88     private void RenderOption()
     89     {
     90         GUI.skin = mySkin;
     91         GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), textureBG);
     92 
     93         //开启音乐按钮
     94         if (GUI.Button(new Rect(0, 0, 403, 75), "", "music_on"))
     95         {
     96             if (!music.isPlaying)
     97             {
     98                 //播放音乐
     99                 music.Play();
    100             }
    101         }
    102         //关闭音乐按钮
    103         if (GUI.Button(new Rect(0, 200, 403, 75), "", "music_off"))
    104         {
    105             //关闭音乐
    106             music.Stop();
    107         }
    108         //返回按钮
    109         if (GUI.Button(new Rect(0, 500, 403, 78), "", "back"))
    110         {
    111             gameState = STATE_MAINMENU;
    112         }
    113     }
    114     /// <summary>
    115     /// 绘制主菜单界面
    116     /// </summary>
    117     private void RenderMainMenu()
    118     {
    119         //设置界面皮肤
    120         GUI.skin = mySkin;
    121         //绘制游戏背景图
    122         GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), textureBG);
    123 
    124         //开始游戏按钮
    125         if (GUI.Button(new Rect(0, 30, 623, 153), "", "start"))
    126         {
    127             //进入开始游戏状态
    128             Application.LoadLevel("Game");
    129         }
    130         //游戏选项按钮
    131         if (GUI.Button(new Rect(0, 180, 623, 153), "", "option"))
    132         {
    133             //处于开始游戏状态
    134             gameState = STATE_OPTION;
    135         }
    136         //游戏帮助按钮
    137         if (GUI.Button(new Rect(0, 320, 623, 153), "", "help"))
    138         {
    139             //进入游戏帮助状态
    140             gameState = STATE_HELP;
    141         }
    142         //游戏退出按钮
    143         if (GUI.Button(new Rect(0, 470, 623, 153), "", "exit"))
    144         {
    145             //退出游戏
    146             Application.Quit();
    147         }
    148     }
    149 }

    Tools

     

     1 using UnityEngine;
     2 using System.Collections;
     3 
     4 public class Tools : MonoBehaviour
     5 {
     6 
     7     /*===============================
     8      * 工具脚本
     9      *==============================*/
    10 
    11 
    12     /// <summary>
    13     /// 
    14     /// </summary>
    15     /// <param name="x">绘制数字 x坐标</param>
    16     /// <param name="y">绘制数字 y坐标</param>
    17     /// <param name="number">需要绘制的数字</param>
    18     /// <param name="texnumber">绘制图片数组资源</param>
    19     public static void DrawImageNumber(int x, int y, int number, Object[] texnumber)
    20     {
    21         //将整数数据转换为字符数组
    22         char[] chars = number.ToString().ToCharArray();
    23         //计算图片的宽度与高度,因为每张图片都是一样大。所以这里获取第一张即可
    24         Texture2D tex = (Texture2D)texnumber[0];
    25         int width = tex.width;
    26         int height = tex.height;
    27 
    28         //遍历字符数组
    29         foreach (char item in chars)
    30         {
    31             //得到每一位整型数组
    32             int i = int.Parse(item.ToString());
    33             //绘制图片数字
    34             GUI.DrawTexture(new Rect(x, y, width, height), texnumber[i] as Texture2D);
    35             x += width;
    36         }
    37     }
    38 
    39 }

    注意事项:NPC需要添加标签:enemy

    游戏源码:

     http://pan.baidu.com/s/1ntmOQnf

  • 相关阅读:
    什么是三元表达式,遇到三元表达式,你该如何去看代码执行的结果,下面的方法简单实用!!!
    遍历某一个标签中的内容;python+selenium定位到列表整体,使用for循环获取列表文本;可用于校验列表是否存在你需要的文本内容
    Selenium3+python3--如何定位鼠标悬停才显示的元素
    selenium中get_attribute的简单使用
    css层叠样式
    前端初识
    视图,触发器,事务,存储过程,内置函数,索引
    pymysql基本操作
    多态与绑定方法
    封装与组合
  • 原文地址:https://www.cnblogs.com/niboy/p/4266451.html
Copyright © 2020-2023  润新知