
1.制作障碍系统 (1.制作几种类型的障碍物的预制体 ((*.编写障碍物基类,以下几种均继承自基类,含碰撞体,RememberY(生成障碍物时该有多大的Y) ((1.矮障碍,仅碰撞体 ((2.高障碍,仅碰撞体 ((3.可冲破障碍 (((1.除基本碰撞体外,额外包含一个触发器,比碰撞体先检测到马,同时获取马的x速度,大于阈值则给障碍做破碎,用马的力度决定破碎力,关闭碎块和马的碰撞 (((*.导入某2D破碎插件 ((4.人马分离障碍 (((WAIT,需要等待人马分离系统先搭建 (2.编写障碍物生成系统 ((1.每若干时间,生成一个随机一种障碍,若干的范围可控 (((1.设计协程,从预制体列表中随机出一种,并在计算好的位置实例化,随后等待范围内的若干时间,然后检查马的存活情况,若马仍存活,重新调用本协程 ((2.生成的位置:x在相机右侧若干不变距离,y根据障碍物的不同而不同,需要计算保存。 (3.编写障碍物消亡系统 ((1.每个障碍物和碎片都会在离开镜头后被删除
147 lines
3.2 KiB
C#
147 lines
3.2 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
using Delaunay.Utils;
|
|
|
|
namespace Delaunay
|
|
{
|
|
|
|
internal sealed class HalfedgePriorityQueue: Utils.IDisposable // also known as heap
|
|
{
|
|
private Halfedge[] _hash;
|
|
private int _count;
|
|
private int _minBucket;
|
|
private int _hashsize;
|
|
|
|
private float _ymin;
|
|
private float _deltay;
|
|
|
|
public HalfedgePriorityQueue (float ymin, float deltay, int sqrt_nsites)
|
|
{
|
|
_ymin = ymin;
|
|
_deltay = deltay;
|
|
_hashsize = 4 * sqrt_nsites;
|
|
Initialize ();
|
|
}
|
|
|
|
public void Dispose ()
|
|
{
|
|
// get rid of dummies
|
|
for (int i = 0; i < _hashsize; ++i) {
|
|
_hash [i].Dispose ();
|
|
_hash [i] = null;
|
|
}
|
|
_hash = null;
|
|
}
|
|
|
|
private void Initialize ()
|
|
{
|
|
int i;
|
|
|
|
_count = 0;
|
|
_minBucket = 0;
|
|
_hash = new Halfedge[_hashsize];
|
|
// dummy Halfedge at the top of each hash
|
|
for (i = 0; i < _hashsize; ++i) {
|
|
_hash [i] = Halfedge.CreateDummy ();
|
|
_hash [i].nextInPriorityQueue = null;
|
|
}
|
|
}
|
|
|
|
public void Insert (Halfedge halfEdge)
|
|
{
|
|
Halfedge previous, next;
|
|
int insertionBucket = Bucket (halfEdge);
|
|
if (insertionBucket < _minBucket) {
|
|
_minBucket = insertionBucket;
|
|
}
|
|
previous = _hash [insertionBucket];
|
|
while ((next = previous.nextInPriorityQueue) != null
|
|
&& (halfEdge.ystar > next.ystar || (halfEdge.ystar == next.ystar && halfEdge.vertex.x > next.vertex.x))) {
|
|
previous = next;
|
|
}
|
|
halfEdge.nextInPriorityQueue = previous.nextInPriorityQueue;
|
|
previous.nextInPriorityQueue = halfEdge;
|
|
++_count;
|
|
}
|
|
|
|
public void Remove (Halfedge halfEdge)
|
|
{
|
|
Halfedge previous;
|
|
int removalBucket = Bucket (halfEdge);
|
|
|
|
if (halfEdge.vertex != null) {
|
|
previous = _hash [removalBucket];
|
|
while (previous.nextInPriorityQueue != halfEdge) {
|
|
previous = previous.nextInPriorityQueue;
|
|
}
|
|
previous.nextInPriorityQueue = halfEdge.nextInPriorityQueue;
|
|
_count--;
|
|
halfEdge.vertex = null;
|
|
halfEdge.nextInPriorityQueue = null;
|
|
halfEdge.Dispose ();
|
|
}
|
|
}
|
|
|
|
private int Bucket (Halfedge halfEdge)
|
|
{
|
|
int theBucket = (int)((halfEdge.ystar - _ymin) / _deltay * _hashsize);
|
|
if (theBucket < 0)
|
|
theBucket = 0;
|
|
if (theBucket >= _hashsize)
|
|
theBucket = _hashsize - 1;
|
|
return theBucket;
|
|
}
|
|
|
|
private bool IsEmpty (int bucket)
|
|
{
|
|
return (_hash [bucket].nextInPriorityQueue == null);
|
|
}
|
|
|
|
/**
|
|
* move _minBucket until it contains an actual Halfedge (not just the dummy at the top);
|
|
*
|
|
*/
|
|
private void AdjustMinBucket ()
|
|
{
|
|
while (_minBucket < _hashsize - 1 && IsEmpty(_minBucket)) {
|
|
++_minBucket;
|
|
}
|
|
}
|
|
|
|
public bool Empty ()
|
|
{
|
|
return _count == 0;
|
|
}
|
|
|
|
/**
|
|
* @return coordinates of the Halfedge's vertex in V*, the transformed Voronoi diagram
|
|
*
|
|
*/
|
|
public Vector2 Min ()
|
|
{
|
|
AdjustMinBucket ();
|
|
Halfedge answer = _hash [_minBucket].nextInPriorityQueue;
|
|
return new Vector2 (answer.vertex.x, answer.ystar);
|
|
}
|
|
|
|
/**
|
|
* remove and return the min Halfedge
|
|
* @return
|
|
*
|
|
*/
|
|
public Halfedge ExtractMin ()
|
|
{
|
|
Halfedge answer;
|
|
|
|
// get the first real Halfedge in _minBucket
|
|
answer = _hash [_minBucket].nextInPriorityQueue;
|
|
|
|
_hash [_minBucket].nextInPriorityQueue = answer.nextInPriorityQueue;
|
|
_count--;
|
|
answer.nextInPriorityQueue = null;
|
|
|
|
return answer;
|
|
}
|
|
|
|
}
|
|
} |