Ejemplo n.º 1
0
    // 移動を終了するノードの位置を調整する
    void AdjustNodeStop()
    {
        ////Log.Debug("AdjustNodeStop");
        Vec2Int nearNodeID = SearchNearNode(gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position);
        Vec2Int nextNodeID = SearchLimitNode(tapNodeID, ConvertSlideDirToLinkDir(slideDir));
        _eSlideDir reverseDir = ReverseDirection(slideDir);
        Vector2 pos = new Vector2(gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position.x, gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position.y);
        Vector2 standardPos = new Vector2(nodePlacePosList[nearNodeID.y][nearNodeID.x].x, nodePlacePosList[nearNodeID.y][nearNodeID.x].y);

        // スライド方向を更新
        if (pos.x != standardPos.x || pos.y != standardPos.y)
        {
            _eSlideDir checkDir = CheckSlideDir(pos, standardPos);
            if (slideDir != checkDir)
            {
                slideDir = checkDir;

                Vec2Int tmp = slidingLimitNodeID;
                slidingLimitNodeID = slidingReverseLimitNodeID;
                slidingReverseLimitNodeID = tmp;
            }
        }

        // スライド方向のノードに、スライド終了を通知
        while (nextNodeID.x > -1)
        {
            gameNodeScripts[nextNodeID.y][nextNodeID.x].EndSlide();
            nextNodeID = GetDirNode(nextNodeID, reverseDir);
        }

        // 回り込み処理
        CheckSlideOutLimitNode();
        LoopBackNode();

        // 移動処理
        switch (slideDir)
        {
            case _eSlideDir.LEFT:
            case _eSlideDir.RIGHT:
                pos = standardPos;

                // タップしているノードを移動
                gameNodeScripts[tapNodeID.y][tapNodeID.x].SlideNode(slideDir, standardPos);

                // タップしているノードより左側のノードを移動
                nextNodeID = GetDirNode(tapNodeID, _eLinkDir.L);
                for (int i = 1; nextNodeID.x > -1; ++i)
                {
                    pos.x = standardPos.x - moveNodeDistAbs.x * i;
                    gameNodeScripts[nextNodeID.y][nextNodeID.x].SlideNode(slideDir, pos);
                    nextNodeID = GetDirNode(nextNodeID, _eLinkDir.L);
                }
                // タップしているノードより右側のノードを移動
                nextNodeID = GetDirNode(tapNodeID, _eLinkDir.R);
                for (int i = 1; nextNodeID.x > -1; ++i)
                {
                    pos.x = standardPos.x + moveNodeDistAbs.x * i;
                    gameNodeScripts[nextNodeID.y][nextNodeID.x].SlideNode(slideDir, pos);
                    nextNodeID = GetDirNode(nextNodeID, _eLinkDir.R);
                }

                break;

            case _eSlideDir.LEFTUP:
            case _eSlideDir.RIGHTDOWN:
                // タップしているノードを移動
                gameNodeScripts[tapNodeID.y][tapNodeID.x].SlideNode(slideDir, standardPos);

                // タップしているノードより左上側のノードを移動
                nextNodeID = GetDirNode(tapNodeID, _eLinkDir.LU);
                for (int i = 1; nextNodeID.x > -1; ++i)
                {
                    pos.x = standardPos.x - moveNodeDistAbs.x * i;
                    pos.y = standardPos.y + moveNodeDistAbs.y * i;
                    gameNodeScripts[nextNodeID.y][nextNodeID.x].SlideNode(slideDir, pos);
                    nextNodeID = GetDirNode(nextNodeID, _eLinkDir.LU);
                }
                // タップしているノードより右下側のノードを移動
                nextNodeID = GetDirNode(tapNodeID, _eLinkDir.RD);
                for (int i = 1; nextNodeID.x > -1; ++i)
                {
                    pos.x = standardPos.x + moveNodeDistAbs.x * i;
                    pos.y = standardPos.y - moveNodeDistAbs.y * i;
                    gameNodeScripts[nextNodeID.y][nextNodeID.x].SlideNode(slideDir, pos);
                    nextNodeID = GetDirNode(nextNodeID, _eLinkDir.RD);
                }
                break;

            case _eSlideDir.RIGHTUP:
            case _eSlideDir.LEFTDOWN:
                // タップしているノードを移動
                gameNodeScripts[tapNodeID.y][tapNodeID.x].SlideNode(slideDir, standardPos);

                // タップしているノードより右上側のノードを移動
                nextNodeID = GetDirNode(tapNodeID, _eLinkDir.RU);
                for (int i = 1; nextNodeID.x > -1; ++i)
                {
                    pos.x = standardPos.x + moveNodeDistAbs.x * i;
                    pos.y = standardPos.y + moveNodeDistAbs.y * i;
                    gameNodeScripts[nextNodeID.y][nextNodeID.x].SlideNode(slideDir, pos);
                    nextNodeID = GetDirNode(nextNodeID, _eLinkDir.RU);
                }
                // タップしているノードより左下側のノードを移動
                nextNodeID = GetDirNode(tapNodeID, _eLinkDir.LD);
                for (int i = 1; nextNodeID.x > -1; ++i)
                {
                    pos.x = standardPos.x - moveNodeDistAbs.x * i;
                    pos.y = standardPos.y - moveNodeDistAbs.y * i;
                    gameNodeScripts[nextNodeID.y][nextNodeID.x].SlideNode(slideDir, pos);
                    nextNodeID = GetDirNode(nextNodeID, _eLinkDir.LD);
                }
                break;

            default:
                break;
        }
    }
