untiy 一个逗比并且有无聊的游戏制作

   先分享一波图,咋们还是看一波图吧。

 看完图了之后大家有什么感想,是不是觉得很简单啊,这么简单的游戏还做(感觉逗比刘真的是个逗比了啊,哎 我已经看不下去了)。这个美术很简单,总共就没有几张图。图中的,大家可以先想想一下 如果得到图中的一个圆圈。我们可以从美术哪儿得到啊(这逗比刘 问的啥问题,简直就是个大sb,其实逗比刘也可以画出来啊),大家如果观察仔细的话可以发现大圈和小圈他的那个环的宽度都是一样的,如果用美术得到这样一张图,当我们放大的时候,我们发现这个圈会变大的(但是逗比刘认为这个可以通过shader轻松的解决这个不和谐的问题)。这里我们还是用网格来绘制这样的一个圆环。那么还是从最简单的绘制一个圆环开始吧。第二张图就可以清晰的看到网格,我的思路是这样的。例如我们把一个圆平均分成200份,当然这只是假设,一个小的圆圈怎么可能分成200份呢,所以我们把一个圆的周长按0.2平分即可,首先我们建一个类:

CircleBuilder,

public class CircleBuilder
{
}
当我们不需要继承由monobehavior所得到功能的时候,那么我们就没必要继承monobehavior了,先定义初始化方法:

    private Material _shareMaterial;
    private PlayerHandler _playerHandler;
    private GameObject _obstacle;
    private GameObject _circle;

    public void Intilized(Material mat,PlayerHandler player,GameObject obstacle,GameObject circle)
    {
        _shareMaterial = mat;
        _playerHandler = player;
        _obstacle = obstacle;

        _circle = circle;
    }
接下来就开始写主要生成方法: 

  public GameObject CreateCirlceMesh(float circle,bool isaddColider,ref CircleData circleData)
  {
        GameObject ob = new GameObject("Child");
        retun ob;
  }
然后我们定义内环和外环顶点数组,然后对其定义

   GameObject ob = new GameObject("Child");

    List<Vector3> inList = new List<Vector3>(150);
    List<Vector3> outList = new List<Vector3>(150);

    Vector3 p1, p2, p3, p4;
    int nodeCount = (int)((circle * 2 * Mathf.PI) / 0.2f);</span>
nodecount表示圆环的节点个数,接着我们开始对2内环数组和外环数组对其赋值。
        int nodeCount = (int)((circle * 2 * Mathf.PI) / 0.2f);
        for (int i = 0; i < nodeCount; i++)
        {
            p1=(GetPosByIndex(circle, nodeCount, i));
            p2=(GetPosByIndex(circle, nodeCount, (i + 1) % nodeCount));
            p3=(GetPosByIndex(circle - 0.1f, nodeCount, (i + 1) % nodeCount));
            p4=(GetPosByIndex(circle - 0.1f, nodeCount, i));
            if (!outList.Contains(p1))
                outList.Add(p1);
            if (!outList.Contains(p2))
                outList.Add(p2);
            if (!inList.Contains(p4))
                inList.Add(p4);
            if (!inList.Contains(p3))
                inList.Add(p3);
        }
内环和外环半径相差0.1,然后根据圆的公式求得圆上各个点。p1,p2外环上相邻的2个点,p3,p4内环上相邻的2个点。最后我们将一个整圆将它分成2个半圆(其实整个圆进行绘制也是可以的)
       if (!inList.Contains(p3))
                inList.Add(p3);
        }
      <span>  int q = inList.Count;
        int p = q / 2;
        List<Vector3> lefList=new List<Vector3>(80);
        List<Vector3> rightList = new List<Vector3>(80);
        for (int i = 0; i <= p; i++)
            lefList.Add(inList[i]);
        for (int i = p; i >=0 ; i--)
            lefList.Add(outList[i]);

        for (int i = p; i < q; i++)
            rightList.Add(inList[i]);
        rightList.Add(inList[0]);
        rightList.Add(outList[0]);
        for (int i = q - 1; i >= p; i--)
            rightList.Add(outList[i]);

        CreateChildGameObject(ob.transform,lefList,isaddColider);
        CreateChildGameObject(ob.transform, rightList, isaddColider);            

        circleData.Intilized(q, ob.transform, _playerHandler.gameObject, circle);</span>

