当前位置:   article > 正文

3D游戏——巡逻兵

3D游戏——巡逻兵

工厂模式

工厂模式(Factory Design Pattern)也是游戏开发中比较常用的创建型模式,一般情况下,工厂模式分为三种更加细分的类型:简单工厂、工厂方法和抽象工厂

工厂模式的意义:

将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。

设计模式的依赖抽象原则

  • 创建对象实例时,不要直接new类,而是把这个new类的动作放在一个工厂的方法中,并返回。(变量不要直接持有具体类的引用)
  • 不要让类继承具体类,而是继承抽象类或者实现interface(接口)
  • 不要覆盖基类中已经实现的方法

(学习了大佬的讲解:工厂模式)

游戏规则

使用WSAD或方向键上下左右移动player,进入巡逻兵的追捕后逃脱可积累一分,若与巡逻兵碰撞则游戏结束,收集完地图上的所有水晶即可获胜。

游戏设计

  • 创建一个地图和若干巡逻兵(使用动画);
  • 每个巡逻兵走一个3~5个边的凸多边型,位置数据是相对地址。即每次确定下一个目标位置,用自己当前位置为原点计算;
  • 巡逻兵碰撞到障碍物,则会自动选下一个点为目标;
  • 巡逻兵在设定范围内感知到玩家,会自动追击玩家;
  • 失去玩家目标后,继续巡逻;
  • 计分:玩家每次甩掉一个巡逻兵计一分,与巡逻兵碰撞游戏结束;

程序设计

使用订阅与发布模式传消息
工厂模式生产巡逻兵

游戏UML图

3

实现部分

项目模型

在网站Unity3D_模型_资源_商店(unity asset store)_免费下载 - 爱给网 (aigei.com)下载

1

 AnimatorController

 实现代码

工厂模式:PatrolFactory.cs

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class PatorlFactory : MonoBehaviour {
  5. //工厂模式就负责生产,其他的不负责,所以可以看到这个类只和角色有关系和其他所有代码都没有关系
  6. private GameObject player = null; //玩家
  7. private GameObject patrol = null; //巡逻兵
  8. private List<GameObject> patrolList = new List<GameObject>(); //正在被使用的巡逻兵
  9. private Vector3[] vec = new Vector3[9]; //保存每个巡逻兵的初始位置
  10. public GameObject LoadPlayer()
  11. {
  12. player = Instantiate(Resources.Load("Prefabs/Player"), new Vector3(0, 9, 0), Quaternion.identity) as GameObject;
  13. return player;
  14. }
  15. public List<GameObject> LoadPatrol()
  16. {
  17. int[] pos_x = { -6, 4, 13 };
  18. int[] pos_z = { -4, 6, -13 };
  19. int index = 0;
  20. for(int i=0;i < 3;i++)
  21. {
  22. for(int j=0;j < 3;j++)
  23. {
  24. vec[index] = new Vector3(pos_x[i], 0, pos_z[j]);
  25. index++;
  26. }
  27. }
  28. for(int i=0; i < 9; i++)
  29. {
  30. patrol = Instantiate(Resources.Load<GameObject>("Prefabs/Patrol1"));
  31. patrol.transform.position = vec[i];
  32. patrol.GetComponent<PatrolData>().sign = i + 1;
  33. patrol.GetComponent<PatrolData>().start_position = vec[i];
  34. patrolList.Add(patrol);
  35. }
  36. return patrolList;
  37. }
  38. //游戏结束时,暂停所有动作
  39. public void StopPatrol()
  40. {
  41. for (int i = 0; i < patrolList.Count; i++)
  42. {
  43. patrolList[i].gameObject.GetComponent<Animator>().SetBool("run", false);
  44. }
  45. }
  46. }

 巡逻动作:PatrolAction.cs

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class GoPatrolAction : SSAction
  5. {
  6. private enum Dirction { E, N, W, S };
  7. private float pos_x, pos_z;
  8. private float move_length;
  9. private float move_speed = 1.2f;
  10. private bool move_sign = true;
  11. private Dirction dirction = Dirction.E;
  12. private PatrolData data;
  13. private GoPatrolAction() { }
  14. public static GoPatrolAction GetSSAction(Vector3 location)
  15. {
  16. GoPatrolAction action = CreateInstance<GoPatrolAction>();
  17. action.pos_x = location.x;
  18. action.pos_z = location.z;
  19. action.move_length = Random.Range(5, 8);
  20. return action;
  21. }
  22. public override void Update()
  23. {
  24. if (transform.localEulerAngles.x != 0 || transform.localEulerAngles.z != 0)transform.localEulerAngles = new Vector3(0, transform.localEulerAngles.y, 0);
  25. if (transform.position.y != 0)transform.position = new Vector3(transform.position.x, 0, transform.position.z);
  26. Gopatrol();
  27. if (data.follow_player && data.wall_sign == data.sign)
  28. {
  29. this.destroy = true;
  30. this.callback.SSActionEvent(this,0,this.gameobject);
  31. }
  32. }
  33. public override void Start(){data = this.gameobject.GetComponent<PatrolData>();}
  34. void Gopatrol()
  35. {
  36. if (move_sign)
  37. {
  38. switch (dirction)
  39. {
  40. case Dirction.E:
  41. pos_x -= move_length;
  42. break;
  43. case Dirction.N:
  44. pos_z += move_length;
  45. break;
  46. case Dirction.W:
  47. pos_x += move_length;
  48. break;
  49. case Dirction.S:
  50. pos_z -= move_length;
  51. break;
  52. }
  53. move_sign = false;
  54. }
  55. this.transform.LookAt(new Vector3(pos_x, 0, pos_z));
  56. float distance = Vector3.Distance(transform.position, new Vector3(pos_x, 0, pos_z));
  57. if (distance > 0.9){transform.position = Vector3.MoveTowards(this.transform.position, new Vector3(pos_x, 0, pos_z), move_speed * Time.deltaTime);
  58. }else
  59. {
  60. dirction = dirction + 1;
  61. if(dirction > Dirction.S)dirction = Dirction.E;
  62. move_sign = true;
  63. }
  64. }
  65. }