Ejemplo n.º 2
0
    //移動したいノードを確定
    //ドラッグを算出し移動したい方向列を確定
    //ドラッグされている間、列ごと移動、
    //タップ点からスワイプ地点まで座標の差分を算出し
    //列のすべてのノードをその位置へ移動させる
    //離すと一番近いノード確定位置まで調整
    public void StartSlideNodes(Vec2Int nextNodeID, _eSlideDir newSlideDir)
    {
        ////Log.Debug("StartSlideNodes : " + nextNodeID + " / " + newSlideDir);
        moveNodeDist = new Vector2(gameNodePrefabs[nextNodeID.y][nextNodeID.x].transform.position.x, gameNodePrefabs[nextNodeID.y][nextNodeID.x].transform.position.y)
                     - new Vector2(gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position.x, gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position.y);   // スライド方向ベクトル兼移動量を算出
        moveNodeInitPos = gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position;      // ノードの移動開始位置を保存

        // スライド方向を設定
        slideDir = newSlideDir;

        // 絶対値を算出
        moveNodeDistAbs.x = Mathf.Abs(moveNodeDist.x);
        moveNodeDistAbs.y = Mathf.Abs(moveNodeDist.y);

        // スライド開始準備
        Vec2Int nextID = SearchLimitNode(tapNodeID, ConvertSlideDirToLinkDir(slideDir));
        _eSlideDir reverseDir = ReverseDirection(slideDir);
        while (nextID.x > -1)
        {
            gameNodeScripts[nextID.y][nextID.x].StartSlide();
            nextID = GetDirNode(nextID, reverseDir);
        }

        // スライド方向の端のノードIDを算出
        slidingLimitNodeID = SearchLimitNode(tapNodeID, ConvertSlideDirToLinkDir(slideDir));
        slidingReverseLimitNodeID = SearchLimitNode(tapNodeID, ConvertSlideDirToLinkDir(ReverseDirection(slideDir)));

        // タップしているノードの位置と、タップしている位置との距離を算出
        tapPosMoveNodePosDist = moveNodeDist.normalized * Vector2.Dot(moveNodeDist.normalized, startTapPos - moveNodeInitPos);
    }