这只是我们做一个环的第一步,我们只有顶点,没有绘制顺序怎么可能绘制出一个圆呢。那么接下来添加CreateChildGameObject方法

   <span> private void CreateChildGameObject(Transform parent, List<Vector3> pointlist, bool isAdd)
    {

        GameObject tem = new GameObject("sb");
        tem.tag = "Obstacle";

        tem.AddComponent<MeshFilter>().mesh = ViewTool.GetObjMesh(pointlist);
        var meshRenderer = tem.AddComponent<MeshRenderer>();
        meshRenderer.sharedMaterial = _shareMaterial;
        tem.transform.SetParent(parent);

        if (isAdd)
        {
            var colider = tem.AddComponent<PolygonCollider2D>();
            colider.points = V3ToV2(pointlist).ToArray();
        }

    } </span>
    private Vector3 GetPosByIndex(float circle, int nodecount, int index)
    {
        float angle = (360f / nodecount * index - 90) * Mathf.Deg2Rad;
        float x = Mathf.Cos(angle) * circle;
        float y = Mathf.Sin(angle) * circle;
        return new Vector3(x, y, 0);
    }
    private List<Vector2> V3ToV2(List<Vector3> points)
    {
        List<Vector2> point = new List<Vector2>();
        for (int i = 0; i < points.Count; i++)
        {
            point.Add(new Vector2(points[i].x, points[i].y));
        }
        return point;
    }
我们还需要添加一个通过点得到网格的方法:GetObjMesh(List<Vector3> pointsList)所以需要贴出这一部分的代码。

public static class ViewTool
{
    public static void ChangeMatColor(Material meshMaterial)
    {
        float r = Random.Range(0, 255);
        float g = Random.Range(0, 255);
        float b = Random.Range(0, 255);
        float a = Random.Range(125, 255);
        Color tempColor=new Color(r/255f,g/255f,b/255f,a/255f);
        meshMaterial.DOColor(tempColor, 5.0f).OnComplete(delegate
        {
            meshMaterial.DOColor(new Color(0,0,0,1), 5.0f);
        });
    }
    public static void RemoveView(GameObject ob)
    {
        for (int i = 0; i < ob.transform.childCount; i++)
        {
            var child = ob.transform.GetChild(i);
            if (child.transform.CompareTag("Spike"))
                Pools.RecyclePoolObj(child.gameObject);
        }
        Object.Destroy(ob);
    }
    public static float GetColorLength(Material shareMaterial)
    {
        Vector3 temp=new Vector3(1,0,0);
        Color p = shareMaterial.color;
        Vector3 endvalue=new Vector3(p.r,p.g,p.b);
        return Vector3.Dot(endvalue, temp);
    }

    public static Mesh GetObjMesh(List<Vector3> pointsList)
    {
        Mesh curmesh=new Mesh();
        int onepertwo = pointsList.Count/2;
        List<int> indictInts=new List<int>();
        for (int i = 0; i < onepertwo; i++)
        {
            indictInts.Add(i); indictInts.Add(2 * onepertwo - 2-i); indictInts.Add(2 * onepertwo - 1-i);
            indictInts.Add(i); indictInts.Add(i+1); indictInts.Add(2 * onepertwo - 2-i);
        }
        curmesh.vertices = pointsList.ToArray();
        curmesh.triangles = indictInts.ToArray();
        return curmesh;
    }
}
一些基本的工作做完之后,我们就可以生成出一个圆了,这里我们的做法其实数据和视图是存在分离的,这里的视图就是我们用网格来生成这个圆环,同样我们也可以用其他的方式,例如直接用一张图。所以还得定义我们的圆环数据类,该数据的包含几个基本的属性,例如圆环的半径,圆环的所在的游戏实例及圆环节点个数及玩家所在的是内环还是外环,所以一个基本的类就构造出来了,玩家需要在环上移动,这个移动方式不是简单的圆周运动,如果是圆周运动的话那么球在大环上我们看起来移动的慢,在小环上移动的慢,这很显然是不和谐的,所以球在圆上做的是直线运动,只不过我们每帧都在指定球的运动的目标点罢了。所以这个基本的类应该具备2个功能就是痛过index索引得到一个在圆上的位置和痛过在圆上的位置得到一个索引。同样还得有一个最基本的方法了。

using System.Collections.Generic;
using UnityEngine;

public class CircleData
{

    public Transform Parent { set; get; }
    public ListType CurType { set; get; }
    public int Count { set; get; }
    public float Radius { set; get; }

    public Vector3 NextVector3 { set; get; }
    public Vector3 PreVector3 { set; get; }


