• PacMan 02——玩家移动


    版权申明:

    • 本文原创首发于以下网站:
    1. 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123
    2. 优梦创客的官方博客:https://91make.top
    3. 优梦创客的游戏讲堂:https://91make.ke.qq.com
    4. 『优梦创客』的微信公众号:umaketop
    • 您可以自由转载,但必须加入完整的版权声明

    player的行走

    行走原理:

    1.每次移动一个单位,判断是否有障碍物,障碍物不可以穿越
    2.在按下按键时候触发一个方法,该方法生成一个射线,如果发现墙壁,则就返回true
    3.只有四个移动方向
    4.每次移动距离都要与豆子间隔相等

    代码如下

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class PlayerController : MonoBehaviour {
         float Speed=5f;//移动速度
        Vector2 playerto;//移动方向
        void Start()
        {
            playerto = gameObject.transform.position;//初始位置
        }
        void FixedUpdate()
        {
            //移动方法
            Vector2 a = Vector2.MoveTowards(this.gameObject.transform.position, playerto, Speed * Time.fixedDeltaTime);//移动方法
            this.gameObject.GetComponent<Rigidbody2D>().MovePosition(a);//利用rigidoby2D移动
            if ((Vector2)gameObject.transform.position == playerto)
            {
                Vector2 s=Vector2.zero;
                if (Input.GetKey(KeyCode.A)&&!CanGo(Vector2.left))
                {
                    s = Vector2.left;
                }
                 else if (Input.GetKey(KeyCode.S)&&!CanGo(Vector2.down))
                {
                    s = Vector2.down;
                }
                 else if (Input.GetKey(KeyCode.D)&&!CanGo(Vector2.right))
                {
                    s = Vector2.right;
                }
                 else if (Input.GetKey(KeyCode.W)&&!CanGo(Vector2.up))
                {
                    s = Vector2.up;
                }
                playerto += s;//改变移动坐标
                gameObject.GetComponent<Animator>().SetFloat("DirX",s.x);//播放相应的动画
                gameObject.GetComponent<Animator>().SetFloat("DirY",s.y);
            }
        }
        void Update()
        {
        }
        bool CanGo(Vector2 ss)//检测方法
        {
            //Debug.Log("检测到障碍物");
           RaycastHit2D raycastHit2=Physics2D.Linecast(this.transform.position,(Vector2)this.transform.position+ss,1<<LayerMask.NameToLayer("map"));
            if (raycastHit2==true)
            {
                Debug.Log("检测到障碍物");
            }
            return raycastHit2;//返回射线信息
        }
    }
    
    

    状态机

    FSM

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class StaticMachine<T> : MonoBehaviour {
        // 状态机控制器;
        public SureStatic<T> SureStatic = null;//当前的状态;
        public T owner;//状态机拥有者;
        public void Init(T owner,SureStatic<T> initalState)
        {
            this.owner = owner;
            SureStatic = initalState;
            ChangeState(SureStatic);//状态机变化方法
        }
    	public void ChangeState(SureStatic<T> NewState)
        {
            if (NewState!=null)
            {
                SureStatic.Exit(owner);
            }
            SureStatic = NewState;
            SureStatic.Enter(owner);
        }
        public void Update()
        {
            SureStatic.Update(owner);
        }
    }
    
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SureStatic<T> : MonoBehaviour
    {
        //被用于继承
        public virtual void Exit(T a)//状态退出
        {
    
        }
    	public virtual void Enter(T b)//状态进入
        {
    
        }
        public virtual void Update(T c)//状态更新
        {
    
        }
    }
    
    

    怪物的状态转换(只有出发和巡逻)

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Moster : MonoBehaviour {
        StaticMachine<Moster> machine = new StaticMachine<Moster>();
        public List<Vector2> LiveHomePath;
        public float speed = 4f;
        class WayPointSetect:SureStatic<Moster>//一种状态,出发状态
        {
            private List<Vector2> path;
            private int index;//当前走的路径点个数
             public  WayPointSetect(List<Vector2> path)
            {
                this.path = path;
                this.index = 0;
            }
            public override void Update(Moster c)
            {
                Vector2 a = Vector2.MoveTowards(c.transform.position,path[index],c.speed*Time.fixedDeltaTime);
                c.GetComponent<Rigidbody2D>().MovePosition(a);
                if ((Vector2)c.transform.position==a)
                {
                    index++;
                    if (index>=path.Count)//.count属性判断元素真实个数
                    {
                        c.machine.Init(c,new XunluoPoint());//走完路点后,开始巡逻状态
                        Debug.Log("出发路点完成");
                    }else 
                    {
                        Vector2 b = path[index] - path[index - 1];
                        c.GetComponent<Animator>().SetFloat("MirX",b.x);
                        c.GetComponent<Animator>().SetFloat("MirY",b.y);
                    }
                }
            }
        }
        class XunluoPoint:SureStatic<Moster>//巡逻状态
        {
            private Vector2 dir;//目标点
            private Vector2 Edir;//当前方向向量
            private Vector2[] EdirTo = new Vector2[] { Vector2.left, Vector2.up,Vector2.right,Vector2.down };
            public override void Enter(Moster b)
            {
                dir = b.transform.position;
                Edir = b.transform.position;
            }
            public override void Update(Moster c)
            {
                //Edir = c.transform.position;
                Vector2 b = Vector2.MoveTowards(c.transform.position,dir,c.speed*Time.fixedDeltaTime);
                c.gameObject.GetComponent<Rigidbody2D>().MovePosition(b);
                if ((Vector2)c.transform.position==dir)
                {
                    List<Vector2> Averation = new List<Vector2>();
                    for (int i=0;i<EdirTo.Length;i++)
                    {
    
                        if (EdirTo[i]==-Edir)
                        {
                            Debug.Log("相反,跳出路径;");
                            continue;
                        }
                        if (c.CanGo(EdirTo[i]) == false)
                        {
                            Averation.Add(EdirTo[i]);
                        }    
                        
                    }
                    int a = Random.Range(0,Averation.Count);
                    Edir = Averation[a];
                    dir += Averation[a];
                    //Vector2 s = dir - Edir;
                    c.GetComponent<Animator>().SetFloat("MirX", Edir.x);
                    c.GetComponent<Animator>().SetFloat("MirY", Edir.y);
                }
            }
        }
        private bool CanGo(Vector2 dir)
        {
            RaycastHit2D a = Physics2D.Linecast(this.transform.position,(Vector2)this.transform.position+dir,1<<LayerMask.NameToLayer("map"));
            return a;
        }
    	void Start ()
        {
            machine.Init(this, new WayPointSetect(LiveHomePath));//初始化
    	}
         void FixedUpdate()
         {
            machine.Update();//每帧调用
         }
    }
  • 相关阅读:
    linux系统数据落盘之细节
    不同类型文件“可读写”的含义
    zz存储系统中缓存的三种类型
    library满(磁带紊乱、虚拟机恢复失败)
    TSM日常维护
    入门级磁带机使用方法
    关于 tsm 磁带槽位
    TSM lan-free原理及配置
    TSM中备份(Backup)和归档(Archive)的区别
    指定stg备份 (即指定tape 磁带)
  • 原文地址:https://www.cnblogs.com/raymondking123/p/11582427.html
Copyright © 2020-2023  润新知