Ejemplo n.º 3
0
    // タップ位置から、タップしているノードの、移動ライン上の座標を算出する
    Vector2 AdjustNodeLinePosition(_eSlideDir dir)
    {
        //Log.Debug("AdjustNodeLinePosition : " + dir);
        Vector2 adjustPos = tapPos;
        Vector2 slideDist = tapPos - startTapPos;     // スライド量
        Vector2 moveDist = moveNodeDist.normalized * Vector2.Dot(moveNodeDist.normalized, slideDist);      // 斜め移動量

        switch (slideDir)
        {
            case _eSlideDir.LEFT:
            case _eSlideDir.RIGHT:
                // タップしているノードの位置を調整
                //adjustPos = AdjustGameScreen(tapPos);
                adjustPos.y = gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position.y;
                break;

            case _eSlideDir.LEFTUP:
            case _eSlideDir.RIGHTDOWN:
                // タップしているノードの位置を調整
                Vec2Int lu = SearchLimitNode(tapNodeID, _eLinkDir.LU);
                Vec2Int rd = SearchLimitNode(tapNodeID, _eLinkDir.RD);
                adjustPos = moveNodeInitPos + moveDist + tapPosMoveNodePosDist;
                if (adjustPos.x < nodePlacePosList[lu.y][lu.x].x)
                    adjustPos.x = nodePlacePosList[lu.y][lu.x].x;
                if (adjustPos.x > nodePlacePosList[rd.y][rd.x].x)
                    adjustPos.x = nodePlacePosList[rd.y][rd.x].x;
                if (adjustPos.y > nodePlacePosList[lu.y][lu.x].y)
                    adjustPos.y = nodePlacePosList[lu.y][lu.x].y;
                if (adjustPos.y < nodePlacePosList[rd.y][rd.x].y)
                    adjustPos.y = nodePlacePosList[rd.y][rd.x].y;
                break;

            case _eSlideDir.RIGHTUP:
            case _eSlideDir.LEFTDOWN:
                // タップしているノードの位置を調整
                Vec2Int ru = SearchLimitNode(tapNodeID, _eLinkDir.RU);
                Vec2Int ld = SearchLimitNode(tapNodeID, _eLinkDir.LD);
                adjustPos = moveNodeInitPos + moveDist + tapPosMoveNodePosDist;
                if (adjustPos.x > nodePlacePosList[ru.y][ru.x].x)
                    adjustPos.x = nodePlacePosList[ru.y][ru.x].x;
                if (adjustPos.x < nodePlacePosList[ld.y][ld.x].x)
                    adjustPos.x = nodePlacePosList[ld.y][ld.x].x;
                if (adjustPos.y > nodePlacePosList[ru.y][ru.x].y)
                    adjustPos.y = nodePlacePosList[ru.y][ru.x].y;
                if (adjustPos.y < nodePlacePosList[ld.y][ld.x].y)
                    adjustPos.y = nodePlacePosList[ld.y][ld.x].y;
                break;

            default:
                break;
        }

        return adjustPos;
    }
Ejemplo n.º 4
0
    //位置と方向から、指定ノードに隣り合うノードのrowとcolを返す
    //なければ、(-1,-1)を返す
    // フレームノードを除く
    public Vec2Int GetDirNodeRemoveFrame(int x, int y, _eSlideDir toSlideDir)
    {
        _eLinkDir toDir = ConvertSlideDirToLinkDir(toSlideDir);

        return GetDirNodeRemoveFrame(x, y, toDir);
    }
Ejemplo n.º 5
0
 //位置と方向から、指定ノードに隣り合うノードのrowとcolを返す
 //なければ、(-1,-1)を返す
 // フレームノードを除く
 public Vec2Int GetDirNodeRemoveFrame(Vec2Int nodeID, _eSlideDir toSlideDir)
 {
     return GetDirNodeRemoveFrame(nodeID.x, nodeID.y, toSlideDir);
 }