    private GameObject _player;
    public Vector3 GetTargetPos(int index,ListType curType)
    {
        float offset = _player.GetComponent<CircleCollider2D>().radius;
        float scale = _player.transform.localScale.x;
        float r = 0;
        if (curType == ListType.In)
            r = Radius - scale * offset-0.1f;
        if (curType == ListType.Out)
            r = Radius + scale * offset;

        return GetTargetPos(r,index);
    }

    private Vector3 GetTargetPos(float r,int index)
    {
        float x = Mathf.Cos(index * Mathf.PI / Count * 2 - Mathf.PI / 2) * r;
        float y = Mathf.Sin(index * Mathf.PI / Count * 2 - Mathf.PI / 2) * r;
        Vector3 temp = new Vector3(x, y, 0);

        return temp;
    }
    public int GetTargetIndex(Vector3 targetVector3,ListType listType)
    {
        float offset = _player.GetComponent<CircleCollider2D>().radius;
        float scale = _player.transform.localScale.x;
        int min = 0, max = 0;
        float r=0;
        if (listType == ListType.In)
            r = Radius - scale*offset - 0.1f;
        if (listType == ListType.Out)
            r = Radius + scale*offset;
        if (targetVector3.x >= 0 && targetVector3.y >= 0)
        {
             min = Count / 4 - 1;
             max = Count / 4 + 1;
        }
        if (targetVector3.x >= 0 && targetVector3.y <= 0)
        {
            min = 0;
            max = Count / 4 + 1;
        }
        if (targetVector3.x <= 0 && targetVector3.y >= 0)
        {
            min = Count / 2 + 1;
            max = Count / 4 + 1;
        }
        if (targetVector3.x <= 0 && targetVector3.y <= 0)
        {
            min = Count / 4 * 3 + 1;
            max = Count / 4 + 1;
        }
        for (int i = 0; i < max; i++)
        {
            Vector3 temp = GetTargetPos(r, (i + min) % Count);
            float distance = Vector3.SqrMagnitude(temp - targetVector3);
            if (distance < 0.05)
                return i + min;
        }
        return 200;
    }
    public void  Intilized(int count,Transform parent,GameObject obj,float radius)
    {

        CurType=ListType.In;

        _player = obj;
        Parent = parent;
        Radius = radius;
        Count = count;
    }
}
我们还得必须添加几个枚举,要不然程序出报错了。

public enum GameState
{
    None,
    Playing,
    Pause,
    FailOver,
}
public enum ListType
{
    None,
    In,
    Out
}
public enum LevelState
{
    None,
    OneState,
    TwoState,
    ThreeState,
    FourState,
    FiveState,
}

public enum ColorType
{
    None,
    Green,
    Blue,
    Yellow,
    Red
}
这下应该不会出错了,当我们添加一个圆环所具备的基本数据的时候,我们就可以绘制出一个圆环了。如果我们需要绘制出很过个圆并且让这些圆无缝的连接在一起的时候,这时我们需要一个管理者来统一管理。作为一个管理类,他必须具备一些基本的功能例如添加一个圆环实例和删除一个圆环实例。同时还应该有一个基本的初始化方法。所以接着我们需要添加一个管理类了:

public class CirclesManager
{
    private List<CircleData> _circleDatas;
    private List<GameObject> _circleObjects;
    private CircleBuilder _circleBuilder;

    public int Curindex;
    private PlayerHandler _player;
    public CircleData CurCircleData
    {
        get
        {
            return _circleDatas[Curindex];
        }
    }