追踪动作:PatrolFollowAction.cs

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class PatrolFollowAction : SSAction
  5. {
  6. private float speed = 2f;
  7. private GameObject player;
  8. private PatrolData data;
  9. private PatrolFollowAction() { }
  10. public static PatrolFollowAction GetSSAction(GameObject player)
  11. {
  12. PatrolFollowAction action = CreateInstance<PatrolFollowAction>();
  13. action.player = player;
  14. return action;
  15. }
  16. public override void Update()
  17. {
  18. if (transform.localEulerAngles.x != 0 || transform.localEulerAngles.z != 0)transform.localEulerAngles = new Vector3(0, transform.localEulerAngles.y, 0);
  19. if (transform.position.y != 0)transform.position = new Vector3(transform.position.x, 0, transform.position.z);
  20. Follow();
  21. if (!data.follow_player || data.wall_sign != data.sign)
  22. {
  23. this.destroy = true;
  24. this.callback.SSActionEvent(this,1,this.gameobject);
  25. }
  26. }
  27. public override void Start(){data = this.gameobject.GetComponent<PatrolData>();}
  28. void Follow()
  29. {
  30. transform.position = Vector3.MoveTowards(this.transform.position, player.transform.position, speed * Time.deltaTime);
  31. this.transform.LookAt(player.transform.position);
  32. }
  33. }

动作管理:PatrolActionManager.cs

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class PatrolActionManager : SSActionManager, ISSActionCallback
  5. {
  6. private GoPatrolAction go_patrol;
  7. public void GoPatrol(GameObject patrol)
  8. {
  9. go_patrol = GoPatrolAction.GetSSAction(patrol.transform.position);
  10. this.RunAction(patrol, go_patrol, this);
  11. }
  12. public void DestroyAllAction(){DestroyAll();}
  13. public void SSActionEvent(SSAction source, int intParam = 0, GameObject objectParam = null)
  14. {
  15. if (intParam == 0)
  16. {
  17. PatrolFollowAction follow = PatrolFollowAction.GetSSAction(objectParam.gameObject.GetComponent<PatrolData>().player);
  18. this.RunAction(objectParam, follow, this);
  19. }
  20. else
  21. {
  22. GoPatrolAction move = GoPatrolAction.GetSSAction(objectParam.gameObject.GetComponent<PatrolData>().start_position);
  23. this.RunAction(objectParam, move, this);
  24. Singleton<GameEventManager>.Instance.PlayerEscape();
  25. }
  26. }
  27. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号