Ejemplo n.º 6
0
    // Use this for initialization
    void Start()
    {
        ////Log.Debug("Start");

        //音声データを取得 添字をenum化すべきか
        audioSources = GetComponents<AudioSource>();
        /*if (audioSources.Length != (int)_eAudioNumber.MAX)
            print("音声取得に失敗");*/

        // ----- プレハブデータを Resources から取得
        gameNodePrefab = Resources.Load<GameObject>(gameNodePrefabPath);
        frameNodePrefab = Resources.Load<GameObject>(frameNodePrefabPath);
        gameArrowPrefab = Resources.Load<GameObject>(gameArrowPrefabPath);

        // ----- スプライトデータを Resources から取得
        gameNodeSprite = Resources.LoadAll<Sprite>(gameNodeSpritePath);
        nodeMaskSprite = Resources.LoadAll<Sprite>(nodeMaskSpritePath);
        frameNodeSprite = Resources.LoadAll<Sprite>(frameNodeSpritePath);

        // GameEffect スクリプトを取得
        gameEffect = transform.GetComponent<GameEffect>();

        // ----- ノード準備
        NodeTemplate.AllCalc(NodeTemp);
        InitNode();
        //開始演出が終わるまでは操作を受け付けない
        SetSlideAll(true);

        // スライドベクトルの垂線を算出
        Vector3 leftUp = gameNodePrefabs[0][1].transform.position - gameNodePrefabs[0][0].transform.position;
        Vector3 leftDown = gameNodePrefabs[1][1].transform.position - gameNodePrefabs[0][0].transform.position;
        Matrix4x4 mtx = Matrix4x4.identity;
        mtx.SetTRS(new Vector3(0.0f, 0.0f, 0.0f), Quaternion.Euler(0.0f, 0.0f, 90.0f), new Vector3(1.0f, 1.0f, 1.0f));
        leftUp = mtx.MultiplyVector(leftUp).normalized;
        leftDown = mtx.MultiplyVector(leftDown).normalized;
        slideLeftUpPerNorm = new Vector2(leftUp.x, leftUp.y);
        slideLeftDownPerNorm = new Vector2(leftDown.x, leftDown.y);

        // SE準備
        cumSlideIntervalPlaySE = 0.0f;

        // ----- インプット処理
        Observable
            .EveryUpdate()
            .Where(_ => Input.GetMouseButton(0))
            .Subscribe(_ => {
                // タップに成功していなければ未処理
                if (!isTap)
                {
                    return;
                }
                Vector3 worldTapPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

                // スライド処理
                if (isSlide)
                {
                    prevTapPos = tapPos;
                    tapPos = new Vector2(worldTapPos.x, worldTapPos.y);

                    SlideNodes();
                    CheckSlideOutLimitNode();
                    LoopBackNode();

                    return;
                }

                // スライド判定
                if (tapNodeID.x > -1 && startTapPos != (Vector2)worldTapPos)
                {
                    _eSlideDir dir = CheckSlideDir(startTapPos, new Vector2(worldTapPos.x, worldTapPos.y));
                    Vec2Int nextNodeID = GetDirNode(tapNodeID, dir);
                    if (nextNodeID.x > -1)
                    {
                        if (Vector3.Distance(gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position, worldTapPos) >
                            Vector3.Distance(gameNodePrefabs[nextNodeID.y][nextNodeID.x].transform.position, worldTapPos))
                        {
                            isSlide = true;
                            _isNodeAction = true;
                            StartSlideNodes(nextNodeID, dir);
                        }
                    }
                }
            })
            .AddTo(this.gameObject);
        Observable
            .EveryUpdate()
            .Where(_ => Input.GetMouseButtonDown(0))
            .Subscribe(_ => {
                // スライド中なら未処理
                if (isSlide)
                    return;
                if (pauseScript.pauseState == _ePauseState.PAUSE)
                    return;

                if (levelControllerScript.LevelState != _eLevelState.STAND)
                    return;

                // タップ成功
                isTap = true;
                ////Log.Debug("MouseButtonDown");

                Vector3 worldTapPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                startTapPos = new Vector2(worldTapPos.x, worldTapPos.y);

                // タップしているノードのIDを検索
                tapNodeID = SearchNearNodeRemoveFrame(worldTapPos);
            })
            .AddTo(this.gameObject);
        Observable
            .EveryUpdate()
            .Where(_ => Input.GetMouseButtonUp(0))
            .Subscribe(_ => TapRelease()/*{
                // タップに成功していなければ未処理
                if (!isTap)
                    return;

                // タップ終了
                isTap = false;
                //Log.Debug("MouseButtonUp");

                if (isSlide)
                {
                    AdjustNodeStop();
                    isSlideEnd = true;
                    tapNodeID = Vec2Int.zero;
                }
                else {
                    if (tapNodeID.x > -1)
                    {
                        audioSources[(int)_eAudioNumber.ROTATE].Play();
                        gameNodeScripts[tapNodeID.y][tapNodeID.x].RotationNode();
                        _isNodeAction = true;
                    }
                }
            }*/)
            .AddTo(gameObject);

        // ノードのアニメーション終了と同時に接続チェック
        Observable
            .EveryUpdate()
            .Select(x =>  !(IsNodeAction) && !(isNodeLock))
            .DistinctUntilChanged()
            .Where(x => x)
            .ThrottleFrame(3)
            .Subscribe(x => {
                CheckLink();
            })
            .AddTo(gameObject);

        // ノードがアクション中かチェック
        Observable
            .EveryUpdate()
            .Where(_ => _isNodeAction)
            .Subscribe(_ => {
                for (int i = 0; i < col; ++i)
                {
                    foreach (var nodes in gameNodeScripts[i])
                    {
                        if (nodes.IsAction)
                            return;
                    }
                }
                _isNodeAction = false;
            })
            .AddTo(gameObject);

        // ノードがスライド終了処理中かチェック
        Observable
            .EveryUpdate()
            .Where(_ => isSlideEnd)
            .Subscribe(_ => {
                for (int i = 0; i < col; ++i)
                {
                    foreach (var nodes in gameNodeScripts[i])
                    {
                        if (nodes.IsSlideEnd)
                        {
                            return;
                        }
                    }
                }
                isSlideEnd = false;
                if (isSlide)
                {
                    isSlide = false;
                    slideDir = _eSlideDir.NONE;

                    cumSlideIntervalPlaySE = 0.0f;
                }
            })
            .AddTo(gameObject);

        // SE再生処理
        Observable
            .EveryUpdate()
            .Where(_ => isSlide)
            .Subscribe(_ => {
                if(cumSlideIntervalPlaySE > slideIntervalPlaySE) {
                    audioSources[(int)_eAudioNumber.SLIDE].Play();

                    cumSlideIntervalPlaySE = 0.0f;
                }
            })
            .AddTo(gameObject);

        Observable
            .NextFrame()
            .Subscribe(_ => CheckLink(true, true))
            .AddTo(this);
    }