    public void Intilized(Material mat, PlayerHandler player, GameObject obstacle,GameObject circle)
    {
        Curindex = 0;
        _circleDatas=new List<CircleData>();
        _circleObjects=new List<GameObject>(4);
        for (int i = 0; i < 4; i++)
        {
            var temp=new CircleData();
            _circleDatas.Add(temp);
        }
        _player = player;
        _circleBuilder=new CircleBuilder();
        _circleBuilder.Intilized(mat, player, obstacle, circle);
    }
    public void InitlizedCircleObj(int totalNum,List<float> circleList)
    {
        for (int i = 0; i < totalNum; i++)
        {
            var circleData = _circleDatas[i];
            GameObject ob = _circleBuilder.CreateCirlceMesh(circleList[i], false,ref circleData);
            _circleObjects.Add(ob);
            if (i==0)
                ob.transform.position = new Vector3(0, 0, 0);
            else
            {
                float radius = _circleDatas[i].Radius + _circleDatas[i-1].Radius - 0.1f;

                ob.transform.position = VectorHelpr.GetVector3ByDis(radius, _circleDatas[i - 1].Parent.position);

                Vector3 dir = (ob.transform.position - _circleDatas[i - 1].Parent.position).normalized;
                _circleDatas[i - 1].NextVector3 = dir * (_circleDatas[i - 1].Radius - 0.1f - _player.Skin)+ 
                    _circleDatas[i - 1].Parent.position;
                _circleDatas[i].PreVector3 = -dir * (_circleDatas[i].Radius - _player.Skin - 0.1f) + _circleDatas[i].Parent.position;
            }
        }
    }
    private void AddCirlceToList(int num)
    {
        int count = _circleDatas.Count;
        var preCircleData = _circleDatas[Curindex];
        GameObject ob1 = _circleBuilder.CreateCirlceMesh(UnityEngine.Random.Range(1.5f, 2.7f), false, ref preCircleData);

        int temp = Curindex;
        Curindex++;
        Curindex %= 4;
        var curCircleData = _circleDatas[(Curindex + 2) % count];

        float radius = curCircleData.Radius + preCircleData.Radius - 0.1f;
        ob1.transform.position = VectorHelpr.GetVector3ByDis(radius, curCircleData.Parent.position);

        Vector3 dir = (preCircleData.Parent.position - curCircleData.Parent.position).normalized;
        curCircleData.NextVector3 = dir * (curCircleData.Radius - 0.1f - _player.Skin) +
                   curCircleData.Parent.position;
        preCircleData.PreVector3 = -dir * (preCircleData.Radius - _player.Skin - 0.1f) + preCircleData.Parent.position;


        _circleObjects[temp] = ob1;
        _circleBuilder.AddObsToCircle(_circleDatas[(temp + 2) % count], num);
    }
    public void UpdateList(int num)
    {
        ViewTool.RemoveView(_circleObjects[Curindex]);
        _circleObjects[Curindex]=null;

        AddCirlceToList(num);
    }
    public void ClearCircleData()
    {
        _circleDatas.Clear();
        for (int i = 0; i < _circleObjects.Count; i++)
        {
            Object.Destroy(_circleObjects[i]);
        }
    }
    public void Reintilized(Action callAction)
    {
        bool isComplete = false;
        for (int i = 0; i < _circleObjects.Count; i++)
        {
            _circleObjects[i].transform.localScale = Vector3.zero;
            _circleObjects[i].transform.DOScale(new Vector3(1, 1, 0), 1.0f).OnComplete(delegate
            {
                if (!isComplete)
                {
                    isComplete = true;
                    callAction.Invoke();
                }
            });
        }
    }

}
管理类就只有添加,删除,因为删除和添加是一个前一个后进行的,所以我用一个UpdateList(int num)代替就行了,其他的都是基本初始化方法了。当我们游戏开始的时候,我们需要生成几个相连接的圆环,所以他应该还要定义一个方法就是初始化我们最开始游戏运行时的圆环数据和圆环实例。管理类需要用到几个工具方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DG.Tweening;
using UnityEngine;



