public void createItems(List <DanmakuItemData> itemDatas) { updateLastDanmakuList(); for (int i = 0; i < itemDatas.Count; i++) { GameObject go = GameObject.Instantiate(danmakuItemPrefab); //内容 DanmakuItem item = go.GetComponent <DanmakuItem>(); item.setContent(itemDatas[i]); DanmakuPositionData positionData = createNewDanmakuPostionData(item); go.transform.SetParent(displayArea.transform, false); go.transform.localPosition = getLocalPosition(positionData); //移动动画 NTween.TweenPosition animation = go.GetComponent <NTween.TweenPosition>(); animation.from = go.transform.localPosition; animation.to = go.transform.localPosition; animation.to.x = -(displayArea.rect.width + item.getWidth()) / 2; //速度和时间 float speed = 50f; animation.duration = (animation.from.x - animation.to.x) / speed; animation.PlayForward(); //移出屏幕后消失 animation.onFinishCallback = (tweener) => { tweener.transform.SetParent(null, false); GameObject.Destroy(tweener.gameObject); }; } }
//为新弹幕创建一个位置信息,itemHeight:新弹幕的高度 private DanmakuPositionData createNewDanmakuPostionData(DanmakuItem item) { int iter1 = 0; int iter2 = 0; int maxEndx = -1; int finalIter1 = 0; int finalIter2 = 0; int itemHeight = item.getHeight(); while (iter1 < _laskDanmakuList.Count && iter2 < _laskDanmakuList.Count) { while (iter2 < _laskDanmakuList.Count && _laskDanmakuList[iter1].yTop - _laskDanmakuList[iter2].yBottom < itemHeight) { iter2 = iter2 + 1; } //查找结束 if (iter2 >= _laskDanmakuList.Count) { break; } while (iter1 < iter2 && _laskDanmakuList[iter1 + 1].yTop - _laskDanmakuList[iter2].yBottom >= itemHeight) { iter1 = iter1 + 1; } //最大的endx int tempMaxEndx = 0; for (int i = iter1; i <= iter2; i++) { if (_laskDanmakuList[i].endX > tempMaxEndx) { tempMaxEndx = _laskDanmakuList[i].endX; } } if (maxEndx < 0 || tempMaxEndx < maxEndx) { maxEndx = tempMaxEndx; finalIter1 = iter1; finalIter2 = iter2; } iter2++; iter1++; } //插入数据 DanmakuPositionData data = new DanmakuPositionData(); data.item = item; data.yTop = _laskDanmakuList[finalIter1].yTop; data.yBottom = data.yTop - item.getHeight(); data.endX = maxEndx + item.getWidth(); _laskDanmakuList[finalIter2].yTop = data.yBottom; //删掉被覆盖的部分 if (_laskDanmakuList[finalIter2].yTop == _laskDanmakuList[finalIter2].yBottom) { _laskDanmakuList.RemoveAt(finalIter2); } iter2 = finalIter2 - 1; for (; iter2 >= finalIter1; iter2--) { _laskDanmakuList.RemoveAt(iter2); } _laskDanmakuList.Insert(finalIter1, data); return(data); }
//获取弹幕的最右侧相对于展示区域的最右侧的偏移 private int getEndX(DanmakuItem item) { int offsetX = (int)(displayArea.rect.width + item.getWidth()) / 2; return((int)item.transform.localPosition.x - offsetX + item.getWidth()); }