public void MoveLeftRight(bool left, BallStateType stateFrom) { Vector2 direction = left?m_LeftVector:m_RightVector; // куда двигаемся? влево или вправо m_moveVectors.Clear(); // очищаем очередь движений m_moveBackVectors.Clear(); // очищаем очередь обратных движений Vector2 pos = new Vector2(transform.position.x, transform.position.y); //текущая позиция Игрока int column = (int)((pos.x + m_RightX) / m_CellSide); // текущая колонка float len = 0.0f; // длина на которую нужно передвинуть Игрока float newX = 0.0f; // новая позиция по Х if (left) { newX = m_LeftX + (column - 1) * m_CellSide + m_CellSide / 2; } else { newX = m_LeftX + (column + 1) * m_CellSide + m_CellSide / 2; } len = (pos - new Vector2(newX, pos.y)).magnitude; int cnt = (int)(len / LeftRightSpeed) + 1; // кол-во кадров для передвижения const float maxX = 1.0f; // макс. знач. Х для расчета траектории по формуле (в масштабе) float d = maxX / cnt; // шаг изм. Х за один кадр в масштабе float x = 0; float y = 0.0f; if (!PreLeftRight(stateFrom)) { return; } float posX = pos.x; while (cnt > 0) { x += d; y = 0.5f * x; //y = x * (1 - x); //y = Mathf.Sin(x); if (x > maxX / 2) { y = -y; } if (x == maxX / 2) { y = 0; } Vector2 mov = direction + new Vector2(0, y); posX += LeftRightSpeed; float speed = LeftRightSpeed; if (posX > (pos.x + len)) { speed = LeftRightSpeed - (posX - (pos.x + len)); } m_moveVectors.Enqueue(new MoveInfo(mov, speed)); cnt--; } }
MoveInfo m_moveVector; //текущий вектор для движения public void SetState(BallStateType type) // метод для изменения состояния { if (m_States.ContainsKey(type)) // если тип сотояния есть в списке доступных { m_State = m_States[type]; // то устаналвиваем ссылку на этот тип. m_State.UpdateParams(); } }
bool PreLeftRight(BallStateType stateFrom) // функция предварительных расчетов перед полетом влево или право { Vector2 pos = new Vector2(transform.position.x, transform.position.y); // теущая позиция игрока float H = pos.y + m_UpY; // сдвиг координатной сетки на позиции (0,0). int level = (int)(H / m_CellSide); // текущий уровень игрока (0 - первый). float h = m_CellSide * level; // У координата полки текущего уровня float hH = H - h; // позиция по У Игрока относительно полки float moveLen = 0; // растояние сдвига игрока небоходимое для переноса в центр ячейки (иницализировано в 0) Vector2 movVector = upVector; // вектор для направления сдвига (инициализировано в вектор- вверх) float halfCell = m_CellSide / 2; if (hH > halfCell) // если позиция Игрока относительно полки больше половины ячейки { if (stateFrom != BallStateType.JUMP) // если Игрок не в состоянии прыжка { if (!ObstacleCheck()) // если нет приград сверху (т.к. при движении Игрок окажется на сл уровне { moveLen = m_CellSide * 1.5f - hH; // растояние на которое нужно сдвинуть игрока - выстоа ячейки + пол следующей ячейки и минус его позиция отосительно текущей полки } else { SetState(BallStateType.IN_AIR); // иначе продолжаем движение вверх return(false); } } else { movVector = downVector; // если игрок в состоянии прижков. не логично двигать его до сл. уровня moveLen = halfCell - hH; // поетому сдвигамем его вниз к центру ячейки. } } if (hH < halfCell) // если игрок ниже чем середина ячейки { moveLen = halfCell - hH; // сдвигаем игрока вверх до средины текущей ячейки } if (moveLen > 0) // если Игрока нужно сдвинуть { int N = (int)(moveLen / LeftRightSpeed); // кол-во необходимых кадров для передвижения while (N > 0) // пока есть кадры { m_moveVectors.Enqueue(new MoveInfo(movVector, LeftRightSpeed)); // ложим в очередь инфу о движении N--; //уменьшаем кол-во необходимых кадров } } return(true); }