public static class VectorHelpr
{
    public static Vector3 GetVector3ByDis(float radius,Vector3 pos)
    {
        float x = UnityEngine.Random.Range(radius/3, 2*radius/3);
        float y = -Mathf.Sqrt(radius*radius-x*x);

        if (pos.x > 0)
            x = -x;
        return  pos+ new Vector3(x,y,0);
    }
    public static bool JudgeGameOver(CircleData curCircleData,Transform player)
    {
        int cur = curCircleData.GetTargetIndex(curCircleData.NextVector3-curCircleData.Parent.position,ListType.In);
        int nextindex = curCircleData.GetTargetIndex(player.position - curCircleData.Parent.position,ListType.Out);
        ListType curType = curCircleData.CurType;
        if (curType == ListType.Out)
        {
           
            bool b1 = Mathf.Abs(nextindex - cur) <=3;
            return  b1;
        }
        return false;
    }
    public static void CamerFloow(Camera mainCamera,Vector3 targetVector3)
    {
        targetVector3 = new Vector3(targetVector3.x, targetVector3.y, mainCamera.transform.position.z);
        mainCamera.transform.position = targetVector3;
    }
    public static Vector3 GetNormalDir(Vector3 dir, Vector3 center)
    {
        Vector3 endvalue = Quaternion.AngleAxis(90, new Vector3(0, 0, 1))*dir;
        return endvalue;
    }
    public static float GetSpeedByLevel(SpeedLevel curLevel)
    {
        switch (curLevel)
        {
            case SpeedLevel.One:
                return 2f;
            case SpeedLevel.Two:
                return 2.5f;
            case SpeedLevel.Three:
                return 3f;
            case SpeedLevel.Four:
                return 4;
            case SpeedLevel.Five:
                return 4.5f;
        }
        return 0;
    }
    private static LevelState GetLevelStateByScore(int score)
    {
        if (score >= 0 && score <= 50)
            return LevelState.OneState;
        if(score>50&&score<=150)
            return LevelState.TwoState;
        if(score>150&&score<=300)
            return LevelState.ThreeState;
        if(score>300&&score<=500)
            return LevelState.FourState;
        if(score>500&&score<=700)
            return LevelState.FiveState;
        return LevelState.None;
    }
    public static Vector2 GetSpeedAndObsByScore(int score)
    {
        LevelState curLevelState = GetLevelStateByScore(score);
        float speed=0, num=0;
        switch (curLevelState)
        {
            case LevelState.OneState:
                   speed = GetSpeedByLevel(SpeedLevel.One);
                   num = UnityEngine.Random.Range(0, 10)%6 == 0 ? 0 : UnityEngine.Random.Range(2,5);
                   break;
            case LevelState.TwoState:
                   speed = GetSpeedByLevel(SpeedLevel.One);
                   int min = UnityEngine.Random.Range(2, 4);
                   num = UnityEngine.Random.Range(0, 10) % 6 == 0 ? min : min + 2;
                   break;
            case LevelState.ThreeState:
                   speed = GetSpeedByLevel(SpeedLevel.Two);
                   num = UnityEngine.Random.Range(4, 6);
                   break;
            case LevelState.FourState:
                   speed = GetSpeedByLevel(SpeedLevel.Three);
                   num = UnityEngine.Random.Range(4, 6)+1;
                   break;   
            case LevelState.FiveState:
                    speed = GetSpeedByLevel(SpeedLevel.Four);
                    num = UnityEngine.Random.Range(4, 7)+2;
                    break;
                 
        }
        return new Vector2(speed, num);
    }
    public static bool IsBoundIndex(int minindex,int maxindex,int index)
    {
        bool b1 = Mathf.Abs(index - minindex) > 4;
        bool b2 = Mathf.Abs(index - maxindex) > 4;
        return (b1 && b2);
    }
    public static List<int> GetRandomInts(int min,int max,int num)
    {
        List<int> endvalue=new List<int>();
        while (num>=1)
        {
            int temp = UnityEngine.Random.Range(min, max);
            if (!endvalue.Contains(temp))
            {
                endvalue.Add(temp);
                num--;
            }
        }
        return endvalue;
    }

    public static Vector3 GetPosByNormal(Vector3 start,Vector3 end,Vector3 temp,float pradius,float nradius)
    {
        Vector3 dir = (end - start).normalized;
        Vector3 dir1 = (temp - start).normalized;

        float cos = Vector3.Dot(dir, dir1);
        float sin = Mathf.Sqrt(1 - cos * cos);

        bool b = (dir.x*dir1.y - dir.y*dir1.x)>0;
        Vector3 normal = (Quaternion.Euler(0, 0, 90) * dir).normalized;
        float vdistance = pradius*sin;
        float hdistance =Mathf.Sqrt(nradius*nradius - vdistance*vdistance);
        Vector3 endvalue = -dir*hdistance + (b?1:-1)*normal*vdistance;

        return endvalue+end;
    }
}
工具类中的每个方法都很容易理解,我就不多讲,看方法的名字就知道方法是干什么的了。所以我们写代码的时候方法名字和方法体里面要干的事最好保持一致,这样才能让别人和自己以后回顾代码的时候更容易快速的理解。因为你的代码是写个人看的不是写个机器看的,如果你的一个类动不动就是上千行,那么阅读起来会是相当困难的。接下来就讲一下我们的主游戏逻辑类该怎么去写,首先我们的明白一个道理,应该尽量保证我们建的类在不需要继承monobehavior所带来的好处的时候那么我们就没必要去继承至于为什么我前面代码优化中讲到这点。所以我们主游戏逻辑类应该继承monobehavior,主要是因为我们需要在inspect面板上指定一些预设和ui。这个主游戏逻辑相当于值最高层的管理类,所以它的级别应该比较高了,所以常用的调用关系应该是它去调用别人而不是别人可以调用它,如果存在这方面的调用,例如主游戏逻辑中管理游戏的状态,假如我们的玩家死了的话。我们需要指定游戏结束,这里我们几种方法分别列举一下:1 我们可以用一种消息处理机制(这部分前面已经讲到) 2 我们可以使用接口,让主游戏逻辑类继承一个改变游戏状态的接口,然后我们在玩家类持有该接口的引用,同时我们在主游戏逻辑类中初始化玩家的时候给指定引用例如intilized(this)。3 最后一种方法就是单例了。我个人建议不采用,前面2种方法任选其一即可。好了贴出主游戏逻辑的代码吧

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using Random = UnityEngine.Random;

