C# 计算游戏技能攻击区域
来源:互联网 发布:淘宝海报设计价格 编辑:程序博客网 时间:2024/05/22 00:26
孙广东 2017.10.22
http://blog.csdn.NET/u010019717
1、判断 一个点是否在 与坐标平行的矩形内
public struct AAB2 { public Vector2 Min; public Vector2 Max; public static AAB2 CreateAAB2(Transform point0, Transform point1) { // Creates aab from two unsorted points, if you know min and max use constructor return CreateFromTwoPoints(point0.position, point1.position); } public static AAB2 CreateFromTwoPoints(Vector2 point0, Vector2 point1) { AAB2 aab; if (point0.x < point1.x) { aab.Min.x = point0.x; aab.Max.x = point1.x; } else { aab.Min.x = point1.x; aab.Max.x = point0.x; } if (point0.y < point1.y) { aab.Min.y = point0.y; aab.Max.y = point1.y; return aab; } aab.Min.y = point1.y; aab.Max.y = point0.y; return aab; } public bool Contains(ref Vector2 point) { if (point.x < this.Min.x) { return false; } if (point.x > this.Max.x) { return false; } if (point.y < this.Min.y) { return false; } if (point.y > this.Max.y) { return false; } return true; } public void CalcVertices(out Vector2 vertex0, out Vector2 vertex1, out Vector2 vertex2, out Vector2 vertex3) { vertex0 = this.Min; vertex1 = new Vector2(this.Max.x, this.Min.y); vertex2 = this.Max; vertex3 = new Vector2(this.Min.x, this.Max.y); }}
[ExecuteInEditMode]public class Test_ContPoint2AAB2 : MonoBehaviour{ public Transform Point; public Transform Box_Point0, Box_Point1; private const float _pointRadius = .11f; private void OnDrawGizmos() { Vector2 point = Point.position; AAB2 box = AAB2.CreateAAB2(Box_Point0, Box_Point1); bool cont = box.Contains(ref point); FiguresColor(); DrawAAB(ref box); if (cont) ResultsColor(); DrawPoint(point); LogInfo(cont); } protected void DrawPoint(Vector2 position) { Gizmos.DrawSphere(position, _pointRadius); } protected void ResultsColor() { Gizmos.color = Color.blue; } protected void FiguresColor() { Gizmos.color = Color.gray; } protected void LogInfo(object value) { Debug.Log(value); } protected void DrawAAB(ref AAB2 box) { Vector2 v0, v1, v2, v3; box.CalcVertices(out v0, out v1, out v2, out v3); Gizmos.DrawLine(v0, v1); Gizmos.DrawLine(v1, v2); Gizmos.DrawLine(v2, v3); Gizmos.DrawLine(v3, v0); }}
2、 判断是否在矩形内
矩形就是 Box 对象决定, 自己是原点, 旋转决定了两个轴 , Scale决定了 宽高!
[ExecuteInEditMode]public class Test_ContPoint2Box2 : MonoBehaviour{ public Transform Point; public Transform Box; private const float _pointRadius = .11f; private void OnDrawGizmos() { Vector2 point = Point.position; Box2 box = Box2.CreateBox2(Box); bool cont = box.Contains(ref point); FiguresColor(); DrawBox(ref box); if (cont) ResultsColor(); DrawPoint(point); LogInfo(cont); } protected void DrawPoint(Vector2 position) { Gizmos.DrawSphere(position, _pointRadius); } protected void ResultsColor() { Gizmos.color = Color.blue; } protected void FiguresColor() { Gizmos.color = Color.gray; } protected void LogInfo(object value) { Debug.Log(value); } protected void DrawBox(ref Box2 box) { Vector2 v0, v1, v2, v3; box.CalcVertices(out v0, out v1, out v2, out v3); Gizmos.DrawLine(v0, v1); Gizmos.DrawLine(v1, v2); Gizmos.DrawLine(v2, v3); Gizmos.DrawLine(v3, v0); }}
public struct Box2 { public Vector2 Center; public Vector2 Axis0; public Vector2 Axis1; public Vector2 Extents; public Box2(Vector2 center, Vector2 axis0, Vector2 axis1, Vector2 extents) { this.Center = center; this.Axis0 = axis0; this.Axis1 = axis1; this.Extents = extents; } public static Box2 CreateBox2(Transform box) { return new Box2(box.position, box.right, box.up, box.localScale); } public bool Contains(ref Vector2 point) { Vector2 vector; vector.x = point.x - this.Center.x; vector.y = point.y - this.Center.y; float num = vector.Dot(ref this.Axis0); if (num < -this.Extents.x) { return false; } if (num > this.Extents.x) { return false; } num = vector.Dot(ref this.Axis1); if (num < -this.Extents.y) { return false; } if (num > this.Extents.y) { return false; } return true; } public void CalcVertices(out Vector2 vertex0, out Vector2 vertex1, out Vector2 vertex2, out Vector2 vertex3) { Vector2 vector = (Vector2)(this.Axis0 * this.Extents.x); Vector2 vector2 = (Vector2)(this.Axis1 * this.Extents.y); vertex0 = (this.Center - vector) - vector2; vertex1 = (this.Center + vector) - vector2; vertex2 = (this.Center + vector) + vector2; vertex3 = (this.Center - vector) + vector2; }}public static class Vector2ex{ public static float Dot(this Vector2 vector, ref Vector2 value) { return ((vector.x * value.x) + (vector.y * value.y)); }}
3、 判断一个点是否在园内部
[ExecuteInEditMode]public class Test_ContPoint2Circle2 : MonoBehaviour{ public Transform Point; public Transform Circle; private const float _pointRadius = .11f; private void OnDrawGizmos() { Vector2 point = Point.position; Circle2 circle = Circle2.CreateCircle2(Circle); bool cont = circle.Contains(ref point); FiguresColor(); DrawCircle(ref circle); if (cont) ResultsColor(); DrawPoint(point); LogInfo(cont); } protected void DrawPoint(Vector2 position) { Gizmos.DrawSphere(position, _pointRadius); } protected void ResultsColor() { Gizmos.color = Color.blue; } protected void FiguresColor() { Gizmos.color = Color.gray; } protected void LogInfo(object value) { Debug.Log(value); } protected void DrawCircle(ref Circle2 circle) { int count = 40; float delta = 2f * Mathf.PI / count; Vector3 prev = circle.Eval(0); for (int i = 1; i <= count; ++i) { Vector3 curr = circle.Eval(i * delta); Gizmos.DrawLine(prev, curr); prev = curr; } }}
public struct Circle2{ public Vector2 Center; public float Radius; public Circle2(Vector2 center, float radius) { this.Center = center; this.Radius = radius; } public bool Contains(ref Vector2 point) { Vector2 vector = point - this.Center; return (vector.SqrMagnitude() <= (this.Radius * this.Radius)); } public Vector2 Eval(float t) { return new Vector2(this.Center.x + (this.Radius * Mathf.Cos(t)), this.Center.y + (this.Radius * Mathf.Sin(t))); } public static Circle2 CreateCircle2(Transform circle) { return new Circle2(circle.position, circle.localScale.x); }}
4、 三角形内
[ExecuteInEditMode]public class Test_ContPoint2Triangle2 : MonoBehaviour{ public Transform Point; public Transform V0, V1, V2; private const float _pointRadius = .11f; private void OnDrawGizmos() { Vector2 point = Point.position; Triangle2 triangle = Triangle2.CreateTriangle2(V0, V1, V2); Orientations orientation = triangle.CalcOrientation(); if (orientation == Orientations.CCW) { bool cont = triangle.Contains(ref point); bool cont1 = triangle.ContainsCCW(ref point); // 如果你知道三角形方向(顶点顺序方向),就用这个 FiguresColor(); DrawTriangle(ref triangle); if (cont) ResultsColor(); DrawPoint(point); LogInfo("Orientation: " + orientation + " Contained: " + cont); if (cont != cont1) Debug.LogError("cont != cont1"); } else if (orientation == Orientations.CW) { bool cont = triangle.Contains(ref point); bool cont1 = triangle.ContainsCW(ref point); // 如果你知道三角形方向(顶点顺序方向),就用这个 FiguresColor(); DrawTriangle(ref triangle); if (cont) ResultsColor(); DrawPoint(point); LogInfo("Orientation: " + orientation + " Contained: " + cont); if (cont != cont1) Debug.LogError("cont != cont1"); } else // Degenerate { Debug.LogError("Triangle is degenerate"); } } void DrawTriangle(ref Triangle2 triangle) { Gizmos.DrawLine(triangle.V0, triangle.V1); Gizmos.DrawLine(triangle.V1, triangle.V2); Gizmos.DrawLine(triangle.V2, triangle.V0); } protected void DrawPoint(Vector2 position) { Gizmos.DrawSphere(position, _pointRadius); } protected void ResultsColor() { Gizmos.color = Color.blue; } protected void FiguresColor() { Gizmos.color = Color.gray; } protected void LogInfo(object value) { Debug.Log(value); }}
public enum Orientations{ CW, CCW, None}public struct Triangle2 { public Vector2 V0; public Vector2 V1; public Vector2 V2; public static Triangle2 CreateTriangle2(Transform v0, Transform v1, Transform v2) { return new Triangle2(v0.position, v1.position, v2.position); } public Triangle2(Vector2 v0, Vector2 v1, Vector2 v2) { this.V0 = v0; this.V1 = v1; this.V2 = v2; } public Orientations CalcOrientation(float threshold = 1E-05f) { float num = this.CalcDeterminant(); if (num > threshold) { return Orientations.CCW; } if (num < -threshold) { return Orientations.CW; } return Orientations.None; } public float CalcDeterminant() { return ((((((this.V1.x * this.V2.y) + (this.V0.x * this.V1.y)) + (this.V2.x * this.V0.y)) - (this.V1.x * this.V0.y)) - (this.V2.x * this.V1.y)) - (this.V0.x * this.V2.y)); } public bool Contains(ref Vector2 point) { bool flag = (((point.x - this.V1.x) * (this.V0.y - this.V1.y)) - ((point.y - this.V1.y) * (this.V0.x - this.V1.x))) < 0f; bool flag2 = (((point.x - this.V2.x) * (this.V1.y - this.V2.y)) - ((point.y - this.V2.y) * (this.V1.x - this.V2.x))) < 0f; if (flag != flag2) { return false; } bool flag3 = (((point.x - this.V0.x) * (this.V2.y - this.V0.y)) - ((point.y - this.V0.y) * (this.V2.x - this.V0.x))) < 0f; return (flag2 == flag3); } /// <summary> /// 当已经知道 三个顶点的顺序是逆时针方向的时候使用 /// </summary> /// <param name="point"></param> /// <returns></returns> public bool ContainsCCW(ref Vector2 point) { if ((((point.x - this.V0.x) * (this.V1.y - this.V0.y)) - ((point.y - this.V0.y) * (this.V1.x - this.V0.x))) > 0f) { return false; } if ((((point.x - this.V1.x) * (this.V2.y - this.V1.y)) - ((point.y - this.V1.y) * (this.V2.x - this.V1.x))) > 0f) { return false; } if ((((point.x - this.V2.x) * (this.V0.y - this.V2.y)) - ((point.y - this.V2.y) * (this.V0.x - this.V2.x))) > 0f) { return false; } return true; } /// <summary> /// 当已经知道 三个顶点的顺序是顺时针方向的时候使用 /// </summary> /// <param name="point"></param> /// <returns></returns> public bool ContainsCW(ref Vector2 point) { if ((((point.x - this.V0.x) * (this.V1.y - this.V0.y)) - ((point.y - this.V0.y) * (this.V1.x - this.V0.x))) < 0f) { return false; } if ((((point.x - this.V1.x) * (this.V2.y - this.V1.y)) - ((point.y - this.V1.y) * (this.V2.x - this.V1.x))) < 0f) { return false; } if ((((point.x - this.V2.x) * (this.V0.y - this.V2.y)) - ((point.y - this.V2.y) * (this.V0.x - this.V2.x))) < 0f) { return false; } return true; }}
5、 凸多边形内
public class Test_ContPoint2ConvexPolygon2 : MonoBehaviour { public Transform Point; public Transform[] ConvexPolygon; private const float _pointRadius = .11f; private void OnDrawGizmos() { Vector2 point = Point.position; Polygon2 convexPolygon = Polygon2.CreatePolygon2(ConvexPolygon); Orientations orientation; // 判断是凸状的不? bool convex = convexPolygon.IsConvex(out orientation); if (convex) { bool cont; if (orientation == Orientations.CCW) { cont = convexPolygon.ContainsConvexCCW(ref point); //cont = convexPolygon.ContainsConvexQuadCCW(point); // 如果你知道 方向(顶点顺序方向),就用这个 } else // CW { cont = convexPolygon.ContainsConvexCW(ref point); //cont = convexPolygon.ContainsConvexQuadCW(point); } FiguresColor(); DrawPolygon(convexPolygon); if (cont) ResultsColor(); DrawPoint(point); LogInfo("Orientation: " + orientation + " Contained: " + cont); } else { FiguresColor(); DrawPolygon(convexPolygon); DrawPoint(point); Debug.LogError("polygon is non-convex"); } } protected void DrawPolygon(Polygon2 polygon) { for (int i0 = 0, i1 = polygon.VertexCount - 1; i0 < polygon.VertexCount; i1 = i0, ++i0) { Gizmos.DrawLine(polygon[i0], polygon[i1]); } } protected void DrawPoint(Vector2 position) { Gizmos.DrawSphere(position, _pointRadius); } protected void ResultsColor() { Gizmos.color = Color.blue; } protected void FiguresColor() { Gizmos.color = Color.gray; } protected void LogInfo(object value) { Debug.Log(value); }}
public struct Edge2{ public Vector2 Point0; public Vector2 Point1; public Vector2 Direction; public Vector2 Normal; public float Length;}public static class Vector3ex{ public static Vector2 ToVector2XY(this Vector3 vector) { return new Vector2(vector.x, vector.y); }}public struct Polygon2 { private Edge2[] _edges; private Vector2[] _vertices; public Polygon2(int vertexCount) { this._vertices = new Vector2[vertexCount]; this._edges = new Edge2[vertexCount]; } public Vector2 this[int vertexIndex] { get { return this._vertices[vertexIndex]; } set { this._vertices[vertexIndex] = value; } } public int VertexCount { get { return this._vertices.Length; } } public static Polygon2 CreatePolygon2(Transform[] polygon) { Polygon2 result = new Polygon2(polygon.Length); for (int i = 0; i < polygon.Length; ++i) { result[i] = polygon[i].position.ToVector2XY(); } result.UpdateEdges(); return result; } public void UpdateEdges() { int length = this._vertices.Length; int index = length - 1; for (int i = 0; i < length; i++) { Vector2 vector = (this._edges[index].Point1 = this._vertices[i]) - (this._edges[index].Point0 = this._vertices[index]); this._edges[index].Length = Vector2ex.Normalize(ref vector, 1E-05f); this._edges[index].Direction = vector; this._edges[index].Normal = vector.Perp(); index = i; } } /// <summary> /// 判断当前是不是 凸 状的 /// </summary> /// <param name="orientation"></param> /// <param name="threshold"></param> /// <returns></returns> public bool IsConvex(out Orientations orientation, float threshold = 1E-05f) { orientation = Orientations.None; int length = this._edges.Length; int num2 = 0; int index = length - 1; for (int i = 0; i < length; i++) { Vector2 vector = -this._edges[index].Direction; Vector2 direction = this._edges[i].Direction; float num5 = vector.DotPerp(ref direction); int num6 = ((num5 < -threshold) || (num5 > threshold)) ? ((num5 > 0f) ? 1 : -1) : 0; if (num6 != 0) { if (num2 != 0) { if (((num2 > 0) && (num6 < 0)) || ((num2 < 0) && (num6 > 0))) { return false; } } else { num2 += num6; } } index = i; } orientation = (num2 == 0) ? Orientations.None : ((num2 > 0) ? Orientations.CW : Orientations.CCW); return (orientation != Orientations.None); } public bool ContainsConvexCCW(ref Vector2 point) { return this.SubContainsPointCCW(ref point, 0, 0); } public bool ContainsConvexCW(ref Vector2 point) { return this.SubContainsPointCW(ref point, 0, 0); } private bool SubContainsPointCCW(ref Vector2 p, int i0, int i1) { float num2; float num3; float num4; float num5; int num7; int length = this._vertices.Length; int num6 = i1 - i0; if ((num6 == 1) || ((num6 < 0) && ((num6 + length) == 1))) { num2 = this._vertices[i1].y - this._vertices[i0].y; num3 = this._vertices[i0].x - this._vertices[i1].x; num4 = p.x - this._vertices[i0].x; num5 = p.y - this._vertices[i0].y; return (((num2 * num4) + (num3 * num5)) <= 0f); } if (i0 < i1) { num7 = (i0 + i1) >> 1; } else { num7 = ((i0 + i1) + length) >> 1; if (num7 >= length) { num7 -= length; } } num2 = this._vertices[num7].y - this._vertices[i0].y; num3 = this._vertices[i0].x - this._vertices[num7].x; num4 = p.x - this._vertices[i0].x; num5 = p.y - this._vertices[i0].y; if (((num2 * num4) + (num3 * num5)) > 0f) { return this.SubContainsPointCCW(ref p, i0, num7); } return this.SubContainsPointCCW(ref p, num7, i1); } private bool SubContainsPointCW(ref Vector2 p, int i0, int i1) { float num2; float num3; float num4; float num5; int num7; int length = this._vertices.Length; int num6 = i1 - i0; if ((num6 == 1) || ((num6 < 0) && ((num6 + length) == 1))) { num2 = this._vertices[i1].y - this._vertices[i0].y; num3 = this._vertices[i0].x - this._vertices[i1].x; num4 = p.x - this._vertices[i0].x; num5 = p.y - this._vertices[i0].y; return (((num2 * num4) + (num3 * num5)) >= 0f); } if (i0 < i1) { num7 = (i0 + i1) >> 1; } else { num7 = ((i0 + i1) + length) >> 1; if (num7 >= length) { num7 -= length; } } num2 = this._vertices[num7].y - this._vertices[i0].y; num3 = this._vertices[i0].x - this._vertices[num7].x; num4 = p.x - this._vertices[i0].x; num5 = p.y - this._vertices[i0].y; if (((num2 * num4) + (num3 * num5)) < 0f) { return this.SubContainsPointCW(ref p, i0, num7); } return this.SubContainsPointCW(ref p, num7, i1); }}
public static class Vector2ex{ public static float Dot(this Vector2 vector, ref Vector2 value) { return ((vector.x * value.x) + (vector.y * value.y)); } public static float Normalize(ref Vector2 vector, float epsilon = 1E-05f) { float num = Mathf.Sqrt((vector.x * vector.x) + (vector.y * vector.y)); if (num >= epsilon) { float num2 = 1f / num; vector.x *= num2; vector.y *= num2; return num; } vector.x = 0f; vector.y = 0f; return 0f; } public static float DotPerp(this Vector2 vector, ref Vector2 value) { return ((vector.x * value.y) - (vector.y * value.x)); } public static Vector2 Perp(this Vector2 vector) { return new Vector2(vector.y, -vector.x); }}
6、 直接判断是否在多边形内。 凹多边形内 (其实不管是凹还是凸了)
public struct Edge2{ public Vector2 Point0; public Vector2 Point1; public Vector2 Direction; public Vector2 Normal; public float Length;}public static class Vector3ex{ public static Vector2 ToVector2XY(this Vector3 vector) { return new Vector2(vector.x, vector.y); }}public struct Polygon2 { private Edge2[] _edges; private Vector2[] _vertices; public Polygon2(int vertexCount) { this._vertices = new Vector2[vertexCount]; this._edges = new Edge2[vertexCount]; } public Vector2 this[int vertexIndex] { get { return this._vertices[vertexIndex]; } set { this._vertices[vertexIndex] = value; } } public int VertexCount { get { return this._vertices.Length; } } public static Polygon2 CreatePolygon2(Transform[] polygon) { Polygon2 result = new Polygon2(polygon.Length); for (int i = 0; i < polygon.Length; ++i) { result[i] = polygon[i].position.ToVector2XY(); } result.UpdateEdges(); return result; } public void UpdateEdges() { int length = this._vertices.Length; int index = length - 1; for (int i = 0; i < length; i++) { Vector2 vector = (this._edges[index].Point1 = this._vertices[i]) - (this._edges[index].Point0 = this._vertices[index]); this._edges[index].Length = Vector2ex.Normalize(ref vector, 1E-05f); this._edges[index].Direction = vector; this._edges[index].Normal = vector.Perp(); index = i; } } public bool ContainsSimple(ref Vector2 point) { bool flag = false; int length = this._vertices.Length; int index = 0; int num3 = length - 1; while (index < length) { float num4; float num5; Vector2 vector = this._vertices[index]; Vector2 vector2 = this._vertices[num3]; if (point.y < vector2.y) { if (vector.y <= point.y) { num5 = (point.y - vector.y) * (vector2.x - vector.x); num4 = (point.x - vector.x) * (vector2.y - vector.y); if (num5 > num4) { flag = !flag; } } } else if (point.y < vector.y) { num5 = (point.y - vector.y) * (vector2.x - vector.x); num4 = (point.x - vector.x) * (vector2.y - vector.y); if (num5 < num4) { flag = !flag; } } num3 = index; index++; } return flag; }}
[ExecuteInEditMode]public class Test_ContPoint2Polygon2 : MonoBehaviour{ public Transform Point; public Transform[] Polygon; private const float _pointRadius = .11f; private void OnDrawGizmos() { Vector2 point = Point.position; Polygon2 polygon = Polygon2.CreatePolygon2(Polygon); bool cont = polygon.ContainsSimple(ref point); FiguresColor(); DrawPolygon(polygon); if (cont) ResultsColor(); DrawPoint(point); LogInfo(cont); } protected void DrawPolygon(Polygon2 polygon) { for (int i0 = 0, i1 = polygon.VertexCount - 1; i0 < polygon.VertexCount; i1 = i0, ++i0) { Gizmos.DrawLine(polygon[i0], polygon[i1]); } } protected void DrawPoint(Vector2 position) { Gizmos.DrawSphere(position, _pointRadius); } protected void ResultsColor() { Gizmos.color = Color.blue; } protected void FiguresColor() { Gizmos.color = Color.gray; } protected void LogInfo(object value) { Debug.Log(value); }}
public static class Vector2ex{ public static float Normalize(ref Vector2 vector, float epsilon = 1E-05f) { float num = Mathf.Sqrt((vector.x * vector.x) + (vector.y * vector.y)); if (num >= epsilon) { float num2 = 1f / num; vector.x *= num2; vector.y *= num2; return num; } vector.x = 0f; vector.y = 0f; return 0f; } public static Vector2 Perp(this Vector2 vector) { return new Vector2(vector.y, -vector.x); }}
阅读全文
29 7
- C# 计算游戏技能攻击区域
- C# 计算游戏技能攻击区域
- MMO游戏技能攻击区域的计算
- MMO游戏技能攻击区域的计算3--效率分析
- 游戏服务端开发:如何精确计算MMO游戏技能攻击区域?
- MMO游戏技能攻击区域的计算2--给地图划分格子
- 角色技能攻击范围点区域显示
- 游戏中战斗伤害范围攻击计算完整全版
- Silverlight MMORPG网页游戏开发课程[一期] 第十三课:战斗系统之技能/魔法攻击
- 三角形攻击区域
- 求未被攻击的区域
- 攻击、技能冷却 关键代码
- nyistOJ 游戏AOE技能分析(1)自杀还是他杀?beta (计算几何)
- 游戏服务器之技能
- 游戏技能设计
- 游戏技能系统实现
- rpg游戏技能释放
- 云计算技能图谱
- [Java面试六]SpringMVC总结以及在面试中的一些问题.
- 总结
- Java String StringBuffer StringBuilder
- Java集合-HashMap(一)
- 实现Serializable接口的可序列化类中的serialVersionUID的含义
- C# 计算游戏技能攻击区域
- 基于深度学习的Person Re-ID(综述)
- js之script属性async与defer
- Android Studio 快捷键整理分享-SadieYu
- 【Luogu2900】土地征用(斜率优化,动态规划)
- 规范化-数据库设计原则
- C1 输入输出的各种注意事项&用法示例==
- 【JAVASE_学习笔记】抽象类与接口
- 201710222120->利用httplistener实现简易服务器(未含逻辑及数据库)