Ejemplo n.º 7
0
    // ノードのスライド移動処理
    void SlideNodes()
    {
        ////Log.Debug("SlideNodes");
        // スライド対象となるノードの準備
        Vector2 deltaSlideDist = tapPos - prevTapPos;   // 前回フレームからのスライド量
        float checkDir = 0.0f;                          // スライド方向チェック用

        switch (slideDir)
        {
            case _eSlideDir.LEFT:
            case _eSlideDir.RIGHT:
                // スライド方向を再計算
                if (tapPos.x - prevTapPos.x < 0.0f)
                {
                    // スライド方向が前フレームと違ったら更新
                    if (slideDir != _eSlideDir.LEFT)
                    {
                        Vec2Int tmp = slidingLimitNodeID;
                        slidingLimitNodeID = slidingReverseLimitNodeID;
                        slidingReverseLimitNodeID = tmp;

                        slideDir = _eSlideDir.LEFT;
                    }
                }
                else if (tapPos.x - prevTapPos.x > 0.0f)
                {
                    if (slideDir != _eSlideDir.RIGHT)
                    {
                        Vec2Int tmp = slidingLimitNodeID;
                        slidingLimitNodeID = slidingReverseLimitNodeID;
                        slidingReverseLimitNodeID = tmp;

                        slideDir = _eSlideDir.RIGHT;
                    }
                }

                break;

            case _eSlideDir.LEFTUP:
            case _eSlideDir.RIGHTDOWN:
                // スライド方向を再計算
                checkDir = AddVectorFunctions.Vec2Cross(deltaSlideDist, slideLeftUpPerNorm);
                if (checkDir < 0.0f)
                {
                    if (slideDir != _eSlideDir.LEFTUP)
                    {
                        Vec2Int tmp = slidingLimitNodeID;
                        slidingLimitNodeID = slidingReverseLimitNodeID;
                        slidingReverseLimitNodeID = tmp;

                        slideDir = _eSlideDir.LEFTUP;
                    }
                }
                else if (checkDir > 0.0f)
                {
                    if (slideDir != _eSlideDir.RIGHTDOWN)
                    {
                        Vec2Int tmp = slidingLimitNodeID;
                        slidingLimitNodeID = slidingReverseLimitNodeID;
                        slidingReverseLimitNodeID = tmp;

                        slideDir = _eSlideDir.RIGHTDOWN;
                    }
                }

                break;

            case _eSlideDir.RIGHTUP:
            case _eSlideDir.LEFTDOWN:
                // スライド方向を再計算
                checkDir = AddVectorFunctions.Vec2Cross(deltaSlideDist, slideLeftDownPerNorm);
                if (checkDir < 0.0f)
                {
                    if (slideDir != _eSlideDir.LEFTDOWN)
                    {
                        Vec2Int tmp = slidingLimitNodeID;
                        slidingLimitNodeID = slidingReverseLimitNodeID;
                        slidingReverseLimitNodeID = tmp;

                        slideDir = _eSlideDir.LEFTDOWN;
                    }
                }
                else if (checkDir > 0.0f)
                {
                    if (slideDir != _eSlideDir.RIGHTUP)
                    {
                        Vec2Int tmp = slidingLimitNodeID;
                        slidingLimitNodeID = slidingReverseLimitNodeID;
                        slidingReverseLimitNodeID = tmp;

                        slideDir = _eSlideDir.RIGHTUP;
                    }
                }

                break;

            default:
                break;
        }

        // ノードを移動
        AdjustSlideNodePosition();
    }