public class GameLayer : MonoBehaviour, IGetCurGameState
{
    [SerializeField] private  Material _meshMaterial;
    [SerializeField] private GameObject _obstacle;
    [SerializeField] private GameObject _explostion;
    [SerializeField] private Camera _mainCamera;
    [SerializeField] private GameObject _playerprefab;

    [SerializeField] private EventSystem eventSystem;
    [SerializeField] private GraphicRaycaster graphicRaycaster;
    [SerializeField] private PlayerHandler _playerHandler;
    [SerializeField] private UIManager _uiManager;
    [SerializeField] private GameObject _circle;
    

    private float _speed;
    private GameState _curGameState;
   
    private int _score = 0;
    private CirclesManager _manager;
    private bool _isReverse=true;

    #region MonoBehavior Function

    private PointerEventData _eventData=null;
    private void Awake()
    {
        _eventData = new PointerEventData(eventSystem);
    }
    private void Start()
    {
        _curGameState = GameState.Playing;
        _manager=new CirclesManager();
        _manager.Intilized(_meshMaterial, _playerHandler, _obstacle, _circle);
        _manager.InitlizedCircleObj(4, new List<float>() { 2, 1.5f, 2.5f, 1.0f });
        _uiManager.Intilized(this);
        _uiManager.AddListenerToButton();

        MessagingSystem.Instance.AttachListener(typeof(GamstateMessage), this.HandleGameStateMsg);
        _mainCamera.transform.DOMove(new Vector3(0, 0, -10), 2.0f);
        _speed = (int)VectorHelpr.GetSpeedAndObsByScore(_score).x;

        Pools.ManageRecyclePool(new ObjectPool() { Prefab = _obstacle, InstancesToPreallocate = 15});
    }


    private Vector3 _offsetVector3;
    private bool _isMove = false;
    private CircleData _curCircleData;
    private float _tempr;
    private bool _isDown = false;
    private void Update()
    {
        if (_curGameState == GameState.Playing)
        {
            _curCircleData = _manager.CurCircleData;
            if (Input.GetMouseButtonDown(0)&&_isDown)
            {
                if (CheckGuiRaycastObjects()) return;

                var temp = _curCircleData.GetTargetIndex(_curCircleData.NextVector3 - _curCircleData.Parent.position, ListType.In);
                var temp1 = _curCircleData.GetTargetIndex(_playerHandler.transform.position - _curCircleData.Parent.position, ListType.In);

                if (Mathf.Abs(temp - temp1) <= 1)
                {

                    Vector3 prePos = _curCircleData.Parent.position;
                    float radiu = _curCircleData.Radius;

                    _speed = (int) VectorHelpr.GetSpeedAndObsByScore(_score).x;
                    _manager.UpdateList((int)VectorHelpr.GetSpeedAndObsByScore(_score).y);
                    _isReverse = !_isReverse;
                    _curCircleData = _manager.CurCircleData;

                    var endvalue = VectorHelpr.GetPosByNormal(prePos, _curCircleData.Parent.position,
                        _playerHandler.transform.position, radiu- 0.2f, _curCircleData.Radius - 0.2f);

                    _index = _curCircleData.GetTargetIndex(endvalue - _curCircleData.Parent.position, ListType.In);
                    if (_isReverse)
                    {
                        _index++;
                        _index %= _curCircleData.Count;
                    }
                    else
                    {
                        _index--;
                        if (_index < 0)
                            _index += _curCircleData.Count;
                    }

                    _playerHandler.transform.position = endvalue;
                    _isMove = false;

                    
                    _curCircleData.CurType = ListType.In;

                    VectorHelpr.CamerFloow(_mainCamera, _curCircleData.Parent.position);
                    _uiManager.SetCurScoreText(++_score);
                }
                else
                {
                   
                    if (_curCircleData.CurType == ListType.In)
                    {
                        _curCircleData.CurType = ListType.Out;
                        _offsetVector3 = _playerHandler.transform.position - _curCircleData.Parent.position;
                        _tempr = _curCircleData.Radius + _playerHandler.Skin;
                        _playerHandler.transform.position = _curCircleData.Parent.position + _offsetVector3.normalized * _tempr;
                    }
                    else
                    {
                        _offsetVector3 = _playerHandler.transform.position - _curCircleData.Parent.position;
                        _tempr = _curCircleData.Radius - _playerHandler.Skin - 0.1f;
                        _playerHandler.transform.position = _curCircleData.Parent.position + _offsetVector3.normalized * _tempr;
                        _curCircleData.CurType = ListType.In;
                    }
                }
            }
            if (_index > 0 && !_isDown)
                _isDown = true;
            if (_isMove)
                MoveThisPlayer(_curCircleData);
            _isMove = true;

            if (VectorHelpr.JudgeGameOver(_curCircleData, _playerHandler.transform))
               _curGameState = GameState.FailOver;
        }
        if (_curGameState == GameState.FailOver)
        {
            Instantiate(_explostion, _playerHandler.transform.position, Quaternion.identity);
            Destroy(_playerHandler.gameObject);
            _uiManager.PopUpFailItem(0, null);
           
            _manager.ClearCircleData();
            _curGameState = GameState.None;
        }
    }

