// 旋转图形 static public SceneShapePolygon rotate(SceneShapeRect rect, Vector2 pos, float angles) { SceneShapePolygon shape = new SceneShapePolygon(); Vector3 lt = new Vector3(rect.mLeft, 0.0f, rect.mTop); Vector3 rt = new Vector3(rect.mRight, 0.0f, rect.mTop); Vector3 lb = new Vector3(rect.mLeft, 0.0f, rect.mBottom); Vector3 rb = new Vector3(rect.mRight, 0.0f, rect.mBottom); Quaternion q = new Quaternion(); q.eulerAngles = new Vector3(0, angles, 0); Vector3 center = new Vector3(pos.x, 0.0f, pos.y); Vector3 ltnew = (q * (lt - center)) + center; Vector3 rtnew = (q * (rt - center)) + center; Vector3 lbnew = (q * (lb - center)) + center; Vector3 rbnew = (q * (rb - center)) + center; shape.PushbackVector2(new Vector2(ltnew.x, ltnew.z)); shape.PushbackVector2(new Vector2(rtnew.x, rtnew.z)); shape.PushbackVector2(new Vector2(rbnew.x, rbnew.z)); shape.PushbackVector2(new Vector2(lbnew.x, lbnew.z)); return(shape); }
public SceneShapeRect(SceneShapeRect rect) { mLeft = rect.mLeft; mTop = rect.mTop; mRight = rect.mRight; mBottom = rect.mBottom; }
// 矩形与多边形重叠(相交或包含) static public bool overlap(SceneShapeRect rect, SceneShapePolygon polygon) { // 矩形有顶点在多边形内 一定相交 if (polygon.contains(rect.leftTop())) { return(true); } if (polygon.contains(rect.rightTop())) { return(true); } if (polygon.contains(rect.rightBottom())) { return(true); } if (polygon.contains(rect.leftBottom())) { return(true); } for (int i = 0; i < polygon.mPts.Count; ++i) { Vector2 pt1 = polygon.mPts[i]; Vector2 pt2 = polygon.mPts[((i + 1) % polygon.mPts.Count)]; // 多边形有顶点在矩形内 一定相交 if (rect.contains(pt1)) { return(true); } // 多边形与矩形有边相交 两图形一定相交 if (Utility.isSegmentIntersect(pt1, pt2, rect.leftTop(), rect.rightTop())) { return(true); } if (Utility.isSegmentIntersect(pt1, pt2, rect.rightTop(), rect.rightBottom())) { return(true); } if (Utility.isSegmentIntersect(pt1, pt2, rect.rightBottom(), rect.leftBottom())) { return(true); } if (Utility.isSegmentIntersect(pt1, pt2, rect.leftBottom(), rect.leftTop())) { return(true); } } return(false); }
//搜索区域内的 BattleUnit public ArrayList SearchObject(SceneShapeRect shape, int searchType, bool ignoreDead = true) { ArrayList objs = new ArrayList(); PoolSlot slot = mObjPool.UsedList(); while (slot != null) { ObjectBase unit = slot.Content as ObjectBase; if (unit == null) { slot = slot.NextSlot; continue; } if (!ObjectType.IsCanSearch(searchType, unit.Type)) { slot = slot.NextSlot; continue; } Vector3 pos = unit.GetPosition(); if (shape.contains(new Vector2(pos.x, pos.z))) { objs.Add(unit); } slot = slot.NextSlot; } if (!ignoreDead) { for (int i = 0; i < mWaitDestoryObjects.Count; ++i) { ObjectBase obj = mWaitDestoryObjects[i]; if (obj == null) { continue; } if (!ObjectType.IsCanSearch(searchType, obj.Type)) { continue; } Vector3 pos = obj.GetPosition(); if (shape.contains(new Vector2(pos.x, pos.z))) { objs.Add(obj); } } } return(objs); }
// 解析Zones private void ParseZones(XmlNode node) { XmlNodeList nodeList = node.ChildNodes; for (int i = 0; i < nodeList.Count; ++i) { XmlNode childNode = nodeList[i]; if (childNode != null && childNode.Name == "Zone") { int type = System.Convert.ToInt32(childNode.Attributes["type"].Value); if ((Zone.ZoneType)type == Zone.ZoneType.ZoneType_Invalid || !System.Enum.IsDefined(typeof(Zone.ZoneType), type)) { continue; } Zone zone = new Zone(); zone.type = (Zone.ZoneType)type; zone.name = childNode.Attributes["name"].Value; ShapeType shapetype = (ShapeType)(System.Convert.ToInt32(childNode.Attributes["shapeType"].Value)); if (shapetype == ShapeType.ShapeType_Round) { zone.shape = new SceneShapeRound(); SceneShapeRound round = zone.shape as SceneShapeRound; round.mCenter.x = (float)System.Convert.ToDouble(childNode.Attributes["x"].Value); round.mCenter.y = (float)System.Convert.ToDouble(childNode.Attributes["y"].Value); round.mRadius = (float)System.Convert.ToDouble(childNode.Attributes["r"].Value); } else if (shapetype == ShapeType.ShapeType_Rect) { zone.shape = new SceneShapeRect(); SceneShapeRect rect = zone.shape as SceneShapeRect; rect.mLeft = (float)System.Convert.ToDouble(childNode.Attributes["x1"].Value); rect.mTop = (float)System.Convert.ToDouble(childNode.Attributes["y1"].Value); rect.mRight = (float)System.Convert.ToDouble(childNode.Attributes["x2"].Value); rect.mBottom = (float)System.Convert.ToDouble(childNode.Attributes["y2"].Value); } else if (shapetype == ShapeType.ShapeType_Polygon) { zone.shape = new SceneShapePolygon(); SceneShapePolygon polygon = zone.shape as SceneShapePolygon; int index = 1; XmlAttribute attribX = null; XmlAttribute attribY = null; while ((attribX = childNode.Attributes["x" + index.ToString()]) != null && (attribY = childNode.Attributes["y" + index.ToString()]) != null) { polygon.PushbackVector2(new Vector2((float)System.Convert.ToDouble(attribX.Value), (float)System.Convert.ToDouble(attribY.Value))); index++; } } mZones.Add(zone.name, zone); } } }
// 矩形与矩形重叠(相交或包含) static public bool overlap(SceneShapeRect rect1, SceneShapeRect rect2) { if (Mathf.Abs((rect1.mLeft + rect1.mRight) * 0.5f - (rect2.mLeft + rect2.mRight) * 0.5f) < ((rect1.mRight + rect2.mRight - rect1.mLeft - rect2.mLeft) * 0.5f) && Mathf.Abs((rect1.mTop + rect1.mBottom) * 0.5f - (rect2.mTop + rect2.mBottom) * 0.5f) < ((rect1.mTop + rect2.mTop - rect1.mBottom - rect2.mBottom) * 0.5f)) { return(true); } return(false); }
// 根据形状参数、位置、弧度 创建形状 static public SceneShape Create(SceneShapeParam param, Vector2 pos, float radians) { if (param.mType == ShapeType.ShapeType_Round) { if (param == null || param.mParams == null || param.mParams.Count < 1) { return(null); } return(new SceneShapeRound(pos, param.mParams[0])); } else if (param.mType == ShapeType.ShapeType_Rect) { if (param == null || param.mParams == null || param.mParams.Count < 2) { return(null); } if ((int)(radians * 100000) % (int)(Mathf.PI * 100000 * 2) == 0) { if ((int)(radians * 100000) % (int)(Mathf.PI * 100000) == 0) { return(new SceneShapeRect(pos, param.mParams[0], param.mParams[1])); } return(new SceneShapeRect(pos, param.mParams[1], param.mParams[0])); } else { SceneShapeRect rect = new SceneShapeRect(pos, param.mParams[0], param.mParams[1]); return(rotate(rect, pos, radians * Mathf.Rad2Deg)); } } else if (param.mType == ShapeType.ShapeType_Polygon) { if (param == null || param.mParams == null || param.mParams.Count < 2 || param.mParams.Count % 2 != 0) { return(null); } SceneShapePolygon shape = new SceneShapePolygon(); for (int i = 0; i < (int)(param.mParams.Count * 0.5); ++i) { shape.PushbackVector2(new Vector2(param.mParams[2 * i], param.mParams[2 * i + 1])); } return(rotate(ref shape, pos, radians * Mathf.Rad2Deg)); } GameDebug.LogError("SceneShape.Creat() 未知的图形类别"); return(null); }
//获取跨图传送点 public Vector3 GetTransPort() { ArrayList list = mEventsTypeMap["onPlayerEnterZone"]; if (list == null) { return(Vector3.zero); } string zoneName = ""; foreach (XMLEventStruct e in list) { foreach (XMLFunctionStruct f in e.mFunctions) { if (f.mType == "OpenUI" && f.mParams[0] == "mainmap") { zoneName = e.mParams[0]; } } } if (zoneName != "") { Zone zone = mZones[zoneName] as Zone; if (zone != null) { if (zone.shape is SceneShapeRound) { SceneShapeRound ssr = zone.shape as SceneShapeRound; GameDebug.Log("获取传送点 " + new Vector3(ssr.mCenter.x, 0, ssr.mCenter.y)); return(new Vector3(ssr.mCenter.x, 0, ssr.mCenter.y)); } else if (zone.shape is SceneShapeRect) { SceneShapeRect sst = zone.shape as SceneShapeRect; GameDebug.Log("获取传送点 " + new Vector3((sst.mLeft + sst.mRight) / 2, 0, (sst.mTop + sst.mBottom) / 2)); return(new Vector3((sst.mLeft + sst.mRight) / 2, 0, (sst.mTop + sst.mBottom) / 2)); } } } return(Vector3.zero); }
// 相交 public bool intersect(SceneShapeRect rect) { return(shape.intersect(rect)); }
// 圆与矩形重叠(相交或包含) static public bool overlap(SceneShapeRound round, SceneShapeRect rect) { if (rect.contains(round.mCenter)) { return(true); } if (round.contains(new Vector2(rect.mLeft, rect.mBottom)) || round.contains(new Vector2(rect.mLeft, rect.mTop)) || round.contains(new Vector2(rect.mRight, rect.mBottom)) || round.contains(new Vector2(rect.mRight, rect.mTop))) { return(true); } float x = rect.mLeft - round.mCenter.x; if (Mathf.Abs(x) > round.mRadius) { return(false); } if (rect.contains(new Vector2(round.mCenter.x + x, round.mCenter.y))) { return(true); } x = rect.mRight - round.mCenter.x; if (Mathf.Abs(x) > round.mRadius) { return(false); } if (rect.contains(new Vector2(round.mCenter.x + x, round.mCenter.y))) { return(true); } x = rect.mBottom - round.mCenter.y; if (Mathf.Abs(x) > round.mRadius) { return(false); } if (rect.contains(new Vector2(round.mCenter.x, round.mCenter.y + x))) { return(true); } x = rect.mTop - round.mCenter.y; if (Mathf.Abs(x) > round.mRadius) { return(false); } if (rect.contains(new Vector2(round.mCenter.x, round.mCenter.y + x))) { return(true); } return(false); }
// 包含矩形 public bool contains(SceneShapeRect rect) { return(rect.mLeft >= mLeft && rect.mRight <= mRight && rect.mTop <= mTop && rect.mBottom >= mBottom); }
static public bool overlap(SceneShapeLine shape1, SceneShapeRect shape2) { return(Geometryalgorithm2d.lineseg_intersect_rectangle( new LineSegf(new Vector2f(shape1.mVertex1.x, shape1.mVertex1.y), new Vector2f(shape1.mVertex2.x, shape1.mVertex2.y)), new Rectanglef(new Vector2f(shape2.leftBottom().x, shape2.leftBottom().y), new Vector2f(shape2.rightTop().x, shape2.rightTop().y)))); }
/// <summary> /// 根据目标选择参数, 以centerPosition为中心选择目标. /// </summary> /// <param name="attackerAttr">攻击者的数据</param> /// <param name="centerPosition">选择的中心点</param> /// <param name="attackerDirection">攻击者的方向(对于矩形, 扇形时用到)</param> /// <param name="res">目标选择的资源</param> /// <returns>目标集合, 不会为null.</returns> public static ArrayList SelectTargets(AttackerAttr attackerAttr, Vector3 centerPosition, float attackerDirection, TargetSelectionTableItem targetSelRes) { BaseScene scn = SceneManager.Instance.GetCurScene(); if (scn == null) { return(null); } SceneShapeRect selRect = null; ArrayList result = null; SceneShape shape = null; switch (targetSelRes.shape) { // 假设目标最大半径为5.0f米 case ShapeType.ShapeType_Round: { float radius = targetSelRes.CircleRadius * 2.0f + 5.0f; selRect = new SceneShapeRect(new Vector2(centerPosition.x, centerPosition.z), radius, radius); shape = new SceneShapeRound(new Vector2(centerPosition.x, centerPosition.z), targetSelRes.CircleRadius); } break; case ShapeType.ShapeType_Rect: { float radius = targetSelRes.RectLength + targetSelRes.RectWidth + 5.0f; selRect = new SceneShapeRect(new Vector2(centerPosition.x, centerPosition.z), radius, radius); SceneShapeRect rect = new SceneShapeRect(new Vector2(centerPosition.x, centerPosition.z), targetSelRes.RectLength, targetSelRes.RectWidth); shape = SceneShapeUtilities.rotate(rect, new Vector2(centerPosition.x, centerPosition.z), attackerDirection * Mathf.Rad2Deg); } break; case ShapeType.ShapeType_Invalid: break; default: ResourceInvalidParam("targetselection", (uint)targetSelRes.resID, "形状"); break; } if (shape != null && selRect != null) { ArrayList lst = scn.SearchObject(selRect, ObjectType.OBJ_SEARCH_BATTLEUNIT); if (lst != null && lst.Count > 0) { result = new ArrayList(); for (int i = 0; i < lst.Count; i++) { ObjectBase obj = lst[i] as ObjectBase; if (obj == null) { continue; } if (shape.intersect(obj.GetShape())) { result.Add(obj); } } } } if (result == null) { result = new ArrayList(); } // 根据阵营筛选. FilterTargetsBy(result, filterTargetsByLeague, attackerAttr, targetSelRes.leagueSel); // 最多只能选择maxTargetCount个单位. RandomSampling(result, targetSelRes.maxTargetCount); return(result); }