Exemplo n.º 1
0
        // Update is called once per frame
        void Update()
        {
            slowMotion          = Mathf.Clamp(slowMotion, 0.01f, 1.0f);
            Time.timeScale      = slowMotion;
            Time.fixedDeltaTime = 0.02f * slowMotion;

            if (Input.GetButtonDown("Fire1"))
            {
                Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                pos.z = transform.position.z;

                GameObject go = Instantiate(obj);
                go.transform.position = pos;
                go.transform.rotation = Quaternion.identity;

                quadtree.Add(go.GetComponent <QtAgent> ());

                placedAgent = go.GetComponent <QtAgent>();

                if (go.GetComponent <Rigidbody2D> () != null)
                {
                    int     cornerIndex = Random.Range(0, quadtree.Boundary.AllCorners.Length);
                    Vector2 corner      = quadtree.Boundary.AllCorners [cornerIndex];
                    Vector2 dir         = (corner - placedAgent.GetCenter()).normalized * 3.0f;
                    go.GetComponent <Rigidbody2D> ().AddForce(dir);
                }
            }

            if (Input.GetButtonDown("Fire2"))
            {
                Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                pos.z = transform.position.z;

                GameObject go = Instantiate(obj);
                go.transform.position = pos;
                go.GetComponent <SpriteRenderer> ().color = Color.black;

                quadtree.Add(go.GetComponent <QtAgent> ());

                pickAgent = go.GetComponent <QtAgent>();


                /*
                 * //clear prvious agent contact status
                 * foreach (IQuadtreeAgent a in queryAgents)
                 *      a.GetGameObject ().GetComponent<QtCircleAgent> ().contact = false;
                 *
                 * List<IQuadtreeAgent> retriveAgents = pickAgent.CurrentNode.FindElements(pickAgent);
                 * foreach (IQuadtreeAgent agent in retriveAgents) {
                 *
                 *      agent.GetGameObject ().GetComponent<QtCircleAgent> ().contact = true;
                 *
                 *      queryAgents.Add (agent);
                 * }
                 */
            }

            if (Input.GetButtonDown("Jump"))
            {
                QtAgent[] agents = GameObject.FindObjectsOfType <QtAgent> ();

                StartCoroutine(RemoveAgents(agents));
            }

            if (Input.GetButton("Submit"))
            {
                Vector3 mPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                Vector2 pos  = new Vector2(mPos.x, mPos.y);

                if (circleQuery == null)
                {
                    circleQuery = new QtCircleQuery(pos, queryRadius);
                }

                if (rectQuery == null)
                {
                    rectQuery = new QtRectangleQuery(pos, rectQuerySize);
                }

                ((ConvexCircle)circleQuery.GetShape()).Center = pos;
                ((ConvexCircle)circleQuery.GetShape()).Radius = queryRadius;

                ((ConvexRect)rectQuery.GetShape()).Center   = pos;
                ((ConvexRect)rectQuery.GetShape()).Width    = rectQuerySize.x;
                ((ConvexRect)rectQuery.GetShape()).Height   = rectQuerySize.y;
                ((ConvexRect)rectQuery.GetShape()).Rotation = ((ConvexRect)rectQuery.GetShape()).Rotation + Time.deltaTime * 80.0f;


                //clear prvious agent contact status
                List <IQuadtreeAgent> .Enumerator er = queryAgents.GetEnumerator();
                while (er.MoveNext())
                {
                    (er.Current as QtCircleAgent).contact = false;
                }
                queryAgents.Clear();


                // quadtree query
                //er = quadtree.QueryRange (circleQuery).GetEnumerator();
                er = quadtree.QueryRange(rectQuery).GetEnumerator();
                while (er.MoveNext())
                {
                    (er.Current as QtCircleAgent).contact = true;
                    queryAgents.Add(er.Current);

                    Vector2 force = er.Current.GetCenter() - (circleQuery.GetShape() as ConvexCircle).Center;
                    force = force.normalized * (100.0f * ((circleQuery.GetShape() as ConvexCircle).Radius - force.magnitude / (circleQuery.GetShape() as ConvexCircle).Radius));

                    if ((er.Current as QtAgent).agRigidbody2D)
                    {
                        (er.Current as QtAgent).agRigidbody2D.AddForce(force);
                    }
                }

                drawQuery = true;
            }
            else
            {
                drawQuery = false;


                //clear prvious agent contact status

                /*
                 * foreach (IQuadtreeAgent a in queryAgents){
                 *      //a.GetGameObject ().GetComponent<QtCircleAgent> ().contact = false;
                 *      (a as QtCircleAgent).contact = false;
                 * }
                 */
                List <IQuadtreeAgent> .Enumerator er = queryAgents.GetEnumerator();
                while (er.MoveNext())
                {
                    (er.Current as QtCircleAgent).contact = false;
                }
                queryAgents.Clear();
            }
        }
Exemplo n.º 2
0
		/**
		 * Query elements within or contact with query shape
		 * 
		 * You can create your own query with any kind of convex shape
		 * 
		 * Return list of elements contact with or within query shape
		 * 
		 * Param upwardSearch true query will find the node that query shape complete fit in  in first
		 * place then start search downward from that node. It is recommend to leave value as true for 
		 * more accurate result. 
		 **/
		public List<IQuadtreeAgent> QueryRange(IQuadtreeQuery query, bool upwardSearch = true){

			if (query == null) {

				#if DEBUG
				Debug.LogError("Can't query range, given query is null");
				#endif
				return null;
			}

			/**
			 * Upward search from this node
			 * 
			 * This will go up until the node wihch query shape complete fit in
			 **/
			if (upwardSearch) {

				//If this is the node query shape complete fit in
				CollisionResult cResult = query.GetShape().IntersectWithShape(boundary);

				//we found the node then start query from this node
				if (cResult == CollisionResult.Fit) {

					//downward search from parent if there is parent node
					//the reason from parent node is that parent node's overlap element
					//might be contact query shape
					if (parentNode != null) {

						//from parent node we start downward search
						return parentNode.QueryRange (query, false);
					}
						
				} else {//continue search upward

					//If there is a parent node otherwsie this is root node and start from
					//here downward search
					if (parentNode != null) {

						//Continue finding upward until the node query shape can totally fit in
						return parentNode.QueryRange (query, true);
					}
				}

			}

			/**
			 * Downward search from this node
			 * 
			 * Downward search only search elements in child node include this node
			 **/

			List<IQuadtreeAgent> result = new List<IQuadtreeAgent> ();

			CollisionResult r = query.GetShape ().IntersectWithShape (boundary);

			//if not contact with query shape which is not in range
			if (r == CollisionResult.None)
				return result;

			//search child nodes
			if (nodes != null) {

				IEnumerator er = nodes.GetEnumerator ();
				while (er.MoveNext ()) {
					result.AddRange ((er.Current as QuadtreeNode).QueryRange (query, false));
				}
					
			}

			//add this node's elements
			result.AddRange (elements);
			result.AddRange (overlapElements);

			//Check if any of element contact query shape
			List<IQuadtreeAgent> filterResult = new List<IQuadtreeAgent>();

			List<IQuadtreeAgent>.Enumerator resultEr = result.GetEnumerator();
			while(resultEr.MoveNext()){

				if(resultEr.Current.GetShape().IntersectWithShape(query.GetShape()) != CollisionResult.None){
				
					filterResult.Add(resultEr.Current);
				}
			}

			return filterResult;
		}