    #endregion
    #region Private Function

    private int _index = 0;
    private void MoveThisPlayer(CircleData curCircleData)
    {
        Vector3 targetPos = curCircleData.GetTargetPos(_index, curCircleData.CurType) + curCircleData.Parent.position;
        Vector3 playerPos = _playerHandler.transform.position;
        float delta = _speed*Time.smoothDeltaTime;
        bool b = (Vector3.SqrMagnitude(targetPos - playerPos) < delta*delta);
        if (b)
        {
            if (_isReverse)
            {
                _index++;
                _index %= curCircleData.Count;
            }
            else
            {
                _index--;
                if (_index < 0)
                    _index += curCircleData.Count;
            }
           
        }
        _playerHandler.transform.position += delta * (targetPos - playerPos).normalized;
    }
    private bool HandleGameStateMsg(BaseMessage curMessage)
    {
        GamstateMessage gamstateMessage = curMessage as GamstateMessage;
        if (gamstateMessage != null)
        {
            _curGameState = gamstateMessage.CurGameState;
        }
        return true;
    }
    private bool CheckGuiRaycastObjects()
    {
        _eventData.pressPosition = Input.mousePosition;
        _eventData.position = Input.mousePosition;
        List<RaycastResult> list = new List<RaycastResult>();
        graphicRaycaster.Raycast(_eventData, list);
        for (int i = 0; i < list.Count; i++)
        {
            if (list[i].gameObject.CompareTag("Button"))
                return true;
        }
        return false;
    }
   
    #endregion
    public GameState GetGameState()
    {
        return _curGameState;
    }
    public void ReIntilized()
    {
        GameObject ob = GameObject.Instantiate(_playerprefab, new Vector3(0,0.5f,0), Quaternion.identity)as GameObject;
        if (ob != null) _playerHandler = ob.GetComponent<PlayerHandler>();

        _speed =VectorHelpr.GetSpeedByLevel(SpeedLevel.One);
        _manager.Intilized(_meshMaterial, _playerHandler, _obstacle, _circle);
        _manager.InitlizedCircleObj(4, new List<float>() { 2, 1.5f, 2.5f, 1.0f });
        _manager.Reintilized(delegate {_curGameState=GameState.Playing;});

        _isReverse = true;
        _score = 0;
        _index = 0;
        _mainCamera.transform.position=new Vector3(0,0,-10);
        VectorHelpr.CamerFloow(_mainCamera, _manager.CurCircleData.Parent.position);
    }

}
方法体里面的东西比较简单没人什么复杂,就前面圆圈的生成麻烦一点了。如果还有什么不懂的可以qq和我讨论:1850761495

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









本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。
实现软键盘主要用到了系统的两个类:Keyboard和KeyboardView。 Keyboard类源码的介绍是: Listener for virtual keyboard events.即用于监听虚拟键盘。 KeyboardView类源码的介绍是: A view that renders a virtual {@link Keyboard}. It handles rendering of keys and detecting key presses and touch movements.即它处理绘制
先上效果图:文章后面会给出代码: 对赛贝尔曲线不了解的同学可以先看看这篇文章: http://blog.csdn.net/u010335298/article/details/51912118 二次赛贝尔曲线方程式讲解和根据赛贝尔曲线起点,终点和线上的点求控制点: 二次赛贝尔曲线的公式为: 其中,p0是起点,p1是控制点,p2是终点,下图很好的说明了他们的关系: 由公式,我们可以求得曲线上的任意一点的坐标: 假设p0(x,y),p1(x,y),p2(x,y)已知,我们要求的点为P(x,y),未知,则: x