Ejemplo n.º 8
0
    // スライド方向の逆方向を求める
    _eSlideDir ReverseDirection(_eSlideDir dir)
    {
        _eSlideDir reverse = _eSlideDir.NONE;

        switch (dir)
        {
            case _eSlideDir.LEFT:
                reverse = _eSlideDir.RIGHT;
                break;
            case _eSlideDir.RIGHT:
                reverse = _eSlideDir.LEFT;
                break;
            case _eSlideDir.LEFTUP:
                reverse = _eSlideDir.RIGHTDOWN;
                break;
            case _eSlideDir.LEFTDOWN:
                reverse = _eSlideDir.RIGHTUP;
                break;
            case _eSlideDir.RIGHTUP:
                reverse = _eSlideDir.LEFTDOWN;
                break;
            case _eSlideDir.RIGHTDOWN:
                reverse = _eSlideDir.LEFTUP;
                break;
        }

        return reverse;
    }
Ejemplo n.º 9
0
    // _eSlideDir を _eLinkDir に変換する
    _eLinkDir ConvertSlideDirToLinkDir(_eSlideDir dir)
    {
        _eLinkDir convert = _eLinkDir.NONE;

        switch (dir)
        {
            case _eSlideDir.LEFT:
                convert = _eLinkDir.L;
                break;
            case _eSlideDir.RIGHT:
                convert = _eLinkDir.R;
                break;
            case _eSlideDir.LEFTUP:
                convert = _eLinkDir.LU;
                break;
            case _eSlideDir.LEFTDOWN:
                convert = _eLinkDir.LD;
                break;
            case _eSlideDir.RIGHTUP:
                convert = _eLinkDir.RU;
                break;
            case _eSlideDir.RIGHTDOWN:
                convert = _eLinkDir.RD;
                break;
        }

        return convert;
    }
Ejemplo n.º 10
0
Archivo: Node.cs Proyecto: GotoK/H401
    // ノード移動処理
    public void SlideNode(_eSlideDir dir, Vector2 pos)
    {
        // スライド方向が指定されていなければ未処理
        if (dir == _eSlideDir.NONE)
            return;

        // アクション開始
        IsSlide = true;

        transform.DOKill();

        float time = 0.0f;
        if (IsSlideStart)
        {
            time = slideStartTime;
            transform.DOMoveZ(IN_ACTION_POSZ, 0.0f);
        }
        else if (IsSlideEnd)
        {
            time = slideEndTime;
        }
        else {
            time = slideTime;
        }

        transform.DOMoveX(pos.x, time)
            .OnComplete(() => {
                IsSlide = false;
                if (IsSlideStart)
                    IsSlideStart = false;
                if (IsSlideEnd)
                {
                    IsSlideEnd = false;
                    transform.DOMoveZ(0.0f, 0.0f);
                }
            });
        transform.DOMoveY(pos.y, time);
    }