
1.制作障碍系统 (1.制作几种类型的障碍物的预制体 ((*.编写障碍物基类,以下几种均继承自基类,含碰撞体,RememberY(生成障碍物时该有多大的Y) ((1.矮障碍,仅碰撞体 ((2.高障碍,仅碰撞体 ((3.可冲破障碍 (((1.除基本碰撞体外,额外包含一个触发器,比碰撞体先检测到马,同时获取马的x速度,大于阈值则给障碍做破碎,用马的力度决定破碎力,关闭碎块和马的碰撞 (((*.导入某2D破碎插件 ((4.人马分离障碍 (((WAIT,需要等待人马分离系统先搭建 (2.编写障碍物生成系统 ((1.每若干时间,生成一个随机一种障碍,若干的范围可控 (((1.设计协程,从预制体列表中随机出一种,并在计算好的位置实例化,随后等待范围内的若干时间,然后检查马的存活情况,若马仍存活,重新调用本协程 ((2.生成的位置:x在相机右侧若干不变距离,y根据障碍物的不同而不同,需要计算保存。 (3.编写障碍物消亡系统 ((1.每个障碍物和碎片都会在离开镜头后被删除
175 lines
4.6 KiB
C#
175 lines
4.6 KiB
C#
using UnityEngine;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Delaunay.Geo;
|
|
using Delaunay.LR;
|
|
|
|
namespace Delaunay
|
|
{
|
|
|
|
public class Node
|
|
{
|
|
public static Stack<Node> pool = new Stack<Node> ();
|
|
|
|
public Node parent;
|
|
public int treeSize;
|
|
}
|
|
|
|
public enum KruskalType
|
|
{
|
|
MINIMUM,
|
|
MAXIMUM
|
|
}
|
|
|
|
public static class DelaunayHelpers
|
|
{
|
|
public static List<LineSegment> VisibleLineSegments (List<Edge> edges)
|
|
{
|
|
List<LineSegment> segments = new List<LineSegment> ();
|
|
|
|
for (int i = 0; i<edges.Count; i++) {
|
|
Edge edge = edges [i];
|
|
if (edge.visible) {
|
|
Nullable<Vector2> p1 = edge.clippedEnds [Side.LEFT];
|
|
Nullable<Vector2> p2 = edge.clippedEnds [Side.RIGHT];
|
|
segments.Add (new LineSegment (p1, p2));
|
|
}
|
|
}
|
|
|
|
return segments;
|
|
}
|
|
|
|
public static List<Edge> SelectEdgesForSitePoint (Vector2 coord, List<Edge> edgesToTest)
|
|
{
|
|
return edgesToTest.FindAll (delegate (Edge edge) {
|
|
return ((edge.leftSite != null && edge.leftSite.Coord == coord)
|
|
|| (edge.rightSite != null && edge.rightSite.Coord == coord));
|
|
});
|
|
}
|
|
|
|
public static List<Edge> SelectNonIntersectingEdges (/*keepOutMask:BitmapData,*/List<Edge> edgesToTest)
|
|
{
|
|
// if (keepOutMask == null)
|
|
// {
|
|
return edgesToTest;
|
|
// }
|
|
|
|
// var zeroPoint:Point = new Point();
|
|
// return edgesToTest.filter(myTest);
|
|
//
|
|
// function myTest(edge:Edge, index:int, vector:Vector.<Edge>):Boolean
|
|
// {
|
|
// var delaunayLineBmp:BitmapData = edge.makeDelaunayLineBmp();
|
|
// var notIntersecting:Boolean = !(keepOutMask.hitTest(zeroPoint, 1, delaunayLineBmp, zeroPoint, 1));
|
|
// delaunayLineBmp.dispose();
|
|
// return notIntersecting;
|
|
// }
|
|
}
|
|
|
|
public static List<LineSegment> DelaunayLinesForEdges (List<Edge> edges)
|
|
{
|
|
List<LineSegment> segments = new List<LineSegment> ();
|
|
Edge edge;
|
|
for (int i = 0; i < edges.Count; i++) {
|
|
edge = edges [i];
|
|
segments.Add (edge.DelaunayLine ());
|
|
}
|
|
return segments;
|
|
}
|
|
|
|
/**
|
|
* Kruskal's spanning tree algorithm with union-find
|
|
* Skiena: The Algorithm Design Manual, p. 196ff
|
|
* Note: the sites are implied: they consist of the end points of the line segments
|
|
*/
|
|
public static List<LineSegment> Kruskal (List<LineSegment> lineSegments, KruskalType type = KruskalType.MINIMUM)
|
|
{
|
|
Dictionary<Nullable<Vector2>,Node> nodes = new Dictionary<Nullable<Vector2>,Node> ();
|
|
List<LineSegment> mst = new List<LineSegment> ();
|
|
Stack<Node> nodePool = Node.pool;
|
|
|
|
switch (type) {
|
|
// note that the compare functions are the reverse of what you'd expect
|
|
// because (see below) we traverse the lineSegments in reverse order for speed
|
|
case KruskalType.MAXIMUM:
|
|
lineSegments.Sort (delegate (LineSegment l1, LineSegment l2) {
|
|
return LineSegment.CompareLengths (l1, l2);
|
|
});
|
|
break;
|
|
default:
|
|
lineSegments.Sort (delegate (LineSegment l1, LineSegment l2) {
|
|
return LineSegment.CompareLengths_MAX (l1, l2);
|
|
});
|
|
break;
|
|
}
|
|
|
|
for (int i = lineSegments.Count; --i > -1;) {
|
|
LineSegment lineSegment = lineSegments [i];
|
|
|
|
Node node0 = null;
|
|
Node rootOfSet0;
|
|
if (!nodes.ContainsKey (lineSegment.p0)) {
|
|
node0 = nodePool.Count > 0 ? nodePool.Pop () : new Node ();
|
|
// intialize the node:
|
|
rootOfSet0 = node0.parent = node0;
|
|
node0.treeSize = 1;
|
|
|
|
nodes [lineSegment.p0] = node0;
|
|
} else {
|
|
node0 = nodes [lineSegment.p0];
|
|
rootOfSet0 = Find (node0);
|
|
}
|
|
|
|
Node node1 = null;
|
|
Node rootOfSet1;
|
|
if (!nodes.ContainsKey (lineSegment.p1)) {
|
|
node1 = nodePool.Count > 0 ? nodePool.Pop () : new Node ();
|
|
// intialize the node:
|
|
rootOfSet1 = node1.parent = node1;
|
|
node1.treeSize = 1;
|
|
|
|
nodes [lineSegment.p1] = node1;
|
|
} else {
|
|
node1 = nodes [lineSegment.p1];
|
|
rootOfSet1 = Find (node1);
|
|
}
|
|
|
|
if (rootOfSet0 != rootOfSet1) { // nodes not in same set
|
|
mst.Add (lineSegment);
|
|
|
|
// merge the two sets:
|
|
int treeSize0 = rootOfSet0.treeSize;
|
|
int treeSize1 = rootOfSet1.treeSize;
|
|
if (treeSize0 >= treeSize1) {
|
|
// set0 absorbs set1:
|
|
rootOfSet1.parent = rootOfSet0;
|
|
rootOfSet0.treeSize += treeSize1;
|
|
} else {
|
|
// set1 absorbs set0:
|
|
rootOfSet0.parent = rootOfSet1;
|
|
rootOfSet1.treeSize += treeSize0;
|
|
}
|
|
}
|
|
}
|
|
foreach (Node node in nodes.Values) {
|
|
nodePool.Push (node);
|
|
}
|
|
|
|
return mst;
|
|
}
|
|
|
|
private static Node Find (Node node)
|
|
{
|
|
if (node.parent == node) {
|
|
return node;
|
|
} else {
|
|
Node root = Find (node.parent);
|
|
// this line is just to speed up subsequent finds by keeping the tree depth low:
|
|
node.parent = root;
|
|
return root;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
} |