Android-ViewPager嵌套使用探究 - 2016-07-17 14:07:45

终于不再是实习生,走出了穷逼的实习生生活,正式开始稍微不那么穷逼的正职员工生活,三天的启航培训还是挺欢乐的,学到一句话,保持饥渴,哈哈,感觉放到哪方面都说得通。 回归正题: ViewPager的嵌套使用是一个很常见的问题,然而,最近又一次遇到ViewPager的嵌套使用问题。 情景是这样的,需求上给出了这样的要求,需要实现内外两个ViewPager嵌套的效果,外部ViewPager控制着4个Tab的切换滑动,内部ViewPager控制着若干个二级Tab的滑动切换(这里可能是广告栏,也可能是榜单等),另外,
转载请标明出处: 一片枫叶的专栏 上一篇文章中我们讲解了android产品研发过程中的代码Review。通过代码Review能够提高产品质量,增强团队成员之间的沟通,提高开发效率,所以良好的产品开发迭代过程中,代码Review是一个必不可少的步骤。那么如何进行代码Review呢?我们主要讲解了团队成员之间的代码Review,代码lint检查,开发规范等方面的知识点,更多关于代码Review相关的知识可参考我的: android产品研发(二十)–代码Review 本文我们将讲解一下android UI优化方

ViewPager 切换页面 - 2016-07-17 14:07:42

package com.gaoo.apptab; /** * ViewPager 实现tab * * 代码中存在一个小问题: 点击底部导航栏时,点击下面的文字没有问题可以正常切换,而点击标签文字上方的图片就不能实现正常切换了,这是为什么? * 因为我们在底部导航栏 4个 LinearLayout 布局中 图片的展示的控件是 ImageButton ,而它本身具备消费点击事件的能力,自己把点击事件消费掉了, * 而我们这里的ImageButton 没有实现点击事件,所以就不能切换. * 从而导致最外层的 L

Retrofit2.0使用 - 2016-07-17 14:07:42

随着Google对HttpClient 摒弃,和Volley的逐渐没落,OkHttp开始异军突起,而Retrofit则对okHttp进行了强制依赖。 Retrofit是由Square公司出品的针对于Android和Java的类型安全的Http客户端, 如果看源码会发现其实质上就是对okHttp的封装,使用面向接口的方式进行网络请求,利用动态生成的代理类封装了网络接口请求的底层, 其将请求返回javaBean,对网络认证 REST API进行了很好对支持此,使用Retrofit将会极大的提高我们应用的网络体
整个文件的布局 文件头 索引区 string_ids type_ids proto_ids field_ids method_ids 数据区 class_def class_data_item code_item data 附录 测试用的Dex的java代码 参考资料 整个文件的布局 整个Dex文件可以分成三部分,文件头、索引区、数据区,如下图所示。 文件头 记录Dex文件的概览、包含文件大小、校验码以及其他字段的偏移和大小 索引区 记录字符串常量、类型、方法原形、域、方法的信息的索引 数据区 包含类的定
有时候我们做的游戏不仅仅发布在国内市场,有时候也需要发布在国际市场,这时候我们至少需要中英2套菜单来供不同的玩家使用,毕竟中文不是每个人都能看懂。 Libgdx中提供了 I18NBundle 来供我们使用, I18NBundle 提供了一套机制可以使我们从属性(properties)文件中加载资源, 属性文件中的资源是以”name”和”values”的形式存在的,而且资源最好有一个父文件,这样防止资源丢失时,可以使用父文件中的值: 通过上面图片可以看出string.properties就是父文件,另外2个
Retrofit:Android和Java的类型安全的HTTP客户端。 Introduction: 1.Retrofit把你的HTTP API转换成Java接口 spanpublic interface GitHubService { @GET("users/{user}/repos") CallListRepo listRepos(@Path("user") String user);}/span 2.Retrofit类去实现GitHubService的接口 spanRetrofit retrofit

漫谈android系统(7)-log系统1 - 2016-07-17 14:07:56

前言 罗升阳的《Android系统源代码情景分析》一书,有关log是如何显示,那么真的在代码中是如何实现的呢?就该问题我想需要细细分析 bootloader层的log 在firmware中的log是如何产生的,我没有看过firmware的code,不清楚它是如何实现的,这是我的短板,回头得补上!在这里先分析lk中是如何实现的。 从aboot.c着手 相信在源码中看到bootable\bootloader\lk下的app\aboot.c中最常用于打log信息的语句为dprintf。那么它的原型在哪里? 其原